]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
binutils: Add myself as RISC-V co-maintainer.
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
b3adc24a 2 Copyright (C) 1998-2020 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
2b692964
NC
338#define SECTION_NAME(X) \
339 ((X) == NULL ? _("<none>") \
dda8d76d
NC
340 : filedata->string_table == NULL ? _("<no-strings>") \
341 : ((X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
342 : filedata->string_table + (X)->sh_name))
252b5132 343
ee42cf8c 344#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 345
ba5cdace
NC
346#define GET_ELF_SYMBOLS(file, section, sym_count) \
347 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
348 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 349
10ca4b04
L
350#define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
351 (strtab != NULL && offset < strtab_size)
978c4450
AM
352#define VALID_DYNAMIC_NAME(filedata, offset) \
353 VALID_SYMBOL_NAME (filedata->dynamic_strings, \
354 filedata->dynamic_strings_length, offset)
d79b3d50
NC
355/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
356 already been called and verified that the string exists. */
978c4450
AM
357#define GET_DYNAMIC_NAME(filedata, offset) \
358 (filedata->dynamic_strings + offset)
18bd398b 359
61865e30
NC
360#define REMOVE_ARCH_BITS(ADDR) \
361 do \
362 { \
dda8d76d 363 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
364 (ADDR) &= ~1; \
365 } \
366 while (0)
f16a9783
MS
367
368/* Get the correct GNU hash section name. */
978c4450
AM
369#define GNU_HASH_SECTION_NAME(filedata) \
370 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 371\f
66cfc0fd
AM
372/* Print a BFD_VMA to an internal buffer, for use in error messages.
373 BFD_FMA_FMT can't be used in translated strings. */
374
375static const char *
376bfd_vmatoa (char *fmtch, bfd_vma value)
377{
378 /* bfd_vmatoa is used more then once in a printf call for output.
379 Cycle through an array of buffers. */
380 static int buf_pos = 0;
381 static struct bfd_vmatoa_buf
382 {
383 char place[64];
384 } buf[4];
385 char *ret;
386 char fmt[32];
387
388 ret = buf[buf_pos++].place;
389 buf_pos %= ARRAY_SIZE (buf);
390
391 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
392 snprintf (ret, sizeof (buf[0].place), fmt, value);
393 return ret;
394}
395
dda8d76d
NC
396/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
397 OFFSET + the offset of the current archive member, if we are examining an
398 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
399 allocate a buffer using malloc and fill that. In either case return the
400 pointer to the start of the retrieved data or NULL if something went wrong.
401 If something does go wrong and REASON is not NULL then emit an error
402 message using REASON as part of the context. */
59245841 403
c256ffe7 404static void *
dda8d76d
NC
405get_data (void * var,
406 Filedata * filedata,
407 unsigned long offset,
408 bfd_size_type size,
409 bfd_size_type nmemb,
410 const char * reason)
a6e9f9df 411{
2cf0635d 412 void * mvar;
57028622 413 bfd_size_type amt = size * nmemb;
a6e9f9df 414
c256ffe7 415 if (size == 0 || nmemb == 0)
a6e9f9df
AM
416 return NULL;
417
57028622
NC
418 /* If the size_t type is smaller than the bfd_size_type, eg because
419 you are building a 32-bit tool on a 64-bit host, then make sure
420 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
421 if ((size_t) size != size
422 || (size_t) nmemb != nmemb
423 || (size_t) amt != amt)
57028622
NC
424 {
425 if (reason)
66cfc0fd
AM
426 error (_("Size truncation prevents reading %s"
427 " elements of size %s for %s\n"),
428 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
429 return NULL;
430 }
431
432 /* Check for size overflow. */
7c1c1904 433 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
434 {
435 if (reason)
66cfc0fd
AM
436 error (_("Size overflow prevents reading %s"
437 " elements of size %s for %s\n"),
438 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
439 return NULL;
440 }
441
c22b42ce 442 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 443 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
444 if (filedata->archive_file_offset > filedata->file_size
445 || offset > filedata->file_size - filedata->archive_file_offset
446 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 447 {
049b0c3a 448 if (reason)
66cfc0fd
AM
449 error (_("Reading %s bytes extends past end of file for %s\n"),
450 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
451 return NULL;
452 }
453
978c4450
AM
454 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
455 SEEK_SET))
071436c6
NC
456 {
457 if (reason)
c9c1d674 458 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 459 filedata->archive_file_offset + offset, reason);
071436c6
NC
460 return NULL;
461 }
462
a6e9f9df
AM
463 mvar = var;
464 if (mvar == NULL)
465 {
7c1c1904
AM
466 /* + 1 so that we can '\0' terminate invalid string table sections. */
467 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
468
469 if (mvar == NULL)
470 {
049b0c3a 471 if (reason)
66cfc0fd
AM
472 error (_("Out of memory allocating %s bytes for %s\n"),
473 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
474 return NULL;
475 }
c256ffe7 476
c9c1d674 477 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
478 }
479
dda8d76d 480 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 481 {
049b0c3a 482 if (reason)
66cfc0fd
AM
483 error (_("Unable to read in %s bytes of %s\n"),
484 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
485 if (mvar != var)
486 free (mvar);
487 return NULL;
488 }
489
490 return mvar;
491}
492
32ec8896
NC
493/* Print a VMA value in the MODE specified.
494 Returns the number of characters displayed. */
cb8f3167 495
32ec8896 496static unsigned int
14a91970 497print_vma (bfd_vma vma, print_mode mode)
66543521 498{
32ec8896 499 unsigned int nc = 0;
66543521 500
14a91970 501 switch (mode)
66543521 502 {
14a91970
AM
503 case FULL_HEX:
504 nc = printf ("0x");
1a0670f3 505 /* Fall through. */
14a91970 506 case LONG_HEX:
f7a99963 507#ifdef BFD64
14a91970 508 if (is_32bit_elf)
437c2fb7 509 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 510#endif
14a91970
AM
511 printf_vma (vma);
512 return nc + 16;
b19aac67 513
14a91970
AM
514 case DEC_5:
515 if (vma <= 99999)
516 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 517 /* Fall through. */
14a91970
AM
518 case PREFIX_HEX:
519 nc = printf ("0x");
1a0670f3 520 /* Fall through. */
14a91970
AM
521 case HEX:
522 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 523
14a91970
AM
524 case DEC:
525 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 526
14a91970
AM
527 case UNSIGNED:
528 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896
NC
529
530 default:
531 /* FIXME: Report unrecognised mode ? */
532 return 0;
f7a99963 533 }
f7a99963
NC
534}
535
7bfd842d 536/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 537 multibye characters (assuming the host environment supports them).
31104126 538
7bfd842d
NC
539 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
540
0942c7ab
NC
541 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
542 abs(WIDTH) - 5 characters followed by "[...]".
543
7bfd842d
NC
544 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
545 padding as necessary.
171191ba
NC
546
547 Returns the number of emitted characters. */
548
549static unsigned int
0942c7ab 550print_symbol (signed int width, const char * symbol)
31104126 551{
171191ba 552 bfd_boolean extra_padding = FALSE;
0942c7ab 553 bfd_boolean do_dots = FALSE;
32ec8896 554 signed int num_printed = 0;
3bfcb652 555#ifdef HAVE_MBSTATE_T
7bfd842d 556 mbstate_t state;
3bfcb652 557#endif
32ec8896 558 unsigned int width_remaining;
79bc120c 559 const void * alloced_symbol = NULL;
961c521f 560
7bfd842d 561 if (width < 0)
961c521f 562 {
88305e1b 563 /* Keep the width positive. This helps the code below. */
961c521f 564 width = - width;
171191ba 565 extra_padding = TRUE;
0b4362b0 566 }
56d8f8a9
NC
567 else if (width == 0)
568 return 0;
961c521f 569
7bfd842d
NC
570 if (do_wide)
571 /* Set the remaining width to a very large value.
572 This simplifies the code below. */
573 width_remaining = INT_MAX;
574 else
0942c7ab
NC
575 {
576 width_remaining = width;
577 if (! do_not_show_symbol_truncation
578 && (int) strlen (symbol) > width)
579 {
580 width_remaining -= 5;
581 if ((int) width_remaining < 0)
582 width_remaining = 0;
583 do_dots = TRUE;
584 }
585 }
cb8f3167 586
3bfcb652 587#ifdef HAVE_MBSTATE_T
7bfd842d
NC
588 /* Initialise the multibyte conversion state. */
589 memset (& state, 0, sizeof (state));
3bfcb652 590#endif
961c521f 591
79bc120c
NC
592 if (do_demangle && *symbol)
593 {
594 const char * res = cplus_demangle (symbol, demangle_flags);
595
596 if (res != NULL)
597 alloced_symbol = symbol = res;
598 }
599
7bfd842d
NC
600 while (width_remaining)
601 {
602 size_t n;
7bfd842d 603 const char c = *symbol++;
961c521f 604
7bfd842d 605 if (c == 0)
961c521f
NC
606 break;
607
7bfd842d
NC
608 /* Do not print control characters directly as they can affect terminal
609 settings. Such characters usually appear in the names generated
610 by the assembler for local labels. */
611 if (ISCNTRL (c))
961c521f 612 {
7bfd842d 613 if (width_remaining < 2)
961c521f
NC
614 break;
615
7bfd842d
NC
616 printf ("^%c", c + 0x40);
617 width_remaining -= 2;
171191ba 618 num_printed += 2;
961c521f 619 }
7bfd842d
NC
620 else if (ISPRINT (c))
621 {
622 putchar (c);
623 width_remaining --;
624 num_printed ++;
625 }
961c521f
NC
626 else
627 {
3bfcb652
NC
628#ifdef HAVE_MBSTATE_T
629 wchar_t w;
630#endif
7bfd842d
NC
631 /* Let printf do the hard work of displaying multibyte characters. */
632 printf ("%.1s", symbol - 1);
633 width_remaining --;
634 num_printed ++;
635
3bfcb652 636#ifdef HAVE_MBSTATE_T
7bfd842d
NC
637 /* Try to find out how many bytes made up the character that was
638 just printed. Advance the symbol pointer past the bytes that
639 were displayed. */
640 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
641#else
642 n = 1;
643#endif
7bfd842d
NC
644 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
645 symbol += (n - 1);
961c521f 646 }
961c521f 647 }
171191ba 648
0942c7ab
NC
649 if (do_dots)
650 num_printed += printf ("[...]");
651
7bfd842d 652 if (extra_padding && num_printed < width)
171191ba
NC
653 {
654 /* Fill in the remaining spaces. */
7bfd842d
NC
655 printf ("%-*s", width - num_printed, " ");
656 num_printed = width;
171191ba
NC
657 }
658
79bc120c 659 free ((void *) alloced_symbol);
171191ba 660 return num_printed;
31104126
NC
661}
662
1449284b 663/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
664 the given section's name. Like print_symbol, except that it does not try
665 to print multibyte characters, it just interprets them as hex values. */
666
667static const char *
dda8d76d 668printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b
NC
669{
670#define MAX_PRINT_SEC_NAME_LEN 128
671 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
672 const char * name = SECTION_NAME (sec);
673 char * buf = sec_name_buf;
674 char c;
675 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
676
677 while ((c = * name ++) != 0)
678 {
679 if (ISCNTRL (c))
680 {
681 if (remaining < 2)
682 break;
948f632f 683
74e1a04b
NC
684 * buf ++ = '^';
685 * buf ++ = c + 0x40;
686 remaining -= 2;
687 }
688 else if (ISPRINT (c))
689 {
690 * buf ++ = c;
691 remaining -= 1;
692 }
693 else
694 {
695 static char hex[17] = "0123456789ABCDEF";
696
697 if (remaining < 4)
698 break;
699 * buf ++ = '<';
700 * buf ++ = hex[(c & 0xf0) >> 4];
701 * buf ++ = hex[c & 0x0f];
702 * buf ++ = '>';
703 remaining -= 4;
704 }
705
706 if (remaining == 0)
707 break;
708 }
709
710 * buf = 0;
711 return sec_name_buf;
712}
713
714static const char *
dda8d76d 715printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 716{
dda8d76d 717 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
718 return _("<corrupt>");
719
dda8d76d 720 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
721}
722
89fac5e3
RS
723/* Return a pointer to section NAME, or NULL if no such section exists. */
724
725static Elf_Internal_Shdr *
dda8d76d 726find_section (Filedata * filedata, const char * name)
89fac5e3
RS
727{
728 unsigned int i;
729
68807c3c
NC
730 if (filedata->section_headers == NULL)
731 return NULL;
dda8d76d
NC
732
733 for (i = 0; i < filedata->file_header.e_shnum; i++)
734 if (streq (SECTION_NAME (filedata->section_headers + i), name))
735 return filedata->section_headers + i;
89fac5e3
RS
736
737 return NULL;
738}
739
0b6ae522
DJ
740/* Return a pointer to a section containing ADDR, or NULL if no such
741 section exists. */
742
743static Elf_Internal_Shdr *
dda8d76d 744find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
745{
746 unsigned int i;
747
68807c3c
NC
748 if (filedata->section_headers == NULL)
749 return NULL;
750
dda8d76d 751 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 752 {
dda8d76d
NC
753 Elf_Internal_Shdr *sec = filedata->section_headers + i;
754
0b6ae522
DJ
755 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
756 return sec;
757 }
758
759 return NULL;
760}
761
071436c6 762static Elf_Internal_Shdr *
dda8d76d 763find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
764{
765 unsigned int i;
766
68807c3c
NC
767 if (filedata->section_headers == NULL)
768 return NULL;
769
dda8d76d 770 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 771 {
dda8d76d
NC
772 Elf_Internal_Shdr *sec = filedata->section_headers + i;
773
071436c6
NC
774 if (sec->sh_type == type)
775 return sec;
776 }
777
778 return NULL;
779}
780
657d0d47
CC
781/* Return a pointer to section NAME, or NULL if no such section exists,
782 restricted to the list of sections given in SET. */
783
784static Elf_Internal_Shdr *
dda8d76d 785find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
786{
787 unsigned int i;
788
68807c3c
NC
789 if (filedata->section_headers == NULL)
790 return NULL;
791
657d0d47
CC
792 if (set != NULL)
793 {
794 while ((i = *set++) > 0)
b814a36d
NC
795 {
796 /* See PR 21156 for a reproducer. */
dda8d76d 797 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
798 continue; /* FIXME: Should we issue an error message ? */
799
dda8d76d
NC
800 if (streq (SECTION_NAME (filedata->section_headers + i), name))
801 return filedata->section_headers + i;
b814a36d 802 }
657d0d47
CC
803 }
804
dda8d76d 805 return find_section (filedata, name);
657d0d47
CC
806}
807
32ec8896 808/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
809 This OS has so many departures from the ELF standard that we test it at
810 many places. */
811
32ec8896 812static inline bfd_boolean
dda8d76d 813is_ia64_vms (Filedata * filedata)
28f997cf 814{
dda8d76d
NC
815 return filedata->file_header.e_machine == EM_IA_64
816 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
817}
818
bcedfee6 819/* Guess the relocation size commonly used by the specific machines. */
252b5132 820
32ec8896 821static bfd_boolean
2dc4cec1 822guess_is_rela (unsigned int e_machine)
252b5132 823{
9c19a809 824 switch (e_machine)
252b5132
RH
825 {
826 /* Targets that use REL relocations. */
252b5132 827 case EM_386:
22abe556 828 case EM_IAMCU:
f954747f 829 case EM_960:
e9f53129 830 case EM_ARM:
2b0337b0 831 case EM_D10V:
252b5132 832 case EM_CYGNUS_D10V:
e9f53129 833 case EM_DLX:
252b5132 834 case EM_MIPS:
4fe85591 835 case EM_MIPS_RS3_LE:
e9f53129 836 case EM_CYGNUS_M32R:
1c0d3aa6 837 case EM_SCORE:
f6c1a2d5 838 case EM_XGATE:
fe944acf 839 case EM_NFP:
aca4efc7 840 case EM_BPF:
9c19a809 841 return FALSE;
103f02d3 842
252b5132
RH
843 /* Targets that use RELA relocations. */
844 case EM_68K:
f954747f 845 case EM_860:
a06ea964 846 case EM_AARCH64:
cfb8c092 847 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
848 case EM_ALPHA:
849 case EM_ALTERA_NIOS2:
886a2506
NC
850 case EM_ARC:
851 case EM_ARC_COMPACT:
852 case EM_ARC_COMPACT2:
e9f53129
AM
853 case EM_AVR:
854 case EM_AVR_OLD:
855 case EM_BLACKFIN:
60bca95a 856 case EM_CR16:
e9f53129
AM
857 case EM_CRIS:
858 case EM_CRX:
b8891f8d 859 case EM_CSKY:
2b0337b0 860 case EM_D30V:
252b5132 861 case EM_CYGNUS_D30V:
2b0337b0 862 case EM_FR30:
3f8107ab 863 case EM_FT32:
252b5132 864 case EM_CYGNUS_FR30:
5c70f934 865 case EM_CYGNUS_FRV:
e9f53129
AM
866 case EM_H8S:
867 case EM_H8_300:
868 case EM_H8_300H:
800eeca4 869 case EM_IA_64:
1e4cf259
NC
870 case EM_IP2K:
871 case EM_IP2K_OLD:
3b36097d 872 case EM_IQ2000:
84e94c90 873 case EM_LATTICEMICO32:
ff7eeb89 874 case EM_M32C_OLD:
49f58d10 875 case EM_M32C:
e9f53129
AM
876 case EM_M32R:
877 case EM_MCORE:
15ab5209 878 case EM_CYGNUS_MEP:
a3c62988 879 case EM_METAG:
e9f53129
AM
880 case EM_MMIX:
881 case EM_MN10200:
882 case EM_CYGNUS_MN10200:
883 case EM_MN10300:
884 case EM_CYGNUS_MN10300:
5506d11a 885 case EM_MOXIE:
e9f53129
AM
886 case EM_MSP430:
887 case EM_MSP430_OLD:
d031aafb 888 case EM_MT:
35c08157 889 case EM_NDS32:
64fd6348 890 case EM_NIOS32:
73589c9d 891 case EM_OR1K:
e9f53129
AM
892 case EM_PPC64:
893 case EM_PPC:
2b100bb5 894 case EM_TI_PRU:
e23eba97 895 case EM_RISCV:
99c513f6 896 case EM_RL78:
c7927a3c 897 case EM_RX:
e9f53129
AM
898 case EM_S390:
899 case EM_S390_OLD:
900 case EM_SH:
901 case EM_SPARC:
902 case EM_SPARC32PLUS:
903 case EM_SPARCV9:
904 case EM_SPU:
40b36596 905 case EM_TI_C6000:
aa137e4d
NC
906 case EM_TILEGX:
907 case EM_TILEPRO:
708e2187 908 case EM_V800:
e9f53129
AM
909 case EM_V850:
910 case EM_CYGNUS_V850:
911 case EM_VAX:
619ed720 912 case EM_VISIUM:
e9f53129 913 case EM_X86_64:
8a9036a4 914 case EM_L1OM:
7a9068fe 915 case EM_K1OM:
e9f53129
AM
916 case EM_XSTORMY16:
917 case EM_XTENSA:
918 case EM_XTENSA_OLD:
7ba29e2a
NC
919 case EM_MICROBLAZE:
920 case EM_MICROBLAZE_OLD:
f96bd6c2 921 case EM_WEBASSEMBLY:
9c19a809 922 return TRUE;
103f02d3 923
e9f53129
AM
924 case EM_68HC05:
925 case EM_68HC08:
926 case EM_68HC11:
927 case EM_68HC16:
928 case EM_FX66:
929 case EM_ME16:
d1133906 930 case EM_MMA:
d1133906
NC
931 case EM_NCPU:
932 case EM_NDR1:
e9f53129 933 case EM_PCP:
d1133906 934 case EM_ST100:
e9f53129 935 case EM_ST19:
d1133906 936 case EM_ST7:
e9f53129
AM
937 case EM_ST9PLUS:
938 case EM_STARCORE:
d1133906 939 case EM_SVX:
e9f53129 940 case EM_TINYJ:
9c19a809
NC
941 default:
942 warn (_("Don't know about relocations on this machine architecture\n"));
943 return FALSE;
944 }
945}
252b5132 946
dda8d76d 947/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
948 Returns TRUE upon success, FALSE otherwise. If successful then a
949 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
950 and the number of relocs loaded is placed in *NRELASP. It is the caller's
951 responsibility to free the allocated buffer. */
952
953static bfd_boolean
dda8d76d
NC
954slurp_rela_relocs (Filedata * filedata,
955 unsigned long rel_offset,
956 unsigned long rel_size,
957 Elf_Internal_Rela ** relasp,
958 unsigned long * nrelasp)
9c19a809 959{
2cf0635d 960 Elf_Internal_Rela * relas;
8b73c356 961 size_t nrelas;
4d6ed7c8 962 unsigned int i;
252b5132 963
4d6ed7c8
NC
964 if (is_32bit_elf)
965 {
2cf0635d 966 Elf32_External_Rela * erelas;
103f02d3 967
dda8d76d 968 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 969 rel_size, _("32-bit relocation data"));
a6e9f9df 970 if (!erelas)
32ec8896 971 return FALSE;
252b5132 972
4d6ed7c8 973 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 974
3f5e193b
NC
975 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
976 sizeof (Elf_Internal_Rela));
103f02d3 977
4d6ed7c8
NC
978 if (relas == NULL)
979 {
c256ffe7 980 free (erelas);
591a748a 981 error (_("out of memory parsing relocs\n"));
32ec8896 982 return FALSE;
4d6ed7c8 983 }
103f02d3 984
4d6ed7c8
NC
985 for (i = 0; i < nrelas; i++)
986 {
987 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
988 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 989 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 990 }
103f02d3 991
4d6ed7c8
NC
992 free (erelas);
993 }
994 else
995 {
2cf0635d 996 Elf64_External_Rela * erelas;
103f02d3 997
dda8d76d 998 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 999 rel_size, _("64-bit relocation data"));
a6e9f9df 1000 if (!erelas)
32ec8896 1001 return FALSE;
4d6ed7c8
NC
1002
1003 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1004
3f5e193b
NC
1005 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1006 sizeof (Elf_Internal_Rela));
103f02d3 1007
4d6ed7c8
NC
1008 if (relas == NULL)
1009 {
c256ffe7 1010 free (erelas);
591a748a 1011 error (_("out of memory parsing relocs\n"));
32ec8896 1012 return FALSE;
9c19a809 1013 }
4d6ed7c8
NC
1014
1015 for (i = 0; i < nrelas; i++)
9c19a809 1016 {
66543521
AM
1017 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1018 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1019 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1020
1021 /* The #ifdef BFD64 below is to prevent a compile time
1022 warning. We know that if we do not have a 64 bit data
1023 type that we will never execute this code anyway. */
1024#ifdef BFD64
dda8d76d
NC
1025 if (filedata->file_header.e_machine == EM_MIPS
1026 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1027 {
1028 /* In little-endian objects, r_info isn't really a
1029 64-bit little-endian value: it has a 32-bit
1030 little-endian symbol index followed by four
1031 individual byte fields. Reorder INFO
1032 accordingly. */
91d6fa6a
NC
1033 bfd_vma inf = relas[i].r_info;
1034 inf = (((inf & 0xffffffff) << 32)
1035 | ((inf >> 56) & 0xff)
1036 | ((inf >> 40) & 0xff00)
1037 | ((inf >> 24) & 0xff0000)
1038 | ((inf >> 8) & 0xff000000));
1039 relas[i].r_info = inf;
861fb55a
DJ
1040 }
1041#endif /* BFD64 */
4d6ed7c8 1042 }
103f02d3 1043
4d6ed7c8
NC
1044 free (erelas);
1045 }
32ec8896 1046
4d6ed7c8
NC
1047 *relasp = relas;
1048 *nrelasp = nrelas;
32ec8896 1049 return TRUE;
4d6ed7c8 1050}
103f02d3 1051
dda8d76d 1052/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1053 Returns TRUE upon success, FALSE otherwise. If successful then a
1054 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1055 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1056 responsibility to free the allocated buffer. */
1057
1058static bfd_boolean
dda8d76d
NC
1059slurp_rel_relocs (Filedata * filedata,
1060 unsigned long rel_offset,
1061 unsigned long rel_size,
1062 Elf_Internal_Rela ** relsp,
1063 unsigned long * nrelsp)
4d6ed7c8 1064{
2cf0635d 1065 Elf_Internal_Rela * rels;
8b73c356 1066 size_t nrels;
4d6ed7c8 1067 unsigned int i;
103f02d3 1068
4d6ed7c8
NC
1069 if (is_32bit_elf)
1070 {
2cf0635d 1071 Elf32_External_Rel * erels;
103f02d3 1072
dda8d76d 1073 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1074 rel_size, _("32-bit relocation data"));
a6e9f9df 1075 if (!erels)
32ec8896 1076 return FALSE;
103f02d3 1077
4d6ed7c8 1078 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1079
3f5e193b 1080 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1081
4d6ed7c8
NC
1082 if (rels == NULL)
1083 {
c256ffe7 1084 free (erels);
591a748a 1085 error (_("out of memory parsing relocs\n"));
32ec8896 1086 return FALSE;
4d6ed7c8
NC
1087 }
1088
1089 for (i = 0; i < nrels; i++)
1090 {
1091 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1092 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1093 rels[i].r_addend = 0;
9ea033b2 1094 }
4d6ed7c8
NC
1095
1096 free (erels);
9c19a809
NC
1097 }
1098 else
1099 {
2cf0635d 1100 Elf64_External_Rel * erels;
9ea033b2 1101
dda8d76d 1102 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1103 rel_size, _("64-bit relocation data"));
a6e9f9df 1104 if (!erels)
32ec8896 1105 return FALSE;
103f02d3 1106
4d6ed7c8 1107 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1108
3f5e193b 1109 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1110
4d6ed7c8 1111 if (rels == NULL)
9c19a809 1112 {
c256ffe7 1113 free (erels);
591a748a 1114 error (_("out of memory parsing relocs\n"));
32ec8896 1115 return FALSE;
4d6ed7c8 1116 }
103f02d3 1117
4d6ed7c8
NC
1118 for (i = 0; i < nrels; i++)
1119 {
66543521
AM
1120 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1121 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1122 rels[i].r_addend = 0;
861fb55a
DJ
1123
1124 /* The #ifdef BFD64 below is to prevent a compile time
1125 warning. We know that if we do not have a 64 bit data
1126 type that we will never execute this code anyway. */
1127#ifdef BFD64
dda8d76d
NC
1128 if (filedata->file_header.e_machine == EM_MIPS
1129 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1130 {
1131 /* In little-endian objects, r_info isn't really a
1132 64-bit little-endian value: it has a 32-bit
1133 little-endian symbol index followed by four
1134 individual byte fields. Reorder INFO
1135 accordingly. */
91d6fa6a
NC
1136 bfd_vma inf = rels[i].r_info;
1137 inf = (((inf & 0xffffffff) << 32)
1138 | ((inf >> 56) & 0xff)
1139 | ((inf >> 40) & 0xff00)
1140 | ((inf >> 24) & 0xff0000)
1141 | ((inf >> 8) & 0xff000000));
1142 rels[i].r_info = inf;
861fb55a
DJ
1143 }
1144#endif /* BFD64 */
4d6ed7c8 1145 }
103f02d3 1146
4d6ed7c8
NC
1147 free (erels);
1148 }
32ec8896 1149
4d6ed7c8
NC
1150 *relsp = rels;
1151 *nrelsp = nrels;
32ec8896 1152 return TRUE;
4d6ed7c8 1153}
103f02d3 1154
aca88567
NC
1155/* Returns the reloc type extracted from the reloc info field. */
1156
1157static unsigned int
dda8d76d 1158get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1159{
1160 if (is_32bit_elf)
1161 return ELF32_R_TYPE (reloc_info);
1162
dda8d76d 1163 switch (filedata->file_header.e_machine)
aca88567
NC
1164 {
1165 case EM_MIPS:
1166 /* Note: We assume that reloc_info has already been adjusted for us. */
1167 return ELF64_MIPS_R_TYPE (reloc_info);
1168
1169 case EM_SPARCV9:
1170 return ELF64_R_TYPE_ID (reloc_info);
1171
1172 default:
1173 return ELF64_R_TYPE (reloc_info);
1174 }
1175}
1176
1177/* Return the symbol index extracted from the reloc info field. */
1178
1179static bfd_vma
1180get_reloc_symindex (bfd_vma reloc_info)
1181{
1182 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1183}
1184
13761a11 1185static inline bfd_boolean
dda8d76d 1186uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1187{
1188 return
dda8d76d 1189 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1190 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1191 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1192 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1193 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1194}
1195
d3ba0551
AM
1196/* Display the contents of the relocation data found at the specified
1197 offset. */
ee42cf8c 1198
32ec8896 1199static bfd_boolean
dda8d76d
NC
1200dump_relocations (Filedata * filedata,
1201 unsigned long rel_offset,
1202 unsigned long rel_size,
1203 Elf_Internal_Sym * symtab,
1204 unsigned long nsyms,
1205 char * strtab,
1206 unsigned long strtablen,
1207 int is_rela,
1208 bfd_boolean is_dynsym)
4d6ed7c8 1209{
32ec8896 1210 unsigned long i;
2cf0635d 1211 Elf_Internal_Rela * rels;
32ec8896 1212 bfd_boolean res = TRUE;
103f02d3 1213
4d6ed7c8 1214 if (is_rela == UNKNOWN)
dda8d76d 1215 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1216
4d6ed7c8
NC
1217 if (is_rela)
1218 {
dda8d76d 1219 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1220 return FALSE;
4d6ed7c8
NC
1221 }
1222 else
1223 {
dda8d76d 1224 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1225 return FALSE;
252b5132
RH
1226 }
1227
410f7a12
L
1228 if (is_32bit_elf)
1229 {
1230 if (is_rela)
2c71103e
NC
1231 {
1232 if (do_wide)
1233 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1234 else
1235 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1236 }
410f7a12 1237 else
2c71103e
NC
1238 {
1239 if (do_wide)
1240 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1241 else
1242 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1243 }
410f7a12 1244 }
252b5132 1245 else
410f7a12
L
1246 {
1247 if (is_rela)
2c71103e
NC
1248 {
1249 if (do_wide)
8beeaeb7 1250 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1251 else
1252 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1253 }
410f7a12 1254 else
2c71103e
NC
1255 {
1256 if (do_wide)
8beeaeb7 1257 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1258 else
1259 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1260 }
410f7a12 1261 }
252b5132
RH
1262
1263 for (i = 0; i < rel_size; i++)
1264 {
2cf0635d 1265 const char * rtype;
b34976b6 1266 bfd_vma offset;
91d6fa6a 1267 bfd_vma inf;
b34976b6
AM
1268 bfd_vma symtab_index;
1269 bfd_vma type;
103f02d3 1270
b34976b6 1271 offset = rels[i].r_offset;
91d6fa6a 1272 inf = rels[i].r_info;
103f02d3 1273
dda8d76d 1274 type = get_reloc_type (filedata, inf);
91d6fa6a 1275 symtab_index = get_reloc_symindex (inf);
252b5132 1276
410f7a12
L
1277 if (is_32bit_elf)
1278 {
39dbeff8
AM
1279 printf ("%8.8lx %8.8lx ",
1280 (unsigned long) offset & 0xffffffff,
91d6fa6a 1281 (unsigned long) inf & 0xffffffff);
410f7a12
L
1282 }
1283 else
1284 {
39dbeff8 1285 printf (do_wide
d1ce973e
AM
1286 ? "%16.16" BFD_VMA_FMT "x %16.16" BFD_VMA_FMT "x "
1287 : "%12.12" BFD_VMA_FMT "x %12.12" BFD_VMA_FMT "x ",
91d6fa6a 1288 offset, inf);
410f7a12 1289 }
103f02d3 1290
dda8d76d 1291 switch (filedata->file_header.e_machine)
252b5132
RH
1292 {
1293 default:
1294 rtype = NULL;
1295 break;
1296
a06ea964
NC
1297 case EM_AARCH64:
1298 rtype = elf_aarch64_reloc_type (type);
1299 break;
1300
2b0337b0 1301 case EM_M32R:
252b5132 1302 case EM_CYGNUS_M32R:
9ea033b2 1303 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1304 break;
1305
1306 case EM_386:
22abe556 1307 case EM_IAMCU:
9ea033b2 1308 rtype = elf_i386_reloc_type (type);
252b5132
RH
1309 break;
1310
ba2685cc
AM
1311 case EM_68HC11:
1312 case EM_68HC12:
1313 rtype = elf_m68hc11_reloc_type (type);
1314 break;
75751cd9 1315
7b4ae824
JD
1316 case EM_S12Z:
1317 rtype = elf_s12z_reloc_type (type);
1318 break;
1319
252b5132 1320 case EM_68K:
9ea033b2 1321 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1322 break;
1323
f954747f
AM
1324 case EM_960:
1325 rtype = elf_i960_reloc_type (type);
1326 break;
1327
adde6300 1328 case EM_AVR:
2b0337b0 1329 case EM_AVR_OLD:
adde6300
AM
1330 rtype = elf_avr_reloc_type (type);
1331 break;
1332
9ea033b2
NC
1333 case EM_OLD_SPARCV9:
1334 case EM_SPARC32PLUS:
1335 case EM_SPARCV9:
252b5132 1336 case EM_SPARC:
9ea033b2 1337 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1338 break;
1339
e9f53129
AM
1340 case EM_SPU:
1341 rtype = elf_spu_reloc_type (type);
1342 break;
1343
708e2187
NC
1344 case EM_V800:
1345 rtype = v800_reloc_type (type);
1346 break;
2b0337b0 1347 case EM_V850:
252b5132 1348 case EM_CYGNUS_V850:
9ea033b2 1349 rtype = v850_reloc_type (type);
252b5132
RH
1350 break;
1351
2b0337b0 1352 case EM_D10V:
252b5132 1353 case EM_CYGNUS_D10V:
9ea033b2 1354 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1355 break;
1356
2b0337b0 1357 case EM_D30V:
252b5132 1358 case EM_CYGNUS_D30V:
9ea033b2 1359 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1360 break;
1361
d172d4ba
NC
1362 case EM_DLX:
1363 rtype = elf_dlx_reloc_type (type);
1364 break;
1365
252b5132 1366 case EM_SH:
9ea033b2 1367 rtype = elf_sh_reloc_type (type);
252b5132
RH
1368 break;
1369
2b0337b0 1370 case EM_MN10300:
252b5132 1371 case EM_CYGNUS_MN10300:
9ea033b2 1372 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1373 break;
1374
2b0337b0 1375 case EM_MN10200:
252b5132 1376 case EM_CYGNUS_MN10200:
9ea033b2 1377 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1378 break;
1379
2b0337b0 1380 case EM_FR30:
252b5132 1381 case EM_CYGNUS_FR30:
9ea033b2 1382 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1383 break;
1384
ba2685cc
AM
1385 case EM_CYGNUS_FRV:
1386 rtype = elf_frv_reloc_type (type);
1387 break;
5c70f934 1388
b8891f8d
AJ
1389 case EM_CSKY:
1390 rtype = elf_csky_reloc_type (type);
1391 break;
1392
3f8107ab
AM
1393 case EM_FT32:
1394 rtype = elf_ft32_reloc_type (type);
1395 break;
1396
252b5132 1397 case EM_MCORE:
9ea033b2 1398 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1399 break;
1400
3c3bdf30
NC
1401 case EM_MMIX:
1402 rtype = elf_mmix_reloc_type (type);
1403 break;
1404
5506d11a
AM
1405 case EM_MOXIE:
1406 rtype = elf_moxie_reloc_type (type);
1407 break;
1408
2469cfa2 1409 case EM_MSP430:
dda8d76d 1410 if (uses_msp430x_relocs (filedata))
13761a11
NC
1411 {
1412 rtype = elf_msp430x_reloc_type (type);
1413 break;
1414 }
1a0670f3 1415 /* Fall through. */
2469cfa2
NC
1416 case EM_MSP430_OLD:
1417 rtype = elf_msp430_reloc_type (type);
1418 break;
1419
35c08157
KLC
1420 case EM_NDS32:
1421 rtype = elf_nds32_reloc_type (type);
1422 break;
1423
252b5132 1424 case EM_PPC:
9ea033b2 1425 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1426 break;
1427
c833c019
AM
1428 case EM_PPC64:
1429 rtype = elf_ppc64_reloc_type (type);
1430 break;
1431
252b5132 1432 case EM_MIPS:
4fe85591 1433 case EM_MIPS_RS3_LE:
9ea033b2 1434 rtype = elf_mips_reloc_type (type);
252b5132
RH
1435 break;
1436
e23eba97
NC
1437 case EM_RISCV:
1438 rtype = elf_riscv_reloc_type (type);
1439 break;
1440
252b5132 1441 case EM_ALPHA:
9ea033b2 1442 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1443 break;
1444
1445 case EM_ARM:
9ea033b2 1446 rtype = elf_arm_reloc_type (type);
252b5132
RH
1447 break;
1448
584da044 1449 case EM_ARC:
886a2506
NC
1450 case EM_ARC_COMPACT:
1451 case EM_ARC_COMPACT2:
9ea033b2 1452 rtype = elf_arc_reloc_type (type);
252b5132
RH
1453 break;
1454
1455 case EM_PARISC:
69e617ca 1456 rtype = elf_hppa_reloc_type (type);
252b5132 1457 break;
7d466069 1458
b8720f9d
JL
1459 case EM_H8_300:
1460 case EM_H8_300H:
1461 case EM_H8S:
1462 rtype = elf_h8_reloc_type (type);
1463 break;
1464
73589c9d
CS
1465 case EM_OR1K:
1466 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1467 break;
1468
7d466069 1469 case EM_PJ:
2b0337b0 1470 case EM_PJ_OLD:
7d466069
ILT
1471 rtype = elf_pj_reloc_type (type);
1472 break;
800eeca4
JW
1473 case EM_IA_64:
1474 rtype = elf_ia64_reloc_type (type);
1475 break;
1b61cf92
HPN
1476
1477 case EM_CRIS:
1478 rtype = elf_cris_reloc_type (type);
1479 break;
535c37ff 1480
f954747f
AM
1481 case EM_860:
1482 rtype = elf_i860_reloc_type (type);
1483 break;
1484
bcedfee6 1485 case EM_X86_64:
8a9036a4 1486 case EM_L1OM:
7a9068fe 1487 case EM_K1OM:
bcedfee6
NC
1488 rtype = elf_x86_64_reloc_type (type);
1489 break;
a85d7ed0 1490
f954747f
AM
1491 case EM_S370:
1492 rtype = i370_reloc_type (type);
1493 break;
1494
53c7db4b
KH
1495 case EM_S390_OLD:
1496 case EM_S390:
1497 rtype = elf_s390_reloc_type (type);
1498 break;
93fbbb04 1499
1c0d3aa6
NC
1500 case EM_SCORE:
1501 rtype = elf_score_reloc_type (type);
1502 break;
1503
93fbbb04
GK
1504 case EM_XSTORMY16:
1505 rtype = elf_xstormy16_reloc_type (type);
1506 break;
179d3252 1507
1fe1f39c
NC
1508 case EM_CRX:
1509 rtype = elf_crx_reloc_type (type);
1510 break;
1511
179d3252
JT
1512 case EM_VAX:
1513 rtype = elf_vax_reloc_type (type);
1514 break;
1e4cf259 1515
619ed720
EB
1516 case EM_VISIUM:
1517 rtype = elf_visium_reloc_type (type);
1518 break;
1519
aca4efc7
JM
1520 case EM_BPF:
1521 rtype = elf_bpf_reloc_type (type);
1522 break;
1523
cfb8c092
NC
1524 case EM_ADAPTEVA_EPIPHANY:
1525 rtype = elf_epiphany_reloc_type (type);
1526 break;
1527
1e4cf259
NC
1528 case EM_IP2K:
1529 case EM_IP2K_OLD:
1530 rtype = elf_ip2k_reloc_type (type);
1531 break;
3b36097d
SC
1532
1533 case EM_IQ2000:
1534 rtype = elf_iq2000_reloc_type (type);
1535 break;
88da6820
NC
1536
1537 case EM_XTENSA_OLD:
1538 case EM_XTENSA:
1539 rtype = elf_xtensa_reloc_type (type);
1540 break;
a34e3ecb 1541
84e94c90
NC
1542 case EM_LATTICEMICO32:
1543 rtype = elf_lm32_reloc_type (type);
1544 break;
1545
ff7eeb89 1546 case EM_M32C_OLD:
49f58d10
JB
1547 case EM_M32C:
1548 rtype = elf_m32c_reloc_type (type);
1549 break;
1550
d031aafb
NS
1551 case EM_MT:
1552 rtype = elf_mt_reloc_type (type);
a34e3ecb 1553 break;
1d65ded4
CM
1554
1555 case EM_BLACKFIN:
1556 rtype = elf_bfin_reloc_type (type);
1557 break;
15ab5209
DB
1558
1559 case EM_CYGNUS_MEP:
1560 rtype = elf_mep_reloc_type (type);
1561 break;
60bca95a
NC
1562
1563 case EM_CR16:
1564 rtype = elf_cr16_reloc_type (type);
1565 break;
dd24e3da 1566
7ba29e2a
NC
1567 case EM_MICROBLAZE:
1568 case EM_MICROBLAZE_OLD:
1569 rtype = elf_microblaze_reloc_type (type);
1570 break;
c7927a3c 1571
99c513f6
DD
1572 case EM_RL78:
1573 rtype = elf_rl78_reloc_type (type);
1574 break;
1575
c7927a3c
NC
1576 case EM_RX:
1577 rtype = elf_rx_reloc_type (type);
1578 break;
c29aca4a 1579
a3c62988
NC
1580 case EM_METAG:
1581 rtype = elf_metag_reloc_type (type);
1582 break;
1583
c29aca4a
NC
1584 case EM_XC16X:
1585 case EM_C166:
1586 rtype = elf_xc16x_reloc_type (type);
1587 break;
40b36596
JM
1588
1589 case EM_TI_C6000:
1590 rtype = elf_tic6x_reloc_type (type);
1591 break;
aa137e4d
NC
1592
1593 case EM_TILEGX:
1594 rtype = elf_tilegx_reloc_type (type);
1595 break;
1596
1597 case EM_TILEPRO:
1598 rtype = elf_tilepro_reloc_type (type);
1599 break;
f6c1a2d5 1600
f96bd6c2
PC
1601 case EM_WEBASSEMBLY:
1602 rtype = elf_wasm32_reloc_type (type);
1603 break;
1604
f6c1a2d5
NC
1605 case EM_XGATE:
1606 rtype = elf_xgate_reloc_type (type);
1607 break;
36591ba1
SL
1608
1609 case EM_ALTERA_NIOS2:
1610 rtype = elf_nios2_reloc_type (type);
1611 break;
2b100bb5
DD
1612
1613 case EM_TI_PRU:
1614 rtype = elf_pru_reloc_type (type);
1615 break;
fe944acf
FT
1616
1617 case EM_NFP:
1618 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1619 rtype = elf_nfp3200_reloc_type (type);
1620 else
1621 rtype = elf_nfp_reloc_type (type);
1622 break;
6655dba2
SB
1623
1624 case EM_Z80:
1625 rtype = elf_z80_reloc_type (type);
1626 break;
252b5132
RH
1627 }
1628
1629 if (rtype == NULL)
39dbeff8 1630 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1631 else
5c144731 1632 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1633
dda8d76d 1634 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1635 && rtype != NULL
7ace3541
RH
1636 && streq (rtype, "R_ALPHA_LITUSE")
1637 && is_rela)
1638 {
1639 switch (rels[i].r_addend)
1640 {
1641 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1642 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1643 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1644 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1645 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1646 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1647 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1648 default: rtype = NULL;
1649 }
32ec8896 1650
7ace3541
RH
1651 if (rtype)
1652 printf (" (%s)", rtype);
1653 else
1654 {
1655 putchar (' ');
1656 printf (_("<unknown addend: %lx>"),
1657 (unsigned long) rels[i].r_addend);
32ec8896 1658 res = FALSE;
7ace3541
RH
1659 }
1660 }
1661 else if (symtab_index)
252b5132 1662 {
af3fc3bc 1663 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1664 {
27a45f42
AS
1665 error (_(" bad symbol index: %08lx in reloc\n"),
1666 (unsigned long) symtab_index);
32ec8896
NC
1667 res = FALSE;
1668 }
af3fc3bc 1669 else
19936277 1670 {
2cf0635d 1671 Elf_Internal_Sym * psym;
bb4d2ac2
L
1672 const char * version_string;
1673 enum versioned_symbol_info sym_info;
1674 unsigned short vna_other;
19936277 1675
af3fc3bc 1676 psym = symtab + symtab_index;
103f02d3 1677
bb4d2ac2 1678 version_string
dda8d76d 1679 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1680 strtab, strtablen,
1681 symtab_index,
1682 psym,
1683 &sym_info,
1684 &vna_other);
1685
af3fc3bc 1686 printf (" ");
171191ba 1687
d8045f23
NC
1688 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1689 {
1690 const char * name;
1691 unsigned int len;
1692 unsigned int width = is_32bit_elf ? 8 : 14;
1693
1694 /* Relocations against GNU_IFUNC symbols do not use the value
1695 of the symbol as the address to relocate against. Instead
1696 they invoke the function named by the symbol and use its
1697 result as the address for relocation.
1698
1699 To indicate this to the user, do not display the value of
1700 the symbol in the "Symbols's Value" field. Instead show
1701 its name followed by () as a hint that the symbol is
1702 invoked. */
1703
1704 if (strtab == NULL
1705 || psym->st_name == 0
1706 || psym->st_name >= strtablen)
1707 name = "??";
1708 else
1709 name = strtab + psym->st_name;
1710
1711 len = print_symbol (width, name);
bb4d2ac2
L
1712 if (version_string)
1713 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1714 version_string);
d8045f23
NC
1715 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1716 }
1717 else
1718 {
1719 print_vma (psym->st_value, LONG_HEX);
171191ba 1720
d8045f23
NC
1721 printf (is_32bit_elf ? " " : " ");
1722 }
103f02d3 1723
af3fc3bc 1724 if (psym->st_name == 0)
f1ef08cb 1725 {
2cf0635d 1726 const char * sec_name = "<null>";
f1ef08cb
AM
1727 char name_buf[40];
1728
1729 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1730 {
dda8d76d
NC
1731 if (psym->st_shndx < filedata->file_header.e_shnum)
1732 sec_name = SECTION_NAME (filedata->section_headers + psym->st_shndx);
f1ef08cb
AM
1733 else if (psym->st_shndx == SHN_ABS)
1734 sec_name = "ABS";
1735 else if (psym->st_shndx == SHN_COMMON)
1736 sec_name = "COMMON";
dda8d76d 1737 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1738 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1739 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1740 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1741 sec_name = "SCOMMON";
dda8d76d 1742 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1743 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1744 sec_name = "SUNDEF";
dda8d76d
NC
1745 else if ((filedata->file_header.e_machine == EM_X86_64
1746 || filedata->file_header.e_machine == EM_L1OM
1747 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1748 && psym->st_shndx == SHN_X86_64_LCOMMON)
1749 sec_name = "LARGE_COMMON";
dda8d76d
NC
1750 else if (filedata->file_header.e_machine == EM_IA_64
1751 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1752 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1753 sec_name = "ANSI_COM";
dda8d76d 1754 else if (is_ia64_vms (filedata)
148b93f2
NC
1755 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1756 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1757 else
1758 {
1759 sprintf (name_buf, "<section 0x%x>",
1760 (unsigned int) psym->st_shndx);
1761 sec_name = name_buf;
1762 }
1763 }
1764 print_symbol (22, sec_name);
1765 }
af3fc3bc 1766 else if (strtab == NULL)
d79b3d50 1767 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1768 else if (psym->st_name >= strtablen)
32ec8896 1769 {
27a45f42
AS
1770 error (_("<corrupt string table index: %3ld>\n"),
1771 psym->st_name);
32ec8896
NC
1772 res = FALSE;
1773 }
af3fc3bc 1774 else
bb4d2ac2
L
1775 {
1776 print_symbol (22, strtab + psym->st_name);
1777 if (version_string)
1778 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1779 version_string);
1780 }
103f02d3 1781
af3fc3bc 1782 if (is_rela)
171191ba 1783 {
7360e63f 1784 bfd_vma off = rels[i].r_addend;
171191ba 1785
7360e63f 1786 if ((bfd_signed_vma) off < 0)
598aaa76 1787 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1788 else
598aaa76 1789 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1790 }
19936277 1791 }
252b5132 1792 }
1b228002 1793 else if (is_rela)
f7a99963 1794 {
7360e63f 1795 bfd_vma off = rels[i].r_addend;
e04d7088
L
1796
1797 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1798 if ((bfd_signed_vma) off < 0)
e04d7088
L
1799 printf ("-%" BFD_VMA_FMT "x", - off);
1800 else
1801 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1802 }
252b5132 1803
dda8d76d 1804 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1805 && rtype != NULL
1806 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1807 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1808
252b5132 1809 putchar ('\n');
2c71103e 1810
aca88567 1811#ifdef BFD64
dda8d76d 1812 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1813 {
91d6fa6a
NC
1814 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1815 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1816 const char * rtype2 = elf_mips_reloc_type (type2);
1817 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1818
2c71103e
NC
1819 printf (" Type2: ");
1820
1821 if (rtype2 == NULL)
39dbeff8
AM
1822 printf (_("unrecognized: %-7lx"),
1823 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1824 else
1825 printf ("%-17.17s", rtype2);
1826
18bd398b 1827 printf ("\n Type3: ");
2c71103e
NC
1828
1829 if (rtype3 == NULL)
39dbeff8
AM
1830 printf (_("unrecognized: %-7lx"),
1831 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1832 else
1833 printf ("%-17.17s", rtype3);
1834
53c7db4b 1835 putchar ('\n');
2c71103e 1836 }
aca88567 1837#endif /* BFD64 */
252b5132
RH
1838 }
1839
c8286bd1 1840 free (rels);
32ec8896
NC
1841
1842 return res;
252b5132
RH
1843}
1844
37c18eed
SD
1845static const char *
1846get_aarch64_dynamic_type (unsigned long type)
1847{
1848 switch (type)
1849 {
1850 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 1851 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 1852 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
1853 default:
1854 return NULL;
1855 }
1856}
1857
252b5132 1858static const char *
d3ba0551 1859get_mips_dynamic_type (unsigned long type)
252b5132
RH
1860{
1861 switch (type)
1862 {
1863 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1864 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1865 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1866 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1867 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1868 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1869 case DT_MIPS_MSYM: return "MIPS_MSYM";
1870 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1871 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1872 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1873 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1874 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1875 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1876 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1877 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1878 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1879 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1880 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1881 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1882 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1883 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1884 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1885 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1886 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1887 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1888 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1889 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1890 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1891 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1892 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1893 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1894 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1895 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1896 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1897 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1898 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1899 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1900 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1901 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1902 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1903 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1904 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1905 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1906 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1907 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1908 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 1909 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
1910 default:
1911 return NULL;
1912 }
1913}
1914
9a097730 1915static const char *
d3ba0551 1916get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1917{
1918 switch (type)
1919 {
1920 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1921 default:
1922 return NULL;
1923 }
103f02d3
UD
1924}
1925
7490d522
AM
1926static const char *
1927get_ppc_dynamic_type (unsigned long type)
1928{
1929 switch (type)
1930 {
a7f2871e 1931 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1932 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1933 default:
1934 return NULL;
1935 }
1936}
1937
f1cb7e17 1938static const char *
d3ba0551 1939get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1940{
1941 switch (type)
1942 {
a7f2871e
AM
1943 case DT_PPC64_GLINK: return "PPC64_GLINK";
1944 case DT_PPC64_OPD: return "PPC64_OPD";
1945 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1946 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1947 default:
1948 return NULL;
1949 }
1950}
1951
103f02d3 1952static const char *
d3ba0551 1953get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1954{
1955 switch (type)
1956 {
1957 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1958 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1959 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1960 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1961 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1962 case DT_HP_PREINIT: return "HP_PREINIT";
1963 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1964 case DT_HP_NEEDED: return "HP_NEEDED";
1965 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1966 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1967 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1968 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1969 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1970 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1971 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1972 case DT_HP_FILTERED: return "HP_FILTERED";
1973 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1974 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1975 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1976 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1977 case DT_PLT: return "PLT";
1978 case DT_PLT_SIZE: return "PLT_SIZE";
1979 case DT_DLT: return "DLT";
1980 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1981 default:
1982 return NULL;
1983 }
1984}
9a097730 1985
ecc51f48 1986static const char *
d3ba0551 1987get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1988{
1989 switch (type)
1990 {
148b93f2
NC
1991 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1992 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1993 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1994 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1995 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1996 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1997 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1998 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1999 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2000 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2001 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2002 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2003 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2004 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2005 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2006 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2007 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2008 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2009 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2010 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2011 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2012 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2013 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2014 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2015 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2016 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2017 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2018 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2019 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2020 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2021 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2022 default:
2023 return NULL;
2024 }
2025}
2026
fd85a6a1
NC
2027static const char *
2028get_solaris_section_type (unsigned long type)
2029{
2030 switch (type)
2031 {
2032 case 0x6fffffee: return "SUNW_ancillary";
2033 case 0x6fffffef: return "SUNW_capchain";
2034 case 0x6ffffff0: return "SUNW_capinfo";
2035 case 0x6ffffff1: return "SUNW_symsort";
2036 case 0x6ffffff2: return "SUNW_tlssort";
2037 case 0x6ffffff3: return "SUNW_LDYNSYM";
2038 case 0x6ffffff4: return "SUNW_dof";
2039 case 0x6ffffff5: return "SUNW_cap";
2040 case 0x6ffffff6: return "SUNW_SIGNATURE";
2041 case 0x6ffffff7: return "SUNW_ANNOTATE";
2042 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2043 case 0x6ffffff9: return "SUNW_DEBUG";
2044 case 0x6ffffffa: return "SUNW_move";
2045 case 0x6ffffffb: return "SUNW_COMDAT";
2046 case 0x6ffffffc: return "SUNW_syminfo";
2047 case 0x6ffffffd: return "SUNW_verdef";
2048 case 0x6ffffffe: return "SUNW_verneed";
2049 case 0x6fffffff: return "SUNW_versym";
2050 case 0x70000000: return "SPARC_GOTDATA";
2051 default: return NULL;
2052 }
2053}
2054
fabcb361
RH
2055static const char *
2056get_alpha_dynamic_type (unsigned long type)
2057{
2058 switch (type)
2059 {
2060 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2061 default: return NULL;
fabcb361
RH
2062 }
2063}
2064
1c0d3aa6
NC
2065static const char *
2066get_score_dynamic_type (unsigned long type)
2067{
2068 switch (type)
2069 {
2070 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2071 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2072 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2073 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2074 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2075 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2076 default: return NULL;
1c0d3aa6
NC
2077 }
2078}
2079
40b36596
JM
2080static const char *
2081get_tic6x_dynamic_type (unsigned long type)
2082{
2083 switch (type)
2084 {
2085 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2086 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2087 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2088 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2089 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2090 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2091 default: return NULL;
40b36596
JM
2092 }
2093}
1c0d3aa6 2094
36591ba1
SL
2095static const char *
2096get_nios2_dynamic_type (unsigned long type)
2097{
2098 switch (type)
2099 {
2100 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2101 default: return NULL;
36591ba1
SL
2102 }
2103}
2104
fd85a6a1
NC
2105static const char *
2106get_solaris_dynamic_type (unsigned long type)
2107{
2108 switch (type)
2109 {
2110 case 0x6000000d: return "SUNW_AUXILIARY";
2111 case 0x6000000e: return "SUNW_RTLDINF";
2112 case 0x6000000f: return "SUNW_FILTER";
2113 case 0x60000010: return "SUNW_CAP";
2114 case 0x60000011: return "SUNW_SYMTAB";
2115 case 0x60000012: return "SUNW_SYMSZ";
2116 case 0x60000013: return "SUNW_SORTENT";
2117 case 0x60000014: return "SUNW_SYMSORT";
2118 case 0x60000015: return "SUNW_SYMSORTSZ";
2119 case 0x60000016: return "SUNW_TLSSORT";
2120 case 0x60000017: return "SUNW_TLSSORTSZ";
2121 case 0x60000018: return "SUNW_CAPINFO";
2122 case 0x60000019: return "SUNW_STRPAD";
2123 case 0x6000001a: return "SUNW_CAPCHAIN";
2124 case 0x6000001b: return "SUNW_LDMACH";
2125 case 0x6000001d: return "SUNW_CAPCHAINENT";
2126 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2127 case 0x60000021: return "SUNW_PARENT";
2128 case 0x60000023: return "SUNW_ASLR";
2129 case 0x60000025: return "SUNW_RELAX";
2130 case 0x60000029: return "SUNW_NXHEAP";
2131 case 0x6000002b: return "SUNW_NXSTACK";
2132
2133 case 0x70000001: return "SPARC_REGISTER";
2134 case 0x7ffffffd: return "AUXILIARY";
2135 case 0x7ffffffe: return "USED";
2136 case 0x7fffffff: return "FILTER";
2137
15f205b1 2138 default: return NULL;
fd85a6a1
NC
2139 }
2140}
2141
252b5132 2142static const char *
dda8d76d 2143get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2144{
e9e44622 2145 static char buff[64];
252b5132
RH
2146
2147 switch (type)
2148 {
2149 case DT_NULL: return "NULL";
2150 case DT_NEEDED: return "NEEDED";
2151 case DT_PLTRELSZ: return "PLTRELSZ";
2152 case DT_PLTGOT: return "PLTGOT";
2153 case DT_HASH: return "HASH";
2154 case DT_STRTAB: return "STRTAB";
2155 case DT_SYMTAB: return "SYMTAB";
2156 case DT_RELA: return "RELA";
2157 case DT_RELASZ: return "RELASZ";
2158 case DT_RELAENT: return "RELAENT";
2159 case DT_STRSZ: return "STRSZ";
2160 case DT_SYMENT: return "SYMENT";
2161 case DT_INIT: return "INIT";
2162 case DT_FINI: return "FINI";
2163 case DT_SONAME: return "SONAME";
2164 case DT_RPATH: return "RPATH";
2165 case DT_SYMBOLIC: return "SYMBOLIC";
2166 case DT_REL: return "REL";
2167 case DT_RELSZ: return "RELSZ";
2168 case DT_RELENT: return "RELENT";
2169 case DT_PLTREL: return "PLTREL";
2170 case DT_DEBUG: return "DEBUG";
2171 case DT_TEXTREL: return "TEXTREL";
2172 case DT_JMPREL: return "JMPREL";
2173 case DT_BIND_NOW: return "BIND_NOW";
2174 case DT_INIT_ARRAY: return "INIT_ARRAY";
2175 case DT_FINI_ARRAY: return "FINI_ARRAY";
2176 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2177 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2178 case DT_RUNPATH: return "RUNPATH";
2179 case DT_FLAGS: return "FLAGS";
2d0e6f43 2180
d1133906
NC
2181 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2182 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2183 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2184
05107a46 2185 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2186 case DT_PLTPADSZ: return "PLTPADSZ";
2187 case DT_MOVEENT: return "MOVEENT";
2188 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2189 case DT_FEATURE: return "FEATURE";
252b5132
RH
2190 case DT_POSFLAG_1: return "POSFLAG_1";
2191 case DT_SYMINSZ: return "SYMINSZ";
2192 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2193
252b5132 2194 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2195 case DT_CONFIG: return "CONFIG";
2196 case DT_DEPAUDIT: return "DEPAUDIT";
2197 case DT_AUDIT: return "AUDIT";
2198 case DT_PLTPAD: return "PLTPAD";
2199 case DT_MOVETAB: return "MOVETAB";
252b5132 2200 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2201
252b5132 2202 case DT_VERSYM: return "VERSYM";
103f02d3 2203
67a4f2b7
AO
2204 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2205 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2206 case DT_RELACOUNT: return "RELACOUNT";
2207 case DT_RELCOUNT: return "RELCOUNT";
2208 case DT_FLAGS_1: return "FLAGS_1";
2209 case DT_VERDEF: return "VERDEF";
2210 case DT_VERDEFNUM: return "VERDEFNUM";
2211 case DT_VERNEED: return "VERNEED";
2212 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2213
019148e4 2214 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2215 case DT_USED: return "USED";
2216 case DT_FILTER: return "FILTER";
103f02d3 2217
047b2264
JJ
2218 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2219 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2220 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2221 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2222 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2223 case DT_GNU_HASH: return "GNU_HASH";
047b2264 2224
252b5132
RH
2225 default:
2226 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2227 {
2cf0635d 2228 const char * result;
103f02d3 2229
dda8d76d 2230 switch (filedata->file_header.e_machine)
252b5132 2231 {
37c18eed
SD
2232 case EM_AARCH64:
2233 result = get_aarch64_dynamic_type (type);
2234 break;
252b5132 2235 case EM_MIPS:
4fe85591 2236 case EM_MIPS_RS3_LE:
252b5132
RH
2237 result = get_mips_dynamic_type (type);
2238 break;
9a097730
RH
2239 case EM_SPARCV9:
2240 result = get_sparc64_dynamic_type (type);
2241 break;
7490d522
AM
2242 case EM_PPC:
2243 result = get_ppc_dynamic_type (type);
2244 break;
f1cb7e17
AM
2245 case EM_PPC64:
2246 result = get_ppc64_dynamic_type (type);
2247 break;
ecc51f48
NC
2248 case EM_IA_64:
2249 result = get_ia64_dynamic_type (type);
2250 break;
fabcb361
RH
2251 case EM_ALPHA:
2252 result = get_alpha_dynamic_type (type);
2253 break;
1c0d3aa6
NC
2254 case EM_SCORE:
2255 result = get_score_dynamic_type (type);
2256 break;
40b36596
JM
2257 case EM_TI_C6000:
2258 result = get_tic6x_dynamic_type (type);
2259 break;
36591ba1
SL
2260 case EM_ALTERA_NIOS2:
2261 result = get_nios2_dynamic_type (type);
2262 break;
252b5132 2263 default:
dda8d76d 2264 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2265 result = get_solaris_dynamic_type (type);
2266 else
2267 result = NULL;
252b5132
RH
2268 break;
2269 }
2270
2271 if (result != NULL)
2272 return result;
2273
e9e44622 2274 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2275 }
eec8f817 2276 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2277 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2278 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2279 {
2cf0635d 2280 const char * result;
103f02d3 2281
dda8d76d 2282 switch (filedata->file_header.e_machine)
103f02d3
UD
2283 {
2284 case EM_PARISC:
2285 result = get_parisc_dynamic_type (type);
2286 break;
148b93f2
NC
2287 case EM_IA_64:
2288 result = get_ia64_dynamic_type (type);
2289 break;
103f02d3 2290 default:
dda8d76d 2291 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2292 result = get_solaris_dynamic_type (type);
2293 else
2294 result = NULL;
103f02d3
UD
2295 break;
2296 }
2297
2298 if (result != NULL)
2299 return result;
2300
e9e44622
JJ
2301 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2302 type);
103f02d3 2303 }
252b5132 2304 else
e9e44622 2305 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2306
252b5132
RH
2307 return buff;
2308 }
2309}
2310
2311static char *
d3ba0551 2312get_file_type (unsigned e_type)
252b5132 2313{
89246a0e 2314 static char buff[64];
252b5132
RH
2315
2316 switch (e_type)
2317 {
32ec8896
NC
2318 case ET_NONE: return _("NONE (None)");
2319 case ET_REL: return _("REL (Relocatable file)");
2320 case ET_EXEC: return _("EXEC (Executable file)");
2321 case ET_DYN: return _("DYN (Shared object file)");
2322 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2323
2324 default:
2325 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2326 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2327 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2328 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2329 else
e9e44622 2330 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2331 return buff;
2332 }
2333}
2334
2335static char *
d3ba0551 2336get_machine_name (unsigned e_machine)
252b5132 2337{
b34976b6 2338 static char buff[64]; /* XXX */
252b5132
RH
2339
2340 switch (e_machine)
2341 {
55e22ca8
NC
2342 /* Please keep this switch table sorted by increasing EM_ value. */
2343 /* 0 */
c45021f2
NC
2344 case EM_NONE: return _("None");
2345 case EM_M32: return "WE32100";
2346 case EM_SPARC: return "Sparc";
2347 case EM_386: return "Intel 80386";
2348 case EM_68K: return "MC68000";
2349 case EM_88K: return "MC88000";
22abe556 2350 case EM_IAMCU: return "Intel MCU";
fb70ec17 2351 case EM_860: return "Intel 80860";
c45021f2
NC
2352 case EM_MIPS: return "MIPS R3000";
2353 case EM_S370: return "IBM System/370";
55e22ca8 2354 /* 10 */
7036c0e1 2355 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2356 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2357 case EM_PARISC: return "HPPA";
55e22ca8 2358 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2359 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2360 case EM_960: return "Intel 80960";
c45021f2 2361 case EM_PPC: return "PowerPC";
55e22ca8 2362 /* 20 */
285d1771 2363 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2364 case EM_S390_OLD:
2365 case EM_S390: return "IBM S/390";
2366 case EM_SPU: return "SPU";
2367 /* 30 */
2368 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2369 case EM_FR20: return "Fujitsu FR20";
2370 case EM_RH32: return "TRW RH32";
b34976b6 2371 case EM_MCORE: return "MCORE";
55e22ca8 2372 /* 40 */
7036c0e1
AJ
2373 case EM_ARM: return "ARM";
2374 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2375 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2376 case EM_SPARCV9: return "Sparc v9";
2377 case EM_TRICORE: return "Siemens Tricore";
584da044 2378 case EM_ARC: return "ARC";
c2dcd04e
NC
2379 case EM_H8_300: return "Renesas H8/300";
2380 case EM_H8_300H: return "Renesas H8/300H";
2381 case EM_H8S: return "Renesas H8S";
2382 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2383 /* 50 */
30800947 2384 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2385 case EM_MIPS_X: return "Stanford MIPS-X";
2386 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2387 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2388 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2389 case EM_PCP: return "Siemens PCP";
2390 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2391 case EM_NDR1: return "Denso NDR1 microprocesspr";
2392 case EM_STARCORE: return "Motorola Star*Core processor";
2393 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2394 /* 60 */
7036c0e1
AJ
2395 case EM_ST100: return "STMicroelectronics ST100 processor";
2396 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2397 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2398 case EM_PDSP: return "Sony DSP processor";
2399 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2400 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2401 case EM_FX66: return "Siemens FX66 microcontroller";
2402 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2403 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2404 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2405 /* 70 */
7036c0e1
AJ
2406 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2407 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2408 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2409 case EM_SVX: return "Silicon Graphics SVx";
2410 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2411 case EM_VAX: return "Digital VAX";
1b61cf92 2412 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2413 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2414 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2415 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2416 /* 80 */
b34976b6 2417 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2418 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2419 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2420 case EM_AVR_OLD:
2421 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2422 case EM_CYGNUS_FR30:
2423 case EM_FR30: return "Fujitsu FR30";
2424 case EM_CYGNUS_D10V:
2425 case EM_D10V: return "d10v";
2426 case EM_CYGNUS_D30V:
2427 case EM_D30V: return "d30v";
2428 case EM_CYGNUS_V850:
2429 case EM_V850: return "Renesas V850";
2430 case EM_CYGNUS_M32R:
2431 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2432 case EM_CYGNUS_MN10300:
2433 case EM_MN10300: return "mn10300";
2434 /* 90 */
2435 case EM_CYGNUS_MN10200:
2436 case EM_MN10200: return "mn10200";
2437 case EM_PJ: return "picoJava";
73589c9d 2438 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2439 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2440 case EM_XTENSA_OLD:
2441 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2442 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2443 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2444 case EM_NS32K: return "National Semiconductor 32000 series";
2445 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2446 case EM_SNP1K: return "Trebia SNP 1000 processor";
2447 /* 100 */
9abca702 2448 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2449 case EM_IP2K_OLD:
2450 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2451 case EM_MAX: return "MAX Processor";
2452 case EM_CR: return "National Semiconductor CompactRISC";
2453 case EM_F2MC16: return "Fujitsu F2MC16";
2454 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2455 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2456 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2457 case EM_SEP: return "Sharp embedded microprocessor";
2458 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2459 /* 110 */
11636f9e
JM
2460 case EM_UNICORE: return "Unicore";
2461 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2462 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2463 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2464 case EM_CRX: return "National Semiconductor CRX microprocessor";
2465 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2466 case EM_C166:
d70c5fc7 2467 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2468 case EM_M16C: return "Renesas M16C series microprocessors";
2469 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2470 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2471 /* 120 */
2472 case EM_M32C: return "Renesas M32c";
2473 /* 130 */
11636f9e
JM
2474 case EM_TSK3000: return "Altium TSK3000 core";
2475 case EM_RS08: return "Freescale RS08 embedded processor";
2476 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2477 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2478 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2479 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2480 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2481 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2482 /* 140 */
11636f9e
JM
2483 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2484 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2485 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2486 case EM_TI_PRU: return "TI PRU I/O processor";
2487 /* 160 */
11636f9e
JM
2488 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2489 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2490 case EM_R32C: return "Renesas R32C series microprocessors";
2491 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2492 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2493 case EM_8051: return "Intel 8051 and variants";
2494 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2495 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2496 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2497 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2498 /* 170 */
11636f9e
JM
2499 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2500 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2501 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2502 case EM_RX: return "Renesas RX";
a3c62988 2503 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2504 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2505 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2506 case EM_CR16:
2507 case EM_MICROBLAZE:
2508 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2509 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2510 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2511 /* 180 */
2512 case EM_L1OM: return "Intel L1OM";
2513 case EM_K1OM: return "Intel K1OM";
2514 case EM_INTEL182: return "Intel (reserved)";
2515 case EM_AARCH64: return "AArch64";
2516 case EM_ARM184: return "ARM (reserved)";
2517 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2518 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2519 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2520 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2521 /* 190 */
11636f9e 2522 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2523 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2524 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2525 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2526 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2527 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2528 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2529 case EM_RL78: return "Renesas RL78";
6d913794 2530 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2531 case EM_78K0R: return "Renesas 78K0R";
2532 /* 200 */
6d913794 2533 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2534 case EM_BA1: return "Beyond BA1 CPU architecture";
2535 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2536 case EM_XCORE: return "XMOS xCORE processor family";
2537 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
55e22ca8 2538 /* 210 */
6d913794
NC
2539 case EM_KM32: return "KM211 KM32 32-bit processor";
2540 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2541 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2542 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2543 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2544 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2545 case EM_COGE: return "Cognitive Smart Memory Processor";
2546 case EM_COOL: return "Bluechip Systems CoolEngine";
2547 case EM_NORC: return "Nanoradio Optimized RISC";
2548 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2549 /* 220 */
15f205b1 2550 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2551 case EM_VISIUM: return "CDS VISIUMcore processor";
2552 case EM_FT32: return "FTDI Chip FT32";
2553 case EM_MOXIE: return "Moxie";
2554 case EM_AMDGPU: return "AMD GPU";
2555 case EM_RISCV: return "RISC-V";
2556 case EM_LANAI: return "Lanai 32-bit processor";
2557 case EM_BPF: return "Linux BPF";
fe944acf 2558 case EM_NFP: return "Netronome Flow Processor";
55e22ca8
NC
2559
2560 /* Large numbers... */
2561 case EM_MT: return "Morpho Techologies MT processor";
2562 case EM_ALPHA: return "Alpha";
2563 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2564 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2565 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2566 case EM_IQ2000: return "Vitesse IQ2000";
2567 case EM_M32C_OLD:
2568 case EM_NIOS32: return "Altera Nios";
2569 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2570 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2571 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2572 case EM_S12Z: return "Freescale S12Z";
b8891f8d 2573 case EM_CSKY: return "C-SKY";
55e22ca8 2574
252b5132 2575 default:
35d9dd2f 2576 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2577 return buff;
2578 }
2579}
2580
a9522a21
AB
2581static void
2582decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2583{
2584 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
2585 other compilers don't a specific architecture type in the e_flags, and
2586 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2587 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2588 architectures.
2589
2590 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2591 but also sets a specific architecture type in the e_flags field.
2592
2593 However, when decoding the flags we don't worry if we see an
2594 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2595 ARCEM architecture type. */
2596
2597 switch (e_flags & EF_ARC_MACH_MSK)
2598 {
2599 /* We only expect these to occur for EM_ARC_COMPACT2. */
2600 case EF_ARC_CPU_ARCV2EM:
2601 strcat (buf, ", ARC EM");
2602 break;
2603 case EF_ARC_CPU_ARCV2HS:
2604 strcat (buf, ", ARC HS");
2605 break;
2606
2607 /* We only expect these to occur for EM_ARC_COMPACT. */
2608 case E_ARC_MACH_ARC600:
2609 strcat (buf, ", ARC600");
2610 break;
2611 case E_ARC_MACH_ARC601:
2612 strcat (buf, ", ARC601");
2613 break;
2614 case E_ARC_MACH_ARC700:
2615 strcat (buf, ", ARC700");
2616 break;
2617
2618 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2619 new ELF with new architecture being read by an old version of
2620 readelf, or (c) An ELF built with non-GNU compiler that does not
2621 set the architecture in the e_flags. */
2622 default:
2623 if (e_machine == EM_ARC_COMPACT)
2624 strcat (buf, ", Unknown ARCompact");
2625 else
2626 strcat (buf, ", Unknown ARC");
2627 break;
2628 }
2629
2630 switch (e_flags & EF_ARC_OSABI_MSK)
2631 {
2632 case E_ARC_OSABI_ORIG:
2633 strcat (buf, ", (ABI:legacy)");
2634 break;
2635 case E_ARC_OSABI_V2:
2636 strcat (buf, ", (ABI:v2)");
2637 break;
2638 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2639 case E_ARC_OSABI_V3:
2640 strcat (buf, ", v3 no-legacy-syscalls ABI");
2641 break;
53a346d8
CZ
2642 case E_ARC_OSABI_V4:
2643 strcat (buf, ", v4 ABI");
2644 break;
a9522a21
AB
2645 default:
2646 strcat (buf, ", unrecognised ARC OSABI flag");
2647 break;
2648 }
2649}
2650
f3485b74 2651static void
d3ba0551 2652decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2653{
2654 unsigned eabi;
32ec8896 2655 bfd_boolean unknown = FALSE;
f3485b74
NC
2656
2657 eabi = EF_ARM_EABI_VERSION (e_flags);
2658 e_flags &= ~ EF_ARM_EABIMASK;
2659
2660 /* Handle "generic" ARM flags. */
2661 if (e_flags & EF_ARM_RELEXEC)
2662 {
2663 strcat (buf, ", relocatable executable");
2664 e_flags &= ~ EF_ARM_RELEXEC;
2665 }
76da6bbe 2666
18a20338
CL
2667 if (e_flags & EF_ARM_PIC)
2668 {
2669 strcat (buf, ", position independent");
2670 e_flags &= ~ EF_ARM_PIC;
2671 }
2672
f3485b74
NC
2673 /* Now handle EABI specific flags. */
2674 switch (eabi)
2675 {
2676 default:
2c71103e 2677 strcat (buf, ", <unrecognized EABI>");
f3485b74 2678 if (e_flags)
32ec8896 2679 unknown = TRUE;
f3485b74
NC
2680 break;
2681
2682 case EF_ARM_EABI_VER1:
a5bcd848 2683 strcat (buf, ", Version1 EABI");
f3485b74
NC
2684 while (e_flags)
2685 {
2686 unsigned flag;
76da6bbe 2687
f3485b74
NC
2688 /* Process flags one bit at a time. */
2689 flag = e_flags & - e_flags;
2690 e_flags &= ~ flag;
76da6bbe 2691
f3485b74
NC
2692 switch (flag)
2693 {
a5bcd848 2694 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2695 strcat (buf, ", sorted symbol tables");
2696 break;
76da6bbe 2697
f3485b74 2698 default:
32ec8896 2699 unknown = TRUE;
f3485b74
NC
2700 break;
2701 }
2702 }
2703 break;
76da6bbe 2704
a5bcd848
PB
2705 case EF_ARM_EABI_VER2:
2706 strcat (buf, ", Version2 EABI");
2707 while (e_flags)
2708 {
2709 unsigned flag;
2710
2711 /* Process flags one bit at a time. */
2712 flag = e_flags & - e_flags;
2713 e_flags &= ~ flag;
2714
2715 switch (flag)
2716 {
2717 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2718 strcat (buf, ", sorted symbol tables");
2719 break;
2720
2721 case EF_ARM_DYNSYMSUSESEGIDX:
2722 strcat (buf, ", dynamic symbols use segment index");
2723 break;
2724
2725 case EF_ARM_MAPSYMSFIRST:
2726 strcat (buf, ", mapping symbols precede others");
2727 break;
2728
2729 default:
32ec8896 2730 unknown = TRUE;
a5bcd848
PB
2731 break;
2732 }
2733 }
2734 break;
2735
d507cf36
PB
2736 case EF_ARM_EABI_VER3:
2737 strcat (buf, ", Version3 EABI");
8cb51566
PB
2738 break;
2739
2740 case EF_ARM_EABI_VER4:
2741 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2742 while (e_flags)
2743 {
2744 unsigned flag;
2745
2746 /* Process flags one bit at a time. */
2747 flag = e_flags & - e_flags;
2748 e_flags &= ~ flag;
2749
2750 switch (flag)
2751 {
2752 case EF_ARM_BE8:
2753 strcat (buf, ", BE8");
2754 break;
2755
2756 case EF_ARM_LE8:
2757 strcat (buf, ", LE8");
2758 break;
2759
2760 default:
32ec8896 2761 unknown = TRUE;
3bfcb652
NC
2762 break;
2763 }
3bfcb652
NC
2764 }
2765 break;
3a4a14e9
PB
2766
2767 case EF_ARM_EABI_VER5:
2768 strcat (buf, ", Version5 EABI");
d507cf36
PB
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
3bfcb652
NC
2787 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2788 strcat (buf, ", soft-float ABI");
2789 break;
2790
2791 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2792 strcat (buf, ", hard-float ABI");
2793 break;
2794
d507cf36 2795 default:
32ec8896 2796 unknown = TRUE;
d507cf36
PB
2797 break;
2798 }
2799 }
2800 break;
2801
f3485b74 2802 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2803 strcat (buf, ", GNU EABI");
f3485b74
NC
2804 while (e_flags)
2805 {
2806 unsigned flag;
76da6bbe 2807
f3485b74
NC
2808 /* Process flags one bit at a time. */
2809 flag = e_flags & - e_flags;
2810 e_flags &= ~ flag;
76da6bbe 2811
f3485b74
NC
2812 switch (flag)
2813 {
a5bcd848 2814 case EF_ARM_INTERWORK:
f3485b74
NC
2815 strcat (buf, ", interworking enabled");
2816 break;
76da6bbe 2817
a5bcd848 2818 case EF_ARM_APCS_26:
f3485b74
NC
2819 strcat (buf, ", uses APCS/26");
2820 break;
76da6bbe 2821
a5bcd848 2822 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2823 strcat (buf, ", uses APCS/float");
2824 break;
76da6bbe 2825
a5bcd848 2826 case EF_ARM_PIC:
f3485b74
NC
2827 strcat (buf, ", position independent");
2828 break;
76da6bbe 2829
a5bcd848 2830 case EF_ARM_ALIGN8:
f3485b74
NC
2831 strcat (buf, ", 8 bit structure alignment");
2832 break;
76da6bbe 2833
a5bcd848 2834 case EF_ARM_NEW_ABI:
f3485b74
NC
2835 strcat (buf, ", uses new ABI");
2836 break;
76da6bbe 2837
a5bcd848 2838 case EF_ARM_OLD_ABI:
f3485b74
NC
2839 strcat (buf, ", uses old ABI");
2840 break;
76da6bbe 2841
a5bcd848 2842 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2843 strcat (buf, ", software FP");
2844 break;
76da6bbe 2845
90e01f86
ILT
2846 case EF_ARM_VFP_FLOAT:
2847 strcat (buf, ", VFP");
2848 break;
2849
fde78edd
NC
2850 case EF_ARM_MAVERICK_FLOAT:
2851 strcat (buf, ", Maverick FP");
2852 break;
2853
f3485b74 2854 default:
32ec8896 2855 unknown = TRUE;
f3485b74
NC
2856 break;
2857 }
2858 }
2859 }
f3485b74
NC
2860
2861 if (unknown)
2b692964 2862 strcat (buf,_(", <unknown>"));
f3485b74
NC
2863}
2864
343433df
AB
2865static void
2866decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2867{
2868 --size; /* Leave space for null terminator. */
2869
2870 switch (e_flags & EF_AVR_MACH)
2871 {
2872 case E_AVR_MACH_AVR1:
2873 strncat (buf, ", avr:1", size);
2874 break;
2875 case E_AVR_MACH_AVR2:
2876 strncat (buf, ", avr:2", size);
2877 break;
2878 case E_AVR_MACH_AVR25:
2879 strncat (buf, ", avr:25", size);
2880 break;
2881 case E_AVR_MACH_AVR3:
2882 strncat (buf, ", avr:3", size);
2883 break;
2884 case E_AVR_MACH_AVR31:
2885 strncat (buf, ", avr:31", size);
2886 break;
2887 case E_AVR_MACH_AVR35:
2888 strncat (buf, ", avr:35", size);
2889 break;
2890 case E_AVR_MACH_AVR4:
2891 strncat (buf, ", avr:4", size);
2892 break;
2893 case E_AVR_MACH_AVR5:
2894 strncat (buf, ", avr:5", size);
2895 break;
2896 case E_AVR_MACH_AVR51:
2897 strncat (buf, ", avr:51", size);
2898 break;
2899 case E_AVR_MACH_AVR6:
2900 strncat (buf, ", avr:6", size);
2901 break;
2902 case E_AVR_MACH_AVRTINY:
2903 strncat (buf, ", avr:100", size);
2904 break;
2905 case E_AVR_MACH_XMEGA1:
2906 strncat (buf, ", avr:101", size);
2907 break;
2908 case E_AVR_MACH_XMEGA2:
2909 strncat (buf, ", avr:102", size);
2910 break;
2911 case E_AVR_MACH_XMEGA3:
2912 strncat (buf, ", avr:103", size);
2913 break;
2914 case E_AVR_MACH_XMEGA4:
2915 strncat (buf, ", avr:104", size);
2916 break;
2917 case E_AVR_MACH_XMEGA5:
2918 strncat (buf, ", avr:105", size);
2919 break;
2920 case E_AVR_MACH_XMEGA6:
2921 strncat (buf, ", avr:106", size);
2922 break;
2923 case E_AVR_MACH_XMEGA7:
2924 strncat (buf, ", avr:107", size);
2925 break;
2926 default:
2927 strncat (buf, ", avr:<unknown>", size);
2928 break;
2929 }
2930
2931 size -= strlen (buf);
2932 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2933 strncat (buf, ", link-relax", size);
2934}
2935
35c08157
KLC
2936static void
2937decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2938{
2939 unsigned abi;
2940 unsigned arch;
2941 unsigned config;
2942 unsigned version;
32ec8896
NC
2943 bfd_boolean has_fpu = FALSE;
2944 unsigned int r = 0;
35c08157
KLC
2945
2946 static const char *ABI_STRINGS[] =
2947 {
2948 "ABI v0", /* use r5 as return register; only used in N1213HC */
2949 "ABI v1", /* use r0 as return register */
2950 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2951 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2952 "AABI",
2953 "ABI2 FP+"
35c08157
KLC
2954 };
2955 static const char *VER_STRINGS[] =
2956 {
2957 "Andes ELF V1.3 or older",
2958 "Andes ELF V1.3.1",
2959 "Andes ELF V1.4"
2960 };
2961 static const char *ARCH_STRINGS[] =
2962 {
2963 "",
2964 "Andes Star v1.0",
2965 "Andes Star v2.0",
2966 "Andes Star v3.0",
2967 "Andes Star v3.0m"
2968 };
2969
2970 abi = EF_NDS_ABI & e_flags;
2971 arch = EF_NDS_ARCH & e_flags;
2972 config = EF_NDS_INST & e_flags;
2973 version = EF_NDS32_ELF_VERSION & e_flags;
2974
2975 memset (buf, 0, size);
2976
2977 switch (abi)
2978 {
2979 case E_NDS_ABI_V0:
2980 case E_NDS_ABI_V1:
2981 case E_NDS_ABI_V2:
2982 case E_NDS_ABI_V2FP:
2983 case E_NDS_ABI_AABI:
40c7a7cb 2984 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2985 /* In case there are holes in the array. */
2986 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2987 break;
2988
2989 default:
2990 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2991 break;
2992 }
2993
2994 switch (version)
2995 {
2996 case E_NDS32_ELF_VER_1_2:
2997 case E_NDS32_ELF_VER_1_3:
2998 case E_NDS32_ELF_VER_1_4:
2999 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3000 break;
3001
3002 default:
3003 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3004 break;
3005 }
3006
3007 if (E_NDS_ABI_V0 == abi)
3008 {
3009 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3010 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3011 if (arch == E_NDS_ARCH_STAR_V1_0)
3012 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3013 return;
3014 }
3015
3016 switch (arch)
3017 {
3018 case E_NDS_ARCH_STAR_V1_0:
3019 case E_NDS_ARCH_STAR_V2_0:
3020 case E_NDS_ARCH_STAR_V3_0:
3021 case E_NDS_ARCH_STAR_V3_M:
3022 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3023 break;
3024
3025 default:
3026 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3027 /* ARCH version determines how the e_flags are interpreted.
3028 If it is unknown, we cannot proceed. */
3029 return;
3030 }
3031
3032 /* Newer ABI; Now handle architecture specific flags. */
3033 if (arch == E_NDS_ARCH_STAR_V1_0)
3034 {
3035 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3036 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3037
3038 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3039 r += snprintf (buf + r, size -r, ", MAC");
3040
3041 if (config & E_NDS32_HAS_DIV_INST)
3042 r += snprintf (buf + r, size -r, ", DIV");
3043
3044 if (config & E_NDS32_HAS_16BIT_INST)
3045 r += snprintf (buf + r, size -r, ", 16b");
3046 }
3047 else
3048 {
3049 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3050 {
3051 if (version <= E_NDS32_ELF_VER_1_3)
3052 r += snprintf (buf + r, size -r, ", [B8]");
3053 else
3054 r += snprintf (buf + r, size -r, ", EX9");
3055 }
3056
3057 if (config & E_NDS32_HAS_MAC_DX_INST)
3058 r += snprintf (buf + r, size -r, ", MAC_DX");
3059
3060 if (config & E_NDS32_HAS_DIV_DX_INST)
3061 r += snprintf (buf + r, size -r, ", DIV_DX");
3062
3063 if (config & E_NDS32_HAS_16BIT_INST)
3064 {
3065 if (version <= E_NDS32_ELF_VER_1_3)
3066 r += snprintf (buf + r, size -r, ", 16b");
3067 else
3068 r += snprintf (buf + r, size -r, ", IFC");
3069 }
3070 }
3071
3072 if (config & E_NDS32_HAS_EXT_INST)
3073 r += snprintf (buf + r, size -r, ", PERF1");
3074
3075 if (config & E_NDS32_HAS_EXT2_INST)
3076 r += snprintf (buf + r, size -r, ", PERF2");
3077
3078 if (config & E_NDS32_HAS_FPU_INST)
3079 {
32ec8896 3080 has_fpu = TRUE;
35c08157
KLC
3081 r += snprintf (buf + r, size -r, ", FPU_SP");
3082 }
3083
3084 if (config & E_NDS32_HAS_FPU_DP_INST)
3085 {
32ec8896 3086 has_fpu = TRUE;
35c08157
KLC
3087 r += snprintf (buf + r, size -r, ", FPU_DP");
3088 }
3089
3090 if (config & E_NDS32_HAS_FPU_MAC_INST)
3091 {
32ec8896 3092 has_fpu = TRUE;
35c08157
KLC
3093 r += snprintf (buf + r, size -r, ", FPU_MAC");
3094 }
3095
3096 if (has_fpu)
3097 {
3098 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3099 {
3100 case E_NDS32_FPU_REG_8SP_4DP:
3101 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3102 break;
3103 case E_NDS32_FPU_REG_16SP_8DP:
3104 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3105 break;
3106 case E_NDS32_FPU_REG_32SP_16DP:
3107 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3108 break;
3109 case E_NDS32_FPU_REG_32SP_32DP:
3110 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3111 break;
3112 }
3113 }
3114
3115 if (config & E_NDS32_HAS_AUDIO_INST)
3116 r += snprintf (buf + r, size -r, ", AUDIO");
3117
3118 if (config & E_NDS32_HAS_STRING_INST)
3119 r += snprintf (buf + r, size -r, ", STR");
3120
3121 if (config & E_NDS32_HAS_REDUCED_REGS)
3122 r += snprintf (buf + r, size -r, ", 16REG");
3123
3124 if (config & E_NDS32_HAS_VIDEO_INST)
3125 {
3126 if (version <= E_NDS32_ELF_VER_1_3)
3127 r += snprintf (buf + r, size -r, ", VIDEO");
3128 else
3129 r += snprintf (buf + r, size -r, ", SATURATION");
3130 }
3131
3132 if (config & E_NDS32_HAS_ENCRIPT_INST)
3133 r += snprintf (buf + r, size -r, ", ENCRP");
3134
3135 if (config & E_NDS32_HAS_L2C_INST)
3136 r += snprintf (buf + r, size -r, ", L2C");
3137}
3138
252b5132 3139static char *
dda8d76d 3140get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3141{
b34976b6 3142 static char buf[1024];
252b5132
RH
3143
3144 buf[0] = '\0';
76da6bbe 3145
252b5132
RH
3146 if (e_flags)
3147 {
3148 switch (e_machine)
3149 {
3150 default:
3151 break;
3152
886a2506 3153 case EM_ARC_COMPACT2:
886a2506 3154 case EM_ARC_COMPACT:
a9522a21
AB
3155 decode_ARC_machine_flags (e_flags, e_machine, buf);
3156 break;
886a2506 3157
f3485b74
NC
3158 case EM_ARM:
3159 decode_ARM_machine_flags (e_flags, buf);
3160 break;
76da6bbe 3161
343433df
AB
3162 case EM_AVR:
3163 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3164 break;
3165
781303ce
MF
3166 case EM_BLACKFIN:
3167 if (e_flags & EF_BFIN_PIC)
3168 strcat (buf, ", PIC");
3169
3170 if (e_flags & EF_BFIN_FDPIC)
3171 strcat (buf, ", FDPIC");
3172
3173 if (e_flags & EF_BFIN_CODE_IN_L1)
3174 strcat (buf, ", code in L1");
3175
3176 if (e_flags & EF_BFIN_DATA_IN_L1)
3177 strcat (buf, ", data in L1");
3178
3179 break;
3180
ec2dfb42
AO
3181 case EM_CYGNUS_FRV:
3182 switch (e_flags & EF_FRV_CPU_MASK)
3183 {
3184 case EF_FRV_CPU_GENERIC:
3185 break;
3186
3187 default:
3188 strcat (buf, ", fr???");
3189 break;
57346661 3190
ec2dfb42
AO
3191 case EF_FRV_CPU_FR300:
3192 strcat (buf, ", fr300");
3193 break;
3194
3195 case EF_FRV_CPU_FR400:
3196 strcat (buf, ", fr400");
3197 break;
3198 case EF_FRV_CPU_FR405:
3199 strcat (buf, ", fr405");
3200 break;
3201
3202 case EF_FRV_CPU_FR450:
3203 strcat (buf, ", fr450");
3204 break;
3205
3206 case EF_FRV_CPU_FR500:
3207 strcat (buf, ", fr500");
3208 break;
3209 case EF_FRV_CPU_FR550:
3210 strcat (buf, ", fr550");
3211 break;
3212
3213 case EF_FRV_CPU_SIMPLE:
3214 strcat (buf, ", simple");
3215 break;
3216 case EF_FRV_CPU_TOMCAT:
3217 strcat (buf, ", tomcat");
3218 break;
3219 }
1c877e87 3220 break;
ec2dfb42 3221
53c7db4b 3222 case EM_68K:
425c6cb0 3223 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3224 strcat (buf, ", m68000");
425c6cb0 3225 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3226 strcat (buf, ", cpu32");
3227 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3228 strcat (buf, ", fido_a");
425c6cb0 3229 else
266abb8f 3230 {
2cf0635d
NC
3231 char const * isa = _("unknown");
3232 char const * mac = _("unknown mac");
3233 char const * additional = NULL;
0112cd26 3234
c694fd50 3235 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3236 {
c694fd50 3237 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3238 isa = "A";
3239 additional = ", nodiv";
3240 break;
c694fd50 3241 case EF_M68K_CF_ISA_A:
266abb8f
NS
3242 isa = "A";
3243 break;
c694fd50 3244 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3245 isa = "A+";
3246 break;
c694fd50 3247 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3248 isa = "B";
3249 additional = ", nousp";
3250 break;
c694fd50 3251 case EF_M68K_CF_ISA_B:
266abb8f
NS
3252 isa = "B";
3253 break;
f608cd77
NS
3254 case EF_M68K_CF_ISA_C:
3255 isa = "C";
3256 break;
3257 case EF_M68K_CF_ISA_C_NODIV:
3258 isa = "C";
3259 additional = ", nodiv";
3260 break;
266abb8f
NS
3261 }
3262 strcat (buf, ", cf, isa ");
3263 strcat (buf, isa);
0b2e31dc
NS
3264 if (additional)
3265 strcat (buf, additional);
c694fd50 3266 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3267 strcat (buf, ", float");
c694fd50 3268 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3269 {
3270 case 0:
3271 mac = NULL;
3272 break;
c694fd50 3273 case EF_M68K_CF_MAC:
266abb8f
NS
3274 mac = "mac";
3275 break;
c694fd50 3276 case EF_M68K_CF_EMAC:
266abb8f
NS
3277 mac = "emac";
3278 break;
f608cd77
NS
3279 case EF_M68K_CF_EMAC_B:
3280 mac = "emac_b";
3281 break;
266abb8f
NS
3282 }
3283 if (mac)
3284 {
3285 strcat (buf, ", ");
3286 strcat (buf, mac);
3287 }
266abb8f 3288 }
53c7db4b 3289 break;
33c63f9d 3290
153a2776
NC
3291 case EM_CYGNUS_MEP:
3292 switch (e_flags & EF_MEP_CPU_MASK)
3293 {
3294 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3295 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3296 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3297 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3298 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3299 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3300 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3301 }
3302
3303 switch (e_flags & EF_MEP_COP_MASK)
3304 {
3305 case EF_MEP_COP_NONE: break;
3306 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3307 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3308 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3309 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3310 default: strcat (buf, _("<unknown MeP copro type>")); break;
3311 }
3312
3313 if (e_flags & EF_MEP_LIBRARY)
3314 strcat (buf, ", Built for Library");
3315
3316 if (e_flags & EF_MEP_INDEX_MASK)
3317 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3318 e_flags & EF_MEP_INDEX_MASK);
3319
3320 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3321 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3322 e_flags & ~ EF_MEP_ALL_FLAGS);
3323 break;
3324
252b5132
RH
3325 case EM_PPC:
3326 if (e_flags & EF_PPC_EMB)
3327 strcat (buf, ", emb");
3328
3329 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3330 strcat (buf, _(", relocatable"));
252b5132
RH
3331
3332 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3333 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3334 break;
3335
ee67d69a
AM
3336 case EM_PPC64:
3337 if (e_flags & EF_PPC64_ABI)
3338 {
3339 char abi[] = ", abiv0";
3340
3341 abi[6] += e_flags & EF_PPC64_ABI;
3342 strcat (buf, abi);
3343 }
3344 break;
3345
708e2187
NC
3346 case EM_V800:
3347 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3348 strcat (buf, ", RH850 ABI");
0b4362b0 3349
708e2187
NC
3350 if (e_flags & EF_V800_850E3)
3351 strcat (buf, ", V3 architecture");
3352
3353 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3354 strcat (buf, ", FPU not used");
3355
3356 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3357 strcat (buf, ", regmode: COMMON");
3358
3359 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3360 strcat (buf, ", r4 not used");
3361
3362 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3363 strcat (buf, ", r30 not used");
3364
3365 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3366 strcat (buf, ", r5 not used");
3367
3368 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3369 strcat (buf, ", r2 not used");
3370
3371 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3372 {
3373 switch (e_flags & - e_flags)
3374 {
3375 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3376 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3377 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3378 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3379 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3380 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3381 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3382 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3383 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3384 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3385 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3386 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3387 default: break;
3388 }
3389 }
3390 break;
3391
2b0337b0 3392 case EM_V850:
252b5132
RH
3393 case EM_CYGNUS_V850:
3394 switch (e_flags & EF_V850_ARCH)
3395 {
78c8d46c
NC
3396 case E_V850E3V5_ARCH:
3397 strcat (buf, ", v850e3v5");
3398 break;
1cd986c5
NC
3399 case E_V850E2V3_ARCH:
3400 strcat (buf, ", v850e2v3");
3401 break;
3402 case E_V850E2_ARCH:
3403 strcat (buf, ", v850e2");
3404 break;
3405 case E_V850E1_ARCH:
3406 strcat (buf, ", v850e1");
8ad30312 3407 break;
252b5132
RH
3408 case E_V850E_ARCH:
3409 strcat (buf, ", v850e");
3410 break;
252b5132
RH
3411 case E_V850_ARCH:
3412 strcat (buf, ", v850");
3413 break;
3414 default:
2b692964 3415 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3416 break;
3417 }
3418 break;
3419
2b0337b0 3420 case EM_M32R:
252b5132
RH
3421 case EM_CYGNUS_M32R:
3422 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3423 strcat (buf, ", m32r");
252b5132
RH
3424 break;
3425
3426 case EM_MIPS:
4fe85591 3427 case EM_MIPS_RS3_LE:
252b5132
RH
3428 if (e_flags & EF_MIPS_NOREORDER)
3429 strcat (buf, ", noreorder");
3430
3431 if (e_flags & EF_MIPS_PIC)
3432 strcat (buf, ", pic");
3433
3434 if (e_flags & EF_MIPS_CPIC)
3435 strcat (buf, ", cpic");
3436
d1bdd336
TS
3437 if (e_flags & EF_MIPS_UCODE)
3438 strcat (buf, ", ugen_reserved");
3439
252b5132
RH
3440 if (e_flags & EF_MIPS_ABI2)
3441 strcat (buf, ", abi2");
3442
43521d43
TS
3443 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3444 strcat (buf, ", odk first");
3445
a5d22d2a
TS
3446 if (e_flags & EF_MIPS_32BITMODE)
3447 strcat (buf, ", 32bitmode");
3448
ba92f887
MR
3449 if (e_flags & EF_MIPS_NAN2008)
3450 strcat (buf, ", nan2008");
3451
fef1b0b3
SE
3452 if (e_flags & EF_MIPS_FP64)
3453 strcat (buf, ", fp64");
3454
156c2f8b
NC
3455 switch ((e_flags & EF_MIPS_MACH))
3456 {
3457 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3458 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3459 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3460 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3461 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3462 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3463 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3464 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3465 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3466 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3467 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3468 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3469 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3470 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3471 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3472 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3473 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3474 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3475 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3476 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3477 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3478 case 0:
3479 /* We simply ignore the field in this case to avoid confusion:
3480 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3481 extension. */
3482 break;
2b692964 3483 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3484 }
43521d43
TS
3485
3486 switch ((e_flags & EF_MIPS_ABI))
3487 {
3488 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3489 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3490 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3491 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3492 case 0:
3493 /* We simply ignore the field in this case to avoid confusion:
3494 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3495 This means it is likely to be an o32 file, but not for
3496 sure. */
3497 break;
2b692964 3498 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3499 }
3500
3501 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3502 strcat (buf, ", mdmx");
3503
3504 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3505 strcat (buf, ", mips16");
3506
df58fc94
RS
3507 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3508 strcat (buf, ", micromips");
3509
43521d43
TS
3510 switch ((e_flags & EF_MIPS_ARCH))
3511 {
3512 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3513 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3514 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3515 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3516 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3517 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3518 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3519 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3520 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3521 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3522 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3523 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3524 }
252b5132 3525 break;
351b4b40 3526
35c08157
KLC
3527 case EM_NDS32:
3528 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3529 break;
3530
fe944acf
FT
3531 case EM_NFP:
3532 switch (EF_NFP_MACH (e_flags))
3533 {
3534 case E_NFP_MACH_3200:
3535 strcat (buf, ", NFP-32xx");
3536 break;
3537 case E_NFP_MACH_6000:
3538 strcat (buf, ", NFP-6xxx");
3539 break;
3540 }
3541 break;
3542
e23eba97
NC
3543 case EM_RISCV:
3544 if (e_flags & EF_RISCV_RVC)
3545 strcat (buf, ", RVC");
2922d21d 3546
7f999549
JW
3547 if (e_flags & EF_RISCV_RVE)
3548 strcat (buf, ", RVE");
3549
2922d21d
AW
3550 switch (e_flags & EF_RISCV_FLOAT_ABI)
3551 {
3552 case EF_RISCV_FLOAT_ABI_SOFT:
3553 strcat (buf, ", soft-float ABI");
3554 break;
3555
3556 case EF_RISCV_FLOAT_ABI_SINGLE:
3557 strcat (buf, ", single-float ABI");
3558 break;
3559
3560 case EF_RISCV_FLOAT_ABI_DOUBLE:
3561 strcat (buf, ", double-float ABI");
3562 break;
3563
3564 case EF_RISCV_FLOAT_ABI_QUAD:
3565 strcat (buf, ", quad-float ABI");
3566 break;
3567 }
e23eba97
NC
3568 break;
3569
ccde1100
AO
3570 case EM_SH:
3571 switch ((e_flags & EF_SH_MACH_MASK))
3572 {
3573 case EF_SH1: strcat (buf, ", sh1"); break;
3574 case EF_SH2: strcat (buf, ", sh2"); break;
3575 case EF_SH3: strcat (buf, ", sh3"); break;
3576 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3577 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3578 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3579 case EF_SH3E: strcat (buf, ", sh3e"); break;
3580 case EF_SH4: strcat (buf, ", sh4"); break;
3581 case EF_SH5: strcat (buf, ", sh5"); break;
3582 case EF_SH2E: strcat (buf, ", sh2e"); break;
3583 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3584 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3585 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3586 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3587 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3588 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3589 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3590 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3591 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3592 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3593 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3594 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3595 }
3596
cec6a5b8
MR
3597 if (e_flags & EF_SH_PIC)
3598 strcat (buf, ", pic");
3599
3600 if (e_flags & EF_SH_FDPIC)
3601 strcat (buf, ", fdpic");
ccde1100 3602 break;
948f632f 3603
73589c9d
CS
3604 case EM_OR1K:
3605 if (e_flags & EF_OR1K_NODELAY)
3606 strcat (buf, ", no delay");
3607 break;
57346661 3608
351b4b40
RH
3609 case EM_SPARCV9:
3610 if (e_flags & EF_SPARC_32PLUS)
3611 strcat (buf, ", v8+");
3612
3613 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3614 strcat (buf, ", ultrasparcI");
3615
3616 if (e_flags & EF_SPARC_SUN_US3)
3617 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3618
3619 if (e_flags & EF_SPARC_HAL_R1)
3620 strcat (buf, ", halr1");
3621
3622 if (e_flags & EF_SPARC_LEDATA)
3623 strcat (buf, ", ledata");
3624
3625 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3626 strcat (buf, ", tso");
3627
3628 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3629 strcat (buf, ", pso");
3630
3631 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3632 strcat (buf, ", rmo");
3633 break;
7d466069 3634
103f02d3
UD
3635 case EM_PARISC:
3636 switch (e_flags & EF_PARISC_ARCH)
3637 {
3638 case EFA_PARISC_1_0:
3639 strcpy (buf, ", PA-RISC 1.0");
3640 break;
3641 case EFA_PARISC_1_1:
3642 strcpy (buf, ", PA-RISC 1.1");
3643 break;
3644 case EFA_PARISC_2_0:
3645 strcpy (buf, ", PA-RISC 2.0");
3646 break;
3647 default:
3648 break;
3649 }
3650 if (e_flags & EF_PARISC_TRAPNIL)
3651 strcat (buf, ", trapnil");
3652 if (e_flags & EF_PARISC_EXT)
3653 strcat (buf, ", ext");
3654 if (e_flags & EF_PARISC_LSB)
3655 strcat (buf, ", lsb");
3656 if (e_flags & EF_PARISC_WIDE)
3657 strcat (buf, ", wide");
3658 if (e_flags & EF_PARISC_NO_KABP)
3659 strcat (buf, ", no kabp");
3660 if (e_flags & EF_PARISC_LAZYSWAP)
3661 strcat (buf, ", lazyswap");
30800947 3662 break;
76da6bbe 3663
7d466069 3664 case EM_PJ:
2b0337b0 3665 case EM_PJ_OLD:
7d466069
ILT
3666 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3667 strcat (buf, ", new calling convention");
3668
3669 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3670 strcat (buf, ", gnu calling convention");
3671 break;
4d6ed7c8
NC
3672
3673 case EM_IA_64:
3674 if ((e_flags & EF_IA_64_ABI64))
3675 strcat (buf, ", 64-bit");
3676 else
3677 strcat (buf, ", 32-bit");
3678 if ((e_flags & EF_IA_64_REDUCEDFP))
3679 strcat (buf, ", reduced fp model");
3680 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3681 strcat (buf, ", no function descriptors, constant gp");
3682 else if ((e_flags & EF_IA_64_CONS_GP))
3683 strcat (buf, ", constant gp");
3684 if ((e_flags & EF_IA_64_ABSOLUTE))
3685 strcat (buf, ", absolute");
dda8d76d 3686 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3687 {
3688 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3689 strcat (buf, ", vms_linkages");
3690 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3691 {
3692 case EF_IA_64_VMS_COMCOD_SUCCESS:
3693 break;
3694 case EF_IA_64_VMS_COMCOD_WARNING:
3695 strcat (buf, ", warning");
3696 break;
3697 case EF_IA_64_VMS_COMCOD_ERROR:
3698 strcat (buf, ", error");
3699 break;
3700 case EF_IA_64_VMS_COMCOD_ABORT:
3701 strcat (buf, ", abort");
3702 break;
3703 default:
bee0ee85
NC
3704 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3705 e_flags & EF_IA_64_VMS_COMCOD);
3706 strcat (buf, ", <unknown>");
28f997cf
TG
3707 }
3708 }
4d6ed7c8 3709 break;
179d3252
JT
3710
3711 case EM_VAX:
3712 if ((e_flags & EF_VAX_NONPIC))
3713 strcat (buf, ", non-PIC");
3714 if ((e_flags & EF_VAX_DFLOAT))
3715 strcat (buf, ", D-Float");
3716 if ((e_flags & EF_VAX_GFLOAT))
3717 strcat (buf, ", G-Float");
3718 break;
c7927a3c 3719
619ed720
EB
3720 case EM_VISIUM:
3721 if (e_flags & EF_VISIUM_ARCH_MCM)
3722 strcat (buf, ", mcm");
3723 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3724 strcat (buf, ", mcm24");
3725 if (e_flags & EF_VISIUM_ARCH_GR6)
3726 strcat (buf, ", gr6");
3727 break;
3728
4046d87a 3729 case EM_RL78:
1740ba0c
NC
3730 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3731 {
3732 case E_FLAG_RL78_ANY_CPU: break;
3733 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3734 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3735 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3736 }
856ea05c
KP
3737 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3738 strcat (buf, ", 64-bit doubles");
4046d87a 3739 break;
0b4362b0 3740
c7927a3c
NC
3741 case EM_RX:
3742 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3743 strcat (buf, ", 64-bit doubles");
3744 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3745 strcat (buf, ", dsp");
d4cb0ea0 3746 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3747 strcat (buf, ", pid");
708e2187
NC
3748 if (e_flags & E_FLAG_RX_ABI)
3749 strcat (buf, ", RX ABI");
3525236c
NC
3750 if (e_flags & E_FLAG_RX_SINSNS_SET)
3751 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3752 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3753 if (e_flags & E_FLAG_RX_V2)
3754 strcat (buf, ", V2");
f87673e0
YS
3755 if (e_flags & E_FLAG_RX_V3)
3756 strcat (buf, ", V3");
d4cb0ea0 3757 break;
55786da2
AK
3758
3759 case EM_S390:
3760 if (e_flags & EF_S390_HIGH_GPRS)
3761 strcat (buf, ", highgprs");
d4cb0ea0 3762 break;
40b36596
JM
3763
3764 case EM_TI_C6000:
3765 if ((e_flags & EF_C6000_REL))
3766 strcat (buf, ", relocatable module");
d4cb0ea0 3767 break;
13761a11
NC
3768
3769 case EM_MSP430:
3770 strcat (buf, _(": architecture variant: "));
3771 switch (e_flags & EF_MSP430_MACH)
3772 {
3773 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3774 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3775 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3776 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3777 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3778 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3779 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3780 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3781 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3782 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3783 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3784 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3785 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3786 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3787 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3788 default:
3789 strcat (buf, _(": unknown")); break;
3790 }
3791
3792 if (e_flags & ~ EF_MSP430_MACH)
3793 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
3794 break;
3795
3796 case EM_Z80:
3797 switch (e_flags & EF_Z80_MACH_MSK)
3798 {
3799 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
3800 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
3801 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
3802 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
3803 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
3804 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 3805 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
3806 default:
3807 strcat (buf, _(", unknown")); break;
3808 }
3809 break;
252b5132
RH
3810 }
3811 }
3812
3813 return buf;
3814}
3815
252b5132 3816static const char *
dda8d76d 3817get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3818{
3819 static char buff[32];
3820
3821 switch (osabi)
3822 {
3823 case ELFOSABI_NONE: return "UNIX - System V";
3824 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3825 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3826 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3827 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3828 case ELFOSABI_AIX: return "UNIX - AIX";
3829 case ELFOSABI_IRIX: return "UNIX - IRIX";
3830 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3831 case ELFOSABI_TRU64: return "UNIX - TRU64";
3832 case ELFOSABI_MODESTO: return "Novell - Modesto";
3833 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3834 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3835 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3836 case ELFOSABI_AROS: return "AROS";
11636f9e 3837 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3838 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3839 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3840 default:
40b36596 3841 if (osabi >= 64)
dda8d76d 3842 switch (filedata->file_header.e_machine)
40b36596
JM
3843 {
3844 case EM_ARM:
3845 switch (osabi)
3846 {
3847 case ELFOSABI_ARM: return "ARM";
18a20338 3848 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3849 default:
3850 break;
3851 }
3852 break;
3853
3854 case EM_MSP430:
3855 case EM_MSP430_OLD:
619ed720 3856 case EM_VISIUM:
40b36596
JM
3857 switch (osabi)
3858 {
3859 case ELFOSABI_STANDALONE: return _("Standalone App");
3860 default:
3861 break;
3862 }
3863 break;
3864
3865 case EM_TI_C6000:
3866 switch (osabi)
3867 {
3868 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3869 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3870 default:
3871 break;
3872 }
3873 break;
3874
3875 default:
3876 break;
3877 }
e9e44622 3878 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3879 return buff;
3880 }
3881}
3882
a06ea964
NC
3883static const char *
3884get_aarch64_segment_type (unsigned long type)
3885{
3886 switch (type)
3887 {
32ec8896
NC
3888 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3889 default: return NULL;
a06ea964 3890 }
a06ea964
NC
3891}
3892
b294bdf8
MM
3893static const char *
3894get_arm_segment_type (unsigned long type)
3895{
3896 switch (type)
3897 {
32ec8896
NC
3898 case PT_ARM_EXIDX: return "EXIDX";
3899 default: return NULL;
b294bdf8 3900 }
b294bdf8
MM
3901}
3902
b4cbbe8f
AK
3903static const char *
3904get_s390_segment_type (unsigned long type)
3905{
3906 switch (type)
3907 {
3908 case PT_S390_PGSTE: return "S390_PGSTE";
3909 default: return NULL;
3910 }
3911}
3912
d3ba0551
AM
3913static const char *
3914get_mips_segment_type (unsigned long type)
252b5132
RH
3915{
3916 switch (type)
3917 {
32ec8896
NC
3918 case PT_MIPS_REGINFO: return "REGINFO";
3919 case PT_MIPS_RTPROC: return "RTPROC";
3920 case PT_MIPS_OPTIONS: return "OPTIONS";
3921 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3922 default: return NULL;
252b5132 3923 }
252b5132
RH
3924}
3925
103f02d3 3926static const char *
d3ba0551 3927get_parisc_segment_type (unsigned long type)
103f02d3
UD
3928{
3929 switch (type)
3930 {
103f02d3
UD
3931 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3932 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3933 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3934 default: return NULL;
103f02d3 3935 }
103f02d3
UD
3936}
3937
4d6ed7c8 3938static const char *
d3ba0551 3939get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3940{
3941 switch (type)
3942 {
3943 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3944 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 3945 default: return NULL;
4d6ed7c8 3946 }
4d6ed7c8
NC
3947}
3948
40b36596
JM
3949static const char *
3950get_tic6x_segment_type (unsigned long type)
3951{
3952 switch (type)
3953 {
32ec8896
NC
3954 case PT_C6000_PHATTR: return "C6000_PHATTR";
3955 default: return NULL;
40b36596 3956 }
40b36596
JM
3957}
3958
df3a023b
AM
3959static const char *
3960get_hpux_segment_type (unsigned long type, unsigned e_machine)
3961{
3962 if (e_machine == EM_PARISC)
3963 switch (type)
3964 {
3965 case PT_HP_TLS: return "HP_TLS";
3966 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3967 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3968 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3969 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3970 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3971 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3972 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3973 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3974 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3975 case PT_HP_PARALLEL: return "HP_PARALLEL";
3976 case PT_HP_FASTBIND: return "HP_FASTBIND";
3977 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3978 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3979 case PT_HP_STACK: return "HP_STACK";
3980 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
3981 default: return NULL;
3982 }
3983
3984 if (e_machine == EM_IA_64)
3985 switch (type)
3986 {
3987 case PT_HP_TLS: return "HP_TLS";
3988 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3989 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3990 case PT_IA_64_HP_STACK: return "HP_STACK";
3991 default: return NULL;
3992 }
3993
3994 return NULL;
3995}
3996
5522f910
NC
3997static const char *
3998get_solaris_segment_type (unsigned long type)
3999{
4000 switch (type)
4001 {
4002 case 0x6464e550: return "PT_SUNW_UNWIND";
4003 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4004 case 0x6ffffff7: return "PT_LOSUNW";
4005 case 0x6ffffffa: return "PT_SUNWBSS";
4006 case 0x6ffffffb: return "PT_SUNWSTACK";
4007 case 0x6ffffffc: return "PT_SUNWDTRACE";
4008 case 0x6ffffffd: return "PT_SUNWCAP";
4009 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4010 default: return NULL;
5522f910
NC
4011 }
4012}
4013
252b5132 4014static const char *
dda8d76d 4015get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4016{
b34976b6 4017 static char buff[32];
252b5132
RH
4018
4019 switch (p_type)
4020 {
b34976b6
AM
4021 case PT_NULL: return "NULL";
4022 case PT_LOAD: return "LOAD";
252b5132 4023 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4024 case PT_INTERP: return "INTERP";
4025 case PT_NOTE: return "NOTE";
4026 case PT_SHLIB: return "SHLIB";
4027 case PT_PHDR: return "PHDR";
13ae64f3 4028 case PT_TLS: return "TLS";
32ec8896 4029 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4030 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4031 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4032 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4033
3eba3ef3
NC
4034 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4035 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4036 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
4037
252b5132 4038 default:
df3a023b 4039 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4040 {
2cf0635d 4041 const char * result;
103f02d3 4042
dda8d76d 4043 switch (filedata->file_header.e_machine)
252b5132 4044 {
a06ea964
NC
4045 case EM_AARCH64:
4046 result = get_aarch64_segment_type (p_type);
4047 break;
b294bdf8
MM
4048 case EM_ARM:
4049 result = get_arm_segment_type (p_type);
4050 break;
252b5132 4051 case EM_MIPS:
4fe85591 4052 case EM_MIPS_RS3_LE:
252b5132
RH
4053 result = get_mips_segment_type (p_type);
4054 break;
103f02d3
UD
4055 case EM_PARISC:
4056 result = get_parisc_segment_type (p_type);
4057 break;
4d6ed7c8
NC
4058 case EM_IA_64:
4059 result = get_ia64_segment_type (p_type);
4060 break;
40b36596
JM
4061 case EM_TI_C6000:
4062 result = get_tic6x_segment_type (p_type);
4063 break;
b4cbbe8f
AK
4064 case EM_S390:
4065 case EM_S390_OLD:
4066 result = get_s390_segment_type (p_type);
4067 break;
252b5132
RH
4068 default:
4069 result = NULL;
4070 break;
4071 }
103f02d3 4072
252b5132
RH
4073 if (result != NULL)
4074 return result;
103f02d3 4075
1a9ccd70 4076 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4077 }
4078 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4079 {
df3a023b 4080 const char * result = NULL;
103f02d3 4081
df3a023b 4082 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4083 {
df3a023b
AM
4084 case ELFOSABI_GNU:
4085 case ELFOSABI_FREEBSD:
4086 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4087 {
4088 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4089 result = buff;
4090 }
103f02d3 4091 break;
df3a023b
AM
4092 case ELFOSABI_HPUX:
4093 result = get_hpux_segment_type (p_type,
4094 filedata->file_header.e_machine);
4095 break;
4096 case ELFOSABI_SOLARIS:
4097 result = get_solaris_segment_type (p_type);
00428cca 4098 break;
103f02d3 4099 default:
103f02d3
UD
4100 break;
4101 }
103f02d3
UD
4102 if (result != NULL)
4103 return result;
4104
1a9ccd70 4105 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4106 }
252b5132 4107 else
e9e44622 4108 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4109
4110 return buff;
4111 }
4112}
4113
53a346d8
CZ
4114static const char *
4115get_arc_section_type_name (unsigned int sh_type)
4116{
4117 switch (sh_type)
4118 {
4119 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4120 default:
4121 break;
4122 }
4123 return NULL;
4124}
4125
252b5132 4126static const char *
d3ba0551 4127get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4128{
4129 switch (sh_type)
4130 {
b34976b6
AM
4131 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4132 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4133 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4134 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4135 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4136 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4137 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4138 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4139 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4140 case SHT_MIPS_RELD: return "MIPS_RELD";
4141 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4142 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4143 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4144 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4145 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4146 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4147 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4148 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4149 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4150 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4151 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4152 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4153 case SHT_MIPS_LINE: return "MIPS_LINE";
4154 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4155 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4156 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4157 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4158 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4159 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4160 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4161 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4162 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4163 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4164 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4165 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4166 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4167 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4168 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4169 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4170 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4171 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4172 default:
4173 break;
4174 }
4175 return NULL;
4176}
4177
103f02d3 4178static const char *
d3ba0551 4179get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4180{
4181 switch (sh_type)
4182 {
4183 case SHT_PARISC_EXT: return "PARISC_EXT";
4184 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4185 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4186 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4187 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4188 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4189 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4190 default: return NULL;
103f02d3 4191 }
103f02d3
UD
4192}
4193
4d6ed7c8 4194static const char *
dda8d76d 4195get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4196{
18bd398b 4197 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4198 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4199 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4200
4d6ed7c8
NC
4201 switch (sh_type)
4202 {
148b93f2
NC
4203 case SHT_IA_64_EXT: return "IA_64_EXT";
4204 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4205 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4206 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4207 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4208 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4209 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4210 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4211 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4212 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4213 default:
4214 break;
4215 }
4216 return NULL;
4217}
4218
d2b2c203
DJ
4219static const char *
4220get_x86_64_section_type_name (unsigned int sh_type)
4221{
4222 switch (sh_type)
4223 {
4224 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4225 default: return NULL;
d2b2c203 4226 }
d2b2c203
DJ
4227}
4228
a06ea964
NC
4229static const char *
4230get_aarch64_section_type_name (unsigned int sh_type)
4231{
4232 switch (sh_type)
4233 {
32ec8896
NC
4234 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4235 default: return NULL;
a06ea964 4236 }
a06ea964
NC
4237}
4238
40a18ebd
NC
4239static const char *
4240get_arm_section_type_name (unsigned int sh_type)
4241{
4242 switch (sh_type)
4243 {
7f6fed87
NC
4244 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4245 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4246 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4247 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4248 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4249 default: return NULL;
40a18ebd 4250 }
40a18ebd
NC
4251}
4252
40b36596
JM
4253static const char *
4254get_tic6x_section_type_name (unsigned int sh_type)
4255{
4256 switch (sh_type)
4257 {
32ec8896
NC
4258 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4259 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4260 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4261 case SHT_TI_ICODE: return "TI_ICODE";
4262 case SHT_TI_XREF: return "TI_XREF";
4263 case SHT_TI_HANDLER: return "TI_HANDLER";
4264 case SHT_TI_INITINFO: return "TI_INITINFO";
4265 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4266 default: return NULL;
40b36596 4267 }
40b36596
JM
4268}
4269
13761a11 4270static const char *
b0191216 4271get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4272{
4273 switch (sh_type)
4274 {
32ec8896
NC
4275 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4276 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4277 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4278 default: return NULL;
13761a11
NC
4279 }
4280}
4281
fe944acf
FT
4282static const char *
4283get_nfp_section_type_name (unsigned int sh_type)
4284{
4285 switch (sh_type)
4286 {
4287 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4288 case SHT_NFP_INITREG: return "NFP_INITREG";
4289 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4290 default: return NULL;
4291 }
4292}
4293
685080f2
NC
4294static const char *
4295get_v850_section_type_name (unsigned int sh_type)
4296{
4297 switch (sh_type)
4298 {
32ec8896
NC
4299 case SHT_V850_SCOMMON: return "V850 Small Common";
4300 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4301 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4302 case SHT_RENESAS_IOP: return "RENESAS IOP";
4303 case SHT_RENESAS_INFO: return "RENESAS INFO";
4304 default: return NULL;
685080f2
NC
4305 }
4306}
4307
2dc8dd17
JW
4308static const char *
4309get_riscv_section_type_name (unsigned int sh_type)
4310{
4311 switch (sh_type)
4312 {
4313 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4314 default: return NULL;
4315 }
4316}
4317
0861f561
CQ
4318static const char *
4319get_csky_section_type_name (unsigned int sh_type)
4320{
4321 switch (sh_type)
4322 {
4323 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4324 default: return NULL;
4325 }
4326}
4327
252b5132 4328static const char *
dda8d76d 4329get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4330{
b34976b6 4331 static char buff[32];
9fb71ee4 4332 const char * result;
252b5132
RH
4333
4334 switch (sh_type)
4335 {
4336 case SHT_NULL: return "NULL";
4337 case SHT_PROGBITS: return "PROGBITS";
4338 case SHT_SYMTAB: return "SYMTAB";
4339 case SHT_STRTAB: return "STRTAB";
4340 case SHT_RELA: return "RELA";
4341 case SHT_HASH: return "HASH";
4342 case SHT_DYNAMIC: return "DYNAMIC";
4343 case SHT_NOTE: return "NOTE";
4344 case SHT_NOBITS: return "NOBITS";
4345 case SHT_REL: return "REL";
4346 case SHT_SHLIB: return "SHLIB";
4347 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4348 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4349 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4350 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4351 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4352 case SHT_GROUP: return "GROUP";
67ce483b 4353 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4354 case SHT_GNU_verdef: return "VERDEF";
4355 case SHT_GNU_verneed: return "VERNEED";
4356 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4357 case 0x6ffffff0: return "VERSYM";
4358 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4359 case 0x7ffffffd: return "AUXILIARY";
4360 case 0x7fffffff: return "FILTER";
047b2264 4361 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4362
4363 default:
4364 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4365 {
dda8d76d 4366 switch (filedata->file_header.e_machine)
252b5132 4367 {
53a346d8
CZ
4368 case EM_ARC:
4369 case EM_ARC_COMPACT:
4370 case EM_ARC_COMPACT2:
4371 result = get_arc_section_type_name (sh_type);
4372 break;
252b5132 4373 case EM_MIPS:
4fe85591 4374 case EM_MIPS_RS3_LE:
252b5132
RH
4375 result = get_mips_section_type_name (sh_type);
4376 break;
103f02d3
UD
4377 case EM_PARISC:
4378 result = get_parisc_section_type_name (sh_type);
4379 break;
4d6ed7c8 4380 case EM_IA_64:
dda8d76d 4381 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4382 break;
d2b2c203 4383 case EM_X86_64:
8a9036a4 4384 case EM_L1OM:
7a9068fe 4385 case EM_K1OM:
d2b2c203
DJ
4386 result = get_x86_64_section_type_name (sh_type);
4387 break;
a06ea964
NC
4388 case EM_AARCH64:
4389 result = get_aarch64_section_type_name (sh_type);
4390 break;
40a18ebd
NC
4391 case EM_ARM:
4392 result = get_arm_section_type_name (sh_type);
4393 break;
40b36596
JM
4394 case EM_TI_C6000:
4395 result = get_tic6x_section_type_name (sh_type);
4396 break;
13761a11 4397 case EM_MSP430:
b0191216 4398 result = get_msp430_section_type_name (sh_type);
13761a11 4399 break;
fe944acf
FT
4400 case EM_NFP:
4401 result = get_nfp_section_type_name (sh_type);
4402 break;
685080f2
NC
4403 case EM_V800:
4404 case EM_V850:
4405 case EM_CYGNUS_V850:
4406 result = get_v850_section_type_name (sh_type);
4407 break;
2dc8dd17
JW
4408 case EM_RISCV:
4409 result = get_riscv_section_type_name (sh_type);
4410 break;
0861f561
CQ
4411 case EM_CSKY:
4412 result = get_csky_section_type_name (sh_type);
4413 break;
252b5132
RH
4414 default:
4415 result = NULL;
4416 break;
4417 }
4418
4419 if (result != NULL)
4420 return result;
4421
9fb71ee4 4422 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4423 }
4424 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4425 {
dda8d76d 4426 switch (filedata->file_header.e_machine)
148b93f2
NC
4427 {
4428 case EM_IA_64:
dda8d76d 4429 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4430 break;
4431 default:
dda8d76d 4432 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4433 result = get_solaris_section_type (sh_type);
4434 else
1b4b80bf
NC
4435 {
4436 switch (sh_type)
4437 {
4438 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4439 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4440 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4441 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4442 default:
4443 result = NULL;
4444 break;
4445 }
4446 }
148b93f2
NC
4447 break;
4448 }
4449
4450 if (result != NULL)
4451 return result;
4452
9fb71ee4 4453 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4454 }
252b5132 4455 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4456 {
dda8d76d 4457 switch (filedata->file_header.e_machine)
685080f2
NC
4458 {
4459 case EM_V800:
4460 case EM_V850:
4461 case EM_CYGNUS_V850:
9fb71ee4 4462 result = get_v850_section_type_name (sh_type);
a9fb83be 4463 break;
685080f2 4464 default:
9fb71ee4 4465 result = NULL;
685080f2
NC
4466 break;
4467 }
4468
9fb71ee4
NC
4469 if (result != NULL)
4470 return result;
4471
4472 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4473 }
252b5132 4474 else
a7dbfd1c
NC
4475 /* This message is probably going to be displayed in a 15
4476 character wide field, so put the hex value first. */
4477 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4478
252b5132
RH
4479 return buff;
4480 }
4481}
4482
79bc120c
NC
4483enum long_option_values
4484{
4485 OPTION_DEBUG_DUMP = 512,
4486 OPTION_DYN_SYMS,
0f03783c 4487 OPTION_LTO_SYMS,
79bc120c
NC
4488 OPTION_DWARF_DEPTH,
4489 OPTION_DWARF_START,
4490 OPTION_DWARF_CHECK,
4491 OPTION_CTF_DUMP,
4492 OPTION_CTF_PARENT,
4493 OPTION_CTF_SYMBOLS,
4494 OPTION_CTF_STRINGS,
4495 OPTION_WITH_SYMBOL_VERSIONS,
4496 OPTION_RECURSE_LIMIT,
4497 OPTION_NO_RECURSE_LIMIT,
4498 OPTION_NO_DEMANGLING
4499};
2979dc34 4500
85b1c36d 4501static struct option options[] =
252b5132 4502{
79bc120c
NC
4503 /* Note - This table is alpha-sorted on the 'val'
4504 field in order to make adding new options easier. */
4505 {"arch-specific", no_argument, 0, 'A'},
b34976b6 4506 {"all", no_argument, 0, 'a'},
79bc120c
NC
4507 {"demangle", optional_argument, 0, 'C'},
4508 {"archive-index", no_argument, 0, 'c'},
4509 {"use-dynamic", no_argument, 0, 'D'},
4510 {"dynamic", no_argument, 0, 'd'},
b34976b6 4511 {"headers", no_argument, 0, 'e'},
79bc120c
NC
4512 {"section-groups", no_argument, 0, 'g'},
4513 {"help", no_argument, 0, 'H'},
4514 {"file-header", no_argument, 0, 'h'},
b34976b6 4515 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
4516 {"lint", no_argument, 0, 'L'},
4517 {"enable-checks", no_argument, 0, 'L'},
4518 {"program-headers", no_argument, 0, 'l'},
b34976b6 4519 {"segments", no_argument, 0, 'l'},
595cf52e 4520 {"full-section-name",no_argument, 0, 'N'},
79bc120c
NC
4521 {"notes", no_argument, 0, 'n'},
4522 {"string-dump", required_argument, 0, 'p'},
4523 {"relocated-dump", required_argument, 0, 'R'},
4524 {"relocs", no_argument, 0, 'r'},
4525 {"section-headers", no_argument, 0, 'S'},
4526 {"sections", no_argument, 0, 'S'},
b34976b6
AM
4527 {"symbols", no_argument, 0, 's'},
4528 {"syms", no_argument, 0, 's'},
79bc120c
NC
4529 {"silent-truncation",no_argument, 0, 'T'},
4530 {"section-details", no_argument, 0, 't'},
09c11c86 4531 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
4532 {"version-info", no_argument, 0, 'V'},
4533 {"version", no_argument, 0, 'v'},
4534 {"wide", no_argument, 0, 'W'},
b34976b6 4535 {"hex-dump", required_argument, 0, 'x'},
0e602686 4536 {"decompress", no_argument, 0, 'z'},
252b5132 4537
79bc120c
NC
4538 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
4539 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
4540 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4541 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4542 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 4543 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 4544 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
4545 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4546 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4547 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 4548#ifdef ENABLE_LIBCTF
d344b407 4549 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
4550 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
4551 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
4552 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 4553#endif
7d9813f1 4554
b34976b6 4555 {0, no_argument, 0, 0}
252b5132
RH
4556};
4557
4558static void
2cf0635d 4559usage (FILE * stream)
252b5132 4560{
92f01d61
JM
4561 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4562 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4563 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4564 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4565 -h --file-header Display the ELF file header\n\
4566 -l --program-headers Display the program headers\n\
4567 --segments An alias for --program-headers\n\
4568 -S --section-headers Display the sections' header\n\
4569 --sections An alias for --section-headers\n\
f5842774 4570 -g --section-groups Display the section groups\n\
5477e8a0 4571 -t --section-details Display the section details\n\
8b53311e
NC
4572 -e --headers Equivalent to: -h -l -S\n\
4573 -s --syms Display the symbol table\n\
3f08eb35 4574 --symbols An alias for --syms\n\
1b513401 4575 --dyn-syms Display the dynamic symbol table\n\
0f03783c 4576 --lto-syms Display LTO symbol tables\n\
79bc120c
NC
4577 -C --demangle[=STYLE] Decode low-level symbol names into user-level names\n\
4578 The STYLE, if specified, can be `auto' (the default),\n\
4579 `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
4580 or `gnat'\n\
4581 --no-demangle Do not demangle low-level symbol names. (This is the default)\n\
4582 --recurse-limit Enable a demangling recursion limit. (This is the default)\n\
4583 --no-recurse-limit Disable a demangling recursion limit\n\
8b53311e
NC
4584 -n --notes Display the core notes (if present)\n\
4585 -r --relocs Display the relocations (if present)\n\
4586 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4587 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4588 -V --version-info Display the version sections (if present)\n\
1b31d05e 4589 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4590 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4591 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
1b513401 4592 -L --lint|--enable-checks Display warning messages for possible problems\n\
09c11c86
NC
4593 -x --hex-dump=<number|name>\n\
4594 Dump the contents of section <number|name> as bytes\n\
4595 -p --string-dump=<number|name>\n\
4596 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4597 -R --relocated-dump=<number|name>\n\
4598 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4599 -z --decompress Decompress section before dumping it\n\
e4b7104b 4600 -w[lLiaprmfFsoORtUuTgAckK] or\n\
1ed06042 4601 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
e4b7104b 4602 =frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,\n\
657d0d47 4603 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
dda8d76d
NC
4604 =addr,=cu_index,=links,=follow-links]\n\
4605 Display the contents of DWARF debug sections\n"));
fd2f0033
TT
4606 fprintf (stream, _("\
4607 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4608 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4609 or deeper\n"));
094e34f2 4610#ifdef ENABLE_LIBCTF
7d9813f1
NA
4611 fprintf (stream, _("\
4612 --ctf=<number|name> Display CTF info from section <number|name>\n\
4613 --ctf-parent=<number|name>\n\
4614 Use section <number|name> as the CTF parent\n\n\
4615 --ctf-symbols=<number|name>\n\
4616 Use section <number|name> as the CTF external symtab\n\n\
4617 --ctf-strings=<number|name>\n\
4618 Use section <number|name> as the CTF external strtab\n\n"));
094e34f2 4619#endif
7d9813f1 4620
252b5132 4621#ifdef SUPPORT_DISASSEMBLY
92f01d61 4622 fprintf (stream, _("\
09c11c86
NC
4623 -i --instruction-dump=<number|name>\n\
4624 Disassemble the contents of section <number|name>\n"));
252b5132 4625#endif
92f01d61 4626 fprintf (stream, _("\
8b53311e
NC
4627 -I --histogram Display histogram of bucket list lengths\n\
4628 -W --wide Allow output width to exceed 80 characters\n\
0942c7ab 4629 -T --silent-truncation If a symbol name is truncated, do not add a suffix [...]\n\
07012eee 4630 @<file> Read options from <file>\n\
8b53311e
NC
4631 -H --help Display this information\n\
4632 -v --version Display the version number of readelf\n"));
1118d252 4633
92f01d61
JM
4634 if (REPORT_BUGS_TO[0] && stream == stdout)
4635 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4636
92f01d61 4637 exit (stream == stdout ? 0 : 1);
252b5132
RH
4638}
4639
18bd398b
NC
4640/* Record the fact that the user wants the contents of section number
4641 SECTION to be displayed using the method(s) encoded as flags bits
4642 in TYPE. Note, TYPE can be zero if we are creating the array for
4643 the first time. */
4644
252b5132 4645static void
6431e409
AM
4646request_dump_bynumber (struct dump_data *dumpdata,
4647 unsigned int section, dump_type type)
252b5132 4648{
6431e409 4649 if (section >= dumpdata->num_dump_sects)
252b5132 4650 {
2cf0635d 4651 dump_type * new_dump_sects;
252b5132 4652
3f5e193b 4653 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4654 sizeof (* new_dump_sects));
252b5132
RH
4655
4656 if (new_dump_sects == NULL)
591a748a 4657 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4658 else
4659 {
6431e409 4660 if (dumpdata->dump_sects)
21b65bac
NC
4661 {
4662 /* Copy current flag settings. */
6431e409
AM
4663 memcpy (new_dump_sects, dumpdata->dump_sects,
4664 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4665
6431e409 4666 free (dumpdata->dump_sects);
21b65bac 4667 }
252b5132 4668
6431e409
AM
4669 dumpdata->dump_sects = new_dump_sects;
4670 dumpdata->num_dump_sects = section + 1;
252b5132
RH
4671 }
4672 }
4673
6431e409
AM
4674 if (dumpdata->dump_sects)
4675 dumpdata->dump_sects[section] |= type;
252b5132
RH
4676}
4677
aef1f6d0
DJ
4678/* Request a dump by section name. */
4679
4680static void
2cf0635d 4681request_dump_byname (const char * section, dump_type type)
aef1f6d0 4682{
2cf0635d 4683 struct dump_list_entry * new_request;
aef1f6d0 4684
3f5e193b
NC
4685 new_request = (struct dump_list_entry *)
4686 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4687 if (!new_request)
591a748a 4688 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4689
4690 new_request->name = strdup (section);
4691 if (!new_request->name)
591a748a 4692 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4693
4694 new_request->type = type;
4695
4696 new_request->next = dump_sects_byname;
4697 dump_sects_byname = new_request;
4698}
4699
cf13d699 4700static inline void
6431e409 4701request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
4702{
4703 int section;
4704 char * cp;
4705
4706 do_dump++;
4707 section = strtoul (optarg, & cp, 0);
4708
4709 if (! *cp && section >= 0)
6431e409 4710 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
4711 else
4712 request_dump_byname (optarg, type);
4713}
4714
252b5132 4715static void
6431e409 4716parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
4717{
4718 int c;
4719
4720 if (argc < 2)
92f01d61 4721 usage (stderr);
252b5132
RH
4722
4723 while ((c = getopt_long
79bc120c 4724 (argc, argv, "ACDHILNR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4725 {
252b5132
RH
4726 switch (c)
4727 {
4728 case 0:
4729 /* Long options. */
4730 break;
4731 case 'H':
92f01d61 4732 usage (stdout);
252b5132
RH
4733 break;
4734
4735 case 'a':
32ec8896
NC
4736 do_syms = TRUE;
4737 do_reloc = TRUE;
4738 do_unwind = TRUE;
4739 do_dynamic = TRUE;
4740 do_header = TRUE;
4741 do_sections = TRUE;
4742 do_section_groups = TRUE;
4743 do_segments = TRUE;
4744 do_version = TRUE;
4745 do_histogram = TRUE;
4746 do_arch = TRUE;
4747 do_notes = TRUE;
252b5132 4748 break;
79bc120c 4749
f5842774 4750 case 'g':
32ec8896 4751 do_section_groups = TRUE;
f5842774 4752 break;
5477e8a0 4753 case 't':
595cf52e 4754 case 'N':
32ec8896
NC
4755 do_sections = TRUE;
4756 do_section_details = TRUE;
595cf52e 4757 break;
252b5132 4758 case 'e':
32ec8896
NC
4759 do_header = TRUE;
4760 do_sections = TRUE;
4761 do_segments = TRUE;
252b5132 4762 break;
a952a375 4763 case 'A':
32ec8896 4764 do_arch = TRUE;
a952a375 4765 break;
252b5132 4766 case 'D':
32ec8896 4767 do_using_dynamic = TRUE;
252b5132
RH
4768 break;
4769 case 'r':
32ec8896 4770 do_reloc = TRUE;
252b5132 4771 break;
4d6ed7c8 4772 case 'u':
32ec8896 4773 do_unwind = TRUE;
4d6ed7c8 4774 break;
252b5132 4775 case 'h':
32ec8896 4776 do_header = TRUE;
252b5132
RH
4777 break;
4778 case 'l':
32ec8896 4779 do_segments = TRUE;
252b5132
RH
4780 break;
4781 case 's':
32ec8896 4782 do_syms = TRUE;
252b5132
RH
4783 break;
4784 case 'S':
32ec8896 4785 do_sections = TRUE;
252b5132
RH
4786 break;
4787 case 'd':
32ec8896 4788 do_dynamic = TRUE;
252b5132 4789 break;
a952a375 4790 case 'I':
32ec8896 4791 do_histogram = TRUE;
a952a375 4792 break;
779fe533 4793 case 'n':
32ec8896 4794 do_notes = TRUE;
779fe533 4795 break;
4145f1d5 4796 case 'c':
32ec8896 4797 do_archive_index = TRUE;
4145f1d5 4798 break;
1b513401
NC
4799 case 'L':
4800 do_checks = TRUE;
4801 break;
252b5132 4802 case 'x':
6431e409 4803 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 4804 break;
09c11c86 4805 case 'p':
6431e409 4806 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
4807 break;
4808 case 'R':
6431e409 4809 request_dump (dumpdata, RELOC_DUMP);
09c11c86 4810 break;
0e602686 4811 case 'z':
32ec8896 4812 decompress_dumps = TRUE;
0e602686 4813 break;
252b5132 4814 case 'w':
32ec8896 4815 do_dump = TRUE;
0f03783c 4816 if (optarg == NULL)
613ff48b 4817 {
32ec8896 4818 do_debugging = TRUE;
613ff48b
CC
4819 dwarf_select_sections_all ();
4820 }
252b5132
RH
4821 else
4822 {
32ec8896 4823 do_debugging = FALSE;
4cb93e3b 4824 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4825 }
4826 break;
2979dc34 4827 case OPTION_DEBUG_DUMP:
32ec8896 4828 do_dump = TRUE;
0f03783c 4829 if (optarg == NULL)
32ec8896 4830 do_debugging = TRUE;
2979dc34
JJ
4831 else
4832 {
32ec8896 4833 do_debugging = FALSE;
4cb93e3b 4834 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4835 }
4836 break;
fd2f0033
TT
4837 case OPTION_DWARF_DEPTH:
4838 {
4839 char *cp;
4840
4841 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4842 }
4843 break;
4844 case OPTION_DWARF_START:
4845 {
4846 char *cp;
4847
4848 dwarf_start_die = strtoul (optarg, & cp, 0);
4849 }
4850 break;
4723351a 4851 case OPTION_DWARF_CHECK:
32ec8896 4852 dwarf_check = TRUE;
4723351a 4853 break;
7d9813f1
NA
4854 case OPTION_CTF_DUMP:
4855 do_ctf = TRUE;
6431e409 4856 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
4857 break;
4858 case OPTION_CTF_SYMBOLS:
df16e041 4859 free (dump_ctf_symtab_name);
7d9813f1
NA
4860 dump_ctf_symtab_name = strdup (optarg);
4861 break;
4862 case OPTION_CTF_STRINGS:
df16e041 4863 free (dump_ctf_strtab_name);
7d9813f1
NA
4864 dump_ctf_strtab_name = strdup (optarg);
4865 break;
4866 case OPTION_CTF_PARENT:
df16e041 4867 free (dump_ctf_parent_name);
7d9813f1
NA
4868 dump_ctf_parent_name = strdup (optarg);
4869 break;
2c610e4b 4870 case OPTION_DYN_SYMS:
32ec8896 4871 do_dyn_syms = TRUE;
2c610e4b 4872 break;
0f03783c
NC
4873 case OPTION_LTO_SYMS:
4874 do_lto_syms = TRUE;
4875 break;
252b5132
RH
4876#ifdef SUPPORT_DISASSEMBLY
4877 case 'i':
6431e409 4878 request_dump (dumpdata, DISASS_DUMP);
cf13d699 4879 break;
252b5132
RH
4880#endif
4881 case 'v':
4882 print_version (program_name);
4883 break;
4884 case 'V':
32ec8896 4885 do_version = TRUE;
252b5132 4886 break;
d974e256 4887 case 'W':
32ec8896 4888 do_wide = TRUE;
d974e256 4889 break;
0942c7ab
NC
4890 case 'T':
4891 do_not_show_symbol_truncation = TRUE;
4892 break;
79bc120c
NC
4893 case 'C':
4894 do_demangle = TRUE;
4895 if (optarg != NULL)
4896 {
4897 enum demangling_styles style;
4898
4899 style = cplus_demangle_name_to_style (optarg);
4900 if (style == unknown_demangling)
4901 error (_("unknown demangling style `%s'"), optarg);
4902
4903 cplus_demangle_set_style (style);
4904 }
4905 break;
4906 case OPTION_NO_DEMANGLING:
4907 do_demangle = FALSE;
4908 break;
4909 case OPTION_RECURSE_LIMIT:
4910 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
4911 break;
4912 case OPTION_NO_RECURSE_LIMIT:
4913 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
4914 break;
4915 case OPTION_WITH_SYMBOL_VERSIONS:
4916 /* Ignored for backward compatibility. */
4917 break;
4918
252b5132 4919 default:
252b5132
RH
4920 /* xgettext:c-format */
4921 error (_("Invalid option '-%c'\n"), c);
1a0670f3 4922 /* Fall through. */
252b5132 4923 case '?':
92f01d61 4924 usage (stderr);
252b5132
RH
4925 }
4926 }
4927
4d6ed7c8 4928 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4929 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4930 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 4931 && !do_section_groups && !do_archive_index
0f03783c 4932 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
4933 {
4934 if (do_checks)
4935 {
4936 check_all = TRUE;
4937 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = TRUE;
4938 do_segments = do_header = do_dump = do_version = TRUE;
4939 do_histogram = do_debugging = do_arch = do_notes = TRUE;
4940 do_section_groups = do_archive_index = do_dyn_syms = TRUE;
0f03783c 4941 do_lto_syms = TRUE;
1b513401
NC
4942 }
4943 else
4944 usage (stderr);
4945 }
252b5132
RH
4946}
4947
4948static const char *
d3ba0551 4949get_elf_class (unsigned int elf_class)
252b5132 4950{
b34976b6 4951 static char buff[32];
103f02d3 4952
252b5132
RH
4953 switch (elf_class)
4954 {
4955 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4956 case ELFCLASS32: return "ELF32";
4957 case ELFCLASS64: return "ELF64";
ab5e7794 4958 default:
e9e44622 4959 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4960 return buff;
252b5132
RH
4961 }
4962}
4963
4964static const char *
d3ba0551 4965get_data_encoding (unsigned int encoding)
252b5132 4966{
b34976b6 4967 static char buff[32];
103f02d3 4968
252b5132
RH
4969 switch (encoding)
4970 {
4971 case ELFDATANONE: return _("none");
33c63f9d
CM
4972 case ELFDATA2LSB: return _("2's complement, little endian");
4973 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4974 default:
e9e44622 4975 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4976 return buff;
252b5132
RH
4977 }
4978}
4979
dda8d76d 4980/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 4981
32ec8896 4982static bfd_boolean
dda8d76d 4983process_file_header (Filedata * filedata)
252b5132 4984{
dda8d76d
NC
4985 Elf_Internal_Ehdr * header = & filedata->file_header;
4986
4987 if ( header->e_ident[EI_MAG0] != ELFMAG0
4988 || header->e_ident[EI_MAG1] != ELFMAG1
4989 || header->e_ident[EI_MAG2] != ELFMAG2
4990 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4991 {
4992 error
4993 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
32ec8896 4994 return FALSE;
252b5132
RH
4995 }
4996
955ff7fc 4997 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 4998
252b5132
RH
4999 if (do_header)
5000 {
32ec8896 5001 unsigned i;
252b5132
RH
5002
5003 printf (_("ELF Header:\n"));
5004 printf (_(" Magic: "));
b34976b6 5005 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5006 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5007 printf ("\n");
5008 printf (_(" Class: %s\n"),
dda8d76d 5009 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5010 printf (_(" Data: %s\n"),
dda8d76d 5011 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5012 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5013 header->e_ident[EI_VERSION],
5014 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5015 ? _(" (current)")
dda8d76d 5016 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5017 ? _(" <unknown>")
789be9f7 5018 : "")));
252b5132 5019 printf (_(" OS/ABI: %s\n"),
dda8d76d 5020 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5021 printf (_(" ABI Version: %d\n"),
dda8d76d 5022 header->e_ident[EI_ABIVERSION]);
252b5132 5023 printf (_(" Type: %s\n"),
dda8d76d 5024 get_file_type (header->e_type));
252b5132 5025 printf (_(" Machine: %s\n"),
dda8d76d 5026 get_machine_name (header->e_machine));
252b5132 5027 printf (_(" Version: 0x%lx\n"),
e8a64888 5028 header->e_version);
76da6bbe 5029
f7a99963 5030 printf (_(" Entry point address: "));
e8a64888 5031 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5032 printf (_("\n Start of program headers: "));
e8a64888 5033 print_vma (header->e_phoff, DEC);
f7a99963 5034 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5035 print_vma (header->e_shoff, DEC);
f7a99963 5036 printf (_(" (bytes into file)\n"));
76da6bbe 5037
252b5132 5038 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5039 header->e_flags,
dda8d76d 5040 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5041 printf (_(" Size of this header: %u (bytes)\n"),
5042 header->e_ehsize);
5043 printf (_(" Size of program headers: %u (bytes)\n"),
5044 header->e_phentsize);
5045 printf (_(" Number of program headers: %u"),
5046 header->e_phnum);
dda8d76d
NC
5047 if (filedata->section_headers != NULL
5048 && header->e_phnum == PN_XNUM
5049 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
5050 {
5051 header->e_phnum = filedata->section_headers[0].sh_info;
5052 printf (" (%u)", header->e_phnum);
5053 }
2046a35d 5054 putc ('\n', stdout);
e8a64888
AM
5055 printf (_(" Size of section headers: %u (bytes)\n"),
5056 header->e_shentsize);
5057 printf (_(" Number of section headers: %u"),
5058 header->e_shnum);
dda8d76d 5059 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5060 {
5061 header->e_shnum = filedata->section_headers[0].sh_size;
5062 printf (" (%u)", header->e_shnum);
5063 }
560f3c1c 5064 putc ('\n', stdout);
e8a64888
AM
5065 printf (_(" Section header string table index: %u"),
5066 header->e_shstrndx);
dda8d76d
NC
5067 if (filedata->section_headers != NULL
5068 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5069 {
5070 header->e_shstrndx = filedata->section_headers[0].sh_link;
5071 printf (" (%u)", header->e_shstrndx);
5072 }
5073 if (header->e_shstrndx != SHN_UNDEF
5074 && header->e_shstrndx >= header->e_shnum)
5075 {
5076 header->e_shstrndx = SHN_UNDEF;
5077 printf (_(" <corrupt: out of range>"));
5078 }
560f3c1c
AM
5079 putc ('\n', stdout);
5080 }
5081
dda8d76d 5082 if (filedata->section_headers != NULL)
560f3c1c 5083 {
dda8d76d
NC
5084 if (header->e_phnum == PN_XNUM
5085 && filedata->section_headers[0].sh_info != 0)
5086 header->e_phnum = filedata->section_headers[0].sh_info;
5087 if (header->e_shnum == SHN_UNDEF)
5088 header->e_shnum = filedata->section_headers[0].sh_size;
5089 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5090 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5091 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
5092 header->e_shstrndx = SHN_UNDEF;
5093 free (filedata->section_headers);
5094 filedata->section_headers = NULL;
252b5132 5095 }
103f02d3 5096
32ec8896 5097 return TRUE;
9ea033b2
NC
5098}
5099
dda8d76d
NC
5100/* Read in the program headers from FILEDATA and store them in PHEADERS.
5101 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5102
e0a31db1 5103static bfd_boolean
dda8d76d 5104get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5105{
2cf0635d
NC
5106 Elf32_External_Phdr * phdrs;
5107 Elf32_External_Phdr * external;
5108 Elf_Internal_Phdr * internal;
b34976b6 5109 unsigned int i;
dda8d76d
NC
5110 unsigned int size = filedata->file_header.e_phentsize;
5111 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5112
5113 /* PR binutils/17531: Cope with unexpected section header sizes. */
5114 if (size == 0 || num == 0)
5115 return FALSE;
5116 if (size < sizeof * phdrs)
5117 {
5118 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5119 return FALSE;
5120 }
5121 if (size > sizeof * phdrs)
5122 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5123
dda8d76d 5124 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5125 size, num, _("program headers"));
5126 if (phdrs == NULL)
5127 return FALSE;
9ea033b2 5128
91d6fa6a 5129 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5130 i < filedata->file_header.e_phnum;
b34976b6 5131 i++, internal++, external++)
252b5132 5132 {
9ea033b2
NC
5133 internal->p_type = BYTE_GET (external->p_type);
5134 internal->p_offset = BYTE_GET (external->p_offset);
5135 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5136 internal->p_paddr = BYTE_GET (external->p_paddr);
5137 internal->p_filesz = BYTE_GET (external->p_filesz);
5138 internal->p_memsz = BYTE_GET (external->p_memsz);
5139 internal->p_flags = BYTE_GET (external->p_flags);
5140 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5141 }
5142
9ea033b2 5143 free (phdrs);
e0a31db1 5144 return TRUE;
252b5132
RH
5145}
5146
dda8d76d
NC
5147/* Read in the program headers from FILEDATA and store them in PHEADERS.
5148 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5149
e0a31db1 5150static bfd_boolean
dda8d76d 5151get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5152{
2cf0635d
NC
5153 Elf64_External_Phdr * phdrs;
5154 Elf64_External_Phdr * external;
5155 Elf_Internal_Phdr * internal;
b34976b6 5156 unsigned int i;
dda8d76d
NC
5157 unsigned int size = filedata->file_header.e_phentsize;
5158 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5159
5160 /* PR binutils/17531: Cope with unexpected section header sizes. */
5161 if (size == 0 || num == 0)
5162 return FALSE;
5163 if (size < sizeof * phdrs)
5164 {
5165 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5166 return FALSE;
5167 }
5168 if (size > sizeof * phdrs)
5169 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5170
dda8d76d 5171 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5172 size, num, _("program headers"));
a6e9f9df 5173 if (!phdrs)
e0a31db1 5174 return FALSE;
9ea033b2 5175
91d6fa6a 5176 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5177 i < filedata->file_header.e_phnum;
b34976b6 5178 i++, internal++, external++)
9ea033b2
NC
5179 {
5180 internal->p_type = BYTE_GET (external->p_type);
5181 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5182 internal->p_offset = BYTE_GET (external->p_offset);
5183 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5184 internal->p_paddr = BYTE_GET (external->p_paddr);
5185 internal->p_filesz = BYTE_GET (external->p_filesz);
5186 internal->p_memsz = BYTE_GET (external->p_memsz);
5187 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5188 }
5189
5190 free (phdrs);
e0a31db1 5191 return TRUE;
9ea033b2 5192}
252b5132 5193
32ec8896 5194/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5195
32ec8896 5196static bfd_boolean
dda8d76d 5197get_program_headers (Filedata * filedata)
d93f0186 5198{
2cf0635d 5199 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5200
5201 /* Check cache of prior read. */
dda8d76d 5202 if (filedata->program_headers != NULL)
32ec8896 5203 return TRUE;
d93f0186 5204
82156ab7
NC
5205 /* Be kind to memory checkers by looking for
5206 e_phnum values which we know must be invalid. */
dda8d76d 5207 if (filedata->file_header.e_phnum
82156ab7 5208 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5209 >= filedata->file_size)
82156ab7
NC
5210 {
5211 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5212 filedata->file_header.e_phnum);
82156ab7
NC
5213 return FALSE;
5214 }
d93f0186 5215
dda8d76d 5216 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5217 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5218 if (phdrs == NULL)
5219 {
8b73c356 5220 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5221 filedata->file_header.e_phnum);
32ec8896 5222 return FALSE;
d93f0186
NC
5223 }
5224
5225 if (is_32bit_elf
dda8d76d
NC
5226 ? get_32bit_program_headers (filedata, phdrs)
5227 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5228 {
dda8d76d 5229 filedata->program_headers = phdrs;
32ec8896 5230 return TRUE;
d93f0186
NC
5231 }
5232
5233 free (phdrs);
32ec8896 5234 return FALSE;
d93f0186
NC
5235}
5236
32ec8896 5237/* Returns TRUE if the program headers were loaded. */
2f62977e 5238
32ec8896 5239static bfd_boolean
dda8d76d 5240process_program_headers (Filedata * filedata)
252b5132 5241{
2cf0635d 5242 Elf_Internal_Phdr * segment;
b34976b6 5243 unsigned int i;
1a9ccd70 5244 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5245
978c4450
AM
5246 filedata->dynamic_addr = 0;
5247 filedata->dynamic_size = 0;
663f67df 5248
dda8d76d 5249 if (filedata->file_header.e_phnum == 0)
252b5132 5250 {
82f2dbf7 5251 /* PR binutils/12467. */
dda8d76d 5252 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5253 {
5254 warn (_("possibly corrupt ELF header - it has a non-zero program"
5255 " header offset, but no program headers\n"));
5256 return FALSE;
5257 }
82f2dbf7 5258 else if (do_segments)
252b5132 5259 printf (_("\nThere are no program headers in this file.\n"));
32ec8896 5260 return TRUE;
252b5132
RH
5261 }
5262
5263 if (do_segments && !do_header)
5264 {
dda8d76d
NC
5265 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
5266 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5267 printf (ngettext ("There is %d program header, starting at offset %s\n",
5268 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5269 filedata->file_header.e_phnum),
5270 filedata->file_header.e_phnum,
5271 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5272 }
5273
dda8d76d 5274 if (! get_program_headers (filedata))
6b4bf3bc 5275 return TRUE;
103f02d3 5276
252b5132
RH
5277 if (do_segments)
5278 {
dda8d76d 5279 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5280 printf (_("\nProgram Headers:\n"));
5281 else
5282 printf (_("\nProgram Headers:\n"));
76da6bbe 5283
f7a99963
NC
5284 if (is_32bit_elf)
5285 printf
5286 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5287 else if (do_wide)
5288 printf
5289 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5290 else
5291 {
5292 printf
5293 (_(" Type Offset VirtAddr PhysAddr\n"));
5294 printf
5295 (_(" FileSiz MemSiz Flags Align\n"));
5296 }
252b5132
RH
5297 }
5298
dda8d76d
NC
5299 for (i = 0, segment = filedata->program_headers;
5300 i < filedata->file_header.e_phnum;
b34976b6 5301 i++, segment++)
252b5132
RH
5302 {
5303 if (do_segments)
5304 {
dda8d76d 5305 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5306
5307 if (is_32bit_elf)
5308 {
5309 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5310 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5311 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5312 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5313 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5314 printf ("%c%c%c ",
5315 (segment->p_flags & PF_R ? 'R' : ' '),
5316 (segment->p_flags & PF_W ? 'W' : ' '),
5317 (segment->p_flags & PF_X ? 'E' : ' '));
5318 printf ("%#lx", (unsigned long) segment->p_align);
5319 }
d974e256
JJ
5320 else if (do_wide)
5321 {
5322 if ((unsigned long) segment->p_offset == segment->p_offset)
5323 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5324 else
5325 {
5326 print_vma (segment->p_offset, FULL_HEX);
5327 putchar (' ');
5328 }
5329
5330 print_vma (segment->p_vaddr, FULL_HEX);
5331 putchar (' ');
5332 print_vma (segment->p_paddr, FULL_HEX);
5333 putchar (' ');
5334
5335 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5336 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5337 else
5338 {
5339 print_vma (segment->p_filesz, FULL_HEX);
5340 putchar (' ');
5341 }
5342
5343 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5344 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5345 else
5346 {
f48e6c45 5347 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5348 }
5349
5350 printf (" %c%c%c ",
5351 (segment->p_flags & PF_R ? 'R' : ' '),
5352 (segment->p_flags & PF_W ? 'W' : ' '),
5353 (segment->p_flags & PF_X ? 'E' : ' '));
5354
5355 if ((unsigned long) segment->p_align == segment->p_align)
5356 printf ("%#lx", (unsigned long) segment->p_align);
5357 else
5358 {
5359 print_vma (segment->p_align, PREFIX_HEX);
5360 }
5361 }
f7a99963
NC
5362 else
5363 {
5364 print_vma (segment->p_offset, FULL_HEX);
5365 putchar (' ');
5366 print_vma (segment->p_vaddr, FULL_HEX);
5367 putchar (' ');
5368 print_vma (segment->p_paddr, FULL_HEX);
5369 printf ("\n ");
5370 print_vma (segment->p_filesz, FULL_HEX);
5371 putchar (' ');
5372 print_vma (segment->p_memsz, FULL_HEX);
5373 printf (" %c%c%c ",
5374 (segment->p_flags & PF_R ? 'R' : ' '),
5375 (segment->p_flags & PF_W ? 'W' : ' '),
5376 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5377 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5378 }
252b5132 5379
1a9ccd70
NC
5380 putc ('\n', stdout);
5381 }
f54498b4 5382
252b5132
RH
5383 switch (segment->p_type)
5384 {
1a9ccd70 5385 case PT_LOAD:
502d895c
NC
5386#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5387 required by the ELF standard, several programs, including the Linux
5388 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5389 if (previous_load
5390 && previous_load->p_vaddr > segment->p_vaddr)
5391 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5392#endif
1a9ccd70
NC
5393 if (segment->p_memsz < segment->p_filesz)
5394 error (_("the segment's file size is larger than its memory size\n"));
5395 previous_load = segment;
5396 break;
5397
5398 case PT_PHDR:
5399 /* PR 20815 - Verify that the program header is loaded into memory. */
5400 if (i > 0 && previous_load != NULL)
5401 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5402 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5403 {
5404 unsigned int j;
5405
dda8d76d 5406 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5407 {
5408 Elf_Internal_Phdr *load = filedata->program_headers + j;
5409 if (load->p_type == PT_LOAD
5410 && load->p_offset <= segment->p_offset
5411 && (load->p_offset + load->p_filesz
5412 >= segment->p_offset + segment->p_filesz)
5413 && load->p_vaddr <= segment->p_vaddr
5414 && (load->p_vaddr + load->p_filesz
5415 >= segment->p_vaddr + segment->p_filesz))
5416 break;
5417 }
dda8d76d 5418 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5419 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5420 }
5421 break;
5422
252b5132 5423 case PT_DYNAMIC:
978c4450 5424 if (filedata->dynamic_addr)
252b5132
RH
5425 error (_("more than one dynamic segment\n"));
5426
20737c13
AM
5427 /* By default, assume that the .dynamic section is the first
5428 section in the DYNAMIC segment. */
978c4450
AM
5429 filedata->dynamic_addr = segment->p_offset;
5430 filedata->dynamic_size = segment->p_filesz;
20737c13 5431
b2d38a17
NC
5432 /* Try to locate the .dynamic section. If there is
5433 a section header table, we can easily locate it. */
dda8d76d 5434 if (filedata->section_headers != NULL)
b2d38a17 5435 {
2cf0635d 5436 Elf_Internal_Shdr * sec;
b2d38a17 5437
dda8d76d 5438 sec = find_section (filedata, ".dynamic");
89fac5e3 5439 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5440 {
28f997cf
TG
5441 /* A corresponding .dynamic section is expected, but on
5442 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5443 if (!is_ia64_vms (filedata))
28f997cf 5444 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5445 break;
5446 }
5447
42bb2e33 5448 if (sec->sh_type == SHT_NOBITS)
20737c13 5449 {
978c4450 5450 filedata->dynamic_size = 0;
20737c13
AM
5451 break;
5452 }
42bb2e33 5453
978c4450
AM
5454 filedata->dynamic_addr = sec->sh_offset;
5455 filedata->dynamic_size = sec->sh_size;
b2d38a17 5456
8ac10c5b
L
5457 /* The PT_DYNAMIC segment, which is used by the run-time
5458 loader, should exactly match the .dynamic section. */
5459 if (do_checks
5460 && (filedata->dynamic_addr != segment->p_offset
5461 || filedata->dynamic_size != segment->p_filesz))
5462 warn (_("\
5463the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 5464 }
39e224f6
MW
5465
5466 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5467 segment. Check this after matching against the section headers
5468 so we don't warn on debuginfo file (which have NOBITS .dynamic
5469 sections). */
978c4450
AM
5470 if (filedata->dynamic_addr > filedata->file_size
5471 || (filedata->dynamic_size
5472 > filedata->file_size - filedata->dynamic_addr))
39e224f6
MW
5473 {
5474 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
978c4450 5475 filedata->dynamic_addr = filedata->dynamic_size = 0;
39e224f6 5476 }
252b5132
RH
5477 break;
5478
5479 case PT_INTERP:
978c4450
AM
5480 if (fseek (filedata->handle,
5481 filedata->archive_file_offset + (long) segment->p_offset,
fb52b2f4 5482 SEEK_SET))
252b5132
RH
5483 error (_("Unable to find program interpreter name\n"));
5484 else
5485 {
f8eae8b2 5486 char fmt [32];
9495b2e6 5487 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
5488
5489 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 5490 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 5491
978c4450
AM
5492 filedata->program_interpreter[0] = 0;
5493 if (fscanf (filedata->handle, fmt,
5494 filedata->program_interpreter) <= 0)
7bd7b3ef 5495 error (_("Unable to read program interpreter name\n"));
252b5132
RH
5496
5497 if (do_segments)
f54498b4 5498 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 5499 filedata->program_interpreter);
252b5132
RH
5500 }
5501 break;
5502 }
252b5132
RH
5503 }
5504
dda8d76d
NC
5505 if (do_segments
5506 && filedata->section_headers != NULL
5507 && filedata->string_table != NULL)
252b5132
RH
5508 {
5509 printf (_("\n Section to Segment mapping:\n"));
5510 printf (_(" Segment Sections...\n"));
5511
dda8d76d 5512 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5513 {
9ad5cbcf 5514 unsigned int j;
2cf0635d 5515 Elf_Internal_Shdr * section;
252b5132 5516
dda8d76d
NC
5517 segment = filedata->program_headers + i;
5518 section = filedata->section_headers + 1;
252b5132
RH
5519
5520 printf (" %2.2d ", i);
5521
dda8d76d 5522 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5523 {
f4638467
AM
5524 if (!ELF_TBSS_SPECIAL (section, segment)
5525 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5526 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5527 }
5528
5529 putc ('\n',stdout);
5530 }
5531 }
5532
32ec8896 5533 return TRUE;
252b5132
RH
5534}
5535
5536
d93f0186
NC
5537/* Find the file offset corresponding to VMA by using the program headers. */
5538
5539static long
dda8d76d 5540offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5541{
2cf0635d 5542 Elf_Internal_Phdr * seg;
d93f0186 5543
dda8d76d 5544 if (! get_program_headers (filedata))
d93f0186
NC
5545 {
5546 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5547 return (long) vma;
5548 }
5549
dda8d76d
NC
5550 for (seg = filedata->program_headers;
5551 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5552 ++seg)
5553 {
5554 if (seg->p_type != PT_LOAD)
5555 continue;
5556
5557 if (vma >= (seg->p_vaddr & -seg->p_align)
5558 && vma + size <= seg->p_vaddr + seg->p_filesz)
5559 return vma - seg->p_vaddr + seg->p_offset;
5560 }
5561
5562 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5563 (unsigned long) vma);
d93f0186
NC
5564 return (long) vma;
5565}
5566
5567
dda8d76d
NC
5568/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5569 If PROBE is true, this is just a probe and we do not generate any error
5570 messages if the load fails. */
049b0c3a
NC
5571
5572static bfd_boolean
dda8d76d 5573get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
252b5132 5574{
2cf0635d
NC
5575 Elf32_External_Shdr * shdrs;
5576 Elf_Internal_Shdr * internal;
dda8d76d
NC
5577 unsigned int i;
5578 unsigned int size = filedata->file_header.e_shentsize;
5579 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5580
5581 /* PR binutils/17531: Cope with unexpected section header sizes. */
5582 if (size == 0 || num == 0)
5583 return FALSE;
5584 if (size < sizeof * shdrs)
5585 {
5586 if (! probe)
5587 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5588 return FALSE;
5589 }
5590 if (!probe && size > sizeof * shdrs)
5591 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5592
dda8d76d 5593 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5594 size, num,
5595 probe ? NULL : _("section headers"));
5596 if (shdrs == NULL)
5597 return FALSE;
252b5132 5598
dda8d76d
NC
5599 free (filedata->section_headers);
5600 filedata->section_headers = (Elf_Internal_Shdr *)
5601 cmalloc (num, sizeof (Elf_Internal_Shdr));
5602 if (filedata->section_headers == NULL)
252b5132 5603 {
049b0c3a 5604 if (!probe)
8b73c356 5605 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5606 free (shdrs);
049b0c3a 5607 return FALSE;
252b5132
RH
5608 }
5609
dda8d76d 5610 for (i = 0, internal = filedata->section_headers;
560f3c1c 5611 i < num;
b34976b6 5612 i++, internal++)
252b5132
RH
5613 {
5614 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5615 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5616 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5617 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5618 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5619 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5620 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5621 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5622 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5623 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5624 if (!probe && internal->sh_link > num)
5625 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5626 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5627 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5628 }
5629
5630 free (shdrs);
049b0c3a 5631 return TRUE;
252b5132
RH
5632}
5633
dda8d76d
NC
5634/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5635
049b0c3a 5636static bfd_boolean
dda8d76d 5637get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
9ea033b2 5638{
dda8d76d
NC
5639 Elf64_External_Shdr * shdrs;
5640 Elf_Internal_Shdr * internal;
5641 unsigned int i;
5642 unsigned int size = filedata->file_header.e_shentsize;
5643 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5644
5645 /* PR binutils/17531: Cope with unexpected section header sizes. */
5646 if (size == 0 || num == 0)
5647 return FALSE;
dda8d76d 5648
049b0c3a
NC
5649 if (size < sizeof * shdrs)
5650 {
5651 if (! probe)
5652 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5653 return FALSE;
5654 }
dda8d76d 5655
049b0c3a
NC
5656 if (! probe && size > sizeof * shdrs)
5657 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5658
dda8d76d
NC
5659 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5660 filedata->file_header.e_shoff,
049b0c3a
NC
5661 size, num,
5662 probe ? NULL : _("section headers"));
5663 if (shdrs == NULL)
5664 return FALSE;
9ea033b2 5665
dda8d76d
NC
5666 free (filedata->section_headers);
5667 filedata->section_headers = (Elf_Internal_Shdr *)
5668 cmalloc (num, sizeof (Elf_Internal_Shdr));
5669 if (filedata->section_headers == NULL)
9ea033b2 5670 {
049b0c3a 5671 if (! probe)
8b73c356 5672 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5673 free (shdrs);
049b0c3a 5674 return FALSE;
9ea033b2
NC
5675 }
5676
dda8d76d 5677 for (i = 0, internal = filedata->section_headers;
560f3c1c 5678 i < num;
b34976b6 5679 i++, internal++)
9ea033b2
NC
5680 {
5681 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5682 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5683 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5684 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5685 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5686 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5687 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5688 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5689 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5690 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5691 if (!probe && internal->sh_link > num)
5692 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5693 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5694 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5695 }
5696
5697 free (shdrs);
049b0c3a 5698 return TRUE;
9ea033b2
NC
5699}
5700
252b5132 5701static Elf_Internal_Sym *
dda8d76d
NC
5702get_32bit_elf_symbols (Filedata * filedata,
5703 Elf_Internal_Shdr * section,
5704 unsigned long * num_syms_return)
252b5132 5705{
ba5cdace 5706 unsigned long number = 0;
dd24e3da 5707 Elf32_External_Sym * esyms = NULL;
ba5cdace 5708 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5709 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5710 Elf_Internal_Sym * psym;
b34976b6 5711 unsigned int j;
e3d39609 5712 elf_section_list * entry;
252b5132 5713
c9c1d674
EG
5714 if (section->sh_size == 0)
5715 {
5716 if (num_syms_return != NULL)
5717 * num_syms_return = 0;
5718 return NULL;
5719 }
5720
dd24e3da 5721 /* Run some sanity checks first. */
c9c1d674 5722 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5723 {
c9c1d674 5724 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5725 printable_section_name (filedata, section),
5726 (unsigned long) section->sh_entsize);
ba5cdace 5727 goto exit_point;
dd24e3da
NC
5728 }
5729
dda8d76d 5730 if (section->sh_size > filedata->file_size)
f54498b4
NC
5731 {
5732 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5733 printable_section_name (filedata, section),
5734 (unsigned long) section->sh_size);
f54498b4
NC
5735 goto exit_point;
5736 }
5737
dd24e3da
NC
5738 number = section->sh_size / section->sh_entsize;
5739
5740 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5741 {
c9c1d674 5742 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5743 (unsigned long) section->sh_size,
dda8d76d 5744 printable_section_name (filedata, section),
8066deb1 5745 (unsigned long) section->sh_entsize);
ba5cdace 5746 goto exit_point;
dd24e3da
NC
5747 }
5748
dda8d76d 5749 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5750 section->sh_size, _("symbols"));
dd24e3da 5751 if (esyms == NULL)
ba5cdace 5752 goto exit_point;
252b5132 5753
e3d39609 5754 shndx = NULL;
978c4450 5755 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5756 {
5757 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5758 continue;
5759
5760 if (shndx != NULL)
5761 {
5762 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5763 free (shndx);
5764 }
5765
5766 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5767 entry->hdr->sh_offset,
5768 1, entry->hdr->sh_size,
5769 _("symbol table section indices"));
5770 if (shndx == NULL)
5771 goto exit_point;
5772
5773 /* PR17531: file: heap-buffer-overflow */
5774 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5775 {
5776 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5777 printable_section_name (filedata, entry->hdr),
5778 (unsigned long) entry->hdr->sh_size,
5779 (unsigned long) section->sh_size);
5780 goto exit_point;
c9c1d674 5781 }
e3d39609 5782 }
9ad5cbcf 5783
3f5e193b 5784 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5785
5786 if (isyms == NULL)
5787 {
8b73c356
NC
5788 error (_("Out of memory reading %lu symbols\n"),
5789 (unsigned long) number);
dd24e3da 5790 goto exit_point;
252b5132
RH
5791 }
5792
dd24e3da 5793 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5794 {
5795 psym->st_name = BYTE_GET (esyms[j].st_name);
5796 psym->st_value = BYTE_GET (esyms[j].st_value);
5797 psym->st_size = BYTE_GET (esyms[j].st_size);
5798 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5799 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5800 psym->st_shndx
5801 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5802 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5803 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5804 psym->st_info = BYTE_GET (esyms[j].st_info);
5805 psym->st_other = BYTE_GET (esyms[j].st_other);
5806 }
5807
dd24e3da 5808 exit_point:
e3d39609
NC
5809 free (shndx);
5810 free (esyms);
252b5132 5811
ba5cdace
NC
5812 if (num_syms_return != NULL)
5813 * num_syms_return = isyms == NULL ? 0 : number;
5814
252b5132
RH
5815 return isyms;
5816}
5817
9ea033b2 5818static Elf_Internal_Sym *
dda8d76d
NC
5819get_64bit_elf_symbols (Filedata * filedata,
5820 Elf_Internal_Shdr * section,
5821 unsigned long * num_syms_return)
9ea033b2 5822{
ba5cdace
NC
5823 unsigned long number = 0;
5824 Elf64_External_Sym * esyms = NULL;
5825 Elf_External_Sym_Shndx * shndx = NULL;
5826 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5827 Elf_Internal_Sym * psym;
b34976b6 5828 unsigned int j;
e3d39609 5829 elf_section_list * entry;
9ea033b2 5830
c9c1d674
EG
5831 if (section->sh_size == 0)
5832 {
5833 if (num_syms_return != NULL)
5834 * num_syms_return = 0;
5835 return NULL;
5836 }
5837
dd24e3da 5838 /* Run some sanity checks first. */
c9c1d674 5839 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5840 {
c9c1d674 5841 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5842 printable_section_name (filedata, section),
8066deb1 5843 (unsigned long) section->sh_entsize);
ba5cdace 5844 goto exit_point;
dd24e3da
NC
5845 }
5846
dda8d76d 5847 if (section->sh_size > filedata->file_size)
f54498b4
NC
5848 {
5849 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5850 printable_section_name (filedata, section),
8066deb1 5851 (unsigned long) section->sh_size);
f54498b4
NC
5852 goto exit_point;
5853 }
5854
dd24e3da
NC
5855 number = section->sh_size / section->sh_entsize;
5856
5857 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5858 {
c9c1d674 5859 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5860 (unsigned long) section->sh_size,
dda8d76d 5861 printable_section_name (filedata, section),
8066deb1 5862 (unsigned long) section->sh_entsize);
ba5cdace 5863 goto exit_point;
dd24e3da
NC
5864 }
5865
dda8d76d 5866 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5867 section->sh_size, _("symbols"));
a6e9f9df 5868 if (!esyms)
ba5cdace 5869 goto exit_point;
9ea033b2 5870
e3d39609 5871 shndx = NULL;
978c4450 5872 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5873 {
5874 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5875 continue;
5876
5877 if (shndx != NULL)
5878 {
5879 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5880 free (shndx);
c9c1d674 5881 }
e3d39609
NC
5882
5883 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5884 entry->hdr->sh_offset,
5885 1, entry->hdr->sh_size,
5886 _("symbol table section indices"));
5887 if (shndx == NULL)
5888 goto exit_point;
5889
5890 /* PR17531: file: heap-buffer-overflow */
5891 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5892 {
5893 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5894 printable_section_name (filedata, entry->hdr),
5895 (unsigned long) entry->hdr->sh_size,
5896 (unsigned long) section->sh_size);
5897 goto exit_point;
5898 }
5899 }
9ad5cbcf 5900
3f5e193b 5901 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5902
5903 if (isyms == NULL)
5904 {
8b73c356
NC
5905 error (_("Out of memory reading %lu symbols\n"),
5906 (unsigned long) number);
ba5cdace 5907 goto exit_point;
9ea033b2
NC
5908 }
5909
ba5cdace 5910 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5911 {
5912 psym->st_name = BYTE_GET (esyms[j].st_name);
5913 psym->st_info = BYTE_GET (esyms[j].st_info);
5914 psym->st_other = BYTE_GET (esyms[j].st_other);
5915 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5916
4fbb74a6 5917 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5918 psym->st_shndx
5919 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5920 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5921 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5922
66543521
AM
5923 psym->st_value = BYTE_GET (esyms[j].st_value);
5924 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5925 }
5926
ba5cdace 5927 exit_point:
e3d39609
NC
5928 free (shndx);
5929 free (esyms);
ba5cdace
NC
5930
5931 if (num_syms_return != NULL)
5932 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5933
5934 return isyms;
5935}
5936
d1133906 5937static const char *
dda8d76d 5938get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 5939{
5477e8a0 5940 static char buff[1024];
2cf0635d 5941 char * p = buff;
32ec8896
NC
5942 unsigned int field_size = is_32bit_elf ? 8 : 16;
5943 signed int sindex;
5944 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5945 bfd_vma os_flags = 0;
5946 bfd_vma proc_flags = 0;
5947 bfd_vma unknown_flags = 0;
148b93f2 5948 static const struct
5477e8a0 5949 {
2cf0635d 5950 const char * str;
32ec8896 5951 unsigned int len;
5477e8a0
L
5952 }
5953 flags [] =
5954 {
cfcac11d
NC
5955 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5956 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5957 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5958 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5959 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5960 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5961 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5962 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5963 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5964 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5965 /* IA-64 specific. */
5966 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5967 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5968 /* IA-64 OpenVMS specific. */
5969 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5970 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5971 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5972 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5973 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5974 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5975 /* Generic. */
cfcac11d 5976 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5977 /* SPARC specific. */
77115a4a 5978 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
5979 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
5980 /* ARM specific. */
5981 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 5982 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
5983 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
5984 /* GNU specific. */
5985 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
5986 /* VLE specific. */
5987 /* 25 */ { STRING_COMMA_LEN ("VLE") },
5477e8a0
L
5988 };
5989
5990 if (do_section_details)
5991 {
8d5ff12c
L
5992 sprintf (buff, "[%*.*lx]: ",
5993 field_size, field_size, (unsigned long) sh_flags);
5994 p += field_size + 4;
5477e8a0 5995 }
76da6bbe 5996
d1133906
NC
5997 while (sh_flags)
5998 {
5999 bfd_vma flag;
6000
6001 flag = sh_flags & - sh_flags;
6002 sh_flags &= ~ flag;
76da6bbe 6003
5477e8a0 6004 if (do_section_details)
d1133906 6005 {
5477e8a0
L
6006 switch (flag)
6007 {
91d6fa6a
NC
6008 case SHF_WRITE: sindex = 0; break;
6009 case SHF_ALLOC: sindex = 1; break;
6010 case SHF_EXECINSTR: sindex = 2; break;
6011 case SHF_MERGE: sindex = 3; break;
6012 case SHF_STRINGS: sindex = 4; break;
6013 case SHF_INFO_LINK: sindex = 5; break;
6014 case SHF_LINK_ORDER: sindex = 6; break;
6015 case SHF_OS_NONCONFORMING: sindex = 7; break;
6016 case SHF_GROUP: sindex = 8; break;
6017 case SHF_TLS: sindex = 9; break;
18ae9cc1 6018 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6019 case SHF_COMPRESSED: sindex = 20; break;
a91e1603 6020 case SHF_GNU_MBIND: sindex = 24; break;
76da6bbe 6021
5477e8a0 6022 default:
91d6fa6a 6023 sindex = -1;
dda8d76d 6024 switch (filedata->file_header.e_machine)
148b93f2 6025 {
cfcac11d 6026 case EM_IA_64:
148b93f2 6027 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6028 sindex = 10;
148b93f2 6029 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6030 sindex = 11;
148b93f2 6031#ifdef BFD64
dda8d76d 6032 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6033 switch (flag)
6034 {
91d6fa6a
NC
6035 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6036 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6037 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6038 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6039 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6040 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6041 default: break;
6042 }
6043#endif
cfcac11d
NC
6044 break;
6045
caa83f8b 6046 case EM_386:
22abe556 6047 case EM_IAMCU:
caa83f8b 6048 case EM_X86_64:
7f502d6c 6049 case EM_L1OM:
7a9068fe 6050 case EM_K1OM:
cfcac11d
NC
6051 case EM_OLD_SPARCV9:
6052 case EM_SPARC32PLUS:
6053 case EM_SPARCV9:
6054 case EM_SPARC:
18ae9cc1 6055 if (flag == SHF_ORDERED)
91d6fa6a 6056 sindex = 19;
cfcac11d 6057 break;
ac4c9b04
MG
6058
6059 case EM_ARM:
6060 switch (flag)
6061 {
6062 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6063 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6064 case SHF_COMDEF: sindex = 23; break;
6065 default: break;
6066 }
6067 break;
83eef883
AFB
6068 case EM_PPC:
6069 if (flag == SHF_PPC_VLE)
6070 sindex = 25;
6071 break;
ac4c9b04 6072
cfcac11d
NC
6073 default:
6074 break;
148b93f2 6075 }
5477e8a0
L
6076 }
6077
91d6fa6a 6078 if (sindex != -1)
5477e8a0 6079 {
8d5ff12c
L
6080 if (p != buff + field_size + 4)
6081 {
6082 if (size < (10 + 2))
bee0ee85
NC
6083 {
6084 warn (_("Internal error: not enough buffer room for section flag info"));
6085 return _("<unknown>");
6086 }
8d5ff12c
L
6087 size -= 2;
6088 *p++ = ',';
6089 *p++ = ' ';
6090 }
6091
91d6fa6a
NC
6092 size -= flags [sindex].len;
6093 p = stpcpy (p, flags [sindex].str);
5477e8a0 6094 }
3b22753a 6095 else if (flag & SHF_MASKOS)
8d5ff12c 6096 os_flags |= flag;
d1133906 6097 else if (flag & SHF_MASKPROC)
8d5ff12c 6098 proc_flags |= flag;
d1133906 6099 else
8d5ff12c 6100 unknown_flags |= flag;
5477e8a0
L
6101 }
6102 else
6103 {
6104 switch (flag)
6105 {
6106 case SHF_WRITE: *p = 'W'; break;
6107 case SHF_ALLOC: *p = 'A'; break;
6108 case SHF_EXECINSTR: *p = 'X'; break;
6109 case SHF_MERGE: *p = 'M'; break;
6110 case SHF_STRINGS: *p = 'S'; break;
6111 case SHF_INFO_LINK: *p = 'I'; break;
6112 case SHF_LINK_ORDER: *p = 'L'; break;
6113 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6114 case SHF_GROUP: *p = 'G'; break;
6115 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6116 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6117 case SHF_COMPRESSED: *p = 'C'; break;
a91e1603 6118 case SHF_GNU_MBIND: *p = 'D'; break;
5477e8a0
L
6119
6120 default:
dda8d76d
NC
6121 if ((filedata->file_header.e_machine == EM_X86_64
6122 || filedata->file_header.e_machine == EM_L1OM
6123 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6124 && flag == SHF_X86_64_LARGE)
6125 *p = 'l';
dda8d76d 6126 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6127 && flag == SHF_ARM_PURECODE)
91f68a68 6128 *p = 'y';
dda8d76d 6129 else if (filedata->file_header.e_machine == EM_PPC
83eef883
AFB
6130 && flag == SHF_PPC_VLE)
6131 *p = 'v';
5477e8a0
L
6132 else if (flag & SHF_MASKOS)
6133 {
6134 *p = 'o';
6135 sh_flags &= ~ SHF_MASKOS;
6136 }
6137 else if (flag & SHF_MASKPROC)
6138 {
6139 *p = 'p';
6140 sh_flags &= ~ SHF_MASKPROC;
6141 }
6142 else
6143 *p = 'x';
6144 break;
6145 }
6146 p++;
d1133906
NC
6147 }
6148 }
76da6bbe 6149
8d5ff12c
L
6150 if (do_section_details)
6151 {
6152 if (os_flags)
6153 {
6154 size -= 5 + field_size;
6155 if (p != buff + field_size + 4)
6156 {
6157 if (size < (2 + 1))
bee0ee85
NC
6158 {
6159 warn (_("Internal error: not enough buffer room for section flag info"));
6160 return _("<unknown>");
6161 }
8d5ff12c
L
6162 size -= 2;
6163 *p++ = ',';
6164 *p++ = ' ';
6165 }
6166 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6167 (unsigned long) os_flags);
6168 p += 5 + field_size;
6169 }
6170 if (proc_flags)
6171 {
6172 size -= 7 + field_size;
6173 if (p != buff + field_size + 4)
6174 {
6175 if (size < (2 + 1))
bee0ee85
NC
6176 {
6177 warn (_("Internal error: not enough buffer room for section flag info"));
6178 return _("<unknown>");
6179 }
8d5ff12c
L
6180 size -= 2;
6181 *p++ = ',';
6182 *p++ = ' ';
6183 }
6184 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6185 (unsigned long) proc_flags);
6186 p += 7 + field_size;
6187 }
6188 if (unknown_flags)
6189 {
6190 size -= 10 + field_size;
6191 if (p != buff + field_size + 4)
6192 {
6193 if (size < (2 + 1))
bee0ee85
NC
6194 {
6195 warn (_("Internal error: not enough buffer room for section flag info"));
6196 return _("<unknown>");
6197 }
8d5ff12c
L
6198 size -= 2;
6199 *p++ = ',';
6200 *p++ = ' ';
6201 }
2b692964 6202 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6203 (unsigned long) unknown_flags);
6204 p += 10 + field_size;
6205 }
6206 }
6207
e9e44622 6208 *p = '\0';
d1133906
NC
6209 return buff;
6210}
6211
5844b465 6212static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6213get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6214{
6215 if (is_32bit_elf)
6216 {
6217 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6218
ebdf1ebf
NC
6219 if (size < sizeof (* echdr))
6220 {
6221 error (_("Compressed section is too small even for a compression header\n"));
6222 return 0;
6223 }
6224
77115a4a
L
6225 chdr->ch_type = BYTE_GET (echdr->ch_type);
6226 chdr->ch_size = BYTE_GET (echdr->ch_size);
6227 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6228 return sizeof (*echdr);
6229 }
6230 else
6231 {
6232 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6233
ebdf1ebf
NC
6234 if (size < sizeof (* echdr))
6235 {
6236 error (_("Compressed section is too small even for a compression header\n"));
6237 return 0;
6238 }
6239
77115a4a
L
6240 chdr->ch_type = BYTE_GET (echdr->ch_type);
6241 chdr->ch_size = BYTE_GET (echdr->ch_size);
6242 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6243 return sizeof (*echdr);
6244 }
6245}
6246
32ec8896 6247static bfd_boolean
dda8d76d 6248process_section_headers (Filedata * filedata)
252b5132 6249{
2cf0635d 6250 Elf_Internal_Shdr * section;
b34976b6 6251 unsigned int i;
252b5132 6252
8fb879cd 6253 free (filedata->section_headers);
dda8d76d 6254 filedata->section_headers = NULL;
978c4450
AM
6255 free (filedata->dynamic_symbols);
6256 filedata->dynamic_symbols = NULL;
6257 filedata->num_dynamic_syms = 0;
6258 free (filedata->dynamic_strings);
6259 filedata->dynamic_strings = NULL;
6260 filedata->dynamic_strings_length = 0;
6261 free (filedata->dynamic_syminfo);
6262 filedata->dynamic_syminfo = NULL;
6263 while (filedata->symtab_shndx_list != NULL)
8ff66993 6264 {
978c4450
AM
6265 elf_section_list *next = filedata->symtab_shndx_list->next;
6266 free (filedata->symtab_shndx_list);
6267 filedata->symtab_shndx_list = next;
8ff66993 6268 }
252b5132 6269
dda8d76d 6270 if (filedata->file_header.e_shnum == 0)
252b5132 6271 {
82f2dbf7 6272 /* PR binutils/12467. */
dda8d76d 6273 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6274 {
6275 warn (_("possibly corrupt ELF file header - it has a non-zero"
6276 " section header offset, but no section headers\n"));
6277 return FALSE;
6278 }
82f2dbf7 6279 else if (do_sections)
252b5132
RH
6280 printf (_("\nThere are no sections in this file.\n"));
6281
32ec8896 6282 return TRUE;
252b5132
RH
6283 }
6284
6285 if (do_sections && !do_header)
d3a49aa8
AM
6286 printf (ngettext ("There is %d section header, "
6287 "starting at offset 0x%lx:\n",
6288 "There are %d section headers, "
6289 "starting at offset 0x%lx:\n",
dda8d76d
NC
6290 filedata->file_header.e_shnum),
6291 filedata->file_header.e_shnum,
6292 (unsigned long) filedata->file_header.e_shoff);
252b5132 6293
9ea033b2
NC
6294 if (is_32bit_elf)
6295 {
dda8d76d 6296 if (! get_32bit_section_headers (filedata, FALSE))
32ec8896
NC
6297 return FALSE;
6298 }
6299 else
6300 {
dda8d76d 6301 if (! get_64bit_section_headers (filedata, FALSE))
32ec8896 6302 return FALSE;
9ea033b2 6303 }
252b5132
RH
6304
6305 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6306 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6307 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6308 {
dda8d76d 6309 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6310
c256ffe7
JJ
6311 if (section->sh_size != 0)
6312 {
dda8d76d
NC
6313 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6314 1, section->sh_size,
6315 _("string table"));
0de14b54 6316
dda8d76d 6317 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6318 }
252b5132
RH
6319 }
6320
6321 /* Scan the sections for the dynamic symbol table
e3c8793a 6322 and dynamic string table and debug sections. */
89fac5e3 6323 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6324 switch (filedata->file_header.e_machine)
89fac5e3
RS
6325 {
6326 case EM_MIPS:
6327 case EM_MIPS_RS3_LE:
6328 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6329 FDE addresses. However, the ABI also has a semi-official ILP32
6330 variant for which the normal FDE address size rules apply.
6331
6332 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6333 section, where XX is the size of longs in bits. Unfortunately,
6334 earlier compilers provided no way of distinguishing ILP32 objects
6335 from LP64 objects, so if there's any doubt, we should assume that
6336 the official LP64 form is being used. */
dda8d76d
NC
6337 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6338 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6339 eh_addr_size = 8;
6340 break;
0f56a26a
DD
6341
6342 case EM_H8_300:
6343 case EM_H8_300H:
dda8d76d 6344 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6345 {
6346 case E_H8_MACH_H8300:
6347 case E_H8_MACH_H8300HN:
6348 case E_H8_MACH_H8300SN:
6349 case E_H8_MACH_H8300SXN:
6350 eh_addr_size = 2;
6351 break;
6352 case E_H8_MACH_H8300H:
6353 case E_H8_MACH_H8300S:
6354 case E_H8_MACH_H8300SX:
6355 eh_addr_size = 4;
6356 break;
6357 }
f4236fe4
DD
6358 break;
6359
ff7eeb89 6360 case EM_M32C_OLD:
f4236fe4 6361 case EM_M32C:
dda8d76d 6362 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6363 {
6364 case EF_M32C_CPU_M16C:
6365 eh_addr_size = 2;
6366 break;
6367 }
6368 break;
89fac5e3
RS
6369 }
6370
76ca31c0
NC
6371#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6372 do \
6373 { \
6374 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6375 if (section->sh_entsize != expected_entsize) \
9dd3a467 6376 { \
76ca31c0
NC
6377 char buf[40]; \
6378 sprintf_vma (buf, section->sh_entsize); \
6379 /* Note: coded this way so that there is a single string for \
6380 translation. */ \
6381 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6382 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6383 (unsigned) expected_entsize); \
9dd3a467 6384 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6385 } \
6386 } \
08d8fa11 6387 while (0)
9dd3a467
NC
6388
6389#define CHECK_ENTSIZE(section, i, type) \
1b513401 6390 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
6391 sizeof (Elf64_External_##type))
6392
dda8d76d
NC
6393 for (i = 0, section = filedata->section_headers;
6394 i < filedata->file_header.e_shnum;
b34976b6 6395 i++, section++)
252b5132 6396 {
2cf0635d 6397 char * name = SECTION_NAME (section);
252b5132 6398
1b513401
NC
6399 /* Run some sanity checks on the headers and
6400 possibly fill in some file data as well. */
6401 switch (section->sh_type)
252b5132 6402 {
1b513401 6403 case SHT_DYNSYM:
978c4450 6404 if (filedata->dynamic_symbols != NULL)
252b5132
RH
6405 {
6406 error (_("File contains multiple dynamic symbol tables\n"));
6407 continue;
6408 }
6409
08d8fa11 6410 CHECK_ENTSIZE (section, i, Sym);
978c4450
AM
6411 filedata->dynamic_symbols
6412 = GET_ELF_SYMBOLS (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 6413 filedata->dynamic_symtab_section = section;
1b513401
NC
6414 break;
6415
6416 case SHT_STRTAB:
6417 if (streq (name, ".dynstr"))
252b5132 6418 {
1b513401
NC
6419 if (filedata->dynamic_strings != NULL)
6420 {
6421 error (_("File contains multiple dynamic string tables\n"));
6422 continue;
6423 }
6424
6425 filedata->dynamic_strings
6426 = (char *) get_data (NULL, filedata, section->sh_offset,
6427 1, section->sh_size, _("dynamic strings"));
6428 filedata->dynamic_strings_length
6429 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 6430 filedata->dynamic_strtab_section = section;
252b5132 6431 }
1b513401
NC
6432 break;
6433
6434 case SHT_SYMTAB_SHNDX:
6435 {
6436 elf_section_list * entry = xmalloc (sizeof * entry);
6437
6438 entry->hdr = section;
6439 entry->next = filedata->symtab_shndx_list;
6440 filedata->symtab_shndx_list = entry;
6441 }
6442 break;
6443
6444 case SHT_SYMTAB:
6445 CHECK_ENTSIZE (section, i, Sym);
6446 break;
6447
6448 case SHT_GROUP:
6449 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6450 break;
252b5132 6451
1b513401
NC
6452 case SHT_REL:
6453 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 6454 if (do_checks && section->sh_size == 0)
1b513401
NC
6455 warn (_("Section '%s': zero-sized relocation section\n"), name);
6456 break;
6457
6458 case SHT_RELA:
6459 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 6460 if (do_checks && section->sh_size == 0)
1b513401
NC
6461 warn (_("Section '%s': zero-sized relocation section\n"), name);
6462 break;
6463
6464 case SHT_NOTE:
6465 case SHT_PROGBITS:
546cb2d8
NC
6466 /* Having a zero sized section is not illegal according to the
6467 ELF standard, but it might be an indication that something
6468 is wrong. So issue a warning if we are running in lint mode. */
6469 if (do_checks && section->sh_size == 0)
1b513401
NC
6470 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
6471 break;
6472
6473 default:
6474 break;
6475 }
6476
6477 if ((do_debugging || do_debug_info || do_debug_abbrevs
6478 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
6479 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e4b7104b 6480 || do_debug_str || do_debug_str_offsets || do_debug_loc || do_debug_ranges
1b513401
NC
6481 || do_debug_addr || do_debug_cu_index || do_debug_links)
6482 && (const_strneq (name, ".debug_")
6483 || const_strneq (name, ".zdebug_")))
252b5132 6484 {
1b315056
CS
6485 if (name[1] == 'z')
6486 name += sizeof (".zdebug_") - 1;
6487 else
6488 name += sizeof (".debug_") - 1;
252b5132
RH
6489
6490 if (do_debugging
4723351a
CC
6491 || (do_debug_info && const_strneq (name, "info"))
6492 || (do_debug_info && const_strneq (name, "types"))
6493 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
6494 || (do_debug_lines && strcmp (name, "line") == 0)
6495 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
6496 || (do_debug_pubnames && const_strneq (name, "pubnames"))
6497 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
6498 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
6499 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
6500 || (do_debug_aranges && const_strneq (name, "aranges"))
6501 || (do_debug_ranges && const_strneq (name, "ranges"))
77145576 6502 || (do_debug_ranges && const_strneq (name, "rnglists"))
4723351a
CC
6503 || (do_debug_frames && const_strneq (name, "frame"))
6504 || (do_debug_macinfo && const_strneq (name, "macinfo"))
6505 || (do_debug_macinfo && const_strneq (name, "macro"))
6506 || (do_debug_str && const_strneq (name, "str"))
e4b7104b 6507 || (do_debug_str_offsets && const_strneq (name, "str_offsets"))
4723351a 6508 || (do_debug_loc && const_strneq (name, "loc"))
77145576 6509 || (do_debug_loc && const_strneq (name, "loclists"))
657d0d47
CC
6510 || (do_debug_addr && const_strneq (name, "addr"))
6511 || (do_debug_cu_index && const_strneq (name, "cu_index"))
6512 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 6513 )
6431e409 6514 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6515 }
a262ae96 6516 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6517 else if ((do_debugging || do_debug_info)
0112cd26 6518 && const_strneq (name, ".gnu.linkonce.wi."))
6431e409 6519 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6520 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6521 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6522 else if (do_gdb_index && (streq (name, ".gdb_index")
6523 || streq (name, ".debug_names")))
6431e409 6524 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6525 /* Trace sections for Itanium VMS. */
6526 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6527 || do_trace_aranges)
6528 && const_strneq (name, ".trace_"))
6529 {
6530 name += sizeof (".trace_") - 1;
6531
6532 if (do_debugging
6533 || (do_trace_info && streq (name, "info"))
6534 || (do_trace_abbrevs && streq (name, "abbrev"))
6535 || (do_trace_aranges && streq (name, "aranges"))
6536 )
6431e409 6537 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6538 }
dda8d76d
NC
6539 else if ((do_debugging || do_debug_links)
6540 && (const_strneq (name, ".gnu_debuglink")
6541 || const_strneq (name, ".gnu_debugaltlink")))
6431e409 6542 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6543 }
6544
6545 if (! do_sections)
32ec8896 6546 return TRUE;
252b5132 6547
dda8d76d 6548 if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6549 printf (_("\nSection Headers:\n"));
6550 else
6551 printf (_("\nSection Header:\n"));
76da6bbe 6552
f7a99963 6553 if (is_32bit_elf)
595cf52e 6554 {
5477e8a0 6555 if (do_section_details)
595cf52e
L
6556 {
6557 printf (_(" [Nr] Name\n"));
5477e8a0 6558 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6559 }
6560 else
6561 printf
6562 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6563 }
d974e256 6564 else if (do_wide)
595cf52e 6565 {
5477e8a0 6566 if (do_section_details)
595cf52e
L
6567 {
6568 printf (_(" [Nr] Name\n"));
5477e8a0 6569 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6570 }
6571 else
6572 printf
6573 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6574 }
f7a99963
NC
6575 else
6576 {
5477e8a0 6577 if (do_section_details)
595cf52e
L
6578 {
6579 printf (_(" [Nr] Name\n"));
5477e8a0
L
6580 printf (_(" Type Address Offset Link\n"));
6581 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6582 }
6583 else
6584 {
6585 printf (_(" [Nr] Name Type Address Offset\n"));
6586 printf (_(" Size EntSize Flags Link Info Align\n"));
6587 }
f7a99963 6588 }
252b5132 6589
5477e8a0
L
6590 if (do_section_details)
6591 printf (_(" Flags\n"));
6592
dda8d76d
NC
6593 for (i = 0, section = filedata->section_headers;
6594 i < filedata->file_header.e_shnum;
b34976b6 6595 i++, section++)
252b5132 6596 {
dd905818
NC
6597 /* Run some sanity checks on the section header. */
6598
6599 /* Check the sh_link field. */
6600 switch (section->sh_type)
6601 {
285e3f99
AM
6602 case SHT_REL:
6603 case SHT_RELA:
6604 if (section->sh_link == 0
6605 && (filedata->file_header.e_type == ET_EXEC
6606 || filedata->file_header.e_type == ET_DYN))
6607 /* A dynamic relocation section where all entries use a
6608 zero symbol index need not specify a symtab section. */
6609 break;
6610 /* Fall through. */
dd905818
NC
6611 case SHT_SYMTAB_SHNDX:
6612 case SHT_GROUP:
6613 case SHT_HASH:
6614 case SHT_GNU_HASH:
6615 case SHT_GNU_versym:
285e3f99 6616 if (section->sh_link == 0
dda8d76d
NC
6617 || section->sh_link >= filedata->file_header.e_shnum
6618 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6619 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6620 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6621 i, section->sh_link);
6622 break;
6623
6624 case SHT_DYNAMIC:
6625 case SHT_SYMTAB:
6626 case SHT_DYNSYM:
6627 case SHT_GNU_verneed:
6628 case SHT_GNU_verdef:
6629 case SHT_GNU_LIBLIST:
285e3f99 6630 if (section->sh_link == 0
dda8d76d
NC
6631 || section->sh_link >= filedata->file_header.e_shnum
6632 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6633 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6634 i, section->sh_link);
6635 break;
6636
6637 case SHT_INIT_ARRAY:
6638 case SHT_FINI_ARRAY:
6639 case SHT_PREINIT_ARRAY:
6640 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6641 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6642 i, section->sh_link);
6643 break;
6644
6645 default:
6646 /* FIXME: Add support for target specific section types. */
6647#if 0 /* Currently we do not check other section types as there are too
6648 many special cases. Stab sections for example have a type
6649 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6650 section. */
6651 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6652 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6653 i, section->sh_link);
6654#endif
6655 break;
6656 }
6657
6658 /* Check the sh_info field. */
6659 switch (section->sh_type)
6660 {
6661 case SHT_REL:
6662 case SHT_RELA:
285e3f99
AM
6663 if (section->sh_info == 0
6664 && (filedata->file_header.e_type == ET_EXEC
6665 || filedata->file_header.e_type == ET_DYN))
6666 /* Dynamic relocations apply to segments, so they do not
6667 need to specify the section they relocate. */
6668 break;
6669 if (section->sh_info == 0
dda8d76d
NC
6670 || section->sh_info >= filedata->file_header.e_shnum
6671 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6672 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6673 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6674 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6675 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6676 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6677 /* FIXME: Are other section types valid ? */
dda8d76d 6678 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6679 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6680 i, section->sh_info);
dd905818
NC
6681 break;
6682
6683 case SHT_DYNAMIC:
6684 case SHT_HASH:
6685 case SHT_SYMTAB_SHNDX:
6686 case SHT_INIT_ARRAY:
6687 case SHT_FINI_ARRAY:
6688 case SHT_PREINIT_ARRAY:
6689 if (section->sh_info != 0)
6690 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6691 i, section->sh_info);
6692 break;
6693
6694 case SHT_GROUP:
6695 case SHT_SYMTAB:
6696 case SHT_DYNSYM:
6697 /* A symbol index - we assume that it is valid. */
6698 break;
6699
6700 default:
6701 /* FIXME: Add support for target specific section types. */
6702 if (section->sh_type == SHT_NOBITS)
6703 /* NOBITS section headers with non-zero sh_info fields can be
6704 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6705 information. The stripped sections have their headers
6706 preserved but their types set to SHT_NOBITS. So do not check
6707 this type of section. */
dd905818
NC
6708 ;
6709 else if (section->sh_flags & SHF_INFO_LINK)
6710 {
dda8d76d 6711 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6712 warn (_("[%2u]: Expected link to another section in info field"), i);
6713 }
a91e1603
L
6714 else if (section->sh_type < SHT_LOOS
6715 && (section->sh_flags & SHF_GNU_MBIND) == 0
6716 && section->sh_info != 0)
dd905818
NC
6717 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6718 i, section->sh_info);
6719 break;
6720 }
6721
3e6b6445 6722 /* Check the sh_size field. */
dda8d76d 6723 if (section->sh_size > filedata->file_size
3e6b6445
NC
6724 && section->sh_type != SHT_NOBITS
6725 && section->sh_type != SHT_NULL
6726 && section->sh_type < SHT_LOOS)
6727 warn (_("Size of section %u is larger than the entire file!\n"), i);
6728
7bfd842d 6729 printf (" [%2u] ", i);
5477e8a0 6730 if (do_section_details)
dda8d76d 6731 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6732 else
74e1a04b 6733 print_symbol (-17, SECTION_NAME (section));
0b4362b0 6734
ea52a088 6735 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6736 get_section_type_name (filedata, section->sh_type));
0b4362b0 6737
f7a99963
NC
6738 if (is_32bit_elf)
6739 {
cfcac11d
NC
6740 const char * link_too_big = NULL;
6741
f7a99963 6742 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6743
f7a99963
NC
6744 printf ( " %6.6lx %6.6lx %2.2lx",
6745 (unsigned long) section->sh_offset,
6746 (unsigned long) section->sh_size,
6747 (unsigned long) section->sh_entsize);
d1133906 6748
5477e8a0
L
6749 if (do_section_details)
6750 fputs (" ", stdout);
6751 else
dda8d76d 6752 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6753
dda8d76d 6754 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6755 {
6756 link_too_big = "";
6757 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6758 an error but it can have special values in Solaris binaries. */
dda8d76d 6759 switch (filedata->file_header.e_machine)
cfcac11d 6760 {
caa83f8b 6761 case EM_386:
22abe556 6762 case EM_IAMCU:
caa83f8b 6763 case EM_X86_64:
7f502d6c 6764 case EM_L1OM:
7a9068fe 6765 case EM_K1OM:
cfcac11d
NC
6766 case EM_OLD_SPARCV9:
6767 case EM_SPARC32PLUS:
6768 case EM_SPARCV9:
6769 case EM_SPARC:
6770 if (section->sh_link == (SHN_BEFORE & 0xffff))
6771 link_too_big = "BEFORE";
6772 else if (section->sh_link == (SHN_AFTER & 0xffff))
6773 link_too_big = "AFTER";
6774 break;
6775 default:
6776 break;
6777 }
6778 }
6779
6780 if (do_section_details)
6781 {
6782 if (link_too_big != NULL && * link_too_big)
6783 printf ("<%s> ", link_too_big);
6784 else
6785 printf ("%2u ", section->sh_link);
6786 printf ("%3u %2lu\n", section->sh_info,
6787 (unsigned long) section->sh_addralign);
6788 }
6789 else
6790 printf ("%2u %3u %2lu\n",
6791 section->sh_link,
6792 section->sh_info,
6793 (unsigned long) section->sh_addralign);
6794
6795 if (link_too_big && ! * link_too_big)
6796 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6797 i, section->sh_link);
f7a99963 6798 }
d974e256
JJ
6799 else if (do_wide)
6800 {
6801 print_vma (section->sh_addr, LONG_HEX);
6802
6803 if ((long) section->sh_offset == section->sh_offset)
6804 printf (" %6.6lx", (unsigned long) section->sh_offset);
6805 else
6806 {
6807 putchar (' ');
6808 print_vma (section->sh_offset, LONG_HEX);
6809 }
6810
6811 if ((unsigned long) section->sh_size == section->sh_size)
6812 printf (" %6.6lx", (unsigned long) section->sh_size);
6813 else
6814 {
6815 putchar (' ');
6816 print_vma (section->sh_size, LONG_HEX);
6817 }
6818
6819 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6820 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6821 else
6822 {
6823 putchar (' ');
6824 print_vma (section->sh_entsize, LONG_HEX);
6825 }
6826
5477e8a0
L
6827 if (do_section_details)
6828 fputs (" ", stdout);
6829 else
dda8d76d 6830 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6831
72de5009 6832 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6833
6834 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6835 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6836 else
6837 {
6838 print_vma (section->sh_addralign, DEC);
6839 putchar ('\n');
6840 }
6841 }
5477e8a0 6842 else if (do_section_details)
595cf52e 6843 {
55cc53e9 6844 putchar (' ');
595cf52e
L
6845 print_vma (section->sh_addr, LONG_HEX);
6846 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 6847 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
6848 else
6849 {
6850 printf (" ");
6851 print_vma (section->sh_offset, LONG_HEX);
6852 }
72de5009 6853 printf (" %u\n ", section->sh_link);
595cf52e 6854 print_vma (section->sh_size, LONG_HEX);
5477e8a0 6855 putchar (' ');
595cf52e
L
6856 print_vma (section->sh_entsize, LONG_HEX);
6857
72de5009
AM
6858 printf (" %-16u %lu\n",
6859 section->sh_info,
595cf52e
L
6860 (unsigned long) section->sh_addralign);
6861 }
f7a99963
NC
6862 else
6863 {
6864 putchar (' ');
6865 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
6866 if ((long) section->sh_offset == section->sh_offset)
6867 printf (" %8.8lx", (unsigned long) section->sh_offset);
6868 else
6869 {
6870 printf (" ");
6871 print_vma (section->sh_offset, LONG_HEX);
6872 }
f7a99963
NC
6873 printf ("\n ");
6874 print_vma (section->sh_size, LONG_HEX);
6875 printf (" ");
6876 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 6877
dda8d76d 6878 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6879
72de5009
AM
6880 printf (" %2u %3u %lu\n",
6881 section->sh_link,
6882 section->sh_info,
f7a99963
NC
6883 (unsigned long) section->sh_addralign);
6884 }
5477e8a0
L
6885
6886 if (do_section_details)
77115a4a 6887 {
dda8d76d 6888 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
6889 if ((section->sh_flags & SHF_COMPRESSED) != 0)
6890 {
6891 /* Minimum section size is 12 bytes for 32-bit compression
6892 header + 12 bytes for compressed data header. */
6893 unsigned char buf[24];
d8024a91 6894
77115a4a 6895 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 6896 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
6897 sizeof (buf), _("compression header")))
6898 {
6899 Elf_Internal_Chdr chdr;
d8024a91 6900
5844b465
NC
6901 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
6902 printf (_(" [<corrupt>]\n"));
77115a4a 6903 else
5844b465
NC
6904 {
6905 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
6906 printf (" ZLIB, ");
6907 else
6908 printf (_(" [<unknown>: 0x%x], "),
6909 chdr.ch_type);
6910 print_vma (chdr.ch_size, LONG_HEX);
6911 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
6912 }
77115a4a
L
6913 }
6914 }
6915 }
252b5132
RH
6916 }
6917
5477e8a0 6918 if (!do_section_details)
3dbcc61d 6919 {
9fb71ee4
NC
6920 /* The ordering of the letters shown here matches the ordering of the
6921 corresponding SHF_xxx values, and hence the order in which these
6922 letters will be displayed to the user. */
6923 printf (_("Key to Flags:\n\
6924 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
6925 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 6926 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
dda8d76d
NC
6927 if (filedata->file_header.e_machine == EM_X86_64
6928 || filedata->file_header.e_machine == EM_L1OM
6929 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 6930 printf (_("l (large), "));
dda8d76d 6931 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 6932 printf (_("y (purecode), "));
dda8d76d 6933 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 6934 printf (_("v (VLE), "));
9fb71ee4 6935 printf ("p (processor specific)\n");
0b4362b0 6936 }
d1133906 6937
32ec8896 6938 return TRUE;
252b5132
RH
6939}
6940
28d13567
AM
6941static bfd_boolean
6942get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
6943 Elf_Internal_Sym **symtab, unsigned long *nsyms,
6944 char **strtab, unsigned long *strtablen)
6945{
6946 *strtab = NULL;
6947 *strtablen = 0;
6948 *symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms);
6949
6950 if (*symtab == NULL)
6951 return FALSE;
6952
6953 if (symsec->sh_link != 0)
6954 {
6955 Elf_Internal_Shdr *strsec;
6956
6957 if (symsec->sh_link >= filedata->file_header.e_shnum)
6958 {
6959 error (_("Bad sh_link in symbol table section\n"));
6960 free (*symtab);
6961 *symtab = NULL;
6962 *nsyms = 0;
6963 return FALSE;
6964 }
6965
6966 strsec = filedata->section_headers + symsec->sh_link;
6967
6968 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
6969 1, strsec->sh_size, _("string table"));
6970 if (*strtab == NULL)
6971 {
6972 free (*symtab);
6973 *symtab = NULL;
6974 *nsyms = 0;
6975 return FALSE;
6976 }
6977 *strtablen = strsec->sh_size;
6978 }
6979 return TRUE;
6980}
6981
f5842774
L
6982static const char *
6983get_group_flags (unsigned int flags)
6984{
1449284b 6985 static char buff[128];
220453ec 6986
6d913794
NC
6987 if (flags == 0)
6988 return "";
6989 else if (flags == GRP_COMDAT)
6990 return "COMDAT ";
f5842774 6991
89246a0e
AM
6992 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
6993 flags,
6994 flags & GRP_MASKOS ? _("<OS specific>") : "",
6995 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
6996 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
6997 ? _("<unknown>") : ""));
6d913794 6998
f5842774
L
6999 return buff;
7000}
7001
32ec8896 7002static bfd_boolean
dda8d76d 7003process_section_groups (Filedata * filedata)
f5842774 7004{
2cf0635d 7005 Elf_Internal_Shdr * section;
f5842774 7006 unsigned int i;
2cf0635d
NC
7007 struct group * group;
7008 Elf_Internal_Shdr * symtab_sec;
7009 Elf_Internal_Shdr * strtab_sec;
7010 Elf_Internal_Sym * symtab;
ba5cdace 7011 unsigned long num_syms;
2cf0635d 7012 char * strtab;
c256ffe7 7013 size_t strtab_size;
d1f5c6e3
L
7014
7015 /* Don't process section groups unless needed. */
7016 if (!do_unwind && !do_section_groups)
32ec8896 7017 return TRUE;
f5842774 7018
dda8d76d 7019 if (filedata->file_header.e_shnum == 0)
f5842774
L
7020 {
7021 if (do_section_groups)
82f2dbf7 7022 printf (_("\nThere are no sections to group in this file.\n"));
f5842774 7023
32ec8896 7024 return TRUE;
f5842774
L
7025 }
7026
dda8d76d 7027 if (filedata->section_headers == NULL)
f5842774
L
7028 {
7029 error (_("Section headers are not available!\n"));
fa1908fd 7030 /* PR 13622: This can happen with a corrupt ELF header. */
32ec8896 7031 return FALSE;
f5842774
L
7032 }
7033
978c4450
AM
7034 filedata->section_headers_groups
7035 = (struct group **) calloc (filedata->file_header.e_shnum,
7036 sizeof (struct group *));
e4b17d5c 7037
978c4450 7038 if (filedata->section_headers_groups == NULL)
e4b17d5c 7039 {
8b73c356 7040 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7041 filedata->file_header.e_shnum);
32ec8896 7042 return FALSE;
e4b17d5c
L
7043 }
7044
f5842774 7045 /* Scan the sections for the group section. */
978c4450 7046 filedata->group_count = 0;
dda8d76d
NC
7047 for (i = 0, section = filedata->section_headers;
7048 i < filedata->file_header.e_shnum;
f5842774 7049 i++, section++)
e4b17d5c 7050 if (section->sh_type == SHT_GROUP)
978c4450 7051 filedata->group_count++;
e4b17d5c 7052
978c4450 7053 if (filedata->group_count == 0)
d1f5c6e3
L
7054 {
7055 if (do_section_groups)
7056 printf (_("\nThere are no section groups in this file.\n"));
7057
32ec8896 7058 return TRUE;
d1f5c6e3
L
7059 }
7060
978c4450
AM
7061 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7062 sizeof (struct group));
e4b17d5c 7063
978c4450 7064 if (filedata->section_groups == NULL)
e4b17d5c 7065 {
8b73c356 7066 error (_("Out of memory reading %lu groups\n"),
978c4450 7067 (unsigned long) filedata->group_count);
32ec8896 7068 return FALSE;
e4b17d5c
L
7069 }
7070
d1f5c6e3
L
7071 symtab_sec = NULL;
7072 strtab_sec = NULL;
7073 symtab = NULL;
ba5cdace 7074 num_syms = 0;
d1f5c6e3 7075 strtab = NULL;
c256ffe7 7076 strtab_size = 0;
978c4450 7077 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7078 i < filedata->file_header.e_shnum;
e4b17d5c 7079 i++, section++)
f5842774
L
7080 {
7081 if (section->sh_type == SHT_GROUP)
7082 {
dda8d76d 7083 const char * name = printable_section_name (filedata, section);
74e1a04b 7084 const char * group_name;
2cf0635d
NC
7085 unsigned char * start;
7086 unsigned char * indices;
f5842774 7087 unsigned int entry, j, size;
2cf0635d
NC
7088 Elf_Internal_Shdr * sec;
7089 Elf_Internal_Sym * sym;
f5842774
L
7090
7091 /* Get the symbol table. */
dda8d76d
NC
7092 if (section->sh_link >= filedata->file_header.e_shnum
7093 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7094 != SHT_SYMTAB))
f5842774
L
7095 {
7096 error (_("Bad sh_link in group section `%s'\n"), name);
7097 continue;
7098 }
d1f5c6e3
L
7099
7100 if (symtab_sec != sec)
7101 {
7102 symtab_sec = sec;
9db70fc3 7103 free (symtab);
dda8d76d 7104 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 7105 }
f5842774 7106
dd24e3da
NC
7107 if (symtab == NULL)
7108 {
7109 error (_("Corrupt header in group section `%s'\n"), name);
7110 continue;
7111 }
7112
ba5cdace
NC
7113 if (section->sh_info >= num_syms)
7114 {
7115 error (_("Bad sh_info in group section `%s'\n"), name);
7116 continue;
7117 }
7118
f5842774
L
7119 sym = symtab + section->sh_info;
7120
7121 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7122 {
4fbb74a6 7123 if (sym->st_shndx == 0
dda8d76d 7124 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7125 {
7126 error (_("Bad sh_info in group section `%s'\n"), name);
7127 continue;
7128 }
ba2685cc 7129
dda8d76d 7130 group_name = SECTION_NAME (filedata->section_headers + sym->st_shndx);
c256ffe7 7131 strtab_sec = NULL;
9db70fc3 7132 free (strtab);
f5842774 7133 strtab = NULL;
c256ffe7 7134 strtab_size = 0;
f5842774
L
7135 }
7136 else
7137 {
7138 /* Get the string table. */
dda8d76d 7139 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7140 {
7141 strtab_sec = NULL;
9db70fc3 7142 free (strtab);
c256ffe7
JJ
7143 strtab = NULL;
7144 strtab_size = 0;
7145 }
7146 else if (strtab_sec
dda8d76d 7147 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7148 {
7149 strtab_sec = sec;
9db70fc3 7150 free (strtab);
071436c6 7151
dda8d76d 7152 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7153 1, strtab_sec->sh_size,
7154 _("string table"));
c256ffe7 7155 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7156 }
c256ffe7 7157 group_name = sym->st_name < strtab_size
2b692964 7158 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7159 }
7160
c9c1d674
EG
7161 /* PR 17531: file: loop. */
7162 if (section->sh_entsize > section->sh_size)
7163 {
7164 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7165 printable_section_name (filedata, section),
8066deb1
AM
7166 (unsigned long) section->sh_entsize,
7167 (unsigned long) section->sh_size);
61dd8e19 7168 continue;
c9c1d674
EG
7169 }
7170
dda8d76d 7171 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7172 1, section->sh_size,
7173 _("section data"));
59245841
NC
7174 if (start == NULL)
7175 continue;
f5842774
L
7176
7177 indices = start;
7178 size = (section->sh_size / section->sh_entsize) - 1;
7179 entry = byte_get (indices, 4);
7180 indices += 4;
e4b17d5c
L
7181
7182 if (do_section_groups)
7183 {
2b692964 7184 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7185 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7186
e4b17d5c
L
7187 printf (_(" [Index] Name\n"));
7188 }
7189
7190 group->group_index = i;
7191
f5842774
L
7192 for (j = 0; j < size; j++)
7193 {
2cf0635d 7194 struct group_list * g;
e4b17d5c 7195
f5842774
L
7196 entry = byte_get (indices, 4);
7197 indices += 4;
7198
dda8d76d 7199 if (entry >= filedata->file_header.e_shnum)
391cb864 7200 {
57028622
NC
7201 static unsigned num_group_errors = 0;
7202
7203 if (num_group_errors ++ < 10)
7204 {
7205 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7206 entry, i, filedata->file_header.e_shnum - 1);
57028622 7207 if (num_group_errors == 10)
67ce483b 7208 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7209 }
391cb864
L
7210 continue;
7211 }
391cb864 7212
978c4450 7213 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7214 {
d1f5c6e3
L
7215 if (entry)
7216 {
57028622
NC
7217 static unsigned num_errs = 0;
7218
7219 if (num_errs ++ < 10)
7220 {
7221 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7222 entry, i,
978c4450 7223 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7224 if (num_errs == 10)
7225 warn (_("Further error messages about already contained group sections suppressed\n"));
7226 }
d1f5c6e3
L
7227 continue;
7228 }
7229 else
7230 {
7231 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7232 section group. We just warn it the first time
d1f5c6e3 7233 and ignore it afterwards. */
32ec8896 7234 static bfd_boolean warned = FALSE;
d1f5c6e3
L
7235 if (!warned)
7236 {
7237 error (_("section 0 in group section [%5u]\n"),
978c4450 7238 filedata->section_headers_groups [entry]->group_index);
32ec8896 7239 warned = TRUE;
d1f5c6e3
L
7240 }
7241 }
e4b17d5c
L
7242 }
7243
978c4450 7244 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7245
7246 if (do_section_groups)
7247 {
dda8d76d
NC
7248 sec = filedata->section_headers + entry;
7249 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7250 }
7251
3f5e193b 7252 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7253 g->section_index = entry;
7254 g->next = group->root;
7255 group->root = g;
f5842774
L
7256 }
7257
9db70fc3 7258 free (start);
e4b17d5c
L
7259
7260 group++;
f5842774
L
7261 }
7262 }
7263
9db70fc3
AM
7264 free (symtab);
7265 free (strtab);
32ec8896 7266 return TRUE;
f5842774
L
7267}
7268
28f997cf
TG
7269/* Data used to display dynamic fixups. */
7270
7271struct ia64_vms_dynfixup
7272{
7273 bfd_vma needed_ident; /* Library ident number. */
7274 bfd_vma needed; /* Index in the dstrtab of the library name. */
7275 bfd_vma fixup_needed; /* Index of the library. */
7276 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7277 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7278};
7279
7280/* Data used to display dynamic relocations. */
7281
7282struct ia64_vms_dynimgrela
7283{
7284 bfd_vma img_rela_cnt; /* Number of relocations. */
7285 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7286};
7287
7288/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7289 library). */
7290
32ec8896 7291static bfd_boolean
dda8d76d
NC
7292dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7293 struct ia64_vms_dynfixup * fixup,
7294 const char * strtab,
7295 unsigned int strtab_sz)
28f997cf 7296{
32ec8896 7297 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7298 long i;
32ec8896 7299 const char * lib_name;
28f997cf 7300
978c4450
AM
7301 imfs = get_data (NULL, filedata,
7302 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7303 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7304 _("dynamic section image fixups"));
7305 if (!imfs)
32ec8896 7306 return FALSE;
28f997cf
TG
7307
7308 if (fixup->needed < strtab_sz)
7309 lib_name = strtab + fixup->needed;
7310 else
7311 {
32ec8896 7312 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7313 (unsigned long) fixup->needed);
28f997cf
TG
7314 lib_name = "???";
7315 }
736990c4 7316
28f997cf
TG
7317 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7318 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7319 printf
7320 (_("Seg Offset Type SymVec DataType\n"));
7321
7322 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7323 {
7324 unsigned int type;
7325 const char *rtype;
7326
7327 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7328 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7329 type = BYTE_GET (imfs [i].type);
7330 rtype = elf_ia64_reloc_type (type);
7331 if (rtype == NULL)
7332 printf (" 0x%08x ", type);
7333 else
7334 printf (" %-32s ", rtype);
7335 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7336 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7337 }
7338
7339 free (imfs);
32ec8896 7340 return TRUE;
28f997cf
TG
7341}
7342
7343/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7344
32ec8896 7345static bfd_boolean
dda8d76d 7346dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7347{
7348 Elf64_External_VMS_IMAGE_RELA *imrs;
7349 long i;
7350
978c4450
AM
7351 imrs = get_data (NULL, filedata,
7352 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 7353 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7354 _("dynamic section image relocations"));
28f997cf 7355 if (!imrs)
32ec8896 7356 return FALSE;
28f997cf
TG
7357
7358 printf (_("\nImage relocs\n"));
7359 printf
7360 (_("Seg Offset Type Addend Seg Sym Off\n"));
7361
7362 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7363 {
7364 unsigned int type;
7365 const char *rtype;
7366
7367 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7368 printf ("%08" BFD_VMA_FMT "x ",
7369 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7370 type = BYTE_GET (imrs [i].type);
7371 rtype = elf_ia64_reloc_type (type);
7372 if (rtype == NULL)
7373 printf ("0x%08x ", type);
7374 else
7375 printf ("%-31s ", rtype);
7376 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7377 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7378 printf ("%08" BFD_VMA_FMT "x\n",
7379 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7380 }
7381
7382 free (imrs);
32ec8896 7383 return TRUE;
28f997cf
TG
7384}
7385
7386/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7387
32ec8896 7388static bfd_boolean
dda8d76d 7389process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7390{
7391 struct ia64_vms_dynfixup fixup;
7392 struct ia64_vms_dynimgrela imgrela;
7393 Elf_Internal_Dyn *entry;
28f997cf
TG
7394 bfd_vma strtab_off = 0;
7395 bfd_vma strtab_sz = 0;
7396 char *strtab = NULL;
32ec8896 7397 bfd_boolean res = TRUE;
28f997cf
TG
7398
7399 memset (&fixup, 0, sizeof (fixup));
7400 memset (&imgrela, 0, sizeof (imgrela));
7401
7402 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
7403 for (entry = filedata->dynamic_section;
7404 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
7405 entry++)
7406 {
7407 switch (entry->d_tag)
7408 {
7409 case DT_IA_64_VMS_STRTAB_OFFSET:
7410 strtab_off = entry->d_un.d_val;
7411 break;
7412 case DT_STRSZ:
7413 strtab_sz = entry->d_un.d_val;
7414 if (strtab == NULL)
978c4450
AM
7415 strtab = get_data (NULL, filedata,
7416 filedata->dynamic_addr + strtab_off,
28f997cf 7417 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7418 if (strtab == NULL)
7419 strtab_sz = 0;
28f997cf
TG
7420 break;
7421
7422 case DT_IA_64_VMS_NEEDED_IDENT:
7423 fixup.needed_ident = entry->d_un.d_val;
7424 break;
7425 case DT_NEEDED:
7426 fixup.needed = entry->d_un.d_val;
7427 break;
7428 case DT_IA_64_VMS_FIXUP_NEEDED:
7429 fixup.fixup_needed = entry->d_un.d_val;
7430 break;
7431 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7432 fixup.fixup_rela_cnt = entry->d_un.d_val;
7433 break;
7434 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7435 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7436 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
32ec8896 7437 res = FALSE;
28f997cf 7438 break;
28f997cf
TG
7439 case DT_IA_64_VMS_IMG_RELA_CNT:
7440 imgrela.img_rela_cnt = entry->d_un.d_val;
7441 break;
7442 case DT_IA_64_VMS_IMG_RELA_OFF:
7443 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7444 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
32ec8896 7445 res = FALSE;
28f997cf
TG
7446 break;
7447
7448 default:
7449 break;
7450 }
7451 }
7452
9db70fc3 7453 free (strtab);
28f997cf
TG
7454
7455 return res;
7456}
7457
85b1c36d 7458static struct
566b0d53 7459{
2cf0635d 7460 const char * name;
566b0d53
L
7461 int reloc;
7462 int size;
7463 int rela;
32ec8896
NC
7464}
7465 dynamic_relocations [] =
566b0d53 7466{
32ec8896
NC
7467 { "REL", DT_REL, DT_RELSZ, FALSE },
7468 { "RELA", DT_RELA, DT_RELASZ, TRUE },
7469 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7470};
7471
252b5132 7472/* Process the reloc section. */
18bd398b 7473
32ec8896 7474static bfd_boolean
dda8d76d 7475process_relocs (Filedata * filedata)
252b5132 7476{
b34976b6
AM
7477 unsigned long rel_size;
7478 unsigned long rel_offset;
252b5132 7479
252b5132 7480 if (!do_reloc)
32ec8896 7481 return TRUE;
252b5132
RH
7482
7483 if (do_using_dynamic)
7484 {
32ec8896 7485 int is_rela;
2cf0635d 7486 const char * name;
32ec8896 7487 bfd_boolean has_dynamic_reloc;
566b0d53 7488 unsigned int i;
0de14b54 7489
32ec8896 7490 has_dynamic_reloc = FALSE;
252b5132 7491
566b0d53 7492 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7493 {
566b0d53
L
7494 is_rela = dynamic_relocations [i].rela;
7495 name = dynamic_relocations [i].name;
978c4450
AM
7496 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
7497 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 7498
32ec8896
NC
7499 if (rel_size)
7500 has_dynamic_reloc = TRUE;
566b0d53
L
7501
7502 if (is_rela == UNKNOWN)
aa903cfb 7503 {
566b0d53 7504 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 7505 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
7506 {
7507 case DT_REL:
7508 is_rela = FALSE;
7509 break;
7510 case DT_RELA:
7511 is_rela = TRUE;
7512 break;
7513 }
aa903cfb 7514 }
252b5132 7515
566b0d53
L
7516 if (rel_size)
7517 {
7518 printf
7519 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7520 name, rel_offset, rel_size);
252b5132 7521
dda8d76d
NC
7522 dump_relocations (filedata,
7523 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7524 rel_size,
978c4450
AM
7525 filedata->dynamic_symbols,
7526 filedata->num_dynamic_syms,
7527 filedata->dynamic_strings,
7528 filedata->dynamic_strings_length,
32ec8896 7529 is_rela, TRUE /* is_dynamic */);
566b0d53 7530 }
252b5132 7531 }
566b0d53 7532
dda8d76d
NC
7533 if (is_ia64_vms (filedata))
7534 if (process_ia64_vms_dynamic_relocs (filedata))
32ec8896 7535 has_dynamic_reloc = TRUE;
28f997cf 7536
566b0d53 7537 if (! has_dynamic_reloc)
252b5132
RH
7538 printf (_("\nThere are no dynamic relocations in this file.\n"));
7539 }
7540 else
7541 {
2cf0635d 7542 Elf_Internal_Shdr * section;
b34976b6 7543 unsigned long i;
32ec8896 7544 bfd_boolean found = FALSE;
252b5132 7545
dda8d76d
NC
7546 for (i = 0, section = filedata->section_headers;
7547 i < filedata->file_header.e_shnum;
b34976b6 7548 i++, section++)
252b5132
RH
7549 {
7550 if ( section->sh_type != SHT_RELA
7551 && section->sh_type != SHT_REL)
7552 continue;
7553
7554 rel_offset = section->sh_offset;
7555 rel_size = section->sh_size;
7556
7557 if (rel_size)
7558 {
b34976b6 7559 int is_rela;
d3a49aa8 7560 unsigned long num_rela;
103f02d3 7561
252b5132
RH
7562 printf (_("\nRelocation section "));
7563
dda8d76d 7564 if (filedata->string_table == NULL)
19936277 7565 printf ("%d", section->sh_name);
252b5132 7566 else
dda8d76d 7567 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7568
d3a49aa8
AM
7569 num_rela = rel_size / section->sh_entsize;
7570 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7571 " at offset 0x%lx contains %lu entries:\n",
7572 num_rela),
7573 rel_offset, num_rela);
252b5132 7574
d79b3d50
NC
7575 is_rela = section->sh_type == SHT_RELA;
7576
4fbb74a6 7577 if (section->sh_link != 0
dda8d76d 7578 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7579 {
2cf0635d
NC
7580 Elf_Internal_Shdr * symsec;
7581 Elf_Internal_Sym * symtab;
d79b3d50 7582 unsigned long nsyms;
c256ffe7 7583 unsigned long strtablen = 0;
2cf0635d 7584 char * strtab = NULL;
57346661 7585
dda8d76d 7586 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7587 if (symsec->sh_type != SHT_SYMTAB
7588 && symsec->sh_type != SHT_DYNSYM)
7589 continue;
7590
28d13567
AM
7591 if (!get_symtab (filedata, symsec,
7592 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7593 continue;
252b5132 7594
dda8d76d 7595 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7596 symtab, nsyms, strtab, strtablen,
7597 is_rela,
7598 symsec->sh_type == SHT_DYNSYM);
9db70fc3 7599 free (strtab);
d79b3d50
NC
7600 free (symtab);
7601 }
7602 else
dda8d76d 7603 dump_relocations (filedata, rel_offset, rel_size,
32ec8896
NC
7604 NULL, 0, NULL, 0, is_rela,
7605 FALSE /* is_dynamic */);
252b5132 7606
32ec8896 7607 found = TRUE;
252b5132
RH
7608 }
7609 }
7610
7611 if (! found)
45ac8f4f
NC
7612 {
7613 /* Users sometimes forget the -D option, so try to be helpful. */
7614 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7615 {
978c4450 7616 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f
NC
7617 {
7618 printf (_("\nThere are no static relocations in this file."));
7619 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7620
7621 break;
7622 }
7623 }
7624 if (i == ARRAY_SIZE (dynamic_relocations))
7625 printf (_("\nThere are no relocations in this file.\n"));
7626 }
252b5132
RH
7627 }
7628
32ec8896 7629 return TRUE;
252b5132
RH
7630}
7631
4d6ed7c8
NC
7632/* An absolute address consists of a section and an offset. If the
7633 section is NULL, the offset itself is the address, otherwise, the
7634 address equals to LOAD_ADDRESS(section) + offset. */
7635
7636struct absaddr
948f632f
DA
7637{
7638 unsigned short section;
7639 bfd_vma offset;
7640};
4d6ed7c8 7641
948f632f
DA
7642/* Find the nearest symbol at or below ADDR. Returns the symbol
7643 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7644
4d6ed7c8 7645static void
dda8d76d
NC
7646find_symbol_for_address (Filedata * filedata,
7647 Elf_Internal_Sym * symtab,
7648 unsigned long nsyms,
7649 const char * strtab,
7650 unsigned long strtab_size,
7651 struct absaddr addr,
7652 const char ** symname,
7653 bfd_vma * offset)
4d6ed7c8 7654{
d3ba0551 7655 bfd_vma dist = 0x100000;
2cf0635d 7656 Elf_Internal_Sym * sym;
948f632f
DA
7657 Elf_Internal_Sym * beg;
7658 Elf_Internal_Sym * end;
2cf0635d 7659 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7660
0b6ae522 7661 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7662 beg = symtab;
7663 end = symtab + nsyms;
0b6ae522 7664
948f632f 7665 while (beg < end)
4d6ed7c8 7666 {
948f632f
DA
7667 bfd_vma value;
7668
7669 sym = beg + (end - beg) / 2;
0b6ae522 7670
948f632f 7671 value = sym->st_value;
0b6ae522
DJ
7672 REMOVE_ARCH_BITS (value);
7673
948f632f 7674 if (sym->st_name != 0
4d6ed7c8 7675 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7676 && addr.offset >= value
7677 && addr.offset - value < dist)
4d6ed7c8
NC
7678 {
7679 best = sym;
0b6ae522 7680 dist = addr.offset - value;
4d6ed7c8
NC
7681 if (!dist)
7682 break;
7683 }
948f632f
DA
7684
7685 if (addr.offset < value)
7686 end = sym;
7687 else
7688 beg = sym + 1;
4d6ed7c8 7689 }
1b31d05e 7690
4d6ed7c8
NC
7691 if (best)
7692 {
57346661 7693 *symname = (best->st_name >= strtab_size
2b692964 7694 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7695 *offset = dist;
7696 return;
7697 }
1b31d05e 7698
4d6ed7c8
NC
7699 *symname = NULL;
7700 *offset = addr.offset;
7701}
7702
32ec8896 7703static /* signed */ int
948f632f
DA
7704symcmp (const void *p, const void *q)
7705{
7706 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7707 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7708
7709 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7710}
7711
7712/* Process the unwind section. */
7713
7714#include "unwind-ia64.h"
7715
7716struct ia64_unw_table_entry
7717{
7718 struct absaddr start;
7719 struct absaddr end;
7720 struct absaddr info;
7721};
7722
7723struct ia64_unw_aux_info
7724{
32ec8896
NC
7725 struct ia64_unw_table_entry * table; /* Unwind table. */
7726 unsigned long table_len; /* Length of unwind table. */
7727 unsigned char * info; /* Unwind info. */
7728 unsigned long info_size; /* Size of unwind info. */
7729 bfd_vma info_addr; /* Starting address of unwind info. */
7730 bfd_vma seg_base; /* Starting address of segment. */
7731 Elf_Internal_Sym * symtab; /* The symbol table. */
7732 unsigned long nsyms; /* Number of symbols. */
7733 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7734 unsigned long nfuns; /* Number of entries in funtab. */
7735 char * strtab; /* The string table. */
7736 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7737};
7738
32ec8896 7739static bfd_boolean
dda8d76d 7740dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7741{
2cf0635d 7742 struct ia64_unw_table_entry * tp;
948f632f 7743 unsigned long j, nfuns;
4d6ed7c8 7744 int in_body;
32ec8896 7745 bfd_boolean res = TRUE;
7036c0e1 7746
948f632f
DA
7747 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7748 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7749 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7750 aux->funtab[nfuns++] = aux->symtab[j];
7751 aux->nfuns = nfuns;
7752 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7753
4d6ed7c8
NC
7754 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7755 {
7756 bfd_vma stamp;
7757 bfd_vma offset;
2cf0635d
NC
7758 const unsigned char * dp;
7759 const unsigned char * head;
53774b7e 7760 const unsigned char * end;
2cf0635d 7761 const char * procname;
4d6ed7c8 7762
dda8d76d 7763 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7764 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7765
7766 fputs ("\n<", stdout);
7767
7768 if (procname)
7769 {
7770 fputs (procname, stdout);
7771
7772 if (offset)
7773 printf ("+%lx", (unsigned long) offset);
7774 }
7775
7776 fputs (">: [", stdout);
7777 print_vma (tp->start.offset, PREFIX_HEX);
7778 fputc ('-', stdout);
7779 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7780 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7781 (unsigned long) (tp->info.offset - aux->seg_base));
7782
53774b7e
NC
7783 /* PR 17531: file: 86232b32. */
7784 if (aux->info == NULL)
7785 continue;
7786
97c0a079
AM
7787 offset = tp->info.offset;
7788 if (tp->info.section)
7789 {
7790 if (tp->info.section >= filedata->file_header.e_shnum)
7791 {
7792 warn (_("Invalid section %u in table entry %ld\n"),
7793 tp->info.section, (long) (tp - aux->table));
7794 res = FALSE;
7795 continue;
7796 }
7797 offset += filedata->section_headers[tp->info.section].sh_addr;
7798 }
7799 offset -= aux->info_addr;
53774b7e 7800 /* PR 17531: file: 0997b4d1. */
90679903
AM
7801 if (offset >= aux->info_size
7802 || aux->info_size - offset < 8)
53774b7e
NC
7803 {
7804 warn (_("Invalid offset %lx in table entry %ld\n"),
7805 (long) tp->info.offset, (long) (tp - aux->table));
32ec8896 7806 res = FALSE;
53774b7e
NC
7807 continue;
7808 }
7809
97c0a079 7810 head = aux->info + offset;
a4a00738 7811 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 7812
86f55779 7813 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
7814 (unsigned) UNW_VER (stamp),
7815 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
7816 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
7817 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 7818 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
7819
7820 if (UNW_VER (stamp) != 1)
7821 {
2b692964 7822 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
7823 continue;
7824 }
7825
7826 in_body = 0;
53774b7e
NC
7827 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
7828 /* PR 17531: file: 16ceda89. */
7829 if (end > aux->info + aux->info_size)
7830 end = aux->info + aux->info_size;
7831 for (dp = head + 8; dp < end;)
b4477bc8 7832 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 7833 }
948f632f
DA
7834
7835 free (aux->funtab);
32ec8896
NC
7836
7837 return res;
4d6ed7c8
NC
7838}
7839
53774b7e 7840static bfd_boolean
dda8d76d
NC
7841slurp_ia64_unwind_table (Filedata * filedata,
7842 struct ia64_unw_aux_info * aux,
7843 Elf_Internal_Shdr * sec)
4d6ed7c8 7844{
89fac5e3 7845 unsigned long size, nrelas, i;
2cf0635d
NC
7846 Elf_Internal_Phdr * seg;
7847 struct ia64_unw_table_entry * tep;
7848 Elf_Internal_Shdr * relsec;
7849 Elf_Internal_Rela * rela;
7850 Elf_Internal_Rela * rp;
7851 unsigned char * table;
7852 unsigned char * tp;
7853 Elf_Internal_Sym * sym;
7854 const char * relname;
4d6ed7c8 7855
53774b7e
NC
7856 aux->table_len = 0;
7857
4d6ed7c8
NC
7858 /* First, find the starting address of the segment that includes
7859 this section: */
7860
dda8d76d 7861 if (filedata->file_header.e_phnum)
4d6ed7c8 7862 {
dda8d76d 7863 if (! get_program_headers (filedata))
53774b7e 7864 return FALSE;
4d6ed7c8 7865
dda8d76d
NC
7866 for (seg = filedata->program_headers;
7867 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 7868 ++seg)
4d6ed7c8
NC
7869 {
7870 if (seg->p_type != PT_LOAD)
7871 continue;
7872
7873 if (sec->sh_addr >= seg->p_vaddr
7874 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7875 {
7876 aux->seg_base = seg->p_vaddr;
7877 break;
7878 }
7879 }
4d6ed7c8
NC
7880 }
7881
7882 /* Second, build the unwind table from the contents of the unwind section: */
7883 size = sec->sh_size;
dda8d76d 7884 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7885 _("unwind table"));
a6e9f9df 7886 if (!table)
53774b7e 7887 return FALSE;
4d6ed7c8 7888
53774b7e 7889 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 7890 aux->table = (struct ia64_unw_table_entry *)
53774b7e 7891 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 7892 tep = aux->table;
53774b7e
NC
7893
7894 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
7895 {
7896 tep->start.section = SHN_UNDEF;
7897 tep->end.section = SHN_UNDEF;
7898 tep->info.section = SHN_UNDEF;
c6a0c689
AM
7899 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7900 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7901 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
7902 tep->start.offset += aux->seg_base;
7903 tep->end.offset += aux->seg_base;
7904 tep->info.offset += aux->seg_base;
7905 }
7906 free (table);
7907
41e92641 7908 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
7909 for (relsec = filedata->section_headers;
7910 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
7911 ++relsec)
7912 {
7913 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
7914 || relsec->sh_info >= filedata->file_header.e_shnum
7915 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
7916 continue;
7917
dda8d76d 7918 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 7919 & rela, & nrelas))
53774b7e
NC
7920 {
7921 free (aux->table);
7922 aux->table = NULL;
7923 aux->table_len = 0;
7924 return FALSE;
7925 }
4d6ed7c8
NC
7926
7927 for (rp = rela; rp < rela + nrelas; ++rp)
7928 {
4770fb94 7929 unsigned int sym_ndx;
726bd37d
AM
7930 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
7931 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 7932
82b1b41b
NC
7933 /* PR 17531: file: 9fa67536. */
7934 if (relname == NULL)
7935 {
726bd37d 7936 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
7937 continue;
7938 }
948f632f 7939
0112cd26 7940 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 7941 {
82b1b41b 7942 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
7943 continue;
7944 }
7945
89fac5e3 7946 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 7947
53774b7e
NC
7948 /* PR 17531: file: 5bc8d9bf. */
7949 if (i >= aux->table_len)
7950 {
7951 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
7952 continue;
7953 }
7954
4770fb94
AM
7955 sym_ndx = get_reloc_symindex (rp->r_info);
7956 if (sym_ndx >= aux->nsyms)
7957 {
7958 warn (_("Skipping reloc with invalid symbol index: %u\n"),
7959 sym_ndx);
7960 continue;
7961 }
7962 sym = aux->symtab + sym_ndx;
7963
53774b7e 7964 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
7965 {
7966 case 0:
7967 aux->table[i].start.section = sym->st_shndx;
e466bc6e 7968 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7969 break;
7970 case 1:
7971 aux->table[i].end.section = sym->st_shndx;
e466bc6e 7972 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7973 break;
7974 case 2:
7975 aux->table[i].info.section = sym->st_shndx;
e466bc6e 7976 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7977 break;
7978 default:
7979 break;
7980 }
7981 }
7982
7983 free (rela);
7984 }
7985
53774b7e 7986 return TRUE;
4d6ed7c8
NC
7987}
7988
32ec8896 7989static bfd_boolean
dda8d76d 7990ia64_process_unwind (Filedata * filedata)
4d6ed7c8 7991{
2cf0635d
NC
7992 Elf_Internal_Shdr * sec;
7993 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 7994 unsigned long i, unwcount = 0, unwstart = 0;
57346661 7995 struct ia64_unw_aux_info aux;
32ec8896 7996 bfd_boolean res = TRUE;
f1467e33 7997
4d6ed7c8
NC
7998 memset (& aux, 0, sizeof (aux));
7999
dda8d76d 8000 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8001 {
28d13567 8002 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8003 {
28d13567 8004 if (aux.symtab)
4082ef84 8005 {
28d13567
AM
8006 error (_("Multiple symbol tables encountered\n"));
8007 free (aux.symtab);
8008 aux.symtab = NULL;
4082ef84 8009 free (aux.strtab);
28d13567 8010 aux.strtab = NULL;
4082ef84 8011 }
28d13567
AM
8012 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8013 &aux.strtab, &aux.strtab_size))
8014 return FALSE;
4d6ed7c8
NC
8015 }
8016 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8017 unwcount++;
8018 }
8019
8020 if (!unwcount)
8021 printf (_("\nThere are no unwind sections in this file.\n"));
8022
8023 while (unwcount-- > 0)
8024 {
2cf0635d 8025 char * suffix;
579f31ac
JJ
8026 size_t len, len2;
8027
dda8d76d
NC
8028 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8029 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8030 if (sec->sh_type == SHT_IA_64_UNWIND)
8031 {
8032 unwsec = sec;
8033 break;
8034 }
4082ef84
NC
8035 /* We have already counted the number of SHT_IA64_UNWIND
8036 sections so the loop above should never fail. */
8037 assert (unwsec != NULL);
579f31ac
JJ
8038
8039 unwstart = i + 1;
8040 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8041
e4b17d5c
L
8042 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8043 {
8044 /* We need to find which section group it is in. */
4082ef84 8045 struct group_list * g;
e4b17d5c 8046
978c4450
AM
8047 if (filedata->section_headers_groups == NULL
8048 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8049 i = filedata->file_header.e_shnum;
4082ef84 8050 else
e4b17d5c 8051 {
978c4450 8052 g = filedata->section_headers_groups[i]->root;
18bd398b 8053
4082ef84
NC
8054 for (; g != NULL; g = g->next)
8055 {
dda8d76d 8056 sec = filedata->section_headers + g->section_index;
e4b17d5c 8057
4082ef84
NC
8058 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
8059 break;
8060 }
8061
8062 if (g == NULL)
dda8d76d 8063 i = filedata->file_header.e_shnum;
4082ef84 8064 }
e4b17d5c 8065 }
18bd398b 8066 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 8067 {
18bd398b 8068 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
8069 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
8070 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 8071 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 8072 ++i, ++sec)
18bd398b
NC
8073 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
8074 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8075 break;
8076 }
8077 else
8078 {
8079 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8080 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8081 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8082 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8083 suffix = "";
18bd398b 8084 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac 8085 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 8086 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 8087 ++i, ++sec)
18bd398b
NC
8088 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
8089 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8090 break;
8091 }
8092
dda8d76d 8093 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8094 {
8095 printf (_("\nCould not find unwind info section for "));
8096
dda8d76d 8097 if (filedata->string_table == NULL)
579f31ac
JJ
8098 printf ("%d", unwsec->sh_name);
8099 else
dda8d76d 8100 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8101 }
8102 else
4d6ed7c8 8103 {
4d6ed7c8 8104 aux.info_addr = sec->sh_addr;
dda8d76d 8105 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8106 sec->sh_size,
8107 _("unwind info"));
59245841 8108 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8109
579f31ac 8110 printf (_("\nUnwind section "));
4d6ed7c8 8111
dda8d76d 8112 if (filedata->string_table == NULL)
579f31ac
JJ
8113 printf ("%d", unwsec->sh_name);
8114 else
dda8d76d 8115 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8116
579f31ac 8117 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8118 (unsigned long) unwsec->sh_offset,
89fac5e3 8119 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8120
dda8d76d 8121 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8122 && aux.table_len > 0)
dda8d76d 8123 dump_ia64_unwind (filedata, & aux);
579f31ac 8124
9db70fc3
AM
8125 free ((char *) aux.table);
8126 free ((char *) aux.info);
579f31ac
JJ
8127 aux.table = NULL;
8128 aux.info = NULL;
8129 }
4d6ed7c8 8130 }
4d6ed7c8 8131
9db70fc3
AM
8132 free (aux.symtab);
8133 free ((char *) aux.strtab);
32ec8896
NC
8134
8135 return res;
4d6ed7c8
NC
8136}
8137
3f5e193b 8138struct hppa_unw_table_entry
32ec8896
NC
8139{
8140 struct absaddr start;
8141 struct absaddr end;
8142 unsigned int Cannot_unwind:1; /* 0 */
8143 unsigned int Millicode:1; /* 1 */
8144 unsigned int Millicode_save_sr0:1; /* 2 */
8145 unsigned int Region_description:2; /* 3..4 */
8146 unsigned int reserved1:1; /* 5 */
8147 unsigned int Entry_SR:1; /* 6 */
8148 unsigned int Entry_FR:4; /* Number saved 7..10 */
8149 unsigned int Entry_GR:5; /* Number saved 11..15 */
8150 unsigned int Args_stored:1; /* 16 */
8151 unsigned int Variable_Frame:1; /* 17 */
8152 unsigned int Separate_Package_Body:1; /* 18 */
8153 unsigned int Frame_Extension_Millicode:1; /* 19 */
8154 unsigned int Stack_Overflow_Check:1; /* 20 */
8155 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8156 unsigned int Ada_Region:1; /* 22 */
8157 unsigned int cxx_info:1; /* 23 */
8158 unsigned int cxx_try_catch:1; /* 24 */
8159 unsigned int sched_entry_seq:1; /* 25 */
8160 unsigned int reserved2:1; /* 26 */
8161 unsigned int Save_SP:1; /* 27 */
8162 unsigned int Save_RP:1; /* 28 */
8163 unsigned int Save_MRP_in_frame:1; /* 29 */
8164 unsigned int extn_ptr_defined:1; /* 30 */
8165 unsigned int Cleanup_defined:1; /* 31 */
8166
8167 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8168 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8169 unsigned int Large_frame:1; /* 2 */
8170 unsigned int Pseudo_SP_Set:1; /* 3 */
8171 unsigned int reserved4:1; /* 4 */
8172 unsigned int Total_frame_size:27; /* 5..31 */
8173};
3f5e193b 8174
57346661 8175struct hppa_unw_aux_info
948f632f 8176{
32ec8896
NC
8177 struct hppa_unw_table_entry * table; /* Unwind table. */
8178 unsigned long table_len; /* Length of unwind table. */
8179 bfd_vma seg_base; /* Starting address of segment. */
8180 Elf_Internal_Sym * symtab; /* The symbol table. */
8181 unsigned long nsyms; /* Number of symbols. */
8182 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8183 unsigned long nfuns; /* Number of entries in funtab. */
8184 char * strtab; /* The string table. */
8185 unsigned long strtab_size; /* Size of string table. */
948f632f 8186};
57346661 8187
32ec8896 8188static bfd_boolean
dda8d76d 8189dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8190{
2cf0635d 8191 struct hppa_unw_table_entry * tp;
948f632f 8192 unsigned long j, nfuns;
32ec8896 8193 bfd_boolean res = TRUE;
948f632f
DA
8194
8195 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8196 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8197 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8198 aux->funtab[nfuns++] = aux->symtab[j];
8199 aux->nfuns = nfuns;
8200 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8201
57346661
AM
8202 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8203 {
8204 bfd_vma offset;
2cf0635d 8205 const char * procname;
57346661 8206
dda8d76d 8207 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8208 aux->strtab_size, tp->start, &procname,
8209 &offset);
8210
8211 fputs ("\n<", stdout);
8212
8213 if (procname)
8214 {
8215 fputs (procname, stdout);
8216
8217 if (offset)
8218 printf ("+%lx", (unsigned long) offset);
8219 }
8220
8221 fputs (">: [", stdout);
8222 print_vma (tp->start.offset, PREFIX_HEX);
8223 fputc ('-', stdout);
8224 print_vma (tp->end.offset, PREFIX_HEX);
8225 printf ("]\n\t");
8226
18bd398b
NC
8227#define PF(_m) if (tp->_m) printf (#_m " ");
8228#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8229 PF(Cannot_unwind);
8230 PF(Millicode);
8231 PF(Millicode_save_sr0);
18bd398b 8232 /* PV(Region_description); */
57346661
AM
8233 PF(Entry_SR);
8234 PV(Entry_FR);
8235 PV(Entry_GR);
8236 PF(Args_stored);
8237 PF(Variable_Frame);
8238 PF(Separate_Package_Body);
8239 PF(Frame_Extension_Millicode);
8240 PF(Stack_Overflow_Check);
8241 PF(Two_Instruction_SP_Increment);
8242 PF(Ada_Region);
8243 PF(cxx_info);
8244 PF(cxx_try_catch);
8245 PF(sched_entry_seq);
8246 PF(Save_SP);
8247 PF(Save_RP);
8248 PF(Save_MRP_in_frame);
8249 PF(extn_ptr_defined);
8250 PF(Cleanup_defined);
8251 PF(MPE_XL_interrupt_marker);
8252 PF(HP_UX_interrupt_marker);
8253 PF(Large_frame);
8254 PF(Pseudo_SP_Set);
8255 PV(Total_frame_size);
8256#undef PF
8257#undef PV
8258 }
8259
18bd398b 8260 printf ("\n");
948f632f
DA
8261
8262 free (aux->funtab);
32ec8896
NC
8263
8264 return res;
57346661
AM
8265}
8266
32ec8896 8267static bfd_boolean
dda8d76d
NC
8268slurp_hppa_unwind_table (Filedata * filedata,
8269 struct hppa_unw_aux_info * aux,
8270 Elf_Internal_Shdr * sec)
57346661 8271{
1c0751b2 8272 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8273 Elf_Internal_Phdr * seg;
8274 struct hppa_unw_table_entry * tep;
8275 Elf_Internal_Shdr * relsec;
8276 Elf_Internal_Rela * rela;
8277 Elf_Internal_Rela * rp;
8278 unsigned char * table;
8279 unsigned char * tp;
8280 Elf_Internal_Sym * sym;
8281 const char * relname;
57346661 8282
57346661
AM
8283 /* First, find the starting address of the segment that includes
8284 this section. */
dda8d76d 8285 if (filedata->file_header.e_phnum)
57346661 8286 {
dda8d76d 8287 if (! get_program_headers (filedata))
32ec8896 8288 return FALSE;
57346661 8289
dda8d76d
NC
8290 for (seg = filedata->program_headers;
8291 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8292 ++seg)
8293 {
8294 if (seg->p_type != PT_LOAD)
8295 continue;
8296
8297 if (sec->sh_addr >= seg->p_vaddr
8298 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8299 {
8300 aux->seg_base = seg->p_vaddr;
8301 break;
8302 }
8303 }
8304 }
8305
8306 /* Second, build the unwind table from the contents of the unwind
8307 section. */
8308 size = sec->sh_size;
dda8d76d 8309 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8310 _("unwind table"));
57346661 8311 if (!table)
32ec8896 8312 return FALSE;
57346661 8313
1c0751b2
DA
8314 unw_ent_size = 16;
8315 nentries = size / unw_ent_size;
8316 size = unw_ent_size * nentries;
57346661 8317
e3fdc001 8318 aux->table_len = nentries;
3f5e193b
NC
8319 tep = aux->table = (struct hppa_unw_table_entry *)
8320 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8321
1c0751b2 8322 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8323 {
8324 unsigned int tmp1, tmp2;
8325
8326 tep->start.section = SHN_UNDEF;
8327 tep->end.section = SHN_UNDEF;
8328
1c0751b2
DA
8329 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8330 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8331 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8332 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8333
8334 tep->start.offset += aux->seg_base;
8335 tep->end.offset += aux->seg_base;
57346661
AM
8336
8337 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8338 tep->Millicode = (tmp1 >> 30) & 0x1;
8339 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8340 tep->Region_description = (tmp1 >> 27) & 0x3;
8341 tep->reserved1 = (tmp1 >> 26) & 0x1;
8342 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8343 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8344 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8345 tep->Args_stored = (tmp1 >> 15) & 0x1;
8346 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8347 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8348 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8349 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8350 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8351 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8352 tep->cxx_info = (tmp1 >> 8) & 0x1;
8353 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8354 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8355 tep->reserved2 = (tmp1 >> 5) & 0x1;
8356 tep->Save_SP = (tmp1 >> 4) & 0x1;
8357 tep->Save_RP = (tmp1 >> 3) & 0x1;
8358 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8359 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8360 tep->Cleanup_defined = tmp1 & 0x1;
8361
8362 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8363 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8364 tep->Large_frame = (tmp2 >> 29) & 0x1;
8365 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8366 tep->reserved4 = (tmp2 >> 27) & 0x1;
8367 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8368 }
8369 free (table);
8370
8371 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8372 for (relsec = filedata->section_headers;
8373 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8374 ++relsec)
8375 {
8376 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8377 || relsec->sh_info >= filedata->file_header.e_shnum
8378 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8379 continue;
8380
dda8d76d 8381 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8382 & rela, & nrelas))
32ec8896 8383 return FALSE;
57346661
AM
8384
8385 for (rp = rela; rp < rela + nrelas; ++rp)
8386 {
4770fb94 8387 unsigned int sym_ndx;
726bd37d
AM
8388 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8389 relname = elf_hppa_reloc_type (r_type);
57346661 8390
726bd37d
AM
8391 if (relname == NULL)
8392 {
8393 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8394 continue;
8395 }
8396
57346661 8397 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 8398 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661 8399 {
726bd37d 8400 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8401 continue;
8402 }
8403
8404 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8405 if (i >= aux->table_len)
8406 {
8407 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8408 continue;
8409 }
57346661 8410
4770fb94
AM
8411 sym_ndx = get_reloc_symindex (rp->r_info);
8412 if (sym_ndx >= aux->nsyms)
8413 {
8414 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8415 sym_ndx);
8416 continue;
8417 }
8418 sym = aux->symtab + sym_ndx;
8419
43f6cd05 8420 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8421 {
8422 case 0:
8423 aux->table[i].start.section = sym->st_shndx;
1e456d54 8424 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8425 break;
8426 case 1:
8427 aux->table[i].end.section = sym->st_shndx;
1e456d54 8428 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8429 break;
8430 default:
8431 break;
8432 }
8433 }
8434
8435 free (rela);
8436 }
8437
32ec8896 8438 return TRUE;
57346661
AM
8439}
8440
32ec8896 8441static bfd_boolean
dda8d76d 8442hppa_process_unwind (Filedata * filedata)
57346661 8443{
57346661 8444 struct hppa_unw_aux_info aux;
2cf0635d 8445 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8446 Elf_Internal_Shdr * sec;
18bd398b 8447 unsigned long i;
32ec8896 8448 bfd_boolean res = TRUE;
57346661 8449
dda8d76d 8450 if (filedata->string_table == NULL)
32ec8896 8451 return FALSE;
1b31d05e
NC
8452
8453 memset (& aux, 0, sizeof (aux));
57346661 8454
dda8d76d 8455 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8456 {
28d13567 8457 if (sec->sh_type == SHT_SYMTAB)
57346661 8458 {
28d13567 8459 if (aux.symtab)
4082ef84 8460 {
28d13567
AM
8461 error (_("Multiple symbol tables encountered\n"));
8462 free (aux.symtab);
8463 aux.symtab = NULL;
4082ef84 8464 free (aux.strtab);
28d13567 8465 aux.strtab = NULL;
4082ef84 8466 }
28d13567
AM
8467 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8468 &aux.strtab, &aux.strtab_size))
8469 return FALSE;
57346661 8470 }
18bd398b 8471 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8472 unwsec = sec;
8473 }
8474
8475 if (!unwsec)
8476 printf (_("\nThere are no unwind sections in this file.\n"));
8477
dda8d76d 8478 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8479 {
18bd398b 8480 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8481 {
43f6cd05 8482 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8483
d3a49aa8
AM
8484 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8485 "contains %lu entry:\n",
8486 "\nUnwind section '%s' at offset 0x%lx "
8487 "contains %lu entries:\n",
8488 num_unwind),
dda8d76d 8489 printable_section_name (filedata, sec),
57346661 8490 (unsigned long) sec->sh_offset,
d3a49aa8 8491 num_unwind);
57346661 8492
dda8d76d 8493 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
32ec8896 8494 res = FALSE;
66b09c7e
S
8495
8496 if (res && aux.table_len > 0)
32ec8896 8497 {
dda8d76d 8498 if (! dump_hppa_unwind (filedata, &aux))
32ec8896
NC
8499 res = FALSE;
8500 }
57346661 8501
9db70fc3 8502 free ((char *) aux.table);
57346661
AM
8503 aux.table = NULL;
8504 }
8505 }
8506
9db70fc3
AM
8507 free (aux.symtab);
8508 free ((char *) aux.strtab);
32ec8896
NC
8509
8510 return res;
57346661
AM
8511}
8512
0b6ae522
DJ
8513struct arm_section
8514{
a734115a
NC
8515 unsigned char * data; /* The unwind data. */
8516 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8517 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8518 unsigned long nrelas; /* The number of relocations. */
8519 unsigned int rel_type; /* REL or RELA ? */
8520 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8521};
8522
8523struct arm_unw_aux_info
8524{
dda8d76d 8525 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8526 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8527 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8528 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8529 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8530 char * strtab; /* The file's string table. */
8531 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8532};
8533
8534static const char *
dda8d76d
NC
8535arm_print_vma_and_name (Filedata * filedata,
8536 struct arm_unw_aux_info * aux,
8537 bfd_vma fn,
8538 struct absaddr addr)
0b6ae522
DJ
8539{
8540 const char *procname;
8541 bfd_vma sym_offset;
8542
8543 if (addr.section == SHN_UNDEF)
8544 addr.offset = fn;
8545
dda8d76d 8546 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8547 aux->strtab_size, addr, &procname,
8548 &sym_offset);
8549
8550 print_vma (fn, PREFIX_HEX);
8551
8552 if (procname)
8553 {
8554 fputs (" <", stdout);
8555 fputs (procname, stdout);
8556
8557 if (sym_offset)
8558 printf ("+0x%lx", (unsigned long) sym_offset);
8559 fputc ('>', stdout);
8560 }
8561
8562 return procname;
8563}
8564
8565static void
8566arm_free_section (struct arm_section *arm_sec)
8567{
9db70fc3
AM
8568 free (arm_sec->data);
8569 free (arm_sec->rela);
0b6ae522
DJ
8570}
8571
a734115a
NC
8572/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8573 cached section and install SEC instead.
8574 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8575 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8576 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8577 relocation's offset in ADDR.
1b31d05e
NC
8578 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8579 into the string table of the symbol associated with the reloc. If no
8580 reloc was applied store -1 there.
8581 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
8582
8583static bfd_boolean
dda8d76d
NC
8584get_unwind_section_word (Filedata * filedata,
8585 struct arm_unw_aux_info * aux,
1b31d05e
NC
8586 struct arm_section * arm_sec,
8587 Elf_Internal_Shdr * sec,
8588 bfd_vma word_offset,
8589 unsigned int * wordp,
8590 struct absaddr * addr,
8591 bfd_vma * sym_name)
0b6ae522
DJ
8592{
8593 Elf_Internal_Rela *rp;
8594 Elf_Internal_Sym *sym;
8595 const char * relname;
8596 unsigned int word;
8597 bfd_boolean wrapped;
8598
e0a31db1
NC
8599 if (sec == NULL || arm_sec == NULL)
8600 return FALSE;
8601
0b6ae522
DJ
8602 addr->section = SHN_UNDEF;
8603 addr->offset = 0;
8604
1b31d05e
NC
8605 if (sym_name != NULL)
8606 *sym_name = (bfd_vma) -1;
8607
a734115a 8608 /* If necessary, update the section cache. */
0b6ae522
DJ
8609 if (sec != arm_sec->sec)
8610 {
8611 Elf_Internal_Shdr *relsec;
8612
8613 arm_free_section (arm_sec);
8614
8615 arm_sec->sec = sec;
dda8d76d 8616 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8617 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8618 arm_sec->rela = NULL;
8619 arm_sec->nrelas = 0;
8620
dda8d76d
NC
8621 for (relsec = filedata->section_headers;
8622 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8623 ++relsec)
8624 {
dda8d76d
NC
8625 if (relsec->sh_info >= filedata->file_header.e_shnum
8626 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8627 /* PR 15745: Check the section type as well. */
8628 || (relsec->sh_type != SHT_REL
8629 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8630 continue;
8631
a734115a 8632 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8633 if (relsec->sh_type == SHT_REL)
8634 {
dda8d76d 8635 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8636 relsec->sh_size,
8637 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8638 return FALSE;
0b6ae522 8639 }
1ae40aa4 8640 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8641 {
dda8d76d 8642 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8643 relsec->sh_size,
8644 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8645 return FALSE;
0b6ae522 8646 }
1ae40aa4 8647 break;
0b6ae522
DJ
8648 }
8649
8650 arm_sec->next_rela = arm_sec->rela;
8651 }
8652
a734115a 8653 /* If there is no unwind data we can do nothing. */
0b6ae522 8654 if (arm_sec->data == NULL)
a734115a 8655 return FALSE;
0b6ae522 8656
e0a31db1 8657 /* If the offset is invalid then fail. */
f32ba729
NC
8658 if (/* PR 21343 *//* PR 18879 */
8659 sec->sh_size < 4
8660 || word_offset > (sec->sh_size - 4)
1a915552 8661 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
8662 return FALSE;
8663
a734115a 8664 /* Get the word at the required offset. */
0b6ae522
DJ
8665 word = byte_get (arm_sec->data + word_offset, 4);
8666
0eff7165
NC
8667 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8668 if (arm_sec->rela == NULL)
8669 {
8670 * wordp = word;
8671 return TRUE;
8672 }
8673
a734115a 8674 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
8675 wrapped = FALSE;
8676 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8677 {
8678 bfd_vma prelval, offset;
8679
8680 if (rp->r_offset > word_offset && !wrapped)
8681 {
8682 rp = arm_sec->rela;
8683 wrapped = TRUE;
8684 }
8685 if (rp->r_offset > word_offset)
8686 break;
8687
8688 if (rp->r_offset & 3)
8689 {
8690 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8691 (unsigned long) rp->r_offset);
8692 continue;
8693 }
8694
8695 if (rp->r_offset < word_offset)
8696 continue;
8697
74e1a04b
NC
8698 /* PR 17531: file: 027-161405-0.004 */
8699 if (aux->symtab == NULL)
8700 continue;
8701
0b6ae522
DJ
8702 if (arm_sec->rel_type == SHT_REL)
8703 {
8704 offset = word & 0x7fffffff;
8705 if (offset & 0x40000000)
8706 offset |= ~ (bfd_vma) 0x7fffffff;
8707 }
a734115a 8708 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8709 offset = rp->r_addend;
a734115a 8710 else
74e1a04b
NC
8711 {
8712 error (_("Unknown section relocation type %d encountered\n"),
8713 arm_sec->rel_type);
8714 break;
8715 }
0b6ae522 8716
071436c6
NC
8717 /* PR 17531 file: 027-1241568-0.004. */
8718 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8719 {
8720 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8721 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8722 break;
8723 }
8724
8725 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8726 offset += sym->st_value;
8727 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8728
a734115a 8729 /* Check that we are processing the expected reloc type. */
dda8d76d 8730 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8731 {
8732 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8733 if (relname == NULL)
8734 {
8735 warn (_("Skipping unknown ARM relocation type: %d\n"),
8736 (int) ELF32_R_TYPE (rp->r_info));
8737 continue;
8738 }
a734115a
NC
8739
8740 if (streq (relname, "R_ARM_NONE"))
8741 continue;
0b4362b0 8742
a734115a
NC
8743 if (! streq (relname, "R_ARM_PREL31"))
8744 {
071436c6 8745 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8746 continue;
8747 }
8748 }
dda8d76d 8749 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8750 {
8751 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8752 if (relname == NULL)
8753 {
8754 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8755 (int) ELF32_R_TYPE (rp->r_info));
8756 continue;
8757 }
0b4362b0 8758
a734115a
NC
8759 if (streq (relname, "R_C6000_NONE"))
8760 continue;
8761
8762 if (! streq (relname, "R_C6000_PREL31"))
8763 {
071436c6 8764 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8765 continue;
8766 }
8767
8768 prelval >>= 1;
8769 }
8770 else
74e1a04b
NC
8771 {
8772 /* This function currently only supports ARM and TI unwinders. */
8773 warn (_("Only TI and ARM unwinders are currently supported\n"));
8774 break;
8775 }
fa197c1c 8776
0b6ae522
DJ
8777 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
8778 addr->section = sym->st_shndx;
8779 addr->offset = offset;
74e1a04b 8780
1b31d05e
NC
8781 if (sym_name)
8782 * sym_name = sym->st_name;
0b6ae522
DJ
8783 break;
8784 }
8785
8786 *wordp = word;
8787 arm_sec->next_rela = rp;
8788
a734115a 8789 return TRUE;
0b6ae522
DJ
8790}
8791
a734115a
NC
8792static const char *tic6x_unwind_regnames[16] =
8793{
0b4362b0
RM
8794 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
8795 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
8796 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
8797};
fa197c1c 8798
0b6ae522 8799static void
fa197c1c 8800decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 8801{
fa197c1c
PB
8802 int i;
8803
8804 for (i = 12; mask; mask >>= 1, i--)
8805 {
8806 if (mask & 1)
8807 {
8808 fputs (tic6x_unwind_regnames[i], stdout);
8809 if (mask > 1)
8810 fputs (", ", stdout);
8811 }
8812 }
8813}
0b6ae522
DJ
8814
8815#define ADVANCE \
8816 if (remaining == 0 && more_words) \
8817 { \
8818 data_offset += 4; \
dda8d76d 8819 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 8820 data_offset, & word, & addr, NULL)) \
32ec8896 8821 return FALSE; \
0b6ae522
DJ
8822 remaining = 4; \
8823 more_words--; \
8824 } \
8825
8826#define GET_OP(OP) \
8827 ADVANCE; \
8828 if (remaining) \
8829 { \
8830 remaining--; \
8831 (OP) = word >> 24; \
8832 word <<= 8; \
8833 } \
8834 else \
8835 { \
2b692964 8836 printf (_("[Truncated opcode]\n")); \
32ec8896 8837 return FALSE; \
0b6ae522 8838 } \
cc5914eb 8839 printf ("0x%02x ", OP)
0b6ae522 8840
32ec8896 8841static bfd_boolean
dda8d76d
NC
8842decode_arm_unwind_bytecode (Filedata * filedata,
8843 struct arm_unw_aux_info * aux,
948f632f
DA
8844 unsigned int word,
8845 unsigned int remaining,
8846 unsigned int more_words,
8847 bfd_vma data_offset,
8848 Elf_Internal_Shdr * data_sec,
8849 struct arm_section * data_arm_sec)
fa197c1c
PB
8850{
8851 struct absaddr addr;
32ec8896 8852 bfd_boolean res = TRUE;
0b6ae522
DJ
8853
8854 /* Decode the unwinding instructions. */
8855 while (1)
8856 {
8857 unsigned int op, op2;
8858
8859 ADVANCE;
8860 if (remaining == 0)
8861 break;
8862 remaining--;
8863 op = word >> 24;
8864 word <<= 8;
8865
cc5914eb 8866 printf (" 0x%02x ", op);
0b6ae522
DJ
8867
8868 if ((op & 0xc0) == 0x00)
8869 {
8870 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8871
cc5914eb 8872 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
8873 }
8874 else if ((op & 0xc0) == 0x40)
8875 {
8876 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8877
cc5914eb 8878 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
8879 }
8880 else if ((op & 0xf0) == 0x80)
8881 {
8882 GET_OP (op2);
8883 if (op == 0x80 && op2 == 0)
8884 printf (_("Refuse to unwind"));
8885 else
8886 {
8887 unsigned int mask = ((op & 0x0f) << 8) | op2;
32ec8896 8888 bfd_boolean first = TRUE;
0b6ae522 8889 int i;
2b692964 8890
0b6ae522
DJ
8891 printf ("pop {");
8892 for (i = 0; i < 12; i++)
8893 if (mask & (1 << i))
8894 {
8895 if (first)
32ec8896 8896 first = FALSE;
0b6ae522
DJ
8897 else
8898 printf (", ");
8899 printf ("r%d", 4 + i);
8900 }
8901 printf ("}");
8902 }
8903 }
8904 else if ((op & 0xf0) == 0x90)
8905 {
8906 if (op == 0x9d || op == 0x9f)
8907 printf (_(" [Reserved]"));
8908 else
cc5914eb 8909 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
8910 }
8911 else if ((op & 0xf0) == 0xa0)
8912 {
8913 int end = 4 + (op & 0x07);
32ec8896 8914 bfd_boolean first = TRUE;
0b6ae522 8915 int i;
61865e30 8916
0b6ae522
DJ
8917 printf (" pop {");
8918 for (i = 4; i <= end; i++)
8919 {
8920 if (first)
32ec8896 8921 first = FALSE;
0b6ae522
DJ
8922 else
8923 printf (", ");
8924 printf ("r%d", i);
8925 }
8926 if (op & 0x08)
8927 {
1b31d05e 8928 if (!first)
0b6ae522
DJ
8929 printf (", ");
8930 printf ("r14");
8931 }
8932 printf ("}");
8933 }
8934 else if (op == 0xb0)
8935 printf (_(" finish"));
8936 else if (op == 0xb1)
8937 {
8938 GET_OP (op2);
8939 if (op2 == 0 || (op2 & 0xf0) != 0)
8940 printf (_("[Spare]"));
8941 else
8942 {
8943 unsigned int mask = op2 & 0x0f;
32ec8896 8944 bfd_boolean first = TRUE;
0b6ae522 8945 int i;
61865e30 8946
0b6ae522
DJ
8947 printf ("pop {");
8948 for (i = 0; i < 12; i++)
8949 if (mask & (1 << i))
8950 {
8951 if (first)
32ec8896 8952 first = FALSE;
0b6ae522
DJ
8953 else
8954 printf (", ");
8955 printf ("r%d", i);
8956 }
8957 printf ("}");
8958 }
8959 }
8960 else if (op == 0xb2)
8961 {
b115cf96 8962 unsigned char buf[9];
0b6ae522
DJ
8963 unsigned int i, len;
8964 unsigned long offset;
61865e30 8965
b115cf96 8966 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
8967 {
8968 GET_OP (buf[i]);
8969 if ((buf[i] & 0x80) == 0)
8970 break;
8971 }
4082ef84 8972 if (i == sizeof (buf))
32ec8896 8973 {
27a45f42 8974 error (_("corrupt change to vsp\n"));
32ec8896
NC
8975 res = FALSE;
8976 }
4082ef84
NC
8977 else
8978 {
cd30bcef 8979 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
4082ef84
NC
8980 assert (len == i + 1);
8981 offset = offset * 4 + 0x204;
8982 printf ("vsp = vsp + %ld", offset);
8983 }
0b6ae522 8984 }
61865e30 8985 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 8986 {
61865e30
NC
8987 unsigned int first, last;
8988
8989 GET_OP (op2);
8990 first = op2 >> 4;
8991 last = op2 & 0x0f;
8992 if (op == 0xc8)
8993 first = first + 16;
8994 printf ("pop {D%d", first);
8995 if (last)
8996 printf ("-D%d", first + last);
8997 printf ("}");
8998 }
8999 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9000 {
9001 unsigned int count = op & 0x07;
9002
9003 printf ("pop {D8");
9004 if (count)
9005 printf ("-D%d", 8 + count);
9006 printf ("}");
9007 }
9008 else if (op >= 0xc0 && op <= 0xc5)
9009 {
9010 unsigned int count = op & 0x07;
9011
9012 printf (" pop {wR10");
9013 if (count)
9014 printf ("-wR%d", 10 + count);
9015 printf ("}");
9016 }
9017 else if (op == 0xc6)
9018 {
9019 unsigned int first, last;
9020
9021 GET_OP (op2);
9022 first = op2 >> 4;
9023 last = op2 & 0x0f;
9024 printf ("pop {wR%d", first);
9025 if (last)
9026 printf ("-wR%d", first + last);
9027 printf ("}");
9028 }
9029 else if (op == 0xc7)
9030 {
9031 GET_OP (op2);
9032 if (op2 == 0 || (op2 & 0xf0) != 0)
9033 printf (_("[Spare]"));
0b6ae522
DJ
9034 else
9035 {
61865e30 9036 unsigned int mask = op2 & 0x0f;
32ec8896 9037 bfd_boolean first = TRUE;
61865e30
NC
9038 int i;
9039
9040 printf ("pop {");
9041 for (i = 0; i < 4; i++)
9042 if (mask & (1 << i))
9043 {
9044 if (first)
32ec8896 9045 first = FALSE;
61865e30
NC
9046 else
9047 printf (", ");
9048 printf ("wCGR%d", i);
9049 }
9050 printf ("}");
0b6ae522
DJ
9051 }
9052 }
61865e30 9053 else
32ec8896
NC
9054 {
9055 printf (_(" [unsupported opcode]"));
9056 res = FALSE;
9057 }
9058
0b6ae522
DJ
9059 printf ("\n");
9060 }
32ec8896
NC
9061
9062 return res;
fa197c1c
PB
9063}
9064
32ec8896 9065static bfd_boolean
dda8d76d
NC
9066decode_tic6x_unwind_bytecode (Filedata * filedata,
9067 struct arm_unw_aux_info * aux,
948f632f
DA
9068 unsigned int word,
9069 unsigned int remaining,
9070 unsigned int more_words,
9071 bfd_vma data_offset,
9072 Elf_Internal_Shdr * data_sec,
9073 struct arm_section * data_arm_sec)
fa197c1c
PB
9074{
9075 struct absaddr addr;
9076
9077 /* Decode the unwinding instructions. */
9078 while (1)
9079 {
9080 unsigned int op, op2;
9081
9082 ADVANCE;
9083 if (remaining == 0)
9084 break;
9085 remaining--;
9086 op = word >> 24;
9087 word <<= 8;
9088
9cf03b7e 9089 printf (" 0x%02x ", op);
fa197c1c
PB
9090
9091 if ((op & 0xc0) == 0x00)
9092 {
9093 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9094 printf (" sp = sp + %d", offset);
fa197c1c
PB
9095 }
9096 else if ((op & 0xc0) == 0x80)
9097 {
9098 GET_OP (op2);
9099 if (op == 0x80 && op2 == 0)
9100 printf (_("Refuse to unwind"));
9101 else
9102 {
9103 unsigned int mask = ((op & 0x1f) << 8) | op2;
9104 if (op & 0x20)
9105 printf ("pop compact {");
9106 else
9107 printf ("pop {");
9108
9109 decode_tic6x_unwind_regmask (mask);
9110 printf("}");
9111 }
9112 }
9113 else if ((op & 0xf0) == 0xc0)
9114 {
9115 unsigned int reg;
9116 unsigned int nregs;
9117 unsigned int i;
9118 const char *name;
a734115a
NC
9119 struct
9120 {
32ec8896
NC
9121 unsigned int offset;
9122 unsigned int reg;
fa197c1c
PB
9123 } regpos[16];
9124
9125 /* Scan entire instruction first so that GET_OP output is not
9126 interleaved with disassembly. */
9127 nregs = 0;
9128 for (i = 0; nregs < (op & 0xf); i++)
9129 {
9130 GET_OP (op2);
9131 reg = op2 >> 4;
9132 if (reg != 0xf)
9133 {
9134 regpos[nregs].offset = i * 2;
9135 regpos[nregs].reg = reg;
9136 nregs++;
9137 }
9138
9139 reg = op2 & 0xf;
9140 if (reg != 0xf)
9141 {
9142 regpos[nregs].offset = i * 2 + 1;
9143 regpos[nregs].reg = reg;
9144 nregs++;
9145 }
9146 }
9147
9148 printf (_("pop frame {"));
18344509 9149 if (nregs == 0)
fa197c1c 9150 {
18344509
NC
9151 printf (_("*corrupt* - no registers specified"));
9152 }
9153 else
9154 {
9155 reg = nregs - 1;
9156 for (i = i * 2; i > 0; i--)
fa197c1c 9157 {
18344509
NC
9158 if (regpos[reg].offset == i - 1)
9159 {
9160 name = tic6x_unwind_regnames[regpos[reg].reg];
9161 if (reg > 0)
9162 reg--;
9163 }
9164 else
9165 name = _("[pad]");
fa197c1c 9166
18344509
NC
9167 fputs (name, stdout);
9168 if (i > 1)
9169 printf (", ");
9170 }
fa197c1c
PB
9171 }
9172
9173 printf ("}");
9174 }
9175 else if (op == 0xd0)
9176 printf (" MOV FP, SP");
9177 else if (op == 0xd1)
9178 printf (" __c6xabi_pop_rts");
9179 else if (op == 0xd2)
9180 {
9181 unsigned char buf[9];
9182 unsigned int i, len;
9183 unsigned long offset;
a734115a 9184
fa197c1c
PB
9185 for (i = 0; i < sizeof (buf); i++)
9186 {
9187 GET_OP (buf[i]);
9188 if ((buf[i] & 0x80) == 0)
9189 break;
9190 }
0eff7165
NC
9191 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9192 if (i == sizeof (buf))
9193 {
0eff7165 9194 warn (_("Corrupt stack pointer adjustment detected\n"));
32ec8896 9195 return FALSE;
0eff7165 9196 }
948f632f 9197
cd30bcef 9198 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
fa197c1c
PB
9199 assert (len == i + 1);
9200 offset = offset * 8 + 0x408;
9201 printf (_("sp = sp + %ld"), offset);
9202 }
9203 else if ((op & 0xf0) == 0xe0)
9204 {
9205 if ((op & 0x0f) == 7)
9206 printf (" RETURN");
9207 else
9208 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9209 }
9210 else
9211 {
9212 printf (_(" [unsupported opcode]"));
9213 }
9214 putchar ('\n');
9215 }
32ec8896
NC
9216
9217 return TRUE;
fa197c1c
PB
9218}
9219
9220static bfd_vma
dda8d76d 9221arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9222{
9223 bfd_vma offset;
9224
9225 offset = word & 0x7fffffff;
9226 if (offset & 0x40000000)
9227 offset |= ~ (bfd_vma) 0x7fffffff;
9228
dda8d76d 9229 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9230 offset <<= 1;
9231
9232 return offset + where;
9233}
9234
32ec8896 9235static bfd_boolean
dda8d76d
NC
9236decode_arm_unwind (Filedata * filedata,
9237 struct arm_unw_aux_info * aux,
1b31d05e
NC
9238 unsigned int word,
9239 unsigned int remaining,
9240 bfd_vma data_offset,
9241 Elf_Internal_Shdr * data_sec,
9242 struct arm_section * data_arm_sec)
fa197c1c
PB
9243{
9244 int per_index;
9245 unsigned int more_words = 0;
37e14bc3 9246 struct absaddr addr;
1b31d05e 9247 bfd_vma sym_name = (bfd_vma) -1;
97953bab 9248 bfd_boolean res = TRUE;
fa197c1c
PB
9249
9250 if (remaining == 0)
9251 {
1b31d05e
NC
9252 /* Fetch the first word.
9253 Note - when decoding an object file the address extracted
9254 here will always be 0. So we also pass in the sym_name
9255 parameter so that we can find the symbol associated with
9256 the personality routine. */
dda8d76d 9257 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9258 & word, & addr, & sym_name))
32ec8896 9259 return FALSE;
1b31d05e 9260
fa197c1c
PB
9261 remaining = 4;
9262 }
c93dbb25
CZ
9263 else
9264 {
9265 addr.section = SHN_UNDEF;
9266 addr.offset = 0;
9267 }
fa197c1c
PB
9268
9269 if ((word & 0x80000000) == 0)
9270 {
9271 /* Expand prel31 for personality routine. */
9272 bfd_vma fn;
9273 const char *procname;
9274
dda8d76d 9275 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9276 printf (_(" Personality routine: "));
1b31d05e
NC
9277 if (fn == 0
9278 && addr.section == SHN_UNDEF && addr.offset == 0
9279 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9280 {
9281 procname = aux->strtab + sym_name;
9282 print_vma (fn, PREFIX_HEX);
9283 if (procname)
9284 {
9285 fputs (" <", stdout);
9286 fputs (procname, stdout);
9287 fputc ('>', stdout);
9288 }
9289 }
9290 else
dda8d76d 9291 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9292 fputc ('\n', stdout);
9293
9294 /* The GCC personality routines use the standard compact
9295 encoding, starting with one byte giving the number of
9296 words. */
9297 if (procname != NULL
9298 && (const_strneq (procname, "__gcc_personality_v0")
9299 || const_strneq (procname, "__gxx_personality_v0")
9300 || const_strneq (procname, "__gcj_personality_v0")
9301 || const_strneq (procname, "__gnu_objc_personality_v0")))
9302 {
9303 remaining = 0;
9304 more_words = 1;
9305 ADVANCE;
9306 if (!remaining)
9307 {
9308 printf (_(" [Truncated data]\n"));
32ec8896 9309 return FALSE;
fa197c1c
PB
9310 }
9311 more_words = word >> 24;
9312 word <<= 8;
9313 remaining--;
9314 per_index = -1;
9315 }
9316 else
32ec8896 9317 return TRUE;
fa197c1c
PB
9318 }
9319 else
9320 {
1b31d05e 9321 /* ARM EHABI Section 6.3:
0b4362b0 9322
1b31d05e 9323 An exception-handling table entry for the compact model looks like:
0b4362b0 9324
1b31d05e
NC
9325 31 30-28 27-24 23-0
9326 -- ----- ----- ----
9327 1 0 index Data for personalityRoutine[index] */
9328
dda8d76d 9329 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9330 && (word & 0x70000000))
32ec8896
NC
9331 {
9332 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
9333 res = FALSE;
9334 }
1b31d05e 9335
fa197c1c 9336 per_index = (word >> 24) & 0x7f;
1b31d05e 9337 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9338 if (per_index == 0)
9339 {
9340 more_words = 0;
9341 word <<= 8;
9342 remaining--;
9343 }
9344 else if (per_index < 3)
9345 {
9346 more_words = (word >> 16) & 0xff;
9347 word <<= 16;
9348 remaining -= 2;
9349 }
9350 }
9351
dda8d76d 9352 switch (filedata->file_header.e_machine)
fa197c1c
PB
9353 {
9354 case EM_ARM:
9355 if (per_index < 3)
9356 {
dda8d76d 9357 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9358 data_offset, data_sec, data_arm_sec))
9359 res = FALSE;
fa197c1c
PB
9360 }
9361 else
1b31d05e
NC
9362 {
9363 warn (_("Unknown ARM compact model index encountered\n"));
9364 printf (_(" [reserved]\n"));
32ec8896 9365 res = FALSE;
1b31d05e 9366 }
fa197c1c
PB
9367 break;
9368
9369 case EM_TI_C6000:
9370 if (per_index < 3)
9371 {
dda8d76d 9372 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9373 data_offset, data_sec, data_arm_sec))
9374 res = FALSE;
fa197c1c
PB
9375 }
9376 else if (per_index < 5)
9377 {
9378 if (((word >> 17) & 0x7f) == 0x7f)
9379 printf (_(" Restore stack from frame pointer\n"));
9380 else
9381 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9382 printf (_(" Registers restored: "));
9383 if (per_index == 4)
9384 printf (" (compact) ");
9385 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9386 putchar ('\n');
9387 printf (_(" Return register: %s\n"),
9388 tic6x_unwind_regnames[word & 0xf]);
9389 }
9390 else
1b31d05e 9391 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9392 break;
9393
9394 default:
74e1a04b 9395 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9396 filedata->file_header.e_machine);
32ec8896 9397 res = FALSE;
fa197c1c 9398 }
0b6ae522
DJ
9399
9400 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9401
9402 return res;
0b6ae522
DJ
9403}
9404
32ec8896 9405static bfd_boolean
dda8d76d
NC
9406dump_arm_unwind (Filedata * filedata,
9407 struct arm_unw_aux_info * aux,
9408 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9409{
9410 struct arm_section exidx_arm_sec, extab_arm_sec;
9411 unsigned int i, exidx_len;
948f632f 9412 unsigned long j, nfuns;
32ec8896 9413 bfd_boolean res = TRUE;
0b6ae522
DJ
9414
9415 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9416 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9417 exidx_len = exidx_sec->sh_size / 8;
9418
948f632f
DA
9419 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9420 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9421 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9422 aux->funtab[nfuns++] = aux->symtab[j];
9423 aux->nfuns = nfuns;
9424 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9425
0b6ae522
DJ
9426 for (i = 0; i < exidx_len; i++)
9427 {
9428 unsigned int exidx_fn, exidx_entry;
9429 struct absaddr fn_addr, entry_addr;
9430 bfd_vma fn;
9431
9432 fputc ('\n', stdout);
9433
dda8d76d 9434 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9435 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9436 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9437 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9438 {
948f632f 9439 free (aux->funtab);
1b31d05e
NC
9440 arm_free_section (& exidx_arm_sec);
9441 arm_free_section (& extab_arm_sec);
32ec8896 9442 return FALSE;
0b6ae522
DJ
9443 }
9444
83c257ca
NC
9445 /* ARM EHABI, Section 5:
9446 An index table entry consists of 2 words.
9447 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9448 if (exidx_fn & 0x80000000)
32ec8896
NC
9449 {
9450 warn (_("corrupt index table entry: %x\n"), exidx_fn);
9451 res = FALSE;
9452 }
83c257ca 9453
dda8d76d 9454 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9455
dda8d76d 9456 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9457 fputs (": ", stdout);
9458
9459 if (exidx_entry == 1)
9460 {
9461 print_vma (exidx_entry, PREFIX_HEX);
9462 fputs (" [cantunwind]\n", stdout);
9463 }
9464 else if (exidx_entry & 0x80000000)
9465 {
9466 print_vma (exidx_entry, PREFIX_HEX);
9467 fputc ('\n', stdout);
dda8d76d 9468 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9469 }
9470 else
9471 {
8f73510c 9472 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9473 Elf_Internal_Shdr *table_sec;
9474
9475 fputs ("@", stdout);
dda8d76d 9476 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9477 print_vma (table, PREFIX_HEX);
9478 printf ("\n");
9479
9480 /* Locate the matching .ARM.extab. */
9481 if (entry_addr.section != SHN_UNDEF
dda8d76d 9482 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9483 {
dda8d76d 9484 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9485 table_offset = entry_addr.offset;
1a915552
NC
9486 /* PR 18879 */
9487 if (table_offset > table_sec->sh_size
9488 || ((bfd_signed_vma) table_offset) < 0)
9489 {
9490 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9491 (unsigned long) table_offset,
dda8d76d 9492 printable_section_name (filedata, table_sec));
32ec8896 9493 res = FALSE;
1a915552
NC
9494 continue;
9495 }
0b6ae522
DJ
9496 }
9497 else
9498 {
dda8d76d 9499 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9500 if (table_sec != NULL)
9501 table_offset = table - table_sec->sh_addr;
9502 }
32ec8896 9503
0b6ae522
DJ
9504 if (table_sec == NULL)
9505 {
9506 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9507 (unsigned long) table);
32ec8896 9508 res = FALSE;
0b6ae522
DJ
9509 continue;
9510 }
32ec8896 9511
dda8d76d 9512 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896
NC
9513 &extab_arm_sec))
9514 res = FALSE;
0b6ae522
DJ
9515 }
9516 }
9517
9518 printf ("\n");
9519
948f632f 9520 free (aux->funtab);
0b6ae522
DJ
9521 arm_free_section (&exidx_arm_sec);
9522 arm_free_section (&extab_arm_sec);
32ec8896
NC
9523
9524 return res;
0b6ae522
DJ
9525}
9526
fa197c1c 9527/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9528
32ec8896 9529static bfd_boolean
dda8d76d 9530arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9531{
9532 struct arm_unw_aux_info aux;
9533 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9534 Elf_Internal_Shdr *sec;
9535 unsigned long i;
fa197c1c 9536 unsigned int sec_type;
32ec8896 9537 bfd_boolean res = TRUE;
0b6ae522 9538
dda8d76d 9539 switch (filedata->file_header.e_machine)
fa197c1c
PB
9540 {
9541 case EM_ARM:
9542 sec_type = SHT_ARM_EXIDX;
9543 break;
9544
9545 case EM_TI_C6000:
9546 sec_type = SHT_C6000_UNWIND;
9547 break;
9548
0b4362b0 9549 default:
74e1a04b 9550 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9551 filedata->file_header.e_machine);
32ec8896 9552 return FALSE;
fa197c1c
PB
9553 }
9554
dda8d76d 9555 if (filedata->string_table == NULL)
32ec8896 9556 return FALSE;
1b31d05e
NC
9557
9558 memset (& aux, 0, sizeof (aux));
dda8d76d 9559 aux.filedata = filedata;
0b6ae522 9560
dda8d76d 9561 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9562 {
28d13567 9563 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9564 {
28d13567 9565 if (aux.symtab)
74e1a04b 9566 {
28d13567
AM
9567 error (_("Multiple symbol tables encountered\n"));
9568 free (aux.symtab);
9569 aux.symtab = NULL;
74e1a04b 9570 free (aux.strtab);
28d13567 9571 aux.strtab = NULL;
74e1a04b 9572 }
28d13567
AM
9573 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9574 &aux.strtab, &aux.strtab_size))
9575 return FALSE;
0b6ae522 9576 }
fa197c1c 9577 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9578 unwsec = sec;
9579 }
9580
1b31d05e 9581 if (unwsec == NULL)
0b6ae522 9582 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9583 else
dda8d76d 9584 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9585 {
9586 if (sec->sh_type == sec_type)
9587 {
d3a49aa8
AM
9588 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9589 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9590 "contains %lu entry:\n",
9591 "\nUnwind section '%s' at offset 0x%lx "
9592 "contains %lu entries:\n",
9593 num_unwind),
dda8d76d 9594 printable_section_name (filedata, sec),
1b31d05e 9595 (unsigned long) sec->sh_offset,
d3a49aa8 9596 num_unwind);
0b6ae522 9597
dda8d76d 9598 if (! dump_arm_unwind (filedata, &aux, sec))
32ec8896 9599 res = FALSE;
1b31d05e
NC
9600 }
9601 }
0b6ae522 9602
9db70fc3
AM
9603 free (aux.symtab);
9604 free ((char *) aux.strtab);
32ec8896
NC
9605
9606 return res;
0b6ae522
DJ
9607}
9608
32ec8896 9609static bfd_boolean
dda8d76d 9610process_unwind (Filedata * filedata)
57346661 9611{
2cf0635d
NC
9612 struct unwind_handler
9613 {
32ec8896 9614 unsigned int machtype;
dda8d76d 9615 bfd_boolean (* handler)(Filedata *);
2cf0635d
NC
9616 } handlers[] =
9617 {
0b6ae522 9618 { EM_ARM, arm_process_unwind },
57346661
AM
9619 { EM_IA_64, ia64_process_unwind },
9620 { EM_PARISC, hppa_process_unwind },
fa197c1c 9621 { EM_TI_C6000, arm_process_unwind },
32ec8896 9622 { 0, NULL }
57346661
AM
9623 };
9624 int i;
9625
9626 if (!do_unwind)
32ec8896 9627 return TRUE;
57346661
AM
9628
9629 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9630 if (filedata->file_header.e_machine == handlers[i].machtype)
9631 return handlers[i].handler (filedata);
57346661 9632
1b31d05e 9633 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9634 get_machine_name (filedata->file_header.e_machine));
32ec8896 9635 return TRUE;
57346661
AM
9636}
9637
37c18eed
SD
9638static void
9639dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
9640{
9641 switch (entry->d_tag)
9642 {
9643 case DT_AARCH64_BTI_PLT:
1dbade74 9644 case DT_AARCH64_PAC_PLT:
37c18eed
SD
9645 break;
9646 default:
9647 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9648 break;
9649 }
9650 putchar ('\n');
9651}
9652
252b5132 9653static void
978c4450 9654dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
9655{
9656 switch (entry->d_tag)
9657 {
9658 case DT_MIPS_FLAGS:
9659 if (entry->d_un.d_val == 0)
4b68bca3 9660 printf (_("NONE"));
252b5132
RH
9661 else
9662 {
9663 static const char * opts[] =
9664 {
9665 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9666 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9667 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9668 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9669 "RLD_ORDER_SAFE"
9670 };
9671 unsigned int cnt;
32ec8896 9672 bfd_boolean first = TRUE;
2b692964 9673
60bca95a 9674 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9675 if (entry->d_un.d_val & (1 << cnt))
9676 {
9677 printf ("%s%s", first ? "" : " ", opts[cnt]);
32ec8896 9678 first = FALSE;
252b5132 9679 }
252b5132
RH
9680 }
9681 break;
103f02d3 9682
252b5132 9683 case DT_MIPS_IVERSION:
978c4450
AM
9684 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
9685 printf (_("Interface Version: %s"),
9686 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 9687 else
76ca31c0
NC
9688 {
9689 char buf[40];
9690 sprintf_vma (buf, entry->d_un.d_ptr);
9691 /* Note: coded this way so that there is a single string for translation. */
9692 printf (_("<corrupt: %s>"), buf);
9693 }
252b5132 9694 break;
103f02d3 9695
252b5132
RH
9696 case DT_MIPS_TIME_STAMP:
9697 {
d5b07ef4 9698 char timebuf[128];
2cf0635d 9699 struct tm * tmp;
91d6fa6a 9700 time_t atime = entry->d_un.d_val;
82b1b41b 9701
91d6fa6a 9702 tmp = gmtime (&atime);
82b1b41b
NC
9703 /* PR 17531: file: 6accc532. */
9704 if (tmp == NULL)
9705 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9706 else
9707 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9708 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9709 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9710 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9711 }
9712 break;
103f02d3 9713
252b5132
RH
9714 case DT_MIPS_RLD_VERSION:
9715 case DT_MIPS_LOCAL_GOTNO:
9716 case DT_MIPS_CONFLICTNO:
9717 case DT_MIPS_LIBLISTNO:
9718 case DT_MIPS_SYMTABNO:
9719 case DT_MIPS_UNREFEXTNO:
9720 case DT_MIPS_HIPAGENO:
9721 case DT_MIPS_DELTA_CLASS_NO:
9722 case DT_MIPS_DELTA_INSTANCE_NO:
9723 case DT_MIPS_DELTA_RELOC_NO:
9724 case DT_MIPS_DELTA_SYM_NO:
9725 case DT_MIPS_DELTA_CLASSSYM_NO:
9726 case DT_MIPS_COMPACT_SIZE:
c69075ac 9727 print_vma (entry->d_un.d_val, DEC);
252b5132 9728 break;
103f02d3 9729
f16a9783 9730 case DT_MIPS_XHASH:
978c4450
AM
9731 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
9732 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
9733 /* Falls through. */
9734
103f02d3 9735 default:
4b68bca3 9736 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9737 }
4b68bca3 9738 putchar ('\n');
103f02d3
UD
9739}
9740
103f02d3 9741static void
2cf0635d 9742dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9743{
9744 switch (entry->d_tag)
9745 {
9746 case DT_HP_DLD_FLAGS:
9747 {
9748 static struct
9749 {
9750 long int bit;
2cf0635d 9751 const char * str;
5e220199
NC
9752 }
9753 flags[] =
9754 {
9755 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9756 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9757 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9758 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9759 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9760 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9761 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9762 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9763 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9764 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9765 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9766 { DT_HP_GST, "HP_GST" },
9767 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
9768 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
9769 { DT_HP_NODELETE, "HP_NODELETE" },
9770 { DT_HP_GROUP, "HP_GROUP" },
9771 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 9772 };
32ec8896 9773 bfd_boolean first = TRUE;
5e220199 9774 size_t cnt;
f7a99963 9775 bfd_vma val = entry->d_un.d_val;
103f02d3 9776
60bca95a 9777 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 9778 if (val & flags[cnt].bit)
30800947
NC
9779 {
9780 if (! first)
9781 putchar (' ');
9782 fputs (flags[cnt].str, stdout);
32ec8896 9783 first = FALSE;
30800947
NC
9784 val ^= flags[cnt].bit;
9785 }
76da6bbe 9786
103f02d3 9787 if (val != 0 || first)
f7a99963
NC
9788 {
9789 if (! first)
9790 putchar (' ');
9791 print_vma (val, HEX);
9792 }
103f02d3
UD
9793 }
9794 break;
76da6bbe 9795
252b5132 9796 default:
f7a99963
NC
9797 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9798 break;
252b5132 9799 }
35b1837e 9800 putchar ('\n');
252b5132
RH
9801}
9802
28f997cf
TG
9803#ifdef BFD64
9804
9805/* VMS vs Unix time offset and factor. */
9806
9807#define VMS_EPOCH_OFFSET 35067168000000000LL
9808#define VMS_GRANULARITY_FACTOR 10000000
9809
9810/* Display a VMS time in a human readable format. */
9811
9812static void
9813print_vms_time (bfd_int64_t vmstime)
9814{
9815 struct tm *tm;
9816 time_t unxtime;
9817
9818 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
9819 tm = gmtime (&unxtime);
9820 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
9821 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
9822 tm->tm_hour, tm->tm_min, tm->tm_sec);
9823}
9824#endif /* BFD64 */
9825
ecc51f48 9826static void
2cf0635d 9827dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
9828{
9829 switch (entry->d_tag)
9830 {
0de14b54 9831 case DT_IA_64_PLT_RESERVE:
bdf4d63a 9832 /* First 3 slots reserved. */
ecc51f48
NC
9833 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9834 printf (" -- ");
9835 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
9836 break;
9837
28f997cf
TG
9838 case DT_IA_64_VMS_LINKTIME:
9839#ifdef BFD64
9840 print_vms_time (entry->d_un.d_val);
9841#endif
9842 break;
9843
9844 case DT_IA_64_VMS_LNKFLAGS:
9845 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9846 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
9847 printf (" CALL_DEBUG");
9848 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
9849 printf (" NOP0BUFS");
9850 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
9851 printf (" P0IMAGE");
9852 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
9853 printf (" MKTHREADS");
9854 if (entry->d_un.d_val & VMS_LF_UPCALLS)
9855 printf (" UPCALLS");
9856 if (entry->d_un.d_val & VMS_LF_IMGSTA)
9857 printf (" IMGSTA");
9858 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
9859 printf (" INITIALIZE");
9860 if (entry->d_un.d_val & VMS_LF_MAIN)
9861 printf (" MAIN");
9862 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
9863 printf (" EXE_INIT");
9864 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
9865 printf (" TBK_IN_IMG");
9866 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
9867 printf (" DBG_IN_IMG");
9868 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
9869 printf (" TBK_IN_DSF");
9870 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
9871 printf (" DBG_IN_DSF");
9872 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
9873 printf (" SIGNATURES");
9874 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
9875 printf (" REL_SEG_OFF");
9876 break;
9877
bdf4d63a
JJ
9878 default:
9879 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9880 break;
ecc51f48 9881 }
bdf4d63a 9882 putchar ('\n');
ecc51f48
NC
9883}
9884
32ec8896 9885static bfd_boolean
dda8d76d 9886get_32bit_dynamic_section (Filedata * filedata)
252b5132 9887{
2cf0635d
NC
9888 Elf32_External_Dyn * edyn;
9889 Elf32_External_Dyn * ext;
9890 Elf_Internal_Dyn * entry;
103f02d3 9891
978c4450
AM
9892 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
9893 filedata->dynamic_addr, 1,
9894 filedata->dynamic_size,
9895 _("dynamic section"));
a6e9f9df 9896 if (!edyn)
32ec8896 9897 return FALSE;
103f02d3 9898
071436c6
NC
9899 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9900 might not have the luxury of section headers. Look for the DT_NULL
9901 terminator to determine the number of entries. */
978c4450
AM
9902 for (ext = edyn, filedata->dynamic_nent = 0;
9903 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
9904 ext++)
9905 {
978c4450 9906 filedata->dynamic_nent++;
ba2685cc
AM
9907 if (BYTE_GET (ext->d_tag) == DT_NULL)
9908 break;
9909 }
252b5132 9910
978c4450
AM
9911 filedata->dynamic_section
9912 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
9913 if (filedata->dynamic_section == NULL)
252b5132 9914 {
8b73c356 9915 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 9916 (unsigned long) filedata->dynamic_nent);
9ea033b2 9917 free (edyn);
32ec8896 9918 return FALSE;
9ea033b2 9919 }
252b5132 9920
978c4450
AM
9921 for (ext = edyn, entry = filedata->dynamic_section;
9922 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 9923 ext++, entry++)
9ea033b2 9924 {
fb514b26
AM
9925 entry->d_tag = BYTE_GET (ext->d_tag);
9926 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9927 }
9928
9ea033b2
NC
9929 free (edyn);
9930
32ec8896 9931 return TRUE;
9ea033b2
NC
9932}
9933
32ec8896 9934static bfd_boolean
dda8d76d 9935get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 9936{
2cf0635d
NC
9937 Elf64_External_Dyn * edyn;
9938 Elf64_External_Dyn * ext;
9939 Elf_Internal_Dyn * entry;
103f02d3 9940
071436c6 9941 /* Read in the data. */
978c4450
AM
9942 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
9943 filedata->dynamic_addr, 1,
9944 filedata->dynamic_size,
9945 _("dynamic section"));
a6e9f9df 9946 if (!edyn)
32ec8896 9947 return FALSE;
103f02d3 9948
071436c6
NC
9949 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9950 might not have the luxury of section headers. Look for the DT_NULL
9951 terminator to determine the number of entries. */
978c4450 9952 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 9953 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 9954 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
9955 ext++)
9956 {
978c4450 9957 filedata->dynamic_nent++;
66543521 9958 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
9959 break;
9960 }
252b5132 9961
978c4450
AM
9962 filedata->dynamic_section
9963 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
9964 if (filedata->dynamic_section == NULL)
252b5132 9965 {
8b73c356 9966 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 9967 (unsigned long) filedata->dynamic_nent);
252b5132 9968 free (edyn);
32ec8896 9969 return FALSE;
252b5132
RH
9970 }
9971
071436c6 9972 /* Convert from external to internal formats. */
978c4450
AM
9973 for (ext = edyn, entry = filedata->dynamic_section;
9974 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 9975 ext++, entry++)
252b5132 9976 {
66543521
AM
9977 entry->d_tag = BYTE_GET (ext->d_tag);
9978 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9979 }
9980
9981 free (edyn);
9982
32ec8896 9983 return TRUE;
9ea033b2
NC
9984}
9985
e9e44622
JJ
9986static void
9987print_dynamic_flags (bfd_vma flags)
d1133906 9988{
32ec8896 9989 bfd_boolean first = TRUE;
13ae64f3 9990
d1133906
NC
9991 while (flags)
9992 {
9993 bfd_vma flag;
9994
9995 flag = flags & - flags;
9996 flags &= ~ flag;
9997
e9e44622 9998 if (first)
32ec8896 9999 first = FALSE;
e9e44622
JJ
10000 else
10001 putc (' ', stdout);
13ae64f3 10002
d1133906
NC
10003 switch (flag)
10004 {
e9e44622
JJ
10005 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10006 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10007 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10008 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10009 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10010 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10011 }
10012 }
e9e44622 10013 puts ("");
d1133906
NC
10014}
10015
10ca4b04
L
10016static bfd_vma *
10017get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10018{
10019 unsigned char * e_data;
10020 bfd_vma * i_data;
10021
10022 /* If the size_t type is smaller than the bfd_size_type, eg because
10023 you are building a 32-bit tool on a 64-bit host, then make sure
10024 that when (number) is cast to (size_t) no information is lost. */
10025 if (sizeof (size_t) < sizeof (bfd_size_type)
10026 && (bfd_size_type) ((size_t) number) != number)
10027 {
10028 error (_("Size truncation prevents reading %s elements of size %u\n"),
10029 bfd_vmatoa ("u", number), ent_size);
10030 return NULL;
10031 }
10032
10033 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10034 attempting to allocate memory when the read is bound to fail. */
10035 if (ent_size * number > filedata->file_size)
10036 {
10037 error (_("Invalid number of dynamic entries: %s\n"),
10038 bfd_vmatoa ("u", number));
10039 return NULL;
10040 }
10041
10042 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10043 if (e_data == NULL)
10044 {
10045 error (_("Out of memory reading %s dynamic entries\n"),
10046 bfd_vmatoa ("u", number));
10047 return NULL;
10048 }
10049
10050 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10051 {
10052 error (_("Unable to read in %s bytes of dynamic data\n"),
10053 bfd_vmatoa ("u", number * ent_size));
10054 free (e_data);
10055 return NULL;
10056 }
10057
10058 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10059 if (i_data == NULL)
10060 {
10061 error (_("Out of memory allocating space for %s dynamic entries\n"),
10062 bfd_vmatoa ("u", number));
10063 free (e_data);
10064 return NULL;
10065 }
10066
10067 while (number--)
10068 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10069
10070 free (e_data);
10071
10072 return i_data;
10073}
10074
10075static unsigned long
10076get_num_dynamic_syms (Filedata * filedata)
10077{
10078 unsigned long num_of_syms = 0;
10079
10080 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10081 return num_of_syms;
10082
978c4450 10083 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10084 {
10085 unsigned char nb[8];
10086 unsigned char nc[8];
10087 unsigned int hash_ent_size = 4;
10088
10089 if ((filedata->file_header.e_machine == EM_ALPHA
10090 || filedata->file_header.e_machine == EM_S390
10091 || filedata->file_header.e_machine == EM_S390_OLD)
10092 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10093 hash_ent_size = 8;
10094
10095 if (fseek (filedata->handle,
978c4450
AM
10096 (filedata->archive_file_offset
10097 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10098 sizeof nb + sizeof nc)),
10099 SEEK_SET))
10100 {
10101 error (_("Unable to seek to start of dynamic information\n"));
10102 goto no_hash;
10103 }
10104
10105 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10106 {
10107 error (_("Failed to read in number of buckets\n"));
10108 goto no_hash;
10109 }
10110
10111 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10112 {
10113 error (_("Failed to read in number of chains\n"));
10114 goto no_hash;
10115 }
10116
978c4450
AM
10117 filedata->nbuckets = byte_get (nb, hash_ent_size);
10118 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10119
2482f306
AM
10120 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10121 {
10122 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10123 hash_ent_size);
10124 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10125 hash_ent_size);
001890e1 10126
2482f306
AM
10127 if (filedata->buckets != NULL && filedata->chains != NULL)
10128 num_of_syms = filedata->nchains;
10129 }
ceb9bf11 10130 no_hash:
10ca4b04
L
10131 if (num_of_syms == 0)
10132 {
9db70fc3
AM
10133 free (filedata->buckets);
10134 filedata->buckets = NULL;
10135 free (filedata->chains);
10136 filedata->chains = NULL;
978c4450 10137 filedata->nbuckets = 0;
10ca4b04
L
10138 }
10139 }
10140
978c4450 10141 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10142 {
10143 unsigned char nb[16];
10144 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10145 bfd_vma buckets_vma;
10146 unsigned long hn;
10ca4b04
L
10147
10148 if (fseek (filedata->handle,
978c4450
AM
10149 (filedata->archive_file_offset
10150 + offset_from_vma (filedata,
10151 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10152 sizeof nb)),
10153 SEEK_SET))
10154 {
10155 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10156 goto no_gnu_hash;
10157 }
10158
10159 if (fread (nb, 16, 1, filedata->handle) != 1)
10160 {
10161 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10162 goto no_gnu_hash;
10163 }
10164
978c4450
AM
10165 filedata->ngnubuckets = byte_get (nb, 4);
10166 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10167 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10168 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10169 if (is_32bit_elf)
10170 buckets_vma += bitmaskwords * 4;
10171 else
10172 buckets_vma += bitmaskwords * 8;
10173
10174 if (fseek (filedata->handle,
978c4450 10175 (filedata->archive_file_offset
10ca4b04
L
10176 + offset_from_vma (filedata, buckets_vma, 4)),
10177 SEEK_SET))
10178 {
10179 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10180 goto no_gnu_hash;
10181 }
10182
978c4450
AM
10183 filedata->gnubuckets
10184 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10185
978c4450 10186 if (filedata->gnubuckets == NULL)
90837ea7 10187 goto no_gnu_hash;
10ca4b04 10188
978c4450
AM
10189 for (i = 0; i < filedata->ngnubuckets; i++)
10190 if (filedata->gnubuckets[i] != 0)
10ca4b04 10191 {
978c4450 10192 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10193 goto no_gnu_hash;
10ca4b04 10194
978c4450
AM
10195 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10196 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10197 }
10198
10199 if (maxchain == 0xffffffff)
90837ea7 10200 goto no_gnu_hash;
10ca4b04 10201
978c4450 10202 maxchain -= filedata->gnusymidx;
10ca4b04
L
10203
10204 if (fseek (filedata->handle,
978c4450
AM
10205 (filedata->archive_file_offset
10206 + offset_from_vma (filedata,
10207 buckets_vma + 4 * (filedata->ngnubuckets
10208 + maxchain),
10209 4)),
10ca4b04
L
10210 SEEK_SET))
10211 {
10212 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10213 goto no_gnu_hash;
10214 }
10215
10216 do
10217 {
10218 if (fread (nb, 4, 1, filedata->handle) != 1)
10219 {
10220 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10221 goto no_gnu_hash;
10222 }
10223
10224 if (maxchain + 1 == 0)
90837ea7 10225 goto no_gnu_hash;
10ca4b04
L
10226
10227 ++maxchain;
10228 }
10229 while ((byte_get (nb, 4) & 1) == 0);
10230
10231 if (fseek (filedata->handle,
978c4450
AM
10232 (filedata->archive_file_offset
10233 + offset_from_vma (filedata, (buckets_vma
10234 + 4 * filedata->ngnubuckets),
10235 4)),
10ca4b04
L
10236 SEEK_SET))
10237 {
10238 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10239 goto no_gnu_hash;
10240 }
10241
978c4450
AM
10242 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10243 filedata->ngnuchains = maxchain;
10ca4b04 10244
978c4450 10245 if (filedata->gnuchains == NULL)
90837ea7 10246 goto no_gnu_hash;
10ca4b04 10247
978c4450 10248 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10249 {
10250 if (fseek (filedata->handle,
978c4450 10251 (filedata->archive_file_offset
10ca4b04 10252 + offset_from_vma (filedata, (buckets_vma
978c4450 10253 + 4 * (filedata->ngnubuckets
10ca4b04
L
10254 + maxchain)), 4)),
10255 SEEK_SET))
10256 {
10257 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10258 goto no_gnu_hash;
10259 }
10260
978c4450 10261 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10262 if (filedata->mipsxlat == NULL)
10263 goto no_gnu_hash;
10ca4b04
L
10264 }
10265
978c4450
AM
10266 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10267 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10268 {
978c4450
AM
10269 bfd_vma si = filedata->gnubuckets[hn];
10270 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10271
10272 do
10273 {
978c4450 10274 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 10275 {
c31ab5a0
AM
10276 if (off < filedata->ngnuchains
10277 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 10278 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
10279 }
10280 else
10281 {
10282 if (si >= num_of_syms)
10283 num_of_syms = si + 1;
10284 }
10285 si++;
10286 }
978c4450
AM
10287 while (off < filedata->ngnuchains
10288 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
10289 }
10290
90837ea7 10291 if (num_of_syms == 0)
10ca4b04 10292 {
90837ea7 10293 no_gnu_hash:
9db70fc3
AM
10294 free (filedata->mipsxlat);
10295 filedata->mipsxlat = NULL;
10296 free (filedata->gnuchains);
10297 filedata->gnuchains = NULL;
10298 free (filedata->gnubuckets);
10299 filedata->gnubuckets = NULL;
978c4450
AM
10300 filedata->ngnubuckets = 0;
10301 filedata->ngnuchains = 0;
10ca4b04
L
10302 }
10303 }
10304
10305 return num_of_syms;
10306}
10307
b2d38a17
NC
10308/* Parse and display the contents of the dynamic section. */
10309
32ec8896 10310static bfd_boolean
dda8d76d 10311process_dynamic_section (Filedata * filedata)
9ea033b2 10312{
2cf0635d 10313 Elf_Internal_Dyn * entry;
9ea033b2 10314
978c4450 10315 if (filedata->dynamic_size == 0)
9ea033b2
NC
10316 {
10317 if (do_dynamic)
b2d38a17 10318 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2 10319
32ec8896 10320 return TRUE;
9ea033b2
NC
10321 }
10322
10323 if (is_32bit_elf)
10324 {
dda8d76d 10325 if (! get_32bit_dynamic_section (filedata))
32ec8896
NC
10326 return FALSE;
10327 }
10328 else
10329 {
dda8d76d 10330 if (! get_64bit_dynamic_section (filedata))
32ec8896 10331 return FALSE;
9ea033b2 10332 }
9ea033b2 10333
252b5132 10334 /* Find the appropriate symbol table. */
978c4450 10335 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 10336 {
2482f306
AM
10337 unsigned long num_of_syms;
10338
978c4450
AM
10339 for (entry = filedata->dynamic_section;
10340 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10341 ++entry)
10ca4b04 10342 if (entry->d_tag == DT_SYMTAB)
978c4450 10343 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 10344 else if (entry->d_tag == DT_SYMENT)
978c4450 10345 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 10346 else if (entry->d_tag == DT_HASH)
978c4450 10347 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 10348 else if (entry->d_tag == DT_GNU_HASH)
978c4450 10349 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
10350 else if ((filedata->file_header.e_machine == EM_MIPS
10351 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10352 && entry->d_tag == DT_MIPS_XHASH)
10353 {
978c4450
AM
10354 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10355 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 10356 }
252b5132 10357
2482f306
AM
10358 num_of_syms = get_num_dynamic_syms (filedata);
10359
10360 if (num_of_syms != 0
10361 && filedata->dynamic_symbols == NULL
10362 && filedata->dynamic_info[DT_SYMTAB]
978c4450 10363 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
10364 {
10365 Elf_Internal_Phdr *seg;
2482f306 10366 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 10367
2482f306
AM
10368 if (! get_program_headers (filedata))
10369 {
10370 error (_("Cannot interpret virtual addresses "
10371 "without program headers.\n"));
10372 return FALSE;
10373 }
252b5132 10374
2482f306
AM
10375 for (seg = filedata->program_headers;
10376 seg < filedata->program_headers + filedata->file_header.e_phnum;
10377 ++seg)
10378 {
10379 if (seg->p_type != PT_LOAD)
10380 continue;
252b5132 10381
2482f306
AM
10382 if (seg->p_offset + seg->p_filesz > filedata->file_size)
10383 {
10384 /* See PR 21379 for a reproducer. */
10385 error (_("Invalid PT_LOAD entry\n"));
10386 return FALSE;
10387 }
252b5132 10388
2482f306
AM
10389 if (vma >= (seg->p_vaddr & -seg->p_align)
10390 && vma < seg->p_vaddr + seg->p_filesz)
10391 {
10392 /* Since we do not know how big the symbol table is,
10393 we default to reading in up to the end of PT_LOAD
10394 segment and processing that. This is overkill, I
10395 know, but it should work. */
10396 Elf_Internal_Shdr section;
10397 section.sh_offset = (vma - seg->p_vaddr
10398 + seg->p_offset);
10399 section.sh_size = (num_of_syms
10400 * filedata->dynamic_info[DT_SYMENT]);
10401 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
10402
10403 if (do_checks
10404 && filedata->dynamic_symtab_section != NULL
10405 && ((filedata->dynamic_symtab_section->sh_offset
10406 != section.sh_offset)
10407 || (filedata->dynamic_symtab_section->sh_size
10408 != section.sh_size)
10409 || (filedata->dynamic_symtab_section->sh_entsize
10410 != section.sh_entsize)))
10411 warn (_("\
10412the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
10413
2482f306
AM
10414 section.sh_name = filedata->string_table_length;
10415 filedata->dynamic_symbols
10416 = GET_ELF_SYMBOLS (filedata, &section,
10417 &filedata->num_dynamic_syms);
10418 if (filedata->dynamic_symbols == NULL
10419 || filedata->num_dynamic_syms != num_of_syms)
10420 {
10421 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
10422 return FALSE;
10423 }
10424 break;
10425 }
10426 }
10427 }
10428 }
252b5132
RH
10429
10430 /* Similarly find a string table. */
978c4450
AM
10431 if (filedata->dynamic_strings == NULL)
10432 for (entry = filedata->dynamic_section;
10433 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
10434 ++entry)
10435 {
10436 if (entry->d_tag == DT_STRTAB)
978c4450 10437 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 10438
10ca4b04 10439 if (entry->d_tag == DT_STRSZ)
978c4450 10440 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10441
978c4450
AM
10442 if (filedata->dynamic_info[DT_STRTAB]
10443 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
10444 {
10445 unsigned long offset;
978c4450 10446 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
10447
10448 offset = offset_from_vma (filedata,
978c4450 10449 filedata->dynamic_info[DT_STRTAB],
10ca4b04 10450 str_tab_len);
8ac10c5b
L
10451 if (do_checks
10452 && filedata->dynamic_strtab_section
10453 && ((filedata->dynamic_strtab_section->sh_offset
10454 != (file_ptr) offset)
10455 || (filedata->dynamic_strtab_section->sh_size
10456 != str_tab_len)))
10457 warn (_("\
10458the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
10459
978c4450
AM
10460 filedata->dynamic_strings
10461 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
10462 _("dynamic string table"));
10463 if (filedata->dynamic_strings == NULL)
10ca4b04
L
10464 {
10465 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10466 break;
10467 }
e3d39609 10468
978c4450 10469 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
10470 break;
10471 }
10472 }
252b5132
RH
10473
10474 /* And find the syminfo section if available. */
978c4450 10475 if (filedata->dynamic_syminfo == NULL)
252b5132 10476 {
3e8bba36 10477 unsigned long syminsz = 0;
252b5132 10478
978c4450
AM
10479 for (entry = filedata->dynamic_section;
10480 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10481 ++entry)
252b5132
RH
10482 {
10483 if (entry->d_tag == DT_SYMINENT)
10484 {
10485 /* Note: these braces are necessary to avoid a syntax
10486 error from the SunOS4 C compiler. */
049b0c3a
NC
10487 /* PR binutils/17531: A corrupt file can trigger this test.
10488 So do not use an assert, instead generate an error message. */
10489 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10490 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10491 (int) entry->d_un.d_val);
252b5132
RH
10492 }
10493 else if (entry->d_tag == DT_SYMINSZ)
10494 syminsz = entry->d_un.d_val;
10495 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
10496 filedata->dynamic_syminfo_offset
10497 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
10498 }
10499
978c4450 10500 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 10501 {
2cf0635d
NC
10502 Elf_External_Syminfo * extsyminfo;
10503 Elf_External_Syminfo * extsym;
10504 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10505
10506 /* There is a syminfo section. Read the data. */
3f5e193b 10507 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
10508 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
10509 1, syminsz, _("symbol information"));
a6e9f9df 10510 if (!extsyminfo)
32ec8896 10511 return FALSE;
252b5132 10512
978c4450 10513 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
10514 {
10515 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 10516 free (filedata->dynamic_syminfo);
e3d39609 10517 }
978c4450
AM
10518 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
10519 if (filedata->dynamic_syminfo == NULL)
252b5132 10520 {
2482f306
AM
10521 error (_("Out of memory allocating %lu bytes "
10522 "for dynamic symbol info\n"),
8b73c356 10523 (unsigned long) syminsz);
32ec8896 10524 return FALSE;
252b5132
RH
10525 }
10526
2482f306
AM
10527 filedata->dynamic_syminfo_nent
10528 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 10529 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
10530 syminfo < (filedata->dynamic_syminfo
10531 + filedata->dynamic_syminfo_nent);
86dba8ee 10532 ++syminfo, ++extsym)
252b5132 10533 {
86dba8ee
AM
10534 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10535 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10536 }
10537
10538 free (extsyminfo);
10539 }
10540 }
10541
978c4450 10542 if (do_dynamic && filedata->dynamic_addr)
d3a49aa8
AM
10543 printf (ngettext ("\nDynamic section at offset 0x%lx "
10544 "contains %lu entry:\n",
10545 "\nDynamic section at offset 0x%lx "
10546 "contains %lu entries:\n",
978c4450
AM
10547 filedata->dynamic_nent),
10548 filedata->dynamic_addr, (unsigned long) filedata->dynamic_nent);
252b5132
RH
10549 if (do_dynamic)
10550 printf (_(" Tag Type Name/Value\n"));
10551
978c4450
AM
10552 for (entry = filedata->dynamic_section;
10553 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10554 entry++)
252b5132
RH
10555 {
10556 if (do_dynamic)
f7a99963 10557 {
2cf0635d 10558 const char * dtype;
e699b9ff 10559
f7a99963
NC
10560 putchar (' ');
10561 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10562 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10563 printf (" (%s)%*s", dtype,
32ec8896 10564 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10565 }
252b5132
RH
10566
10567 switch (entry->d_tag)
10568 {
d1133906
NC
10569 case DT_FLAGS:
10570 if (do_dynamic)
e9e44622 10571 print_dynamic_flags (entry->d_un.d_val);
d1133906 10572 break;
76da6bbe 10573
252b5132
RH
10574 case DT_AUXILIARY:
10575 case DT_FILTER:
019148e4
L
10576 case DT_CONFIG:
10577 case DT_DEPAUDIT:
10578 case DT_AUDIT:
252b5132
RH
10579 if (do_dynamic)
10580 {
019148e4 10581 switch (entry->d_tag)
b34976b6 10582 {
019148e4
L
10583 case DT_AUXILIARY:
10584 printf (_("Auxiliary library"));
10585 break;
10586
10587 case DT_FILTER:
10588 printf (_("Filter library"));
10589 break;
10590
b34976b6 10591 case DT_CONFIG:
019148e4
L
10592 printf (_("Configuration file"));
10593 break;
10594
10595 case DT_DEPAUDIT:
10596 printf (_("Dependency audit library"));
10597 break;
10598
10599 case DT_AUDIT:
10600 printf (_("Audit library"));
10601 break;
10602 }
252b5132 10603
978c4450
AM
10604 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10605 printf (": [%s]\n",
10606 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 10607 else
f7a99963
NC
10608 {
10609 printf (": ");
10610 print_vma (entry->d_un.d_val, PREFIX_HEX);
10611 putchar ('\n');
10612 }
252b5132
RH
10613 }
10614 break;
10615
dcefbbbd 10616 case DT_FEATURE:
252b5132
RH
10617 if (do_dynamic)
10618 {
10619 printf (_("Flags:"));
86f55779 10620
252b5132
RH
10621 if (entry->d_un.d_val == 0)
10622 printf (_(" None\n"));
10623 else
10624 {
10625 unsigned long int val = entry->d_un.d_val;
86f55779 10626
252b5132
RH
10627 if (val & DTF_1_PARINIT)
10628 {
10629 printf (" PARINIT");
10630 val ^= DTF_1_PARINIT;
10631 }
dcefbbbd
L
10632 if (val & DTF_1_CONFEXP)
10633 {
10634 printf (" CONFEXP");
10635 val ^= DTF_1_CONFEXP;
10636 }
252b5132
RH
10637 if (val != 0)
10638 printf (" %lx", val);
10639 puts ("");
10640 }
10641 }
10642 break;
10643
10644 case DT_POSFLAG_1:
10645 if (do_dynamic)
10646 {
10647 printf (_("Flags:"));
86f55779 10648
252b5132
RH
10649 if (entry->d_un.d_val == 0)
10650 printf (_(" None\n"));
10651 else
10652 {
10653 unsigned long int val = entry->d_un.d_val;
86f55779 10654
252b5132
RH
10655 if (val & DF_P1_LAZYLOAD)
10656 {
10657 printf (" LAZYLOAD");
10658 val ^= DF_P1_LAZYLOAD;
10659 }
10660 if (val & DF_P1_GROUPPERM)
10661 {
10662 printf (" GROUPPERM");
10663 val ^= DF_P1_GROUPPERM;
10664 }
10665 if (val != 0)
10666 printf (" %lx", val);
10667 puts ("");
10668 }
10669 }
10670 break;
10671
10672 case DT_FLAGS_1:
10673 if (do_dynamic)
10674 {
10675 printf (_("Flags:"));
10676 if (entry->d_un.d_val == 0)
10677 printf (_(" None\n"));
10678 else
10679 {
10680 unsigned long int val = entry->d_un.d_val;
86f55779 10681
252b5132
RH
10682 if (val & DF_1_NOW)
10683 {
10684 printf (" NOW");
10685 val ^= DF_1_NOW;
10686 }
10687 if (val & DF_1_GLOBAL)
10688 {
10689 printf (" GLOBAL");
10690 val ^= DF_1_GLOBAL;
10691 }
10692 if (val & DF_1_GROUP)
10693 {
10694 printf (" GROUP");
10695 val ^= DF_1_GROUP;
10696 }
10697 if (val & DF_1_NODELETE)
10698 {
10699 printf (" NODELETE");
10700 val ^= DF_1_NODELETE;
10701 }
10702 if (val & DF_1_LOADFLTR)
10703 {
10704 printf (" LOADFLTR");
10705 val ^= DF_1_LOADFLTR;
10706 }
10707 if (val & DF_1_INITFIRST)
10708 {
10709 printf (" INITFIRST");
10710 val ^= DF_1_INITFIRST;
10711 }
10712 if (val & DF_1_NOOPEN)
10713 {
10714 printf (" NOOPEN");
10715 val ^= DF_1_NOOPEN;
10716 }
10717 if (val & DF_1_ORIGIN)
10718 {
10719 printf (" ORIGIN");
10720 val ^= DF_1_ORIGIN;
10721 }
10722 if (val & DF_1_DIRECT)
10723 {
10724 printf (" DIRECT");
10725 val ^= DF_1_DIRECT;
10726 }
10727 if (val & DF_1_TRANS)
10728 {
10729 printf (" TRANS");
10730 val ^= DF_1_TRANS;
10731 }
10732 if (val & DF_1_INTERPOSE)
10733 {
10734 printf (" INTERPOSE");
10735 val ^= DF_1_INTERPOSE;
10736 }
f7db6139 10737 if (val & DF_1_NODEFLIB)
dcefbbbd 10738 {
f7db6139
L
10739 printf (" NODEFLIB");
10740 val ^= DF_1_NODEFLIB;
dcefbbbd
L
10741 }
10742 if (val & DF_1_NODUMP)
10743 {
10744 printf (" NODUMP");
10745 val ^= DF_1_NODUMP;
10746 }
34b60028 10747 if (val & DF_1_CONFALT)
dcefbbbd 10748 {
34b60028
L
10749 printf (" CONFALT");
10750 val ^= DF_1_CONFALT;
10751 }
10752 if (val & DF_1_ENDFILTEE)
10753 {
10754 printf (" ENDFILTEE");
10755 val ^= DF_1_ENDFILTEE;
10756 }
10757 if (val & DF_1_DISPRELDNE)
10758 {
10759 printf (" DISPRELDNE");
10760 val ^= DF_1_DISPRELDNE;
10761 }
10762 if (val & DF_1_DISPRELPND)
10763 {
10764 printf (" DISPRELPND");
10765 val ^= DF_1_DISPRELPND;
10766 }
10767 if (val & DF_1_NODIRECT)
10768 {
10769 printf (" NODIRECT");
10770 val ^= DF_1_NODIRECT;
10771 }
10772 if (val & DF_1_IGNMULDEF)
10773 {
10774 printf (" IGNMULDEF");
10775 val ^= DF_1_IGNMULDEF;
10776 }
10777 if (val & DF_1_NOKSYMS)
10778 {
10779 printf (" NOKSYMS");
10780 val ^= DF_1_NOKSYMS;
10781 }
10782 if (val & DF_1_NOHDR)
10783 {
10784 printf (" NOHDR");
10785 val ^= DF_1_NOHDR;
10786 }
10787 if (val & DF_1_EDITED)
10788 {
10789 printf (" EDITED");
10790 val ^= DF_1_EDITED;
10791 }
10792 if (val & DF_1_NORELOC)
10793 {
10794 printf (" NORELOC");
10795 val ^= DF_1_NORELOC;
10796 }
10797 if (val & DF_1_SYMINTPOSE)
10798 {
10799 printf (" SYMINTPOSE");
10800 val ^= DF_1_SYMINTPOSE;
10801 }
10802 if (val & DF_1_GLOBAUDIT)
10803 {
10804 printf (" GLOBAUDIT");
10805 val ^= DF_1_GLOBAUDIT;
10806 }
10807 if (val & DF_1_SINGLETON)
10808 {
10809 printf (" SINGLETON");
10810 val ^= DF_1_SINGLETON;
dcefbbbd 10811 }
5c383f02
RO
10812 if (val & DF_1_STUB)
10813 {
10814 printf (" STUB");
10815 val ^= DF_1_STUB;
10816 }
10817 if (val & DF_1_PIE)
10818 {
10819 printf (" PIE");
10820 val ^= DF_1_PIE;
10821 }
b1202ffa
L
10822 if (val & DF_1_KMOD)
10823 {
10824 printf (" KMOD");
10825 val ^= DF_1_KMOD;
10826 }
10827 if (val & DF_1_WEAKFILTER)
10828 {
10829 printf (" WEAKFILTER");
10830 val ^= DF_1_WEAKFILTER;
10831 }
10832 if (val & DF_1_NOCOMMON)
10833 {
10834 printf (" NOCOMMON");
10835 val ^= DF_1_NOCOMMON;
10836 }
252b5132
RH
10837 if (val != 0)
10838 printf (" %lx", val);
10839 puts ("");
10840 }
10841 }
10842 break;
10843
10844 case DT_PLTREL:
978c4450 10845 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 10846 if (do_dynamic)
dda8d76d 10847 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
10848 break;
10849
10850 case DT_NULL :
10851 case DT_NEEDED :
10852 case DT_PLTGOT :
10853 case DT_HASH :
10854 case DT_STRTAB :
10855 case DT_SYMTAB :
10856 case DT_RELA :
10857 case DT_INIT :
10858 case DT_FINI :
10859 case DT_SONAME :
10860 case DT_RPATH :
10861 case DT_SYMBOLIC:
10862 case DT_REL :
10863 case DT_DEBUG :
10864 case DT_TEXTREL :
10865 case DT_JMPREL :
019148e4 10866 case DT_RUNPATH :
978c4450 10867 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
10868
10869 if (do_dynamic)
10870 {
2cf0635d 10871 char * name;
252b5132 10872
978c4450
AM
10873 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10874 name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 10875 else
d79b3d50 10876 name = NULL;
252b5132
RH
10877
10878 if (name)
10879 {
10880 switch (entry->d_tag)
10881 {
10882 case DT_NEEDED:
10883 printf (_("Shared library: [%s]"), name);
10884
978c4450 10885 if (streq (name, filedata->program_interpreter))
f7a99963 10886 printf (_(" program interpreter"));
252b5132
RH
10887 break;
10888
10889 case DT_SONAME:
f7a99963 10890 printf (_("Library soname: [%s]"), name);
252b5132
RH
10891 break;
10892
10893 case DT_RPATH:
f7a99963 10894 printf (_("Library rpath: [%s]"), name);
252b5132
RH
10895 break;
10896
019148e4
L
10897 case DT_RUNPATH:
10898 printf (_("Library runpath: [%s]"), name);
10899 break;
10900
252b5132 10901 default:
f7a99963
NC
10902 print_vma (entry->d_un.d_val, PREFIX_HEX);
10903 break;
252b5132
RH
10904 }
10905 }
10906 else
f7a99963
NC
10907 print_vma (entry->d_un.d_val, PREFIX_HEX);
10908
10909 putchar ('\n');
252b5132
RH
10910 }
10911 break;
10912
10913 case DT_PLTRELSZ:
10914 case DT_RELASZ :
10915 case DT_STRSZ :
10916 case DT_RELSZ :
10917 case DT_RELAENT :
10918 case DT_SYMENT :
10919 case DT_RELENT :
978c4450 10920 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 10921 /* Fall through. */
252b5132
RH
10922 case DT_PLTPADSZ:
10923 case DT_MOVEENT :
10924 case DT_MOVESZ :
10925 case DT_INIT_ARRAYSZ:
10926 case DT_FINI_ARRAYSZ:
047b2264
JJ
10927 case DT_GNU_CONFLICTSZ:
10928 case DT_GNU_LIBLISTSZ:
252b5132 10929 if (do_dynamic)
f7a99963
NC
10930 {
10931 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 10932 printf (_(" (bytes)\n"));
f7a99963 10933 }
252b5132
RH
10934 break;
10935
10936 case DT_VERDEFNUM:
10937 case DT_VERNEEDNUM:
10938 case DT_RELACOUNT:
10939 case DT_RELCOUNT:
10940 if (do_dynamic)
f7a99963
NC
10941 {
10942 print_vma (entry->d_un.d_val, UNSIGNED);
10943 putchar ('\n');
10944 }
252b5132
RH
10945 break;
10946
10947 case DT_SYMINSZ:
10948 case DT_SYMINENT:
10949 case DT_SYMINFO:
10950 case DT_USED:
10951 case DT_INIT_ARRAY:
10952 case DT_FINI_ARRAY:
10953 if (do_dynamic)
10954 {
d79b3d50 10955 if (entry->d_tag == DT_USED
978c4450 10956 && VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
252b5132 10957 {
978c4450 10958 char * name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 10959
b34976b6 10960 if (*name)
252b5132
RH
10961 {
10962 printf (_("Not needed object: [%s]\n"), name);
10963 break;
10964 }
10965 }
103f02d3 10966
f7a99963
NC
10967 print_vma (entry->d_un.d_val, PREFIX_HEX);
10968 putchar ('\n');
252b5132
RH
10969 }
10970 break;
10971
10972 case DT_BIND_NOW:
10973 /* The value of this entry is ignored. */
35b1837e
AM
10974 if (do_dynamic)
10975 putchar ('\n');
252b5132 10976 break;
103f02d3 10977
047b2264
JJ
10978 case DT_GNU_PRELINKED:
10979 if (do_dynamic)
10980 {
2cf0635d 10981 struct tm * tmp;
91d6fa6a 10982 time_t atime = entry->d_un.d_val;
047b2264 10983
91d6fa6a 10984 tmp = gmtime (&atime);
071436c6
NC
10985 /* PR 17533 file: 041-1244816-0.004. */
10986 if (tmp == NULL)
5a2cbcf4
L
10987 printf (_("<corrupt time val: %lx"),
10988 (unsigned long) atime);
071436c6
NC
10989 else
10990 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
10991 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10992 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
10993
10994 }
10995 break;
10996
fdc90cb4 10997 case DT_GNU_HASH:
978c4450 10998 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
10999 if (do_dynamic)
11000 {
11001 print_vma (entry->d_un.d_val, PREFIX_HEX);
11002 putchar ('\n');
11003 }
11004 break;
11005
252b5132
RH
11006 default:
11007 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11008 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11009 = entry->d_un.d_val;
252b5132
RH
11010
11011 if (do_dynamic)
11012 {
dda8d76d 11013 switch (filedata->file_header.e_machine)
252b5132 11014 {
37c18eed
SD
11015 case EM_AARCH64:
11016 dynamic_section_aarch64_val (entry);
11017 break;
252b5132 11018 case EM_MIPS:
4fe85591 11019 case EM_MIPS_RS3_LE:
978c4450 11020 dynamic_section_mips_val (filedata, entry);
252b5132 11021 break;
103f02d3 11022 case EM_PARISC:
b2d38a17 11023 dynamic_section_parisc_val (entry);
103f02d3 11024 break;
ecc51f48 11025 case EM_IA_64:
b2d38a17 11026 dynamic_section_ia64_val (entry);
ecc51f48 11027 break;
252b5132 11028 default:
f7a99963
NC
11029 print_vma (entry->d_un.d_val, PREFIX_HEX);
11030 putchar ('\n');
252b5132
RH
11031 }
11032 }
11033 break;
11034 }
11035 }
11036
32ec8896 11037 return TRUE;
252b5132
RH
11038}
11039
11040static char *
d3ba0551 11041get_ver_flags (unsigned int flags)
252b5132 11042{
6d4f21f6 11043 static char buff[128];
252b5132
RH
11044
11045 buff[0] = 0;
11046
11047 if (flags == 0)
11048 return _("none");
11049
11050 if (flags & VER_FLG_BASE)
7bb1ad17 11051 strcat (buff, "BASE");
252b5132
RH
11052
11053 if (flags & VER_FLG_WEAK)
11054 {
11055 if (flags & VER_FLG_BASE)
7bb1ad17 11056 strcat (buff, " | ");
252b5132 11057
7bb1ad17 11058 strcat (buff, "WEAK");
252b5132
RH
11059 }
11060
44ec90b9
RO
11061 if (flags & VER_FLG_INFO)
11062 {
11063 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11064 strcat (buff, " | ");
44ec90b9 11065
7bb1ad17 11066 strcat (buff, "INFO");
44ec90b9
RO
11067 }
11068
11069 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11070 {
11071 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11072 strcat (buff, " | ");
11073
11074 strcat (buff, _("<unknown>"));
11075 }
252b5132
RH
11076
11077 return buff;
11078}
11079
11080/* Display the contents of the version sections. */
98fb390a 11081
32ec8896 11082static bfd_boolean
dda8d76d 11083process_version_sections (Filedata * filedata)
252b5132 11084{
2cf0635d 11085 Elf_Internal_Shdr * section;
b34976b6 11086 unsigned i;
32ec8896 11087 bfd_boolean found = FALSE;
252b5132
RH
11088
11089 if (! do_version)
32ec8896 11090 return TRUE;
252b5132 11091
dda8d76d
NC
11092 for (i = 0, section = filedata->section_headers;
11093 i < filedata->file_header.e_shnum;
b34976b6 11094 i++, section++)
252b5132
RH
11095 {
11096 switch (section->sh_type)
11097 {
11098 case SHT_GNU_verdef:
11099 {
2cf0635d 11100 Elf_External_Verdef * edefs;
452bf675
AM
11101 unsigned long idx;
11102 unsigned long cnt;
2cf0635d 11103 char * endbuf;
252b5132 11104
32ec8896 11105 found = TRUE;
252b5132 11106
d3a49aa8
AM
11107 printf (ngettext ("\nVersion definition section '%s' "
11108 "contains %u entry:\n",
11109 "\nVersion definition section '%s' "
11110 "contains %u entries:\n",
11111 section->sh_info),
dda8d76d 11112 printable_section_name (filedata, section),
74e1a04b 11113 section->sh_info);
252b5132 11114
ae9ac79e 11115 printf (_(" Addr: 0x"));
252b5132 11116 printf_vma (section->sh_addr);
233f82cf 11117 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11118 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11119 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11120
3f5e193b 11121 edefs = (Elf_External_Verdef *)
dda8d76d 11122 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11123 _("version definition section"));
a6e9f9df
AM
11124 if (!edefs)
11125 break;
59245841 11126 endbuf = (char *) edefs + section->sh_size;
252b5132 11127
1445030f 11128 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11129 {
2cf0635d
NC
11130 char * vstart;
11131 Elf_External_Verdef * edef;
b34976b6 11132 Elf_Internal_Verdef ent;
2cf0635d 11133 Elf_External_Verdaux * eaux;
b34976b6 11134 Elf_Internal_Verdaux aux;
452bf675 11135 unsigned long isum;
b34976b6 11136 int j;
103f02d3 11137
252b5132 11138 vstart = ((char *) edefs) + idx;
54806181
AM
11139 if (vstart + sizeof (*edef) > endbuf)
11140 break;
252b5132
RH
11141
11142 edef = (Elf_External_Verdef *) vstart;
11143
11144 ent.vd_version = BYTE_GET (edef->vd_version);
11145 ent.vd_flags = BYTE_GET (edef->vd_flags);
11146 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11147 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11148 ent.vd_hash = BYTE_GET (edef->vd_hash);
11149 ent.vd_aux = BYTE_GET (edef->vd_aux);
11150 ent.vd_next = BYTE_GET (edef->vd_next);
11151
452bf675 11152 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11153 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11154
11155 printf (_(" Index: %d Cnt: %d "),
11156 ent.vd_ndx, ent.vd_cnt);
11157
452bf675 11158 /* Check for overflow. */
1445030f 11159 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11160 break;
11161
252b5132
RH
11162 vstart += ent.vd_aux;
11163
1445030f
AM
11164 if (vstart + sizeof (*eaux) > endbuf)
11165 break;
252b5132
RH
11166 eaux = (Elf_External_Verdaux *) vstart;
11167
11168 aux.vda_name = BYTE_GET (eaux->vda_name);
11169 aux.vda_next = BYTE_GET (eaux->vda_next);
11170
978c4450
AM
11171 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
11172 printf (_("Name: %s\n"),
11173 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132
RH
11174 else
11175 printf (_("Name index: %ld\n"), aux.vda_name);
11176
11177 isum = idx + ent.vd_aux;
11178
b34976b6 11179 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11180 {
1445030f
AM
11181 if (aux.vda_next < sizeof (*eaux)
11182 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11183 {
11184 warn (_("Invalid vda_next field of %lx\n"),
11185 aux.vda_next);
11186 j = ent.vd_cnt;
11187 break;
11188 }
dd24e3da 11189 /* Check for overflow. */
7e26601c 11190 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11191 break;
11192
252b5132
RH
11193 isum += aux.vda_next;
11194 vstart += aux.vda_next;
11195
54806181
AM
11196 if (vstart + sizeof (*eaux) > endbuf)
11197 break;
1445030f 11198 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11199
11200 aux.vda_name = BYTE_GET (eaux->vda_name);
11201 aux.vda_next = BYTE_GET (eaux->vda_next);
11202
978c4450 11203 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
452bf675 11204 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450
AM
11205 isum, j,
11206 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132 11207 else
452bf675 11208 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11209 isum, j, aux.vda_name);
11210 }
dd24e3da 11211
54806181
AM
11212 if (j < ent.vd_cnt)
11213 printf (_(" Version def aux past end of section\n"));
252b5132 11214
c9f02c3e
MR
11215 /* PR 17531:
11216 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11217 if (ent.vd_next < sizeof (*edef)
11218 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11219 {
11220 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11221 cnt = section->sh_info;
11222 break;
11223 }
452bf675 11224 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11225 break;
11226
252b5132
RH
11227 idx += ent.vd_next;
11228 }
dd24e3da 11229
54806181
AM
11230 if (cnt < section->sh_info)
11231 printf (_(" Version definition past end of section\n"));
252b5132
RH
11232
11233 free (edefs);
11234 }
11235 break;
103f02d3 11236
252b5132
RH
11237 case SHT_GNU_verneed:
11238 {
2cf0635d 11239 Elf_External_Verneed * eneed;
452bf675
AM
11240 unsigned long idx;
11241 unsigned long cnt;
2cf0635d 11242 char * endbuf;
252b5132 11243
32ec8896 11244 found = TRUE;
252b5132 11245
d3a49aa8
AM
11246 printf (ngettext ("\nVersion needs section '%s' "
11247 "contains %u entry:\n",
11248 "\nVersion needs section '%s' "
11249 "contains %u entries:\n",
11250 section->sh_info),
dda8d76d 11251 printable_section_name (filedata, section), section->sh_info);
252b5132
RH
11252
11253 printf (_(" Addr: 0x"));
11254 printf_vma (section->sh_addr);
72de5009 11255 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11256 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11257 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11258
dda8d76d 11259 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11260 section->sh_offset, 1,
11261 section->sh_size,
9cf03b7e 11262 _("Version Needs section"));
a6e9f9df
AM
11263 if (!eneed)
11264 break;
59245841 11265 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11266
11267 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11268 {
2cf0635d 11269 Elf_External_Verneed * entry;
b34976b6 11270 Elf_Internal_Verneed ent;
452bf675 11271 unsigned long isum;
b34976b6 11272 int j;
2cf0635d 11273 char * vstart;
252b5132
RH
11274
11275 vstart = ((char *) eneed) + idx;
54806181
AM
11276 if (vstart + sizeof (*entry) > endbuf)
11277 break;
252b5132
RH
11278
11279 entry = (Elf_External_Verneed *) vstart;
11280
11281 ent.vn_version = BYTE_GET (entry->vn_version);
11282 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11283 ent.vn_file = BYTE_GET (entry->vn_file);
11284 ent.vn_aux = BYTE_GET (entry->vn_aux);
11285 ent.vn_next = BYTE_GET (entry->vn_next);
11286
452bf675 11287 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11288
978c4450
AM
11289 if (VALID_DYNAMIC_NAME (filedata, ent.vn_file))
11290 printf (_(" File: %s"),
11291 GET_DYNAMIC_NAME (filedata, ent.vn_file));
252b5132
RH
11292 else
11293 printf (_(" File: %lx"), ent.vn_file);
11294
11295 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11296
dd24e3da 11297 /* Check for overflow. */
7e26601c 11298 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11299 break;
252b5132
RH
11300 vstart += ent.vn_aux;
11301
11302 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11303 {
2cf0635d 11304 Elf_External_Vernaux * eaux;
b34976b6 11305 Elf_Internal_Vernaux aux;
252b5132 11306
54806181
AM
11307 if (vstart + sizeof (*eaux) > endbuf)
11308 break;
252b5132
RH
11309 eaux = (Elf_External_Vernaux *) vstart;
11310
11311 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11312 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11313 aux.vna_other = BYTE_GET (eaux->vna_other);
11314 aux.vna_name = BYTE_GET (eaux->vna_name);
11315 aux.vna_next = BYTE_GET (eaux->vna_next);
11316
978c4450 11317 if (VALID_DYNAMIC_NAME (filedata, aux.vna_name))
452bf675 11318 printf (_(" %#06lx: Name: %s"),
978c4450 11319 isum, GET_DYNAMIC_NAME (filedata, aux.vna_name));
252b5132 11320 else
452bf675 11321 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11322 isum, aux.vna_name);
11323
11324 printf (_(" Flags: %s Version: %d\n"),
11325 get_ver_flags (aux.vna_flags), aux.vna_other);
11326
1445030f
AM
11327 if (aux.vna_next < sizeof (*eaux)
11328 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11329 {
11330 warn (_("Invalid vna_next field of %lx\n"),
11331 aux.vna_next);
11332 j = ent.vn_cnt;
11333 break;
11334 }
1445030f
AM
11335 /* Check for overflow. */
11336 if (aux.vna_next > (size_t) (endbuf - vstart))
11337 break;
252b5132
RH
11338 isum += aux.vna_next;
11339 vstart += aux.vna_next;
11340 }
9cf03b7e 11341
54806181 11342 if (j < ent.vn_cnt)
9cf03b7e 11343 warn (_("Missing Version Needs auxillary information\n"));
252b5132 11344
1445030f
AM
11345 if (ent.vn_next < sizeof (*entry)
11346 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11347 {
452bf675 11348 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11349 cnt = section->sh_info;
11350 break;
11351 }
1445030f
AM
11352 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11353 break;
252b5132
RH
11354 idx += ent.vn_next;
11355 }
9cf03b7e 11356
54806181 11357 if (cnt < section->sh_info)
9cf03b7e 11358 warn (_("Missing Version Needs information\n"));
103f02d3 11359
252b5132
RH
11360 free (eneed);
11361 }
11362 break;
11363
11364 case SHT_GNU_versym:
11365 {
2cf0635d 11366 Elf_Internal_Shdr * link_section;
8b73c356
NC
11367 size_t total;
11368 unsigned int cnt;
2cf0635d
NC
11369 unsigned char * edata;
11370 unsigned short * data;
11371 char * strtab;
11372 Elf_Internal_Sym * symbols;
11373 Elf_Internal_Shdr * string_sec;
ba5cdace 11374 unsigned long num_syms;
d3ba0551 11375 long off;
252b5132 11376
dda8d76d 11377 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11378 break;
11379
dda8d76d 11380 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11381 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11382
dda8d76d 11383 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11384 break;
11385
32ec8896 11386 found = TRUE;
252b5132 11387
dda8d76d 11388 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
11389 if (symbols == NULL)
11390 break;
252b5132 11391
dda8d76d 11392 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11393
dda8d76d 11394 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11395 string_sec->sh_size,
11396 _("version string table"));
a6e9f9df 11397 if (!strtab)
0429c154
MS
11398 {
11399 free (symbols);
11400 break;
11401 }
252b5132 11402
d3a49aa8
AM
11403 printf (ngettext ("\nVersion symbols section '%s' "
11404 "contains %lu entry:\n",
11405 "\nVersion symbols section '%s' "
11406 "contains %lu entries:\n",
11407 total),
dda8d76d 11408 printable_section_name (filedata, section), (unsigned long) total);
252b5132 11409
ae9ac79e 11410 printf (_(" Addr: 0x"));
252b5132 11411 printf_vma (section->sh_addr);
72de5009 11412 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11413 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11414 printable_section_name (filedata, link_section));
252b5132 11415
dda8d76d 11416 off = offset_from_vma (filedata,
978c4450 11417 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11418 total * sizeof (short));
95099889
AM
11419 edata = (unsigned char *) get_data (NULL, filedata, off,
11420 sizeof (short), total,
11421 _("version symbol data"));
a6e9f9df
AM
11422 if (!edata)
11423 {
11424 free (strtab);
0429c154 11425 free (symbols);
a6e9f9df
AM
11426 break;
11427 }
252b5132 11428
3f5e193b 11429 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11430
11431 for (cnt = total; cnt --;)
b34976b6
AM
11432 data[cnt] = byte_get (edata + cnt * sizeof (short),
11433 sizeof (short));
252b5132
RH
11434
11435 free (edata);
11436
11437 for (cnt = 0; cnt < total; cnt += 4)
11438 {
11439 int j, nn;
ab273396
AM
11440 char *name;
11441 char *invalid = _("*invalid*");
252b5132
RH
11442
11443 printf (" %03x:", cnt);
11444
11445 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11446 switch (data[cnt + j])
252b5132
RH
11447 {
11448 case 0:
11449 fputs (_(" 0 (*local*) "), stdout);
11450 break;
11451
11452 case 1:
11453 fputs (_(" 1 (*global*) "), stdout);
11454 break;
11455
11456 default:
c244d050
NC
11457 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11458 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11459
dd24e3da 11460 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11461 array, break to avoid an out-of-bounds read. */
11462 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11463 {
11464 warn (_("invalid index into symbol array\n"));
11465 break;
11466 }
11467
ab273396 11468 name = NULL;
978c4450 11469 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11470 {
b34976b6
AM
11471 Elf_Internal_Verneed ivn;
11472 unsigned long offset;
252b5132 11473
d93f0186 11474 offset = offset_from_vma
978c4450
AM
11475 (filedata,
11476 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11477 sizeof (Elf_External_Verneed));
252b5132 11478
b34976b6 11479 do
252b5132 11480 {
b34976b6
AM
11481 Elf_Internal_Vernaux ivna;
11482 Elf_External_Verneed evn;
11483 Elf_External_Vernaux evna;
11484 unsigned long a_off;
252b5132 11485
dda8d76d 11486 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11487 _("version need")) == NULL)
11488 break;
0b4362b0 11489
252b5132
RH
11490 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11491 ivn.vn_next = BYTE_GET (evn.vn_next);
11492
11493 a_off = offset + ivn.vn_aux;
11494
11495 do
11496 {
dda8d76d 11497 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11498 1, _("version need aux (2)")) == NULL)
11499 {
11500 ivna.vna_next = 0;
11501 ivna.vna_other = 0;
11502 }
11503 else
11504 {
11505 ivna.vna_next = BYTE_GET (evna.vna_next);
11506 ivna.vna_other = BYTE_GET (evna.vna_other);
11507 }
252b5132
RH
11508
11509 a_off += ivna.vna_next;
11510 }
b34976b6 11511 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11512 && ivna.vna_next != 0);
11513
b34976b6 11514 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11515 {
11516 ivna.vna_name = BYTE_GET (evna.vna_name);
11517
54806181 11518 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11519 name = invalid;
54806181
AM
11520 else
11521 name = strtab + ivna.vna_name;
252b5132
RH
11522 break;
11523 }
11524
11525 offset += ivn.vn_next;
11526 }
11527 while (ivn.vn_next);
11528 }
00d93f34 11529
ab273396 11530 if (data[cnt + j] != 0x8001
978c4450 11531 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 11532 {
b34976b6
AM
11533 Elf_Internal_Verdef ivd;
11534 Elf_External_Verdef evd;
11535 unsigned long offset;
252b5132 11536
d93f0186 11537 offset = offset_from_vma
978c4450
AM
11538 (filedata,
11539 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 11540 sizeof evd);
252b5132
RH
11541
11542 do
11543 {
dda8d76d 11544 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
11545 _("version def")) == NULL)
11546 {
11547 ivd.vd_next = 0;
948f632f 11548 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
11549 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
11550 break;
59245841
NC
11551 }
11552 else
11553 {
11554 ivd.vd_next = BYTE_GET (evd.vd_next);
11555 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11556 }
252b5132
RH
11557
11558 offset += ivd.vd_next;
11559 }
c244d050 11560 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
11561 && ivd.vd_next != 0);
11562
c244d050 11563 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 11564 {
b34976b6
AM
11565 Elf_External_Verdaux evda;
11566 Elf_Internal_Verdaux ivda;
252b5132
RH
11567
11568 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11569
dda8d76d 11570 if (get_data (&evda, filedata,
59245841
NC
11571 offset - ivd.vd_next + ivd.vd_aux,
11572 sizeof (evda), 1,
11573 _("version def aux")) == NULL)
11574 break;
252b5132
RH
11575
11576 ivda.vda_name = BYTE_GET (evda.vda_name);
11577
54806181 11578 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
11579 name = invalid;
11580 else if (name != NULL && name != invalid)
11581 name = _("*both*");
54806181
AM
11582 else
11583 name = strtab + ivda.vda_name;
252b5132
RH
11584 }
11585 }
ab273396
AM
11586 if (name != NULL)
11587 nn += printf ("(%s%-*s",
11588 name,
11589 12 - (int) strlen (name),
11590 ")");
252b5132
RH
11591
11592 if (nn < 18)
11593 printf ("%*c", 18 - nn, ' ');
11594 }
11595
11596 putchar ('\n');
11597 }
11598
11599 free (data);
11600 free (strtab);
11601 free (symbols);
11602 }
11603 break;
103f02d3 11604
252b5132
RH
11605 default:
11606 break;
11607 }
11608 }
11609
11610 if (! found)
11611 printf (_("\nNo version information found in this file.\n"));
11612
32ec8896 11613 return TRUE;
252b5132
RH
11614}
11615
d1133906 11616static const char *
dda8d76d 11617get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 11618{
89246a0e 11619 static char buff[64];
252b5132
RH
11620
11621 switch (binding)
11622 {
b34976b6
AM
11623 case STB_LOCAL: return "LOCAL";
11624 case STB_GLOBAL: return "GLOBAL";
11625 case STB_WEAK: return "WEAK";
252b5132
RH
11626 default:
11627 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
11628 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
11629 binding);
252b5132 11630 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
11631 {
11632 if (binding == STB_GNU_UNIQUE
df3a023b 11633 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
11634 return "UNIQUE";
11635 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
11636 }
252b5132 11637 else
e9e44622 11638 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
11639 return buff;
11640 }
11641}
11642
d1133906 11643static const char *
dda8d76d 11644get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 11645{
89246a0e 11646 static char buff[64];
252b5132
RH
11647
11648 switch (type)
11649 {
b34976b6
AM
11650 case STT_NOTYPE: return "NOTYPE";
11651 case STT_OBJECT: return "OBJECT";
11652 case STT_FUNC: return "FUNC";
11653 case STT_SECTION: return "SECTION";
11654 case STT_FILE: return "FILE";
11655 case STT_COMMON: return "COMMON";
11656 case STT_TLS: return "TLS";
15ab5209
DB
11657 case STT_RELC: return "RELC";
11658 case STT_SRELC: return "SRELC";
252b5132
RH
11659 default:
11660 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 11661 {
dda8d76d 11662 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 11663 return "THUMB_FUNC";
103f02d3 11664
dda8d76d 11665 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
11666 return "REGISTER";
11667
dda8d76d 11668 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
11669 return "PARISC_MILLI";
11670
e9e44622 11671 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 11672 }
252b5132 11673 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 11674 {
dda8d76d 11675 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
11676 {
11677 if (type == STT_HP_OPAQUE)
11678 return "HP_OPAQUE";
11679 if (type == STT_HP_STUB)
11680 return "HP_STUB";
11681 }
11682
d8045f23 11683 if (type == STT_GNU_IFUNC
dda8d76d 11684 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 11685 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
11686 return "IFUNC";
11687
e9e44622 11688 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 11689 }
252b5132 11690 else
e9e44622 11691 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
11692 return buff;
11693 }
11694}
11695
d1133906 11696static const char *
d3ba0551 11697get_symbol_visibility (unsigned int visibility)
d1133906
NC
11698{
11699 switch (visibility)
11700 {
b34976b6
AM
11701 case STV_DEFAULT: return "DEFAULT";
11702 case STV_INTERNAL: return "INTERNAL";
11703 case STV_HIDDEN: return "HIDDEN";
d1133906 11704 case STV_PROTECTED: return "PROTECTED";
bee0ee85 11705 default:
27a45f42 11706 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 11707 return _("<unknown>");
d1133906
NC
11708 }
11709}
11710
2057d69d
CZ
11711static const char *
11712get_alpha_symbol_other (unsigned int other)
9abca702 11713{
2057d69d
CZ
11714 switch (other)
11715 {
11716 case STO_ALPHA_NOPV: return "NOPV";
11717 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
11718 default:
27a45f42 11719 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 11720 return _("<unknown>");
9abca702 11721 }
2057d69d
CZ
11722}
11723
fd85a6a1
NC
11724static const char *
11725get_solaris_symbol_visibility (unsigned int visibility)
11726{
11727 switch (visibility)
11728 {
11729 case 4: return "EXPORTED";
11730 case 5: return "SINGLETON";
11731 case 6: return "ELIMINATE";
11732 default: return get_symbol_visibility (visibility);
11733 }
11734}
11735
2301ed1c
SN
11736static const char *
11737get_aarch64_symbol_other (unsigned int other)
11738{
11739 static char buf[32];
11740
11741 if (other & STO_AARCH64_VARIANT_PCS)
11742 {
11743 other &= ~STO_AARCH64_VARIANT_PCS;
11744 if (other == 0)
11745 return "VARIANT_PCS";
11746 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
11747 return buf;
11748 }
11749 return NULL;
11750}
11751
5e2b0d47
NC
11752static const char *
11753get_mips_symbol_other (unsigned int other)
11754{
11755 switch (other)
11756 {
32ec8896
NC
11757 case STO_OPTIONAL: return "OPTIONAL";
11758 case STO_MIPS_PLT: return "MIPS PLT";
11759 case STO_MIPS_PIC: return "MIPS PIC";
11760 case STO_MICROMIPS: return "MICROMIPS";
11761 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
11762 case STO_MIPS16: return "MIPS16";
11763 default: return NULL;
5e2b0d47
NC
11764 }
11765}
11766
28f997cf 11767static const char *
dda8d76d 11768get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 11769{
dda8d76d 11770 if (is_ia64_vms (filedata))
28f997cf
TG
11771 {
11772 static char res[32];
11773
11774 res[0] = 0;
11775
11776 /* Function types is for images and .STB files only. */
dda8d76d 11777 switch (filedata->file_header.e_type)
28f997cf
TG
11778 {
11779 case ET_DYN:
11780 case ET_EXEC:
11781 switch (VMS_ST_FUNC_TYPE (other))
11782 {
11783 case VMS_SFT_CODE_ADDR:
11784 strcat (res, " CA");
11785 break;
11786 case VMS_SFT_SYMV_IDX:
11787 strcat (res, " VEC");
11788 break;
11789 case VMS_SFT_FD:
11790 strcat (res, " FD");
11791 break;
11792 case VMS_SFT_RESERVE:
11793 strcat (res, " RSV");
11794 break;
11795 default:
bee0ee85
NC
11796 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
11797 VMS_ST_FUNC_TYPE (other));
11798 strcat (res, " <unknown>");
11799 break;
28f997cf
TG
11800 }
11801 break;
11802 default:
11803 break;
11804 }
11805 switch (VMS_ST_LINKAGE (other))
11806 {
11807 case VMS_STL_IGNORE:
11808 strcat (res, " IGN");
11809 break;
11810 case VMS_STL_RESERVE:
11811 strcat (res, " RSV");
11812 break;
11813 case VMS_STL_STD:
11814 strcat (res, " STD");
11815 break;
11816 case VMS_STL_LNK:
11817 strcat (res, " LNK");
11818 break;
11819 default:
bee0ee85
NC
11820 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
11821 VMS_ST_LINKAGE (other));
11822 strcat (res, " <unknown>");
11823 break;
28f997cf
TG
11824 }
11825
11826 if (res[0] != 0)
11827 return res + 1;
11828 else
11829 return res;
11830 }
11831 return NULL;
11832}
11833
6911b7dc
AM
11834static const char *
11835get_ppc64_symbol_other (unsigned int other)
11836{
14732552
AM
11837 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
11838 return NULL;
11839
11840 other >>= STO_PPC64_LOCAL_BIT;
11841 if (other <= 6)
6911b7dc 11842 {
89246a0e 11843 static char buf[64];
14732552
AM
11844 if (other >= 2)
11845 other = ppc64_decode_local_entry (other);
11846 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
11847 return buf;
11848 }
11849 return NULL;
11850}
11851
5e2b0d47 11852static const char *
dda8d76d 11853get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
11854{
11855 const char * result = NULL;
89246a0e 11856 static char buff [64];
5e2b0d47
NC
11857
11858 if (other == 0)
11859 return "";
11860
dda8d76d 11861 switch (filedata->file_header.e_machine)
5e2b0d47 11862 {
2057d69d
CZ
11863 case EM_ALPHA:
11864 result = get_alpha_symbol_other (other);
11865 break;
2301ed1c
SN
11866 case EM_AARCH64:
11867 result = get_aarch64_symbol_other (other);
11868 break;
5e2b0d47
NC
11869 case EM_MIPS:
11870 result = get_mips_symbol_other (other);
28f997cf
TG
11871 break;
11872 case EM_IA_64:
dda8d76d 11873 result = get_ia64_symbol_other (filedata, other);
28f997cf 11874 break;
6911b7dc
AM
11875 case EM_PPC64:
11876 result = get_ppc64_symbol_other (other);
11877 break;
5e2b0d47 11878 default:
fd85a6a1 11879 result = NULL;
5e2b0d47
NC
11880 break;
11881 }
11882
11883 if (result)
11884 return result;
11885
11886 snprintf (buff, sizeof buff, _("<other>: %x"), other);
11887 return buff;
11888}
11889
d1133906 11890static const char *
dda8d76d 11891get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 11892{
b34976b6 11893 static char buff[32];
5cf1065c 11894
252b5132
RH
11895 switch (type)
11896 {
b34976b6
AM
11897 case SHN_UNDEF: return "UND";
11898 case SHN_ABS: return "ABS";
11899 case SHN_COMMON: return "COM";
252b5132 11900 default:
9ce701e2 11901 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
11902 && filedata->file_header.e_machine == EM_IA_64
11903 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
11904 return "ANSI_COM";
11905 else if ((filedata->file_header.e_machine == EM_X86_64
11906 || filedata->file_header.e_machine == EM_L1OM
11907 || filedata->file_header.e_machine == EM_K1OM)
11908 && type == SHN_X86_64_LCOMMON)
11909 return "LARGE_COM";
11910 else if ((type == SHN_MIPS_SCOMMON
11911 && filedata->file_header.e_machine == EM_MIPS)
11912 || (type == SHN_TIC6X_SCOMMON
11913 && filedata->file_header.e_machine == EM_TI_C6000))
11914 return "SCOM";
11915 else if (type == SHN_MIPS_SUNDEFINED
11916 && filedata->file_header.e_machine == EM_MIPS)
11917 return "SUND";
11918 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
11919 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
11920 else if (type >= SHN_LOOS && type <= SHN_HIOS)
11921 sprintf (buff, "OS [0x%04x]", type & 0xffff);
11922 else if (type >= SHN_LORESERVE)
11923 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
11924 else if (filedata->file_header.e_shnum != 0
11925 && type >= filedata->file_header.e_shnum)
11926 sprintf (buff, _("bad section index[%3d]"), type);
11927 else
11928 sprintf (buff, "%3d", type);
11929 break;
fd85a6a1
NC
11930 }
11931
10ca4b04 11932 return buff;
6bd1a22c
L
11933}
11934
bb4d2ac2 11935static const char *
dda8d76d 11936get_symbol_version_string (Filedata * filedata,
1449284b
NC
11937 bfd_boolean is_dynsym,
11938 const char * strtab,
11939 unsigned long int strtab_size,
11940 unsigned int si,
11941 Elf_Internal_Sym * psym,
11942 enum versioned_symbol_info * sym_info,
11943 unsigned short * vna_other)
bb4d2ac2 11944{
ab273396
AM
11945 unsigned char data[2];
11946 unsigned short vers_data;
11947 unsigned long offset;
7a815dd5 11948 unsigned short max_vd_ndx;
bb4d2ac2 11949
ab273396 11950 if (!is_dynsym
978c4450 11951 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 11952 return NULL;
bb4d2ac2 11953
978c4450
AM
11954 offset = offset_from_vma (filedata,
11955 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 11956 sizeof data + si * sizeof (vers_data));
bb4d2ac2 11957
dda8d76d 11958 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
11959 sizeof (data), 1, _("version data")) == NULL)
11960 return NULL;
11961
11962 vers_data = byte_get (data, 2);
bb4d2ac2 11963
1f6f5dba 11964 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 11965 return NULL;
bb4d2ac2 11966
0b8b7609 11967 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
11968 max_vd_ndx = 0;
11969
ab273396
AM
11970 /* Usually we'd only see verdef for defined symbols, and verneed for
11971 undefined symbols. However, symbols defined by the linker in
11972 .dynbss for variables copied from a shared library in order to
11973 avoid text relocations are defined yet have verneed. We could
11974 use a heuristic to detect the special case, for example, check
11975 for verneed first on symbols defined in SHT_NOBITS sections, but
11976 it is simpler and more reliable to just look for both verdef and
11977 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 11978
ab273396
AM
11979 if (psym->st_shndx != SHN_UNDEF
11980 && vers_data != 0x8001
978c4450 11981 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
11982 {
11983 Elf_Internal_Verdef ivd;
11984 Elf_Internal_Verdaux ivda;
11985 Elf_External_Verdaux evda;
11986 unsigned long off;
bb4d2ac2 11987
dda8d76d 11988 off = offset_from_vma (filedata,
978c4450 11989 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
11990 sizeof (Elf_External_Verdef));
11991
11992 do
bb4d2ac2 11993 {
ab273396
AM
11994 Elf_External_Verdef evd;
11995
dda8d76d 11996 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
11997 _("version def")) == NULL)
11998 {
11999 ivd.vd_ndx = 0;
12000 ivd.vd_aux = 0;
12001 ivd.vd_next = 0;
1f6f5dba 12002 ivd.vd_flags = 0;
ab273396
AM
12003 }
12004 else
bb4d2ac2 12005 {
ab273396
AM
12006 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12007 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12008 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12009 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12010 }
bb4d2ac2 12011
7a815dd5
L
12012 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12013 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12014
ab273396
AM
12015 off += ivd.vd_next;
12016 }
12017 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12018
ab273396
AM
12019 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12020 {
9abca702 12021 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12022 return NULL;
12023
ab273396
AM
12024 off -= ivd.vd_next;
12025 off += ivd.vd_aux;
bb4d2ac2 12026
dda8d76d 12027 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12028 _("version def aux")) != NULL)
12029 {
12030 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12031
ab273396 12032 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12033 return (ivda.vda_name < strtab_size
12034 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12035 }
12036 }
12037 }
bb4d2ac2 12038
978c4450 12039 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12040 {
12041 Elf_External_Verneed evn;
12042 Elf_Internal_Verneed ivn;
12043 Elf_Internal_Vernaux ivna;
bb4d2ac2 12044
dda8d76d 12045 offset = offset_from_vma (filedata,
978c4450 12046 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12047 sizeof evn);
12048 do
12049 {
12050 unsigned long vna_off;
bb4d2ac2 12051
dda8d76d 12052 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12053 _("version need")) == NULL)
12054 {
12055 ivna.vna_next = 0;
12056 ivna.vna_other = 0;
12057 ivna.vna_name = 0;
12058 break;
12059 }
bb4d2ac2 12060
ab273396
AM
12061 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12062 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12063
ab273396 12064 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12065
ab273396
AM
12066 do
12067 {
12068 Elf_External_Vernaux evna;
bb4d2ac2 12069
dda8d76d 12070 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12071 _("version need aux (3)")) == NULL)
bb4d2ac2 12072 {
ab273396
AM
12073 ivna.vna_next = 0;
12074 ivna.vna_other = 0;
12075 ivna.vna_name = 0;
bb4d2ac2 12076 }
bb4d2ac2 12077 else
bb4d2ac2 12078 {
ab273396
AM
12079 ivna.vna_other = BYTE_GET (evna.vna_other);
12080 ivna.vna_next = BYTE_GET (evna.vna_next);
12081 ivna.vna_name = BYTE_GET (evna.vna_name);
12082 }
bb4d2ac2 12083
ab273396
AM
12084 vna_off += ivna.vna_next;
12085 }
12086 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12087
ab273396
AM
12088 if (ivna.vna_other == vers_data)
12089 break;
bb4d2ac2 12090
ab273396
AM
12091 offset += ivn.vn_next;
12092 }
12093 while (ivn.vn_next != 0);
bb4d2ac2 12094
ab273396
AM
12095 if (ivna.vna_other == vers_data)
12096 {
12097 *sym_info = symbol_undefined;
12098 *vna_other = ivna.vna_other;
12099 return (ivna.vna_name < strtab_size
12100 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12101 }
7a815dd5
L
12102 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12103 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12104 return _("<corrupt>");
bb4d2ac2 12105 }
ab273396 12106 return NULL;
bb4d2ac2
L
12107}
12108
10ca4b04
L
12109static void
12110print_dynamic_symbol (Filedata *filedata, unsigned long si,
12111 Elf_Internal_Sym *symtab,
12112 Elf_Internal_Shdr *section,
12113 char *strtab, size_t strtab_size)
252b5132 12114{
10ca4b04
L
12115 const char *version_string;
12116 enum versioned_symbol_info sym_info;
12117 unsigned short vna_other;
12118 Elf_Internal_Sym *psym = symtab + si;
0942c7ab 12119
10ca4b04
L
12120 printf ("%6ld: ", si);
12121 print_vma (psym->st_value, LONG_HEX);
12122 putchar (' ');
12123 print_vma (psym->st_size, DEC_5);
12124 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12125 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12126 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12127 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12128 else
252b5132 12129 {
10ca4b04 12130 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12131
10ca4b04
L
12132 printf (" %-7s", get_symbol_visibility (vis));
12133 /* Check to see if any other bits in the st_other field are set.
12134 Note - displaying this information disrupts the layout of the
12135 table being generated, but for the moment this case is very rare. */
12136 if (psym->st_other ^ vis)
12137 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12138 }
10ca4b04 12139 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab
NC
12140
12141 bfd_boolean is_valid = VALID_SYMBOL_NAME (strtab, strtab_size,
12142 psym->st_name);
12143 const char * sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
10ca4b04
L
12144
12145 version_string
12146 = get_symbol_version_string (filedata,
12147 (section == NULL
12148 || section->sh_type == SHT_DYNSYM),
12149 strtab, strtab_size, si,
12150 psym, &sym_info, &vna_other);
0942c7ab
NC
12151
12152 int len_avail = 21;
12153 if (! do_wide && version_string != NULL)
12154 {
ddb43bab 12155 char buffer[16];
0942c7ab 12156
ddb43bab 12157 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
12158
12159 if (sym_info == symbol_undefined)
12160 len_avail -= sprintf (buffer," (%d)", vna_other);
12161 else if (sym_info != symbol_hidden)
12162 len_avail -= 1;
12163 }
12164
12165 print_symbol (len_avail, sstr);
12166
10ca4b04
L
12167 if (version_string)
12168 {
12169 if (sym_info == symbol_undefined)
12170 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12171 else
10ca4b04
L
12172 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12173 version_string);
12174 }
6bd1a22c 12175
10ca4b04 12176 putchar ('\n');
6bd1a22c 12177
10ca4b04
L
12178 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12179 && section != NULL
12180 && si >= section->sh_info
12181 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12182 && filedata->file_header.e_machine != EM_MIPS
12183 /* Solaris binaries have been found to violate this requirement as
12184 well. Not sure if this is a bug or an ABI requirement. */
12185 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12186 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12187 si, printable_section_name (filedata, section), section->sh_info);
12188}
f16a9783 12189
0f03783c
NC
12190static const char *
12191get_lto_kind (unsigned int kind)
12192{
12193 switch (kind)
12194 {
12195 case 0: return "DEF";
12196 case 1: return "WEAKDEF";
12197 case 2: return "UNDEF";
12198 case 3: return "WEAKUNDEF";
12199 case 4: return "COMMON";
12200 default:
12201 break;
12202 }
12203
12204 static char buffer[30];
12205 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
12206 sprintf (buffer, "<unknown: %u>", kind);
12207 return buffer;
12208}
12209
12210static const char *
12211get_lto_visibility (unsigned int visibility)
12212{
12213 switch (visibility)
12214 {
12215 case 0: return "DEFAULT";
12216 case 1: return "PROTECTED";
12217 case 2: return "INTERNAL";
12218 case 3: return "HIDDEN";
12219 default:
12220 break;
12221 }
12222
12223 static char buffer[30];
12224 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
12225 sprintf (buffer, "<unknown: %u>", visibility);
12226 return buffer;
12227}
12228
12229static const char *
12230get_lto_sym_type (unsigned int sym_type)
12231{
12232 switch (sym_type)
12233 {
12234 case 0: return "UNKNOWN";
12235 case 1: return "FUNCTION";
12236 case 2: return "VARIABLE";
12237 default:
12238 break;
12239 }
12240
12241 static char buffer[30];
12242 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
12243 sprintf (buffer, "<unknown: %u>", sym_type);
12244 return buffer;
12245}
12246
12247/* Display an LTO format symbol table.
12248 FIXME: The format of LTO symbol tables is not formalized.
12249 So this code could need changing in the future. */
12250
12251static bfd_boolean
12252display_lto_symtab (Filedata * filedata,
12253 Elf_Internal_Shdr * section)
12254{
12255 if (section->sh_size == 0)
12256 {
12257 printf (_("\nLTO Symbol table '%s' is empty!\n"),
12258 printable_section_name (filedata, section));
12259 return TRUE;
12260 }
12261
12262 if (section->sh_size > filedata->file_size)
12263 {
12264 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
12265 printable_section_name (filedata, section),
12266 (unsigned long) section->sh_size);
12267 return FALSE;
12268 }
12269
12270 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
12271 section->sh_size, 1, _("LTO symbols"));
12272 if (alloced_data == NULL)
12273 return FALSE;
12274
12275 /* Look for extended data for the symbol table. */
12276 Elf_Internal_Shdr * ext;
12277 void * ext_data_orig = NULL;
12278 char * ext_data = NULL;
12279 char * ext_data_end = NULL;
12280 char * ext_name = NULL;
12281
12282 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
12283 SECTION_NAME (section) + strlen (".gnu.lto_.symtab.")) > 0
12284 && ext_name != NULL /* Paranoia. */
12285 && (ext = find_section (filedata, ext_name)) != NULL)
12286 {
12287 if (ext->sh_size < 3)
12288 error (_("LTO Symbol extension table '%s' is empty!\n"),
12289 printable_section_name (filedata, ext));
12290 else
12291 {
12292 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
12293 ext->sh_size, 1,
12294 _("LTO ext symbol data"));
12295 if (ext_data != NULL)
12296 {
12297 ext_data_end = ext_data + ext->sh_size;
12298 if (* ext_data++ != 1)
12299 error (_("Unexpected version number in symbol extension table\n"));
12300 }
12301 }
12302 }
12303
12304 const unsigned char * data = (const unsigned char *) alloced_data;
12305 const unsigned char * end = data + section->sh_size;
12306
12307 if (ext_data_orig != NULL)
12308 {
12309 if (do_wide)
12310 printf (_("\nLTO Symbol table '%s' and extension table '%s' contain:\n"),
12311 printable_section_name (filedata, section),
12312 printable_section_name (filedata, ext));
12313 else
12314 {
12315 printf (_("\nLTO Symbol table '%s'\n"),
12316 printable_section_name (filedata, section));
12317 printf (_(" and extension table '%s' contain:\n"),
12318 printable_section_name (filedata, ext));
12319 }
12320 }
12321 else
12322 printf (_("\nLTO Symbol table '%s' contains:\n"),
12323 printable_section_name (filedata, section));
12324
12325
12326 /* FIXME: Add a wide version. */
12327 if (ext_data_orig != NULL)
12328 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
12329 else
12330 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
12331
12332 /* FIXME: We do not handle style prefixes. */
12333
12334 while (data < end)
12335 {
12336 const unsigned char * sym_name = data;
12337 data += strnlen ((const char *) sym_name, end - data) + 1;
12338 if (data >= end)
12339 goto fail;
12340
12341 const unsigned char * comdat_key = data;
12342 data += strnlen ((const char *) comdat_key, end - data) + 1;
12343 if (data >= end)
12344 goto fail;
12345
12346 if (data + 2 + 8 + 4 > end)
12347 goto fail;
12348
12349 unsigned int kind = *data++;
12350 unsigned int visibility = *data++;
12351
12352 elf_vma size = byte_get (data, 8);
12353 data += 8;
12354
12355 elf_vma slot = byte_get (data, 4);
12356 data += 4;
12357
12358 if (ext_data != NULL)
12359 {
12360 if (ext_data < (ext_data_end - 1))
12361 {
12362 unsigned int sym_type = * ext_data ++;
12363 unsigned int sec_kind = * ext_data ++;
12364
12365 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
12366 * comdat_key == 0 ? "-" : (char *) comdat_key,
12367 get_lto_kind (kind),
12368 get_lto_visibility (visibility),
12369 (long) size,
12370 (long) slot,
12371 get_lto_sym_type (sym_type),
12372 (long) sec_kind);
12373 print_symbol (6, (const char *) sym_name);
12374 }
12375 else
12376 {
12377 error (_("Ran out of LTO symbol extension data\n"));
12378 ext_data = NULL;
12379 /* FIXME: return FAIL result ? */
12380 }
12381 }
12382 else
12383 {
12384 printf (" %10s %10s %11s %08lx %08lx _",
12385 * comdat_key == 0 ? "-" : (char *) comdat_key,
12386 get_lto_kind (kind),
12387 get_lto_visibility (visibility),
12388 (long) size,
12389 (long) slot);
12390 print_symbol (21, (const char *) sym_name);
12391 }
12392 putchar ('\n');
12393 }
12394
12395 if (ext_data != NULL && ext_data < ext_data_end)
12396 {
12397 error (_("Data remains in the LTO symbol extension table\n"));
12398 goto fail;
12399 }
12400
12401 free (alloced_data);
12402 free (ext_data_orig);
12403 free (ext_name);
12404 return TRUE;
12405
12406 fail:
12407 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
12408 free (alloced_data);
12409 free (ext_data_orig);
12410 free (ext_name);
12411 return FALSE;
12412}
12413
12414/* Display LTO symbol tables. */
12415
12416static bfd_boolean
12417process_lto_symbol_tables (Filedata * filedata)
12418{
12419 Elf_Internal_Shdr * section;
12420 unsigned int i;
12421 bfd_boolean res = TRUE;
12422
12423 if (!do_lto_syms)
12424 return TRUE;
12425
12426 if (filedata->section_headers == NULL)
12427 return TRUE;
12428
12429 for (i = 0, section = filedata->section_headers;
12430 i < filedata->file_header.e_shnum;
12431 i++, section++)
12432 if (CONST_STRNEQ (SECTION_NAME (section), ".gnu.lto_.symtab"))
12433 res &= display_lto_symtab (filedata, section);
12434
12435 return res;
12436}
12437
10ca4b04 12438/* Dump the symbol table. */
0f03783c 12439
10ca4b04
L
12440static bfd_boolean
12441process_symbol_table (Filedata * filedata)
12442{
12443 Elf_Internal_Shdr * section;
f16a9783 12444
10ca4b04
L
12445 if (!do_syms && !do_dyn_syms && !do_histogram)
12446 return TRUE;
6bd1a22c 12447
978c4450 12448 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
12449 && do_syms
12450 && do_using_dynamic
978c4450
AM
12451 && filedata->dynamic_strings != NULL
12452 && filedata->dynamic_symbols != NULL)
6bd1a22c 12453 {
10ca4b04 12454 unsigned long si;
6bd1a22c 12455
10ca4b04
L
12456 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12457 "\nSymbol table for image contains %lu entries:\n",
978c4450
AM
12458 filedata->num_dynamic_syms),
12459 filedata->num_dynamic_syms);
10ca4b04
L
12460 if (is_32bit_elf)
12461 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12462 else
12463 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12464
978c4450
AM
12465 for (si = 0; si < filedata->num_dynamic_syms; si++)
12466 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
12467 filedata->dynamic_strings,
12468 filedata->dynamic_strings_length);
252b5132 12469 }
8b73c356 12470 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 12471 && filedata->section_headers != NULL)
252b5132 12472 {
b34976b6 12473 unsigned int i;
252b5132 12474
dda8d76d
NC
12475 for (i = 0, section = filedata->section_headers;
12476 i < filedata->file_header.e_shnum;
252b5132
RH
12477 i++, section++)
12478 {
2cf0635d 12479 char * strtab = NULL;
c256ffe7 12480 unsigned long int strtab_size = 0;
2cf0635d 12481 Elf_Internal_Sym * symtab;
ef3df110 12482 unsigned long si, num_syms;
252b5132 12483
2c610e4b
L
12484 if ((section->sh_type != SHT_SYMTAB
12485 && section->sh_type != SHT_DYNSYM)
12486 || (!do_syms
12487 && section->sh_type == SHT_SYMTAB))
252b5132
RH
12488 continue;
12489
dd24e3da
NC
12490 if (section->sh_entsize == 0)
12491 {
12492 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 12493 printable_section_name (filedata, section));
dd24e3da
NC
12494 continue;
12495 }
12496
d3a49aa8
AM
12497 num_syms = section->sh_size / section->sh_entsize;
12498 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
12499 "\nSymbol table '%s' contains %lu entries:\n",
12500 num_syms),
dda8d76d 12501 printable_section_name (filedata, section),
d3a49aa8 12502 num_syms);
dd24e3da 12503
f7a99963 12504 if (is_32bit_elf)
ca47b30c 12505 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 12506 else
ca47b30c 12507 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 12508
dda8d76d 12509 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
12510 if (symtab == NULL)
12511 continue;
12512
dda8d76d 12513 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 12514 {
dda8d76d
NC
12515 strtab = filedata->string_table;
12516 strtab_size = filedata->string_table_length;
c256ffe7 12517 }
dda8d76d 12518 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 12519 {
2cf0635d 12520 Elf_Internal_Shdr * string_sec;
252b5132 12521
dda8d76d 12522 string_sec = filedata->section_headers + section->sh_link;
252b5132 12523
dda8d76d 12524 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
12525 1, string_sec->sh_size,
12526 _("string table"));
c256ffe7 12527 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
12528 }
12529
10ca4b04
L
12530 for (si = 0; si < num_syms; si++)
12531 print_dynamic_symbol (filedata, si, symtab, section,
12532 strtab, strtab_size);
252b5132
RH
12533
12534 free (symtab);
dda8d76d 12535 if (strtab != filedata->string_table)
252b5132
RH
12536 free (strtab);
12537 }
12538 }
12539 else if (do_syms)
12540 printf
12541 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
12542
978c4450 12543 if (do_histogram && filedata->buckets != NULL)
252b5132 12544 {
2cf0635d
NC
12545 unsigned long * lengths;
12546 unsigned long * counts;
66543521
AM
12547 unsigned long hn;
12548 bfd_vma si;
12549 unsigned long maxlength = 0;
12550 unsigned long nzero_counts = 0;
12551 unsigned long nsyms = 0;
6bd6a03d 12552 char *visited;
252b5132 12553
d3a49aa8
AM
12554 printf (ngettext ("\nHistogram for bucket list length "
12555 "(total of %lu bucket):\n",
12556 "\nHistogram for bucket list length "
12557 "(total of %lu buckets):\n",
978c4450
AM
12558 (unsigned long) filedata->nbuckets),
12559 (unsigned long) filedata->nbuckets);
252b5132 12560
978c4450
AM
12561 lengths = (unsigned long *) calloc (filedata->nbuckets,
12562 sizeof (*lengths));
252b5132
RH
12563 if (lengths == NULL)
12564 {
8b73c356 12565 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 12566 goto err_out;
252b5132 12567 }
978c4450
AM
12568 visited = xcmalloc (filedata->nchains, 1);
12569 memset (visited, 0, filedata->nchains);
8b73c356
NC
12570
12571 printf (_(" Length Number %% of total Coverage\n"));
978c4450 12572 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 12573 {
978c4450 12574 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 12575 {
b34976b6 12576 ++nsyms;
252b5132 12577 if (maxlength < ++lengths[hn])
b34976b6 12578 ++maxlength;
978c4450 12579 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
12580 {
12581 error (_("histogram chain is corrupt\n"));
12582 break;
12583 }
12584 visited[si] = 1;
252b5132
RH
12585 }
12586 }
6bd6a03d 12587 free (visited);
252b5132 12588
3f5e193b 12589 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
12590 if (counts == NULL)
12591 {
b2e951ec 12592 free (lengths);
8b73c356 12593 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 12594 goto err_out;
252b5132
RH
12595 }
12596
978c4450 12597 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 12598 ++counts[lengths[hn]];
252b5132 12599
978c4450 12600 if (filedata->nbuckets > 0)
252b5132 12601 {
66543521
AM
12602 unsigned long i;
12603 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12604 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 12605 for (i = 1; i <= maxlength; ++i)
103f02d3 12606 {
66543521
AM
12607 nzero_counts += counts[i] * i;
12608 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12609 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
12610 (nzero_counts * 100.0) / nsyms);
12611 }
252b5132
RH
12612 }
12613
12614 free (counts);
12615 free (lengths);
12616 }
12617
978c4450
AM
12618 free (filedata->buckets);
12619 filedata->buckets = NULL;
12620 filedata->nbuckets = 0;
12621 free (filedata->chains);
12622 filedata->chains = NULL;
252b5132 12623
978c4450 12624 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 12625 {
2cf0635d
NC
12626 unsigned long * lengths;
12627 unsigned long * counts;
fdc90cb4
JJ
12628 unsigned long hn;
12629 unsigned long maxlength = 0;
12630 unsigned long nzero_counts = 0;
12631 unsigned long nsyms = 0;
fdc90cb4 12632
f16a9783 12633 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 12634 "(total of %lu bucket):\n",
f16a9783 12635 "\nHistogram for `%s' bucket list length "
d3a49aa8 12636 "(total of %lu buckets):\n",
978c4450
AM
12637 (unsigned long) filedata->ngnubuckets),
12638 GNU_HASH_SECTION_NAME (filedata),
12639 (unsigned long) filedata->ngnubuckets);
8b73c356 12640
978c4450
AM
12641 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
12642 sizeof (*lengths));
fdc90cb4
JJ
12643 if (lengths == NULL)
12644 {
8b73c356 12645 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 12646 goto err_out;
fdc90cb4
JJ
12647 }
12648
fdc90cb4
JJ
12649 printf (_(" Length Number %% of total Coverage\n"));
12650
978c4450
AM
12651 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
12652 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
12653 {
12654 bfd_vma off, length = 1;
12655
978c4450 12656 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 12657 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
12658 off < filedata->ngnuchains
12659 && (filedata->gnuchains[off] & 1) == 0;
071436c6 12660 ++off)
fdc90cb4
JJ
12661 ++length;
12662 lengths[hn] = length;
12663 if (length > maxlength)
12664 maxlength = length;
12665 nsyms += length;
12666 }
12667
3f5e193b 12668 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
12669 if (counts == NULL)
12670 {
b2e951ec 12671 free (lengths);
8b73c356 12672 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 12673 goto err_out;
fdc90cb4
JJ
12674 }
12675
978c4450 12676 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
12677 ++counts[lengths[hn]];
12678
978c4450 12679 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
12680 {
12681 unsigned long j;
12682 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12683 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
12684 for (j = 1; j <= maxlength; ++j)
12685 {
12686 nzero_counts += counts[j] * j;
12687 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12688 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
12689 (nzero_counts * 100.0) / nsyms);
12690 }
12691 }
12692
12693 free (counts);
12694 free (lengths);
fdc90cb4 12695 }
978c4450
AM
12696 free (filedata->gnubuckets);
12697 filedata->gnubuckets = NULL;
12698 filedata->ngnubuckets = 0;
12699 free (filedata->gnuchains);
12700 filedata->gnuchains = NULL;
12701 filedata->ngnuchains = 0;
12702 free (filedata->mipsxlat);
12703 filedata->mipsxlat = NULL;
32ec8896 12704 return TRUE;
fd486f32
AM
12705
12706 err_out:
978c4450
AM
12707 free (filedata->gnubuckets);
12708 filedata->gnubuckets = NULL;
12709 filedata->ngnubuckets = 0;
12710 free (filedata->gnuchains);
12711 filedata->gnuchains = NULL;
12712 filedata->ngnuchains = 0;
12713 free (filedata->mipsxlat);
12714 filedata->mipsxlat = NULL;
12715 free (filedata->buckets);
12716 filedata->buckets = NULL;
12717 filedata->nbuckets = 0;
12718 free (filedata->chains);
12719 filedata->chains = NULL;
fd486f32 12720 return FALSE;
252b5132
RH
12721}
12722
32ec8896 12723static bfd_boolean
dda8d76d 12724process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
252b5132 12725{
b4c96d0d 12726 unsigned int i;
252b5132 12727
978c4450 12728 if (filedata->dynamic_syminfo == NULL
252b5132
RH
12729 || !do_dynamic)
12730 /* No syminfo, this is ok. */
32ec8896 12731 return TRUE;
252b5132
RH
12732
12733 /* There better should be a dynamic symbol section. */
978c4450 12734 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
32ec8896 12735 return FALSE;
252b5132 12736
978c4450 12737 if (filedata->dynamic_addr)
d3a49aa8
AM
12738 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
12739 "contains %d entry:\n",
12740 "\nDynamic info segment at offset 0x%lx "
12741 "contains %d entries:\n",
978c4450
AM
12742 filedata->dynamic_syminfo_nent),
12743 filedata->dynamic_syminfo_offset, filedata->dynamic_syminfo_nent);
252b5132
RH
12744
12745 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 12746 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 12747 {
978c4450 12748 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 12749
31104126 12750 printf ("%4d: ", i);
978c4450 12751 if (i >= filedata->num_dynamic_syms)
4082ef84 12752 printf (_("<corrupt index>"));
978c4450
AM
12753 else if (VALID_DYNAMIC_NAME (filedata, filedata->dynamic_symbols[i].st_name))
12754 print_symbol (30, GET_DYNAMIC_NAME (filedata,
12755 filedata->dynamic_symbols[i].st_name));
d79b3d50 12756 else
978c4450 12757 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 12758 putchar (' ');
252b5132 12759
978c4450 12760 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
12761 {
12762 case SYMINFO_BT_SELF:
12763 fputs ("SELF ", stdout);
12764 break;
12765 case SYMINFO_BT_PARENT:
12766 fputs ("PARENT ", stdout);
12767 break;
12768 default:
978c4450
AM
12769 if (filedata->dynamic_syminfo[i].si_boundto > 0
12770 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
12771 && VALID_DYNAMIC_NAME (filedata,
12772 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 12773 {
978c4450
AM
12774 print_symbol (10, GET_DYNAMIC_NAME (filedata,
12775 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
12776 putchar (' ' );
12777 }
252b5132 12778 else
978c4450 12779 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
12780 break;
12781 }
12782
12783 if (flags & SYMINFO_FLG_DIRECT)
12784 printf (" DIRECT");
12785 if (flags & SYMINFO_FLG_PASSTHRU)
12786 printf (" PASSTHRU");
12787 if (flags & SYMINFO_FLG_COPY)
12788 printf (" COPY");
12789 if (flags & SYMINFO_FLG_LAZYLOAD)
12790 printf (" LAZYLOAD");
12791
12792 puts ("");
12793 }
12794
32ec8896 12795 return TRUE;
252b5132
RH
12796}
12797
75802ccb
CE
12798/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
12799 is contained by the region START .. END. The types of ADDR, START
12800 and END should all be the same. Note both ADDR + NELEM and END
12801 point to just beyond the end of the regions that are being tested. */
12802#define IN_RANGE(START,END,ADDR,NELEM) \
12803 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 12804
cf13d699
NC
12805/* Check to see if the given reloc needs to be handled in a target specific
12806 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
12807 FALSE.
12808
12809 If called with reloc == NULL, then this is a signal that reloc processing
12810 for the current section has finished, and any saved state should be
12811 discarded. */
09c11c86 12812
cf13d699 12813static bfd_boolean
dda8d76d
NC
12814target_specific_reloc_handling (Filedata * filedata,
12815 Elf_Internal_Rela * reloc,
12816 unsigned char * start,
12817 unsigned char * end,
12818 Elf_Internal_Sym * symtab,
12819 unsigned long num_syms)
252b5132 12820{
f84ce13b
NC
12821 unsigned int reloc_type = 0;
12822 unsigned long sym_index = 0;
12823
12824 if (reloc)
12825 {
dda8d76d 12826 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
12827 sym_index = get_reloc_symindex (reloc->r_info);
12828 }
252b5132 12829
dda8d76d 12830 switch (filedata->file_header.e_machine)
252b5132 12831 {
13761a11
NC
12832 case EM_MSP430:
12833 case EM_MSP430_OLD:
12834 {
12835 static Elf_Internal_Sym * saved_sym = NULL;
12836
f84ce13b
NC
12837 if (reloc == NULL)
12838 {
12839 saved_sym = NULL;
12840 return TRUE;
12841 }
12842
13761a11
NC
12843 switch (reloc_type)
12844 {
12845 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 12846 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 12847 if (uses_msp430x_relocs (filedata))
13761a11 12848 break;
1a0670f3 12849 /* Fall through. */
13761a11 12850 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 12851 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
12852 /* PR 21139. */
12853 if (sym_index >= num_syms)
12854 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
12855 sym_index);
12856 else
12857 saved_sym = symtab + sym_index;
13761a11
NC
12858 return TRUE;
12859
12860 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
12861 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
12862 goto handle_sym_diff;
0b4362b0 12863
13761a11
NC
12864 case 5: /* R_MSP430_16_BYTE */
12865 case 9: /* R_MSP430_8 */
7d81bc93 12866 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 12867 if (uses_msp430x_relocs (filedata))
13761a11
NC
12868 break;
12869 goto handle_sym_diff;
12870
12871 case 2: /* R_MSP430_ABS16 */
12872 case 15: /* R_MSP430X_ABS16 */
7d81bc93 12873 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 12874 if (! uses_msp430x_relocs (filedata))
13761a11
NC
12875 break;
12876 goto handle_sym_diff;
0b4362b0 12877
13761a11
NC
12878 handle_sym_diff:
12879 if (saved_sym != NULL)
12880 {
12881 bfd_vma value;
5a805384 12882 unsigned int reloc_size = 0;
7d81bc93
JL
12883 int leb_ret = 0;
12884 switch (reloc_type)
12885 {
12886 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
12887 reloc_size = 4;
12888 break;
12889 case 11: /* R_MSP430_GNU_SET_ULEB128 */
12890 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384
AM
12891 if (reloc->r_offset < (size_t) (end - start))
12892 read_leb128 (start + reloc->r_offset, end, FALSE,
12893 &reloc_size, &leb_ret);
7d81bc93
JL
12894 break;
12895 default:
12896 reloc_size = 2;
12897 break;
12898 }
13761a11 12899
5a805384 12900 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
12901 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
12902 "ULEB128 value\n"),
12903 (long) reloc->r_offset);
12904 else if (sym_index >= num_syms)
f84ce13b
NC
12905 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
12906 sym_index);
03f7786e 12907 else
f84ce13b
NC
12908 {
12909 value = reloc->r_addend + (symtab[sym_index].st_value
12910 - saved_sym->st_value);
12911
b32e566b 12912 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12913 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12914 else
12915 /* PR 21137 */
12916 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
12917 (long) reloc->r_offset);
f84ce13b 12918 }
13761a11
NC
12919
12920 saved_sym = NULL;
12921 return TRUE;
12922 }
12923 break;
12924
12925 default:
12926 if (saved_sym != NULL)
071436c6 12927 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
12928 break;
12929 }
12930 break;
12931 }
12932
cf13d699
NC
12933 case EM_MN10300:
12934 case EM_CYGNUS_MN10300:
12935 {
12936 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 12937
f84ce13b
NC
12938 if (reloc == NULL)
12939 {
12940 saved_sym = NULL;
12941 return TRUE;
12942 }
12943
cf13d699
NC
12944 switch (reloc_type)
12945 {
12946 case 34: /* R_MN10300_ALIGN */
12947 return TRUE;
12948 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
12949 if (sym_index >= num_syms)
12950 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
12951 sym_index);
12952 else
12953 saved_sym = symtab + sym_index;
cf13d699 12954 return TRUE;
f84ce13b 12955
cf13d699
NC
12956 case 1: /* R_MN10300_32 */
12957 case 2: /* R_MN10300_16 */
12958 if (saved_sym != NULL)
12959 {
03f7786e 12960 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 12961 bfd_vma value;
252b5132 12962
f84ce13b
NC
12963 if (sym_index >= num_syms)
12964 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
12965 sym_index);
03f7786e 12966 else
f84ce13b
NC
12967 {
12968 value = reloc->r_addend + (symtab[sym_index].st_value
12969 - saved_sym->st_value);
12970
b32e566b 12971 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12972 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12973 else
12974 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
12975 (long) reloc->r_offset);
f84ce13b 12976 }
252b5132 12977
cf13d699
NC
12978 saved_sym = NULL;
12979 return TRUE;
12980 }
12981 break;
12982 default:
12983 if (saved_sym != NULL)
071436c6 12984 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
12985 break;
12986 }
12987 break;
12988 }
6ff71e76
NC
12989
12990 case EM_RL78:
12991 {
12992 static bfd_vma saved_sym1 = 0;
12993 static bfd_vma saved_sym2 = 0;
12994 static bfd_vma value;
12995
f84ce13b
NC
12996 if (reloc == NULL)
12997 {
12998 saved_sym1 = saved_sym2 = 0;
12999 return TRUE;
13000 }
13001
6ff71e76
NC
13002 switch (reloc_type)
13003 {
13004 case 0x80: /* R_RL78_SYM. */
13005 saved_sym1 = saved_sym2;
f84ce13b
NC
13006 if (sym_index >= num_syms)
13007 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
13008 sym_index);
13009 else
13010 {
13011 saved_sym2 = symtab[sym_index].st_value;
13012 saved_sym2 += reloc->r_addend;
13013 }
6ff71e76
NC
13014 return TRUE;
13015
13016 case 0x83: /* R_RL78_OPsub. */
13017 value = saved_sym1 - saved_sym2;
13018 saved_sym2 = saved_sym1 = 0;
13019 return TRUE;
13020 break;
13021
13022 case 0x41: /* R_RL78_ABS32. */
b32e566b 13023 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 13024 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
13025 else
13026 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13027 (long) reloc->r_offset);
6ff71e76
NC
13028 value = 0;
13029 return TRUE;
13030
13031 case 0x43: /* R_RL78_ABS16. */
b32e566b 13032 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 13033 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
13034 else
13035 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13036 (long) reloc->r_offset);
6ff71e76
NC
13037 value = 0;
13038 return TRUE;
13039
13040 default:
13041 break;
13042 }
13043 break;
13044 }
252b5132
RH
13045 }
13046
cf13d699 13047 return FALSE;
252b5132
RH
13048}
13049
aca88567
NC
13050/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
13051 DWARF debug sections. This is a target specific test. Note - we do not
13052 go through the whole including-target-headers-multiple-times route, (as
13053 we have already done with <elf/h8.h>) because this would become very
13054 messy and even then this function would have to contain target specific
13055 information (the names of the relocs instead of their numeric values).
13056 FIXME: This is not the correct way to solve this problem. The proper way
13057 is to have target specific reloc sizing and typing functions created by
13058 the reloc-macros.h header, in the same way that it already creates the
13059 reloc naming functions. */
13060
13061static bfd_boolean
dda8d76d 13062is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13063{
d347c9df 13064 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13065 switch (filedata->file_header.e_machine)
aca88567 13066 {
41e92641 13067 case EM_386:
22abe556 13068 case EM_IAMCU:
41e92641 13069 return reloc_type == 1; /* R_386_32. */
aca88567
NC
13070 case EM_68K:
13071 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
13072 case EM_860:
13073 return reloc_type == 1; /* R_860_32. */
13074 case EM_960:
13075 return reloc_type == 2; /* R_960_32. */
a06ea964 13076 case EM_AARCH64:
9282b95a
JW
13077 return (reloc_type == 258
13078 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
13079 case EM_BPF:
13080 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
13081 case EM_ADAPTEVA_EPIPHANY:
13082 return reloc_type == 3;
aca88567 13083 case EM_ALPHA:
137b6b5f 13084 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
13085 case EM_ARC:
13086 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
13087 case EM_ARC_COMPACT:
13088 case EM_ARC_COMPACT2:
13089 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
13090 case EM_ARM:
13091 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 13092 case EM_AVR_OLD:
aca88567
NC
13093 case EM_AVR:
13094 return reloc_type == 1;
13095 case EM_BLACKFIN:
13096 return reloc_type == 0x12; /* R_byte4_data. */
13097 case EM_CRIS:
13098 return reloc_type == 3; /* R_CRIS_32. */
13099 case EM_CR16:
13100 return reloc_type == 3; /* R_CR16_NUM32. */
13101 case EM_CRX:
13102 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
13103 case EM_CSKY:
13104 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
13105 case EM_CYGNUS_FRV:
13106 return reloc_type == 1;
41e92641
NC
13107 case EM_CYGNUS_D10V:
13108 case EM_D10V:
13109 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
13110 case EM_CYGNUS_D30V:
13111 case EM_D30V:
13112 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
13113 case EM_DLX:
13114 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
13115 case EM_CYGNUS_FR30:
13116 case EM_FR30:
13117 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
13118 case EM_FT32:
13119 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
13120 case EM_H8S:
13121 case EM_H8_300:
13122 case EM_H8_300H:
13123 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 13124 case EM_IA_64:
262cdac7
AM
13125 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
13126 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
13127 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
13128 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
13129 case EM_IP2K_OLD:
13130 case EM_IP2K:
13131 return reloc_type == 2; /* R_IP2K_32. */
13132 case EM_IQ2000:
13133 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
13134 case EM_LATTICEMICO32:
13135 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 13136 case EM_M32C_OLD:
aca88567
NC
13137 case EM_M32C:
13138 return reloc_type == 3; /* R_M32C_32. */
13139 case EM_M32R:
13140 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
13141 case EM_68HC11:
13142 case EM_68HC12:
13143 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 13144 case EM_S12Z:
2849d19f
JD
13145 return reloc_type == 7 || /* R_S12Z_EXT32 */
13146 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
13147 case EM_MCORE:
13148 return reloc_type == 1; /* R_MCORE_ADDR32. */
13149 case EM_CYGNUS_MEP:
13150 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
13151 case EM_METAG:
13152 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
13153 case EM_MICROBLAZE:
13154 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
13155 case EM_MIPS:
13156 return reloc_type == 2; /* R_MIPS_32. */
13157 case EM_MMIX:
13158 return reloc_type == 4; /* R_MMIX_32. */
13159 case EM_CYGNUS_MN10200:
13160 case EM_MN10200:
13161 return reloc_type == 1; /* R_MN10200_32. */
13162 case EM_CYGNUS_MN10300:
13163 case EM_MN10300:
13164 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
13165 case EM_MOXIE:
13166 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
13167 case EM_MSP430_OLD:
13168 case EM_MSP430:
13761a11 13169 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
13170 case EM_MT:
13171 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
13172 case EM_NDS32:
13173 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 13174 case EM_ALTERA_NIOS2:
36591ba1 13175 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
13176 case EM_NIOS32:
13177 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
13178 case EM_OR1K:
13179 return reloc_type == 1; /* R_OR1K_32. */
aca88567 13180 case EM_PARISC:
9abca702 13181 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 13182 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 13183 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
13184 case EM_PJ:
13185 case EM_PJ_OLD:
13186 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
13187 case EM_PPC64:
13188 return reloc_type == 1; /* R_PPC64_ADDR32. */
13189 case EM_PPC:
13190 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
13191 case EM_TI_PRU:
13192 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
13193 case EM_RISCV:
13194 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
13195 case EM_RL78:
13196 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
13197 case EM_RX:
13198 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
13199 case EM_S370:
13200 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
13201 case EM_S390_OLD:
13202 case EM_S390:
13203 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
13204 case EM_SCORE:
13205 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
13206 case EM_SH:
13207 return reloc_type == 1; /* R_SH_DIR32. */
13208 case EM_SPARC32PLUS:
13209 case EM_SPARCV9:
13210 case EM_SPARC:
13211 return reloc_type == 3 /* R_SPARC_32. */
13212 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
13213 case EM_SPU:
13214 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
13215 case EM_TI_C6000:
13216 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
13217 case EM_TILEGX:
13218 return reloc_type == 2; /* R_TILEGX_32. */
13219 case EM_TILEPRO:
13220 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
13221 case EM_CYGNUS_V850:
13222 case EM_V850:
13223 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
13224 case EM_V800:
13225 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
13226 case EM_VAX:
13227 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
13228 case EM_VISIUM:
13229 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
13230 case EM_WEBASSEMBLY:
13231 return reloc_type == 1; /* R_WASM32_32. */
aca88567 13232 case EM_X86_64:
8a9036a4 13233 case EM_L1OM:
7a9068fe 13234 case EM_K1OM:
aca88567 13235 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
13236 case EM_XC16X:
13237 case EM_C166:
13238 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
13239 case EM_XGATE:
13240 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
13241 case EM_XSTORMY16:
13242 return reloc_type == 1; /* R_XSTROMY16_32. */
13243 case EM_XTENSA_OLD:
13244 case EM_XTENSA:
13245 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
13246 case EM_Z80:
13247 return reloc_type == 6; /* R_Z80_32. */
aca88567 13248 default:
bee0ee85
NC
13249 {
13250 static unsigned int prev_warn = 0;
13251
13252 /* Avoid repeating the same warning multiple times. */
dda8d76d 13253 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 13254 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
13255 filedata->file_header.e_machine);
13256 prev_warn = filedata->file_header.e_machine;
bee0ee85
NC
13257 return FALSE;
13258 }
aca88567
NC
13259 }
13260}
13261
13262/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13263 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
13264
13265static bfd_boolean
dda8d76d 13266is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13267{
dda8d76d 13268 switch (filedata->file_header.e_machine)
d347c9df 13269 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 13270 {
41e92641 13271 case EM_386:
22abe556 13272 case EM_IAMCU:
3e0873ac 13273 return reloc_type == 2; /* R_386_PC32. */
aca88567 13274 case EM_68K:
3e0873ac 13275 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
13276 case EM_AARCH64:
13277 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
13278 case EM_ADAPTEVA_EPIPHANY:
13279 return reloc_type == 6;
aca88567
NC
13280 case EM_ALPHA:
13281 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
13282 case EM_ARC_COMPACT:
13283 case EM_ARC_COMPACT2:
13284 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 13285 case EM_ARM:
3e0873ac 13286 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
13287 case EM_AVR_OLD:
13288 case EM_AVR:
13289 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
13290 case EM_MICROBLAZE:
13291 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
13292 case EM_OR1K:
13293 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 13294 case EM_PARISC:
85acf597 13295 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
13296 case EM_PPC:
13297 return reloc_type == 26; /* R_PPC_REL32. */
13298 case EM_PPC64:
3e0873ac 13299 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
13300 case EM_RISCV:
13301 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
13302 case EM_S390_OLD:
13303 case EM_S390:
3e0873ac 13304 return reloc_type == 5; /* R_390_PC32. */
aca88567 13305 case EM_SH:
3e0873ac 13306 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
13307 case EM_SPARC32PLUS:
13308 case EM_SPARCV9:
13309 case EM_SPARC:
3e0873ac 13310 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
13311 case EM_SPU:
13312 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
13313 case EM_TILEGX:
13314 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
13315 case EM_TILEPRO:
13316 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
13317 case EM_VISIUM:
13318 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 13319 case EM_X86_64:
8a9036a4 13320 case EM_L1OM:
7a9068fe 13321 case EM_K1OM:
3e0873ac 13322 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
13323 case EM_VAX:
13324 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
13325 case EM_XTENSA_OLD:
13326 case EM_XTENSA:
13327 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
13328 default:
13329 /* Do not abort or issue an error message here. Not all targets use
13330 pc-relative 32-bit relocs in their DWARF debug information and we
13331 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
13332 more helpful warning message will be generated by apply_relocations
13333 anyway, so just return. */
aca88567
NC
13334 return FALSE;
13335 }
13336}
13337
13338/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13339 a 64-bit absolute RELA relocation used in DWARF debug sections. */
13340
13341static bfd_boolean
dda8d76d 13342is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13343{
dda8d76d 13344 switch (filedata->file_header.e_machine)
aca88567 13345 {
a06ea964
NC
13346 case EM_AARCH64:
13347 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
13348 case EM_ALPHA:
13349 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 13350 case EM_IA_64:
262cdac7
AM
13351 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
13352 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
13353 case EM_PARISC:
13354 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
13355 case EM_PPC64:
13356 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
13357 case EM_RISCV:
13358 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
13359 case EM_SPARC32PLUS:
13360 case EM_SPARCV9:
13361 case EM_SPARC:
714da62f
NC
13362 return reloc_type == 32 /* R_SPARC_64. */
13363 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 13364 case EM_X86_64:
8a9036a4 13365 case EM_L1OM:
7a9068fe 13366 case EM_K1OM:
aca88567 13367 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
13368 case EM_S390_OLD:
13369 case EM_S390:
aa137e4d
NC
13370 return reloc_type == 22; /* R_S390_64. */
13371 case EM_TILEGX:
13372 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 13373 case EM_MIPS:
aa137e4d 13374 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
13375 default:
13376 return FALSE;
13377 }
13378}
13379
85acf597
RH
13380/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
13381 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
13382
13383static bfd_boolean
dda8d76d 13384is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 13385{
dda8d76d 13386 switch (filedata->file_header.e_machine)
85acf597 13387 {
a06ea964
NC
13388 case EM_AARCH64:
13389 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 13390 case EM_ALPHA:
aa137e4d 13391 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 13392 case EM_IA_64:
262cdac7
AM
13393 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
13394 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 13395 case EM_PARISC:
aa137e4d 13396 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 13397 case EM_PPC64:
aa137e4d 13398 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
13399 case EM_SPARC32PLUS:
13400 case EM_SPARCV9:
13401 case EM_SPARC:
aa137e4d 13402 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 13403 case EM_X86_64:
8a9036a4 13404 case EM_L1OM:
7a9068fe 13405 case EM_K1OM:
aa137e4d 13406 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
13407 case EM_S390_OLD:
13408 case EM_S390:
aa137e4d
NC
13409 return reloc_type == 23; /* R_S390_PC64. */
13410 case EM_TILEGX:
13411 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
13412 default:
13413 return FALSE;
13414 }
13415}
13416
4dc3c23d
AM
13417/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13418 a 24-bit absolute RELA relocation used in DWARF debug sections. */
13419
13420static bfd_boolean
dda8d76d 13421is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 13422{
dda8d76d 13423 switch (filedata->file_header.e_machine)
4dc3c23d
AM
13424 {
13425 case EM_CYGNUS_MN10200:
13426 case EM_MN10200:
13427 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
13428 case EM_FT32:
13429 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
13430 case EM_Z80:
13431 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d
AM
13432 default:
13433 return FALSE;
13434 }
13435}
13436
aca88567
NC
13437/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13438 a 16-bit absolute RELA relocation used in DWARF debug sections. */
13439
13440static bfd_boolean
dda8d76d 13441is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 13442{
d347c9df 13443 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13444 switch (filedata->file_header.e_machine)
4b78141a 13445 {
886a2506
NC
13446 case EM_ARC:
13447 case EM_ARC_COMPACT:
13448 case EM_ARC_COMPACT2:
13449 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
13450 case EM_ADAPTEVA_EPIPHANY:
13451 return reloc_type == 5;
aca88567
NC
13452 case EM_AVR_OLD:
13453 case EM_AVR:
13454 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
13455 case EM_CYGNUS_D10V:
13456 case EM_D10V:
13457 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
13458 case EM_FT32:
13459 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
13460 case EM_H8S:
13461 case EM_H8_300:
13462 case EM_H8_300H:
aca88567
NC
13463 return reloc_type == R_H8_DIR16;
13464 case EM_IP2K_OLD:
13465 case EM_IP2K:
13466 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 13467 case EM_M32C_OLD:
f4236fe4
DD
13468 case EM_M32C:
13469 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
13470 case EM_CYGNUS_MN10200:
13471 case EM_MN10200:
13472 return reloc_type == 2; /* R_MN10200_16. */
13473 case EM_CYGNUS_MN10300:
13474 case EM_MN10300:
13475 return reloc_type == 2; /* R_MN10300_16. */
aca88567 13476 case EM_MSP430:
dda8d76d 13477 if (uses_msp430x_relocs (filedata))
13761a11 13478 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 13479 /* Fall through. */
78c8d46c 13480 case EM_MSP430_OLD:
aca88567 13481 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
13482 case EM_NDS32:
13483 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 13484 case EM_ALTERA_NIOS2:
36591ba1 13485 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
13486 case EM_NIOS32:
13487 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
13488 case EM_OR1K:
13489 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
13490 case EM_RISCV:
13491 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
13492 case EM_TI_PRU:
13493 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
13494 case EM_TI_C6000:
13495 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
13496 case EM_VISIUM:
13497 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
13498 case EM_XC16X:
13499 case EM_C166:
13500 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
13501 case EM_XGATE:
13502 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
13503 case EM_Z80:
13504 return reloc_type == 4; /* R_Z80_16. */
4b78141a 13505 default:
aca88567 13506 return FALSE;
4b78141a
NC
13507 }
13508}
13509
39e07931
AS
13510/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13511 a 8-bit absolute RELA relocation used in DWARF debug sections. */
13512
13513static bfd_boolean
13514is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13515{
13516 switch (filedata->file_header.e_machine)
13517 {
13518 case EM_RISCV:
13519 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
13520 case EM_Z80:
13521 return reloc_type == 1; /* R_Z80_8. */
39e07931
AS
13522 default:
13523 return FALSE;
13524 }
13525}
13526
13527/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13528 a 6-bit absolute RELA relocation used in DWARF debug sections. */
13529
13530static bfd_boolean
13531is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13532{
13533 switch (filedata->file_header.e_machine)
13534 {
13535 case EM_RISCV:
13536 return reloc_type == 53; /* R_RISCV_SET6. */
13537 default:
13538 return FALSE;
13539 }
13540}
13541
03336641
JW
13542/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13543 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
13544
13545static bfd_boolean
13546is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13547{
13548 /* Please keep this table alpha-sorted for ease of visual lookup. */
13549 switch (filedata->file_header.e_machine)
13550 {
13551 case EM_RISCV:
13552 return reloc_type == 35; /* R_RISCV_ADD32. */
13553 default:
13554 return FALSE;
13555 }
13556}
13557
13558/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13559 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
13560
13561static bfd_boolean
13562is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13563{
13564 /* Please keep this table alpha-sorted for ease of visual lookup. */
13565 switch (filedata->file_header.e_machine)
13566 {
13567 case EM_RISCV:
13568 return reloc_type == 39; /* R_RISCV_SUB32. */
13569 default:
13570 return FALSE;
13571 }
13572}
13573
13574/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13575 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
13576
13577static bfd_boolean
13578is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13579{
13580 /* Please keep this table alpha-sorted for ease of visual lookup. */
13581 switch (filedata->file_header.e_machine)
13582 {
13583 case EM_RISCV:
13584 return reloc_type == 36; /* R_RISCV_ADD64. */
13585 default:
13586 return FALSE;
13587 }
13588}
13589
13590/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13591 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
13592
13593static bfd_boolean
13594is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13595{
13596 /* Please keep this table alpha-sorted for ease of visual lookup. */
13597 switch (filedata->file_header.e_machine)
13598 {
13599 case EM_RISCV:
13600 return reloc_type == 40; /* R_RISCV_SUB64. */
13601 default:
13602 return FALSE;
13603 }
13604}
13605
13606/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13607 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
13608
13609static bfd_boolean
13610is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13611{
13612 /* Please keep this table alpha-sorted for ease of visual lookup. */
13613 switch (filedata->file_header.e_machine)
13614 {
13615 case EM_RISCV:
13616 return reloc_type == 34; /* R_RISCV_ADD16. */
13617 default:
13618 return FALSE;
13619 }
13620}
13621
13622/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13623 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
13624
13625static bfd_boolean
13626is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13627{
13628 /* Please keep this table alpha-sorted for ease of visual lookup. */
13629 switch (filedata->file_header.e_machine)
13630 {
13631 case EM_RISCV:
13632 return reloc_type == 38; /* R_RISCV_SUB16. */
13633 default:
13634 return FALSE;
13635 }
13636}
13637
13638/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13639 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
13640
13641static bfd_boolean
13642is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13643{
13644 /* Please keep this table alpha-sorted for ease of visual lookup. */
13645 switch (filedata->file_header.e_machine)
13646 {
13647 case EM_RISCV:
13648 return reloc_type == 33; /* R_RISCV_ADD8. */
13649 default:
13650 return FALSE;
13651 }
13652}
13653
13654/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13655 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
13656
13657static bfd_boolean
13658is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13659{
13660 /* Please keep this table alpha-sorted for ease of visual lookup. */
13661 switch (filedata->file_header.e_machine)
13662 {
13663 case EM_RISCV:
13664 return reloc_type == 37; /* R_RISCV_SUB8. */
13665 default:
13666 return FALSE;
13667 }
13668}
13669
39e07931
AS
13670/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13671 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
13672
13673static bfd_boolean
13674is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13675{
13676 switch (filedata->file_header.e_machine)
13677 {
13678 case EM_RISCV:
13679 return reloc_type == 52; /* R_RISCV_SUB6. */
13680 default:
13681 return FALSE;
13682 }
13683}
13684
2a7b2e88
JK
13685/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
13686 relocation entries (possibly formerly used for SHT_GROUP sections). */
13687
13688static bfd_boolean
dda8d76d 13689is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 13690{
dda8d76d 13691 switch (filedata->file_header.e_machine)
2a7b2e88 13692 {
cb8f3167 13693 case EM_386: /* R_386_NONE. */
d347c9df 13694 case EM_68K: /* R_68K_NONE. */
cfb8c092 13695 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
13696 case EM_ALPHA: /* R_ALPHA_NONE. */
13697 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 13698 case EM_ARC: /* R_ARC_NONE. */
886a2506 13699 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 13700 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 13701 case EM_ARM: /* R_ARM_NONE. */
d347c9df 13702 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 13703 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
13704 case EM_FT32: /* R_FT32_NONE. */
13705 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 13706 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
13707 case EM_L1OM: /* R_X86_64_NONE. */
13708 case EM_M32R: /* R_M32R_NONE. */
13709 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 13710 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 13711 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
13712 case EM_NIOS32: /* R_NIOS_NONE. */
13713 case EM_OR1K: /* R_OR1K_NONE. */
13714 case EM_PARISC: /* R_PARISC_NONE. */
13715 case EM_PPC64: /* R_PPC64_NONE. */
13716 case EM_PPC: /* R_PPC_NONE. */
e23eba97 13717 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
13718 case EM_S390: /* R_390_NONE. */
13719 case EM_S390_OLD:
13720 case EM_SH: /* R_SH_NONE. */
13721 case EM_SPARC32PLUS:
13722 case EM_SPARC: /* R_SPARC_NONE. */
13723 case EM_SPARCV9:
aa137e4d
NC
13724 case EM_TILEGX: /* R_TILEGX_NONE. */
13725 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
13726 case EM_TI_C6000:/* R_C6000_NONE. */
13727 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 13728 case EM_XC16X:
6655dba2 13729 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 13730 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 13731 return reloc_type == 0;
d347c9df 13732
a06ea964
NC
13733 case EM_AARCH64:
13734 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
13735 case EM_AVR_OLD:
13736 case EM_AVR:
13737 return (reloc_type == 0 /* R_AVR_NONE. */
13738 || reloc_type == 30 /* R_AVR_DIFF8. */
13739 || reloc_type == 31 /* R_AVR_DIFF16. */
13740 || reloc_type == 32 /* R_AVR_DIFF32. */);
13741 case EM_METAG:
13742 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
13743 case EM_NDS32:
13744 return (reloc_type == 0 /* R_XTENSA_NONE. */
13745 || reloc_type == 204 /* R_NDS32_DIFF8. */
13746 || reloc_type == 205 /* R_NDS32_DIFF16. */
13747 || reloc_type == 206 /* R_NDS32_DIFF32. */
13748 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
13749 case EM_TI_PRU:
13750 return (reloc_type == 0 /* R_PRU_NONE. */
13751 || reloc_type == 65 /* R_PRU_DIFF8. */
13752 || reloc_type == 66 /* R_PRU_DIFF16. */
13753 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
13754 case EM_XTENSA_OLD:
13755 case EM_XTENSA:
4dc3c23d
AM
13756 return (reloc_type == 0 /* R_XTENSA_NONE. */
13757 || reloc_type == 17 /* R_XTENSA_DIFF8. */
13758 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
13759 || reloc_type == 19 /* R_XTENSA_DIFF32. */
13760 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
13761 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
13762 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
13763 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
13764 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
13765 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88
JK
13766 }
13767 return FALSE;
13768}
13769
d1c4b12b
NC
13770/* Returns TRUE if there is a relocation against
13771 section NAME at OFFSET bytes. */
13772
13773bfd_boolean
13774reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
13775{
13776 Elf_Internal_Rela * relocs;
13777 Elf_Internal_Rela * rp;
13778
13779 if (dsec == NULL || dsec->reloc_info == NULL)
13780 return FALSE;
13781
13782 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
13783
13784 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
13785 if (rp->r_offset == offset)
13786 return TRUE;
13787
13788 return FALSE;
13789}
13790
cf13d699 13791/* Apply relocations to a section.
32ec8896
NC
13792 Returns TRUE upon success, FALSE otherwise.
13793 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
13794 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
13795 will be set to the number of relocs loaded.
13796
cf13d699 13797 Note: So far support has been added only for those relocations
32ec8896
NC
13798 which can be found in debug sections. FIXME: Add support for
13799 more relocations ? */
1b315056 13800
32ec8896 13801static bfd_boolean
dda8d76d 13802apply_relocations (Filedata * filedata,
d1c4b12b
NC
13803 const Elf_Internal_Shdr * section,
13804 unsigned char * start,
13805 bfd_size_type size,
1449284b 13806 void ** relocs_return,
d1c4b12b 13807 unsigned long * num_relocs_return)
1b315056 13808{
cf13d699 13809 Elf_Internal_Shdr * relsec;
0d2a7a93 13810 unsigned char * end = start + size;
cb8f3167 13811
d1c4b12b
NC
13812 if (relocs_return != NULL)
13813 {
13814 * (Elf_Internal_Rela **) relocs_return = NULL;
13815 * num_relocs_return = 0;
13816 }
13817
dda8d76d 13818 if (filedata->file_header.e_type != ET_REL)
32ec8896
NC
13819 /* No relocs to apply. */
13820 return TRUE;
1b315056 13821
cf13d699 13822 /* Find the reloc section associated with the section. */
dda8d76d
NC
13823 for (relsec = filedata->section_headers;
13824 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 13825 ++relsec)
252b5132 13826 {
41e92641
NC
13827 bfd_boolean is_rela;
13828 unsigned long num_relocs;
2cf0635d
NC
13829 Elf_Internal_Rela * relocs;
13830 Elf_Internal_Rela * rp;
13831 Elf_Internal_Shdr * symsec;
13832 Elf_Internal_Sym * symtab;
ba5cdace 13833 unsigned long num_syms;
2cf0635d 13834 Elf_Internal_Sym * sym;
252b5132 13835
41e92641 13836 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13837 || relsec->sh_info >= filedata->file_header.e_shnum
13838 || filedata->section_headers + relsec->sh_info != section
c256ffe7 13839 || relsec->sh_size == 0
dda8d76d 13840 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 13841 continue;
428409d5 13842
a788aedd
AM
13843 symsec = filedata->section_headers + relsec->sh_link;
13844 if (symsec->sh_type != SHT_SYMTAB
13845 && symsec->sh_type != SHT_DYNSYM)
13846 return FALSE;
13847
41e92641
NC
13848 is_rela = relsec->sh_type == SHT_RELA;
13849
13850 if (is_rela)
13851 {
dda8d76d 13852 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 13853 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13854 return FALSE;
41e92641
NC
13855 }
13856 else
13857 {
dda8d76d 13858 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 13859 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13860 return FALSE;
41e92641
NC
13861 }
13862
13863 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 13864 if (filedata->file_header.e_machine == EM_SH)
41e92641 13865 is_rela = FALSE;
428409d5 13866
dda8d76d 13867 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 13868
41e92641 13869 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 13870 {
41e92641
NC
13871 bfd_vma addend;
13872 unsigned int reloc_type;
13873 unsigned int reloc_size;
03336641
JW
13874 bfd_boolean reloc_inplace = FALSE;
13875 bfd_boolean reloc_subtract = FALSE;
91d6fa6a 13876 unsigned char * rloc;
ba5cdace 13877 unsigned long sym_index;
4b78141a 13878
dda8d76d 13879 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 13880
dda8d76d 13881 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 13882 continue;
dda8d76d 13883 else if (is_none_reloc (filedata, reloc_type))
98fb390a 13884 continue;
dda8d76d
NC
13885 else if (is_32bit_abs_reloc (filedata, reloc_type)
13886 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 13887 reloc_size = 4;
dda8d76d
NC
13888 else if (is_64bit_abs_reloc (filedata, reloc_type)
13889 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 13890 reloc_size = 8;
dda8d76d 13891 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 13892 reloc_size = 3;
dda8d76d 13893 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 13894 reloc_size = 2;
39e07931
AS
13895 else if (is_8bit_abs_reloc (filedata, reloc_type)
13896 || is_6bit_abs_reloc (filedata, reloc_type))
13897 reloc_size = 1;
03336641
JW
13898 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
13899 reloc_type))
13900 || is_32bit_inplace_add_reloc (filedata, reloc_type))
13901 {
13902 reloc_size = 4;
13903 reloc_inplace = TRUE;
13904 }
13905 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
13906 reloc_type))
13907 || is_64bit_inplace_add_reloc (filedata, reloc_type))
13908 {
13909 reloc_size = 8;
13910 reloc_inplace = TRUE;
13911 }
13912 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
13913 reloc_type))
13914 || is_16bit_inplace_add_reloc (filedata, reloc_type))
13915 {
13916 reloc_size = 2;
13917 reloc_inplace = TRUE;
13918 }
13919 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
13920 reloc_type))
13921 || is_8bit_inplace_add_reloc (filedata, reloc_type))
13922 {
13923 reloc_size = 1;
13924 reloc_inplace = TRUE;
13925 }
39e07931
AS
13926 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
13927 reloc_type)))
13928 {
13929 reloc_size = 1;
13930 reloc_inplace = TRUE;
13931 }
aca88567 13932 else
4b78141a 13933 {
bee0ee85 13934 static unsigned int prev_reloc = 0;
dda8d76d 13935
bee0ee85
NC
13936 if (reloc_type != prev_reloc)
13937 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 13938 reloc_type, printable_section_name (filedata, section));
bee0ee85 13939 prev_reloc = reloc_type;
4b78141a
NC
13940 continue;
13941 }
103f02d3 13942
91d6fa6a 13943 rloc = start + rp->r_offset;
75802ccb 13944 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
13945 {
13946 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
13947 (unsigned long) rp->r_offset,
dda8d76d 13948 printable_section_name (filedata, section));
700dd8b7
L
13949 continue;
13950 }
103f02d3 13951
ba5cdace
NC
13952 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
13953 if (sym_index >= num_syms)
13954 {
13955 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 13956 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
13957 continue;
13958 }
13959 sym = symtab + sym_index;
41e92641
NC
13960
13961 /* If the reloc has a symbol associated with it,
55f25fc3
L
13962 make sure that it is of an appropriate type.
13963
13964 Relocations against symbols without type can happen.
13965 Gcc -feliminate-dwarf2-dups may generate symbols
13966 without type for debug info.
13967
13968 Icc generates relocations against function symbols
13969 instead of local labels.
13970
13971 Relocations against object symbols can happen, eg when
13972 referencing a global array. For an example of this see
13973 the _clz.o binary in libgcc.a. */
aca88567 13974 if (sym != symtab
b8871f35 13975 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 13976 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 13977 {
d3a49aa8 13978 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
13979 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
13980 printable_section_name (filedata, relsec),
d3a49aa8 13981 (long int)(rp - relocs));
aca88567 13982 continue;
5b18a4bc 13983 }
252b5132 13984
4dc3c23d
AM
13985 addend = 0;
13986 if (is_rela)
13987 addend += rp->r_addend;
c47320c3
AM
13988 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
13989 partial_inplace. */
4dc3c23d 13990 if (!is_rela
dda8d76d 13991 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 13992 && reloc_type == 1)
dda8d76d
NC
13993 || ((filedata->file_header.e_machine == EM_PJ
13994 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 13995 && reloc_type == 1)
dda8d76d
NC
13996 || ((filedata->file_header.e_machine == EM_D30V
13997 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
13998 && reloc_type == 12)
13999 || reloc_inplace)
39e07931
AS
14000 {
14001 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
14002 addend += byte_get (rloc, reloc_size) & 0x3f;
14003 else
14004 addend += byte_get (rloc, reloc_size);
14005 }
cb8f3167 14006
dda8d76d
NC
14007 if (is_32bit_pcrel_reloc (filedata, reloc_type)
14008 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
14009 {
14010 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 14011 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 14012 addend -= 8;
91d6fa6a 14013 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
14014 reloc_size);
14015 }
39e07931
AS
14016 else if (is_6bit_abs_reloc (filedata, reloc_type)
14017 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
14018 {
14019 if (reloc_subtract)
14020 addend -= sym->st_value;
14021 else
14022 addend += sym->st_value;
14023 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
14024 byte_put (rloc, addend, reloc_size);
14025 }
03336641
JW
14026 else if (reloc_subtract)
14027 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 14028 else
91d6fa6a 14029 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 14030 }
252b5132 14031
5b18a4bc 14032 free (symtab);
f84ce13b
NC
14033 /* Let the target specific reloc processing code know that
14034 we have finished with these relocs. */
dda8d76d 14035 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
14036
14037 if (relocs_return)
14038 {
14039 * (Elf_Internal_Rela **) relocs_return = relocs;
14040 * num_relocs_return = num_relocs;
14041 }
14042 else
14043 free (relocs);
14044
5b18a4bc
NC
14045 break;
14046 }
32ec8896 14047
dfc616fa 14048 return TRUE;
5b18a4bc 14049}
103f02d3 14050
cf13d699 14051#ifdef SUPPORT_DISASSEMBLY
32ec8896 14052static bfd_boolean
dda8d76d 14053disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14054{
dda8d76d 14055 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 14056
74e1a04b 14057 /* FIXME: XXX -- to be done --- XXX */
cf13d699 14058
32ec8896 14059 return TRUE;
cf13d699
NC
14060}
14061#endif
14062
14063/* Reads in the contents of SECTION from FILE, returning a pointer
14064 to a malloc'ed buffer or NULL if something went wrong. */
14065
14066static char *
dda8d76d 14067get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14068{
dda8d76d 14069 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
14070
14071 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
14072 {
c6b78c96 14073 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 14074 printable_section_name (filedata, section));
cf13d699
NC
14075 return NULL;
14076 }
14077
dda8d76d 14078 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 14079 _("section contents"));
cf13d699
NC
14080}
14081
0e602686
NC
14082/* Uncompresses a section that was compressed using zlib, in place. */
14083
14084static bfd_boolean
dda8d76d
NC
14085uncompress_section_contents (unsigned char ** buffer,
14086 dwarf_size_type uncompressed_size,
14087 dwarf_size_type * size)
0e602686
NC
14088{
14089 dwarf_size_type compressed_size = *size;
14090 unsigned char * compressed_buffer = *buffer;
14091 unsigned char * uncompressed_buffer;
14092 z_stream strm;
14093 int rc;
14094
14095 /* It is possible the section consists of several compressed
14096 buffers concatenated together, so we uncompress in a loop. */
14097 /* PR 18313: The state field in the z_stream structure is supposed
14098 to be invisible to the user (ie us), but some compilers will
14099 still complain about it being used without initialisation. So
14100 we first zero the entire z_stream structure and then set the fields
14101 that we need. */
14102 memset (& strm, 0, sizeof strm);
14103 strm.avail_in = compressed_size;
14104 strm.next_in = (Bytef *) compressed_buffer;
14105 strm.avail_out = uncompressed_size;
14106 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
14107
14108 rc = inflateInit (& strm);
14109 while (strm.avail_in > 0)
14110 {
14111 if (rc != Z_OK)
14112 goto fail;
14113 strm.next_out = ((Bytef *) uncompressed_buffer
14114 + (uncompressed_size - strm.avail_out));
14115 rc = inflate (&strm, Z_FINISH);
14116 if (rc != Z_STREAM_END)
14117 goto fail;
14118 rc = inflateReset (& strm);
14119 }
14120 rc = inflateEnd (& strm);
14121 if (rc != Z_OK
14122 || strm.avail_out != 0)
14123 goto fail;
14124
14125 *buffer = uncompressed_buffer;
14126 *size = uncompressed_size;
14127 return TRUE;
14128
14129 fail:
14130 free (uncompressed_buffer);
14131 /* Indicate decompression failure. */
14132 *buffer = NULL;
14133 return FALSE;
14134}
dd24e3da 14135
32ec8896 14136static bfd_boolean
dda8d76d 14137dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14138{
0e602686
NC
14139 Elf_Internal_Shdr * relsec;
14140 bfd_size_type num_bytes;
fd8008d8
L
14141 unsigned char * data;
14142 unsigned char * end;
14143 unsigned char * real_start;
14144 unsigned char * start;
0e602686 14145 bfd_boolean some_strings_shown;
cf13d699 14146
dda8d76d 14147 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14148 if (start == NULL)
c6b78c96
NC
14149 /* PR 21820: Do not fail if the section was empty. */
14150 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
14151
0e602686 14152 num_bytes = section->sh_size;
cf13d699 14153
dda8d76d 14154 printf (_("\nString dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 14155
0e602686
NC
14156 if (decompress_dumps)
14157 {
14158 dwarf_size_type new_size = num_bytes;
14159 dwarf_size_type uncompressed_size = 0;
14160
14161 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14162 {
14163 Elf_Internal_Chdr chdr;
14164 unsigned int compression_header_size
ebdf1ebf
NC
14165 = get_compression_header (& chdr, (unsigned char *) start,
14166 num_bytes);
5844b465
NC
14167 if (compression_header_size == 0)
14168 /* An error message will have already been generated
14169 by get_compression_header. */
14170 goto error_out;
0e602686 14171
813dabb9 14172 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14173 {
813dabb9 14174 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14175 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14176 goto error_out;
813dabb9 14177 }
813dabb9
L
14178 uncompressed_size = chdr.ch_size;
14179 start += compression_header_size;
14180 new_size -= compression_header_size;
0e602686
NC
14181 }
14182 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14183 {
14184 /* Read the zlib header. In this case, it should be "ZLIB"
14185 followed by the uncompressed section size, 8 bytes in
14186 big-endian order. */
14187 uncompressed_size = start[4]; uncompressed_size <<= 8;
14188 uncompressed_size += start[5]; uncompressed_size <<= 8;
14189 uncompressed_size += start[6]; uncompressed_size <<= 8;
14190 uncompressed_size += start[7]; uncompressed_size <<= 8;
14191 uncompressed_size += start[8]; uncompressed_size <<= 8;
14192 uncompressed_size += start[9]; uncompressed_size <<= 8;
14193 uncompressed_size += start[10]; uncompressed_size <<= 8;
14194 uncompressed_size += start[11];
14195 start += 12;
14196 new_size -= 12;
14197 }
14198
1835f746
NC
14199 if (uncompressed_size)
14200 {
14201 if (uncompress_section_contents (& start,
14202 uncompressed_size, & new_size))
14203 num_bytes = new_size;
14204 else
14205 {
14206 error (_("Unable to decompress section %s\n"),
dda8d76d 14207 printable_section_name (filedata, section));
f761cb13 14208 goto error_out;
1835f746
NC
14209 }
14210 }
bc303e5d
NC
14211 else
14212 start = real_start;
0e602686 14213 }
fd8008d8 14214
cf13d699
NC
14215 /* If the section being dumped has relocations against it the user might
14216 be expecting these relocations to have been applied. Check for this
14217 case and issue a warning message in order to avoid confusion.
14218 FIXME: Maybe we ought to have an option that dumps a section with
14219 relocs applied ? */
dda8d76d
NC
14220 for (relsec = filedata->section_headers;
14221 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14222 ++relsec)
14223 {
14224 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14225 || relsec->sh_info >= filedata->file_header.e_shnum
14226 || filedata->section_headers + relsec->sh_info != section
cf13d699 14227 || relsec->sh_size == 0
dda8d76d 14228 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14229 continue;
14230
14231 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14232 break;
14233 }
14234
cf13d699
NC
14235 data = start;
14236 end = start + num_bytes;
14237 some_strings_shown = FALSE;
14238
ba3265d0
NC
14239#ifdef HAVE_MBSTATE_T
14240 mbstate_t state;
14241 /* Initialise the multibyte conversion state. */
14242 memset (& state, 0, sizeof (state));
14243#endif
14244
14245 bfd_boolean continuing = FALSE;
14246
cf13d699
NC
14247 while (data < end)
14248 {
14249 while (!ISPRINT (* data))
14250 if (++ data >= end)
14251 break;
14252
14253 if (data < end)
14254 {
071436c6
NC
14255 size_t maxlen = end - data;
14256
ba3265d0
NC
14257 if (continuing)
14258 {
14259 printf (" ");
14260 continuing = FALSE;
14261 }
14262 else
14263 {
d1ce973e 14264 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
14265 }
14266
4082ef84
NC
14267 if (maxlen > 0)
14268 {
f3da8a96 14269 char c = 0;
ba3265d0
NC
14270
14271 while (maxlen)
14272 {
14273 c = *data++;
14274
14275 if (c == 0)
14276 break;
14277
14278 /* PR 25543: Treat new-lines as string-ending characters. */
14279 if (c == '\n')
14280 {
14281 printf ("\\n\n");
14282 if (*data != 0)
14283 continuing = TRUE;
14284 break;
14285 }
14286
14287 /* Do not print control characters directly as they can affect terminal
14288 settings. Such characters usually appear in the names generated
14289 by the assembler for local labels. */
14290 if (ISCNTRL (c))
14291 {
14292 printf ("^%c", c + 0x40);
14293 }
14294 else if (ISPRINT (c))
14295 {
14296 putchar (c);
14297 }
14298 else
14299 {
14300 size_t n;
14301#ifdef HAVE_MBSTATE_T
14302 wchar_t w;
14303#endif
14304 /* Let printf do the hard work of displaying multibyte characters. */
14305 printf ("%.1s", data - 1);
14306#ifdef HAVE_MBSTATE_T
14307 /* Try to find out how many bytes made up the character that was
14308 just printed. Advance the symbol pointer past the bytes that
14309 were displayed. */
14310 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
14311#else
14312 n = 1;
14313#endif
14314 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
14315 data += (n - 1);
14316 }
14317 }
14318
14319 if (c != '\n')
14320 putchar ('\n');
4082ef84
NC
14321 }
14322 else
14323 {
14324 printf (_("<corrupt>\n"));
14325 data = end;
14326 }
cf13d699
NC
14327 some_strings_shown = TRUE;
14328 }
14329 }
14330
14331 if (! some_strings_shown)
14332 printf (_(" No strings found in this section."));
14333
0e602686 14334 free (real_start);
cf13d699
NC
14335
14336 putchar ('\n');
32ec8896 14337 return TRUE;
f761cb13
AM
14338
14339error_out:
14340 free (real_start);
14341 return FALSE;
cf13d699
NC
14342}
14343
32ec8896 14344static bfd_boolean
dda8d76d
NC
14345dump_section_as_bytes (Elf_Internal_Shdr * section,
14346 Filedata * filedata,
14347 bfd_boolean relocate)
cf13d699
NC
14348{
14349 Elf_Internal_Shdr * relsec;
0e602686
NC
14350 bfd_size_type bytes;
14351 bfd_size_type section_size;
14352 bfd_vma addr;
14353 unsigned char * data;
14354 unsigned char * real_start;
14355 unsigned char * start;
14356
dda8d76d 14357 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14358 if (start == NULL)
c6b78c96
NC
14359 /* PR 21820: Do not fail if the section was empty. */
14360 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
32ec8896 14361
0e602686 14362 section_size = section->sh_size;
cf13d699 14363
dda8d76d 14364 printf (_("\nHex dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 14365
0e602686
NC
14366 if (decompress_dumps)
14367 {
14368 dwarf_size_type new_size = section_size;
14369 dwarf_size_type uncompressed_size = 0;
14370
14371 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14372 {
14373 Elf_Internal_Chdr chdr;
14374 unsigned int compression_header_size
ebdf1ebf 14375 = get_compression_header (& chdr, start, section_size);
0e602686 14376
5844b465
NC
14377 if (compression_header_size == 0)
14378 /* An error message will have already been generated
14379 by get_compression_header. */
14380 goto error_out;
14381
813dabb9 14382 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14383 {
813dabb9 14384 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14385 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14386 goto error_out;
0e602686 14387 }
813dabb9
L
14388 uncompressed_size = chdr.ch_size;
14389 start += compression_header_size;
14390 new_size -= compression_header_size;
0e602686
NC
14391 }
14392 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14393 {
14394 /* Read the zlib header. In this case, it should be "ZLIB"
14395 followed by the uncompressed section size, 8 bytes in
14396 big-endian order. */
14397 uncompressed_size = start[4]; uncompressed_size <<= 8;
14398 uncompressed_size += start[5]; uncompressed_size <<= 8;
14399 uncompressed_size += start[6]; uncompressed_size <<= 8;
14400 uncompressed_size += start[7]; uncompressed_size <<= 8;
14401 uncompressed_size += start[8]; uncompressed_size <<= 8;
14402 uncompressed_size += start[9]; uncompressed_size <<= 8;
14403 uncompressed_size += start[10]; uncompressed_size <<= 8;
14404 uncompressed_size += start[11];
14405 start += 12;
14406 new_size -= 12;
14407 }
14408
f055032e
NC
14409 if (uncompressed_size)
14410 {
14411 if (uncompress_section_contents (& start, uncompressed_size,
14412 & new_size))
bc303e5d
NC
14413 {
14414 section_size = new_size;
14415 }
f055032e
NC
14416 else
14417 {
14418 error (_("Unable to decompress section %s\n"),
dda8d76d 14419 printable_section_name (filedata, section));
bc303e5d 14420 /* FIXME: Print the section anyway ? */
f761cb13 14421 goto error_out;
f055032e
NC
14422 }
14423 }
bc303e5d
NC
14424 else
14425 start = real_start;
0e602686 14426 }
14ae95f2 14427
cf13d699
NC
14428 if (relocate)
14429 {
dda8d76d 14430 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 14431 goto error_out;
cf13d699
NC
14432 }
14433 else
14434 {
14435 /* If the section being dumped has relocations against it the user might
14436 be expecting these relocations to have been applied. Check for this
14437 case and issue a warning message in order to avoid confusion.
14438 FIXME: Maybe we ought to have an option that dumps a section with
14439 relocs applied ? */
dda8d76d
NC
14440 for (relsec = filedata->section_headers;
14441 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14442 ++relsec)
14443 {
14444 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14445 || relsec->sh_info >= filedata->file_header.e_shnum
14446 || filedata->section_headers + relsec->sh_info != section
cf13d699 14447 || relsec->sh_size == 0
dda8d76d 14448 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14449 continue;
14450
14451 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14452 break;
14453 }
14454 }
14455
14456 addr = section->sh_addr;
0e602686 14457 bytes = section_size;
cf13d699
NC
14458 data = start;
14459
14460 while (bytes)
14461 {
14462 int j;
14463 int k;
14464 int lbytes;
14465
14466 lbytes = (bytes > 16 ? 16 : bytes);
14467
14468 printf (" 0x%8.8lx ", (unsigned long) addr);
14469
14470 for (j = 0; j < 16; j++)
14471 {
14472 if (j < lbytes)
14473 printf ("%2.2x", data[j]);
14474 else
14475 printf (" ");
14476
14477 if ((j & 3) == 3)
14478 printf (" ");
14479 }
14480
14481 for (j = 0; j < lbytes; j++)
14482 {
14483 k = data[j];
14484 if (k >= ' ' && k < 0x7f)
14485 printf ("%c", k);
14486 else
14487 printf (".");
14488 }
14489
14490 putchar ('\n');
14491
14492 data += lbytes;
14493 addr += lbytes;
14494 bytes -= lbytes;
14495 }
14496
0e602686 14497 free (real_start);
cf13d699
NC
14498
14499 putchar ('\n');
32ec8896 14500 return TRUE;
f761cb13
AM
14501
14502 error_out:
14503 free (real_start);
14504 return FALSE;
cf13d699
NC
14505}
14506
094e34f2 14507#ifdef ENABLE_LIBCTF
7d9813f1
NA
14508static ctf_sect_t *
14509shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
14510{
90bd5423 14511 buf->cts_name = SECTION_NAME (shdr);
7d9813f1
NA
14512 buf->cts_size = shdr->sh_size;
14513 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
14514
14515 return buf;
14516}
14517
14518/* Formatting callback function passed to ctf_dump. Returns either the pointer
14519 it is passed, or a pointer to newly-allocated storage, in which case
14520 dump_ctf() will free it when it no longer needs it. */
14521
2f6ecaed
NA
14522static char *
14523dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14524 char *s, void *arg)
7d9813f1 14525{
3e50a591 14526 const char *blanks = arg;
7d9813f1
NA
14527 char *new_s;
14528
3e50a591 14529 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
14530 return s;
14531 return new_s;
14532}
14533
926c9e76
NA
14534/* Dump CTF errors/warnings. */
14535static void
14536dump_ctf_errs (ctf_file_t *fp)
14537{
14538 ctf_next_t *it = NULL;
14539 char *errtext;
14540 int is_warning;
14541 int err;
14542
14543 /* Dump accumulated errors and warnings. */
14544 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
14545 {
5e9b84f7 14546 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
14547 errtext);
14548 free (errtext);
14549 }
14550 if (err != ECTF_NEXT_END)
14551 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
14552}
14553
2f6ecaed
NA
14554/* Dump one CTF archive member. */
14555
14556static int
14557dump_ctf_archive_member (ctf_file_t *ctf, const char *name, void *arg)
14558{
14559 ctf_file_t *parent = (ctf_file_t *) arg;
14560 const char *things[] = {"Header", "Labels", "Data objects",
14561 "Function objects", "Variables", "Types", "Strings",
14562 ""};
14563 const char **thing;
14564 size_t i;
8b37e7b6 14565 int err = 0;
2f6ecaed
NA
14566
14567 /* Only print out the name of non-default-named archive members.
14568 The name .ctf appears everywhere, even for things that aren't
14569 really archives, so printing it out is liable to be confusing.
14570
14571 The parent, if there is one, is the default-owned archive member:
14572 avoid importing it into itself. (This does no harm, but looks
14573 confusing.) */
14574
14575 if (strcmp (name, ".ctf") != 0)
14576 {
14577 printf (_("\nCTF archive member: %s:\n"), name);
14578 ctf_import (ctf, parent);
14579 }
14580
14581 for (i = 0, thing = things; *thing[0]; thing++, i++)
14582 {
14583 ctf_dump_state_t *s = NULL;
14584 char *item;
14585
14586 printf ("\n %s:\n", *thing);
14587 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
14588 (void *) " ")) != NULL)
14589 {
14590 printf ("%s\n", item);
14591 free (item);
14592 }
14593
14594 if (ctf_errno (ctf))
14595 {
14596 error (_("Iteration failed: %s, %s\n"), *thing,
14597 ctf_errmsg (ctf_errno (ctf)));
8b37e7b6
NA
14598 err = 1;
14599 goto out;
2f6ecaed
NA
14600 }
14601 }
8b37e7b6
NA
14602
14603 out:
926c9e76 14604 dump_ctf_errs (ctf);
8b37e7b6 14605 return err;
2f6ecaed
NA
14606}
14607
7d9813f1
NA
14608static bfd_boolean
14609dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
14610{
14611 Elf_Internal_Shdr * parent_sec = NULL;
14612 Elf_Internal_Shdr * symtab_sec = NULL;
14613 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
14614 void * data = NULL;
14615 void * symdata = NULL;
14616 void * strdata = NULL;
14617 void * parentdata = NULL;
14618 ctf_sect_t ctfsect, symsect, strsect, parentsect;
14619 ctf_sect_t * symsectp = NULL;
14620 ctf_sect_t * strsectp = NULL;
2f6ecaed
NA
14621 ctf_archive_t * ctfa = NULL;
14622 ctf_archive_t * parenta = NULL, *lookparent;
14623 ctf_file_t * parent = NULL;
7d9813f1 14624
7d9813f1
NA
14625 int err;
14626 bfd_boolean ret = FALSE;
7d9813f1
NA
14627
14628 shdr_to_ctf_sect (&ctfsect, section, filedata);
14629 data = get_section_contents (section, filedata);
14630 ctfsect.cts_data = data;
14631
616febde
NA
14632 if (!dump_ctf_symtab_name)
14633 dump_ctf_symtab_name = strdup (".symtab");
14634
14635 if (!dump_ctf_strtab_name)
14636 dump_ctf_strtab_name = strdup (".strtab");
14637
14638 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
14639 {
14640 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
14641 {
14642 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
14643 goto fail;
14644 }
14645 if ((symdata = (void *) get_data (NULL, filedata,
14646 symtab_sec->sh_offset, 1,
14647 symtab_sec->sh_size,
14648 _("symbols"))) == NULL)
14649 goto fail;
14650 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
14651 symsect.cts_data = symdata;
14652 }
df16e041 14653 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
14654 {
14655 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
14656 {
14657 error (_("No string table section named %s\n"),
14658 dump_ctf_strtab_name);
14659 goto fail;
14660 }
14661 if ((strdata = (void *) get_data (NULL, filedata,
14662 strtab_sec->sh_offset, 1,
14663 strtab_sec->sh_size,
14664 _("strings"))) == NULL)
14665 goto fail;
14666 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
14667 strsect.cts_data = strdata;
14668 }
14669 if (dump_ctf_parent_name)
14670 {
14671 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
14672 {
14673 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
14674 goto fail;
14675 }
14676 if ((parentdata = (void *) get_data (NULL, filedata,
14677 parent_sec->sh_offset, 1,
14678 parent_sec->sh_size,
14679 _("CTF parent"))) == NULL)
14680 goto fail;
14681 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
14682 parentsect.cts_data = parentdata;
14683 }
14684
2f6ecaed
NA
14685 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
14686 libctf papers over the difference, so we can pretend it is always an
14687 archive. Possibly open the parent as well, if one was specified. */
7d9813f1 14688
2f6ecaed 14689 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 14690 {
926c9e76 14691 dump_ctf_errs (NULL);
7d9813f1
NA
14692 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14693 goto fail;
14694 }
14695
14696 if (parentdata)
14697 {
2f6ecaed
NA
14698 if ((parenta = ctf_arc_bufopen (&parentsect, symsectp, strsectp,
14699 &err)) == NULL)
7d9813f1 14700 {
926c9e76 14701 dump_ctf_errs (NULL);
7d9813f1
NA
14702 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14703 goto fail;
14704 }
2f6ecaed
NA
14705 lookparent = parenta;
14706 }
14707 else
14708 lookparent = ctfa;
7d9813f1 14709
2f6ecaed
NA
14710 /* Assume that the applicable parent archive member is the default one.
14711 (This is what all known implementations are expected to do, if they
14712 put CTFs and their parents in archives together.) */
14713 if ((parent = ctf_arc_open_by_name (lookparent, NULL, &err)) == NULL)
14714 {
926c9e76 14715 dump_ctf_errs (NULL);
2f6ecaed
NA
14716 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14717 goto fail;
7d9813f1
NA
14718 }
14719
14720 ret = TRUE;
14721
14722 printf (_("\nDump of CTF section '%s':\n"),
14723 printable_section_name (filedata, section));
14724
2f6ecaed
NA
14725 if (ctf_archive_iter (ctfa, dump_ctf_archive_member, parent) != 0)
14726 ret = FALSE;
7d9813f1
NA
14727
14728 fail:
7d9813f1 14729 ctf_file_close (parent);
2f6ecaed
NA
14730 ctf_close (ctfa);
14731 ctf_close (parenta);
7d9813f1
NA
14732 free (parentdata);
14733 free (data);
14734 free (symdata);
14735 free (strdata);
14736 return ret;
14737}
094e34f2 14738#endif
7d9813f1 14739
32ec8896 14740static bfd_boolean
dda8d76d
NC
14741load_specific_debug_section (enum dwarf_section_display_enum debug,
14742 const Elf_Internal_Shdr * sec,
14743 void * data)
1007acb3 14744{
2cf0635d 14745 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 14746 char buf [64];
dda8d76d 14747 Filedata * filedata = (Filedata *) data;
9abca702 14748
19e6b90e 14749 if (section->start != NULL)
dda8d76d
NC
14750 {
14751 /* If it is already loaded, do nothing. */
14752 if (streq (section->filename, filedata->file_name))
14753 return TRUE;
14754 free (section->start);
14755 }
1007acb3 14756
19e6b90e
L
14757 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
14758 section->address = sec->sh_addr;
06614111 14759 section->user_data = NULL;
dda8d76d
NC
14760 section->filename = filedata->file_name;
14761 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
14762 sec->sh_offset, 1,
14763 sec->sh_size, buf);
59245841
NC
14764 if (section->start == NULL)
14765 section->size = 0;
14766 else
14767 {
77115a4a
L
14768 unsigned char *start = section->start;
14769 dwarf_size_type size = sec->sh_size;
dab394de 14770 dwarf_size_type uncompressed_size = 0;
77115a4a
L
14771
14772 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
14773 {
14774 Elf_Internal_Chdr chdr;
d8024a91
NC
14775 unsigned int compression_header_size;
14776
f53be977
L
14777 if (size < (is_32bit_elf
14778 ? sizeof (Elf32_External_Chdr)
14779 : sizeof (Elf64_External_Chdr)))
d8024a91 14780 {
55be8fd0 14781 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 14782 section->name);
32ec8896 14783 return FALSE;
d8024a91
NC
14784 }
14785
ebdf1ebf 14786 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
14787 if (compression_header_size == 0)
14788 /* An error message will have already been generated
14789 by get_compression_header. */
14790 return FALSE;
d8024a91 14791
813dabb9
L
14792 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
14793 {
14794 warn (_("section '%s' has unsupported compress type: %d\n"),
14795 section->name, chdr.ch_type);
32ec8896 14796 return FALSE;
813dabb9 14797 }
dab394de 14798 uncompressed_size = chdr.ch_size;
77115a4a
L
14799 start += compression_header_size;
14800 size -= compression_header_size;
14801 }
dab394de
L
14802 else if (size > 12 && streq ((char *) start, "ZLIB"))
14803 {
14804 /* Read the zlib header. In this case, it should be "ZLIB"
14805 followed by the uncompressed section size, 8 bytes in
14806 big-endian order. */
14807 uncompressed_size = start[4]; uncompressed_size <<= 8;
14808 uncompressed_size += start[5]; uncompressed_size <<= 8;
14809 uncompressed_size += start[6]; uncompressed_size <<= 8;
14810 uncompressed_size += start[7]; uncompressed_size <<= 8;
14811 uncompressed_size += start[8]; uncompressed_size <<= 8;
14812 uncompressed_size += start[9]; uncompressed_size <<= 8;
14813 uncompressed_size += start[10]; uncompressed_size <<= 8;
14814 uncompressed_size += start[11];
14815 start += 12;
14816 size -= 12;
14817 }
14818
1835f746 14819 if (uncompressed_size)
77115a4a 14820 {
1835f746
NC
14821 if (uncompress_section_contents (&start, uncompressed_size,
14822 &size))
14823 {
14824 /* Free the compressed buffer, update the section buffer
14825 and the section size if uncompress is successful. */
14826 free (section->start);
14827 section->start = start;
14828 }
14829 else
14830 {
14831 error (_("Unable to decompress section %s\n"),
dda8d76d 14832 printable_section_name (filedata, sec));
32ec8896 14833 return FALSE;
1835f746 14834 }
77115a4a 14835 }
bc303e5d 14836
77115a4a 14837 section->size = size;
59245841 14838 }
4a114e3e 14839
1b315056 14840 if (section->start == NULL)
32ec8896 14841 return FALSE;
1b315056 14842
19e6b90e 14843 if (debug_displays [debug].relocate)
32ec8896 14844 {
dda8d76d 14845 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896
NC
14846 & section->reloc_info, & section->num_relocs))
14847 return FALSE;
14848 }
d1c4b12b
NC
14849 else
14850 {
14851 section->reloc_info = NULL;
14852 section->num_relocs = 0;
14853 }
1007acb3 14854
32ec8896 14855 return TRUE;
1007acb3
L
14856}
14857
301a9420
AM
14858#if HAVE_LIBDEBUGINFOD
14859/* Return a hex string representation of the build-id. */
14860unsigned char *
14861get_build_id (void * data)
14862{
14863 Filedata * filedata = (Filedata *)data;
14864 Elf_Internal_Shdr * shdr;
14865 unsigned long i;
14866
55be8fd0
NC
14867 /* Iterate through notes to find note.gnu.build-id.
14868 FIXME: Only the first note in any note section is examined. */
301a9420
AM
14869 for (i = 0, shdr = filedata->section_headers;
14870 i < filedata->file_header.e_shnum && shdr != NULL;
14871 i++, shdr++)
14872 {
14873 if (shdr->sh_type != SHT_NOTE)
14874 continue;
14875
14876 char * next;
14877 char * end;
14878 size_t data_remaining;
14879 size_t min_notesz;
14880 Elf_External_Note * enote;
14881 Elf_Internal_Note inote;
14882
14883 bfd_vma offset = shdr->sh_offset;
14884 bfd_vma align = shdr->sh_addralign;
14885 bfd_vma length = shdr->sh_size;
14886
14887 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
14888 if (enote == NULL)
14889 continue;
14890
14891 if (align < 4)
14892 align = 4;
14893 else if (align != 4 && align != 8)
f761cb13
AM
14894 {
14895 free (enote);
14896 continue;
14897 }
301a9420
AM
14898
14899 end = (char *) enote + length;
14900 data_remaining = end - (char *) enote;
14901
14902 if (!is_ia64_vms (filedata))
14903 {
14904 min_notesz = offsetof (Elf_External_Note, name);
14905 if (data_remaining < min_notesz)
14906 {
55be8fd0
NC
14907 warn (_("\
14908malformed note encountered in section %s whilst scanning for build-id note\n"),
14909 printable_section_name (filedata, shdr));
f761cb13 14910 free (enote);
55be8fd0 14911 continue;
301a9420
AM
14912 }
14913 data_remaining -= min_notesz;
14914
14915 inote.type = BYTE_GET (enote->type);
14916 inote.namesz = BYTE_GET (enote->namesz);
14917 inote.namedata = enote->name;
14918 inote.descsz = BYTE_GET (enote->descsz);
14919 inote.descdata = ((char *) enote
14920 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
14921 inote.descpos = offset + (inote.descdata - (char *) enote);
14922 next = ((char *) enote
14923 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
14924 }
14925 else
14926 {
14927 Elf64_External_VMS_Note *vms_enote;
14928
14929 /* PR binutils/15191
14930 Make sure that there is enough data to read. */
14931 min_notesz = offsetof (Elf64_External_VMS_Note, name);
14932 if (data_remaining < min_notesz)
14933 {
55be8fd0
NC
14934 warn (_("\
14935malformed note encountered in section %s whilst scanning for build-id note\n"),
14936 printable_section_name (filedata, shdr));
f761cb13 14937 free (enote);
55be8fd0 14938 continue;
301a9420
AM
14939 }
14940 data_remaining -= min_notesz;
14941
14942 vms_enote = (Elf64_External_VMS_Note *) enote;
14943 inote.type = BYTE_GET (vms_enote->type);
14944 inote.namesz = BYTE_GET (vms_enote->namesz);
14945 inote.namedata = vms_enote->name;
14946 inote.descsz = BYTE_GET (vms_enote->descsz);
14947 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
14948 inote.descpos = offset + (inote.descdata - (char *) enote);
14949 next = inote.descdata + align_power (inote.descsz, 3);
14950 }
14951
14952 /* Skip malformed notes. */
14953 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
14954 || (size_t) (inote.descdata - inote.namedata) > data_remaining
14955 || (size_t) (next - inote.descdata) < inote.descsz
14956 || ((size_t) (next - inote.descdata)
14957 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
14958 {
55be8fd0
NC
14959 warn (_("\
14960malformed note encountered in section %s whilst scanning for build-id note\n"),
14961 printable_section_name (filedata, shdr));
f761cb13 14962 free (enote);
301a9420
AM
14963 continue;
14964 }
14965
14966 /* Check if this is the build-id note. If so then convert the build-id
14967 bytes to a hex string. */
14968 if (inote.namesz > 0
14969 && const_strneq (inote.namedata, "GNU")
14970 && inote.type == NT_GNU_BUILD_ID)
14971 {
14972 unsigned long j;
14973 char * build_id;
14974
14975 build_id = malloc (inote.descsz * 2 + 1);
14976 if (build_id == NULL)
f761cb13
AM
14977 {
14978 free (enote);
14979 return NULL;
14980 }
301a9420
AM
14981
14982 for (j = 0; j < inote.descsz; ++j)
14983 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
14984 build_id[inote.descsz * 2] = '\0';
f761cb13 14985 free (enote);
301a9420 14986
55be8fd0 14987 return (unsigned char *) build_id;
301a9420 14988 }
f761cb13 14989 free (enote);
301a9420
AM
14990 }
14991
14992 return NULL;
14993}
14994#endif /* HAVE_LIBDEBUGINFOD */
14995
657d0d47
CC
14996/* If this is not NULL, load_debug_section will only look for sections
14997 within the list of sections given here. */
32ec8896 14998static unsigned int * section_subset = NULL;
657d0d47 14999
32ec8896 15000bfd_boolean
dda8d76d 15001load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 15002{
2cf0635d
NC
15003 struct dwarf_section * section = &debug_displays [debug].section;
15004 Elf_Internal_Shdr * sec;
dda8d76d
NC
15005 Filedata * filedata = (Filedata *) data;
15006
f425ec66
NC
15007 /* Without section headers we cannot find any sections. */
15008 if (filedata->section_headers == NULL)
15009 return FALSE;
15010
9c1ce108
AM
15011 if (filedata->string_table == NULL
15012 && filedata->file_header.e_shstrndx != SHN_UNDEF
15013 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
15014 {
15015 Elf_Internal_Shdr * strs;
15016
15017 /* Read in the string table, so that we have section names to scan. */
15018 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
15019
4dff97b2 15020 if (strs != NULL && strs->sh_size != 0)
dda8d76d 15021 {
9c1ce108
AM
15022 filedata->string_table
15023 = (char *) get_data (NULL, filedata, strs->sh_offset,
15024 1, strs->sh_size, _("string table"));
dda8d76d 15025
9c1ce108
AM
15026 filedata->string_table_length
15027 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
15028 }
15029 }
d966045b
DJ
15030
15031 /* Locate the debug section. */
dda8d76d 15032 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
15033 if (sec != NULL)
15034 section->name = section->uncompressed_name;
15035 else
15036 {
dda8d76d 15037 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
15038 if (sec != NULL)
15039 section->name = section->compressed_name;
15040 }
15041 if (sec == NULL)
32ec8896 15042 return FALSE;
d966045b 15043
657d0d47
CC
15044 /* If we're loading from a subset of sections, and we've loaded
15045 a section matching this name before, it's likely that it's a
15046 different one. */
15047 if (section_subset != NULL)
15048 free_debug_section (debug);
15049
dda8d76d 15050 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
15051}
15052
19e6b90e
L
15053void
15054free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 15055{
2cf0635d 15056 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 15057
19e6b90e
L
15058 if (section->start == NULL)
15059 return;
1007acb3 15060
19e6b90e
L
15061 free ((char *) section->start);
15062 section->start = NULL;
15063 section->address = 0;
15064 section->size = 0;
a788aedd 15065
9db70fc3
AM
15066 free (section->reloc_info);
15067 section->reloc_info = NULL;
15068 section->num_relocs = 0;
1007acb3
L
15069}
15070
32ec8896 15071static bfd_boolean
dda8d76d 15072display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 15073{
2cf0635d 15074 char * name = SECTION_NAME (section);
dda8d76d 15075 const char * print_name = printable_section_name (filedata, section);
19e6b90e 15076 bfd_size_type length;
32ec8896 15077 bfd_boolean result = TRUE;
3f5e193b 15078 int i;
1007acb3 15079
19e6b90e
L
15080 length = section->sh_size;
15081 if (length == 0)
1007acb3 15082 {
74e1a04b 15083 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
32ec8896 15084 return TRUE;
1007acb3 15085 }
5dff79d8
NC
15086 if (section->sh_type == SHT_NOBITS)
15087 {
15088 /* There is no point in dumping the contents of a debugging section
15089 which has the NOBITS type - the bits in the file will be random.
15090 This can happen when a file containing a .eh_frame section is
15091 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
15092 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
15093 print_name);
32ec8896 15094 return FALSE;
5dff79d8 15095 }
1007acb3 15096
0112cd26 15097 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 15098 name = ".debug_info";
1007acb3 15099
19e6b90e
L
15100 /* See if we know how to display the contents of this section. */
15101 for (i = 0; i < max; i++)
d85bf2ba
NC
15102 {
15103 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
15104 struct dwarf_section_display * display = debug_displays + i;
15105 struct dwarf_section * sec = & display->section;
d966045b 15106
d85bf2ba
NC
15107 if (streq (sec->uncompressed_name, name)
15108 || (id == line && const_strneq (name, ".debug_line."))
15109 || streq (sec->compressed_name, name))
15110 {
15111 bfd_boolean secondary = (section != find_section (filedata, name));
1007acb3 15112
d85bf2ba
NC
15113 if (secondary)
15114 free_debug_section (id);
dda8d76d 15115
d85bf2ba
NC
15116 if (i == line && const_strneq (name, ".debug_line."))
15117 sec->name = name;
15118 else if (streq (sec->uncompressed_name, name))
15119 sec->name = sec->uncompressed_name;
15120 else
15121 sec->name = sec->compressed_name;
657d0d47 15122
d85bf2ba
NC
15123 if (load_specific_debug_section (id, section, filedata))
15124 {
15125 /* If this debug section is part of a CU/TU set in a .dwp file,
15126 restrict load_debug_section to the sections in that set. */
15127 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 15128
d85bf2ba 15129 result &= display->display (sec, filedata);
657d0d47 15130
d85bf2ba 15131 section_subset = NULL;
1007acb3 15132
d85bf2ba
NC
15133 if (secondary || (id != info && id != abbrev))
15134 free_debug_section (id);
15135 }
15136 break;
15137 }
15138 }
1007acb3 15139
19e6b90e 15140 if (i == max)
1007acb3 15141 {
74e1a04b 15142 printf (_("Unrecognized debug section: %s\n"), print_name);
32ec8896 15143 result = FALSE;
1007acb3
L
15144 }
15145
19e6b90e 15146 return result;
5b18a4bc 15147}
103f02d3 15148
aef1f6d0
DJ
15149/* Set DUMP_SECTS for all sections where dumps were requested
15150 based on section name. */
15151
15152static void
dda8d76d 15153initialise_dumps_byname (Filedata * filedata)
aef1f6d0 15154{
2cf0635d 15155 struct dump_list_entry * cur;
aef1f6d0
DJ
15156
15157 for (cur = dump_sects_byname; cur; cur = cur->next)
15158 {
15159 unsigned int i;
32ec8896 15160 bfd_boolean any = FALSE;
aef1f6d0 15161
dda8d76d
NC
15162 for (i = 0; i < filedata->file_header.e_shnum; i++)
15163 if (streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 15164 {
6431e409 15165 request_dump_bynumber (&filedata->dump, i, cur->type);
32ec8896 15166 any = TRUE;
aef1f6d0
DJ
15167 }
15168
15169 if (!any)
15170 warn (_("Section '%s' was not dumped because it does not exist!\n"),
15171 cur->name);
15172 }
15173}
15174
32ec8896 15175static bfd_boolean
dda8d76d 15176process_section_contents (Filedata * filedata)
5b18a4bc 15177{
2cf0635d 15178 Elf_Internal_Shdr * section;
19e6b90e 15179 unsigned int i;
32ec8896 15180 bfd_boolean res = TRUE;
103f02d3 15181
19e6b90e 15182 if (! do_dump)
32ec8896 15183 return TRUE;
103f02d3 15184
dda8d76d 15185 initialise_dumps_byname (filedata);
aef1f6d0 15186
dda8d76d 15187 for (i = 0, section = filedata->section_headers;
6431e409 15188 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
15189 i++, section++)
15190 {
6431e409 15191 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 15192
19e6b90e 15193#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
15194 if (dump & DISASS_DUMP)
15195 {
15196 if (! disassemble_section (section, filedata))
15197 res = FALSE;
15198 }
19e6b90e 15199#endif
dda8d76d 15200 if (dump & HEX_DUMP)
32ec8896 15201 {
dda8d76d 15202 if (! dump_section_as_bytes (section, filedata, FALSE))
32ec8896
NC
15203 res = FALSE;
15204 }
103f02d3 15205
dda8d76d 15206 if (dump & RELOC_DUMP)
32ec8896 15207 {
dda8d76d 15208 if (! dump_section_as_bytes (section, filedata, TRUE))
32ec8896
NC
15209 res = FALSE;
15210 }
09c11c86 15211
dda8d76d 15212 if (dump & STRING_DUMP)
32ec8896 15213 {
dda8d76d 15214 if (! dump_section_as_strings (section, filedata))
32ec8896
NC
15215 res = FALSE;
15216 }
cf13d699 15217
dda8d76d 15218 if (dump & DEBUG_DUMP)
32ec8896 15219 {
dda8d76d 15220 if (! display_debug_section (i, section, filedata))
32ec8896
NC
15221 res = FALSE;
15222 }
7d9813f1 15223
094e34f2 15224#ifdef ENABLE_LIBCTF
7d9813f1
NA
15225 if (dump & CTF_DUMP)
15226 {
15227 if (! dump_section_as_ctf (section, filedata))
15228 res = FALSE;
15229 }
094e34f2 15230#endif
5b18a4bc 15231 }
103f02d3 15232
19e6b90e
L
15233 /* Check to see if the user requested a
15234 dump of a section that does not exist. */
6431e409 15235 while (i < filedata->dump.num_dump_sects)
0ee3043f 15236 {
6431e409 15237 if (filedata->dump.dump_sects[i])
32ec8896
NC
15238 {
15239 warn (_("Section %d was not dumped because it does not exist!\n"), i);
15240 res = FALSE;
15241 }
0ee3043f
NC
15242 i++;
15243 }
32ec8896
NC
15244
15245 return res;
5b18a4bc 15246}
103f02d3 15247
5b18a4bc 15248static void
19e6b90e 15249process_mips_fpe_exception (int mask)
5b18a4bc 15250{
19e6b90e
L
15251 if (mask)
15252 {
32ec8896
NC
15253 bfd_boolean first = TRUE;
15254
19e6b90e 15255 if (mask & OEX_FPU_INEX)
32ec8896 15256 fputs ("INEX", stdout), first = FALSE;
19e6b90e 15257 if (mask & OEX_FPU_UFLO)
32ec8896 15258 printf ("%sUFLO", first ? "" : "|"), first = FALSE;
19e6b90e 15259 if (mask & OEX_FPU_OFLO)
32ec8896 15260 printf ("%sOFLO", first ? "" : "|"), first = FALSE;
19e6b90e 15261 if (mask & OEX_FPU_DIV0)
32ec8896 15262 printf ("%sDIV0", first ? "" : "|"), first = FALSE;
19e6b90e
L
15263 if (mask & OEX_FPU_INVAL)
15264 printf ("%sINVAL", first ? "" : "|");
15265 }
5b18a4bc 15266 else
19e6b90e 15267 fputs ("0", stdout);
5b18a4bc 15268}
103f02d3 15269
f6f0e17b
NC
15270/* Display's the value of TAG at location P. If TAG is
15271 greater than 0 it is assumed to be an unknown tag, and
15272 a message is printed to this effect. Otherwise it is
15273 assumed that a message has already been printed.
15274
15275 If the bottom bit of TAG is set it assumed to have a
15276 string value, otherwise it is assumed to have an integer
15277 value.
15278
15279 Returns an updated P pointing to the first unread byte
15280 beyond the end of TAG's value.
15281
15282 Reads at or beyond END will not be made. */
15283
15284static unsigned char *
60abdbed 15285display_tag_value (signed int tag,
f6f0e17b
NC
15286 unsigned char * p,
15287 const unsigned char * const end)
15288{
15289 unsigned long val;
15290
15291 if (tag > 0)
15292 printf (" Tag_unknown_%d: ", tag);
15293
15294 if (p >= end)
15295 {
4082ef84 15296 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
15297 }
15298 else if (tag & 1)
15299 {
071436c6
NC
15300 /* PR 17531 file: 027-19978-0.004. */
15301 size_t maxlen = (end - p) - 1;
15302
15303 putchar ('"');
4082ef84
NC
15304 if (maxlen > 0)
15305 {
15306 print_symbol ((int) maxlen, (const char *) p);
15307 p += strnlen ((char *) p, maxlen) + 1;
15308 }
15309 else
15310 {
15311 printf (_("<corrupt string tag>"));
15312 p = (unsigned char *) end;
15313 }
071436c6 15314 printf ("\"\n");
f6f0e17b
NC
15315 }
15316 else
15317 {
cd30bcef 15318 READ_ULEB (val, p, end);
f6f0e17b
NC
15319 printf ("%ld (0x%lx)\n", val, val);
15320 }
15321
4082ef84 15322 assert (p <= end);
f6f0e17b
NC
15323 return p;
15324}
15325
53a346d8
CZ
15326/* ARC ABI attributes section. */
15327
15328static unsigned char *
15329display_arc_attribute (unsigned char * p,
15330 const unsigned char * const end)
15331{
15332 unsigned int tag;
53a346d8
CZ
15333 unsigned int val;
15334
cd30bcef 15335 READ_ULEB (tag, p, end);
53a346d8
CZ
15336
15337 switch (tag)
15338 {
15339 case Tag_ARC_PCS_config:
cd30bcef 15340 READ_ULEB (val, p, end);
53a346d8
CZ
15341 printf (" Tag_ARC_PCS_config: ");
15342 switch (val)
15343 {
15344 case 0:
15345 printf (_("Absent/Non standard\n"));
15346 break;
15347 case 1:
15348 printf (_("Bare metal/mwdt\n"));
15349 break;
15350 case 2:
15351 printf (_("Bare metal/newlib\n"));
15352 break;
15353 case 3:
15354 printf (_("Linux/uclibc\n"));
15355 break;
15356 case 4:
15357 printf (_("Linux/glibc\n"));
15358 break;
15359 default:
15360 printf (_("Unknown\n"));
15361 break;
15362 }
15363 break;
15364
15365 case Tag_ARC_CPU_base:
cd30bcef 15366 READ_ULEB (val, p, end);
53a346d8
CZ
15367 printf (" Tag_ARC_CPU_base: ");
15368 switch (val)
15369 {
15370 default:
15371 case TAG_CPU_NONE:
15372 printf (_("Absent\n"));
15373 break;
15374 case TAG_CPU_ARC6xx:
15375 printf ("ARC6xx\n");
15376 break;
15377 case TAG_CPU_ARC7xx:
15378 printf ("ARC7xx\n");
15379 break;
15380 case TAG_CPU_ARCEM:
15381 printf ("ARCEM\n");
15382 break;
15383 case TAG_CPU_ARCHS:
15384 printf ("ARCHS\n");
15385 break;
15386 }
15387 break;
15388
15389 case Tag_ARC_CPU_variation:
cd30bcef 15390 READ_ULEB (val, p, end);
53a346d8
CZ
15391 printf (" Tag_ARC_CPU_variation: ");
15392 switch (val)
15393 {
15394 default:
15395 if (val > 0 && val < 16)
53a346d8 15396 printf ("Core%d\n", val);
d8cbc93b
JL
15397 else
15398 printf ("Unknown\n");
15399 break;
15400
53a346d8
CZ
15401 case 0:
15402 printf (_("Absent\n"));
15403 break;
15404 }
15405 break;
15406
15407 case Tag_ARC_CPU_name:
15408 printf (" Tag_ARC_CPU_name: ");
15409 p = display_tag_value (-1, p, end);
15410 break;
15411
15412 case Tag_ARC_ABI_rf16:
cd30bcef 15413 READ_ULEB (val, p, end);
53a346d8
CZ
15414 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
15415 break;
15416
15417 case Tag_ARC_ABI_osver:
cd30bcef 15418 READ_ULEB (val, p, end);
53a346d8
CZ
15419 printf (" Tag_ARC_ABI_osver: v%d\n", val);
15420 break;
15421
15422 case Tag_ARC_ABI_pic:
15423 case Tag_ARC_ABI_sda:
cd30bcef 15424 READ_ULEB (val, p, end);
53a346d8
CZ
15425 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
15426 : " Tag_ARC_ABI_pic: ");
15427 switch (val)
15428 {
15429 case 0:
15430 printf (_("Absent\n"));
15431 break;
15432 case 1:
15433 printf ("MWDT\n");
15434 break;
15435 case 2:
15436 printf ("GNU\n");
15437 break;
15438 default:
15439 printf (_("Unknown\n"));
15440 break;
15441 }
15442 break;
15443
15444 case Tag_ARC_ABI_tls:
cd30bcef 15445 READ_ULEB (val, p, end);
53a346d8
CZ
15446 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
15447 break;
15448
15449 case Tag_ARC_ABI_enumsize:
cd30bcef 15450 READ_ULEB (val, p, end);
53a346d8
CZ
15451 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
15452 _("smallest"));
15453 break;
15454
15455 case Tag_ARC_ABI_exceptions:
cd30bcef 15456 READ_ULEB (val, p, end);
53a346d8
CZ
15457 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
15458 : _("default"));
15459 break;
15460
15461 case Tag_ARC_ABI_double_size:
cd30bcef 15462 READ_ULEB (val, p, end);
53a346d8
CZ
15463 printf (" Tag_ARC_ABI_double_size: %d\n", val);
15464 break;
15465
15466 case Tag_ARC_ISA_config:
15467 printf (" Tag_ARC_ISA_config: ");
15468 p = display_tag_value (-1, p, end);
15469 break;
15470
15471 case Tag_ARC_ISA_apex:
15472 printf (" Tag_ARC_ISA_apex: ");
15473 p = display_tag_value (-1, p, end);
15474 break;
15475
15476 case Tag_ARC_ISA_mpy_option:
cd30bcef 15477 READ_ULEB (val, p, end);
53a346d8
CZ
15478 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
15479 break;
15480
db1e1b45 15481 case Tag_ARC_ATR_version:
cd30bcef 15482 READ_ULEB (val, p, end);
db1e1b45 15483 printf (" Tag_ARC_ATR_version: %d\n", val);
15484 break;
15485
53a346d8
CZ
15486 default:
15487 return display_tag_value (tag & 1, p, end);
15488 }
15489
15490 return p;
15491}
15492
11c1ff18
PB
15493/* ARM EABI attributes section. */
15494typedef struct
15495{
70e99720 15496 unsigned int tag;
2cf0635d 15497 const char * name;
11c1ff18 15498 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 15499 unsigned int type;
2cf0635d 15500 const char ** table;
11c1ff18
PB
15501} arm_attr_public_tag;
15502
2cf0635d 15503static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 15504 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 15505 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 15506 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
2cf0635d
NC
15507static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
15508static const char * arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 15509 {"No", "Thumb-1", "Thumb-2", "Yes"};
75375b3e 15510static const char * arm_attr_tag_FP_arch[] =
bca38921 15511 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 15512 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 15513static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 15514static const char * arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
15515 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
15516 "NEON for ARMv8.1"};
2cf0635d 15517static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
15518 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
15519 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 15520static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 15521 {"V6", "SB", "TLS", "Unused"};
2cf0635d 15522static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 15523 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 15524static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 15525 {"Absolute", "PC-relative", "None"};
2cf0635d 15526static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 15527 {"None", "direct", "GOT-indirect"};
2cf0635d 15528static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 15529 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
15530static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
15531static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 15532 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
15533static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
15534static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
15535static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 15536 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 15537static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 15538 {"Unused", "small", "int", "forced to int"};
2cf0635d 15539static const char * arm_attr_tag_ABI_HardFP_use[] =
99654aaf 15540 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
2cf0635d 15541static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 15542 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 15543static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 15544 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 15545static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
15546 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15547 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 15548static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
15549 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15550 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 15551static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 15552static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 15553 {"Not Allowed", "Allowed"};
2cf0635d 15554static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 15555 {"None", "IEEE 754", "Alternative Format"};
15afaa63
TP
15556static const char * arm_attr_tag_DSP_extension[] =
15557 {"Follow architecture", "Allowed"};
dd24e3da 15558static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
15559 {"Not Allowed", "Allowed"};
15560static const char * arm_attr_tag_DIV_use[] =
dd24e3da 15561 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 15562 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
15563static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
15564static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 15565 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 15566 "TrustZone and Virtualization Extensions"};
dd24e3da 15567static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 15568 {"Not Allowed", "Allowed"};
11c1ff18 15569
a7ad558c
AV
15570static const char * arm_attr_tag_MVE_arch[] =
15571 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
15572
11c1ff18
PB
15573#define LOOKUP(id, name) \
15574 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 15575static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
15576{
15577 {4, "CPU_raw_name", 1, NULL},
15578 {5, "CPU_name", 1, NULL},
15579 LOOKUP(6, CPU_arch),
15580 {7, "CPU_arch_profile", 0, NULL},
15581 LOOKUP(8, ARM_ISA_use),
15582 LOOKUP(9, THUMB_ISA_use),
75375b3e 15583 LOOKUP(10, FP_arch),
11c1ff18 15584 LOOKUP(11, WMMX_arch),
f5f53991
AS
15585 LOOKUP(12, Advanced_SIMD_arch),
15586 LOOKUP(13, PCS_config),
11c1ff18
PB
15587 LOOKUP(14, ABI_PCS_R9_use),
15588 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 15589 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
15590 LOOKUP(17, ABI_PCS_GOT_use),
15591 LOOKUP(18, ABI_PCS_wchar_t),
15592 LOOKUP(19, ABI_FP_rounding),
15593 LOOKUP(20, ABI_FP_denormal),
15594 LOOKUP(21, ABI_FP_exceptions),
15595 LOOKUP(22, ABI_FP_user_exceptions),
15596 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
15597 {24, "ABI_align_needed", 0, NULL},
15598 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
15599 LOOKUP(26, ABI_enum_size),
15600 LOOKUP(27, ABI_HardFP_use),
15601 LOOKUP(28, ABI_VFP_args),
15602 LOOKUP(29, ABI_WMMX_args),
15603 LOOKUP(30, ABI_optimization_goals),
15604 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 15605 {32, "compatibility", 0, NULL},
f5f53991 15606 LOOKUP(34, CPU_unaligned_access),
75375b3e 15607 LOOKUP(36, FP_HP_extension),
8e79c3df 15608 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
15609 LOOKUP(42, MPextension_use),
15610 LOOKUP(44, DIV_use),
15afaa63 15611 LOOKUP(46, DSP_extension),
a7ad558c 15612 LOOKUP(48, MVE_arch),
f5f53991
AS
15613 {64, "nodefaults", 0, NULL},
15614 {65, "also_compatible_with", 0, NULL},
15615 LOOKUP(66, T2EE_use),
15616 {67, "conformance", 1, NULL},
15617 LOOKUP(68, Virtualization_use),
cd21e546 15618 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
15619};
15620#undef LOOKUP
15621
11c1ff18 15622static unsigned char *
f6f0e17b
NC
15623display_arm_attribute (unsigned char * p,
15624 const unsigned char * const end)
11c1ff18 15625{
70e99720 15626 unsigned int tag;
70e99720 15627 unsigned int val;
2cf0635d 15628 arm_attr_public_tag * attr;
11c1ff18 15629 unsigned i;
70e99720 15630 unsigned int type;
11c1ff18 15631
cd30bcef 15632 READ_ULEB (tag, p, end);
11c1ff18 15633 attr = NULL;
2cf0635d 15634 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
15635 {
15636 if (arm_attr_public_tags[i].tag == tag)
15637 {
15638 attr = &arm_attr_public_tags[i];
15639 break;
15640 }
15641 }
15642
15643 if (attr)
15644 {
15645 printf (" Tag_%s: ", attr->name);
15646 switch (attr->type)
15647 {
15648 case 0:
15649 switch (tag)
15650 {
15651 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 15652 READ_ULEB (val, p, end);
11c1ff18
PB
15653 switch (val)
15654 {
2b692964
NC
15655 case 0: printf (_("None\n")); break;
15656 case 'A': printf (_("Application\n")); break;
15657 case 'R': printf (_("Realtime\n")); break;
15658 case 'M': printf (_("Microcontroller\n")); break;
15659 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
15660 default: printf ("??? (%d)\n", val); break;
15661 }
15662 break;
15663
75375b3e 15664 case 24: /* Tag_align_needed. */
cd30bcef 15665 READ_ULEB (val, p, end);
75375b3e
MGD
15666 switch (val)
15667 {
2b692964
NC
15668 case 0: printf (_("None\n")); break;
15669 case 1: printf (_("8-byte\n")); break;
15670 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
15671 case 3: printf ("??? 3\n"); break;
15672 default:
15673 if (val <= 12)
dd24e3da 15674 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15675 1 << val);
15676 else
15677 printf ("??? (%d)\n", val);
15678 break;
15679 }
15680 break;
15681
15682 case 25: /* Tag_align_preserved. */
cd30bcef 15683 READ_ULEB (val, p, end);
75375b3e
MGD
15684 switch (val)
15685 {
2b692964
NC
15686 case 0: printf (_("None\n")); break;
15687 case 1: printf (_("8-byte, except leaf SP\n")); break;
15688 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
15689 case 3: printf ("??? 3\n"); break;
15690 default:
15691 if (val <= 12)
dd24e3da 15692 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15693 1 << val);
15694 else
15695 printf ("??? (%d)\n", val);
15696 break;
15697 }
15698 break;
15699
11c1ff18 15700 case 32: /* Tag_compatibility. */
071436c6 15701 {
cd30bcef 15702 READ_ULEB (val, p, end);
071436c6 15703 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
15704 if (p < end - 1)
15705 {
15706 size_t maxlen = (end - p) - 1;
15707
15708 print_symbol ((int) maxlen, (const char *) p);
15709 p += strnlen ((char *) p, maxlen) + 1;
15710 }
15711 else
15712 {
15713 printf (_("<corrupt>"));
15714 p = (unsigned char *) end;
15715 }
071436c6 15716 putchar ('\n');
071436c6 15717 }
11c1ff18
PB
15718 break;
15719
f5f53991 15720 case 64: /* Tag_nodefaults. */
541a3cbd
NC
15721 /* PR 17531: file: 001-505008-0.01. */
15722 if (p < end)
15723 p++;
2b692964 15724 printf (_("True\n"));
f5f53991
AS
15725 break;
15726
15727 case 65: /* Tag_also_compatible_with. */
cd30bcef 15728 READ_ULEB (val, p, end);
f5f53991
AS
15729 if (val == 6 /* Tag_CPU_arch. */)
15730 {
cd30bcef 15731 READ_ULEB (val, p, end);
071436c6 15732 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
15733 printf ("??? (%d)\n", val);
15734 else
15735 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
15736 }
15737 else
15738 printf ("???\n");
071436c6
NC
15739 while (p < end && *(p++) != '\0' /* NUL terminator. */)
15740 ;
f5f53991
AS
15741 break;
15742
11c1ff18 15743 default:
bee0ee85
NC
15744 printf (_("<unknown: %d>\n"), tag);
15745 break;
11c1ff18
PB
15746 }
15747 return p;
15748
15749 case 1:
f6f0e17b 15750 return display_tag_value (-1, p, end);
11c1ff18 15751 case 2:
f6f0e17b 15752 return display_tag_value (0, p, end);
11c1ff18
PB
15753
15754 default:
15755 assert (attr->type & 0x80);
cd30bcef 15756 READ_ULEB (val, p, end);
11c1ff18
PB
15757 type = attr->type & 0x7f;
15758 if (val >= type)
15759 printf ("??? (%d)\n", val);
15760 else
15761 printf ("%s\n", attr->table[val]);
15762 return p;
15763 }
15764 }
11c1ff18 15765
f6f0e17b 15766 return display_tag_value (tag, p, end);
11c1ff18
PB
15767}
15768
104d59d1 15769static unsigned char *
60bca95a 15770display_gnu_attribute (unsigned char * p,
60abdbed 15771 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 15772 const unsigned char * const end)
104d59d1 15773{
cd30bcef 15774 unsigned int tag;
60abdbed 15775 unsigned int val;
104d59d1 15776
cd30bcef 15777 READ_ULEB (tag, p, end);
104d59d1
JM
15778
15779 /* Tag_compatibility is the only generic GNU attribute defined at
15780 present. */
15781 if (tag == 32)
15782 {
cd30bcef 15783 READ_ULEB (val, p, end);
071436c6
NC
15784
15785 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
15786 if (p == end)
15787 {
071436c6 15788 printf (_("<corrupt>\n"));
f6f0e17b
NC
15789 warn (_("corrupt vendor attribute\n"));
15790 }
15791 else
15792 {
4082ef84
NC
15793 if (p < end - 1)
15794 {
15795 size_t maxlen = (end - p) - 1;
071436c6 15796
4082ef84
NC
15797 print_symbol ((int) maxlen, (const char *) p);
15798 p += strnlen ((char *) p, maxlen) + 1;
15799 }
15800 else
15801 {
15802 printf (_("<corrupt>"));
15803 p = (unsigned char *) end;
15804 }
071436c6 15805 putchar ('\n');
f6f0e17b 15806 }
104d59d1
JM
15807 return p;
15808 }
15809
15810 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 15811 return display_proc_gnu_attribute (p, tag, end);
104d59d1 15812
f6f0e17b 15813 return display_tag_value (tag, p, end);
104d59d1
JM
15814}
15815
85f7484a
PB
15816static unsigned char *
15817display_m68k_gnu_attribute (unsigned char * p,
15818 unsigned int tag,
15819 const unsigned char * const end)
15820{
15821 unsigned int val;
15822
15823 if (tag == Tag_GNU_M68K_ABI_FP)
15824 {
15825 printf (" Tag_GNU_M68K_ABI_FP: ");
15826 if (p == end)
15827 {
15828 printf (_("<corrupt>\n"));
15829 return p;
15830 }
15831 READ_ULEB (val, p, end);
15832
15833 if (val > 3)
15834 printf ("(%#x), ", val);
15835
15836 switch (val & 3)
15837 {
15838 case 0:
15839 printf (_("unspecified hard/soft float\n"));
15840 break;
15841 case 1:
15842 printf (_("hard float\n"));
15843 break;
15844 case 2:
15845 printf (_("soft float\n"));
15846 break;
15847 }
15848 return p;
15849 }
15850
15851 return display_tag_value (tag & 1, p, end);
15852}
15853
34c8bcba 15854static unsigned char *
f6f0e17b 15855display_power_gnu_attribute (unsigned char * p,
60abdbed 15856 unsigned int tag,
f6f0e17b 15857 const unsigned char * const end)
34c8bcba 15858{
005d79fd 15859 unsigned int val;
34c8bcba
JM
15860
15861 if (tag == Tag_GNU_Power_ABI_FP)
15862 {
34c8bcba 15863 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 15864 if (p == end)
005d79fd
AM
15865 {
15866 printf (_("<corrupt>\n"));
15867 return p;
15868 }
cd30bcef 15869 READ_ULEB (val, p, end);
60bca95a 15870
005d79fd
AM
15871 if (val > 15)
15872 printf ("(%#x), ", val);
15873
15874 switch (val & 3)
34c8bcba
JM
15875 {
15876 case 0:
005d79fd 15877 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
15878 break;
15879 case 1:
005d79fd 15880 printf (_("hard float, "));
34c8bcba
JM
15881 break;
15882 case 2:
005d79fd 15883 printf (_("soft float, "));
34c8bcba 15884 break;
3c7b9897 15885 case 3:
005d79fd 15886 printf (_("single-precision hard float, "));
3c7b9897 15887 break;
005d79fd
AM
15888 }
15889
15890 switch (val & 0xC)
15891 {
15892 case 0:
15893 printf (_("unspecified long double\n"));
15894 break;
15895 case 4:
15896 printf (_("128-bit IBM long double\n"));
15897 break;
15898 case 8:
15899 printf (_("64-bit long double\n"));
15900 break;
15901 case 12:
15902 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
15903 break;
15904 }
15905 return p;
005d79fd 15906 }
34c8bcba 15907
c6e65352
DJ
15908 if (tag == Tag_GNU_Power_ABI_Vector)
15909 {
c6e65352 15910 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 15911 if (p == end)
005d79fd
AM
15912 {
15913 printf (_("<corrupt>\n"));
15914 return p;
15915 }
cd30bcef 15916 READ_ULEB (val, p, end);
005d79fd
AM
15917
15918 if (val > 3)
15919 printf ("(%#x), ", val);
15920
15921 switch (val & 3)
c6e65352
DJ
15922 {
15923 case 0:
005d79fd 15924 printf (_("unspecified\n"));
c6e65352
DJ
15925 break;
15926 case 1:
005d79fd 15927 printf (_("generic\n"));
c6e65352
DJ
15928 break;
15929 case 2:
15930 printf ("AltiVec\n");
15931 break;
15932 case 3:
15933 printf ("SPE\n");
15934 break;
c6e65352
DJ
15935 }
15936 return p;
005d79fd 15937 }
c6e65352 15938
f82e0623
NF
15939 if (tag == Tag_GNU_Power_ABI_Struct_Return)
15940 {
005d79fd 15941 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 15942 if (p == end)
f6f0e17b 15943 {
005d79fd 15944 printf (_("<corrupt>\n"));
f6f0e17b
NC
15945 return p;
15946 }
cd30bcef 15947 READ_ULEB (val, p, end);
0b4362b0 15948
005d79fd
AM
15949 if (val > 2)
15950 printf ("(%#x), ", val);
15951
15952 switch (val & 3)
15953 {
15954 case 0:
15955 printf (_("unspecified\n"));
15956 break;
15957 case 1:
15958 printf ("r3/r4\n");
15959 break;
15960 case 2:
15961 printf (_("memory\n"));
15962 break;
15963 case 3:
15964 printf ("???\n");
15965 break;
15966 }
f82e0623
NF
15967 return p;
15968 }
15969
f6f0e17b 15970 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
15971}
15972
643f7afb
AK
15973static unsigned char *
15974display_s390_gnu_attribute (unsigned char * p,
60abdbed 15975 unsigned int tag,
643f7afb
AK
15976 const unsigned char * const end)
15977{
cd30bcef 15978 unsigned int val;
643f7afb
AK
15979
15980 if (tag == Tag_GNU_S390_ABI_Vector)
15981 {
643f7afb 15982 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 15983 READ_ULEB (val, p, end);
643f7afb
AK
15984
15985 switch (val)
15986 {
15987 case 0:
15988 printf (_("any\n"));
15989 break;
15990 case 1:
15991 printf (_("software\n"));
15992 break;
15993 case 2:
15994 printf (_("hardware\n"));
15995 break;
15996 default:
15997 printf ("??? (%d)\n", val);
15998 break;
15999 }
16000 return p;
16001 }
16002
16003 return display_tag_value (tag & 1, p, end);
16004}
16005
9e8c70f9 16006static void
60abdbed 16007display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
16008{
16009 if (mask)
16010 {
32ec8896 16011 bfd_boolean first = TRUE;
071436c6 16012
9e8c70f9 16013 if (mask & ELF_SPARC_HWCAP_MUL32)
32ec8896 16014 fputs ("mul32", stdout), first = FALSE;
9e8c70f9 16015 if (mask & ELF_SPARC_HWCAP_DIV32)
32ec8896 16016 printf ("%sdiv32", first ? "" : "|"), first = FALSE;
9e8c70f9 16017 if (mask & ELF_SPARC_HWCAP_FSMULD)
32ec8896 16018 printf ("%sfsmuld", first ? "" : "|"), first = FALSE;
9e8c70f9 16019 if (mask & ELF_SPARC_HWCAP_V8PLUS)
32ec8896 16020 printf ("%sv8plus", first ? "" : "|"), first = FALSE;
9e8c70f9 16021 if (mask & ELF_SPARC_HWCAP_POPC)
32ec8896 16022 printf ("%spopc", first ? "" : "|"), first = FALSE;
9e8c70f9 16023 if (mask & ELF_SPARC_HWCAP_VIS)
32ec8896 16024 printf ("%svis", first ? "" : "|"), first = FALSE;
9e8c70f9 16025 if (mask & ELF_SPARC_HWCAP_VIS2)
32ec8896 16026 printf ("%svis2", first ? "" : "|"), first = FALSE;
9e8c70f9 16027 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
32ec8896 16028 printf ("%sASIBlkInit", first ? "" : "|"), first = FALSE;
9e8c70f9 16029 if (mask & ELF_SPARC_HWCAP_FMAF)
32ec8896 16030 printf ("%sfmaf", first ? "" : "|"), first = FALSE;
9e8c70f9 16031 if (mask & ELF_SPARC_HWCAP_VIS3)
32ec8896 16032 printf ("%svis3", first ? "" : "|"), first = FALSE;
9e8c70f9 16033 if (mask & ELF_SPARC_HWCAP_HPC)
32ec8896 16034 printf ("%shpc", first ? "" : "|"), first = FALSE;
9e8c70f9 16035 if (mask & ELF_SPARC_HWCAP_RANDOM)
32ec8896 16036 printf ("%srandom", first ? "" : "|"), first = FALSE;
9e8c70f9 16037 if (mask & ELF_SPARC_HWCAP_TRANS)
32ec8896 16038 printf ("%strans", first ? "" : "|"), first = FALSE;
9e8c70f9 16039 if (mask & ELF_SPARC_HWCAP_FJFMAU)
32ec8896 16040 printf ("%sfjfmau", first ? "" : "|"), first = FALSE;
9e8c70f9 16041 if (mask & ELF_SPARC_HWCAP_IMA)
32ec8896 16042 printf ("%sima", first ? "" : "|"), first = FALSE;
9e8c70f9 16043 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
32ec8896 16044 printf ("%scspare", first ? "" : "|"), first = FALSE;
9e8c70f9
DM
16045 }
16046 else
071436c6
NC
16047 fputc ('0', stdout);
16048 fputc ('\n', stdout);
9e8c70f9
DM
16049}
16050
3d68f91c 16051static void
60abdbed 16052display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
16053{
16054 if (mask)
16055 {
32ec8896 16056 bfd_boolean first = TRUE;
071436c6 16057
3d68f91c 16058 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
32ec8896 16059 fputs ("fjathplus", stdout), first = FALSE;
3d68f91c 16060 if (mask & ELF_SPARC_HWCAP2_VIS3B)
32ec8896 16061 printf ("%svis3b", first ? "" : "|"), first = FALSE;
3d68f91c 16062 if (mask & ELF_SPARC_HWCAP2_ADP)
32ec8896 16063 printf ("%sadp", first ? "" : "|"), first = FALSE;
3d68f91c 16064 if (mask & ELF_SPARC_HWCAP2_SPARC5)
32ec8896 16065 printf ("%ssparc5", first ? "" : "|"), first = FALSE;
3d68f91c 16066 if (mask & ELF_SPARC_HWCAP2_MWAIT)
32ec8896 16067 printf ("%smwait", first ? "" : "|"), first = FALSE;
3d68f91c 16068 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
32ec8896 16069 printf ("%sxmpmul", first ? "" : "|"), first = FALSE;
3d68f91c 16070 if (mask & ELF_SPARC_HWCAP2_XMONT)
32ec8896 16071 printf ("%sxmont2", first ? "" : "|"), first = FALSE;
3d68f91c 16072 if (mask & ELF_SPARC_HWCAP2_NSEC)
32ec8896 16073 printf ("%snsec", first ? "" : "|"), first = FALSE;
3d68f91c 16074 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
32ec8896 16075 printf ("%sfjathhpc", first ? "" : "|"), first = FALSE;
3d68f91c 16076 if (mask & ELF_SPARC_HWCAP2_FJDES)
32ec8896 16077 printf ("%sfjdes", first ? "" : "|"), first = FALSE;
3d68f91c 16078 if (mask & ELF_SPARC_HWCAP2_FJAES)
32ec8896 16079 printf ("%sfjaes", first ? "" : "|"), first = FALSE;
3d68f91c
JM
16080 }
16081 else
071436c6
NC
16082 fputc ('0', stdout);
16083 fputc ('\n', stdout);
3d68f91c
JM
16084}
16085
9e8c70f9 16086static unsigned char *
f6f0e17b 16087display_sparc_gnu_attribute (unsigned char * p,
60abdbed 16088 unsigned int tag,
f6f0e17b 16089 const unsigned char * const end)
9e8c70f9 16090{
cd30bcef 16091 unsigned int val;
3d68f91c 16092
9e8c70f9
DM
16093 if (tag == Tag_GNU_Sparc_HWCAPS)
16094 {
cd30bcef 16095 READ_ULEB (val, p, end);
9e8c70f9 16096 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
16097 display_sparc_hwcaps (val);
16098 return p;
3d68f91c
JM
16099 }
16100 if (tag == Tag_GNU_Sparc_HWCAPS2)
16101 {
cd30bcef 16102 READ_ULEB (val, p, end);
3d68f91c
JM
16103 printf (" Tag_GNU_Sparc_HWCAPS2: ");
16104 display_sparc_hwcaps2 (val);
16105 return p;
16106 }
9e8c70f9 16107
f6f0e17b 16108 return display_tag_value (tag, p, end);
9e8c70f9
DM
16109}
16110
351cdf24 16111static void
32ec8896 16112print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
16113{
16114 switch (val)
16115 {
16116 case Val_GNU_MIPS_ABI_FP_ANY:
16117 printf (_("Hard or soft float\n"));
16118 break;
16119 case Val_GNU_MIPS_ABI_FP_DOUBLE:
16120 printf (_("Hard float (double precision)\n"));
16121 break;
16122 case Val_GNU_MIPS_ABI_FP_SINGLE:
16123 printf (_("Hard float (single precision)\n"));
16124 break;
16125 case Val_GNU_MIPS_ABI_FP_SOFT:
16126 printf (_("Soft float\n"));
16127 break;
16128 case Val_GNU_MIPS_ABI_FP_OLD_64:
16129 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
16130 break;
16131 case Val_GNU_MIPS_ABI_FP_XX:
16132 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
16133 break;
16134 case Val_GNU_MIPS_ABI_FP_64:
16135 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
16136 break;
16137 case Val_GNU_MIPS_ABI_FP_64A:
16138 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
16139 break;
3350cc01
CM
16140 case Val_GNU_MIPS_ABI_FP_NAN2008:
16141 printf (_("NaN 2008 compatibility\n"));
16142 break;
351cdf24
MF
16143 default:
16144 printf ("??? (%d)\n", val);
16145 break;
16146 }
16147}
16148
2cf19d5c 16149static unsigned char *
f6f0e17b 16150display_mips_gnu_attribute (unsigned char * p,
60abdbed 16151 unsigned int tag,
f6f0e17b 16152 const unsigned char * const end)
2cf19d5c 16153{
2cf19d5c
JM
16154 if (tag == Tag_GNU_MIPS_ABI_FP)
16155 {
32ec8896 16156 unsigned int val;
f6f0e17b 16157
2cf19d5c 16158 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 16159 READ_ULEB (val, p, end);
351cdf24 16160 print_mips_fp_abi_value (val);
2cf19d5c
JM
16161 return p;
16162 }
16163
a9f58168
CF
16164 if (tag == Tag_GNU_MIPS_ABI_MSA)
16165 {
32ec8896 16166 unsigned int val;
a9f58168 16167
a9f58168 16168 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 16169 READ_ULEB (val, p, end);
a9f58168
CF
16170
16171 switch (val)
16172 {
16173 case Val_GNU_MIPS_ABI_MSA_ANY:
16174 printf (_("Any MSA or not\n"));
16175 break;
16176 case Val_GNU_MIPS_ABI_MSA_128:
16177 printf (_("128-bit MSA\n"));
16178 break;
16179 default:
16180 printf ("??? (%d)\n", val);
16181 break;
16182 }
16183 return p;
16184 }
16185
f6f0e17b 16186 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
16187}
16188
59e6276b 16189static unsigned char *
f6f0e17b
NC
16190display_tic6x_attribute (unsigned char * p,
16191 const unsigned char * const end)
59e6276b 16192{
60abdbed 16193 unsigned int tag;
cd30bcef 16194 unsigned int val;
59e6276b 16195
cd30bcef 16196 READ_ULEB (tag, p, end);
59e6276b
JM
16197
16198 switch (tag)
16199 {
75fa6dc1 16200 case Tag_ISA:
75fa6dc1 16201 printf (" Tag_ISA: ");
cd30bcef 16202 READ_ULEB (val, p, end);
59e6276b
JM
16203
16204 switch (val)
16205 {
75fa6dc1 16206 case C6XABI_Tag_ISA_none:
59e6276b
JM
16207 printf (_("None\n"));
16208 break;
75fa6dc1 16209 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
16210 printf ("C62x\n");
16211 break;
75fa6dc1 16212 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
16213 printf ("C67x\n");
16214 break;
75fa6dc1 16215 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
16216 printf ("C67x+\n");
16217 break;
75fa6dc1 16218 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
16219 printf ("C64x\n");
16220 break;
75fa6dc1 16221 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
16222 printf ("C64x+\n");
16223 break;
75fa6dc1 16224 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
16225 printf ("C674x\n");
16226 break;
16227 default:
16228 printf ("??? (%d)\n", val);
16229 break;
16230 }
16231 return p;
16232
87779176 16233 case Tag_ABI_wchar_t:
87779176 16234 printf (" Tag_ABI_wchar_t: ");
cd30bcef 16235 READ_ULEB (val, p, end);
87779176
JM
16236 switch (val)
16237 {
16238 case 0:
16239 printf (_("Not used\n"));
16240 break;
16241 case 1:
16242 printf (_("2 bytes\n"));
16243 break;
16244 case 2:
16245 printf (_("4 bytes\n"));
16246 break;
16247 default:
16248 printf ("??? (%d)\n", val);
16249 break;
16250 }
16251 return p;
16252
16253 case Tag_ABI_stack_align_needed:
87779176 16254 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 16255 READ_ULEB (val, p, end);
87779176
JM
16256 switch (val)
16257 {
16258 case 0:
16259 printf (_("8-byte\n"));
16260 break;
16261 case 1:
16262 printf (_("16-byte\n"));
16263 break;
16264 default:
16265 printf ("??? (%d)\n", val);
16266 break;
16267 }
16268 return p;
16269
16270 case Tag_ABI_stack_align_preserved:
cd30bcef 16271 READ_ULEB (val, p, end);
87779176
JM
16272 printf (" Tag_ABI_stack_align_preserved: ");
16273 switch (val)
16274 {
16275 case 0:
16276 printf (_("8-byte\n"));
16277 break;
16278 case 1:
16279 printf (_("16-byte\n"));
16280 break;
16281 default:
16282 printf ("??? (%d)\n", val);
16283 break;
16284 }
16285 return p;
16286
b5593623 16287 case Tag_ABI_DSBT:
cd30bcef 16288 READ_ULEB (val, p, end);
b5593623
JM
16289 printf (" Tag_ABI_DSBT: ");
16290 switch (val)
16291 {
16292 case 0:
16293 printf (_("DSBT addressing not used\n"));
16294 break;
16295 case 1:
16296 printf (_("DSBT addressing used\n"));
16297 break;
16298 default:
16299 printf ("??? (%d)\n", val);
16300 break;
16301 }
16302 return p;
16303
87779176 16304 case Tag_ABI_PID:
cd30bcef 16305 READ_ULEB (val, p, end);
87779176
JM
16306 printf (" Tag_ABI_PID: ");
16307 switch (val)
16308 {
16309 case 0:
16310 printf (_("Data addressing position-dependent\n"));
16311 break;
16312 case 1:
16313 printf (_("Data addressing position-independent, GOT near DP\n"));
16314 break;
16315 case 2:
16316 printf (_("Data addressing position-independent, GOT far from DP\n"));
16317 break;
16318 default:
16319 printf ("??? (%d)\n", val);
16320 break;
16321 }
16322 return p;
16323
16324 case Tag_ABI_PIC:
cd30bcef 16325 READ_ULEB (val, p, end);
87779176
JM
16326 printf (" Tag_ABI_PIC: ");
16327 switch (val)
16328 {
16329 case 0:
16330 printf (_("Code addressing position-dependent\n"));
16331 break;
16332 case 1:
16333 printf (_("Code addressing position-independent\n"));
16334 break;
16335 default:
16336 printf ("??? (%d)\n", val);
16337 break;
16338 }
16339 return p;
16340
16341 case Tag_ABI_array_object_alignment:
cd30bcef 16342 READ_ULEB (val, p, end);
87779176
JM
16343 printf (" Tag_ABI_array_object_alignment: ");
16344 switch (val)
16345 {
16346 case 0:
16347 printf (_("8-byte\n"));
16348 break;
16349 case 1:
16350 printf (_("4-byte\n"));
16351 break;
16352 case 2:
16353 printf (_("16-byte\n"));
16354 break;
16355 default:
16356 printf ("??? (%d)\n", val);
16357 break;
16358 }
16359 return p;
16360
16361 case Tag_ABI_array_object_align_expected:
cd30bcef 16362 READ_ULEB (val, p, end);
87779176
JM
16363 printf (" Tag_ABI_array_object_align_expected: ");
16364 switch (val)
16365 {
16366 case 0:
16367 printf (_("8-byte\n"));
16368 break;
16369 case 1:
16370 printf (_("4-byte\n"));
16371 break;
16372 case 2:
16373 printf (_("16-byte\n"));
16374 break;
16375 default:
16376 printf ("??? (%d)\n", val);
16377 break;
16378 }
16379 return p;
16380
3cbd1c06 16381 case Tag_ABI_compatibility:
071436c6 16382 {
cd30bcef 16383 READ_ULEB (val, p, end);
071436c6 16384 printf (" Tag_ABI_compatibility: ");
071436c6 16385 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16386 if (p < end - 1)
16387 {
16388 size_t maxlen = (end - p) - 1;
16389
16390 print_symbol ((int) maxlen, (const char *) p);
16391 p += strnlen ((char *) p, maxlen) + 1;
16392 }
16393 else
16394 {
16395 printf (_("<corrupt>"));
16396 p = (unsigned char *) end;
16397 }
071436c6 16398 putchar ('\n');
071436c6
NC
16399 return p;
16400 }
87779176
JM
16401
16402 case Tag_ABI_conformance:
071436c6 16403 {
4082ef84
NC
16404 printf (" Tag_ABI_conformance: \"");
16405 if (p < end - 1)
16406 {
16407 size_t maxlen = (end - p) - 1;
071436c6 16408
4082ef84
NC
16409 print_symbol ((int) maxlen, (const char *) p);
16410 p += strnlen ((char *) p, maxlen) + 1;
16411 }
16412 else
16413 {
16414 printf (_("<corrupt>"));
16415 p = (unsigned char *) end;
16416 }
071436c6 16417 printf ("\"\n");
071436c6
NC
16418 return p;
16419 }
59e6276b
JM
16420 }
16421
f6f0e17b
NC
16422 return display_tag_value (tag, p, end);
16423}
59e6276b 16424
f6f0e17b 16425static void
60abdbed 16426display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
16427{
16428 unsigned long addr = 0;
16429 size_t bytes = end - p;
16430
feceaa59 16431 assert (end >= p);
f6f0e17b 16432 while (bytes)
87779176 16433 {
f6f0e17b
NC
16434 int j;
16435 int k;
16436 int lbytes = (bytes > 16 ? 16 : bytes);
16437
16438 printf (" 0x%8.8lx ", addr);
16439
16440 for (j = 0; j < 16; j++)
16441 {
16442 if (j < lbytes)
16443 printf ("%2.2x", p[j]);
16444 else
16445 printf (" ");
16446
16447 if ((j & 3) == 3)
16448 printf (" ");
16449 }
16450
16451 for (j = 0; j < lbytes; j++)
16452 {
16453 k = p[j];
16454 if (k >= ' ' && k < 0x7f)
16455 printf ("%c", k);
16456 else
16457 printf (".");
16458 }
16459
16460 putchar ('\n');
16461
16462 p += lbytes;
16463 bytes -= lbytes;
16464 addr += lbytes;
87779176 16465 }
59e6276b 16466
f6f0e17b 16467 putchar ('\n');
59e6276b
JM
16468}
16469
13761a11 16470static unsigned char *
b0191216 16471display_msp430_attribute (unsigned char * p,
13761a11
NC
16472 const unsigned char * const end)
16473{
60abdbed
NC
16474 unsigned int val;
16475 unsigned int tag;
13761a11 16476
cd30bcef 16477 READ_ULEB (tag, p, end);
0b4362b0 16478
13761a11
NC
16479 switch (tag)
16480 {
16481 case OFBA_MSPABI_Tag_ISA:
13761a11 16482 printf (" Tag_ISA: ");
cd30bcef 16483 READ_ULEB (val, p, end);
13761a11
NC
16484 switch (val)
16485 {
16486 case 0: printf (_("None\n")); break;
16487 case 1: printf (_("MSP430\n")); break;
16488 case 2: printf (_("MSP430X\n")); break;
16489 default: printf ("??? (%d)\n", val); break;
16490 }
16491 break;
16492
16493 case OFBA_MSPABI_Tag_Code_Model:
13761a11 16494 printf (" Tag_Code_Model: ");
cd30bcef 16495 READ_ULEB (val, p, end);
13761a11
NC
16496 switch (val)
16497 {
16498 case 0: printf (_("None\n")); break;
16499 case 1: printf (_("Small\n")); break;
16500 case 2: printf (_("Large\n")); break;
16501 default: printf ("??? (%d)\n", val); break;
16502 }
16503 break;
16504
16505 case OFBA_MSPABI_Tag_Data_Model:
13761a11 16506 printf (" Tag_Data_Model: ");
cd30bcef 16507 READ_ULEB (val, p, end);
13761a11
NC
16508 switch (val)
16509 {
16510 case 0: printf (_("None\n")); break;
16511 case 1: printf (_("Small\n")); break;
16512 case 2: printf (_("Large\n")); break;
16513 case 3: printf (_("Restricted Large\n")); break;
16514 default: printf ("??? (%d)\n", val); break;
16515 }
16516 break;
16517
16518 default:
16519 printf (_(" <unknown tag %d>: "), tag);
16520
16521 if (tag & 1)
16522 {
071436c6 16523 putchar ('"');
4082ef84
NC
16524 if (p < end - 1)
16525 {
16526 size_t maxlen = (end - p) - 1;
16527
16528 print_symbol ((int) maxlen, (const char *) p);
16529 p += strnlen ((char *) p, maxlen) + 1;
16530 }
16531 else
16532 {
16533 printf (_("<corrupt>"));
16534 p = (unsigned char *) end;
16535 }
071436c6 16536 printf ("\"\n");
13761a11
NC
16537 }
16538 else
16539 {
cd30bcef 16540 READ_ULEB (val, p, end);
13761a11
NC
16541 printf ("%d (0x%x)\n", val, val);
16542 }
16543 break;
16544 }
16545
4082ef84 16546 assert (p <= end);
13761a11
NC
16547 return p;
16548}
16549
c0ea7c52
JL
16550static unsigned char *
16551display_msp430_gnu_attribute (unsigned char * p,
16552 unsigned int tag,
16553 const unsigned char * const end)
16554{
16555 if (tag == Tag_GNU_MSP430_Data_Region)
16556 {
cd30bcef 16557 unsigned int val;
c0ea7c52 16558
c0ea7c52 16559 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 16560 READ_ULEB (val, p, end);
c0ea7c52
JL
16561
16562 switch (val)
16563 {
16564 case Val_GNU_MSP430_Data_Region_Any:
16565 printf (_("Any Region\n"));
16566 break;
16567 case Val_GNU_MSP430_Data_Region_Lower:
16568 printf (_("Lower Region Only\n"));
16569 break;
16570 default:
cd30bcef 16571 printf ("??? (%u)\n", val);
c0ea7c52
JL
16572 }
16573 return p;
16574 }
16575 return display_tag_value (tag & 1, p, end);
16576}
16577
2dc8dd17
JW
16578struct riscv_attr_tag_t {
16579 const char *name;
cd30bcef 16580 unsigned int tag;
2dc8dd17
JW
16581};
16582
16583static struct riscv_attr_tag_t riscv_attr_tag[] =
16584{
16585#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
16586 T(arch),
16587 T(priv_spec),
16588 T(priv_spec_minor),
16589 T(priv_spec_revision),
16590 T(unaligned_access),
16591 T(stack_align),
16592#undef T
16593};
16594
16595static unsigned char *
16596display_riscv_attribute (unsigned char *p,
16597 const unsigned char * const end)
16598{
cd30bcef
AM
16599 unsigned int val;
16600 unsigned int tag;
2dc8dd17
JW
16601 struct riscv_attr_tag_t *attr = NULL;
16602 unsigned i;
16603
cd30bcef 16604 READ_ULEB (tag, p, end);
2dc8dd17
JW
16605
16606 /* Find the name of attribute. */
16607 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
16608 {
16609 if (riscv_attr_tag[i].tag == tag)
16610 {
16611 attr = &riscv_attr_tag[i];
16612 break;
16613 }
16614 }
16615
16616 if (attr)
16617 printf (" %s: ", attr->name);
16618 else
16619 return display_tag_value (tag, p, end);
16620
16621 switch (tag)
16622 {
16623 case Tag_RISCV_priv_spec:
16624 case Tag_RISCV_priv_spec_minor:
16625 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
16626 READ_ULEB (val, p, end);
16627 printf (_("%u\n"), val);
2dc8dd17
JW
16628 break;
16629 case Tag_RISCV_unaligned_access:
cd30bcef 16630 READ_ULEB (val, p, end);
2dc8dd17
JW
16631 switch (val)
16632 {
16633 case 0:
16634 printf (_("No unaligned access\n"));
16635 break;
16636 case 1:
16637 printf (_("Unaligned access\n"));
16638 break;
16639 }
16640 break;
16641 case Tag_RISCV_stack_align:
cd30bcef
AM
16642 READ_ULEB (val, p, end);
16643 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
16644 break;
16645 case Tag_RISCV_arch:
16646 p = display_tag_value (-1, p, end);
16647 break;
16648 default:
16649 return display_tag_value (tag, p, end);
16650 }
16651
16652 return p;
16653}
16654
0861f561
CQ
16655static unsigned char *
16656display_csky_attribute (unsigned char * p,
16657 const unsigned char * const end)
16658{
16659 unsigned int tag;
16660 unsigned int val;
16661 READ_ULEB (tag, p, end);
16662
16663 if (tag >= Tag_CSKY_MAX)
16664 {
16665 return display_tag_value (-1, p, end);
16666 }
16667
16668 switch (tag)
16669 {
16670 case Tag_CSKY_ARCH_NAME:
16671 printf (" Tag_CSKY_ARCH_NAME:\t\t");
16672 return display_tag_value (-1, p, end);
16673 case Tag_CSKY_CPU_NAME:
16674 printf (" Tag_CSKY_CPU_NAME:\t\t");
16675 return display_tag_value (-1, p, end);
16676
16677 case Tag_CSKY_ISA_FLAGS:
16678 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
16679 return display_tag_value (0, p, end);
16680 case Tag_CSKY_ISA_EXT_FLAGS:
16681 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
16682 return display_tag_value (0, p, end);
16683
16684 case Tag_CSKY_DSP_VERSION:
16685 printf (" Tag_CSKY_DSP_VERSION:\t\t");
16686 READ_ULEB (val, p, end);
16687 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
16688 printf ("DSP Extension\n");
16689 else if (val == VAL_CSKY_DSP_VERSION_2)
16690 printf ("DSP 2.0\n");
16691 break;
16692
16693 case Tag_CSKY_VDSP_VERSION:
16694 printf (" Tag_CSKY_VDSP_VERSION:\t");
16695 READ_ULEB (val, p, end);
16696 printf ("VDSP Version %d\n", val);
16697 break;
16698
16699 case Tag_CSKY_FPU_VERSION:
16700 printf (" Tag_CSKY_FPU_VERSION:\t\t");
16701 READ_ULEB (val, p, end);
16702 if (val == VAL_CSKY_FPU_VERSION_1)
16703 printf ("ABIV1 FPU Version 1\n");
16704 else if (val == VAL_CSKY_FPU_VERSION_2)
16705 printf ("FPU Version 2\n");
16706 break;
16707
16708 case Tag_CSKY_FPU_ABI:
16709 printf (" Tag_CSKY_FPU_ABI:\t\t");
16710 READ_ULEB (val, p, end);
16711 if (val == VAL_CSKY_FPU_ABI_HARD)
16712 printf ("Hard\n");
16713 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
16714 printf ("SoftFP\n");
16715 else if (val == VAL_CSKY_FPU_ABI_SOFT)
16716 printf ("Soft\n");
16717 break;
16718 case Tag_CSKY_FPU_ROUNDING:
16719 READ_ULEB (val, p, end);
16720 if (val == 1) {
16721 printf (" Tag_CSKY_FPU_ROUNDING:\t");
16722 printf ("Needed\n");
16723 }
16724 break;
16725 case Tag_CSKY_FPU_DENORMAL:
16726 READ_ULEB (val, p, end);
16727 if (val == 1) {
16728 printf (" Tag_CSKY_FPU_DENORMAL:\t");
16729 printf ("Needed\n");
16730 }
16731 break;
16732 case Tag_CSKY_FPU_Exception:
16733 READ_ULEB (val, p, end);
16734 if (val == 1) {
16735 printf (" Tag_CSKY_FPU_Exception:\t");
16736 printf ("Needed\n");
16737 }
16738 break;
16739 case Tag_CSKY_FPU_NUMBER_MODULE:
16740 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
16741 return display_tag_value (-1, p, end);
16742 case Tag_CSKY_FPU_HARDFP:
16743 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
16744 READ_ULEB (val, p, end);
16745 if (val & VAL_CSKY_FPU_HARDFP_HALF)
16746 printf (" Half");
16747 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
16748 printf (" Single");
16749 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
16750 printf (" Double");
16751 printf ("\n");
16752 break;
16753 default:
16754 return display_tag_value (tag, p, end);
16755 }
16756 return p;
16757}
16758
32ec8896 16759static bfd_boolean
dda8d76d 16760process_attributes (Filedata * filedata,
60bca95a 16761 const char * public_name,
104d59d1 16762 unsigned int proc_type,
f6f0e17b 16763 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 16764 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 16765{
2cf0635d 16766 Elf_Internal_Shdr * sect;
11c1ff18 16767 unsigned i;
32ec8896 16768 bfd_boolean res = TRUE;
11c1ff18
PB
16769
16770 /* Find the section header so that we get the size. */
dda8d76d
NC
16771 for (i = 0, sect = filedata->section_headers;
16772 i < filedata->file_header.e_shnum;
11c1ff18
PB
16773 i++, sect++)
16774 {
071436c6
NC
16775 unsigned char * contents;
16776 unsigned char * p;
16777
104d59d1 16778 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
16779 continue;
16780
dda8d76d 16781 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 16782 sect->sh_size, _("attributes"));
60bca95a 16783 if (contents == NULL)
32ec8896
NC
16784 {
16785 res = FALSE;
16786 continue;
16787 }
60bca95a 16788
11c1ff18 16789 p = contents;
60abdbed
NC
16790 /* The first character is the version of the attributes.
16791 Currently only version 1, (aka 'A') is recognised here. */
16792 if (*p != 'A')
32ec8896
NC
16793 {
16794 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
16795 res = FALSE;
16796 }
60abdbed 16797 else
11c1ff18 16798 {
071436c6
NC
16799 bfd_vma section_len;
16800
16801 section_len = sect->sh_size - 1;
11c1ff18 16802 p++;
60bca95a 16803
071436c6 16804 while (section_len > 0)
11c1ff18 16805 {
071436c6 16806 bfd_vma attr_len;
e9847026 16807 unsigned int namelen;
11c1ff18 16808 bfd_boolean public_section;
104d59d1 16809 bfd_boolean gnu_section;
11c1ff18 16810
071436c6 16811 if (section_len <= 4)
e0a31db1
NC
16812 {
16813 error (_("Tag section ends prematurely\n"));
32ec8896 16814 res = FALSE;
e0a31db1
NC
16815 break;
16816 }
071436c6 16817 attr_len = byte_get (p, 4);
11c1ff18 16818 p += 4;
60bca95a 16819
071436c6 16820 if (attr_len > section_len)
11c1ff18 16821 {
071436c6
NC
16822 error (_("Bad attribute length (%u > %u)\n"),
16823 (unsigned) attr_len, (unsigned) section_len);
16824 attr_len = section_len;
32ec8896 16825 res = FALSE;
11c1ff18 16826 }
74e1a04b 16827 /* PR 17531: file: 001-101425-0.004 */
071436c6 16828 else if (attr_len < 5)
74e1a04b 16829 {
071436c6 16830 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
32ec8896 16831 res = FALSE;
74e1a04b
NC
16832 break;
16833 }
e9847026 16834
071436c6
NC
16835 section_len -= attr_len;
16836 attr_len -= 4;
16837
16838 namelen = strnlen ((char *) p, attr_len) + 1;
16839 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
16840 {
16841 error (_("Corrupt attribute section name\n"));
32ec8896 16842 res = FALSE;
e9847026
NC
16843 break;
16844 }
16845
071436c6
NC
16846 printf (_("Attribute Section: "));
16847 print_symbol (INT_MAX, (const char *) p);
16848 putchar ('\n');
60bca95a
NC
16849
16850 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
16851 public_section = TRUE;
16852 else
16853 public_section = FALSE;
60bca95a
NC
16854
16855 if (streq ((char *) p, "gnu"))
104d59d1
JM
16856 gnu_section = TRUE;
16857 else
16858 gnu_section = FALSE;
60bca95a 16859
11c1ff18 16860 p += namelen;
071436c6 16861 attr_len -= namelen;
e0a31db1 16862
071436c6 16863 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 16864 {
e0a31db1 16865 int tag;
cd30bcef 16866 unsigned int val;
11c1ff18 16867 bfd_vma size;
071436c6 16868 unsigned char * end;
60bca95a 16869
e0a31db1 16870 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 16871 if (attr_len < 6)
e0a31db1
NC
16872 {
16873 error (_("Unused bytes at end of section\n"));
32ec8896 16874 res = FALSE;
e0a31db1
NC
16875 section_len = 0;
16876 break;
16877 }
16878
16879 tag = *(p++);
11c1ff18 16880 size = byte_get (p, 4);
071436c6 16881 if (size > attr_len)
11c1ff18 16882 {
e9847026 16883 error (_("Bad subsection length (%u > %u)\n"),
071436c6 16884 (unsigned) size, (unsigned) attr_len);
32ec8896 16885 res = FALSE;
071436c6 16886 size = attr_len;
11c1ff18 16887 }
e0a31db1
NC
16888 /* PR binutils/17531: Safe handling of corrupt files. */
16889 if (size < 6)
16890 {
16891 error (_("Bad subsection length (%u < 6)\n"),
16892 (unsigned) size);
32ec8896 16893 res = FALSE;
e0a31db1
NC
16894 section_len = 0;
16895 break;
16896 }
60bca95a 16897
071436c6 16898 attr_len -= size;
11c1ff18 16899 end = p + size - 1;
071436c6 16900 assert (end <= contents + sect->sh_size);
11c1ff18 16901 p += 4;
60bca95a 16902
11c1ff18
PB
16903 switch (tag)
16904 {
16905 case 1:
2b692964 16906 printf (_("File Attributes\n"));
11c1ff18
PB
16907 break;
16908 case 2:
2b692964 16909 printf (_("Section Attributes:"));
11c1ff18
PB
16910 goto do_numlist;
16911 case 3:
2b692964 16912 printf (_("Symbol Attributes:"));
1a0670f3 16913 /* Fall through. */
11c1ff18
PB
16914 do_numlist:
16915 for (;;)
16916 {
cd30bcef 16917 READ_ULEB (val, p, end);
11c1ff18
PB
16918 if (val == 0)
16919 break;
16920 printf (" %d", val);
16921 }
16922 printf ("\n");
16923 break;
16924 default:
2b692964 16925 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
16926 public_section = FALSE;
16927 break;
16928 }
60bca95a 16929
071436c6 16930 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
16931 {
16932 while (p < end)
f6f0e17b 16933 p = display_pub_attribute (p, end);
60abdbed 16934 assert (p == end);
104d59d1 16935 }
071436c6 16936 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
16937 {
16938 while (p < end)
16939 p = display_gnu_attribute (p,
f6f0e17b
NC
16940 display_proc_gnu_attribute,
16941 end);
60abdbed 16942 assert (p == end);
11c1ff18 16943 }
071436c6 16944 else if (p < end)
11c1ff18 16945 {
071436c6 16946 printf (_(" Unknown attribute:\n"));
f6f0e17b 16947 display_raw_attribute (p, end);
11c1ff18
PB
16948 p = end;
16949 }
071436c6
NC
16950 else
16951 attr_len = 0;
11c1ff18
PB
16952 }
16953 }
16954 }
d70c5fc7 16955
60bca95a 16956 free (contents);
11c1ff18 16957 }
32ec8896
NC
16958
16959 return res;
11c1ff18
PB
16960}
16961
ccb4c951
RS
16962/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
16963 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
16964 and return the VMA of the next entry, or -1 if there was a problem.
16965 Does not read from DATA_END or beyond. */
ccb4c951
RS
16966
16967static bfd_vma
82b1b41b
NC
16968print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
16969 unsigned char * data_end)
ccb4c951
RS
16970{
16971 printf (" ");
16972 print_vma (addr, LONG_HEX);
16973 printf (" ");
16974 if (addr < pltgot + 0xfff0)
16975 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
16976 else
16977 printf ("%10s", "");
16978 printf (" ");
16979 if (data == NULL)
2b692964 16980 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
16981 else
16982 {
16983 bfd_vma entry;
82b1b41b 16984 unsigned char * from = data + addr - pltgot;
ccb4c951 16985
82b1b41b
NC
16986 if (from + (is_32bit_elf ? 4 : 8) > data_end)
16987 {
16988 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
16989 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
16990 return (bfd_vma) -1;
16991 }
16992 else
16993 {
16994 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
16995 print_vma (entry, LONG_HEX);
16996 }
ccb4c951
RS
16997 }
16998 return addr + (is_32bit_elf ? 4 : 8);
16999}
17000
861fb55a
DJ
17001/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
17002 PLTGOT. Print the Address and Initial fields of an entry at VMA
17003 ADDR and return the VMA of the next entry. */
17004
17005static bfd_vma
2cf0635d 17006print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
17007{
17008 printf (" ");
17009 print_vma (addr, LONG_HEX);
17010 printf (" ");
17011 if (data == NULL)
2b692964 17012 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
17013 else
17014 {
17015 bfd_vma entry;
17016
17017 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17018 print_vma (entry, LONG_HEX);
17019 }
17020 return addr + (is_32bit_elf ? 4 : 8);
17021}
17022
351cdf24
MF
17023static void
17024print_mips_ases (unsigned int mask)
17025{
17026 if (mask & AFL_ASE_DSP)
17027 fputs ("\n\tDSP ASE", stdout);
17028 if (mask & AFL_ASE_DSPR2)
17029 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
17030 if (mask & AFL_ASE_DSPR3)
17031 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
17032 if (mask & AFL_ASE_EVA)
17033 fputs ("\n\tEnhanced VA Scheme", stdout);
17034 if (mask & AFL_ASE_MCU)
17035 fputs ("\n\tMCU (MicroController) ASE", stdout);
17036 if (mask & AFL_ASE_MDMX)
17037 fputs ("\n\tMDMX ASE", stdout);
17038 if (mask & AFL_ASE_MIPS3D)
17039 fputs ("\n\tMIPS-3D ASE", stdout);
17040 if (mask & AFL_ASE_MT)
17041 fputs ("\n\tMT ASE", stdout);
17042 if (mask & AFL_ASE_SMARTMIPS)
17043 fputs ("\n\tSmartMIPS ASE", stdout);
17044 if (mask & AFL_ASE_VIRT)
17045 fputs ("\n\tVZ ASE", stdout);
17046 if (mask & AFL_ASE_MSA)
17047 fputs ("\n\tMSA ASE", stdout);
17048 if (mask & AFL_ASE_MIPS16)
17049 fputs ("\n\tMIPS16 ASE", stdout);
17050 if (mask & AFL_ASE_MICROMIPS)
17051 fputs ("\n\tMICROMIPS ASE", stdout);
17052 if (mask & AFL_ASE_XPA)
17053 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
17054 if (mask & AFL_ASE_MIPS16E2)
17055 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
17056 if (mask & AFL_ASE_CRC)
17057 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
17058 if (mask & AFL_ASE_GINV)
17059 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
17060 if (mask & AFL_ASE_LOONGSON_MMI)
17061 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
17062 if (mask & AFL_ASE_LOONGSON_CAM)
17063 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
17064 if (mask & AFL_ASE_LOONGSON_EXT)
17065 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
17066 if (mask & AFL_ASE_LOONGSON_EXT2)
17067 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
17068 if (mask == 0)
17069 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
17070 else if ((mask & ~AFL_ASE_MASK) != 0)
17071 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
17072}
17073
17074static void
17075print_mips_isa_ext (unsigned int isa_ext)
17076{
17077 switch (isa_ext)
17078 {
17079 case 0:
17080 fputs (_("None"), stdout);
17081 break;
17082 case AFL_EXT_XLR:
17083 fputs ("RMI XLR", stdout);
17084 break;
2c629856
N
17085 case AFL_EXT_OCTEON3:
17086 fputs ("Cavium Networks Octeon3", stdout);
17087 break;
351cdf24
MF
17088 case AFL_EXT_OCTEON2:
17089 fputs ("Cavium Networks Octeon2", stdout);
17090 break;
17091 case AFL_EXT_OCTEONP:
17092 fputs ("Cavium Networks OcteonP", stdout);
17093 break;
351cdf24
MF
17094 case AFL_EXT_OCTEON:
17095 fputs ("Cavium Networks Octeon", stdout);
17096 break;
17097 case AFL_EXT_5900:
17098 fputs ("Toshiba R5900", stdout);
17099 break;
17100 case AFL_EXT_4650:
17101 fputs ("MIPS R4650", stdout);
17102 break;
17103 case AFL_EXT_4010:
17104 fputs ("LSI R4010", stdout);
17105 break;
17106 case AFL_EXT_4100:
17107 fputs ("NEC VR4100", stdout);
17108 break;
17109 case AFL_EXT_3900:
17110 fputs ("Toshiba R3900", stdout);
17111 break;
17112 case AFL_EXT_10000:
17113 fputs ("MIPS R10000", stdout);
17114 break;
17115 case AFL_EXT_SB1:
17116 fputs ("Broadcom SB-1", stdout);
17117 break;
17118 case AFL_EXT_4111:
17119 fputs ("NEC VR4111/VR4181", stdout);
17120 break;
17121 case AFL_EXT_4120:
17122 fputs ("NEC VR4120", stdout);
17123 break;
17124 case AFL_EXT_5400:
17125 fputs ("NEC VR5400", stdout);
17126 break;
17127 case AFL_EXT_5500:
17128 fputs ("NEC VR5500", stdout);
17129 break;
17130 case AFL_EXT_LOONGSON_2E:
17131 fputs ("ST Microelectronics Loongson 2E", stdout);
17132 break;
17133 case AFL_EXT_LOONGSON_2F:
17134 fputs ("ST Microelectronics Loongson 2F", stdout);
17135 break;
38bf472a
MR
17136 case AFL_EXT_INTERAPTIV_MR2:
17137 fputs ("Imagination interAptiv MR2", stdout);
17138 break;
351cdf24 17139 default:
00ac7aa0 17140 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
17141 }
17142}
17143
32ec8896 17144static signed int
351cdf24
MF
17145get_mips_reg_size (int reg_size)
17146{
17147 return (reg_size == AFL_REG_NONE) ? 0
17148 : (reg_size == AFL_REG_32) ? 32
17149 : (reg_size == AFL_REG_64) ? 64
17150 : (reg_size == AFL_REG_128) ? 128
17151 : -1;
17152}
17153
32ec8896 17154static bfd_boolean
dda8d76d 17155process_mips_specific (Filedata * filedata)
5b18a4bc 17156{
2cf0635d 17157 Elf_Internal_Dyn * entry;
351cdf24 17158 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
17159 size_t liblist_offset = 0;
17160 size_t liblistno = 0;
17161 size_t conflictsno = 0;
17162 size_t options_offset = 0;
17163 size_t conflicts_offset = 0;
861fb55a
DJ
17164 size_t pltrelsz = 0;
17165 size_t pltrel = 0;
ccb4c951 17166 bfd_vma pltgot = 0;
861fb55a
DJ
17167 bfd_vma mips_pltgot = 0;
17168 bfd_vma jmprel = 0;
ccb4c951
RS
17169 bfd_vma local_gotno = 0;
17170 bfd_vma gotsym = 0;
17171 bfd_vma symtabno = 0;
32ec8896 17172 bfd_boolean res = TRUE;
103f02d3 17173
dda8d76d 17174 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896
NC
17175 display_mips_gnu_attribute))
17176 res = FALSE;
2cf19d5c 17177
dda8d76d 17178 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
17179
17180 if (sect != NULL)
17181 {
17182 Elf_External_ABIFlags_v0 *abiflags_ext;
17183 Elf_Internal_ABIFlags_v0 abiflags_in;
17184
17185 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
17186 {
17187 error (_("Corrupt MIPS ABI Flags section.\n"));
17188 res = FALSE;
17189 }
351cdf24
MF
17190 else
17191 {
dda8d76d 17192 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
17193 sect->sh_size, _("MIPS ABI Flags section"));
17194 if (abiflags_ext)
17195 {
17196 abiflags_in.version = BYTE_GET (abiflags_ext->version);
17197 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
17198 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
17199 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
17200 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
17201 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
17202 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
17203 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
17204 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
17205 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
17206 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
17207
17208 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
17209 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
17210 if (abiflags_in.isa_rev > 1)
17211 printf ("r%d", abiflags_in.isa_rev);
17212 printf ("\nGPR size: %d",
17213 get_mips_reg_size (abiflags_in.gpr_size));
17214 printf ("\nCPR1 size: %d",
17215 get_mips_reg_size (abiflags_in.cpr1_size));
17216 printf ("\nCPR2 size: %d",
17217 get_mips_reg_size (abiflags_in.cpr2_size));
17218 fputs ("\nFP ABI: ", stdout);
17219 print_mips_fp_abi_value (abiflags_in.fp_abi);
17220 fputs ("ISA Extension: ", stdout);
17221 print_mips_isa_ext (abiflags_in.isa_ext);
17222 fputs ("\nASEs:", stdout);
17223 print_mips_ases (abiflags_in.ases);
17224 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
17225 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
17226 fputc ('\n', stdout);
17227 free (abiflags_ext);
17228 }
17229 }
17230 }
17231
19e6b90e 17232 /* We have a lot of special sections. Thanks SGI! */
978c4450 17233 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
17234 {
17235 /* No dynamic information available. See if there is static GOT. */
dda8d76d 17236 sect = find_section (filedata, ".got");
bbdd9a68
MR
17237 if (sect != NULL)
17238 {
17239 unsigned char *data_end;
17240 unsigned char *data;
17241 bfd_vma ent, end;
17242 int addr_size;
17243
17244 pltgot = sect->sh_addr;
17245
17246 ent = pltgot;
17247 addr_size = (is_32bit_elf ? 4 : 8);
17248 end = pltgot + sect->sh_size;
17249
dda8d76d 17250 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
17251 end - pltgot, 1,
17252 _("Global Offset Table data"));
17253 /* PR 12855: Null data is handled gracefully throughout. */
17254 data_end = data + (end - pltgot);
17255
17256 printf (_("\nStatic GOT:\n"));
17257 printf (_(" Canonical gp value: "));
17258 print_vma (ent + 0x7ff0, LONG_HEX);
17259 printf ("\n\n");
17260
17261 /* In a dynamic binary GOT[0] is reserved for the dynamic
17262 loader to store the lazy resolver pointer, however in
17263 a static binary it may well have been omitted and GOT
17264 reduced to a table of addresses.
17265 PR 21344: Check for the entry being fully available
17266 before fetching it. */
17267 if (data
17268 && data + ent - pltgot + addr_size <= data_end
17269 && byte_get (data + ent - pltgot, addr_size) == 0)
17270 {
17271 printf (_(" Reserved entries:\n"));
17272 printf (_(" %*s %10s %*s\n"),
17273 addr_size * 2, _("Address"), _("Access"),
17274 addr_size * 2, _("Value"));
17275 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17276 printf ("\n");
17277 if (ent == (bfd_vma) -1)
17278 goto sgot_print_fail;
17279
17280 /* Check for the MSB of GOT[1] being set, identifying a
17281 GNU object. This entry will be used by some runtime
17282 loaders, to store the module pointer. Otherwise this
17283 is an ordinary local entry.
17284 PR 21344: Check for the entry being fully available
17285 before fetching it. */
17286 if (data
17287 && data + ent - pltgot + addr_size <= data_end
17288 && (byte_get (data + ent - pltgot, addr_size)
17289 >> (addr_size * 8 - 1)) != 0)
17290 {
17291 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17292 printf ("\n");
17293 if (ent == (bfd_vma) -1)
17294 goto sgot_print_fail;
17295 }
17296 printf ("\n");
17297 }
17298
f17e9d8a 17299 if (data != NULL && ent < end)
bbdd9a68
MR
17300 {
17301 printf (_(" Local entries:\n"));
17302 printf (" %*s %10s %*s\n",
17303 addr_size * 2, _("Address"), _("Access"),
17304 addr_size * 2, _("Value"));
17305 while (ent < end)
17306 {
17307 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17308 printf ("\n");
17309 if (ent == (bfd_vma) -1)
17310 goto sgot_print_fail;
17311 }
17312 printf ("\n");
17313 }
17314
17315 sgot_print_fail:
9db70fc3 17316 free (data);
bbdd9a68
MR
17317 }
17318 return res;
17319 }
252b5132 17320
978c4450 17321 for (entry = filedata->dynamic_section;
071436c6 17322 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
17323 (entry < filedata->dynamic_section + filedata->dynamic_nent
17324 && entry->d_tag != DT_NULL);
071436c6 17325 ++entry)
252b5132
RH
17326 switch (entry->d_tag)
17327 {
17328 case DT_MIPS_LIBLIST:
d93f0186 17329 liblist_offset
dda8d76d 17330 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17331 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
17332 break;
17333 case DT_MIPS_LIBLISTNO:
17334 liblistno = entry->d_un.d_val;
17335 break;
17336 case DT_MIPS_OPTIONS:
dda8d76d 17337 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
17338 break;
17339 case DT_MIPS_CONFLICT:
d93f0186 17340 conflicts_offset
dda8d76d 17341 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17342 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
17343 break;
17344 case DT_MIPS_CONFLICTNO:
17345 conflictsno = entry->d_un.d_val;
17346 break;
ccb4c951 17347 case DT_PLTGOT:
861fb55a
DJ
17348 pltgot = entry->d_un.d_ptr;
17349 break;
ccb4c951
RS
17350 case DT_MIPS_LOCAL_GOTNO:
17351 local_gotno = entry->d_un.d_val;
17352 break;
17353 case DT_MIPS_GOTSYM:
17354 gotsym = entry->d_un.d_val;
17355 break;
17356 case DT_MIPS_SYMTABNO:
17357 symtabno = entry->d_un.d_val;
17358 break;
861fb55a
DJ
17359 case DT_MIPS_PLTGOT:
17360 mips_pltgot = entry->d_un.d_ptr;
17361 break;
17362 case DT_PLTREL:
17363 pltrel = entry->d_un.d_val;
17364 break;
17365 case DT_PLTRELSZ:
17366 pltrelsz = entry->d_un.d_val;
17367 break;
17368 case DT_JMPREL:
17369 jmprel = entry->d_un.d_ptr;
17370 break;
252b5132
RH
17371 default:
17372 break;
17373 }
17374
17375 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
17376 {
2cf0635d 17377 Elf32_External_Lib * elib;
252b5132
RH
17378 size_t cnt;
17379
dda8d76d 17380 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
17381 sizeof (Elf32_External_Lib),
17382 liblistno,
17383 _("liblist section data"));
a6e9f9df 17384 if (elib)
252b5132 17385 {
d3a49aa8
AM
17386 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
17387 "\nSection '.liblist' contains %lu entries:\n",
17388 (unsigned long) liblistno),
a6e9f9df 17389 (unsigned long) liblistno);
2b692964 17390 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
17391 stdout);
17392
17393 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 17394 {
a6e9f9df 17395 Elf32_Lib liblist;
91d6fa6a 17396 time_t atime;
d5b07ef4 17397 char timebuf[128];
2cf0635d 17398 struct tm * tmp;
a6e9f9df
AM
17399
17400 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17401 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
17402 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17403 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17404 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17405
91d6fa6a 17406 tmp = gmtime (&atime);
e9e44622
JJ
17407 snprintf (timebuf, sizeof (timebuf),
17408 "%04u-%02u-%02uT%02u:%02u:%02u",
17409 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17410 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 17411
31104126 17412 printf ("%3lu: ", (unsigned long) cnt);
978c4450
AM
17413 if (VALID_DYNAMIC_NAME (filedata, liblist.l_name))
17414 print_symbol (20, GET_DYNAMIC_NAME (filedata, liblist.l_name));
d79b3d50 17415 else
2b692964 17416 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
17417 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
17418 liblist.l_version);
a6e9f9df
AM
17419
17420 if (liblist.l_flags == 0)
2b692964 17421 puts (_(" NONE"));
a6e9f9df
AM
17422 else
17423 {
17424 static const struct
252b5132 17425 {
2cf0635d 17426 const char * name;
a6e9f9df 17427 int bit;
252b5132 17428 }
a6e9f9df
AM
17429 l_flags_vals[] =
17430 {
17431 { " EXACT_MATCH", LL_EXACT_MATCH },
17432 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
17433 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
17434 { " EXPORTS", LL_EXPORTS },
17435 { " DELAY_LOAD", LL_DELAY_LOAD },
17436 { " DELTA", LL_DELTA }
17437 };
17438 int flags = liblist.l_flags;
17439 size_t fcnt;
17440
60bca95a 17441 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
17442 if ((flags & l_flags_vals[fcnt].bit) != 0)
17443 {
17444 fputs (l_flags_vals[fcnt].name, stdout);
17445 flags ^= l_flags_vals[fcnt].bit;
17446 }
17447 if (flags != 0)
17448 printf (" %#x", (unsigned int) flags);
252b5132 17449
a6e9f9df
AM
17450 puts ("");
17451 }
252b5132 17452 }
252b5132 17453
a6e9f9df
AM
17454 free (elib);
17455 }
32ec8896
NC
17456 else
17457 res = FALSE;
252b5132
RH
17458 }
17459
17460 if (options_offset != 0)
17461 {
2cf0635d 17462 Elf_External_Options * eopt;
252b5132
RH
17463 size_t offset;
17464 int cnt;
dda8d76d 17465 sect = filedata->section_headers;
252b5132
RH
17466
17467 /* Find the section header so that we get the size. */
dda8d76d 17468 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 17469 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
17470 if (sect == NULL)
17471 {
17472 error (_("No MIPS_OPTIONS header found\n"));
32ec8896 17473 return FALSE;
071436c6 17474 }
7fc0c668
NC
17475 /* PR 24243 */
17476 if (sect->sh_size < sizeof (* eopt))
17477 {
17478 error (_("The MIPS options section is too small.\n"));
17479 return FALSE;
17480 }
252b5132 17481
dda8d76d 17482 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 17483 sect->sh_size, _("options"));
a6e9f9df 17484 if (eopt)
252b5132 17485 {
fd17d1e6 17486 Elf_Internal_Options option;
76da6bbe 17487
a6e9f9df 17488 offset = cnt = 0;
82b1b41b 17489 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 17490 {
2cf0635d 17491 Elf_External_Options * eoption;
fd17d1e6 17492 unsigned int optsize;
252b5132 17493
a6e9f9df 17494 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 17495
fd17d1e6 17496 optsize = BYTE_GET (eoption->size);
76da6bbe 17497
82b1b41b 17498 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
17499 if (optsize < sizeof (* eopt)
17500 || optsize > sect->sh_size - offset)
82b1b41b 17501 {
645f43a8 17502 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 17503 optsize);
645f43a8 17504 free (eopt);
32ec8896 17505 return FALSE;
82b1b41b 17506 }
fd17d1e6 17507 offset += optsize;
a6e9f9df
AM
17508 ++cnt;
17509 }
252b5132 17510
d3a49aa8
AM
17511 printf (ngettext ("\nSection '%s' contains %d entry:\n",
17512 "\nSection '%s' contains %d entries:\n",
17513 cnt),
dda8d76d 17514 printable_section_name (filedata, sect), cnt);
76da6bbe 17515
82b1b41b 17516 offset = 0;
a6e9f9df 17517 while (cnt-- > 0)
252b5132 17518 {
a6e9f9df 17519 size_t len;
fd17d1e6
AM
17520 Elf_External_Options * eoption;
17521
17522 eoption = (Elf_External_Options *) ((char *) eopt + offset);
17523
17524 option.kind = BYTE_GET (eoption->kind);
17525 option.size = BYTE_GET (eoption->size);
17526 option.section = BYTE_GET (eoption->section);
17527 option.info = BYTE_GET (eoption->info);
a6e9f9df 17528
fd17d1e6 17529 switch (option.kind)
252b5132 17530 {
a6e9f9df
AM
17531 case ODK_NULL:
17532 /* This shouldn't happen. */
d0c4e780 17533 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 17534 option.section, option.info);
a6e9f9df 17535 break;
2e6be59c 17536
a6e9f9df
AM
17537 case ODK_REGINFO:
17538 printf (" REGINFO ");
dda8d76d 17539 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 17540 {
2cf0635d 17541 Elf32_External_RegInfo * ereg;
b34976b6 17542 Elf32_RegInfo reginfo;
a6e9f9df 17543
2e6be59c 17544 /* 32bit form. */
fd17d1e6
AM
17545 if (option.size < (sizeof (Elf_External_Options)
17546 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
17547 {
17548 printf (_("<corrupt>\n"));
17549 error (_("Truncated MIPS REGINFO option\n"));
17550 cnt = 0;
17551 break;
17552 }
17553
fd17d1e6 17554 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 17555
a6e9f9df
AM
17556 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17557 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17558 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17559 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17560 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
17561 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
17562
d0c4e780
AM
17563 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
17564 reginfo.ri_gprmask, reginfo.ri_gp_value);
17565 printf (" "
17566 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
17567 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
17568 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17569 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17570 }
17571 else
17572 {
17573 /* 64 bit form. */
2cf0635d 17574 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
17575 Elf64_Internal_RegInfo reginfo;
17576
fd17d1e6
AM
17577 if (option.size < (sizeof (Elf_External_Options)
17578 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
17579 {
17580 printf (_("<corrupt>\n"));
17581 error (_("Truncated MIPS REGINFO option\n"));
17582 cnt = 0;
17583 break;
17584 }
17585
fd17d1e6 17586 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
17587 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17588 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17589 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17590 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17591 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 17592 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 17593
d0c4e780
AM
17594 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
17595 reginfo.ri_gprmask, reginfo.ri_gp_value);
17596 printf (" "
17597 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
17598 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
17599 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17600 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17601 }
fd17d1e6 17602 offset += option.size;
a6e9f9df 17603 continue;
2e6be59c 17604
a6e9f9df
AM
17605 case ODK_EXCEPTIONS:
17606 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 17607 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 17608 fputs (") fpe_max(", stdout);
fd17d1e6 17609 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
17610 fputs (")", stdout);
17611
fd17d1e6 17612 if (option.info & OEX_PAGE0)
a6e9f9df 17613 fputs (" PAGE0", stdout);
fd17d1e6 17614 if (option.info & OEX_SMM)
a6e9f9df 17615 fputs (" SMM", stdout);
fd17d1e6 17616 if (option.info & OEX_FPDBUG)
a6e9f9df 17617 fputs (" FPDBUG", stdout);
fd17d1e6 17618 if (option.info & OEX_DISMISS)
a6e9f9df
AM
17619 fputs (" DISMISS", stdout);
17620 break;
2e6be59c 17621
a6e9f9df
AM
17622 case ODK_PAD:
17623 fputs (" PAD ", stdout);
fd17d1e6 17624 if (option.info & OPAD_PREFIX)
a6e9f9df 17625 fputs (" PREFIX", stdout);
fd17d1e6 17626 if (option.info & OPAD_POSTFIX)
a6e9f9df 17627 fputs (" POSTFIX", stdout);
fd17d1e6 17628 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
17629 fputs (" SYMBOL", stdout);
17630 break;
2e6be59c 17631
a6e9f9df
AM
17632 case ODK_HWPATCH:
17633 fputs (" HWPATCH ", stdout);
fd17d1e6 17634 if (option.info & OHW_R4KEOP)
a6e9f9df 17635 fputs (" R4KEOP", stdout);
fd17d1e6 17636 if (option.info & OHW_R8KPFETCH)
a6e9f9df 17637 fputs (" R8KPFETCH", stdout);
fd17d1e6 17638 if (option.info & OHW_R5KEOP)
a6e9f9df 17639 fputs (" R5KEOP", stdout);
fd17d1e6 17640 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
17641 fputs (" R5KCVTL", stdout);
17642 break;
2e6be59c 17643
a6e9f9df
AM
17644 case ODK_FILL:
17645 fputs (" FILL ", stdout);
17646 /* XXX Print content of info word? */
17647 break;
2e6be59c 17648
a6e9f9df
AM
17649 case ODK_TAGS:
17650 fputs (" TAGS ", stdout);
17651 /* XXX Print content of info word? */
17652 break;
2e6be59c 17653
a6e9f9df
AM
17654 case ODK_HWAND:
17655 fputs (" HWAND ", stdout);
fd17d1e6 17656 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 17657 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 17658 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
17659 fputs (" R4KEOP_CLEAN", stdout);
17660 break;
2e6be59c 17661
a6e9f9df
AM
17662 case ODK_HWOR:
17663 fputs (" HWOR ", stdout);
fd17d1e6 17664 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 17665 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 17666 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
17667 fputs (" R4KEOP_CLEAN", stdout);
17668 break;
2e6be59c 17669
a6e9f9df 17670 case ODK_GP_GROUP:
d0c4e780 17671 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
17672 option.info & OGP_GROUP,
17673 (option.info & OGP_SELF) >> 16);
a6e9f9df 17674 break;
2e6be59c 17675
a6e9f9df 17676 case ODK_IDENT:
d0c4e780 17677 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
17678 option.info & OGP_GROUP,
17679 (option.info & OGP_SELF) >> 16);
a6e9f9df 17680 break;
2e6be59c 17681
a6e9f9df
AM
17682 default:
17683 /* This shouldn't happen. */
d0c4e780 17684 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 17685 option.kind, option.section, option.info);
a6e9f9df 17686 break;
252b5132 17687 }
a6e9f9df 17688
2cf0635d 17689 len = sizeof (* eopt);
fd17d1e6 17690 while (len < option.size)
82b1b41b 17691 {
fd17d1e6 17692 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 17693
82b1b41b
NC
17694 if (ISPRINT (datum))
17695 printf ("%c", datum);
17696 else
17697 printf ("\\%03o", datum);
17698 len ++;
17699 }
a6e9f9df 17700 fputs ("\n", stdout);
82b1b41b 17701
fd17d1e6 17702 offset += option.size;
252b5132 17703 }
a6e9f9df 17704 free (eopt);
252b5132 17705 }
32ec8896
NC
17706 else
17707 res = FALSE;
252b5132
RH
17708 }
17709
17710 if (conflicts_offset != 0 && conflictsno != 0)
17711 {
2cf0635d 17712 Elf32_Conflict * iconf;
252b5132
RH
17713 size_t cnt;
17714
978c4450 17715 if (filedata->dynamic_symbols == NULL)
252b5132 17716 {
591a748a 17717 error (_("conflict list found without a dynamic symbol table\n"));
32ec8896 17718 return FALSE;
252b5132
RH
17719 }
17720
7296a62a
NC
17721 /* PR 21345 - print a slightly more helpful error message
17722 if we are sure that the cmalloc will fail. */
645f43a8 17723 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
17724 {
17725 error (_("Overlarge number of conflicts detected: %lx\n"),
17726 (long) conflictsno);
17727 return FALSE;
17728 }
17729
3f5e193b 17730 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
17731 if (iconf == NULL)
17732 {
8b73c356 17733 error (_("Out of memory allocating space for dynamic conflicts\n"));
32ec8896 17734 return FALSE;
252b5132
RH
17735 }
17736
9ea033b2 17737 if (is_32bit_elf)
252b5132 17738 {
2cf0635d 17739 Elf32_External_Conflict * econf32;
a6e9f9df 17740
3f5e193b 17741 econf32 = (Elf32_External_Conflict *)
95099889
AM
17742 get_data (NULL, filedata, conflicts_offset,
17743 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 17744 if (!econf32)
5a814d6d
AM
17745 {
17746 free (iconf);
17747 return FALSE;
17748 }
252b5132
RH
17749
17750 for (cnt = 0; cnt < conflictsno; ++cnt)
17751 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
17752
17753 free (econf32);
252b5132
RH
17754 }
17755 else
17756 {
2cf0635d 17757 Elf64_External_Conflict * econf64;
a6e9f9df 17758
3f5e193b 17759 econf64 = (Elf64_External_Conflict *)
95099889
AM
17760 get_data (NULL, filedata, conflicts_offset,
17761 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 17762 if (!econf64)
5a814d6d
AM
17763 {
17764 free (iconf);
17765 return FALSE;
17766 }
252b5132
RH
17767
17768 for (cnt = 0; cnt < conflictsno; ++cnt)
17769 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
17770
17771 free (econf64);
252b5132
RH
17772 }
17773
d3a49aa8
AM
17774 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
17775 "\nSection '.conflict' contains %lu entries:\n",
17776 (unsigned long) conflictsno),
c7e7ca54 17777 (unsigned long) conflictsno);
252b5132
RH
17778 puts (_(" Num: Index Value Name"));
17779
17780 for (cnt = 0; cnt < conflictsno; ++cnt)
17781 {
b34976b6 17782 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 17783
978c4450 17784 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 17785 printf (_("<corrupt symbol index>"));
d79b3d50 17786 else
e0a31db1
NC
17787 {
17788 Elf_Internal_Sym * psym;
17789
978c4450 17790 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
17791 print_vma (psym->st_value, FULL_HEX);
17792 putchar (' ');
978c4450
AM
17793 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17794 print_symbol (25, GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17795 else
17796 printf (_("<corrupt: %14ld>"), psym->st_name);
17797 }
31104126 17798 putchar ('\n');
252b5132
RH
17799 }
17800
252b5132
RH
17801 free (iconf);
17802 }
17803
ccb4c951
RS
17804 if (pltgot != 0 && local_gotno != 0)
17805 {
91d6fa6a 17806 bfd_vma ent, local_end, global_end;
bbeee7ea 17807 size_t i, offset;
2cf0635d 17808 unsigned char * data;
82b1b41b 17809 unsigned char * data_end;
bbeee7ea 17810 int addr_size;
ccb4c951 17811
91d6fa6a 17812 ent = pltgot;
ccb4c951
RS
17813 addr_size = (is_32bit_elf ? 4 : 8);
17814 local_end = pltgot + local_gotno * addr_size;
ccb4c951 17815
74e1a04b
NC
17816 /* PR binutils/17533 file: 012-111227-0.004 */
17817 if (symtabno < gotsym)
17818 {
17819 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 17820 (unsigned long) gotsym, (unsigned long) symtabno);
32ec8896 17821 return FALSE;
74e1a04b 17822 }
82b1b41b 17823
74e1a04b 17824 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
17825 /* PR 17531: file: 54c91a34. */
17826 if (global_end < local_end)
17827 {
17828 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
32ec8896 17829 return FALSE;
82b1b41b 17830 }
948f632f 17831
dda8d76d
NC
17832 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
17833 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
17834 global_end - pltgot, 1,
17835 _("Global Offset Table data"));
919383ac 17836 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 17837 data_end = data + (global_end - pltgot);
59245841 17838
ccb4c951
RS
17839 printf (_("\nPrimary GOT:\n"));
17840 printf (_(" Canonical gp value: "));
17841 print_vma (pltgot + 0x7ff0, LONG_HEX);
17842 printf ("\n\n");
17843
17844 printf (_(" Reserved entries:\n"));
17845 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
17846 addr_size * 2, _("Address"), _("Access"),
17847 addr_size * 2, _("Initial"));
82b1b41b 17848 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 17849 printf (_(" Lazy resolver\n"));
82b1b41b
NC
17850 if (ent == (bfd_vma) -1)
17851 goto got_print_fail;
75ec1fdb 17852
c4ab9505
MR
17853 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
17854 This entry will be used by some runtime loaders, to store the
17855 module pointer. Otherwise this is an ordinary local entry.
17856 PR 21344: Check for the entry being fully available before
17857 fetching it. */
17858 if (data
17859 && data + ent - pltgot + addr_size <= data_end
17860 && (byte_get (data + ent - pltgot, addr_size)
17861 >> (addr_size * 8 - 1)) != 0)
17862 {
17863 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17864 printf (_(" Module pointer (GNU extension)\n"));
17865 if (ent == (bfd_vma) -1)
17866 goto got_print_fail;
ccb4c951
RS
17867 }
17868 printf ("\n");
17869
f17e9d8a 17870 if (data != NULL && ent < local_end)
ccb4c951
RS
17871 {
17872 printf (_(" Local entries:\n"));
cc5914eb 17873 printf (" %*s %10s %*s\n",
2b692964
NC
17874 addr_size * 2, _("Address"), _("Access"),
17875 addr_size * 2, _("Initial"));
91d6fa6a 17876 while (ent < local_end)
ccb4c951 17877 {
82b1b41b 17878 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 17879 printf ("\n");
82b1b41b
NC
17880 if (ent == (bfd_vma) -1)
17881 goto got_print_fail;
ccb4c951
RS
17882 }
17883 printf ("\n");
17884 }
17885
f17e9d8a 17886 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
17887 {
17888 int sym_width;
17889
17890 printf (_(" Global entries:\n"));
cc5914eb 17891 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
17892 addr_size * 2, _("Address"),
17893 _("Access"),
2b692964 17894 addr_size * 2, _("Initial"),
9cf03b7e
NC
17895 addr_size * 2, _("Sym.Val."),
17896 _("Type"),
17897 /* Note for translators: "Ndx" = abbreviated form of "Index". */
17898 _("Ndx"), _("Name"));
0b4362b0 17899
ccb4c951 17900 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 17901
ccb4c951
RS
17902 for (i = gotsym; i < symtabno; i++)
17903 {
82b1b41b 17904 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 17905 printf (" ");
e0a31db1 17906
978c4450 17907 if (filedata->dynamic_symbols == NULL)
e0a31db1 17908 printf (_("<no dynamic symbols>"));
978c4450 17909 else if (i < filedata->num_dynamic_syms)
e0a31db1 17910 {
978c4450 17911 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
17912
17913 print_vma (psym->st_value, LONG_HEX);
17914 printf (" %-7s %3s ",
dda8d76d
NC
17915 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
17916 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 17917
978c4450
AM
17918 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17919 print_symbol (sym_width,
17920 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17921 else
17922 printf (_("<corrupt: %14ld>"), psym->st_name);
17923 }
ccb4c951 17924 else
7fc5ac57
JBG
17925 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
17926 (unsigned long) i);
e0a31db1 17927
ccb4c951 17928 printf ("\n");
82b1b41b
NC
17929 if (ent == (bfd_vma) -1)
17930 break;
ccb4c951
RS
17931 }
17932 printf ("\n");
17933 }
17934
82b1b41b 17935 got_print_fail:
9db70fc3 17936 free (data);
ccb4c951
RS
17937 }
17938
861fb55a
DJ
17939 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
17940 {
91d6fa6a 17941 bfd_vma ent, end;
861fb55a
DJ
17942 size_t offset, rel_offset;
17943 unsigned long count, i;
2cf0635d 17944 unsigned char * data;
861fb55a 17945 int addr_size, sym_width;
2cf0635d 17946 Elf_Internal_Rela * rels;
861fb55a 17947
dda8d76d 17948 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
17949 if (pltrel == DT_RELA)
17950 {
dda8d76d 17951 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 17952 return FALSE;
861fb55a
DJ
17953 }
17954 else
17955 {
dda8d76d 17956 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 17957 return FALSE;
861fb55a
DJ
17958 }
17959
91d6fa6a 17960 ent = mips_pltgot;
861fb55a
DJ
17961 addr_size = (is_32bit_elf ? 4 : 8);
17962 end = mips_pltgot + (2 + count) * addr_size;
17963
dda8d76d
NC
17964 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
17965 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 17966 1, _("Procedure Linkage Table data"));
59245841 17967 if (data == NULL)
32ec8896 17968 return FALSE;
59245841 17969
9cf03b7e 17970 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
17971 printf (_(" Reserved entries:\n"));
17972 printf (_(" %*s %*s Purpose\n"),
2b692964 17973 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 17974 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 17975 printf (_(" PLT lazy resolver\n"));
91d6fa6a 17976 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 17977 printf (_(" Module pointer\n"));
861fb55a
DJ
17978 printf ("\n");
17979
17980 printf (_(" Entries:\n"));
cc5914eb 17981 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
17982 addr_size * 2, _("Address"),
17983 addr_size * 2, _("Initial"),
17984 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
17985 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
17986 for (i = 0; i < count; i++)
17987 {
df97ab2a 17988 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 17989
91d6fa6a 17990 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 17991 printf (" ");
e0a31db1 17992
978c4450 17993 if (idx >= filedata->num_dynamic_syms)
df97ab2a 17994 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 17995 else
e0a31db1 17996 {
978c4450 17997 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
17998
17999 print_vma (psym->st_value, LONG_HEX);
18000 printf (" %-7s %3s ",
dda8d76d
NC
18001 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18002 get_symbol_index_type (filedata, psym->st_shndx));
978c4450
AM
18003 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18004 print_symbol (sym_width,
18005 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18006 else
18007 printf (_("<corrupt: %14ld>"), psym->st_name);
18008 }
861fb55a
DJ
18009 printf ("\n");
18010 }
18011 printf ("\n");
18012
9db70fc3 18013 free (data);
861fb55a
DJ
18014 free (rels);
18015 }
18016
32ec8896 18017 return res;
252b5132
RH
18018}
18019
32ec8896 18020static bfd_boolean
dda8d76d 18021process_nds32_specific (Filedata * filedata)
35c08157
KLC
18022{
18023 Elf_Internal_Shdr *sect = NULL;
18024
dda8d76d 18025 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 18026 if (sect != NULL && sect->sh_size >= 4)
35c08157 18027 {
9c7b8e9b
AM
18028 unsigned char *buf;
18029 unsigned int flag;
35c08157
KLC
18030
18031 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
18032 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
18033 _("NDS32 elf flags section"));
35c08157 18034
9c7b8e9b 18035 if (buf == NULL)
32ec8896
NC
18036 return FALSE;
18037
9c7b8e9b
AM
18038 flag = byte_get (buf, 4);
18039 free (buf);
18040 switch (flag & 0x3)
35c08157
KLC
18041 {
18042 case 0:
18043 printf ("(VEC_SIZE):\tNo entry.\n");
18044 break;
18045 case 1:
18046 printf ("(VEC_SIZE):\t4 bytes\n");
18047 break;
18048 case 2:
18049 printf ("(VEC_SIZE):\t16 bytes\n");
18050 break;
18051 case 3:
18052 printf ("(VEC_SIZE):\treserved\n");
18053 break;
18054 }
18055 }
18056
18057 return TRUE;
18058}
18059
32ec8896 18060static bfd_boolean
dda8d76d 18061process_gnu_liblist (Filedata * filedata)
047b2264 18062{
2cf0635d
NC
18063 Elf_Internal_Shdr * section;
18064 Elf_Internal_Shdr * string_sec;
18065 Elf32_External_Lib * elib;
18066 char * strtab;
c256ffe7 18067 size_t strtab_size;
047b2264 18068 size_t cnt;
d3a49aa8 18069 unsigned long num_liblist;
047b2264 18070 unsigned i;
32ec8896 18071 bfd_boolean res = TRUE;
047b2264
JJ
18072
18073 if (! do_arch)
32ec8896 18074 return TRUE;
047b2264 18075
dda8d76d
NC
18076 for (i = 0, section = filedata->section_headers;
18077 i < filedata->file_header.e_shnum;
b34976b6 18078 i++, section++)
047b2264
JJ
18079 {
18080 switch (section->sh_type)
18081 {
18082 case SHT_GNU_LIBLIST:
dda8d76d 18083 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
18084 break;
18085
3f5e193b 18086 elib = (Elf32_External_Lib *)
dda8d76d 18087 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 18088 _("liblist section data"));
047b2264
JJ
18089
18090 if (elib == NULL)
32ec8896
NC
18091 {
18092 res = FALSE;
18093 break;
18094 }
047b2264 18095
dda8d76d
NC
18096 string_sec = filedata->section_headers + section->sh_link;
18097 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
18098 string_sec->sh_size,
18099 _("liblist string table"));
047b2264
JJ
18100 if (strtab == NULL
18101 || section->sh_entsize != sizeof (Elf32_External_Lib))
18102 {
18103 free (elib);
2842702f 18104 free (strtab);
32ec8896 18105 res = FALSE;
047b2264
JJ
18106 break;
18107 }
59245841 18108 strtab_size = string_sec->sh_size;
047b2264 18109
d3a49aa8
AM
18110 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
18111 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
18112 "\nLibrary list section '%s' contains %lu entries:\n",
18113 num_liblist),
dda8d76d 18114 printable_section_name (filedata, section),
d3a49aa8 18115 num_liblist);
047b2264 18116
2b692964 18117 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
18118
18119 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
18120 ++cnt)
18121 {
18122 Elf32_Lib liblist;
91d6fa6a 18123 time_t atime;
d5b07ef4 18124 char timebuf[128];
2cf0635d 18125 struct tm * tmp;
047b2264
JJ
18126
18127 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18128 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
18129 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18130 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18131 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18132
91d6fa6a 18133 tmp = gmtime (&atime);
e9e44622
JJ
18134 snprintf (timebuf, sizeof (timebuf),
18135 "%04u-%02u-%02uT%02u:%02u:%02u",
18136 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18137 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
18138
18139 printf ("%3lu: ", (unsigned long) cnt);
18140 if (do_wide)
c256ffe7 18141 printf ("%-20s", liblist.l_name < strtab_size
2b692964 18142 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 18143 else
c256ffe7 18144 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 18145 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
18146 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
18147 liblist.l_version, liblist.l_flags);
18148 }
18149
18150 free (elib);
2842702f 18151 free (strtab);
047b2264
JJ
18152 }
18153 }
18154
32ec8896 18155 return res;
047b2264
JJ
18156}
18157
9437c45b 18158static const char *
dda8d76d 18159get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
18160{
18161 static char buff[64];
103f02d3 18162
dda8d76d 18163 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
18164 switch (e_type)
18165 {
57346661 18166 case NT_AUXV:
1ec5cd37 18167 return _("NT_AUXV (auxiliary vector)");
57346661 18168 case NT_PRSTATUS:
1ec5cd37 18169 return _("NT_PRSTATUS (prstatus structure)");
57346661 18170 case NT_FPREGSET:
1ec5cd37 18171 return _("NT_FPREGSET (floating point registers)");
57346661 18172 case NT_PRPSINFO:
1ec5cd37 18173 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 18174 case NT_TASKSTRUCT:
1ec5cd37 18175 return _("NT_TASKSTRUCT (task structure)");
57346661 18176 case NT_PRXFPREG:
1ec5cd37 18177 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
18178 case NT_PPC_VMX:
18179 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
18180 case NT_PPC_VSX:
18181 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
18182 case NT_PPC_TAR:
18183 return _("NT_PPC_TAR (ppc TAR register)");
18184 case NT_PPC_PPR:
18185 return _("NT_PPC_PPR (ppc PPR register)");
18186 case NT_PPC_DSCR:
18187 return _("NT_PPC_DSCR (ppc DSCR register)");
18188 case NT_PPC_EBB:
18189 return _("NT_PPC_EBB (ppc EBB registers)");
18190 case NT_PPC_PMU:
18191 return _("NT_PPC_PMU (ppc PMU registers)");
18192 case NT_PPC_TM_CGPR:
18193 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
18194 case NT_PPC_TM_CFPR:
18195 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
18196 case NT_PPC_TM_CVMX:
18197 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
18198 case NT_PPC_TM_CVSX:
3fd21718 18199 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
18200 case NT_PPC_TM_SPR:
18201 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
18202 case NT_PPC_TM_CTAR:
18203 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
18204 case NT_PPC_TM_CPPR:
18205 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
18206 case NT_PPC_TM_CDSCR:
18207 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
18208 case NT_386_TLS:
18209 return _("NT_386_TLS (x86 TLS information)");
18210 case NT_386_IOPERM:
18211 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
18212 case NT_X86_XSTATE:
18213 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
18214 case NT_X86_CET:
18215 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
18216 case NT_S390_HIGH_GPRS:
18217 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
18218 case NT_S390_TIMER:
18219 return _("NT_S390_TIMER (s390 timer register)");
18220 case NT_S390_TODCMP:
18221 return _("NT_S390_TODCMP (s390 TOD comparator register)");
18222 case NT_S390_TODPREG:
18223 return _("NT_S390_TODPREG (s390 TOD programmable register)");
18224 case NT_S390_CTRS:
18225 return _("NT_S390_CTRS (s390 control registers)");
18226 case NT_S390_PREFIX:
18227 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
18228 case NT_S390_LAST_BREAK:
18229 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
18230 case NT_S390_SYSTEM_CALL:
18231 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
18232 case NT_S390_TDB:
18233 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
18234 case NT_S390_VXRS_LOW:
18235 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
18236 case NT_S390_VXRS_HIGH:
18237 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
18238 case NT_S390_GS_CB:
18239 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
18240 case NT_S390_GS_BC:
18241 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
18242 case NT_ARM_VFP:
18243 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
18244 case NT_ARM_TLS:
18245 return _("NT_ARM_TLS (AArch TLS registers)");
18246 case NT_ARM_HW_BREAK:
18247 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
18248 case NT_ARM_HW_WATCH:
18249 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
27456742
AK
18250 case NT_ARC_V2:
18251 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
57346661 18252 case NT_PSTATUS:
1ec5cd37 18253 return _("NT_PSTATUS (pstatus structure)");
57346661 18254 case NT_FPREGS:
1ec5cd37 18255 return _("NT_FPREGS (floating point registers)");
57346661 18256 case NT_PSINFO:
1ec5cd37 18257 return _("NT_PSINFO (psinfo structure)");
57346661 18258 case NT_LWPSTATUS:
1ec5cd37 18259 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 18260 case NT_LWPSINFO:
1ec5cd37 18261 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 18262 case NT_WIN32PSTATUS:
1ec5cd37 18263 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
18264 case NT_SIGINFO:
18265 return _("NT_SIGINFO (siginfo_t data)");
18266 case NT_FILE:
18267 return _("NT_FILE (mapped files)");
1ec5cd37
NC
18268 default:
18269 break;
18270 }
18271 else
18272 switch (e_type)
18273 {
18274 case NT_VERSION:
18275 return _("NT_VERSION (version)");
18276 case NT_ARCH:
18277 return _("NT_ARCH (architecture)");
9ef920e9 18278 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 18279 return _("OPEN");
9ef920e9 18280 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 18281 return _("func");
1ec5cd37
NC
18282 default:
18283 break;
18284 }
18285
e9e44622 18286 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 18287 return buff;
779fe533
NC
18288}
18289
32ec8896 18290static bfd_boolean
9ece1fa9
TT
18291print_core_note (Elf_Internal_Note *pnote)
18292{
18293 unsigned int addr_size = is_32bit_elf ? 4 : 8;
18294 bfd_vma count, page_size;
18295 unsigned char *descdata, *filenames, *descend;
18296
18297 if (pnote->type != NT_FILE)
04ac15ab
AS
18298 {
18299 if (do_wide)
18300 printf ("\n");
18301 return TRUE;
18302 }
9ece1fa9
TT
18303
18304#ifndef BFD64
18305 if (!is_32bit_elf)
18306 {
18307 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
18308 /* Still "successful". */
32ec8896 18309 return TRUE;
9ece1fa9
TT
18310 }
18311#endif
18312
18313 if (pnote->descsz < 2 * addr_size)
18314 {
32ec8896
NC
18315 error (_(" Malformed note - too short for header\n"));
18316 return FALSE;
9ece1fa9
TT
18317 }
18318
18319 descdata = (unsigned char *) pnote->descdata;
18320 descend = descdata + pnote->descsz;
18321
18322 if (descdata[pnote->descsz - 1] != '\0')
18323 {
32ec8896
NC
18324 error (_(" Malformed note - does not end with \\0\n"));
18325 return FALSE;
9ece1fa9
TT
18326 }
18327
18328 count = byte_get (descdata, addr_size);
18329 descdata += addr_size;
18330
18331 page_size = byte_get (descdata, addr_size);
18332 descdata += addr_size;
18333
5396a86e
AM
18334 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
18335 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 18336 {
32ec8896
NC
18337 error (_(" Malformed note - too short for supplied file count\n"));
18338 return FALSE;
9ece1fa9
TT
18339 }
18340
18341 printf (_(" Page size: "));
18342 print_vma (page_size, DEC);
18343 printf ("\n");
18344
18345 printf (_(" %*s%*s%*s\n"),
18346 (int) (2 + 2 * addr_size), _("Start"),
18347 (int) (4 + 2 * addr_size), _("End"),
18348 (int) (4 + 2 * addr_size), _("Page Offset"));
18349 filenames = descdata + count * 3 * addr_size;
595712bb 18350 while (count-- > 0)
9ece1fa9
TT
18351 {
18352 bfd_vma start, end, file_ofs;
18353
18354 if (filenames == descend)
18355 {
32ec8896
NC
18356 error (_(" Malformed note - filenames end too early\n"));
18357 return FALSE;
9ece1fa9
TT
18358 }
18359
18360 start = byte_get (descdata, addr_size);
18361 descdata += addr_size;
18362 end = byte_get (descdata, addr_size);
18363 descdata += addr_size;
18364 file_ofs = byte_get (descdata, addr_size);
18365 descdata += addr_size;
18366
18367 printf (" ");
18368 print_vma (start, FULL_HEX);
18369 printf (" ");
18370 print_vma (end, FULL_HEX);
18371 printf (" ");
18372 print_vma (file_ofs, FULL_HEX);
18373 printf ("\n %s\n", filenames);
18374
18375 filenames += 1 + strlen ((char *) filenames);
18376 }
18377
32ec8896 18378 return TRUE;
9ece1fa9
TT
18379}
18380
1118d252
RM
18381static const char *
18382get_gnu_elf_note_type (unsigned e_type)
18383{
1449284b 18384 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
18385 switch (e_type)
18386 {
18387 case NT_GNU_ABI_TAG:
18388 return _("NT_GNU_ABI_TAG (ABI version tag)");
18389 case NT_GNU_HWCAP:
18390 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
18391 case NT_GNU_BUILD_ID:
18392 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
18393 case NT_GNU_GOLD_VERSION:
18394 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
18395 case NT_GNU_PROPERTY_TYPE_0:
18396 return _("NT_GNU_PROPERTY_TYPE_0");
18397 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
18398 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
18399 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
18400 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 18401 default:
1449284b
NC
18402 {
18403 static char buff[64];
1118d252 18404
1449284b
NC
18405 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18406 return buff;
18407 }
18408 }
1118d252
RM
18409}
18410
a9eafb08
L
18411static void
18412decode_x86_compat_isa (unsigned int bitmask)
18413{
18414 while (bitmask)
18415 {
18416 unsigned int bit = bitmask & (- bitmask);
18417
18418 bitmask &= ~ bit;
18419 switch (bit)
18420 {
18421 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
18422 printf ("i486");
18423 break;
18424 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
18425 printf ("586");
18426 break;
18427 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
18428 printf ("686");
18429 break;
18430 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
18431 printf ("SSE");
18432 break;
18433 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
18434 printf ("SSE2");
18435 break;
18436 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
18437 printf ("SSE3");
18438 break;
18439 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
18440 printf ("SSSE3");
18441 break;
18442 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
18443 printf ("SSE4_1");
18444 break;
18445 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
18446 printf ("SSE4_2");
18447 break;
18448 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
18449 printf ("AVX");
18450 break;
18451 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
18452 printf ("AVX2");
18453 break;
18454 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
18455 printf ("AVX512F");
18456 break;
18457 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
18458 printf ("AVX512CD");
18459 break;
18460 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
18461 printf ("AVX512ER");
18462 break;
18463 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
18464 printf ("AVX512PF");
18465 break;
18466 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
18467 printf ("AVX512VL");
18468 break;
18469 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
18470 printf ("AVX512DQ");
18471 break;
18472 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
18473 printf ("AVX512BW");
18474 break;
65b3d26e
L
18475 default:
18476 printf (_("<unknown: %x>"), bit);
18477 break;
a9eafb08
L
18478 }
18479 if (bitmask)
18480 printf (", ");
18481 }
18482}
18483
9ef920e9 18484static void
32930e4e 18485decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 18486{
0a59decb 18487 if (!bitmask)
90c745dc
L
18488 {
18489 printf (_("<None>"));
18490 return;
18491 }
90c745dc 18492
9ef920e9
NC
18493 while (bitmask)
18494 {
1fc87489 18495 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
18496
18497 bitmask &= ~ bit;
18498 switch (bit)
18499 {
32930e4e 18500 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
18501 printf ("CMOV");
18502 break;
32930e4e 18503 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
18504 printf ("SSE");
18505 break;
32930e4e 18506 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
18507 printf ("SSE2");
18508 break;
32930e4e 18509 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
18510 printf ("SSE3");
18511 break;
32930e4e 18512 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
18513 printf ("SSSE3");
18514 break;
32930e4e 18515 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
18516 printf ("SSE4_1");
18517 break;
32930e4e 18518 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
18519 printf ("SSE4_2");
18520 break;
32930e4e 18521 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
18522 printf ("AVX");
18523 break;
32930e4e 18524 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
18525 printf ("AVX2");
18526 break;
32930e4e 18527 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
18528 printf ("FMA");
18529 break;
32930e4e 18530 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
18531 printf ("AVX512F");
18532 break;
32930e4e 18533 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
18534 printf ("AVX512CD");
18535 break;
32930e4e 18536 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
18537 printf ("AVX512ER");
18538 break;
32930e4e 18539 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
18540 printf ("AVX512PF");
18541 break;
32930e4e 18542 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
18543 printf ("AVX512VL");
18544 break;
32930e4e 18545 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
18546 printf ("AVX512DQ");
18547 break;
32930e4e 18548 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
18549 printf ("AVX512BW");
18550 break;
32930e4e 18551 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
18552 printf ("AVX512_4FMAPS");
18553 break;
32930e4e 18554 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
18555 printf ("AVX512_4VNNIW");
18556 break;
32930e4e 18557 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
18558 printf ("AVX512_BITALG");
18559 break;
32930e4e 18560 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
18561 printf ("AVX512_IFMA");
18562 break;
32930e4e 18563 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
18564 printf ("AVX512_VBMI");
18565 break;
32930e4e 18566 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
18567 printf ("AVX512_VBMI2");
18568 break;
32930e4e 18569 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
18570 printf ("AVX512_VNNI");
18571 break;
32930e4e 18572 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
18573 printf ("AVX512_BF16");
18574 break;
65b3d26e
L
18575 default:
18576 printf (_("<unknown: %x>"), bit);
18577 break;
9ef920e9
NC
18578 }
18579 if (bitmask)
18580 printf (", ");
18581 }
18582}
18583
32930e4e
L
18584static void
18585decode_x86_isa (unsigned int bitmask)
18586{
18587 if (!bitmask)
18588 {
18589 printf (_("x86-64-baseline"));
18590 return;
18591 }
18592
18593 while (bitmask)
18594 {
18595 unsigned int bit = bitmask & (- bitmask);
18596
18597 bitmask &= ~ bit;
18598 switch (bit)
18599 {
18600 case GNU_PROPERTY_X86_ISA_1_V2:
18601 printf ("x86-64-v2");
18602 break;
18603 case GNU_PROPERTY_X86_ISA_1_V3:
18604 printf ("x86-64-v3");
18605 break;
18606 case GNU_PROPERTY_X86_ISA_1_V4:
18607 printf ("x86-64-v4");
18608 break;
18609 default:
18610 printf (_("<unknown: %x>"), bit);
18611 break;
18612 }
18613 if (bitmask)
18614 printf (", ");
18615 }
18616}
18617
ee2fdd6f 18618static void
a9eafb08 18619decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 18620{
0a59decb 18621 if (!bitmask)
90c745dc
L
18622 {
18623 printf (_("<None>"));
18624 return;
18625 }
90c745dc 18626
ee2fdd6f
L
18627 while (bitmask)
18628 {
18629 unsigned int bit = bitmask & (- bitmask);
18630
18631 bitmask &= ~ bit;
18632 switch (bit)
18633 {
18634 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 18635 printf ("IBT");
ee2fdd6f 18636 break;
48580982 18637 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 18638 printf ("SHSTK");
48580982 18639 break;
ee2fdd6f
L
18640 default:
18641 printf (_("<unknown: %x>"), bit);
18642 break;
18643 }
18644 if (bitmask)
18645 printf (", ");
18646 }
18647}
18648
a9eafb08
L
18649static void
18650decode_x86_feature_2 (unsigned int bitmask)
18651{
0a59decb 18652 if (!bitmask)
90c745dc
L
18653 {
18654 printf (_("<None>"));
18655 return;
18656 }
90c745dc 18657
a9eafb08
L
18658 while (bitmask)
18659 {
18660 unsigned int bit = bitmask & (- bitmask);
18661
18662 bitmask &= ~ bit;
18663 switch (bit)
18664 {
18665 case GNU_PROPERTY_X86_FEATURE_2_X86:
18666 printf ("x86");
18667 break;
18668 case GNU_PROPERTY_X86_FEATURE_2_X87:
18669 printf ("x87");
18670 break;
18671 case GNU_PROPERTY_X86_FEATURE_2_MMX:
18672 printf ("MMX");
18673 break;
18674 case GNU_PROPERTY_X86_FEATURE_2_XMM:
18675 printf ("XMM");
18676 break;
18677 case GNU_PROPERTY_X86_FEATURE_2_YMM:
18678 printf ("YMM");
18679 break;
18680 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
18681 printf ("ZMM");
18682 break;
a308b89d
L
18683 case GNU_PROPERTY_X86_FEATURE_2_TMM:
18684 printf ("TMM");
18685 break;
32930e4e
L
18686 case GNU_PROPERTY_X86_FEATURE_2_MASK:
18687 printf ("MASK");
18688 break;
a9eafb08
L
18689 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
18690 printf ("FXSR");
18691 break;
18692 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
18693 printf ("XSAVE");
18694 break;
18695 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
18696 printf ("XSAVEOPT");
18697 break;
18698 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
18699 printf ("XSAVEC");
18700 break;
65b3d26e
L
18701 default:
18702 printf (_("<unknown: %x>"), bit);
18703 break;
a9eafb08
L
18704 }
18705 if (bitmask)
18706 printf (", ");
18707 }
18708}
18709
cd702818
SD
18710static void
18711decode_aarch64_feature_1_and (unsigned int bitmask)
18712{
18713 while (bitmask)
18714 {
18715 unsigned int bit = bitmask & (- bitmask);
18716
18717 bitmask &= ~ bit;
18718 switch (bit)
18719 {
18720 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
18721 printf ("BTI");
18722 break;
18723
18724 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
18725 printf ("PAC");
18726 break;
18727
18728 default:
18729 printf (_("<unknown: %x>"), bit);
18730 break;
18731 }
18732 if (bitmask)
18733 printf (", ");
18734 }
18735}
18736
9ef920e9 18737static void
dda8d76d 18738print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
18739{
18740 unsigned char * ptr = (unsigned char *) pnote->descdata;
18741 unsigned char * ptr_end = ptr + pnote->descsz;
18742 unsigned int size = is_32bit_elf ? 4 : 8;
18743
18744 printf (_(" Properties: "));
18745
1fc87489 18746 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
18747 {
18748 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
18749 return;
18750 }
18751
6ab2c4ed 18752 while (ptr < ptr_end)
9ef920e9 18753 {
1fc87489 18754 unsigned int j;
6ab2c4ed
MC
18755 unsigned int type;
18756 unsigned int datasz;
18757
18758 if ((size_t) (ptr_end - ptr) < 8)
18759 {
18760 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
18761 break;
18762 }
18763
18764 type = byte_get (ptr, 4);
18765 datasz = byte_get (ptr + 4, 4);
9ef920e9 18766
1fc87489 18767 ptr += 8;
9ef920e9 18768
6ab2c4ed 18769 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 18770 {
1fc87489
L
18771 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
18772 type, datasz);
9ef920e9 18773 break;
1fc87489 18774 }
9ef920e9 18775
1fc87489
L
18776 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
18777 {
dda8d76d
NC
18778 if (filedata->file_header.e_machine == EM_X86_64
18779 || filedata->file_header.e_machine == EM_IAMCU
18780 || filedata->file_header.e_machine == EM_386)
1fc87489 18781 {
aa7bca9b
L
18782 unsigned int bitmask;
18783
18784 if (datasz == 4)
0a59decb 18785 bitmask = byte_get (ptr, 4);
aa7bca9b
L
18786 else
18787 bitmask = 0;
18788
1fc87489
L
18789 switch (type)
18790 {
18791 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 18792 if (datasz != 4)
aa7bca9b
L
18793 printf (_("x86 ISA used: <corrupt length: %#x> "),
18794 datasz);
1fc87489 18795 else
aa7bca9b
L
18796 {
18797 printf ("x86 ISA used: ");
18798 decode_x86_isa (bitmask);
18799 }
1fc87489 18800 goto next;
9ef920e9 18801
1fc87489 18802 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 18803 if (datasz != 4)
aa7bca9b
L
18804 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18805 datasz);
1fc87489 18806 else
aa7bca9b
L
18807 {
18808 printf ("x86 ISA needed: ");
18809 decode_x86_isa (bitmask);
18810 }
1fc87489 18811 goto next;
9ef920e9 18812
ee2fdd6f 18813 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 18814 if (datasz != 4)
aa7bca9b
L
18815 printf (_("x86 feature: <corrupt length: %#x> "),
18816 datasz);
ee2fdd6f 18817 else
aa7bca9b
L
18818 {
18819 printf ("x86 feature: ");
a9eafb08
L
18820 decode_x86_feature_1 (bitmask);
18821 }
18822 goto next;
18823
18824 case GNU_PROPERTY_X86_FEATURE_2_USED:
18825 if (datasz != 4)
18826 printf (_("x86 feature used: <corrupt length: %#x> "),
18827 datasz);
18828 else
18829 {
18830 printf ("x86 feature used: ");
18831 decode_x86_feature_2 (bitmask);
18832 }
18833 goto next;
18834
18835 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
18836 if (datasz != 4)
18837 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
18838 else
18839 {
18840 printf ("x86 feature needed: ");
18841 decode_x86_feature_2 (bitmask);
18842 }
18843 goto next;
18844
18845 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
18846 if (datasz != 4)
18847 printf (_("x86 ISA used: <corrupt length: %#x> "),
18848 datasz);
18849 else
18850 {
18851 printf ("x86 ISA used: ");
18852 decode_x86_compat_isa (bitmask);
18853 }
18854 goto next;
18855
18856 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
18857 if (datasz != 4)
18858 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18859 datasz);
18860 else
18861 {
18862 printf ("x86 ISA needed: ");
18863 decode_x86_compat_isa (bitmask);
aa7bca9b 18864 }
ee2fdd6f
L
18865 goto next;
18866
32930e4e
L
18867 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
18868 if (datasz != 4)
18869 printf (_("x86 ISA used: <corrupt length: %#x> "),
18870 datasz);
18871 else
18872 {
18873 printf ("x86 ISA used: ");
18874 decode_x86_compat_2_isa (bitmask);
18875 }
18876 goto next;
18877
18878 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
18879 if (datasz != 4)
18880 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18881 datasz);
18882 else
18883 {
18884 printf ("x86 ISA needed: ");
18885 decode_x86_compat_2_isa (bitmask);
18886 }
18887 goto next;
18888
1fc87489
L
18889 default:
18890 break;
18891 }
18892 }
cd702818
SD
18893 else if (filedata->file_header.e_machine == EM_AARCH64)
18894 {
18895 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
18896 {
18897 printf ("AArch64 feature: ");
18898 if (datasz != 4)
18899 printf (_("<corrupt length: %#x> "), datasz);
18900 else
18901 decode_aarch64_feature_1_and (byte_get (ptr, 4));
18902 goto next;
18903 }
18904 }
1fc87489
L
18905 }
18906 else
18907 {
18908 switch (type)
9ef920e9 18909 {
1fc87489
L
18910 case GNU_PROPERTY_STACK_SIZE:
18911 printf (_("stack size: "));
18912 if (datasz != size)
18913 printf (_("<corrupt length: %#x> "), datasz);
18914 else
18915 printf ("%#lx", (unsigned long) byte_get (ptr, size));
18916 goto next;
18917
18918 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
18919 printf ("no copy on protected ");
18920 if (datasz)
18921 printf (_("<corrupt length: %#x> "), datasz);
18922 goto next;
18923
18924 default:
9ef920e9
NC
18925 break;
18926 }
9ef920e9
NC
18927 }
18928
1fc87489
L
18929 if (type < GNU_PROPERTY_LOPROC)
18930 printf (_("<unknown type %#x data: "), type);
18931 else if (type < GNU_PROPERTY_LOUSER)
18932 printf (_("<procesor-specific type %#x data: "), type);
18933 else
18934 printf (_("<application-specific type %#x data: "), type);
18935 for (j = 0; j < datasz; ++j)
18936 printf ("%02x ", ptr[j] & 0xff);
18937 printf (">");
18938
dc1e8a47 18939 next:
9ef920e9 18940 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
18941 if (ptr == ptr_end)
18942 break;
1fc87489 18943
6ab2c4ed
MC
18944 if (do_wide)
18945 printf (", ");
18946 else
18947 printf ("\n\t");
9ef920e9
NC
18948 }
18949
18950 printf ("\n");
18951}
18952
32ec8896 18953static bfd_boolean
dda8d76d 18954print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 18955{
1449284b 18956 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
18957 switch (pnote->type)
18958 {
18959 case NT_GNU_BUILD_ID:
18960 {
18961 unsigned long i;
18962
18963 printf (_(" Build ID: "));
18964 for (i = 0; i < pnote->descsz; ++i)
18965 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 18966 printf ("\n");
664f90a3
TT
18967 }
18968 break;
18969
18970 case NT_GNU_ABI_TAG:
18971 {
18972 unsigned long os, major, minor, subminor;
18973 const char *osname;
18974
3102e897
NC
18975 /* PR 17531: file: 030-599401-0.004. */
18976 if (pnote->descsz < 16)
18977 {
18978 printf (_(" <corrupt GNU_ABI_TAG>\n"));
18979 break;
18980 }
18981
664f90a3
TT
18982 os = byte_get ((unsigned char *) pnote->descdata, 4);
18983 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
18984 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
18985 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
18986
18987 switch (os)
18988 {
18989 case GNU_ABI_TAG_LINUX:
18990 osname = "Linux";
18991 break;
18992 case GNU_ABI_TAG_HURD:
18993 osname = "Hurd";
18994 break;
18995 case GNU_ABI_TAG_SOLARIS:
18996 osname = "Solaris";
18997 break;
18998 case GNU_ABI_TAG_FREEBSD:
18999 osname = "FreeBSD";
19000 break;
19001 case GNU_ABI_TAG_NETBSD:
19002 osname = "NetBSD";
19003 break;
14ae95f2
RM
19004 case GNU_ABI_TAG_SYLLABLE:
19005 osname = "Syllable";
19006 break;
19007 case GNU_ABI_TAG_NACL:
19008 osname = "NaCl";
19009 break;
664f90a3
TT
19010 default:
19011 osname = "Unknown";
19012 break;
19013 }
19014
19015 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
19016 major, minor, subminor);
19017 }
19018 break;
926c5385
CC
19019
19020 case NT_GNU_GOLD_VERSION:
19021 {
19022 unsigned long i;
19023
19024 printf (_(" Version: "));
19025 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
19026 printf ("%c", pnote->descdata[i]);
19027 printf ("\n");
19028 }
19029 break;
1449284b
NC
19030
19031 case NT_GNU_HWCAP:
19032 {
19033 unsigned long num_entries, mask;
19034
19035 /* Hardware capabilities information. Word 0 is the number of entries.
19036 Word 1 is a bitmask of enabled entries. The rest of the descriptor
19037 is a series of entries, where each entry is a single byte followed
19038 by a nul terminated string. The byte gives the bit number to test
19039 if enabled in the bitmask. */
19040 printf (_(" Hardware Capabilities: "));
19041 if (pnote->descsz < 8)
19042 {
32ec8896
NC
19043 error (_("<corrupt GNU_HWCAP>\n"));
19044 return FALSE;
1449284b
NC
19045 }
19046 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
19047 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19048 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
19049 /* FIXME: Add code to display the entries... */
19050 }
19051 break;
19052
9ef920e9 19053 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 19054 print_gnu_property_note (filedata, pnote);
9ef920e9 19055 break;
9abca702 19056
1449284b
NC
19057 default:
19058 /* Handle unrecognised types. An error message should have already been
19059 created by get_gnu_elf_note_type(), so all that we need to do is to
19060 display the data. */
19061 {
19062 unsigned long i;
19063
19064 printf (_(" Description data: "));
19065 for (i = 0; i < pnote->descsz; ++i)
19066 printf ("%02x ", pnote->descdata[i] & 0xff);
19067 printf ("\n");
19068 }
19069 break;
664f90a3
TT
19070 }
19071
32ec8896 19072 return TRUE;
664f90a3
TT
19073}
19074
685080f2
NC
19075static const char *
19076get_v850_elf_note_type (enum v850_notes n_type)
19077{
19078 static char buff[64];
19079
19080 switch (n_type)
19081 {
19082 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
19083 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
19084 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
19085 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
19086 case V850_NOTE_CACHE_INFO: return _("Use of cache");
19087 case V850_NOTE_MMU_INFO: return _("Use of MMU");
19088 default:
19089 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
19090 return buff;
19091 }
19092}
19093
32ec8896 19094static bfd_boolean
685080f2
NC
19095print_v850_note (Elf_Internal_Note * pnote)
19096{
19097 unsigned int val;
19098
19099 if (pnote->descsz != 4)
32ec8896
NC
19100 return FALSE;
19101
685080f2
NC
19102 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
19103
19104 if (val == 0)
19105 {
19106 printf (_("not set\n"));
32ec8896 19107 return TRUE;
685080f2
NC
19108 }
19109
19110 switch (pnote->type)
19111 {
19112 case V850_NOTE_ALIGNMENT:
19113 switch (val)
19114 {
32ec8896
NC
19115 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return TRUE;
19116 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return TRUE;
685080f2
NC
19117 }
19118 break;
14ae95f2 19119
685080f2
NC
19120 case V850_NOTE_DATA_SIZE:
19121 switch (val)
19122 {
32ec8896
NC
19123 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return TRUE;
19124 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return TRUE;
685080f2
NC
19125 }
19126 break;
14ae95f2 19127
685080f2
NC
19128 case V850_NOTE_FPU_INFO:
19129 switch (val)
19130 {
32ec8896
NC
19131 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return TRUE;
19132 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return TRUE;
685080f2
NC
19133 }
19134 break;
14ae95f2 19135
685080f2
NC
19136 case V850_NOTE_MMU_INFO:
19137 case V850_NOTE_CACHE_INFO:
19138 case V850_NOTE_SIMD_INFO:
19139 if (val == EF_RH850_SIMD)
19140 {
19141 printf (_("yes\n"));
32ec8896 19142 return TRUE;
685080f2
NC
19143 }
19144 break;
19145
19146 default:
19147 /* An 'unknown note type' message will already have been displayed. */
19148 break;
19149 }
19150
19151 printf (_("unknown value: %x\n"), val);
32ec8896 19152 return FALSE;
685080f2
NC
19153}
19154
32ec8896 19155static bfd_boolean
c6056a74
SF
19156process_netbsd_elf_note (Elf_Internal_Note * pnote)
19157{
19158 unsigned int version;
19159
19160 switch (pnote->type)
19161 {
19162 case NT_NETBSD_IDENT:
b966f55f
AM
19163 if (pnote->descsz < 1)
19164 break;
c6056a74
SF
19165 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19166 if ((version / 10000) % 100)
b966f55f 19167 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
19168 version, version / 100000000, (version / 1000000) % 100,
19169 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 19170 'A' + (version / 10000) % 26);
c6056a74
SF
19171 else
19172 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 19173 version, version / 100000000, (version / 1000000) % 100,
15f205b1 19174 (version / 100) % 100);
32ec8896 19175 return TRUE;
c6056a74
SF
19176
19177 case NT_NETBSD_MARCH:
9abca702 19178 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 19179 pnote->descdata);
32ec8896 19180 return TRUE;
c6056a74 19181
9abca702
CZ
19182#ifdef NT_NETBSD_PAX
19183 case NT_NETBSD_PAX:
b966f55f
AM
19184 if (pnote->descsz < 1)
19185 break;
9abca702
CZ
19186 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19187 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
19188 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
19189 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
19190 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
19191 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
19192 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
19193 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
19194 return TRUE;
19195#endif
c6056a74 19196 }
b966f55f
AM
19197
19198 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
19199 pnote->descsz, pnote->type);
19200 return FALSE;
c6056a74
SF
19201}
19202
f4ddf30f 19203static const char *
dda8d76d 19204get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 19205{
f4ddf30f
JB
19206 switch (e_type)
19207 {
19208 case NT_FREEBSD_THRMISC:
19209 return _("NT_THRMISC (thrmisc structure)");
19210 case NT_FREEBSD_PROCSTAT_PROC:
19211 return _("NT_PROCSTAT_PROC (proc data)");
19212 case NT_FREEBSD_PROCSTAT_FILES:
19213 return _("NT_PROCSTAT_FILES (files data)");
19214 case NT_FREEBSD_PROCSTAT_VMMAP:
19215 return _("NT_PROCSTAT_VMMAP (vmmap data)");
19216 case NT_FREEBSD_PROCSTAT_GROUPS:
19217 return _("NT_PROCSTAT_GROUPS (groups data)");
19218 case NT_FREEBSD_PROCSTAT_UMASK:
19219 return _("NT_PROCSTAT_UMASK (umask data)");
19220 case NT_FREEBSD_PROCSTAT_RLIMIT:
19221 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
19222 case NT_FREEBSD_PROCSTAT_OSREL:
19223 return _("NT_PROCSTAT_OSREL (osreldate data)");
19224 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
19225 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
19226 case NT_FREEBSD_PROCSTAT_AUXV:
19227 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
19228 case NT_FREEBSD_PTLWPINFO:
19229 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 19230 }
dda8d76d 19231 return get_note_type (filedata, e_type);
f4ddf30f
JB
19232}
19233
9437c45b 19234static const char *
dda8d76d 19235get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
19236{
19237 static char buff[64];
19238
540e6170
CZ
19239 switch (e_type)
19240 {
19241 case NT_NETBSDCORE_PROCINFO:
19242 /* NetBSD core "procinfo" structure. */
19243 return _("NetBSD procinfo structure");
9437c45b 19244
540e6170
CZ
19245#ifdef NT_NETBSDCORE_AUXV
19246 case NT_NETBSDCORE_AUXV:
19247 return _("NetBSD ELF auxiliary vector data");
19248#endif
9437c45b 19249
06d949ec
KR
19250#ifdef NT_NETBSDCORE_LWPSTATUS
19251 case NT_NETBSDCORE_LWPSTATUS:
19252 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
19253#endif
19254
540e6170 19255 default:
06d949ec 19256 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
19257 defined for NetBSD core files. If the note type is less
19258 than the start of the machine-dependent note types, we don't
19259 understand it. */
19260
19261 if (e_type < NT_NETBSDCORE_FIRSTMACH)
19262 {
19263 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19264 return buff;
19265 }
19266 break;
9437c45b
JT
19267 }
19268
dda8d76d 19269 switch (filedata->file_header.e_machine)
9437c45b
JT
19270 {
19271 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
19272 and PT_GETFPREGS == mach+2. */
19273
19274 case EM_OLD_ALPHA:
19275 case EM_ALPHA:
19276 case EM_SPARC:
19277 case EM_SPARC32PLUS:
19278 case EM_SPARCV9:
19279 switch (e_type)
19280 {
2b692964 19281 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 19282 return _("PT_GETREGS (reg structure)");
2b692964 19283 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 19284 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19285 default:
19286 break;
19287 }
19288 break;
19289
c0d38b0e
CZ
19290 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
19291 There's also old PT___GETREGS40 == mach + 1 for old reg
19292 structure which lacks GBR. */
19293 case EM_SH:
19294 switch (e_type)
19295 {
19296 case NT_NETBSDCORE_FIRSTMACH + 1:
19297 return _("PT___GETREGS40 (old reg structure)");
19298 case NT_NETBSDCORE_FIRSTMACH + 3:
19299 return _("PT_GETREGS (reg structure)");
19300 case NT_NETBSDCORE_FIRSTMACH + 5:
19301 return _("PT_GETFPREGS (fpreg structure)");
19302 default:
19303 break;
19304 }
19305 break;
19306
9437c45b
JT
19307 /* On all other arch's, PT_GETREGS == mach+1 and
19308 PT_GETFPREGS == mach+3. */
19309 default:
19310 switch (e_type)
19311 {
2b692964 19312 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 19313 return _("PT_GETREGS (reg structure)");
2b692964 19314 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 19315 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19316 default:
19317 break;
19318 }
19319 }
19320
9cf03b7e 19321 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 19322 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
19323 return buff;
19324}
19325
70616151
TT
19326static const char *
19327get_stapsdt_note_type (unsigned e_type)
19328{
19329 static char buff[64];
19330
19331 switch (e_type)
19332 {
19333 case NT_STAPSDT:
19334 return _("NT_STAPSDT (SystemTap probe descriptors)");
19335
19336 default:
19337 break;
19338 }
19339
19340 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19341 return buff;
19342}
19343
32ec8896 19344static bfd_boolean
c6a9fc58
TT
19345print_stapsdt_note (Elf_Internal_Note *pnote)
19346{
3ca60c57
NC
19347 size_t len, maxlen;
19348 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
19349 char *data = pnote->descdata;
19350 char *data_end = pnote->descdata + pnote->descsz;
19351 bfd_vma pc, base_addr, semaphore;
19352 char *provider, *probe, *arg_fmt;
19353
3ca60c57
NC
19354 if (pnote->descsz < (addr_size * 3))
19355 goto stapdt_note_too_small;
19356
c6a9fc58
TT
19357 pc = byte_get ((unsigned char *) data, addr_size);
19358 data += addr_size;
3ca60c57 19359
c6a9fc58
TT
19360 base_addr = byte_get ((unsigned char *) data, addr_size);
19361 data += addr_size;
3ca60c57 19362
c6a9fc58
TT
19363 semaphore = byte_get ((unsigned char *) data, addr_size);
19364 data += addr_size;
19365
3ca60c57
NC
19366 if (data >= data_end)
19367 goto stapdt_note_too_small;
19368 maxlen = data_end - data;
19369 len = strnlen (data, maxlen);
19370 if (len < maxlen)
19371 {
19372 provider = data;
19373 data += len + 1;
19374 }
19375 else
19376 goto stapdt_note_too_small;
19377
19378 if (data >= data_end)
19379 goto stapdt_note_too_small;
19380 maxlen = data_end - data;
19381 len = strnlen (data, maxlen);
19382 if (len < maxlen)
19383 {
19384 probe = data;
19385 data += len + 1;
19386 }
19387 else
19388 goto stapdt_note_too_small;
9abca702 19389
3ca60c57
NC
19390 if (data >= data_end)
19391 goto stapdt_note_too_small;
19392 maxlen = data_end - data;
19393 len = strnlen (data, maxlen);
19394 if (len < maxlen)
19395 {
19396 arg_fmt = data;
19397 data += len + 1;
19398 }
19399 else
19400 goto stapdt_note_too_small;
c6a9fc58
TT
19401
19402 printf (_(" Provider: %s\n"), provider);
19403 printf (_(" Name: %s\n"), probe);
19404 printf (_(" Location: "));
19405 print_vma (pc, FULL_HEX);
19406 printf (_(", Base: "));
19407 print_vma (base_addr, FULL_HEX);
19408 printf (_(", Semaphore: "));
19409 print_vma (semaphore, FULL_HEX);
9cf03b7e 19410 printf ("\n");
c6a9fc58
TT
19411 printf (_(" Arguments: %s\n"), arg_fmt);
19412
19413 return data == data_end;
3ca60c57
NC
19414
19415 stapdt_note_too_small:
19416 printf (_(" <corrupt - note is too small>\n"));
19417 error (_("corrupt stapdt note - the data size is too small\n"));
19418 return FALSE;
c6a9fc58
TT
19419}
19420
00e98fc7
TG
19421static const char *
19422get_ia64_vms_note_type (unsigned e_type)
19423{
19424 static char buff[64];
19425
19426 switch (e_type)
19427 {
19428 case NT_VMS_MHD:
19429 return _("NT_VMS_MHD (module header)");
19430 case NT_VMS_LNM:
19431 return _("NT_VMS_LNM (language name)");
19432 case NT_VMS_SRC:
19433 return _("NT_VMS_SRC (source files)");
19434 case NT_VMS_TITLE:
9cf03b7e 19435 return "NT_VMS_TITLE";
00e98fc7
TG
19436 case NT_VMS_EIDC:
19437 return _("NT_VMS_EIDC (consistency check)");
19438 case NT_VMS_FPMODE:
19439 return _("NT_VMS_FPMODE (FP mode)");
19440 case NT_VMS_LINKTIME:
9cf03b7e 19441 return "NT_VMS_LINKTIME";
00e98fc7
TG
19442 case NT_VMS_IMGNAM:
19443 return _("NT_VMS_IMGNAM (image name)");
19444 case NT_VMS_IMGID:
19445 return _("NT_VMS_IMGID (image id)");
19446 case NT_VMS_LINKID:
19447 return _("NT_VMS_LINKID (link id)");
19448 case NT_VMS_IMGBID:
19449 return _("NT_VMS_IMGBID (build id)");
19450 case NT_VMS_GSTNAM:
19451 return _("NT_VMS_GSTNAM (sym table name)");
19452 case NT_VMS_ORIG_DYN:
9cf03b7e 19453 return "NT_VMS_ORIG_DYN";
00e98fc7 19454 case NT_VMS_PATCHTIME:
9cf03b7e 19455 return "NT_VMS_PATCHTIME";
00e98fc7
TG
19456 default:
19457 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19458 return buff;
19459 }
19460}
19461
32ec8896 19462static bfd_boolean
00e98fc7
TG
19463print_ia64_vms_note (Elf_Internal_Note * pnote)
19464{
8d18bf79
NC
19465 int maxlen = pnote->descsz;
19466
19467 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
19468 goto desc_size_fail;
19469
00e98fc7
TG
19470 switch (pnote->type)
19471 {
19472 case NT_VMS_MHD:
8d18bf79
NC
19473 if (maxlen <= 36)
19474 goto desc_size_fail;
19475
19476 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
19477
19478 printf (_(" Creation date : %.17s\n"), pnote->descdata);
19479 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
19480 if (l + 34 < maxlen)
19481 {
19482 printf (_(" Module name : %s\n"), pnote->descdata + 34);
19483 if (l + 35 < maxlen)
19484 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
19485 else
19486 printf (_(" Module version : <missing>\n"));
19487 }
00e98fc7 19488 else
8d18bf79
NC
19489 {
19490 printf (_(" Module name : <missing>\n"));
19491 printf (_(" Module version : <missing>\n"));
19492 }
00e98fc7 19493 break;
8d18bf79 19494
00e98fc7 19495 case NT_VMS_LNM:
8d18bf79 19496 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19497 break;
8d18bf79 19498
00e98fc7
TG
19499#ifdef BFD64
19500 case NT_VMS_FPMODE:
9cf03b7e 19501 printf (_(" Floating Point mode: "));
8d18bf79
NC
19502 if (maxlen < 8)
19503 goto desc_size_fail;
19504 /* FIXME: Generate an error if descsz > 8 ? */
19505
4a5cb34f 19506 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 19507 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 19508 break;
8d18bf79 19509
00e98fc7
TG
19510 case NT_VMS_LINKTIME:
19511 printf (_(" Link time: "));
8d18bf79
NC
19512 if (maxlen < 8)
19513 goto desc_size_fail;
19514 /* FIXME: Generate an error if descsz > 8 ? */
19515
00e98fc7 19516 print_vms_time
8d18bf79 19517 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19518 printf ("\n");
19519 break;
8d18bf79 19520
00e98fc7
TG
19521 case NT_VMS_PATCHTIME:
19522 printf (_(" Patch time: "));
8d18bf79
NC
19523 if (maxlen < 8)
19524 goto desc_size_fail;
19525 /* FIXME: Generate an error if descsz > 8 ? */
19526
00e98fc7 19527 print_vms_time
8d18bf79 19528 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19529 printf ("\n");
19530 break;
8d18bf79 19531
00e98fc7 19532 case NT_VMS_ORIG_DYN:
8d18bf79
NC
19533 if (maxlen < 34)
19534 goto desc_size_fail;
19535
00e98fc7
TG
19536 printf (_(" Major id: %u, minor id: %u\n"),
19537 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
19538 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 19539 printf (_(" Last modified : "));
00e98fc7
TG
19540 print_vms_time
19541 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 19542 printf (_("\n Link flags : "));
4a5cb34f 19543 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 19544 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 19545 printf (_(" Header flags: 0x%08x\n"),
948f632f 19546 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 19547 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
19548 break;
19549#endif
8d18bf79 19550
00e98fc7 19551 case NT_VMS_IMGNAM:
8d18bf79 19552 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19553 break;
8d18bf79 19554
00e98fc7 19555 case NT_VMS_GSTNAM:
8d18bf79 19556 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19557 break;
8d18bf79 19558
00e98fc7 19559 case NT_VMS_IMGID:
8d18bf79 19560 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19561 break;
8d18bf79 19562
00e98fc7 19563 case NT_VMS_LINKID:
8d18bf79 19564 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19565 break;
8d18bf79 19566
00e98fc7 19567 default:
32ec8896 19568 return FALSE;
00e98fc7 19569 }
8d18bf79 19570
32ec8896 19571 return TRUE;
8d18bf79
NC
19572
19573 desc_size_fail:
19574 printf (_(" <corrupt - data size is too small>\n"));
19575 error (_("corrupt IA64 note: data size is too small\n"));
19576 return FALSE;
00e98fc7
TG
19577}
19578
fd486f32
AM
19579struct build_attr_cache {
19580 Filedata *filedata;
19581 char *strtab;
19582 unsigned long strtablen;
19583 Elf_Internal_Sym *symtab;
19584 unsigned long nsyms;
19585} ba_cache;
19586
6f156d7a
NC
19587/* Find the symbol associated with a build attribute that is attached
19588 to address OFFSET. If PNAME is non-NULL then store the name of
19589 the symbol (if found) in the provided pointer, Returns NULL if a
19590 symbol could not be found. */
c799a79d 19591
6f156d7a
NC
19592static Elf_Internal_Sym *
19593get_symbol_for_build_attribute (Filedata * filedata,
19594 unsigned long offset,
19595 bfd_boolean is_open_attr,
19596 const char ** pname)
9ef920e9 19597{
fd486f32
AM
19598 Elf_Internal_Sym *saved_sym = NULL;
19599 Elf_Internal_Sym *sym;
9ef920e9 19600
dda8d76d 19601 if (filedata->section_headers != NULL
fd486f32 19602 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 19603 {
c799a79d 19604 Elf_Internal_Shdr * symsec;
9ef920e9 19605
fd486f32
AM
19606 free (ba_cache.strtab);
19607 ba_cache.strtab = NULL;
19608 free (ba_cache.symtab);
19609 ba_cache.symtab = NULL;
19610
c799a79d 19611 /* Load the symbol and string sections. */
dda8d76d
NC
19612 for (symsec = filedata->section_headers;
19613 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 19614 symsec ++)
9ef920e9 19615 {
28d13567
AM
19616 if (symsec->sh_type == SHT_SYMTAB
19617 && get_symtab (filedata, symsec,
19618 &ba_cache.symtab, &ba_cache.nsyms,
19619 &ba_cache.strtab, &ba_cache.strtablen))
19620 break;
9ef920e9 19621 }
fd486f32 19622 ba_cache.filedata = filedata;
9ef920e9
NC
19623 }
19624
fd486f32 19625 if (ba_cache.symtab == NULL)
6f156d7a 19626 return NULL;
9ef920e9 19627
c799a79d 19628 /* Find a symbol whose value matches offset. */
fd486f32 19629 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
19630 if (sym->st_value == offset)
19631 {
fd486f32 19632 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
19633 /* Huh ? This should not happen. */
19634 continue;
9ef920e9 19635
fd486f32 19636 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 19637 continue;
9ef920e9 19638
8fd75781
NC
19639 /* The AArch64 and ARM architectures define mapping symbols
19640 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
19641 if (ba_cache.strtab[sym->st_name] == '$'
19642 && ba_cache.strtab[sym->st_name + 1] != 0
19643 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
19644 continue;
19645
c799a79d
NC
19646 if (is_open_attr)
19647 {
19648 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
19649 and FILE or OBJECT symbols over NOTYPE symbols. We skip
19650 FUNC symbols entirely. */
19651 switch (ELF_ST_TYPE (sym->st_info))
19652 {
c799a79d 19653 case STT_OBJECT:
6f156d7a 19654 case STT_FILE:
c799a79d 19655 saved_sym = sym;
6f156d7a
NC
19656 if (sym->st_size)
19657 {
19658 /* If the symbol has a size associated
19659 with it then we can stop searching. */
fd486f32 19660 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 19661 }
c799a79d 19662 continue;
9ef920e9 19663
c799a79d
NC
19664 case STT_FUNC:
19665 /* Ignore function symbols. */
19666 continue;
19667
19668 default:
19669 break;
19670 }
19671
19672 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 19673 {
c799a79d
NC
19674 case STB_GLOBAL:
19675 if (saved_sym == NULL
19676 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
19677 saved_sym = sym;
19678 break;
c871dade 19679
c799a79d
NC
19680 case STB_LOCAL:
19681 if (saved_sym == NULL)
19682 saved_sym = sym;
19683 break;
19684
19685 default:
9ef920e9
NC
19686 break;
19687 }
19688 }
c799a79d
NC
19689 else
19690 {
19691 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
19692 continue;
19693
19694 saved_sym = sym;
19695 break;
19696 }
19697 }
19698
6f156d7a 19699 if (saved_sym && pname)
fd486f32 19700 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
19701
19702 return saved_sym;
c799a79d
NC
19703}
19704
d20e98ab
NC
19705/* Returns true iff addr1 and addr2 are in the same section. */
19706
19707static bfd_boolean
19708same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
19709{
19710 Elf_Internal_Shdr * a1;
19711 Elf_Internal_Shdr * a2;
19712
19713 a1 = find_section_by_address (filedata, addr1);
19714 a2 = find_section_by_address (filedata, addr2);
9abca702 19715
d20e98ab
NC
19716 return a1 == a2 && a1 != NULL;
19717}
19718
c799a79d 19719static bfd_boolean
dda8d76d
NC
19720print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
19721 Filedata * filedata)
c799a79d 19722{
6f156d7a
NC
19723 static unsigned long global_offset = 0;
19724 static unsigned long global_end = 0;
19725 static unsigned long func_offset = 0;
19726 static unsigned long func_end = 0;
c871dade 19727
6f156d7a
NC
19728 Elf_Internal_Sym * sym;
19729 const char * name;
19730 unsigned long start;
19731 unsigned long end;
19732 bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
19733
19734 switch (pnote->descsz)
c799a79d 19735 {
6f156d7a
NC
19736 case 0:
19737 /* A zero-length description means that the range of
19738 the previous note of the same type should be used. */
c799a79d 19739 if (is_open_attr)
c871dade 19740 {
6f156d7a
NC
19741 if (global_end > global_offset)
19742 printf (_(" Applies to region from %#lx to %#lx\n"),
19743 global_offset, global_end);
19744 else
19745 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
19746 }
19747 else
19748 {
6f156d7a
NC
19749 if (func_end > func_offset)
19750 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
19751 else
19752 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 19753 }
6f156d7a 19754 return TRUE;
9ef920e9 19755
6f156d7a
NC
19756 case 4:
19757 start = byte_get ((unsigned char *) pnote->descdata, 4);
19758 end = 0;
19759 break;
19760
19761 case 8:
19762 if (is_32bit_elf)
19763 {
19764 /* FIXME: We should check that version 3+ notes are being used here... */
19765 start = byte_get ((unsigned char *) pnote->descdata, 4);
19766 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19767 }
19768 else
19769 {
19770 start = byte_get ((unsigned char *) pnote->descdata, 8);
19771 end = 0;
19772 }
19773 break;
19774
19775 case 16:
19776 start = byte_get ((unsigned char *) pnote->descdata, 8);
19777 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
19778 break;
9abca702 19779
6f156d7a 19780 default:
c799a79d
NC
19781 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
19782 printf (_(" <invalid descsz>"));
19783 return FALSE;
19784 }
19785
6f156d7a
NC
19786 name = NULL;
19787 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
19788 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
19789 in order to avoid them being confused with the start address of the
19790 first function in the file... */
19791 if (sym == NULL && is_open_attr)
19792 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
19793 & name);
6f156d7a
NC
19794
19795 if (end == 0 && sym != NULL && sym->st_size > 0)
19796 end = start + sym->st_size;
c799a79d
NC
19797
19798 if (is_open_attr)
19799 {
d20e98ab
NC
19800 /* FIXME: Need to properly allow for section alignment.
19801 16 is just the alignment used on x86_64. */
19802 if (global_end > 0
19803 && start > BFD_ALIGN (global_end, 16)
19804 /* Build notes are not guaranteed to be organised in order of
19805 increasing address, but we should find the all of the notes
19806 for one section in the same place. */
19807 && same_section (filedata, start, global_end))
6f156d7a
NC
19808 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
19809 global_end + 1, start - 1);
19810
19811 printf (_(" Applies to region from %#lx"), start);
19812 global_offset = start;
19813
19814 if (end)
19815 {
19816 printf (_(" to %#lx"), end);
19817 global_end = end;
19818 }
c799a79d
NC
19819 }
19820 else
19821 {
6f156d7a
NC
19822 printf (_(" Applies to region from %#lx"), start);
19823 func_offset = start;
19824
19825 if (end)
19826 {
19827 printf (_(" to %#lx"), end);
19828 func_end = end;
19829 }
c799a79d
NC
19830 }
19831
6f156d7a
NC
19832 if (sym && name)
19833 printf (_(" (%s)"), name);
19834
19835 printf ("\n");
19836 return TRUE;
9ef920e9
NC
19837}
19838
19839static bfd_boolean
19840print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
19841{
1d15e434
NC
19842 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
19843 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
19844 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
19845 char name_type;
19846 char name_attribute;
1d15e434 19847 const char * expected_types;
9ef920e9
NC
19848 const char * name = pnote->namedata;
19849 const char * text;
88305e1b 19850 signed int left;
9ef920e9
NC
19851
19852 if (name == NULL || pnote->namesz < 2)
19853 {
19854 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 19855 print_symbol (-20, _(" <corrupt name>"));
9ef920e9
NC
19856 return FALSE;
19857 }
19858
6f156d7a
NC
19859 if (do_wide)
19860 left = 28;
19861 else
19862 left = 20;
88305e1b
NC
19863
19864 /* Version 2 of the spec adds a "GA" prefix to the name field. */
19865 if (name[0] == 'G' && name[1] == 'A')
19866 {
6f156d7a
NC
19867 if (pnote->namesz < 4)
19868 {
19869 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
19870 print_symbol (-20, _(" <corrupt name>"));
19871 return FALSE;
19872 }
19873
88305e1b
NC
19874 printf ("GA");
19875 name += 2;
19876 left -= 2;
19877 }
19878
9ef920e9
NC
19879 switch ((name_type = * name))
19880 {
19881 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
19882 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
19883 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
19884 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
19885 printf ("%c", * name);
88305e1b 19886 left --;
9ef920e9
NC
19887 break;
19888 default:
19889 error (_("unrecognised attribute type in name field: %d\n"), name_type);
19890 print_symbol (-20, _("<unknown name type>"));
19891 return FALSE;
19892 }
19893
9ef920e9
NC
19894 ++ name;
19895 text = NULL;
19896
19897 switch ((name_attribute = * name))
19898 {
19899 case GNU_BUILD_ATTRIBUTE_VERSION:
19900 text = _("<version>");
1d15e434 19901 expected_types = string_expected;
9ef920e9
NC
19902 ++ name;
19903 break;
19904 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
19905 text = _("<stack prot>");
75d7d298 19906 expected_types = "!+*";
9ef920e9
NC
19907 ++ name;
19908 break;
19909 case GNU_BUILD_ATTRIBUTE_RELRO:
19910 text = _("<relro>");
1d15e434 19911 expected_types = bool_expected;
9ef920e9
NC
19912 ++ name;
19913 break;
19914 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
19915 text = _("<stack size>");
1d15e434 19916 expected_types = number_expected;
9ef920e9
NC
19917 ++ name;
19918 break;
19919 case GNU_BUILD_ATTRIBUTE_TOOL:
19920 text = _("<tool>");
1d15e434 19921 expected_types = string_expected;
9ef920e9
NC
19922 ++ name;
19923 break;
19924 case GNU_BUILD_ATTRIBUTE_ABI:
19925 text = _("<ABI>");
19926 expected_types = "$*";
19927 ++ name;
19928 break;
19929 case GNU_BUILD_ATTRIBUTE_PIC:
19930 text = _("<PIC>");
1d15e434 19931 expected_types = number_expected;
9ef920e9
NC
19932 ++ name;
19933 break;
a8be5506
NC
19934 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
19935 text = _("<short enum>");
1d15e434 19936 expected_types = bool_expected;
a8be5506
NC
19937 ++ name;
19938 break;
9ef920e9
NC
19939 default:
19940 if (ISPRINT (* name))
19941 {
19942 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
19943
19944 if (len > left && ! do_wide)
19945 len = left;
75d7d298 19946 printf ("%.*s:", len, name);
9ef920e9 19947 left -= len;
0dd6ae21 19948 name += len;
9ef920e9
NC
19949 }
19950 else
19951 {
3e6b6445 19952 static char tmpbuf [128];
88305e1b 19953
3e6b6445
NC
19954 error (_("unrecognised byte in name field: %d\n"), * name);
19955 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
19956 text = tmpbuf;
19957 name ++;
9ef920e9
NC
19958 }
19959 expected_types = "*$!+";
19960 break;
19961 }
19962
19963 if (text)
88305e1b 19964 left -= printf ("%s", text);
9ef920e9
NC
19965
19966 if (strchr (expected_types, name_type) == NULL)
75d7d298 19967 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
19968
19969 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
19970 {
19971 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
19972 (unsigned long) pnote->namesz,
19973 (long) (name - pnote->namedata));
19974 return FALSE;
19975 }
19976
19977 if (left < 1 && ! do_wide)
19978 return TRUE;
19979
19980 switch (name_type)
19981 {
19982 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
19983 {
b06b2c92 19984 unsigned int bytes;
ddef72cd
NC
19985 unsigned long long val = 0;
19986 unsigned int shift = 0;
19987 char * decoded = NULL;
19988
b06b2c92
NC
19989 bytes = pnote->namesz - (name - pnote->namedata);
19990 if (bytes > 0)
19991 /* The -1 is because the name field is always 0 terminated, and we
19992 want to be able to ensure that the shift in the while loop below
19993 will not overflow. */
19994 -- bytes;
19995
ddef72cd
NC
19996 if (bytes > sizeof (val))
19997 {
3e6b6445
NC
19998 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
19999 bytes);
20000 bytes = sizeof (val);
ddef72cd 20001 }
3e6b6445
NC
20002 /* We do not bother to warn if bytes == 0 as this can
20003 happen with some early versions of the gcc plugin. */
9ef920e9
NC
20004
20005 while (bytes --)
20006 {
54b8331d 20007 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
20008
20009 val |= byte << shift;
9ef920e9
NC
20010 shift += 8;
20011 }
20012
75d7d298 20013 switch (name_attribute)
9ef920e9 20014 {
75d7d298 20015 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
20016 switch (val)
20017 {
75d7d298
NC
20018 case 0: decoded = "static"; break;
20019 case 1: decoded = "pic"; break;
20020 case 2: decoded = "PIC"; break;
20021 case 3: decoded = "pie"; break;
20022 case 4: decoded = "PIE"; break;
20023 default: break;
9ef920e9 20024 }
75d7d298
NC
20025 break;
20026 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20027 switch (val)
9ef920e9 20028 {
75d7d298
NC
20029 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
20030 case 0: decoded = "off"; break;
20031 case 1: decoded = "on"; break;
20032 case 2: decoded = "all"; break;
20033 case 3: decoded = "strong"; break;
20034 case 4: decoded = "explicit"; break;
20035 default: break;
9ef920e9 20036 }
75d7d298
NC
20037 break;
20038 default:
20039 break;
9ef920e9
NC
20040 }
20041
75d7d298 20042 if (decoded != NULL)
3e6b6445
NC
20043 {
20044 print_symbol (-left, decoded);
20045 left = 0;
20046 }
20047 else if (val == 0)
20048 {
20049 printf ("0x0");
20050 left -= 3;
20051 }
9ef920e9 20052 else
75d7d298
NC
20053 {
20054 if (do_wide)
ddef72cd 20055 left -= printf ("0x%llx", val);
75d7d298 20056 else
ddef72cd 20057 left -= printf ("0x%-.*llx", left, val);
75d7d298 20058 }
9ef920e9
NC
20059 }
20060 break;
20061 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20062 left -= print_symbol (- left, name);
20063 break;
20064 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20065 left -= print_symbol (- left, "true");
20066 break;
20067 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20068 left -= print_symbol (- left, "false");
20069 break;
20070 }
20071
20072 if (do_wide && left > 0)
20073 printf ("%-*s", left, " ");
9abca702 20074
9ef920e9
NC
20075 return TRUE;
20076}
20077
6d118b09
NC
20078/* Note that by the ELF standard, the name field is already null byte
20079 terminated, and namesz includes the terminating null byte.
20080 I.E. the value of namesz for the name "FSF" is 4.
20081
e3c8793a 20082 If the value of namesz is zero, there is no name present. */
9ef920e9 20083
32ec8896 20084static bfd_boolean
9ef920e9 20085process_note (Elf_Internal_Note * pnote,
dda8d76d 20086 Filedata * filedata)
779fe533 20087{
2cf0635d
NC
20088 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
20089 const char * nt;
9437c45b
JT
20090
20091 if (pnote->namesz == 0)
1ec5cd37
NC
20092 /* If there is no note name, then use the default set of
20093 note type strings. */
dda8d76d 20094 nt = get_note_type (filedata, pnote->type);
1ec5cd37 20095
1118d252
RM
20096 else if (const_strneq (pnote->namedata, "GNU"))
20097 /* GNU-specific object file notes. */
20098 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
20099
20100 else if (const_strneq (pnote->namedata, "FreeBSD"))
20101 /* FreeBSD-specific core file notes. */
dda8d76d 20102 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 20103
0112cd26 20104 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 20105 /* NetBSD-specific core file notes. */
dda8d76d 20106 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 20107
c6056a74
SF
20108 else if (const_strneq (pnote->namedata, "NetBSD"))
20109 /* NetBSD-specific core file notes. */
20110 return process_netbsd_elf_note (pnote);
20111
9abca702
CZ
20112 else if (const_strneq (pnote->namedata, "PaX"))
20113 /* NetBSD-specific core file notes. */
20114 return process_netbsd_elf_note (pnote);
20115
b15fa79e
AM
20116 else if (strneq (pnote->namedata, "SPU/", 4))
20117 {
20118 /* SPU-specific core file notes. */
20119 nt = pnote->namedata + 4;
20120 name = "SPU";
20121 }
20122
00e98fc7
TG
20123 else if (const_strneq (pnote->namedata, "IPF/VMS"))
20124 /* VMS/ia64-specific file notes. */
20125 nt = get_ia64_vms_note_type (pnote->type);
20126
70616151
TT
20127 else if (const_strneq (pnote->namedata, "stapsdt"))
20128 nt = get_stapsdt_note_type (pnote->type);
20129
9437c45b 20130 else
1ec5cd37
NC
20131 /* Don't recognize this note name; just use the default set of
20132 note type strings. */
dda8d76d 20133 nt = get_note_type (filedata, pnote->type);
9437c45b 20134
1449284b 20135 printf (" ");
9ef920e9 20136
483767a3
AM
20137 if (((const_strneq (pnote->namedata, "GA")
20138 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20139 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20140 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20141 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
20142 print_gnu_build_attribute_name (pnote);
20143 else
20144 print_symbol (-20, name);
20145
20146 if (do_wide)
20147 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
20148 else
20149 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7
TG
20150
20151 if (const_strneq (pnote->namedata, "IPF/VMS"))
20152 return print_ia64_vms_note (pnote);
664f90a3 20153 else if (const_strneq (pnote->namedata, "GNU"))
dda8d76d 20154 return print_gnu_note (filedata, pnote);
c6a9fc58
TT
20155 else if (const_strneq (pnote->namedata, "stapsdt"))
20156 return print_stapsdt_note (pnote);
9ece1fa9
TT
20157 else if (const_strneq (pnote->namedata, "CORE"))
20158 return print_core_note (pnote);
483767a3
AM
20159 else if (((const_strneq (pnote->namedata, "GA")
20160 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20161 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20162 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20163 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 20164 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 20165
9ef920e9 20166 if (pnote->descsz)
1449284b
NC
20167 {
20168 unsigned long i;
20169
20170 printf (_(" description data: "));
20171 for (i = 0; i < pnote->descsz; i++)
178d8719 20172 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
20173 if (!do_wide)
20174 printf ("\n");
1449284b
NC
20175 }
20176
9ef920e9
NC
20177 if (do_wide)
20178 printf ("\n");
20179
32ec8896 20180 return TRUE;
1449284b 20181}
6d118b09 20182
32ec8896 20183static bfd_boolean
dda8d76d
NC
20184process_notes_at (Filedata * filedata,
20185 Elf_Internal_Shdr * section,
20186 bfd_vma offset,
82ed9683
L
20187 bfd_vma length,
20188 bfd_vma align)
779fe533 20189{
2cf0635d
NC
20190 Elf_External_Note * pnotes;
20191 Elf_External_Note * external;
4dff97b2
NC
20192 char * end;
20193 bfd_boolean res = TRUE;
103f02d3 20194
779fe533 20195 if (length <= 0)
32ec8896 20196 return FALSE;
103f02d3 20197
1449284b
NC
20198 if (section)
20199 {
dda8d76d 20200 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 20201 if (pnotes)
32ec8896 20202 {
dda8d76d 20203 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
20204 {
20205 free (pnotes);
20206 return FALSE;
20207 }
32ec8896 20208 }
1449284b
NC
20209 }
20210 else
82ed9683 20211 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 20212 _("notes"));
4dff97b2 20213
dd24e3da 20214 if (pnotes == NULL)
32ec8896 20215 return FALSE;
779fe533 20216
103f02d3 20217 external = pnotes;
103f02d3 20218
1449284b 20219 if (section)
dda8d76d 20220 printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b
NC
20221 else
20222 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
20223 (unsigned long) offset, (unsigned long) length);
20224
82ed9683
L
20225 /* NB: Some note sections may have alignment value of 0 or 1. gABI
20226 specifies that notes should be aligned to 4 bytes in 32-bit
20227 objects and to 8 bytes in 64-bit objects. As a Linux extension,
20228 we also support 4 byte alignment in 64-bit objects. If section
20229 alignment is less than 4, we treate alignment as 4 bytes. */
20230 if (align < 4)
20231 align = 4;
20232 else if (align != 4 && align != 8)
20233 {
20234 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
20235 (long) align);
a788aedd 20236 free (pnotes);
82ed9683
L
20237 return FALSE;
20238 }
20239
dbe15e4e 20240 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 20241
c8071705
NC
20242 end = (char *) pnotes + length;
20243 while ((char *) external < end)
779fe533 20244 {
b34976b6 20245 Elf_Internal_Note inote;
15b42fb0 20246 size_t min_notesz;
4dff97b2 20247 char * next;
2cf0635d 20248 char * temp = NULL;
c8071705 20249 size_t data_remaining = end - (char *) external;
6d118b09 20250
dda8d76d 20251 if (!is_ia64_vms (filedata))
15b42fb0 20252 {
9dd3a467
NC
20253 /* PR binutils/15191
20254 Make sure that there is enough data to read. */
15b42fb0
AM
20255 min_notesz = offsetof (Elf_External_Note, name);
20256 if (data_remaining < min_notesz)
9dd3a467 20257 {
d3a49aa8
AM
20258 warn (ngettext ("Corrupt note: only %ld byte remains, "
20259 "not enough for a full note\n",
20260 "Corrupt note: only %ld bytes remain, "
20261 "not enough for a full note\n",
20262 data_remaining),
20263 (long) data_remaining);
9dd3a467
NC
20264 break;
20265 }
5396a86e
AM
20266 data_remaining -= min_notesz;
20267
15b42fb0
AM
20268 inote.type = BYTE_GET (external->type);
20269 inote.namesz = BYTE_GET (external->namesz);
20270 inote.namedata = external->name;
20271 inote.descsz = BYTE_GET (external->descsz);
276da9b3 20272 inote.descdata = ((char *) external
4dff97b2 20273 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 20274 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 20275 next = ((char *) external
4dff97b2 20276 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 20277 }
00e98fc7 20278 else
15b42fb0
AM
20279 {
20280 Elf64_External_VMS_Note *vms_external;
00e98fc7 20281
9dd3a467
NC
20282 /* PR binutils/15191
20283 Make sure that there is enough data to read. */
15b42fb0
AM
20284 min_notesz = offsetof (Elf64_External_VMS_Note, name);
20285 if (data_remaining < min_notesz)
9dd3a467 20286 {
d3a49aa8
AM
20287 warn (ngettext ("Corrupt note: only %ld byte remains, "
20288 "not enough for a full note\n",
20289 "Corrupt note: only %ld bytes remain, "
20290 "not enough for a full note\n",
20291 data_remaining),
20292 (long) data_remaining);
9dd3a467
NC
20293 break;
20294 }
5396a86e 20295 data_remaining -= min_notesz;
3e55a963 20296
15b42fb0
AM
20297 vms_external = (Elf64_External_VMS_Note *) external;
20298 inote.type = BYTE_GET (vms_external->type);
20299 inote.namesz = BYTE_GET (vms_external->namesz);
20300 inote.namedata = vms_external->name;
20301 inote.descsz = BYTE_GET (vms_external->descsz);
20302 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
20303 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20304 next = inote.descdata + align_power (inote.descsz, 3);
20305 }
20306
5396a86e
AM
20307 /* PR 17531: file: 3443835e. */
20308 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
20309 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
20310 || (size_t) (inote.descdata - inote.namedata) > data_remaining
20311 || (size_t) (next - inote.descdata) < inote.descsz
20312 || ((size_t) (next - inote.descdata)
20313 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 20314 {
15b42fb0 20315 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 20316 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
20317 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
20318 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
20319 break;
20320 }
20321
15b42fb0 20322 external = (Elf_External_Note *) next;
dd24e3da 20323
6d118b09
NC
20324 /* Verify that name is null terminated. It appears that at least
20325 one version of Linux (RedHat 6.0) generates corefiles that don't
20326 comply with the ELF spec by failing to include the null byte in
20327 namesz. */
18344509 20328 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 20329 {
5396a86e 20330 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 20331 {
5396a86e
AM
20332 temp = (char *) malloc (inote.namesz + 1);
20333 if (temp == NULL)
20334 {
20335 error (_("Out of memory allocating space for inote name\n"));
20336 res = FALSE;
20337 break;
20338 }
76da6bbe 20339
5396a86e
AM
20340 memcpy (temp, inote.namedata, inote.namesz);
20341 inote.namedata = temp;
20342 }
20343 inote.namedata[inote.namesz] = 0;
6d118b09
NC
20344 }
20345
dda8d76d 20346 if (! process_note (& inote, filedata))
6b4bf3bc 20347 res = FALSE;
103f02d3 20348
9db70fc3
AM
20349 free (temp);
20350 temp = NULL;
779fe533
NC
20351 }
20352
20353 free (pnotes);
103f02d3 20354
779fe533
NC
20355 return res;
20356}
20357
32ec8896 20358static bfd_boolean
dda8d76d 20359process_corefile_note_segments (Filedata * filedata)
779fe533 20360{
2cf0635d 20361 Elf_Internal_Phdr * segment;
b34976b6 20362 unsigned int i;
32ec8896 20363 bfd_boolean res = TRUE;
103f02d3 20364
dda8d76d 20365 if (! get_program_headers (filedata))
6b4bf3bc 20366 return TRUE;
103f02d3 20367
dda8d76d
NC
20368 for (i = 0, segment = filedata->program_headers;
20369 i < filedata->file_header.e_phnum;
b34976b6 20370 i++, segment++)
779fe533
NC
20371 {
20372 if (segment->p_type == PT_NOTE)
dda8d76d 20373 if (! process_notes_at (filedata, NULL,
32ec8896 20374 (bfd_vma) segment->p_offset,
82ed9683
L
20375 (bfd_vma) segment->p_filesz,
20376 (bfd_vma) segment->p_align))
32ec8896 20377 res = FALSE;
779fe533 20378 }
103f02d3 20379
779fe533
NC
20380 return res;
20381}
20382
32ec8896 20383static bfd_boolean
dda8d76d 20384process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
20385{
20386 Elf_External_Note * pnotes;
20387 Elf_External_Note * external;
c8071705 20388 char * end;
32ec8896 20389 bfd_boolean res = TRUE;
685080f2
NC
20390
20391 if (length <= 0)
32ec8896 20392 return FALSE;
685080f2 20393
dda8d76d 20394 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
20395 _("v850 notes"));
20396 if (pnotes == NULL)
32ec8896 20397 return FALSE;
685080f2
NC
20398
20399 external = pnotes;
c8071705 20400 end = (char*) pnotes + length;
685080f2
NC
20401
20402 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
20403 (unsigned long) offset, (unsigned long) length);
20404
c8071705 20405 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
20406 {
20407 Elf_External_Note * next;
20408 Elf_Internal_Note inote;
20409
20410 inote.type = BYTE_GET (external->type);
20411 inote.namesz = BYTE_GET (external->namesz);
20412 inote.namedata = external->name;
20413 inote.descsz = BYTE_GET (external->descsz);
20414 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
20415 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20416
c8071705
NC
20417 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
20418 {
20419 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
20420 inote.descdata = inote.namedata;
20421 inote.namesz = 0;
20422 }
20423
685080f2
NC
20424 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
20425
c8071705 20426 if ( ((char *) next > end)
685080f2
NC
20427 || ((char *) next < (char *) pnotes))
20428 {
20429 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
20430 (unsigned long) ((char *) external - (char *) pnotes));
20431 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20432 inote.type, inote.namesz, inote.descsz);
20433 break;
20434 }
20435
20436 external = next;
20437
20438 /* Prevent out-of-bounds indexing. */
c8071705 20439 if ( inote.namedata + inote.namesz > end
685080f2
NC
20440 || inote.namedata + inote.namesz < inote.namedata)
20441 {
20442 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
20443 (unsigned long) ((char *) external - (char *) pnotes));
20444 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20445 inote.type, inote.namesz, inote.descsz);
20446 break;
20447 }
20448
20449 printf (" %s: ", get_v850_elf_note_type (inote.type));
20450
20451 if (! print_v850_note (& inote))
20452 {
32ec8896 20453 res = FALSE;
685080f2
NC
20454 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
20455 inote.namesz, inote.descsz);
20456 }
20457 }
20458
20459 free (pnotes);
20460
20461 return res;
20462}
20463
32ec8896 20464static bfd_boolean
dda8d76d 20465process_note_sections (Filedata * filedata)
1ec5cd37 20466{
2cf0635d 20467 Elf_Internal_Shdr * section;
1ec5cd37 20468 unsigned long i;
32ec8896
NC
20469 unsigned int n = 0;
20470 bfd_boolean res = TRUE;
1ec5cd37 20471
dda8d76d
NC
20472 for (i = 0, section = filedata->section_headers;
20473 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 20474 i++, section++)
685080f2
NC
20475 {
20476 if (section->sh_type == SHT_NOTE)
20477 {
dda8d76d 20478 if (! process_notes_at (filedata, section,
32ec8896 20479 (bfd_vma) section->sh_offset,
82ed9683
L
20480 (bfd_vma) section->sh_size,
20481 (bfd_vma) section->sh_addralign))
32ec8896 20482 res = FALSE;
685080f2
NC
20483 n++;
20484 }
20485
dda8d76d
NC
20486 if (( filedata->file_header.e_machine == EM_V800
20487 || filedata->file_header.e_machine == EM_V850
20488 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
20489 && section->sh_type == SHT_RENESAS_INFO)
20490 {
dda8d76d 20491 if (! process_v850_notes (filedata,
32ec8896
NC
20492 (bfd_vma) section->sh_offset,
20493 (bfd_vma) section->sh_size))
20494 res = FALSE;
685080f2
NC
20495 n++;
20496 }
20497 }
df565f32
NC
20498
20499 if (n == 0)
20500 /* Try processing NOTE segments instead. */
dda8d76d 20501 return process_corefile_note_segments (filedata);
1ec5cd37
NC
20502
20503 return res;
20504}
20505
32ec8896 20506static bfd_boolean
dda8d76d 20507process_notes (Filedata * filedata)
779fe533
NC
20508{
20509 /* If we have not been asked to display the notes then do nothing. */
20510 if (! do_notes)
32ec8896 20511 return TRUE;
103f02d3 20512
dda8d76d
NC
20513 if (filedata->file_header.e_type != ET_CORE)
20514 return process_note_sections (filedata);
103f02d3 20515
779fe533 20516 /* No program headers means no NOTE segment. */
dda8d76d
NC
20517 if (filedata->file_header.e_phnum > 0)
20518 return process_corefile_note_segments (filedata);
779fe533 20519
1ec5cd37 20520 printf (_("No note segments present in the core file.\n"));
32ec8896 20521 return TRUE;
779fe533
NC
20522}
20523
60abdbed
NC
20524static unsigned char *
20525display_public_gnu_attributes (unsigned char * start,
20526 const unsigned char * const end)
20527{
20528 printf (_(" Unknown GNU attribute: %s\n"), start);
20529
20530 start += strnlen ((char *) start, end - start);
20531 display_raw_attribute (start, end);
20532
20533 return (unsigned char *) end;
20534}
20535
20536static unsigned char *
20537display_generic_attribute (unsigned char * start,
20538 unsigned int tag,
20539 const unsigned char * const end)
20540{
20541 if (tag == 0)
20542 return (unsigned char *) end;
20543
20544 return display_tag_value (tag, start, end);
20545}
20546
32ec8896 20547static bfd_boolean
dda8d76d 20548process_arch_specific (Filedata * filedata)
252b5132 20549{
a952a375 20550 if (! do_arch)
32ec8896 20551 return TRUE;
a952a375 20552
dda8d76d 20553 switch (filedata->file_header.e_machine)
252b5132 20554 {
53a346d8
CZ
20555 case EM_ARC:
20556 case EM_ARC_COMPACT:
20557 case EM_ARC_COMPACT2:
dda8d76d 20558 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
20559 display_arc_attribute,
20560 display_generic_attribute);
11c1ff18 20561 case EM_ARM:
dda8d76d 20562 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
20563 display_arm_attribute,
20564 display_generic_attribute);
20565
252b5132 20566 case EM_MIPS:
4fe85591 20567 case EM_MIPS_RS3_LE:
dda8d76d 20568 return process_mips_specific (filedata);
60abdbed
NC
20569
20570 case EM_MSP430:
dda8d76d 20571 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 20572 display_msp430_attribute,
c0ea7c52 20573 display_msp430_gnu_attribute);
60abdbed 20574
2dc8dd17
JW
20575 case EM_RISCV:
20576 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
20577 display_riscv_attribute,
20578 display_generic_attribute);
20579
35c08157 20580 case EM_NDS32:
dda8d76d 20581 return process_nds32_specific (filedata);
60abdbed 20582
85f7484a
PB
20583 case EM_68K:
20584 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
20585 display_m68k_gnu_attribute);
20586
34c8bcba 20587 case EM_PPC:
b82317dd 20588 case EM_PPC64:
dda8d76d 20589 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20590 display_power_gnu_attribute);
20591
643f7afb
AK
20592 case EM_S390:
20593 case EM_S390_OLD:
dda8d76d 20594 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20595 display_s390_gnu_attribute);
20596
9e8c70f9
DM
20597 case EM_SPARC:
20598 case EM_SPARC32PLUS:
20599 case EM_SPARCV9:
dda8d76d 20600 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20601 display_sparc_gnu_attribute);
20602
59e6276b 20603 case EM_TI_C6000:
dda8d76d 20604 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
20605 display_tic6x_attribute,
20606 display_generic_attribute);
20607
0861f561
CQ
20608 case EM_CSKY:
20609 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
20610 display_csky_attribute, NULL);
20611
252b5132 20612 default:
dda8d76d 20613 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
20614 display_public_gnu_attributes,
20615 display_generic_attribute);
252b5132 20616 }
252b5132
RH
20617}
20618
32ec8896 20619static bfd_boolean
dda8d76d 20620get_file_header (Filedata * filedata)
252b5132 20621{
9ea033b2 20622 /* Read in the identity array. */
dda8d76d 20623 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20624 return FALSE;
252b5132 20625
9ea033b2 20626 /* Determine how to read the rest of the header. */
dda8d76d 20627 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 20628 {
1a0670f3
AM
20629 default:
20630 case ELFDATANONE:
adab8cdc
AO
20631 case ELFDATA2LSB:
20632 byte_get = byte_get_little_endian;
20633 byte_put = byte_put_little_endian;
20634 break;
20635 case ELFDATA2MSB:
20636 byte_get = byte_get_big_endian;
20637 byte_put = byte_put_big_endian;
20638 break;
9ea033b2
NC
20639 }
20640
20641 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 20642 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
20643
20644 /* Read in the rest of the header. */
20645 if (is_32bit_elf)
20646 {
20647 Elf32_External_Ehdr ehdr32;
252b5132 20648
dda8d76d 20649 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20650 return FALSE;
103f02d3 20651
dda8d76d
NC
20652 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
20653 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
20654 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
20655 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
20656 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
20657 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
20658 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
20659 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
20660 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
20661 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
20662 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
20663 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
20664 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 20665 }
252b5132 20666 else
9ea033b2
NC
20667 {
20668 Elf64_External_Ehdr ehdr64;
a952a375
NC
20669
20670 /* If we have been compiled with sizeof (bfd_vma) == 4, then
20671 we will not be able to cope with the 64bit data found in
20672 64 ELF files. Detect this now and abort before we start
50c2245b 20673 overwriting things. */
a952a375
NC
20674 if (sizeof (bfd_vma) < 8)
20675 {
e3c8793a
NC
20676 error (_("This instance of readelf has been built without support for a\n\
2067764 bit data type and so it cannot read 64 bit ELF files.\n"));
32ec8896 20678 return FALSE;
a952a375 20679 }
103f02d3 20680
dda8d76d 20681 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20682 return FALSE;
103f02d3 20683
dda8d76d
NC
20684 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
20685 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
20686 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
20687 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
20688 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
20689 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
20690 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
20691 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
20692 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
20693 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
20694 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
20695 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
20696 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 20697 }
252b5132 20698
dda8d76d 20699 if (filedata->file_header.e_shoff)
7ece0d85
JJ
20700 {
20701 /* There may be some extensions in the first section header. Don't
20702 bomb if we can't read it. */
20703 if (is_32bit_elf)
dda8d76d 20704 get_32bit_section_headers (filedata, TRUE);
7ece0d85 20705 else
dda8d76d 20706 get_64bit_section_headers (filedata, TRUE);
7ece0d85 20707 }
560f3c1c 20708
32ec8896 20709 return TRUE;
252b5132
RH
20710}
20711
dda8d76d
NC
20712static void
20713close_file (Filedata * filedata)
20714{
20715 if (filedata)
20716 {
20717 if (filedata->handle)
20718 fclose (filedata->handle);
20719 free (filedata);
20720 }
20721}
20722
20723void
20724close_debug_file (void * data)
20725{
20726 close_file ((Filedata *) data);
20727}
20728
20729static Filedata *
20730open_file (const char * pathname)
20731{
20732 struct stat statbuf;
20733 Filedata * filedata = NULL;
20734
20735 if (stat (pathname, & statbuf) < 0
20736 || ! S_ISREG (statbuf.st_mode))
20737 goto fail;
20738
20739 filedata = calloc (1, sizeof * filedata);
20740 if (filedata == NULL)
20741 goto fail;
20742
20743 filedata->handle = fopen (pathname, "rb");
20744 if (filedata->handle == NULL)
20745 goto fail;
20746
20747 filedata->file_size = (bfd_size_type) statbuf.st_size;
20748 filedata->file_name = pathname;
20749
20750 if (! get_file_header (filedata))
20751 goto fail;
20752
20753 if (filedata->file_header.e_shoff)
20754 {
20755 bfd_boolean res;
20756
20757 /* Read the section headers again, this time for real. */
20758 if (is_32bit_elf)
20759 res = get_32bit_section_headers (filedata, FALSE);
20760 else
20761 res = get_64bit_section_headers (filedata, FALSE);
20762
20763 if (!res)
20764 goto fail;
20765 }
20766
20767 return filedata;
20768
20769 fail:
20770 if (filedata)
20771 {
20772 if (filedata->handle)
20773 fclose (filedata->handle);
20774 free (filedata);
20775 }
20776 return NULL;
20777}
20778
20779void *
20780open_debug_file (const char * pathname)
20781{
20782 return open_file (pathname);
20783}
20784
fb52b2f4
NC
20785/* Process one ELF object file according to the command line options.
20786 This file may actually be stored in an archive. The file is
32ec8896
NC
20787 positioned at the start of the ELF object. Returns TRUE if no
20788 problems were encountered, FALSE otherwise. */
fb52b2f4 20789
32ec8896 20790static bfd_boolean
dda8d76d 20791process_object (Filedata * filedata)
252b5132 20792{
24841daa 20793 bfd_boolean have_separate_files;
252b5132 20794 unsigned int i;
2482f306 20795 bfd_boolean res;
252b5132 20796
dda8d76d 20797 if (! get_file_header (filedata))
252b5132 20798 {
dda8d76d 20799 error (_("%s: Failed to read file header\n"), filedata->file_name);
32ec8896 20800 return FALSE;
252b5132
RH
20801 }
20802
20803 /* Initialise per file variables. */
978c4450
AM
20804 for (i = ARRAY_SIZE (filedata->version_info); i--;)
20805 filedata->version_info[i] = 0;
252b5132 20806
978c4450
AM
20807 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
20808 filedata->dynamic_info[i] = 0;
20809 filedata->dynamic_info_DT_GNU_HASH = 0;
20810 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
20811
20812 /* Process the file. */
20813 if (show_name)
dda8d76d 20814 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 20815
18bd398b
NC
20816 /* Initialise the dump_sects array from the cmdline_dump_sects array.
20817 Note we do this even if cmdline_dump_sects is empty because we
20818 must make sure that the dump_sets array is zeroed out before each
20819 object file is processed. */
6431e409
AM
20820 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
20821 memset (filedata->dump.dump_sects, 0,
20822 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20823
dda8d76d 20824 if (cmdline.num_dump_sects > 0)
18bd398b 20825 {
6431e409 20826 if (filedata->dump.num_dump_sects == 0)
18bd398b 20827 /* A sneaky way of allocating the dump_sects array. */
6431e409 20828 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
18bd398b 20829
6431e409
AM
20830 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
20831 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
20832 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20833 }
d70c5fc7 20834
dda8d76d 20835 if (! process_file_header (filedata))
32ec8896 20836 return FALSE;
252b5132 20837
dda8d76d 20838 if (! process_section_headers (filedata))
2f62977e 20839 {
32ec8896
NC
20840 /* Without loaded section headers we cannot process lots of things. */
20841 do_unwind = do_version = do_dump = do_arch = FALSE;
252b5132 20842
2f62977e 20843 if (! do_using_dynamic)
32ec8896 20844 do_syms = do_dyn_syms = do_reloc = FALSE;
2f62977e 20845 }
252b5132 20846
dda8d76d 20847 if (! process_section_groups (filedata))
32ec8896
NC
20848 /* Without loaded section groups we cannot process unwind. */
20849 do_unwind = FALSE;
d1f5c6e3 20850
2482f306
AM
20851 res = process_program_headers (filedata);
20852 if (res)
20853 res = process_dynamic_section (filedata);
252b5132 20854
dda8d76d 20855 if (! process_relocs (filedata))
32ec8896 20856 res = FALSE;
252b5132 20857
dda8d76d 20858 if (! process_unwind (filedata))
32ec8896 20859 res = FALSE;
4d6ed7c8 20860
dda8d76d 20861 if (! process_symbol_table (filedata))
32ec8896 20862 res = FALSE;
252b5132 20863
0f03783c
NC
20864 if (! process_lto_symbol_tables (filedata))
20865 res = FALSE;
20866
dda8d76d 20867 if (! process_syminfo (filedata))
32ec8896 20868 res = FALSE;
252b5132 20869
dda8d76d 20870 if (! process_version_sections (filedata))
32ec8896 20871 res = FALSE;
252b5132 20872
82ed9683 20873 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 20874 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 20875 else
24841daa 20876 have_separate_files = FALSE;
dda8d76d
NC
20877
20878 if (! process_section_contents (filedata))
32ec8896 20879 res = FALSE;
f5842774 20880
24841daa 20881 if (have_separate_files)
dda8d76d 20882 {
24841daa
NC
20883 separate_info * d;
20884
20885 for (d = first_separate_info; d != NULL; d = d->next)
20886 {
20887 if (! process_section_headers (d->handle))
20888 res = FALSE;
20889 else if (! process_section_contents (d->handle))
20890 res = FALSE;
20891 }
20892
20893 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
20894 }
20895
20896 if (! process_notes (filedata))
32ec8896 20897 res = FALSE;
103f02d3 20898
dda8d76d 20899 if (! process_gnu_liblist (filedata))
32ec8896 20900 res = FALSE;
047b2264 20901
dda8d76d 20902 if (! process_arch_specific (filedata))
32ec8896 20903 res = FALSE;
252b5132 20904
dda8d76d
NC
20905 free (filedata->program_headers);
20906 filedata->program_headers = NULL;
d93f0186 20907
dda8d76d
NC
20908 free (filedata->section_headers);
20909 filedata->section_headers = NULL;
252b5132 20910
dda8d76d
NC
20911 free (filedata->string_table);
20912 filedata->string_table = NULL;
20913 filedata->string_table_length = 0;
252b5132 20914
9db70fc3
AM
20915 free (filedata->dump.dump_sects);
20916 filedata->dump.dump_sects = NULL;
20917 filedata->dump.num_dump_sects = 0;
a788aedd 20918
9db70fc3
AM
20919 free (filedata->dynamic_strings);
20920 filedata->dynamic_strings = NULL;
20921 filedata->dynamic_strings_length = 0;
252b5132 20922
9db70fc3
AM
20923 free (filedata->dynamic_symbols);
20924 filedata->dynamic_symbols = NULL;
20925 filedata->num_dynamic_syms = 0;
252b5132 20926
9db70fc3
AM
20927 free (filedata->dynamic_syminfo);
20928 filedata->dynamic_syminfo = NULL;
ff78d6d6 20929
9db70fc3
AM
20930 free (filedata->dynamic_section);
20931 filedata->dynamic_section = NULL;
293c573e 20932
978c4450 20933 while (filedata->symtab_shndx_list != NULL)
8fb879cd 20934 {
978c4450
AM
20935 elf_section_list *next = filedata->symtab_shndx_list->next;
20936 free (filedata->symtab_shndx_list);
20937 filedata->symtab_shndx_list = next;
8fb879cd
AM
20938 }
20939
9db70fc3
AM
20940 free (filedata->section_headers_groups);
20941 filedata->section_headers_groups = NULL;
e4b17d5c 20942
978c4450 20943 if (filedata->section_groups)
e4b17d5c 20944 {
2cf0635d
NC
20945 struct group_list * g;
20946 struct group_list * next;
e4b17d5c 20947
978c4450 20948 for (i = 0; i < filedata->group_count; i++)
e4b17d5c 20949 {
978c4450 20950 for (g = filedata->section_groups [i].root; g != NULL; g = next)
e4b17d5c
L
20951 {
20952 next = g->next;
20953 free (g);
20954 }
20955 }
20956
978c4450
AM
20957 free (filedata->section_groups);
20958 filedata->section_groups = NULL;
e4b17d5c
L
20959 }
20960
19e6b90e 20961 free_debug_memory ();
18bd398b 20962
32ec8896 20963 return res;
252b5132
RH
20964}
20965
2cf0635d 20966/* Process an ELF archive.
32ec8896
NC
20967 On entry the file is positioned just after the ARMAG string.
20968 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 20969
32ec8896 20970static bfd_boolean
dda8d76d 20971process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
2cf0635d
NC
20972{
20973 struct archive_info arch;
20974 struct archive_info nested_arch;
20975 size_t got;
32ec8896 20976 bfd_boolean ret = TRUE;
2cf0635d 20977
32ec8896 20978 show_name = TRUE;
2cf0635d
NC
20979
20980 /* The ARCH structure is used to hold information about this archive. */
20981 arch.file_name = NULL;
20982 arch.file = NULL;
20983 arch.index_array = NULL;
20984 arch.sym_table = NULL;
20985 arch.longnames = NULL;
20986
20987 /* The NESTED_ARCH structure is used as a single-item cache of information
20988 about a nested archive (when members of a thin archive reside within
20989 another regular archive file). */
20990 nested_arch.file_name = NULL;
20991 nested_arch.file = NULL;
20992 nested_arch.index_array = NULL;
20993 nested_arch.sym_table = NULL;
20994 nested_arch.longnames = NULL;
20995
dda8d76d 20996 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
20997 filedata->file_size, is_thin_archive,
20998 do_archive_index) != 0)
2cf0635d 20999 {
32ec8896 21000 ret = FALSE;
2cf0635d 21001 goto out;
4145f1d5 21002 }
fb52b2f4 21003
4145f1d5
NC
21004 if (do_archive_index)
21005 {
2cf0635d 21006 if (arch.sym_table == NULL)
1cb7d8b1
AM
21007 error (_("%s: unable to dump the index as none was found\n"),
21008 filedata->file_name);
4145f1d5
NC
21009 else
21010 {
591f7597 21011 unsigned long i, l;
4145f1d5
NC
21012 unsigned long current_pos;
21013
1cb7d8b1
AM
21014 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
21015 "in the symbol table)\n"),
21016 filedata->file_name, (unsigned long) arch.index_num,
21017 arch.sym_size);
dda8d76d
NC
21018
21019 current_pos = ftell (filedata->handle);
4145f1d5 21020
2cf0635d 21021 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 21022 {
1cb7d8b1
AM
21023 if (i == 0
21024 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
21025 {
21026 char * member_name
21027 = get_archive_member_name_at (&arch, arch.index_array[i],
21028 &nested_arch);
2cf0635d 21029
1cb7d8b1
AM
21030 if (member_name != NULL)
21031 {
21032 char * qualified_name
21033 = make_qualified_name (&arch, &nested_arch,
21034 member_name);
2cf0635d 21035
1cb7d8b1
AM
21036 if (qualified_name != NULL)
21037 {
21038 printf (_("Contents of binary %s at offset "),
21039 qualified_name);
c2a7d3f5
NC
21040 (void) print_vma (arch.index_array[i], PREFIX_HEX);
21041 putchar ('\n');
1cb7d8b1
AM
21042 free (qualified_name);
21043 }
fd486f32 21044 free (member_name);
4145f1d5
NC
21045 }
21046 }
2cf0635d
NC
21047
21048 if (l >= arch.sym_size)
4145f1d5 21049 {
1cb7d8b1
AM
21050 error (_("%s: end of the symbol table reached "
21051 "before the end of the index\n"),
dda8d76d 21052 filedata->file_name);
32ec8896 21053 ret = FALSE;
cb8f3167 21054 break;
4145f1d5 21055 }
591f7597 21056 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
21057 printf ("\t%.*s\n",
21058 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 21059 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
21060 }
21061
67ce483b 21062 if (arch.uses_64bit_indices)
c2a7d3f5
NC
21063 l = (l + 7) & ~ 7;
21064 else
21065 l += l & 1;
21066
2cf0635d 21067 if (l < arch.sym_size)
32ec8896 21068 {
d3a49aa8
AM
21069 error (ngettext ("%s: %ld byte remains in the symbol table, "
21070 "but without corresponding entries in "
21071 "the index table\n",
21072 "%s: %ld bytes remain in the symbol table, "
21073 "but without corresponding entries in "
21074 "the index table\n",
21075 arch.sym_size - l),
dda8d76d 21076 filedata->file_name, arch.sym_size - l);
32ec8896
NC
21077 ret = FALSE;
21078 }
4145f1d5 21079
dda8d76d 21080 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 21081 {
1cb7d8b1
AM
21082 error (_("%s: failed to seek back to start of object files "
21083 "in the archive\n"),
dda8d76d 21084 filedata->file_name);
32ec8896 21085 ret = FALSE;
2cf0635d 21086 goto out;
4145f1d5 21087 }
fb52b2f4 21088 }
4145f1d5
NC
21089
21090 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
21091 && !do_segments && !do_header && !do_dump && !do_version
21092 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 21093 && !do_section_groups && !do_dyn_syms)
2cf0635d 21094 {
32ec8896 21095 ret = TRUE; /* Archive index only. */
2cf0635d
NC
21096 goto out;
21097 }
fb52b2f4
NC
21098 }
21099
fb52b2f4
NC
21100 while (1)
21101 {
2cf0635d
NC
21102 char * name;
21103 size_t namelen;
21104 char * qualified_name;
21105
21106 /* Read the next archive header. */
dda8d76d 21107 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
21108 {
21109 error (_("%s: failed to seek to next archive header\n"),
21110 arch.file_name);
21111 ret = FALSE;
21112 break;
21113 }
dda8d76d 21114 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 21115 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
21116 {
21117 if (got == 0)
2cf0635d 21118 break;
28e817cc
NC
21119 /* PR 24049 - we cannot use filedata->file_name as this will
21120 have already been freed. */
21121 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 21122
1cb7d8b1
AM
21123 ret = FALSE;
21124 break;
21125 }
2cf0635d 21126 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
21127 {
21128 error (_("%s: did not find a valid archive header\n"),
21129 arch.file_name);
21130 ret = FALSE;
21131 break;
21132 }
2cf0635d
NC
21133
21134 arch.next_arhdr_offset += sizeof arch.arhdr;
21135
978c4450
AM
21136 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
21137 if (filedata->archive_file_size & 01)
21138 ++filedata->archive_file_size;
2cf0635d
NC
21139
21140 name = get_archive_member_name (&arch, &nested_arch);
21141 if (name == NULL)
fb52b2f4 21142 {
28e817cc 21143 error (_("%s: bad archive file name\n"), arch.file_name);
32ec8896 21144 ret = FALSE;
d989285c 21145 break;
fb52b2f4 21146 }
2cf0635d 21147 namelen = strlen (name);
fb52b2f4 21148
2cf0635d
NC
21149 qualified_name = make_qualified_name (&arch, &nested_arch, name);
21150 if (qualified_name == NULL)
fb52b2f4 21151 {
28e817cc 21152 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 21153 free (name);
32ec8896 21154 ret = FALSE;
d989285c 21155 break;
fb52b2f4
NC
21156 }
21157
2cf0635d 21158 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
21159 {
21160 /* This is a proxy for an external member of a thin archive. */
21161 Filedata * member_filedata;
21162 char * member_file_name = adjust_relative_path
dda8d76d 21163 (filedata->file_name, name, namelen);
32ec8896 21164
fd486f32 21165 free (name);
1cb7d8b1
AM
21166 if (member_file_name == NULL)
21167 {
fd486f32 21168 free (qualified_name);
1cb7d8b1
AM
21169 ret = FALSE;
21170 break;
21171 }
2cf0635d 21172
1cb7d8b1
AM
21173 member_filedata = open_file (member_file_name);
21174 if (member_filedata == NULL)
21175 {
21176 error (_("Input file '%s' is not readable.\n"), member_file_name);
21177 free (member_file_name);
fd486f32 21178 free (qualified_name);
1cb7d8b1
AM
21179 ret = FALSE;
21180 break;
21181 }
2cf0635d 21182
978c4450 21183 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 21184 member_filedata->file_name = qualified_name;
2cf0635d 21185
1cb7d8b1 21186 if (! process_object (member_filedata))
32ec8896 21187 ret = FALSE;
2cf0635d 21188
1cb7d8b1
AM
21189 close_file (member_filedata);
21190 free (member_file_name);
1cb7d8b1 21191 }
2cf0635d 21192 else if (is_thin_archive)
1cb7d8b1
AM
21193 {
21194 Filedata thin_filedata;
eb02c04d 21195
1cb7d8b1 21196 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 21197
a043396b
NC
21198 /* PR 15140: Allow for corrupt thin archives. */
21199 if (nested_arch.file == NULL)
21200 {
21201 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 21202 qualified_name, name);
fd486f32
AM
21203 free (qualified_name);
21204 free (name);
32ec8896 21205 ret = FALSE;
a043396b
NC
21206 break;
21207 }
fd486f32 21208 free (name);
a043396b 21209
1cb7d8b1 21210 /* This is a proxy for a member of a nested archive. */
978c4450
AM
21211 filedata->archive_file_offset
21212 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 21213
1cb7d8b1
AM
21214 /* The nested archive file will have been opened and setup by
21215 get_archive_member_name. */
978c4450
AM
21216 if (fseek (nested_arch.file, filedata->archive_file_offset,
21217 SEEK_SET) != 0)
1cb7d8b1
AM
21218 {
21219 error (_("%s: failed to seek to archive member.\n"),
21220 nested_arch.file_name);
fd486f32 21221 free (qualified_name);
1cb7d8b1
AM
21222 ret = FALSE;
21223 break;
21224 }
2cf0635d 21225
dda8d76d
NC
21226 thin_filedata.handle = nested_arch.file;
21227 thin_filedata.file_name = qualified_name;
9abca702 21228
1cb7d8b1 21229 if (! process_object (& thin_filedata))
32ec8896 21230 ret = FALSE;
1cb7d8b1 21231 }
2cf0635d 21232 else
1cb7d8b1 21233 {
fd486f32 21234 free (name);
978c4450 21235 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 21236 filedata->file_name = qualified_name;
1cb7d8b1 21237 if (! process_object (filedata))
32ec8896 21238 ret = FALSE;
978c4450 21239 arch.next_arhdr_offset += filedata->archive_file_size;
4c836627 21240 /* Stop looping with "negative" archive_file_size. */
978c4450 21241 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 21242 arch.next_arhdr_offset = -1ul;
1cb7d8b1 21243 }
fb52b2f4 21244
2cf0635d 21245 free (qualified_name);
fb52b2f4
NC
21246 }
21247
4145f1d5 21248 out:
2cf0635d
NC
21249 if (nested_arch.file != NULL)
21250 fclose (nested_arch.file);
21251 release_archive (&nested_arch);
21252 release_archive (&arch);
fb52b2f4 21253
d989285c 21254 return ret;
fb52b2f4
NC
21255}
21256
32ec8896 21257static bfd_boolean
2cf0635d 21258process_file (char * file_name)
fb52b2f4 21259{
dda8d76d 21260 Filedata * filedata = NULL;
fb52b2f4
NC
21261 struct stat statbuf;
21262 char armag[SARMAG];
32ec8896 21263 bfd_boolean ret = TRUE;
fb52b2f4
NC
21264
21265 if (stat (file_name, &statbuf) < 0)
21266 {
f24ddbdd
NC
21267 if (errno == ENOENT)
21268 error (_("'%s': No such file\n"), file_name);
21269 else
21270 error (_("Could not locate '%s'. System error message: %s\n"),
21271 file_name, strerror (errno));
32ec8896 21272 return FALSE;
f24ddbdd
NC
21273 }
21274
21275 if (! S_ISREG (statbuf.st_mode))
21276 {
21277 error (_("'%s' is not an ordinary file\n"), file_name);
32ec8896 21278 return FALSE;
fb52b2f4
NC
21279 }
21280
dda8d76d
NC
21281 filedata = calloc (1, sizeof * filedata);
21282 if (filedata == NULL)
21283 {
21284 error (_("Out of memory allocating file data structure\n"));
21285 return FALSE;
21286 }
21287
21288 filedata->file_name = file_name;
21289 filedata->handle = fopen (file_name, "rb");
21290 if (filedata->handle == NULL)
fb52b2f4 21291 {
f24ddbdd 21292 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 21293 free (filedata);
32ec8896 21294 return FALSE;
fb52b2f4
NC
21295 }
21296
dda8d76d 21297 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 21298 {
4145f1d5 21299 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
21300 fclose (filedata->handle);
21301 free (filedata);
32ec8896 21302 return FALSE;
fb52b2f4
NC
21303 }
21304
dda8d76d 21305 filedata->file_size = (bfd_size_type) statbuf.st_size;
f54498b4 21306
fb52b2f4 21307 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 21308 {
dda8d76d 21309 if (! process_archive (filedata, FALSE))
32ec8896
NC
21310 ret = FALSE;
21311 }
2cf0635d 21312 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 21313 {
dda8d76d 21314 if ( ! process_archive (filedata, TRUE))
32ec8896
NC
21315 ret = FALSE;
21316 }
fb52b2f4
NC
21317 else
21318 {
1b513401 21319 if (do_archive_index && !check_all)
4145f1d5
NC
21320 error (_("File %s is not an archive so its index cannot be displayed.\n"),
21321 file_name);
21322
dda8d76d 21323 rewind (filedata->handle);
978c4450 21324 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 21325
dda8d76d 21326 if (! process_object (filedata))
32ec8896 21327 ret = FALSE;
fb52b2f4
NC
21328 }
21329
dda8d76d 21330 fclose (filedata->handle);
8fb879cd
AM
21331 free (filedata->section_headers);
21332 free (filedata->program_headers);
21333 free (filedata->string_table);
6431e409 21334 free (filedata->dump.dump_sects);
dda8d76d 21335 free (filedata);
32ec8896 21336
fd486f32 21337 free (ba_cache.strtab);
1bd6175a 21338 ba_cache.strtab = NULL;
fd486f32 21339 free (ba_cache.symtab);
1bd6175a 21340 ba_cache.symtab = NULL;
fd486f32
AM
21341 ba_cache.filedata = NULL;
21342
fb52b2f4
NC
21343 return ret;
21344}
21345
252b5132
RH
21346#ifdef SUPPORT_DISASSEMBLY
21347/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 21348 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 21349 symbols. */
252b5132
RH
21350
21351void
2cf0635d 21352print_address (unsigned int addr, FILE * outfile)
252b5132
RH
21353{
21354 fprintf (outfile,"0x%8.8x", addr);
21355}
21356
e3c8793a 21357/* Needed by the i386 disassembler. */
dda8d76d 21358
252b5132
RH
21359void
21360db_task_printsym (unsigned int addr)
21361{
21362 print_address (addr, stderr);
21363}
21364#endif
21365
21366int
2cf0635d 21367main (int argc, char ** argv)
252b5132 21368{
ff78d6d6
L
21369 int err;
21370
252b5132
RH
21371#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
21372 setlocale (LC_MESSAGES, "");
3882b010
L
21373#endif
21374#if defined (HAVE_SETLOCALE)
21375 setlocale (LC_CTYPE, "");
252b5132
RH
21376#endif
21377 bindtextdomain (PACKAGE, LOCALEDIR);
21378 textdomain (PACKAGE);
21379
869b9d07
MM
21380 expandargv (&argc, &argv);
21381
dda8d76d 21382 parse_args (& cmdline, argc, argv);
59f14fc0 21383
18bd398b 21384 if (optind < (argc - 1))
1b513401
NC
21385 /* When displaying information for more than one file,
21386 prefix the information with the file name. */
32ec8896 21387 show_name = TRUE;
5656ba2c
L
21388 else if (optind >= argc)
21389 {
1b513401
NC
21390 /* Ensure that the warning is always displayed. */
21391 do_checks = TRUE;
21392
5656ba2c
L
21393 warn (_("Nothing to do.\n"));
21394 usage (stderr);
21395 }
18bd398b 21396
32ec8896 21397 err = FALSE;
252b5132 21398 while (optind < argc)
32ec8896
NC
21399 if (! process_file (argv[optind++]))
21400 err = TRUE;
252b5132 21401
9db70fc3 21402 free (cmdline.dump_sects);
252b5132 21403
7d9813f1
NA
21404 free (dump_ctf_symtab_name);
21405 free (dump_ctf_strtab_name);
21406 free (dump_ctf_parent_name);
21407
32ec8896 21408 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 21409}