]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
GNU strip fails to set sh_link and sh_info on Solaris SPARC64
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
250d07de 2 Copyright (C) 1998-2021 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056 46#include <zlib.h>
3bfcb652 47#ifdef HAVE_WCHAR_H
7bfd842d 48#include <wchar.h>
3bfcb652 49#endif
252b5132 50
a952a375 51#if __GNUC__ >= 2
19936277 52/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 53 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 54 Only do this if we believe that the compiler can support a 64 bit
a952a375 55 data type. For now we only rely on GCC being able to do this. */
19936277 56#define BFD64
a952a375
NC
57#endif
58
3db64b00
AM
59#include "bfd.h"
60#include "bucomm.h"
3284fe0c 61#include "elfcomm.h"
19e6b90e 62#include "dwarf.h"
7d9813f1 63#include "ctf-api.h"
79bc120c 64#include "demangle.h"
252b5132
RH
65
66#include "elf/common.h"
67#include "elf/external.h"
68#include "elf/internal.h"
252b5132 69
4b78141a
NC
70
71/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
72 we can obtain the H8 reloc numbers. We need these for the
73 get_reloc_size() function. We include h8.h again after defining
74 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
75
76#include "elf/h8.h"
77#undef _ELF_H8_H
78
79/* Undo the effects of #including reloc-macros.h. */
80
81#undef START_RELOC_NUMBERS
82#undef RELOC_NUMBER
83#undef FAKE_RELOC
84#undef EMPTY_RELOC
85#undef END_RELOC_NUMBERS
86#undef _RELOC_MACROS_H
87
252b5132
RH
88/* The following headers use the elf/reloc-macros.h file to
89 automatically generate relocation recognition functions
90 such as elf_mips_reloc_type() */
91
92#define RELOC_MACROS_GEN_FUNC
93
a06ea964 94#include "elf/aarch64.h"
252b5132 95#include "elf/alpha.h"
3b16e843 96#include "elf/arc.h"
252b5132 97#include "elf/arm.h"
3b16e843 98#include "elf/avr.h"
1d65ded4 99#include "elf/bfin.h"
60bca95a 100#include "elf/cr16.h"
3b16e843 101#include "elf/cris.h"
1c0d3aa6 102#include "elf/crx.h"
b8891f8d 103#include "elf/csky.h"
252b5132
RH
104#include "elf/d10v.h"
105#include "elf/d30v.h"
d172d4ba 106#include "elf/dlx.h"
aca4efc7 107#include "elf/bpf.h"
cfb8c092 108#include "elf/epiphany.h"
252b5132 109#include "elf/fr30.h"
5c70f934 110#include "elf/frv.h"
3f8107ab 111#include "elf/ft32.h"
3b16e843
NC
112#include "elf/h8.h"
113#include "elf/hppa.h"
114#include "elf/i386.h"
f954747f
AM
115#include "elf/i370.h"
116#include "elf/i860.h"
117#include "elf/i960.h"
3b16e843 118#include "elf/ia64.h"
1e4cf259 119#include "elf/ip2k.h"
84e94c90 120#include "elf/lm32.h"
1c0d3aa6 121#include "elf/iq2000.h"
49f58d10 122#include "elf/m32c.h"
3b16e843
NC
123#include "elf/m32r.h"
124#include "elf/m68k.h"
75751cd9 125#include "elf/m68hc11.h"
7b4ae824 126#include "elf/s12z.h"
252b5132 127#include "elf/mcore.h"
15ab5209 128#include "elf/mep.h"
a3c62988 129#include "elf/metag.h"
7ba29e2a 130#include "elf/microblaze.h"
3b16e843 131#include "elf/mips.h"
3c3bdf30 132#include "elf/mmix.h"
3b16e843
NC
133#include "elf/mn10200.h"
134#include "elf/mn10300.h"
5506d11a 135#include "elf/moxie.h"
4970f871 136#include "elf/mt.h"
2469cfa2 137#include "elf/msp430.h"
35c08157 138#include "elf/nds32.h"
fe944acf 139#include "elf/nfp.h"
13761a11 140#include "elf/nios2.h"
73589c9d 141#include "elf/or1k.h"
7d466069 142#include "elf/pj.h"
3b16e843 143#include "elf/ppc.h"
c833c019 144#include "elf/ppc64.h"
2b100bb5 145#include "elf/pru.h"
03336641 146#include "elf/riscv.h"
99c513f6 147#include "elf/rl78.h"
c7927a3c 148#include "elf/rx.h"
a85d7ed0 149#include "elf/s390.h"
1c0d3aa6 150#include "elf/score.h"
3b16e843
NC
151#include "elf/sh.h"
152#include "elf/sparc.h"
e9f53129 153#include "elf/spu.h"
40b36596 154#include "elf/tic6x.h"
aa137e4d
NC
155#include "elf/tilegx.h"
156#include "elf/tilepro.h"
3b16e843 157#include "elf/v850.h"
179d3252 158#include "elf/vax.h"
619ed720 159#include "elf/visium.h"
f96bd6c2 160#include "elf/wasm32.h"
3b16e843 161#include "elf/x86-64.h"
c29aca4a 162#include "elf/xc16x.h"
f6c1a2d5 163#include "elf/xgate.h"
93fbbb04 164#include "elf/xstormy16.h"
88da6820 165#include "elf/xtensa.h"
6655dba2 166#include "elf/z80.h"
252b5132 167
252b5132 168#include "getopt.h"
566b0d53 169#include "libiberty.h"
09c11c86 170#include "safe-ctype.h"
2cf0635d 171#include "filenames.h"
252b5132 172
15b42fb0
AM
173#ifndef offsetof
174#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
175#endif
176
6a40cf0c
NC
177typedef struct elf_section_list
178{
dda8d76d
NC
179 Elf_Internal_Shdr * hdr;
180 struct elf_section_list * next;
6a40cf0c
NC
181} elf_section_list;
182
dda8d76d
NC
183/* Flag bits indicating particular types of dump. */
184#define HEX_DUMP (1 << 0) /* The -x command line switch. */
185#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
186#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
187#define STRING_DUMP (1 << 3) /* The -p command line switch. */
188#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 189#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
190
191typedef unsigned char dump_type;
192
193/* A linked list of the section names for which dumps were requested. */
194struct dump_list_entry
195{
196 char * name;
197 dump_type type;
198 struct dump_list_entry * next;
199};
200
6431e409
AM
201/* A dynamic array of flags indicating for which sections a dump
202 has been requested via command line switches. */
1b513401
NC
203struct dump_data
204{
6431e409
AM
205 dump_type * dump_sects;
206 unsigned int num_dump_sects;
207};
208
209static struct dump_data cmdline;
210
211static struct dump_list_entry * dump_sects_byname;
212
2cf0635d 213char * program_name = "readelf";
dda8d76d 214
32ec8896
NC
215static bfd_boolean show_name = FALSE;
216static bfd_boolean do_dynamic = FALSE;
217static bfd_boolean do_syms = FALSE;
218static bfd_boolean do_dyn_syms = FALSE;
0f03783c 219static bfd_boolean do_lto_syms = FALSE;
32ec8896
NC
220static bfd_boolean do_reloc = FALSE;
221static bfd_boolean do_sections = FALSE;
222static bfd_boolean do_section_groups = FALSE;
223static bfd_boolean do_section_details = FALSE;
224static bfd_boolean do_segments = FALSE;
225static bfd_boolean do_unwind = FALSE;
226static bfd_boolean do_using_dynamic = FALSE;
227static bfd_boolean do_header = FALSE;
228static bfd_boolean do_dump = FALSE;
229static bfd_boolean do_version = FALSE;
230static bfd_boolean do_histogram = FALSE;
231static bfd_boolean do_debugging = FALSE;
7d9813f1 232static bfd_boolean do_ctf = FALSE;
32ec8896
NC
233static bfd_boolean do_arch = FALSE;
234static bfd_boolean do_notes = FALSE;
235static bfd_boolean do_archive_index = FALSE;
1b513401 236static bfd_boolean check_all = FALSE;
32ec8896
NC
237static bfd_boolean is_32bit_elf = FALSE;
238static bfd_boolean decompress_dumps = FALSE;
0942c7ab 239static bfd_boolean do_not_show_symbol_truncation = FALSE;
79bc120c
NC
240static bfd_boolean do_demangle = FALSE; /* Pretty print C++ symbol names. */
241static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
252b5132 242
7d9813f1
NA
243static char *dump_ctf_parent_name;
244static char *dump_ctf_symtab_name;
245static char *dump_ctf_strtab_name;
246
e4b17d5c
L
247struct group_list
248{
dda8d76d
NC
249 struct group_list * next;
250 unsigned int section_index;
e4b17d5c
L
251};
252
253struct group
254{
dda8d76d
NC
255 struct group_list * root;
256 unsigned int group_index;
e4b17d5c
L
257};
258
978c4450
AM
259typedef struct filedata
260{
261 const char * file_name;
262 FILE * handle;
263 bfd_size_type file_size;
264 Elf_Internal_Ehdr file_header;
265 Elf_Internal_Shdr * section_headers;
266 Elf_Internal_Phdr * program_headers;
267 char * string_table;
268 unsigned long string_table_length;
269 unsigned long archive_file_offset;
270 unsigned long archive_file_size;
271 unsigned long dynamic_addr;
272 bfd_size_type dynamic_size;
273 size_t dynamic_nent;
274 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 275 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450
AM
276 char * dynamic_strings;
277 unsigned long dynamic_strings_length;
8ac10c5b 278 Elf_Internal_Shdr * dynamic_symtab_section;
978c4450
AM
279 unsigned long num_dynamic_syms;
280 Elf_Internal_Sym * dynamic_symbols;
281 bfd_vma version_info[16];
282 unsigned int dynamic_syminfo_nent;
283 Elf_Internal_Syminfo * dynamic_syminfo;
284 unsigned long dynamic_syminfo_offset;
285 bfd_size_type nbuckets;
286 bfd_size_type nchains;
287 bfd_vma * buckets;
288 bfd_vma * chains;
289 bfd_size_type ngnubuckets;
290 bfd_size_type ngnuchains;
291 bfd_vma * gnubuckets;
292 bfd_vma * gnuchains;
293 bfd_vma * mipsxlat;
294 bfd_vma gnusymidx;
295 char program_interpreter[PATH_MAX];
296 bfd_vma dynamic_info[DT_ENCODING];
297 bfd_vma dynamic_info_DT_GNU_HASH;
298 bfd_vma dynamic_info_DT_MIPS_XHASH;
299 elf_section_list * symtab_shndx_list;
300 size_t group_count;
301 struct group * section_groups;
302 struct group ** section_headers_groups;
303 /* A dynamic array of flags indicating for which sections a dump of
304 some kind has been requested. It is reset on a per-object file
305 basis and then initialised from the cmdline_dump_sects array,
306 the results of interpreting the -w switch, and the
307 dump_sects_byname list. */
308 struct dump_data dump;
309} Filedata;
aef1f6d0 310
c256ffe7 311/* How to print a vma value. */
843dd992
NC
312typedef enum print_mode
313{
314 HEX,
315 DEC,
316 DEC_5,
317 UNSIGNED,
318 PREFIX_HEX,
319 FULL_HEX,
320 LONG_HEX
321}
322print_mode;
323
bb4d2ac2
L
324/* Versioned symbol info. */
325enum versioned_symbol_info
326{
327 symbol_undefined,
328 symbol_hidden,
329 symbol_public
330};
331
32ec8896 332static const char * get_symbol_version_string
dda8d76d 333 (Filedata *, bfd_boolean, const char *, unsigned long, unsigned,
32ec8896 334 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 335
9c19a809
NC
336#define UNKNOWN -1
337
b9e920ec
AM
338#define SECTION_NAME(X) \
339 (filedata->string_table + (X)->sh_name)
340
341#define SECTION_NAME_VALID(X) \
342 ((X) != NULL \
343 && filedata->string_table != NULL \
344 && (X)->sh_name < filedata->string_table_length)
345
346#define SECTION_NAME_PRINT(X) \
347 ((X) == NULL ? _("<none>") \
348 : filedata->string_table == NULL ? _("<no-strings>") \
349 : (X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
350 : filedata->string_table + (X)->sh_name)
252b5132 351
ee42cf8c 352#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 353
ba5cdace
NC
354#define GET_ELF_SYMBOLS(file, section, sym_count) \
355 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
356 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 357
10ca4b04
L
358#define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
359 (strtab != NULL && offset < strtab_size)
978c4450
AM
360#define VALID_DYNAMIC_NAME(filedata, offset) \
361 VALID_SYMBOL_NAME (filedata->dynamic_strings, \
362 filedata->dynamic_strings_length, offset)
d79b3d50
NC
363/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
364 already been called and verified that the string exists. */
978c4450
AM
365#define GET_DYNAMIC_NAME(filedata, offset) \
366 (filedata->dynamic_strings + offset)
18bd398b 367
61865e30
NC
368#define REMOVE_ARCH_BITS(ADDR) \
369 do \
370 { \
dda8d76d 371 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
372 (ADDR) &= ~1; \
373 } \
374 while (0)
f16a9783
MS
375
376/* Get the correct GNU hash section name. */
978c4450
AM
377#define GNU_HASH_SECTION_NAME(filedata) \
378 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 379\f
66cfc0fd
AM
380/* Print a BFD_VMA to an internal buffer, for use in error messages.
381 BFD_FMA_FMT can't be used in translated strings. */
382
383static const char *
384bfd_vmatoa (char *fmtch, bfd_vma value)
385{
386 /* bfd_vmatoa is used more then once in a printf call for output.
387 Cycle through an array of buffers. */
388 static int buf_pos = 0;
389 static struct bfd_vmatoa_buf
390 {
391 char place[64];
392 } buf[4];
393 char *ret;
394 char fmt[32];
395
396 ret = buf[buf_pos++].place;
397 buf_pos %= ARRAY_SIZE (buf);
398
399 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
400 snprintf (ret, sizeof (buf[0].place), fmt, value);
401 return ret;
402}
403
dda8d76d
NC
404/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
405 OFFSET + the offset of the current archive member, if we are examining an
406 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
407 allocate a buffer using malloc and fill that. In either case return the
408 pointer to the start of the retrieved data or NULL if something went wrong.
409 If something does go wrong and REASON is not NULL then emit an error
410 message using REASON as part of the context. */
59245841 411
c256ffe7 412static void *
dda8d76d
NC
413get_data (void * var,
414 Filedata * filedata,
415 unsigned long offset,
416 bfd_size_type size,
417 bfd_size_type nmemb,
418 const char * reason)
a6e9f9df 419{
2cf0635d 420 void * mvar;
57028622 421 bfd_size_type amt = size * nmemb;
a6e9f9df 422
c256ffe7 423 if (size == 0 || nmemb == 0)
a6e9f9df
AM
424 return NULL;
425
57028622
NC
426 /* If the size_t type is smaller than the bfd_size_type, eg because
427 you are building a 32-bit tool on a 64-bit host, then make sure
428 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
429 if ((size_t) size != size
430 || (size_t) nmemb != nmemb
431 || (size_t) amt != amt)
57028622
NC
432 {
433 if (reason)
66cfc0fd
AM
434 error (_("Size truncation prevents reading %s"
435 " elements of size %s for %s\n"),
436 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
437 return NULL;
438 }
439
440 /* Check for size overflow. */
7c1c1904 441 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
442 {
443 if (reason)
66cfc0fd
AM
444 error (_("Size overflow prevents reading %s"
445 " elements of size %s for %s\n"),
446 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
447 return NULL;
448 }
449
c22b42ce 450 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 451 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
452 if (filedata->archive_file_offset > filedata->file_size
453 || offset > filedata->file_size - filedata->archive_file_offset
454 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 455 {
049b0c3a 456 if (reason)
66cfc0fd
AM
457 error (_("Reading %s bytes extends past end of file for %s\n"),
458 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
459 return NULL;
460 }
461
978c4450
AM
462 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
463 SEEK_SET))
071436c6
NC
464 {
465 if (reason)
c9c1d674 466 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 467 filedata->archive_file_offset + offset, reason);
071436c6
NC
468 return NULL;
469 }
470
a6e9f9df
AM
471 mvar = var;
472 if (mvar == NULL)
473 {
7c1c1904
AM
474 /* + 1 so that we can '\0' terminate invalid string table sections. */
475 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
476
477 if (mvar == NULL)
478 {
049b0c3a 479 if (reason)
66cfc0fd
AM
480 error (_("Out of memory allocating %s bytes for %s\n"),
481 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
482 return NULL;
483 }
c256ffe7 484
c9c1d674 485 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
486 }
487
dda8d76d 488 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 489 {
049b0c3a 490 if (reason)
66cfc0fd
AM
491 error (_("Unable to read in %s bytes of %s\n"),
492 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
493 if (mvar != var)
494 free (mvar);
495 return NULL;
496 }
497
498 return mvar;
499}
500
32ec8896
NC
501/* Print a VMA value in the MODE specified.
502 Returns the number of characters displayed. */
cb8f3167 503
32ec8896 504static unsigned int
14a91970 505print_vma (bfd_vma vma, print_mode mode)
66543521 506{
32ec8896 507 unsigned int nc = 0;
66543521 508
14a91970 509 switch (mode)
66543521 510 {
14a91970
AM
511 case FULL_HEX:
512 nc = printf ("0x");
1a0670f3 513 /* Fall through. */
14a91970 514 case LONG_HEX:
f7a99963 515#ifdef BFD64
14a91970 516 if (is_32bit_elf)
437c2fb7 517 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 518#endif
14a91970
AM
519 printf_vma (vma);
520 return nc + 16;
b19aac67 521
14a91970
AM
522 case DEC_5:
523 if (vma <= 99999)
524 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 525 /* Fall through. */
14a91970
AM
526 case PREFIX_HEX:
527 nc = printf ("0x");
1a0670f3 528 /* Fall through. */
14a91970
AM
529 case HEX:
530 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 531
14a91970
AM
532 case DEC:
533 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 534
14a91970
AM
535 case UNSIGNED:
536 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896
NC
537
538 default:
539 /* FIXME: Report unrecognised mode ? */
540 return 0;
f7a99963 541 }
f7a99963
NC
542}
543
7bfd842d 544/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 545 multibye characters (assuming the host environment supports them).
31104126 546
7bfd842d
NC
547 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
548
0942c7ab
NC
549 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
550 abs(WIDTH) - 5 characters followed by "[...]".
551
7bfd842d
NC
552 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
553 padding as necessary.
171191ba
NC
554
555 Returns the number of emitted characters. */
556
557static unsigned int
0942c7ab 558print_symbol (signed int width, const char * symbol)
31104126 559{
171191ba 560 bfd_boolean extra_padding = FALSE;
0942c7ab 561 bfd_boolean do_dots = FALSE;
32ec8896 562 signed int num_printed = 0;
3bfcb652 563#ifdef HAVE_MBSTATE_T
7bfd842d 564 mbstate_t state;
3bfcb652 565#endif
32ec8896 566 unsigned int width_remaining;
79bc120c 567 const void * alloced_symbol = NULL;
961c521f 568
7bfd842d 569 if (width < 0)
961c521f 570 {
88305e1b 571 /* Keep the width positive. This helps the code below. */
961c521f 572 width = - width;
171191ba 573 extra_padding = TRUE;
0b4362b0 574 }
56d8f8a9
NC
575 else if (width == 0)
576 return 0;
961c521f 577
7bfd842d
NC
578 if (do_wide)
579 /* Set the remaining width to a very large value.
580 This simplifies the code below. */
581 width_remaining = INT_MAX;
582 else
0942c7ab
NC
583 {
584 width_remaining = width;
585 if (! do_not_show_symbol_truncation
586 && (int) strlen (symbol) > width)
587 {
588 width_remaining -= 5;
589 if ((int) width_remaining < 0)
590 width_remaining = 0;
591 do_dots = TRUE;
592 }
593 }
cb8f3167 594
3bfcb652 595#ifdef HAVE_MBSTATE_T
7bfd842d
NC
596 /* Initialise the multibyte conversion state. */
597 memset (& state, 0, sizeof (state));
3bfcb652 598#endif
961c521f 599
79bc120c
NC
600 if (do_demangle && *symbol)
601 {
602 const char * res = cplus_demangle (symbol, demangle_flags);
603
604 if (res != NULL)
605 alloced_symbol = symbol = res;
606 }
607
7bfd842d
NC
608 while (width_remaining)
609 {
610 size_t n;
7bfd842d 611 const char c = *symbol++;
961c521f 612
7bfd842d 613 if (c == 0)
961c521f
NC
614 break;
615
7bfd842d
NC
616 /* Do not print control characters directly as they can affect terminal
617 settings. Such characters usually appear in the names generated
618 by the assembler for local labels. */
619 if (ISCNTRL (c))
961c521f 620 {
7bfd842d 621 if (width_remaining < 2)
961c521f
NC
622 break;
623
7bfd842d
NC
624 printf ("^%c", c + 0x40);
625 width_remaining -= 2;
171191ba 626 num_printed += 2;
961c521f 627 }
7bfd842d
NC
628 else if (ISPRINT (c))
629 {
630 putchar (c);
631 width_remaining --;
632 num_printed ++;
633 }
961c521f
NC
634 else
635 {
3bfcb652
NC
636#ifdef HAVE_MBSTATE_T
637 wchar_t w;
638#endif
7bfd842d
NC
639 /* Let printf do the hard work of displaying multibyte characters. */
640 printf ("%.1s", symbol - 1);
641 width_remaining --;
642 num_printed ++;
643
3bfcb652 644#ifdef HAVE_MBSTATE_T
7bfd842d
NC
645 /* Try to find out how many bytes made up the character that was
646 just printed. Advance the symbol pointer past the bytes that
647 were displayed. */
648 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
649#else
650 n = 1;
651#endif
7bfd842d
NC
652 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
653 symbol += (n - 1);
961c521f 654 }
961c521f 655 }
171191ba 656
0942c7ab
NC
657 if (do_dots)
658 num_printed += printf ("[...]");
659
7bfd842d 660 if (extra_padding && num_printed < width)
171191ba
NC
661 {
662 /* Fill in the remaining spaces. */
7bfd842d
NC
663 printf ("%-*s", width - num_printed, " ");
664 num_printed = width;
171191ba
NC
665 }
666
79bc120c 667 free ((void *) alloced_symbol);
171191ba 668 return num_printed;
31104126
NC
669}
670
1449284b 671/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
672 the given section's name. Like print_symbol, except that it does not try
673 to print multibyte characters, it just interprets them as hex values. */
674
675static const char *
dda8d76d 676printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b
NC
677{
678#define MAX_PRINT_SEC_NAME_LEN 128
679 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
b9e920ec 680 const char * name = SECTION_NAME_PRINT (sec);
74e1a04b
NC
681 char * buf = sec_name_buf;
682 char c;
683 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
684
685 while ((c = * name ++) != 0)
686 {
687 if (ISCNTRL (c))
688 {
689 if (remaining < 2)
690 break;
948f632f 691
74e1a04b
NC
692 * buf ++ = '^';
693 * buf ++ = c + 0x40;
694 remaining -= 2;
695 }
696 else if (ISPRINT (c))
697 {
698 * buf ++ = c;
699 remaining -= 1;
700 }
701 else
702 {
703 static char hex[17] = "0123456789ABCDEF";
704
705 if (remaining < 4)
706 break;
707 * buf ++ = '<';
708 * buf ++ = hex[(c & 0xf0) >> 4];
709 * buf ++ = hex[c & 0x0f];
710 * buf ++ = '>';
711 remaining -= 4;
712 }
713
714 if (remaining == 0)
715 break;
716 }
717
718 * buf = 0;
719 return sec_name_buf;
720}
721
722static const char *
dda8d76d 723printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 724{
dda8d76d 725 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
726 return _("<corrupt>");
727
dda8d76d 728 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
729}
730
89fac5e3
RS
731/* Return a pointer to section NAME, or NULL if no such section exists. */
732
733static Elf_Internal_Shdr *
dda8d76d 734find_section (Filedata * filedata, const char * name)
89fac5e3
RS
735{
736 unsigned int i;
737
68807c3c
NC
738 if (filedata->section_headers == NULL)
739 return NULL;
dda8d76d
NC
740
741 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
742 if (SECTION_NAME_VALID (filedata->section_headers + i)
743 && streq (SECTION_NAME (filedata->section_headers + i), name))
dda8d76d 744 return filedata->section_headers + i;
89fac5e3
RS
745
746 return NULL;
747}
748
0b6ae522
DJ
749/* Return a pointer to a section containing ADDR, or NULL if no such
750 section exists. */
751
752static Elf_Internal_Shdr *
dda8d76d 753find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
754{
755 unsigned int i;
756
68807c3c
NC
757 if (filedata->section_headers == NULL)
758 return NULL;
759
dda8d76d 760 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 761 {
dda8d76d
NC
762 Elf_Internal_Shdr *sec = filedata->section_headers + i;
763
0b6ae522
DJ
764 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
765 return sec;
766 }
767
768 return NULL;
769}
770
071436c6 771static Elf_Internal_Shdr *
dda8d76d 772find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
773{
774 unsigned int i;
775
68807c3c
NC
776 if (filedata->section_headers == NULL)
777 return NULL;
778
dda8d76d 779 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 780 {
dda8d76d
NC
781 Elf_Internal_Shdr *sec = filedata->section_headers + i;
782
071436c6
NC
783 if (sec->sh_type == type)
784 return sec;
785 }
786
787 return NULL;
788}
789
657d0d47
CC
790/* Return a pointer to section NAME, or NULL if no such section exists,
791 restricted to the list of sections given in SET. */
792
793static Elf_Internal_Shdr *
dda8d76d 794find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
795{
796 unsigned int i;
797
68807c3c
NC
798 if (filedata->section_headers == NULL)
799 return NULL;
800
657d0d47
CC
801 if (set != NULL)
802 {
803 while ((i = *set++) > 0)
b814a36d
NC
804 {
805 /* See PR 21156 for a reproducer. */
dda8d76d 806 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
807 continue; /* FIXME: Should we issue an error message ? */
808
b9e920ec
AM
809 if (SECTION_NAME_VALID (filedata->section_headers + i)
810 && streq (SECTION_NAME (filedata->section_headers + i), name))
dda8d76d 811 return filedata->section_headers + i;
b814a36d 812 }
657d0d47
CC
813 }
814
dda8d76d 815 return find_section (filedata, name);
657d0d47
CC
816}
817
32ec8896 818/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
819 This OS has so many departures from the ELF standard that we test it at
820 many places. */
821
32ec8896 822static inline bfd_boolean
dda8d76d 823is_ia64_vms (Filedata * filedata)
28f997cf 824{
dda8d76d
NC
825 return filedata->file_header.e_machine == EM_IA_64
826 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
827}
828
bcedfee6 829/* Guess the relocation size commonly used by the specific machines. */
252b5132 830
32ec8896 831static bfd_boolean
2dc4cec1 832guess_is_rela (unsigned int e_machine)
252b5132 833{
9c19a809 834 switch (e_machine)
252b5132
RH
835 {
836 /* Targets that use REL relocations. */
252b5132 837 case EM_386:
22abe556 838 case EM_IAMCU:
f954747f 839 case EM_960:
e9f53129 840 case EM_ARM:
2b0337b0 841 case EM_D10V:
252b5132 842 case EM_CYGNUS_D10V:
e9f53129 843 case EM_DLX:
252b5132 844 case EM_MIPS:
4fe85591 845 case EM_MIPS_RS3_LE:
e9f53129 846 case EM_CYGNUS_M32R:
1c0d3aa6 847 case EM_SCORE:
f6c1a2d5 848 case EM_XGATE:
fe944acf 849 case EM_NFP:
aca4efc7 850 case EM_BPF:
9c19a809 851 return FALSE;
103f02d3 852
252b5132
RH
853 /* Targets that use RELA relocations. */
854 case EM_68K:
f954747f 855 case EM_860:
a06ea964 856 case EM_AARCH64:
cfb8c092 857 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
858 case EM_ALPHA:
859 case EM_ALTERA_NIOS2:
886a2506
NC
860 case EM_ARC:
861 case EM_ARC_COMPACT:
862 case EM_ARC_COMPACT2:
e9f53129
AM
863 case EM_AVR:
864 case EM_AVR_OLD:
865 case EM_BLACKFIN:
60bca95a 866 case EM_CR16:
e9f53129
AM
867 case EM_CRIS:
868 case EM_CRX:
b8891f8d 869 case EM_CSKY:
2b0337b0 870 case EM_D30V:
252b5132 871 case EM_CYGNUS_D30V:
2b0337b0 872 case EM_FR30:
3f8107ab 873 case EM_FT32:
252b5132 874 case EM_CYGNUS_FR30:
5c70f934 875 case EM_CYGNUS_FRV:
e9f53129
AM
876 case EM_H8S:
877 case EM_H8_300:
878 case EM_H8_300H:
800eeca4 879 case EM_IA_64:
1e4cf259
NC
880 case EM_IP2K:
881 case EM_IP2K_OLD:
3b36097d 882 case EM_IQ2000:
84e94c90 883 case EM_LATTICEMICO32:
ff7eeb89 884 case EM_M32C_OLD:
49f58d10 885 case EM_M32C:
e9f53129
AM
886 case EM_M32R:
887 case EM_MCORE:
15ab5209 888 case EM_CYGNUS_MEP:
a3c62988 889 case EM_METAG:
e9f53129
AM
890 case EM_MMIX:
891 case EM_MN10200:
892 case EM_CYGNUS_MN10200:
893 case EM_MN10300:
894 case EM_CYGNUS_MN10300:
5506d11a 895 case EM_MOXIE:
e9f53129
AM
896 case EM_MSP430:
897 case EM_MSP430_OLD:
d031aafb 898 case EM_MT:
35c08157 899 case EM_NDS32:
64fd6348 900 case EM_NIOS32:
73589c9d 901 case EM_OR1K:
e9f53129
AM
902 case EM_PPC64:
903 case EM_PPC:
2b100bb5 904 case EM_TI_PRU:
e23eba97 905 case EM_RISCV:
99c513f6 906 case EM_RL78:
c7927a3c 907 case EM_RX:
e9f53129
AM
908 case EM_S390:
909 case EM_S390_OLD:
910 case EM_SH:
911 case EM_SPARC:
912 case EM_SPARC32PLUS:
913 case EM_SPARCV9:
914 case EM_SPU:
40b36596 915 case EM_TI_C6000:
aa137e4d
NC
916 case EM_TILEGX:
917 case EM_TILEPRO:
708e2187 918 case EM_V800:
e9f53129
AM
919 case EM_V850:
920 case EM_CYGNUS_V850:
921 case EM_VAX:
619ed720 922 case EM_VISIUM:
e9f53129 923 case EM_X86_64:
8a9036a4 924 case EM_L1OM:
7a9068fe 925 case EM_K1OM:
e9f53129
AM
926 case EM_XSTORMY16:
927 case EM_XTENSA:
928 case EM_XTENSA_OLD:
7ba29e2a
NC
929 case EM_MICROBLAZE:
930 case EM_MICROBLAZE_OLD:
f96bd6c2 931 case EM_WEBASSEMBLY:
9c19a809 932 return TRUE;
103f02d3 933
e9f53129
AM
934 case EM_68HC05:
935 case EM_68HC08:
936 case EM_68HC11:
937 case EM_68HC16:
938 case EM_FX66:
939 case EM_ME16:
d1133906 940 case EM_MMA:
d1133906
NC
941 case EM_NCPU:
942 case EM_NDR1:
e9f53129 943 case EM_PCP:
d1133906 944 case EM_ST100:
e9f53129 945 case EM_ST19:
d1133906 946 case EM_ST7:
e9f53129
AM
947 case EM_ST9PLUS:
948 case EM_STARCORE:
d1133906 949 case EM_SVX:
e9f53129 950 case EM_TINYJ:
9c19a809
NC
951 default:
952 warn (_("Don't know about relocations on this machine architecture\n"));
953 return FALSE;
954 }
955}
252b5132 956
dda8d76d 957/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
958 Returns TRUE upon success, FALSE otherwise. If successful then a
959 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
960 and the number of relocs loaded is placed in *NRELASP. It is the caller's
961 responsibility to free the allocated buffer. */
962
963static bfd_boolean
dda8d76d
NC
964slurp_rela_relocs (Filedata * filedata,
965 unsigned long rel_offset,
966 unsigned long rel_size,
967 Elf_Internal_Rela ** relasp,
968 unsigned long * nrelasp)
9c19a809 969{
2cf0635d 970 Elf_Internal_Rela * relas;
8b73c356 971 size_t nrelas;
4d6ed7c8 972 unsigned int i;
252b5132 973
4d6ed7c8
NC
974 if (is_32bit_elf)
975 {
2cf0635d 976 Elf32_External_Rela * erelas;
103f02d3 977
dda8d76d 978 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 979 rel_size, _("32-bit relocation data"));
a6e9f9df 980 if (!erelas)
32ec8896 981 return FALSE;
252b5132 982
4d6ed7c8 983 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 984
3f5e193b
NC
985 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
986 sizeof (Elf_Internal_Rela));
103f02d3 987
4d6ed7c8
NC
988 if (relas == NULL)
989 {
c256ffe7 990 free (erelas);
591a748a 991 error (_("out of memory parsing relocs\n"));
32ec8896 992 return FALSE;
4d6ed7c8 993 }
103f02d3 994
4d6ed7c8
NC
995 for (i = 0; i < nrelas; i++)
996 {
997 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
998 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 999 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1000 }
103f02d3 1001
4d6ed7c8
NC
1002 free (erelas);
1003 }
1004 else
1005 {
2cf0635d 1006 Elf64_External_Rela * erelas;
103f02d3 1007
dda8d76d 1008 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1009 rel_size, _("64-bit relocation data"));
a6e9f9df 1010 if (!erelas)
32ec8896 1011 return FALSE;
4d6ed7c8
NC
1012
1013 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1014
3f5e193b
NC
1015 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1016 sizeof (Elf_Internal_Rela));
103f02d3 1017
4d6ed7c8
NC
1018 if (relas == NULL)
1019 {
c256ffe7 1020 free (erelas);
591a748a 1021 error (_("out of memory parsing relocs\n"));
32ec8896 1022 return FALSE;
9c19a809 1023 }
4d6ed7c8
NC
1024
1025 for (i = 0; i < nrelas; i++)
9c19a809 1026 {
66543521
AM
1027 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1028 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1029 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1030
1031 /* The #ifdef BFD64 below is to prevent a compile time
1032 warning. We know that if we do not have a 64 bit data
1033 type that we will never execute this code anyway. */
1034#ifdef BFD64
dda8d76d
NC
1035 if (filedata->file_header.e_machine == EM_MIPS
1036 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1037 {
1038 /* In little-endian objects, r_info isn't really a
1039 64-bit little-endian value: it has a 32-bit
1040 little-endian symbol index followed by four
1041 individual byte fields. Reorder INFO
1042 accordingly. */
91d6fa6a
NC
1043 bfd_vma inf = relas[i].r_info;
1044 inf = (((inf & 0xffffffff) << 32)
1045 | ((inf >> 56) & 0xff)
1046 | ((inf >> 40) & 0xff00)
1047 | ((inf >> 24) & 0xff0000)
1048 | ((inf >> 8) & 0xff000000));
1049 relas[i].r_info = inf;
861fb55a
DJ
1050 }
1051#endif /* BFD64 */
4d6ed7c8 1052 }
103f02d3 1053
4d6ed7c8
NC
1054 free (erelas);
1055 }
32ec8896 1056
4d6ed7c8
NC
1057 *relasp = relas;
1058 *nrelasp = nrelas;
32ec8896 1059 return TRUE;
4d6ed7c8 1060}
103f02d3 1061
dda8d76d 1062/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1063 Returns TRUE upon success, FALSE otherwise. If successful then a
1064 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1065 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1066 responsibility to free the allocated buffer. */
1067
1068static bfd_boolean
dda8d76d
NC
1069slurp_rel_relocs (Filedata * filedata,
1070 unsigned long rel_offset,
1071 unsigned long rel_size,
1072 Elf_Internal_Rela ** relsp,
1073 unsigned long * nrelsp)
4d6ed7c8 1074{
2cf0635d 1075 Elf_Internal_Rela * rels;
8b73c356 1076 size_t nrels;
4d6ed7c8 1077 unsigned int i;
103f02d3 1078
4d6ed7c8
NC
1079 if (is_32bit_elf)
1080 {
2cf0635d 1081 Elf32_External_Rel * erels;
103f02d3 1082
dda8d76d 1083 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1084 rel_size, _("32-bit relocation data"));
a6e9f9df 1085 if (!erels)
32ec8896 1086 return FALSE;
103f02d3 1087
4d6ed7c8 1088 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1089
3f5e193b 1090 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1091
4d6ed7c8
NC
1092 if (rels == NULL)
1093 {
c256ffe7 1094 free (erels);
591a748a 1095 error (_("out of memory parsing relocs\n"));
32ec8896 1096 return FALSE;
4d6ed7c8
NC
1097 }
1098
1099 for (i = 0; i < nrels; i++)
1100 {
1101 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1102 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1103 rels[i].r_addend = 0;
9ea033b2 1104 }
4d6ed7c8
NC
1105
1106 free (erels);
9c19a809
NC
1107 }
1108 else
1109 {
2cf0635d 1110 Elf64_External_Rel * erels;
9ea033b2 1111
dda8d76d 1112 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1113 rel_size, _("64-bit relocation data"));
a6e9f9df 1114 if (!erels)
32ec8896 1115 return FALSE;
103f02d3 1116
4d6ed7c8 1117 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1118
3f5e193b 1119 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1120
4d6ed7c8 1121 if (rels == NULL)
9c19a809 1122 {
c256ffe7 1123 free (erels);
591a748a 1124 error (_("out of memory parsing relocs\n"));
32ec8896 1125 return FALSE;
4d6ed7c8 1126 }
103f02d3 1127
4d6ed7c8
NC
1128 for (i = 0; i < nrels; i++)
1129 {
66543521
AM
1130 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1131 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1132 rels[i].r_addend = 0;
861fb55a
DJ
1133
1134 /* The #ifdef BFD64 below is to prevent a compile time
1135 warning. We know that if we do not have a 64 bit data
1136 type that we will never execute this code anyway. */
1137#ifdef BFD64
dda8d76d
NC
1138 if (filedata->file_header.e_machine == EM_MIPS
1139 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1140 {
1141 /* In little-endian objects, r_info isn't really a
1142 64-bit little-endian value: it has a 32-bit
1143 little-endian symbol index followed by four
1144 individual byte fields. Reorder INFO
1145 accordingly. */
91d6fa6a
NC
1146 bfd_vma inf = rels[i].r_info;
1147 inf = (((inf & 0xffffffff) << 32)
1148 | ((inf >> 56) & 0xff)
1149 | ((inf >> 40) & 0xff00)
1150 | ((inf >> 24) & 0xff0000)
1151 | ((inf >> 8) & 0xff000000));
1152 rels[i].r_info = inf;
861fb55a
DJ
1153 }
1154#endif /* BFD64 */
4d6ed7c8 1155 }
103f02d3 1156
4d6ed7c8
NC
1157 free (erels);
1158 }
32ec8896 1159
4d6ed7c8
NC
1160 *relsp = rels;
1161 *nrelsp = nrels;
32ec8896 1162 return TRUE;
4d6ed7c8 1163}
103f02d3 1164
aca88567
NC
1165/* Returns the reloc type extracted from the reloc info field. */
1166
1167static unsigned int
dda8d76d 1168get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1169{
1170 if (is_32bit_elf)
1171 return ELF32_R_TYPE (reloc_info);
1172
dda8d76d 1173 switch (filedata->file_header.e_machine)
aca88567
NC
1174 {
1175 case EM_MIPS:
1176 /* Note: We assume that reloc_info has already been adjusted for us. */
1177 return ELF64_MIPS_R_TYPE (reloc_info);
1178
1179 case EM_SPARCV9:
1180 return ELF64_R_TYPE_ID (reloc_info);
1181
1182 default:
1183 return ELF64_R_TYPE (reloc_info);
1184 }
1185}
1186
1187/* Return the symbol index extracted from the reloc info field. */
1188
1189static bfd_vma
1190get_reloc_symindex (bfd_vma reloc_info)
1191{
1192 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1193}
1194
13761a11 1195static inline bfd_boolean
dda8d76d 1196uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1197{
1198 return
dda8d76d 1199 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1200 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1201 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1202 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1203 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1204}
1205
d3ba0551
AM
1206/* Display the contents of the relocation data found at the specified
1207 offset. */
ee42cf8c 1208
32ec8896 1209static bfd_boolean
dda8d76d
NC
1210dump_relocations (Filedata * filedata,
1211 unsigned long rel_offset,
1212 unsigned long rel_size,
1213 Elf_Internal_Sym * symtab,
1214 unsigned long nsyms,
1215 char * strtab,
1216 unsigned long strtablen,
1217 int is_rela,
1218 bfd_boolean is_dynsym)
4d6ed7c8 1219{
32ec8896 1220 unsigned long i;
2cf0635d 1221 Elf_Internal_Rela * rels;
32ec8896 1222 bfd_boolean res = TRUE;
103f02d3 1223
4d6ed7c8 1224 if (is_rela == UNKNOWN)
dda8d76d 1225 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1226
4d6ed7c8
NC
1227 if (is_rela)
1228 {
dda8d76d 1229 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1230 return FALSE;
4d6ed7c8
NC
1231 }
1232 else
1233 {
dda8d76d 1234 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1235 return FALSE;
252b5132
RH
1236 }
1237
410f7a12
L
1238 if (is_32bit_elf)
1239 {
1240 if (is_rela)
2c71103e
NC
1241 {
1242 if (do_wide)
1243 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1244 else
1245 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1246 }
410f7a12 1247 else
2c71103e
NC
1248 {
1249 if (do_wide)
1250 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1251 else
1252 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1253 }
410f7a12 1254 }
252b5132 1255 else
410f7a12
L
1256 {
1257 if (is_rela)
2c71103e
NC
1258 {
1259 if (do_wide)
8beeaeb7 1260 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1261 else
1262 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1263 }
410f7a12 1264 else
2c71103e
NC
1265 {
1266 if (do_wide)
8beeaeb7 1267 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1268 else
1269 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1270 }
410f7a12 1271 }
252b5132
RH
1272
1273 for (i = 0; i < rel_size; i++)
1274 {
2cf0635d 1275 const char * rtype;
b34976b6 1276 bfd_vma offset;
91d6fa6a 1277 bfd_vma inf;
b34976b6
AM
1278 bfd_vma symtab_index;
1279 bfd_vma type;
103f02d3 1280
b34976b6 1281 offset = rels[i].r_offset;
91d6fa6a 1282 inf = rels[i].r_info;
103f02d3 1283
dda8d76d 1284 type = get_reloc_type (filedata, inf);
91d6fa6a 1285 symtab_index = get_reloc_symindex (inf);
252b5132 1286
410f7a12
L
1287 if (is_32bit_elf)
1288 {
39dbeff8
AM
1289 printf ("%8.8lx %8.8lx ",
1290 (unsigned long) offset & 0xffffffff,
91d6fa6a 1291 (unsigned long) inf & 0xffffffff);
410f7a12
L
1292 }
1293 else
1294 {
39dbeff8 1295 printf (do_wide
d1ce973e
AM
1296 ? "%16.16" BFD_VMA_FMT "x %16.16" BFD_VMA_FMT "x "
1297 : "%12.12" BFD_VMA_FMT "x %12.12" BFD_VMA_FMT "x ",
91d6fa6a 1298 offset, inf);
410f7a12 1299 }
103f02d3 1300
dda8d76d 1301 switch (filedata->file_header.e_machine)
252b5132
RH
1302 {
1303 default:
1304 rtype = NULL;
1305 break;
1306
a06ea964
NC
1307 case EM_AARCH64:
1308 rtype = elf_aarch64_reloc_type (type);
1309 break;
1310
2b0337b0 1311 case EM_M32R:
252b5132 1312 case EM_CYGNUS_M32R:
9ea033b2 1313 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1314 break;
1315
1316 case EM_386:
22abe556 1317 case EM_IAMCU:
9ea033b2 1318 rtype = elf_i386_reloc_type (type);
252b5132
RH
1319 break;
1320
ba2685cc
AM
1321 case EM_68HC11:
1322 case EM_68HC12:
1323 rtype = elf_m68hc11_reloc_type (type);
1324 break;
75751cd9 1325
7b4ae824
JD
1326 case EM_S12Z:
1327 rtype = elf_s12z_reloc_type (type);
1328 break;
1329
252b5132 1330 case EM_68K:
9ea033b2 1331 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1332 break;
1333
f954747f
AM
1334 case EM_960:
1335 rtype = elf_i960_reloc_type (type);
1336 break;
1337
adde6300 1338 case EM_AVR:
2b0337b0 1339 case EM_AVR_OLD:
adde6300
AM
1340 rtype = elf_avr_reloc_type (type);
1341 break;
1342
9ea033b2
NC
1343 case EM_OLD_SPARCV9:
1344 case EM_SPARC32PLUS:
1345 case EM_SPARCV9:
252b5132 1346 case EM_SPARC:
9ea033b2 1347 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1348 break;
1349
e9f53129
AM
1350 case EM_SPU:
1351 rtype = elf_spu_reloc_type (type);
1352 break;
1353
708e2187
NC
1354 case EM_V800:
1355 rtype = v800_reloc_type (type);
1356 break;
2b0337b0 1357 case EM_V850:
252b5132 1358 case EM_CYGNUS_V850:
9ea033b2 1359 rtype = v850_reloc_type (type);
252b5132
RH
1360 break;
1361
2b0337b0 1362 case EM_D10V:
252b5132 1363 case EM_CYGNUS_D10V:
9ea033b2 1364 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1365 break;
1366
2b0337b0 1367 case EM_D30V:
252b5132 1368 case EM_CYGNUS_D30V:
9ea033b2 1369 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1370 break;
1371
d172d4ba
NC
1372 case EM_DLX:
1373 rtype = elf_dlx_reloc_type (type);
1374 break;
1375
252b5132 1376 case EM_SH:
9ea033b2 1377 rtype = elf_sh_reloc_type (type);
252b5132
RH
1378 break;
1379
2b0337b0 1380 case EM_MN10300:
252b5132 1381 case EM_CYGNUS_MN10300:
9ea033b2 1382 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1383 break;
1384
2b0337b0 1385 case EM_MN10200:
252b5132 1386 case EM_CYGNUS_MN10200:
9ea033b2 1387 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1388 break;
1389
2b0337b0 1390 case EM_FR30:
252b5132 1391 case EM_CYGNUS_FR30:
9ea033b2 1392 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1393 break;
1394
ba2685cc
AM
1395 case EM_CYGNUS_FRV:
1396 rtype = elf_frv_reloc_type (type);
1397 break;
5c70f934 1398
b8891f8d
AJ
1399 case EM_CSKY:
1400 rtype = elf_csky_reloc_type (type);
1401 break;
1402
3f8107ab
AM
1403 case EM_FT32:
1404 rtype = elf_ft32_reloc_type (type);
1405 break;
1406
252b5132 1407 case EM_MCORE:
9ea033b2 1408 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1409 break;
1410
3c3bdf30
NC
1411 case EM_MMIX:
1412 rtype = elf_mmix_reloc_type (type);
1413 break;
1414
5506d11a
AM
1415 case EM_MOXIE:
1416 rtype = elf_moxie_reloc_type (type);
1417 break;
1418
2469cfa2 1419 case EM_MSP430:
dda8d76d 1420 if (uses_msp430x_relocs (filedata))
13761a11
NC
1421 {
1422 rtype = elf_msp430x_reloc_type (type);
1423 break;
1424 }
1a0670f3 1425 /* Fall through. */
2469cfa2
NC
1426 case EM_MSP430_OLD:
1427 rtype = elf_msp430_reloc_type (type);
1428 break;
1429
35c08157
KLC
1430 case EM_NDS32:
1431 rtype = elf_nds32_reloc_type (type);
1432 break;
1433
252b5132 1434 case EM_PPC:
9ea033b2 1435 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1436 break;
1437
c833c019
AM
1438 case EM_PPC64:
1439 rtype = elf_ppc64_reloc_type (type);
1440 break;
1441
252b5132 1442 case EM_MIPS:
4fe85591 1443 case EM_MIPS_RS3_LE:
9ea033b2 1444 rtype = elf_mips_reloc_type (type);
252b5132
RH
1445 break;
1446
e23eba97
NC
1447 case EM_RISCV:
1448 rtype = elf_riscv_reloc_type (type);
1449 break;
1450
252b5132 1451 case EM_ALPHA:
9ea033b2 1452 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1453 break;
1454
1455 case EM_ARM:
9ea033b2 1456 rtype = elf_arm_reloc_type (type);
252b5132
RH
1457 break;
1458
584da044 1459 case EM_ARC:
886a2506
NC
1460 case EM_ARC_COMPACT:
1461 case EM_ARC_COMPACT2:
9ea033b2 1462 rtype = elf_arc_reloc_type (type);
252b5132
RH
1463 break;
1464
1465 case EM_PARISC:
69e617ca 1466 rtype = elf_hppa_reloc_type (type);
252b5132 1467 break;
7d466069 1468
b8720f9d
JL
1469 case EM_H8_300:
1470 case EM_H8_300H:
1471 case EM_H8S:
1472 rtype = elf_h8_reloc_type (type);
1473 break;
1474
73589c9d
CS
1475 case EM_OR1K:
1476 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1477 break;
1478
7d466069 1479 case EM_PJ:
2b0337b0 1480 case EM_PJ_OLD:
7d466069
ILT
1481 rtype = elf_pj_reloc_type (type);
1482 break;
800eeca4
JW
1483 case EM_IA_64:
1484 rtype = elf_ia64_reloc_type (type);
1485 break;
1b61cf92
HPN
1486
1487 case EM_CRIS:
1488 rtype = elf_cris_reloc_type (type);
1489 break;
535c37ff 1490
f954747f
AM
1491 case EM_860:
1492 rtype = elf_i860_reloc_type (type);
1493 break;
1494
bcedfee6 1495 case EM_X86_64:
8a9036a4 1496 case EM_L1OM:
7a9068fe 1497 case EM_K1OM:
bcedfee6
NC
1498 rtype = elf_x86_64_reloc_type (type);
1499 break;
a85d7ed0 1500
f954747f
AM
1501 case EM_S370:
1502 rtype = i370_reloc_type (type);
1503 break;
1504
53c7db4b
KH
1505 case EM_S390_OLD:
1506 case EM_S390:
1507 rtype = elf_s390_reloc_type (type);
1508 break;
93fbbb04 1509
1c0d3aa6
NC
1510 case EM_SCORE:
1511 rtype = elf_score_reloc_type (type);
1512 break;
1513
93fbbb04
GK
1514 case EM_XSTORMY16:
1515 rtype = elf_xstormy16_reloc_type (type);
1516 break;
179d3252 1517
1fe1f39c
NC
1518 case EM_CRX:
1519 rtype = elf_crx_reloc_type (type);
1520 break;
1521
179d3252
JT
1522 case EM_VAX:
1523 rtype = elf_vax_reloc_type (type);
1524 break;
1e4cf259 1525
619ed720
EB
1526 case EM_VISIUM:
1527 rtype = elf_visium_reloc_type (type);
1528 break;
1529
aca4efc7
JM
1530 case EM_BPF:
1531 rtype = elf_bpf_reloc_type (type);
1532 break;
1533
cfb8c092
NC
1534 case EM_ADAPTEVA_EPIPHANY:
1535 rtype = elf_epiphany_reloc_type (type);
1536 break;
1537
1e4cf259
NC
1538 case EM_IP2K:
1539 case EM_IP2K_OLD:
1540 rtype = elf_ip2k_reloc_type (type);
1541 break;
3b36097d
SC
1542
1543 case EM_IQ2000:
1544 rtype = elf_iq2000_reloc_type (type);
1545 break;
88da6820
NC
1546
1547 case EM_XTENSA_OLD:
1548 case EM_XTENSA:
1549 rtype = elf_xtensa_reloc_type (type);
1550 break;
a34e3ecb 1551
84e94c90
NC
1552 case EM_LATTICEMICO32:
1553 rtype = elf_lm32_reloc_type (type);
1554 break;
1555
ff7eeb89 1556 case EM_M32C_OLD:
49f58d10
JB
1557 case EM_M32C:
1558 rtype = elf_m32c_reloc_type (type);
1559 break;
1560
d031aafb
NS
1561 case EM_MT:
1562 rtype = elf_mt_reloc_type (type);
a34e3ecb 1563 break;
1d65ded4
CM
1564
1565 case EM_BLACKFIN:
1566 rtype = elf_bfin_reloc_type (type);
1567 break;
15ab5209
DB
1568
1569 case EM_CYGNUS_MEP:
1570 rtype = elf_mep_reloc_type (type);
1571 break;
60bca95a
NC
1572
1573 case EM_CR16:
1574 rtype = elf_cr16_reloc_type (type);
1575 break;
dd24e3da 1576
7ba29e2a
NC
1577 case EM_MICROBLAZE:
1578 case EM_MICROBLAZE_OLD:
1579 rtype = elf_microblaze_reloc_type (type);
1580 break;
c7927a3c 1581
99c513f6
DD
1582 case EM_RL78:
1583 rtype = elf_rl78_reloc_type (type);
1584 break;
1585
c7927a3c
NC
1586 case EM_RX:
1587 rtype = elf_rx_reloc_type (type);
1588 break;
c29aca4a 1589
a3c62988
NC
1590 case EM_METAG:
1591 rtype = elf_metag_reloc_type (type);
1592 break;
1593
c29aca4a
NC
1594 case EM_XC16X:
1595 case EM_C166:
1596 rtype = elf_xc16x_reloc_type (type);
1597 break;
40b36596
JM
1598
1599 case EM_TI_C6000:
1600 rtype = elf_tic6x_reloc_type (type);
1601 break;
aa137e4d
NC
1602
1603 case EM_TILEGX:
1604 rtype = elf_tilegx_reloc_type (type);
1605 break;
1606
1607 case EM_TILEPRO:
1608 rtype = elf_tilepro_reloc_type (type);
1609 break;
f6c1a2d5 1610
f96bd6c2
PC
1611 case EM_WEBASSEMBLY:
1612 rtype = elf_wasm32_reloc_type (type);
1613 break;
1614
f6c1a2d5
NC
1615 case EM_XGATE:
1616 rtype = elf_xgate_reloc_type (type);
1617 break;
36591ba1
SL
1618
1619 case EM_ALTERA_NIOS2:
1620 rtype = elf_nios2_reloc_type (type);
1621 break;
2b100bb5
DD
1622
1623 case EM_TI_PRU:
1624 rtype = elf_pru_reloc_type (type);
1625 break;
fe944acf
FT
1626
1627 case EM_NFP:
1628 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1629 rtype = elf_nfp3200_reloc_type (type);
1630 else
1631 rtype = elf_nfp_reloc_type (type);
1632 break;
6655dba2
SB
1633
1634 case EM_Z80:
1635 rtype = elf_z80_reloc_type (type);
1636 break;
252b5132
RH
1637 }
1638
1639 if (rtype == NULL)
39dbeff8 1640 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1641 else
5c144731 1642 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1643
dda8d76d 1644 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1645 && rtype != NULL
7ace3541
RH
1646 && streq (rtype, "R_ALPHA_LITUSE")
1647 && is_rela)
1648 {
1649 switch (rels[i].r_addend)
1650 {
1651 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1652 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1653 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1654 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1655 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1656 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1657 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1658 default: rtype = NULL;
1659 }
32ec8896 1660
7ace3541
RH
1661 if (rtype)
1662 printf (" (%s)", rtype);
1663 else
1664 {
1665 putchar (' ');
1666 printf (_("<unknown addend: %lx>"),
1667 (unsigned long) rels[i].r_addend);
32ec8896 1668 res = FALSE;
7ace3541
RH
1669 }
1670 }
1671 else if (symtab_index)
252b5132 1672 {
af3fc3bc 1673 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1674 {
27a45f42
AS
1675 error (_(" bad symbol index: %08lx in reloc\n"),
1676 (unsigned long) symtab_index);
32ec8896
NC
1677 res = FALSE;
1678 }
af3fc3bc 1679 else
19936277 1680 {
2cf0635d 1681 Elf_Internal_Sym * psym;
bb4d2ac2
L
1682 const char * version_string;
1683 enum versioned_symbol_info sym_info;
1684 unsigned short vna_other;
19936277 1685
af3fc3bc 1686 psym = symtab + symtab_index;
103f02d3 1687
bb4d2ac2 1688 version_string
dda8d76d 1689 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1690 strtab, strtablen,
1691 symtab_index,
1692 psym,
1693 &sym_info,
1694 &vna_other);
1695
af3fc3bc 1696 printf (" ");
171191ba 1697
d8045f23
NC
1698 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1699 {
1700 const char * name;
1701 unsigned int len;
1702 unsigned int width = is_32bit_elf ? 8 : 14;
1703
1704 /* Relocations against GNU_IFUNC symbols do not use the value
1705 of the symbol as the address to relocate against. Instead
1706 they invoke the function named by the symbol and use its
1707 result as the address for relocation.
1708
1709 To indicate this to the user, do not display the value of
1710 the symbol in the "Symbols's Value" field. Instead show
1711 its name followed by () as a hint that the symbol is
1712 invoked. */
1713
1714 if (strtab == NULL
1715 || psym->st_name == 0
1716 || psym->st_name >= strtablen)
1717 name = "??";
1718 else
1719 name = strtab + psym->st_name;
1720
1721 len = print_symbol (width, name);
bb4d2ac2
L
1722 if (version_string)
1723 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1724 version_string);
d8045f23
NC
1725 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1726 }
1727 else
1728 {
1729 print_vma (psym->st_value, LONG_HEX);
171191ba 1730
d8045f23
NC
1731 printf (is_32bit_elf ? " " : " ");
1732 }
103f02d3 1733
af3fc3bc 1734 if (psym->st_name == 0)
f1ef08cb 1735 {
2cf0635d 1736 const char * sec_name = "<null>";
f1ef08cb
AM
1737 char name_buf[40];
1738
1739 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1740 {
dda8d76d 1741 if (psym->st_shndx < filedata->file_header.e_shnum)
b9e920ec
AM
1742 sec_name = SECTION_NAME_PRINT (filedata->section_headers
1743 + psym->st_shndx);
f1ef08cb
AM
1744 else if (psym->st_shndx == SHN_ABS)
1745 sec_name = "ABS";
1746 else if (psym->st_shndx == SHN_COMMON)
1747 sec_name = "COMMON";
dda8d76d 1748 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1749 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1750 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1751 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1752 sec_name = "SCOMMON";
dda8d76d 1753 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1754 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1755 sec_name = "SUNDEF";
dda8d76d
NC
1756 else if ((filedata->file_header.e_machine == EM_X86_64
1757 || filedata->file_header.e_machine == EM_L1OM
1758 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1759 && psym->st_shndx == SHN_X86_64_LCOMMON)
1760 sec_name = "LARGE_COMMON";
dda8d76d
NC
1761 else if (filedata->file_header.e_machine == EM_IA_64
1762 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1763 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1764 sec_name = "ANSI_COM";
dda8d76d 1765 else if (is_ia64_vms (filedata)
148b93f2
NC
1766 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1767 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1768 else
1769 {
1770 sprintf (name_buf, "<section 0x%x>",
1771 (unsigned int) psym->st_shndx);
1772 sec_name = name_buf;
1773 }
1774 }
1775 print_symbol (22, sec_name);
1776 }
af3fc3bc 1777 else if (strtab == NULL)
d79b3d50 1778 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1779 else if (psym->st_name >= strtablen)
32ec8896 1780 {
27a45f42
AS
1781 error (_("<corrupt string table index: %3ld>\n"),
1782 psym->st_name);
32ec8896
NC
1783 res = FALSE;
1784 }
af3fc3bc 1785 else
bb4d2ac2
L
1786 {
1787 print_symbol (22, strtab + psym->st_name);
1788 if (version_string)
1789 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1790 version_string);
1791 }
103f02d3 1792
af3fc3bc 1793 if (is_rela)
171191ba 1794 {
7360e63f 1795 bfd_vma off = rels[i].r_addend;
171191ba 1796
7360e63f 1797 if ((bfd_signed_vma) off < 0)
598aaa76 1798 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1799 else
598aaa76 1800 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1801 }
19936277 1802 }
252b5132 1803 }
1b228002 1804 else if (is_rela)
f7a99963 1805 {
7360e63f 1806 bfd_vma off = rels[i].r_addend;
e04d7088
L
1807
1808 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1809 if ((bfd_signed_vma) off < 0)
e04d7088
L
1810 printf ("-%" BFD_VMA_FMT "x", - off);
1811 else
1812 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1813 }
252b5132 1814
dda8d76d 1815 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1816 && rtype != NULL
1817 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1818 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1819
252b5132 1820 putchar ('\n');
2c71103e 1821
aca88567 1822#ifdef BFD64
dda8d76d 1823 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1824 {
91d6fa6a
NC
1825 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1826 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1827 const char * rtype2 = elf_mips_reloc_type (type2);
1828 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1829
2c71103e
NC
1830 printf (" Type2: ");
1831
1832 if (rtype2 == NULL)
39dbeff8
AM
1833 printf (_("unrecognized: %-7lx"),
1834 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1835 else
1836 printf ("%-17.17s", rtype2);
1837
18bd398b 1838 printf ("\n Type3: ");
2c71103e
NC
1839
1840 if (rtype3 == NULL)
39dbeff8
AM
1841 printf (_("unrecognized: %-7lx"),
1842 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1843 else
1844 printf ("%-17.17s", rtype3);
1845
53c7db4b 1846 putchar ('\n');
2c71103e 1847 }
aca88567 1848#endif /* BFD64 */
252b5132
RH
1849 }
1850
c8286bd1 1851 free (rels);
32ec8896
NC
1852
1853 return res;
252b5132
RH
1854}
1855
37c18eed
SD
1856static const char *
1857get_aarch64_dynamic_type (unsigned long type)
1858{
1859 switch (type)
1860 {
1861 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 1862 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 1863 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
1864 default:
1865 return NULL;
1866 }
1867}
1868
252b5132 1869static const char *
d3ba0551 1870get_mips_dynamic_type (unsigned long type)
252b5132
RH
1871{
1872 switch (type)
1873 {
1874 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1875 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1876 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1877 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1878 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1879 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1880 case DT_MIPS_MSYM: return "MIPS_MSYM";
1881 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1882 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1883 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1884 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1885 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1886 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1887 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1888 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1889 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1890 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1891 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1892 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1893 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1894 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1895 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1896 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1897 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1898 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1899 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1900 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1901 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1902 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1903 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1904 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1905 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1906 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1907 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1908 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1909 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1910 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1911 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1912 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1913 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1914 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1915 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1916 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1917 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1918 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1919 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 1920 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
1921 default:
1922 return NULL;
1923 }
1924}
1925
9a097730 1926static const char *
d3ba0551 1927get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1928{
1929 switch (type)
1930 {
1931 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1932 default:
1933 return NULL;
1934 }
103f02d3
UD
1935}
1936
7490d522
AM
1937static const char *
1938get_ppc_dynamic_type (unsigned long type)
1939{
1940 switch (type)
1941 {
a7f2871e 1942 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1943 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1944 default:
1945 return NULL;
1946 }
1947}
1948
f1cb7e17 1949static const char *
d3ba0551 1950get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1951{
1952 switch (type)
1953 {
a7f2871e
AM
1954 case DT_PPC64_GLINK: return "PPC64_GLINK";
1955 case DT_PPC64_OPD: return "PPC64_OPD";
1956 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1957 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1958 default:
1959 return NULL;
1960 }
1961}
1962
103f02d3 1963static const char *
d3ba0551 1964get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1965{
1966 switch (type)
1967 {
1968 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1969 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1970 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1971 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1972 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1973 case DT_HP_PREINIT: return "HP_PREINIT";
1974 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1975 case DT_HP_NEEDED: return "HP_NEEDED";
1976 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1977 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1978 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1979 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1980 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1981 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1982 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1983 case DT_HP_FILTERED: return "HP_FILTERED";
1984 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1985 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1986 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1987 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1988 case DT_PLT: return "PLT";
1989 case DT_PLT_SIZE: return "PLT_SIZE";
1990 case DT_DLT: return "DLT";
1991 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1992 default:
1993 return NULL;
1994 }
1995}
9a097730 1996
ecc51f48 1997static const char *
d3ba0551 1998get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1999{
2000 switch (type)
2001 {
148b93f2
NC
2002 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2003 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2004 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2005 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2006 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2007 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2008 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2009 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2010 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2011 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2012 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2013 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2014 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2015 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2016 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2017 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2018 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2019 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2020 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2021 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2022 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2023 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2024 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2025 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2026 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2027 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2028 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2029 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2030 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2031 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2032 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2033 default:
2034 return NULL;
2035 }
2036}
2037
fd85a6a1
NC
2038static const char *
2039get_solaris_section_type (unsigned long type)
2040{
2041 switch (type)
2042 {
2043 case 0x6fffffee: return "SUNW_ancillary";
2044 case 0x6fffffef: return "SUNW_capchain";
2045 case 0x6ffffff0: return "SUNW_capinfo";
2046 case 0x6ffffff1: return "SUNW_symsort";
2047 case 0x6ffffff2: return "SUNW_tlssort";
2048 case 0x6ffffff3: return "SUNW_LDYNSYM";
2049 case 0x6ffffff4: return "SUNW_dof";
2050 case 0x6ffffff5: return "SUNW_cap";
2051 case 0x6ffffff6: return "SUNW_SIGNATURE";
2052 case 0x6ffffff7: return "SUNW_ANNOTATE";
2053 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2054 case 0x6ffffff9: return "SUNW_DEBUG";
2055 case 0x6ffffffa: return "SUNW_move";
2056 case 0x6ffffffb: return "SUNW_COMDAT";
2057 case 0x6ffffffc: return "SUNW_syminfo";
2058 case 0x6ffffffd: return "SUNW_verdef";
2059 case 0x6ffffffe: return "SUNW_verneed";
2060 case 0x6fffffff: return "SUNW_versym";
2061 case 0x70000000: return "SPARC_GOTDATA";
2062 default: return NULL;
2063 }
2064}
2065
fabcb361
RH
2066static const char *
2067get_alpha_dynamic_type (unsigned long type)
2068{
2069 switch (type)
2070 {
2071 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2072 default: return NULL;
fabcb361
RH
2073 }
2074}
2075
1c0d3aa6
NC
2076static const char *
2077get_score_dynamic_type (unsigned long type)
2078{
2079 switch (type)
2080 {
2081 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2082 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2083 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2084 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2085 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2086 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2087 default: return NULL;
1c0d3aa6
NC
2088 }
2089}
2090
40b36596
JM
2091static const char *
2092get_tic6x_dynamic_type (unsigned long type)
2093{
2094 switch (type)
2095 {
2096 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2097 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2098 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2099 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2100 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2101 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2102 default: return NULL;
40b36596
JM
2103 }
2104}
1c0d3aa6 2105
36591ba1
SL
2106static const char *
2107get_nios2_dynamic_type (unsigned long type)
2108{
2109 switch (type)
2110 {
2111 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2112 default: return NULL;
36591ba1
SL
2113 }
2114}
2115
fd85a6a1
NC
2116static const char *
2117get_solaris_dynamic_type (unsigned long type)
2118{
2119 switch (type)
2120 {
2121 case 0x6000000d: return "SUNW_AUXILIARY";
2122 case 0x6000000e: return "SUNW_RTLDINF";
2123 case 0x6000000f: return "SUNW_FILTER";
2124 case 0x60000010: return "SUNW_CAP";
2125 case 0x60000011: return "SUNW_SYMTAB";
2126 case 0x60000012: return "SUNW_SYMSZ";
2127 case 0x60000013: return "SUNW_SORTENT";
2128 case 0x60000014: return "SUNW_SYMSORT";
2129 case 0x60000015: return "SUNW_SYMSORTSZ";
2130 case 0x60000016: return "SUNW_TLSSORT";
2131 case 0x60000017: return "SUNW_TLSSORTSZ";
2132 case 0x60000018: return "SUNW_CAPINFO";
2133 case 0x60000019: return "SUNW_STRPAD";
2134 case 0x6000001a: return "SUNW_CAPCHAIN";
2135 case 0x6000001b: return "SUNW_LDMACH";
2136 case 0x6000001d: return "SUNW_CAPCHAINENT";
2137 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2138 case 0x60000021: return "SUNW_PARENT";
2139 case 0x60000023: return "SUNW_ASLR";
2140 case 0x60000025: return "SUNW_RELAX";
2141 case 0x60000029: return "SUNW_NXHEAP";
2142 case 0x6000002b: return "SUNW_NXSTACK";
2143
2144 case 0x70000001: return "SPARC_REGISTER";
2145 case 0x7ffffffd: return "AUXILIARY";
2146 case 0x7ffffffe: return "USED";
2147 case 0x7fffffff: return "FILTER";
2148
15f205b1 2149 default: return NULL;
fd85a6a1
NC
2150 }
2151}
2152
252b5132 2153static const char *
dda8d76d 2154get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2155{
e9e44622 2156 static char buff[64];
252b5132
RH
2157
2158 switch (type)
2159 {
2160 case DT_NULL: return "NULL";
2161 case DT_NEEDED: return "NEEDED";
2162 case DT_PLTRELSZ: return "PLTRELSZ";
2163 case DT_PLTGOT: return "PLTGOT";
2164 case DT_HASH: return "HASH";
2165 case DT_STRTAB: return "STRTAB";
2166 case DT_SYMTAB: return "SYMTAB";
2167 case DT_RELA: return "RELA";
2168 case DT_RELASZ: return "RELASZ";
2169 case DT_RELAENT: return "RELAENT";
2170 case DT_STRSZ: return "STRSZ";
2171 case DT_SYMENT: return "SYMENT";
2172 case DT_INIT: return "INIT";
2173 case DT_FINI: return "FINI";
2174 case DT_SONAME: return "SONAME";
2175 case DT_RPATH: return "RPATH";
2176 case DT_SYMBOLIC: return "SYMBOLIC";
2177 case DT_REL: return "REL";
2178 case DT_RELSZ: return "RELSZ";
2179 case DT_RELENT: return "RELENT";
2180 case DT_PLTREL: return "PLTREL";
2181 case DT_DEBUG: return "DEBUG";
2182 case DT_TEXTREL: return "TEXTREL";
2183 case DT_JMPREL: return "JMPREL";
2184 case DT_BIND_NOW: return "BIND_NOW";
2185 case DT_INIT_ARRAY: return "INIT_ARRAY";
2186 case DT_FINI_ARRAY: return "FINI_ARRAY";
2187 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2188 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2189 case DT_RUNPATH: return "RUNPATH";
2190 case DT_FLAGS: return "FLAGS";
2d0e6f43 2191
d1133906
NC
2192 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2193 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2194 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2195
05107a46 2196 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2197 case DT_PLTPADSZ: return "PLTPADSZ";
2198 case DT_MOVEENT: return "MOVEENT";
2199 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2200 case DT_FEATURE: return "FEATURE";
252b5132
RH
2201 case DT_POSFLAG_1: return "POSFLAG_1";
2202 case DT_SYMINSZ: return "SYMINSZ";
2203 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2204
252b5132 2205 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2206 case DT_CONFIG: return "CONFIG";
2207 case DT_DEPAUDIT: return "DEPAUDIT";
2208 case DT_AUDIT: return "AUDIT";
2209 case DT_PLTPAD: return "PLTPAD";
2210 case DT_MOVETAB: return "MOVETAB";
252b5132 2211 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2212
252b5132 2213 case DT_VERSYM: return "VERSYM";
103f02d3 2214
67a4f2b7
AO
2215 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2216 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2217 case DT_RELACOUNT: return "RELACOUNT";
2218 case DT_RELCOUNT: return "RELCOUNT";
2219 case DT_FLAGS_1: return "FLAGS_1";
2220 case DT_VERDEF: return "VERDEF";
2221 case DT_VERDEFNUM: return "VERDEFNUM";
2222 case DT_VERNEED: return "VERNEED";
2223 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2224
019148e4 2225 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2226 case DT_USED: return "USED";
2227 case DT_FILTER: return "FILTER";
103f02d3 2228
047b2264
JJ
2229 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2230 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2231 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2232 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2233 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2234 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2235 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2236
252b5132
RH
2237 default:
2238 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2239 {
2cf0635d 2240 const char * result;
103f02d3 2241
dda8d76d 2242 switch (filedata->file_header.e_machine)
252b5132 2243 {
37c18eed
SD
2244 case EM_AARCH64:
2245 result = get_aarch64_dynamic_type (type);
2246 break;
252b5132 2247 case EM_MIPS:
4fe85591 2248 case EM_MIPS_RS3_LE:
252b5132
RH
2249 result = get_mips_dynamic_type (type);
2250 break;
9a097730
RH
2251 case EM_SPARCV9:
2252 result = get_sparc64_dynamic_type (type);
2253 break;
7490d522
AM
2254 case EM_PPC:
2255 result = get_ppc_dynamic_type (type);
2256 break;
f1cb7e17
AM
2257 case EM_PPC64:
2258 result = get_ppc64_dynamic_type (type);
2259 break;
ecc51f48
NC
2260 case EM_IA_64:
2261 result = get_ia64_dynamic_type (type);
2262 break;
fabcb361
RH
2263 case EM_ALPHA:
2264 result = get_alpha_dynamic_type (type);
2265 break;
1c0d3aa6
NC
2266 case EM_SCORE:
2267 result = get_score_dynamic_type (type);
2268 break;
40b36596
JM
2269 case EM_TI_C6000:
2270 result = get_tic6x_dynamic_type (type);
2271 break;
36591ba1
SL
2272 case EM_ALTERA_NIOS2:
2273 result = get_nios2_dynamic_type (type);
2274 break;
252b5132 2275 default:
dda8d76d 2276 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2277 result = get_solaris_dynamic_type (type);
2278 else
2279 result = NULL;
252b5132
RH
2280 break;
2281 }
2282
2283 if (result != NULL)
2284 return result;
2285
e9e44622 2286 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2287 }
eec8f817 2288 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2289 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2290 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2291 {
2cf0635d 2292 const char * result;
103f02d3 2293
dda8d76d 2294 switch (filedata->file_header.e_machine)
103f02d3
UD
2295 {
2296 case EM_PARISC:
2297 result = get_parisc_dynamic_type (type);
2298 break;
148b93f2
NC
2299 case EM_IA_64:
2300 result = get_ia64_dynamic_type (type);
2301 break;
103f02d3 2302 default:
dda8d76d 2303 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2304 result = get_solaris_dynamic_type (type);
2305 else
2306 result = NULL;
103f02d3
UD
2307 break;
2308 }
2309
2310 if (result != NULL)
2311 return result;
2312
e9e44622
JJ
2313 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2314 type);
103f02d3 2315 }
252b5132 2316 else
e9e44622 2317 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2318
252b5132
RH
2319 return buff;
2320 }
2321}
2322
2323static char *
d3ba0551 2324get_file_type (unsigned e_type)
252b5132 2325{
89246a0e 2326 static char buff[64];
252b5132
RH
2327
2328 switch (e_type)
2329 {
32ec8896
NC
2330 case ET_NONE: return _("NONE (None)");
2331 case ET_REL: return _("REL (Relocatable file)");
2332 case ET_EXEC: return _("EXEC (Executable file)");
2333 case ET_DYN: return _("DYN (Shared object file)");
2334 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2335
2336 default:
2337 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2338 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2339 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2340 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2341 else
e9e44622 2342 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2343 return buff;
2344 }
2345}
2346
2347static char *
d3ba0551 2348get_machine_name (unsigned e_machine)
252b5132 2349{
b34976b6 2350 static char buff[64]; /* XXX */
252b5132
RH
2351
2352 switch (e_machine)
2353 {
55e22ca8
NC
2354 /* Please keep this switch table sorted by increasing EM_ value. */
2355 /* 0 */
c45021f2
NC
2356 case EM_NONE: return _("None");
2357 case EM_M32: return "WE32100";
2358 case EM_SPARC: return "Sparc";
2359 case EM_386: return "Intel 80386";
2360 case EM_68K: return "MC68000";
2361 case EM_88K: return "MC88000";
22abe556 2362 case EM_IAMCU: return "Intel MCU";
fb70ec17 2363 case EM_860: return "Intel 80860";
c45021f2
NC
2364 case EM_MIPS: return "MIPS R3000";
2365 case EM_S370: return "IBM System/370";
55e22ca8 2366 /* 10 */
7036c0e1 2367 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2368 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2369 case EM_PARISC: return "HPPA";
55e22ca8 2370 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2371 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2372 case EM_960: return "Intel 80960";
c45021f2 2373 case EM_PPC: return "PowerPC";
55e22ca8 2374 /* 20 */
285d1771 2375 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2376 case EM_S390_OLD:
2377 case EM_S390: return "IBM S/390";
2378 case EM_SPU: return "SPU";
2379 /* 30 */
2380 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2381 case EM_FR20: return "Fujitsu FR20";
2382 case EM_RH32: return "TRW RH32";
b34976b6 2383 case EM_MCORE: return "MCORE";
55e22ca8 2384 /* 40 */
7036c0e1
AJ
2385 case EM_ARM: return "ARM";
2386 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2387 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2388 case EM_SPARCV9: return "Sparc v9";
2389 case EM_TRICORE: return "Siemens Tricore";
584da044 2390 case EM_ARC: return "ARC";
c2dcd04e
NC
2391 case EM_H8_300: return "Renesas H8/300";
2392 case EM_H8_300H: return "Renesas H8/300H";
2393 case EM_H8S: return "Renesas H8S";
2394 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2395 /* 50 */
30800947 2396 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2397 case EM_MIPS_X: return "Stanford MIPS-X";
2398 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2399 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2400 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2401 case EM_PCP: return "Siemens PCP";
2402 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2403 case EM_NDR1: return "Denso NDR1 microprocesspr";
2404 case EM_STARCORE: return "Motorola Star*Core processor";
2405 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2406 /* 60 */
7036c0e1
AJ
2407 case EM_ST100: return "STMicroelectronics ST100 processor";
2408 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2409 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2410 case EM_PDSP: return "Sony DSP processor";
2411 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2412 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2413 case EM_FX66: return "Siemens FX66 microcontroller";
2414 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2415 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2416 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2417 /* 70 */
7036c0e1
AJ
2418 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2419 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2420 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2421 case EM_SVX: return "Silicon Graphics SVx";
2422 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2423 case EM_VAX: return "Digital VAX";
1b61cf92 2424 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2425 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2426 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2427 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2428 /* 80 */
b34976b6 2429 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2430 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2431 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2432 case EM_AVR_OLD:
2433 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2434 case EM_CYGNUS_FR30:
2435 case EM_FR30: return "Fujitsu FR30";
2436 case EM_CYGNUS_D10V:
2437 case EM_D10V: return "d10v";
2438 case EM_CYGNUS_D30V:
2439 case EM_D30V: return "d30v";
2440 case EM_CYGNUS_V850:
2441 case EM_V850: return "Renesas V850";
2442 case EM_CYGNUS_M32R:
2443 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2444 case EM_CYGNUS_MN10300:
2445 case EM_MN10300: return "mn10300";
2446 /* 90 */
2447 case EM_CYGNUS_MN10200:
2448 case EM_MN10200: return "mn10200";
2449 case EM_PJ: return "picoJava";
73589c9d 2450 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2451 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2452 case EM_XTENSA_OLD:
2453 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2454 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2455 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2456 case EM_NS32K: return "National Semiconductor 32000 series";
2457 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2458 case EM_SNP1K: return "Trebia SNP 1000 processor";
2459 /* 100 */
9abca702 2460 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2461 case EM_IP2K_OLD:
2462 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2463 case EM_MAX: return "MAX Processor";
2464 case EM_CR: return "National Semiconductor CompactRISC";
2465 case EM_F2MC16: return "Fujitsu F2MC16";
2466 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2467 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2468 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2469 case EM_SEP: return "Sharp embedded microprocessor";
2470 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2471 /* 110 */
11636f9e
JM
2472 case EM_UNICORE: return "Unicore";
2473 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2474 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2475 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2476 case EM_CRX: return "National Semiconductor CRX microprocessor";
2477 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2478 case EM_C166:
d70c5fc7 2479 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2480 case EM_M16C: return "Renesas M16C series microprocessors";
2481 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2482 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2483 /* 120 */
2484 case EM_M32C: return "Renesas M32c";
2485 /* 130 */
11636f9e
JM
2486 case EM_TSK3000: return "Altium TSK3000 core";
2487 case EM_RS08: return "Freescale RS08 embedded processor";
2488 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2489 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2490 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2491 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2492 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2493 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2494 /* 140 */
11636f9e
JM
2495 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2496 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2497 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2498 case EM_TI_PRU: return "TI PRU I/O processor";
2499 /* 160 */
11636f9e
JM
2500 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2501 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2502 case EM_R32C: return "Renesas R32C series microprocessors";
2503 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2504 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2505 case EM_8051: return "Intel 8051 and variants";
2506 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2507 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2508 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2509 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2510 /* 170 */
11636f9e
JM
2511 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2512 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2513 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2514 case EM_RX: return "Renesas RX";
a3c62988 2515 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2516 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2517 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2518 case EM_CR16:
2519 case EM_MICROBLAZE:
2520 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2521 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2522 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2523 /* 180 */
2524 case EM_L1OM: return "Intel L1OM";
2525 case EM_K1OM: return "Intel K1OM";
2526 case EM_INTEL182: return "Intel (reserved)";
2527 case EM_AARCH64: return "AArch64";
2528 case EM_ARM184: return "ARM (reserved)";
2529 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2530 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2531 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2532 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2533 /* 190 */
11636f9e 2534 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2535 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2536 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2537 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2538 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2539 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2540 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2541 case EM_RL78: return "Renesas RL78";
6d913794 2542 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2543 case EM_78K0R: return "Renesas 78K0R";
2544 /* 200 */
6d913794 2545 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2546 case EM_BA1: return "Beyond BA1 CPU architecture";
2547 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2548 case EM_XCORE: return "XMOS xCORE processor family";
2549 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
55e22ca8 2550 /* 210 */
6d913794
NC
2551 case EM_KM32: return "KM211 KM32 32-bit processor";
2552 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2553 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2554 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2555 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2556 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2557 case EM_COGE: return "Cognitive Smart Memory Processor";
2558 case EM_COOL: return "Bluechip Systems CoolEngine";
2559 case EM_NORC: return "Nanoradio Optimized RISC";
2560 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2561 /* 220 */
15f205b1 2562 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2563 case EM_VISIUM: return "CDS VISIUMcore processor";
2564 case EM_FT32: return "FTDI Chip FT32";
2565 case EM_MOXIE: return "Moxie";
2566 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2567 /* 230 (all reserved) */
2568 /* 240 */
55e22ca8
NC
2569 case EM_RISCV: return "RISC-V";
2570 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2571 case EM_CEVA: return "CEVA Processor Architecture Family";
2572 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2573 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2574 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2575 case EM_IMG1: return "Imagination Technologies";
2576 /* 250 */
fe944acf 2577 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2578 case EM_VE: return "NEC Vector Engine";
2579 case EM_CSKY: return "C-SKY";
2580 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2581 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2582 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2583 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2584 case EM_65816: return "WDC 65816/65C816";
2585 case EM_LOONGARCH: return "Loongson Loongarch";
2586 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2587
2588 /* Large numbers... */
2589 case EM_MT: return "Morpho Techologies MT processor";
2590 case EM_ALPHA: return "Alpha";
2591 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2592 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2593 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2594 case EM_IQ2000: return "Vitesse IQ2000";
2595 case EM_M32C_OLD:
2596 case EM_NIOS32: return "Altera Nios";
2597 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2598 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2599 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2600 case EM_S12Z: return "Freescale S12Z";
55e22ca8 2601
252b5132 2602 default:
35d9dd2f 2603 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2604 return buff;
2605 }
2606}
2607
a9522a21
AB
2608static void
2609decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2610{
2611 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 2612 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
2613 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2614 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2615 architectures.
2616
2617 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2618 but also sets a specific architecture type in the e_flags field.
2619
2620 However, when decoding the flags we don't worry if we see an
2621 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2622 ARCEM architecture type. */
2623
2624 switch (e_flags & EF_ARC_MACH_MSK)
2625 {
2626 /* We only expect these to occur for EM_ARC_COMPACT2. */
2627 case EF_ARC_CPU_ARCV2EM:
2628 strcat (buf, ", ARC EM");
2629 break;
2630 case EF_ARC_CPU_ARCV2HS:
2631 strcat (buf, ", ARC HS");
2632 break;
2633
2634 /* We only expect these to occur for EM_ARC_COMPACT. */
2635 case E_ARC_MACH_ARC600:
2636 strcat (buf, ", ARC600");
2637 break;
2638 case E_ARC_MACH_ARC601:
2639 strcat (buf, ", ARC601");
2640 break;
2641 case E_ARC_MACH_ARC700:
2642 strcat (buf, ", ARC700");
2643 break;
2644
2645 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2646 new ELF with new architecture being read by an old version of
2647 readelf, or (c) An ELF built with non-GNU compiler that does not
2648 set the architecture in the e_flags. */
2649 default:
2650 if (e_machine == EM_ARC_COMPACT)
2651 strcat (buf, ", Unknown ARCompact");
2652 else
2653 strcat (buf, ", Unknown ARC");
2654 break;
2655 }
2656
2657 switch (e_flags & EF_ARC_OSABI_MSK)
2658 {
2659 case E_ARC_OSABI_ORIG:
2660 strcat (buf, ", (ABI:legacy)");
2661 break;
2662 case E_ARC_OSABI_V2:
2663 strcat (buf, ", (ABI:v2)");
2664 break;
2665 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2666 case E_ARC_OSABI_V3:
2667 strcat (buf, ", v3 no-legacy-syscalls ABI");
2668 break;
53a346d8
CZ
2669 case E_ARC_OSABI_V4:
2670 strcat (buf, ", v4 ABI");
2671 break;
a9522a21
AB
2672 default:
2673 strcat (buf, ", unrecognised ARC OSABI flag");
2674 break;
2675 }
2676}
2677
f3485b74 2678static void
d3ba0551 2679decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2680{
2681 unsigned eabi;
32ec8896 2682 bfd_boolean unknown = FALSE;
f3485b74
NC
2683
2684 eabi = EF_ARM_EABI_VERSION (e_flags);
2685 e_flags &= ~ EF_ARM_EABIMASK;
2686
2687 /* Handle "generic" ARM flags. */
2688 if (e_flags & EF_ARM_RELEXEC)
2689 {
2690 strcat (buf, ", relocatable executable");
2691 e_flags &= ~ EF_ARM_RELEXEC;
2692 }
76da6bbe 2693
18a20338
CL
2694 if (e_flags & EF_ARM_PIC)
2695 {
2696 strcat (buf, ", position independent");
2697 e_flags &= ~ EF_ARM_PIC;
2698 }
2699
f3485b74
NC
2700 /* Now handle EABI specific flags. */
2701 switch (eabi)
2702 {
2703 default:
2c71103e 2704 strcat (buf, ", <unrecognized EABI>");
f3485b74 2705 if (e_flags)
32ec8896 2706 unknown = TRUE;
f3485b74
NC
2707 break;
2708
2709 case EF_ARM_EABI_VER1:
a5bcd848 2710 strcat (buf, ", Version1 EABI");
f3485b74
NC
2711 while (e_flags)
2712 {
2713 unsigned flag;
76da6bbe 2714
f3485b74
NC
2715 /* Process flags one bit at a time. */
2716 flag = e_flags & - e_flags;
2717 e_flags &= ~ flag;
76da6bbe 2718
f3485b74
NC
2719 switch (flag)
2720 {
a5bcd848 2721 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2722 strcat (buf, ", sorted symbol tables");
2723 break;
76da6bbe 2724
f3485b74 2725 default:
32ec8896 2726 unknown = TRUE;
f3485b74
NC
2727 break;
2728 }
2729 }
2730 break;
76da6bbe 2731
a5bcd848
PB
2732 case EF_ARM_EABI_VER2:
2733 strcat (buf, ", Version2 EABI");
2734 while (e_flags)
2735 {
2736 unsigned flag;
2737
2738 /* Process flags one bit at a time. */
2739 flag = e_flags & - e_flags;
2740 e_flags &= ~ flag;
2741
2742 switch (flag)
2743 {
2744 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2745 strcat (buf, ", sorted symbol tables");
2746 break;
2747
2748 case EF_ARM_DYNSYMSUSESEGIDX:
2749 strcat (buf, ", dynamic symbols use segment index");
2750 break;
2751
2752 case EF_ARM_MAPSYMSFIRST:
2753 strcat (buf, ", mapping symbols precede others");
2754 break;
2755
2756 default:
32ec8896 2757 unknown = TRUE;
a5bcd848
PB
2758 break;
2759 }
2760 }
2761 break;
2762
d507cf36
PB
2763 case EF_ARM_EABI_VER3:
2764 strcat (buf, ", Version3 EABI");
8cb51566
PB
2765 break;
2766
2767 case EF_ARM_EABI_VER4:
2768 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2769 while (e_flags)
2770 {
2771 unsigned flag;
2772
2773 /* Process flags one bit at a time. */
2774 flag = e_flags & - e_flags;
2775 e_flags &= ~ flag;
2776
2777 switch (flag)
2778 {
2779 case EF_ARM_BE8:
2780 strcat (buf, ", BE8");
2781 break;
2782
2783 case EF_ARM_LE8:
2784 strcat (buf, ", LE8");
2785 break;
2786
2787 default:
32ec8896 2788 unknown = TRUE;
3bfcb652
NC
2789 break;
2790 }
3bfcb652
NC
2791 }
2792 break;
3a4a14e9
PB
2793
2794 case EF_ARM_EABI_VER5:
2795 strcat (buf, ", Version5 EABI");
d507cf36
PB
2796 while (e_flags)
2797 {
2798 unsigned flag;
2799
2800 /* Process flags one bit at a time. */
2801 flag = e_flags & - e_flags;
2802 e_flags &= ~ flag;
2803
2804 switch (flag)
2805 {
2806 case EF_ARM_BE8:
2807 strcat (buf, ", BE8");
2808 break;
2809
2810 case EF_ARM_LE8:
2811 strcat (buf, ", LE8");
2812 break;
2813
3bfcb652
NC
2814 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2815 strcat (buf, ", soft-float ABI");
2816 break;
2817
2818 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2819 strcat (buf, ", hard-float ABI");
2820 break;
2821
d507cf36 2822 default:
32ec8896 2823 unknown = TRUE;
d507cf36
PB
2824 break;
2825 }
2826 }
2827 break;
2828
f3485b74 2829 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2830 strcat (buf, ", GNU EABI");
f3485b74
NC
2831 while (e_flags)
2832 {
2833 unsigned flag;
76da6bbe 2834
f3485b74
NC
2835 /* Process flags one bit at a time. */
2836 flag = e_flags & - e_flags;
2837 e_flags &= ~ flag;
76da6bbe 2838
f3485b74
NC
2839 switch (flag)
2840 {
a5bcd848 2841 case EF_ARM_INTERWORK:
f3485b74
NC
2842 strcat (buf, ", interworking enabled");
2843 break;
76da6bbe 2844
a5bcd848 2845 case EF_ARM_APCS_26:
f3485b74
NC
2846 strcat (buf, ", uses APCS/26");
2847 break;
76da6bbe 2848
a5bcd848 2849 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2850 strcat (buf, ", uses APCS/float");
2851 break;
76da6bbe 2852
a5bcd848 2853 case EF_ARM_PIC:
f3485b74
NC
2854 strcat (buf, ", position independent");
2855 break;
76da6bbe 2856
a5bcd848 2857 case EF_ARM_ALIGN8:
f3485b74
NC
2858 strcat (buf, ", 8 bit structure alignment");
2859 break;
76da6bbe 2860
a5bcd848 2861 case EF_ARM_NEW_ABI:
f3485b74
NC
2862 strcat (buf, ", uses new ABI");
2863 break;
76da6bbe 2864
a5bcd848 2865 case EF_ARM_OLD_ABI:
f3485b74
NC
2866 strcat (buf, ", uses old ABI");
2867 break;
76da6bbe 2868
a5bcd848 2869 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2870 strcat (buf, ", software FP");
2871 break;
76da6bbe 2872
90e01f86
ILT
2873 case EF_ARM_VFP_FLOAT:
2874 strcat (buf, ", VFP");
2875 break;
2876
fde78edd
NC
2877 case EF_ARM_MAVERICK_FLOAT:
2878 strcat (buf, ", Maverick FP");
2879 break;
2880
f3485b74 2881 default:
32ec8896 2882 unknown = TRUE;
f3485b74
NC
2883 break;
2884 }
2885 }
2886 }
f3485b74
NC
2887
2888 if (unknown)
2b692964 2889 strcat (buf,_(", <unknown>"));
f3485b74
NC
2890}
2891
343433df
AB
2892static void
2893decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2894{
2895 --size; /* Leave space for null terminator. */
2896
2897 switch (e_flags & EF_AVR_MACH)
2898 {
2899 case E_AVR_MACH_AVR1:
2900 strncat (buf, ", avr:1", size);
2901 break;
2902 case E_AVR_MACH_AVR2:
2903 strncat (buf, ", avr:2", size);
2904 break;
2905 case E_AVR_MACH_AVR25:
2906 strncat (buf, ", avr:25", size);
2907 break;
2908 case E_AVR_MACH_AVR3:
2909 strncat (buf, ", avr:3", size);
2910 break;
2911 case E_AVR_MACH_AVR31:
2912 strncat (buf, ", avr:31", size);
2913 break;
2914 case E_AVR_MACH_AVR35:
2915 strncat (buf, ", avr:35", size);
2916 break;
2917 case E_AVR_MACH_AVR4:
2918 strncat (buf, ", avr:4", size);
2919 break;
2920 case E_AVR_MACH_AVR5:
2921 strncat (buf, ", avr:5", size);
2922 break;
2923 case E_AVR_MACH_AVR51:
2924 strncat (buf, ", avr:51", size);
2925 break;
2926 case E_AVR_MACH_AVR6:
2927 strncat (buf, ", avr:6", size);
2928 break;
2929 case E_AVR_MACH_AVRTINY:
2930 strncat (buf, ", avr:100", size);
2931 break;
2932 case E_AVR_MACH_XMEGA1:
2933 strncat (buf, ", avr:101", size);
2934 break;
2935 case E_AVR_MACH_XMEGA2:
2936 strncat (buf, ", avr:102", size);
2937 break;
2938 case E_AVR_MACH_XMEGA3:
2939 strncat (buf, ", avr:103", size);
2940 break;
2941 case E_AVR_MACH_XMEGA4:
2942 strncat (buf, ", avr:104", size);
2943 break;
2944 case E_AVR_MACH_XMEGA5:
2945 strncat (buf, ", avr:105", size);
2946 break;
2947 case E_AVR_MACH_XMEGA6:
2948 strncat (buf, ", avr:106", size);
2949 break;
2950 case E_AVR_MACH_XMEGA7:
2951 strncat (buf, ", avr:107", size);
2952 break;
2953 default:
2954 strncat (buf, ", avr:<unknown>", size);
2955 break;
2956 }
2957
2958 size -= strlen (buf);
2959 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2960 strncat (buf, ", link-relax", size);
2961}
2962
35c08157
KLC
2963static void
2964decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2965{
2966 unsigned abi;
2967 unsigned arch;
2968 unsigned config;
2969 unsigned version;
32ec8896
NC
2970 bfd_boolean has_fpu = FALSE;
2971 unsigned int r = 0;
35c08157
KLC
2972
2973 static const char *ABI_STRINGS[] =
2974 {
2975 "ABI v0", /* use r5 as return register; only used in N1213HC */
2976 "ABI v1", /* use r0 as return register */
2977 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2978 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2979 "AABI",
2980 "ABI2 FP+"
35c08157
KLC
2981 };
2982 static const char *VER_STRINGS[] =
2983 {
2984 "Andes ELF V1.3 or older",
2985 "Andes ELF V1.3.1",
2986 "Andes ELF V1.4"
2987 };
2988 static const char *ARCH_STRINGS[] =
2989 {
2990 "",
2991 "Andes Star v1.0",
2992 "Andes Star v2.0",
2993 "Andes Star v3.0",
2994 "Andes Star v3.0m"
2995 };
2996
2997 abi = EF_NDS_ABI & e_flags;
2998 arch = EF_NDS_ARCH & e_flags;
2999 config = EF_NDS_INST & e_flags;
3000 version = EF_NDS32_ELF_VERSION & e_flags;
3001
3002 memset (buf, 0, size);
3003
3004 switch (abi)
3005 {
3006 case E_NDS_ABI_V0:
3007 case E_NDS_ABI_V1:
3008 case E_NDS_ABI_V2:
3009 case E_NDS_ABI_V2FP:
3010 case E_NDS_ABI_AABI:
40c7a7cb 3011 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3012 /* In case there are holes in the array. */
3013 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3014 break;
3015
3016 default:
3017 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3018 break;
3019 }
3020
3021 switch (version)
3022 {
3023 case E_NDS32_ELF_VER_1_2:
3024 case E_NDS32_ELF_VER_1_3:
3025 case E_NDS32_ELF_VER_1_4:
3026 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3027 break;
3028
3029 default:
3030 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3031 break;
3032 }
3033
3034 if (E_NDS_ABI_V0 == abi)
3035 {
3036 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3037 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3038 if (arch == E_NDS_ARCH_STAR_V1_0)
3039 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3040 return;
3041 }
3042
3043 switch (arch)
3044 {
3045 case E_NDS_ARCH_STAR_V1_0:
3046 case E_NDS_ARCH_STAR_V2_0:
3047 case E_NDS_ARCH_STAR_V3_0:
3048 case E_NDS_ARCH_STAR_V3_M:
3049 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3050 break;
3051
3052 default:
3053 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3054 /* ARCH version determines how the e_flags are interpreted.
3055 If it is unknown, we cannot proceed. */
3056 return;
3057 }
3058
3059 /* Newer ABI; Now handle architecture specific flags. */
3060 if (arch == E_NDS_ARCH_STAR_V1_0)
3061 {
3062 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3063 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3064
3065 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3066 r += snprintf (buf + r, size -r, ", MAC");
3067
3068 if (config & E_NDS32_HAS_DIV_INST)
3069 r += snprintf (buf + r, size -r, ", DIV");
3070
3071 if (config & E_NDS32_HAS_16BIT_INST)
3072 r += snprintf (buf + r, size -r, ", 16b");
3073 }
3074 else
3075 {
3076 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3077 {
3078 if (version <= E_NDS32_ELF_VER_1_3)
3079 r += snprintf (buf + r, size -r, ", [B8]");
3080 else
3081 r += snprintf (buf + r, size -r, ", EX9");
3082 }
3083
3084 if (config & E_NDS32_HAS_MAC_DX_INST)
3085 r += snprintf (buf + r, size -r, ", MAC_DX");
3086
3087 if (config & E_NDS32_HAS_DIV_DX_INST)
3088 r += snprintf (buf + r, size -r, ", DIV_DX");
3089
3090 if (config & E_NDS32_HAS_16BIT_INST)
3091 {
3092 if (version <= E_NDS32_ELF_VER_1_3)
3093 r += snprintf (buf + r, size -r, ", 16b");
3094 else
3095 r += snprintf (buf + r, size -r, ", IFC");
3096 }
3097 }
3098
3099 if (config & E_NDS32_HAS_EXT_INST)
3100 r += snprintf (buf + r, size -r, ", PERF1");
3101
3102 if (config & E_NDS32_HAS_EXT2_INST)
3103 r += snprintf (buf + r, size -r, ", PERF2");
3104
3105 if (config & E_NDS32_HAS_FPU_INST)
3106 {
32ec8896 3107 has_fpu = TRUE;
35c08157
KLC
3108 r += snprintf (buf + r, size -r, ", FPU_SP");
3109 }
3110
3111 if (config & E_NDS32_HAS_FPU_DP_INST)
3112 {
32ec8896 3113 has_fpu = TRUE;
35c08157
KLC
3114 r += snprintf (buf + r, size -r, ", FPU_DP");
3115 }
3116
3117 if (config & E_NDS32_HAS_FPU_MAC_INST)
3118 {
32ec8896 3119 has_fpu = TRUE;
35c08157
KLC
3120 r += snprintf (buf + r, size -r, ", FPU_MAC");
3121 }
3122
3123 if (has_fpu)
3124 {
3125 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3126 {
3127 case E_NDS32_FPU_REG_8SP_4DP:
3128 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3129 break;
3130 case E_NDS32_FPU_REG_16SP_8DP:
3131 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3132 break;
3133 case E_NDS32_FPU_REG_32SP_16DP:
3134 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3135 break;
3136 case E_NDS32_FPU_REG_32SP_32DP:
3137 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3138 break;
3139 }
3140 }
3141
3142 if (config & E_NDS32_HAS_AUDIO_INST)
3143 r += snprintf (buf + r, size -r, ", AUDIO");
3144
3145 if (config & E_NDS32_HAS_STRING_INST)
3146 r += snprintf (buf + r, size -r, ", STR");
3147
3148 if (config & E_NDS32_HAS_REDUCED_REGS)
3149 r += snprintf (buf + r, size -r, ", 16REG");
3150
3151 if (config & E_NDS32_HAS_VIDEO_INST)
3152 {
3153 if (version <= E_NDS32_ELF_VER_1_3)
3154 r += snprintf (buf + r, size -r, ", VIDEO");
3155 else
3156 r += snprintf (buf + r, size -r, ", SATURATION");
3157 }
3158
3159 if (config & E_NDS32_HAS_ENCRIPT_INST)
3160 r += snprintf (buf + r, size -r, ", ENCRP");
3161
3162 if (config & E_NDS32_HAS_L2C_INST)
3163 r += snprintf (buf + r, size -r, ", L2C");
3164}
3165
252b5132 3166static char *
dda8d76d 3167get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3168{
b34976b6 3169 static char buf[1024];
252b5132
RH
3170
3171 buf[0] = '\0';
76da6bbe 3172
252b5132
RH
3173 if (e_flags)
3174 {
3175 switch (e_machine)
3176 {
3177 default:
3178 break;
3179
886a2506 3180 case EM_ARC_COMPACT2:
886a2506 3181 case EM_ARC_COMPACT:
a9522a21
AB
3182 decode_ARC_machine_flags (e_flags, e_machine, buf);
3183 break;
886a2506 3184
f3485b74
NC
3185 case EM_ARM:
3186 decode_ARM_machine_flags (e_flags, buf);
3187 break;
76da6bbe 3188
343433df
AB
3189 case EM_AVR:
3190 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3191 break;
3192
781303ce
MF
3193 case EM_BLACKFIN:
3194 if (e_flags & EF_BFIN_PIC)
3195 strcat (buf, ", PIC");
3196
3197 if (e_flags & EF_BFIN_FDPIC)
3198 strcat (buf, ", FDPIC");
3199
3200 if (e_flags & EF_BFIN_CODE_IN_L1)
3201 strcat (buf, ", code in L1");
3202
3203 if (e_flags & EF_BFIN_DATA_IN_L1)
3204 strcat (buf, ", data in L1");
3205
3206 break;
3207
ec2dfb42
AO
3208 case EM_CYGNUS_FRV:
3209 switch (e_flags & EF_FRV_CPU_MASK)
3210 {
3211 case EF_FRV_CPU_GENERIC:
3212 break;
3213
3214 default:
3215 strcat (buf, ", fr???");
3216 break;
57346661 3217
ec2dfb42
AO
3218 case EF_FRV_CPU_FR300:
3219 strcat (buf, ", fr300");
3220 break;
3221
3222 case EF_FRV_CPU_FR400:
3223 strcat (buf, ", fr400");
3224 break;
3225 case EF_FRV_CPU_FR405:
3226 strcat (buf, ", fr405");
3227 break;
3228
3229 case EF_FRV_CPU_FR450:
3230 strcat (buf, ", fr450");
3231 break;
3232
3233 case EF_FRV_CPU_FR500:
3234 strcat (buf, ", fr500");
3235 break;
3236 case EF_FRV_CPU_FR550:
3237 strcat (buf, ", fr550");
3238 break;
3239
3240 case EF_FRV_CPU_SIMPLE:
3241 strcat (buf, ", simple");
3242 break;
3243 case EF_FRV_CPU_TOMCAT:
3244 strcat (buf, ", tomcat");
3245 break;
3246 }
1c877e87 3247 break;
ec2dfb42 3248
53c7db4b 3249 case EM_68K:
425c6cb0 3250 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3251 strcat (buf, ", m68000");
425c6cb0 3252 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3253 strcat (buf, ", cpu32");
3254 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3255 strcat (buf, ", fido_a");
425c6cb0 3256 else
266abb8f 3257 {
2cf0635d
NC
3258 char const * isa = _("unknown");
3259 char const * mac = _("unknown mac");
3260 char const * additional = NULL;
0112cd26 3261
c694fd50 3262 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3263 {
c694fd50 3264 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3265 isa = "A";
3266 additional = ", nodiv";
3267 break;
c694fd50 3268 case EF_M68K_CF_ISA_A:
266abb8f
NS
3269 isa = "A";
3270 break;
c694fd50 3271 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3272 isa = "A+";
3273 break;
c694fd50 3274 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3275 isa = "B";
3276 additional = ", nousp";
3277 break;
c694fd50 3278 case EF_M68K_CF_ISA_B:
266abb8f
NS
3279 isa = "B";
3280 break;
f608cd77
NS
3281 case EF_M68K_CF_ISA_C:
3282 isa = "C";
3283 break;
3284 case EF_M68K_CF_ISA_C_NODIV:
3285 isa = "C";
3286 additional = ", nodiv";
3287 break;
266abb8f
NS
3288 }
3289 strcat (buf, ", cf, isa ");
3290 strcat (buf, isa);
0b2e31dc
NS
3291 if (additional)
3292 strcat (buf, additional);
c694fd50 3293 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3294 strcat (buf, ", float");
c694fd50 3295 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3296 {
3297 case 0:
3298 mac = NULL;
3299 break;
c694fd50 3300 case EF_M68K_CF_MAC:
266abb8f
NS
3301 mac = "mac";
3302 break;
c694fd50 3303 case EF_M68K_CF_EMAC:
266abb8f
NS
3304 mac = "emac";
3305 break;
f608cd77
NS
3306 case EF_M68K_CF_EMAC_B:
3307 mac = "emac_b";
3308 break;
266abb8f
NS
3309 }
3310 if (mac)
3311 {
3312 strcat (buf, ", ");
3313 strcat (buf, mac);
3314 }
266abb8f 3315 }
53c7db4b 3316 break;
33c63f9d 3317
153a2776
NC
3318 case EM_CYGNUS_MEP:
3319 switch (e_flags & EF_MEP_CPU_MASK)
3320 {
3321 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3322 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3323 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3324 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3325 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3326 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3327 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3328 }
3329
3330 switch (e_flags & EF_MEP_COP_MASK)
3331 {
3332 case EF_MEP_COP_NONE: break;
3333 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3334 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3335 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3336 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3337 default: strcat (buf, _("<unknown MeP copro type>")); break;
3338 }
3339
3340 if (e_flags & EF_MEP_LIBRARY)
3341 strcat (buf, ", Built for Library");
3342
3343 if (e_flags & EF_MEP_INDEX_MASK)
3344 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3345 e_flags & EF_MEP_INDEX_MASK);
3346
3347 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3348 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3349 e_flags & ~ EF_MEP_ALL_FLAGS);
3350 break;
3351
252b5132
RH
3352 case EM_PPC:
3353 if (e_flags & EF_PPC_EMB)
3354 strcat (buf, ", emb");
3355
3356 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3357 strcat (buf, _(", relocatable"));
252b5132
RH
3358
3359 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3360 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3361 break;
3362
ee67d69a
AM
3363 case EM_PPC64:
3364 if (e_flags & EF_PPC64_ABI)
3365 {
3366 char abi[] = ", abiv0";
3367
3368 abi[6] += e_flags & EF_PPC64_ABI;
3369 strcat (buf, abi);
3370 }
3371 break;
3372
708e2187
NC
3373 case EM_V800:
3374 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3375 strcat (buf, ", RH850 ABI");
0b4362b0 3376
708e2187
NC
3377 if (e_flags & EF_V800_850E3)
3378 strcat (buf, ", V3 architecture");
3379
3380 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3381 strcat (buf, ", FPU not used");
3382
3383 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3384 strcat (buf, ", regmode: COMMON");
3385
3386 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3387 strcat (buf, ", r4 not used");
3388
3389 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3390 strcat (buf, ", r30 not used");
3391
3392 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3393 strcat (buf, ", r5 not used");
3394
3395 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3396 strcat (buf, ", r2 not used");
3397
3398 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3399 {
3400 switch (e_flags & - e_flags)
3401 {
3402 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3403 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3404 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3405 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3406 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3407 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3408 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3409 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3410 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3411 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3412 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3413 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3414 default: break;
3415 }
3416 }
3417 break;
3418
2b0337b0 3419 case EM_V850:
252b5132
RH
3420 case EM_CYGNUS_V850:
3421 switch (e_flags & EF_V850_ARCH)
3422 {
78c8d46c
NC
3423 case E_V850E3V5_ARCH:
3424 strcat (buf, ", v850e3v5");
3425 break;
1cd986c5
NC
3426 case E_V850E2V3_ARCH:
3427 strcat (buf, ", v850e2v3");
3428 break;
3429 case E_V850E2_ARCH:
3430 strcat (buf, ", v850e2");
3431 break;
3432 case E_V850E1_ARCH:
3433 strcat (buf, ", v850e1");
8ad30312 3434 break;
252b5132
RH
3435 case E_V850E_ARCH:
3436 strcat (buf, ", v850e");
3437 break;
252b5132
RH
3438 case E_V850_ARCH:
3439 strcat (buf, ", v850");
3440 break;
3441 default:
2b692964 3442 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3443 break;
3444 }
3445 break;
3446
2b0337b0 3447 case EM_M32R:
252b5132
RH
3448 case EM_CYGNUS_M32R:
3449 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3450 strcat (buf, ", m32r");
252b5132
RH
3451 break;
3452
3453 case EM_MIPS:
4fe85591 3454 case EM_MIPS_RS3_LE:
252b5132
RH
3455 if (e_flags & EF_MIPS_NOREORDER)
3456 strcat (buf, ", noreorder");
3457
3458 if (e_flags & EF_MIPS_PIC)
3459 strcat (buf, ", pic");
3460
3461 if (e_flags & EF_MIPS_CPIC)
3462 strcat (buf, ", cpic");
3463
d1bdd336
TS
3464 if (e_flags & EF_MIPS_UCODE)
3465 strcat (buf, ", ugen_reserved");
3466
252b5132
RH
3467 if (e_flags & EF_MIPS_ABI2)
3468 strcat (buf, ", abi2");
3469
43521d43
TS
3470 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3471 strcat (buf, ", odk first");
3472
a5d22d2a
TS
3473 if (e_flags & EF_MIPS_32BITMODE)
3474 strcat (buf, ", 32bitmode");
3475
ba92f887
MR
3476 if (e_flags & EF_MIPS_NAN2008)
3477 strcat (buf, ", nan2008");
3478
fef1b0b3
SE
3479 if (e_flags & EF_MIPS_FP64)
3480 strcat (buf, ", fp64");
3481
156c2f8b
NC
3482 switch ((e_flags & EF_MIPS_MACH))
3483 {
3484 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3485 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3486 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3487 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3488 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3489 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3490 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3491 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3492 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3493 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3494 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3495 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3496 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3497 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3498 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3499 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3500 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3501 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3502 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3503 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3504 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3505 case 0:
3506 /* We simply ignore the field in this case to avoid confusion:
3507 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3508 extension. */
3509 break;
2b692964 3510 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3511 }
43521d43
TS
3512
3513 switch ((e_flags & EF_MIPS_ABI))
3514 {
3515 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3516 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3517 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3518 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3519 case 0:
3520 /* We simply ignore the field in this case to avoid confusion:
3521 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3522 This means it is likely to be an o32 file, but not for
3523 sure. */
3524 break;
2b692964 3525 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3526 }
3527
3528 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3529 strcat (buf, ", mdmx");
3530
3531 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3532 strcat (buf, ", mips16");
3533
df58fc94
RS
3534 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3535 strcat (buf, ", micromips");
3536
43521d43
TS
3537 switch ((e_flags & EF_MIPS_ARCH))
3538 {
3539 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3540 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3541 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3542 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3543 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3544 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3545 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3546 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3547 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3548 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3549 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3550 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3551 }
252b5132 3552 break;
351b4b40 3553
35c08157
KLC
3554 case EM_NDS32:
3555 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3556 break;
3557
fe944acf
FT
3558 case EM_NFP:
3559 switch (EF_NFP_MACH (e_flags))
3560 {
3561 case E_NFP_MACH_3200:
3562 strcat (buf, ", NFP-32xx");
3563 break;
3564 case E_NFP_MACH_6000:
3565 strcat (buf, ", NFP-6xxx");
3566 break;
3567 }
3568 break;
3569
e23eba97
NC
3570 case EM_RISCV:
3571 if (e_flags & EF_RISCV_RVC)
3572 strcat (buf, ", RVC");
2922d21d 3573
7f999549
JW
3574 if (e_flags & EF_RISCV_RVE)
3575 strcat (buf, ", RVE");
3576
2922d21d
AW
3577 switch (e_flags & EF_RISCV_FLOAT_ABI)
3578 {
3579 case EF_RISCV_FLOAT_ABI_SOFT:
3580 strcat (buf, ", soft-float ABI");
3581 break;
3582
3583 case EF_RISCV_FLOAT_ABI_SINGLE:
3584 strcat (buf, ", single-float ABI");
3585 break;
3586
3587 case EF_RISCV_FLOAT_ABI_DOUBLE:
3588 strcat (buf, ", double-float ABI");
3589 break;
3590
3591 case EF_RISCV_FLOAT_ABI_QUAD:
3592 strcat (buf, ", quad-float ABI");
3593 break;
3594 }
e23eba97
NC
3595 break;
3596
ccde1100
AO
3597 case EM_SH:
3598 switch ((e_flags & EF_SH_MACH_MASK))
3599 {
3600 case EF_SH1: strcat (buf, ", sh1"); break;
3601 case EF_SH2: strcat (buf, ", sh2"); break;
3602 case EF_SH3: strcat (buf, ", sh3"); break;
3603 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3604 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3605 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3606 case EF_SH3E: strcat (buf, ", sh3e"); break;
3607 case EF_SH4: strcat (buf, ", sh4"); break;
3608 case EF_SH5: strcat (buf, ", sh5"); break;
3609 case EF_SH2E: strcat (buf, ", sh2e"); break;
3610 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3611 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3612 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3613 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3614 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3615 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3616 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3617 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3618 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3619 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3620 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3621 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3622 }
3623
cec6a5b8
MR
3624 if (e_flags & EF_SH_PIC)
3625 strcat (buf, ", pic");
3626
3627 if (e_flags & EF_SH_FDPIC)
3628 strcat (buf, ", fdpic");
ccde1100 3629 break;
948f632f 3630
73589c9d
CS
3631 case EM_OR1K:
3632 if (e_flags & EF_OR1K_NODELAY)
3633 strcat (buf, ", no delay");
3634 break;
57346661 3635
351b4b40
RH
3636 case EM_SPARCV9:
3637 if (e_flags & EF_SPARC_32PLUS)
3638 strcat (buf, ", v8+");
3639
3640 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3641 strcat (buf, ", ultrasparcI");
3642
3643 if (e_flags & EF_SPARC_SUN_US3)
3644 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3645
3646 if (e_flags & EF_SPARC_HAL_R1)
3647 strcat (buf, ", halr1");
3648
3649 if (e_flags & EF_SPARC_LEDATA)
3650 strcat (buf, ", ledata");
3651
3652 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3653 strcat (buf, ", tso");
3654
3655 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3656 strcat (buf, ", pso");
3657
3658 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3659 strcat (buf, ", rmo");
3660 break;
7d466069 3661
103f02d3
UD
3662 case EM_PARISC:
3663 switch (e_flags & EF_PARISC_ARCH)
3664 {
3665 case EFA_PARISC_1_0:
3666 strcpy (buf, ", PA-RISC 1.0");
3667 break;
3668 case EFA_PARISC_1_1:
3669 strcpy (buf, ", PA-RISC 1.1");
3670 break;
3671 case EFA_PARISC_2_0:
3672 strcpy (buf, ", PA-RISC 2.0");
3673 break;
3674 default:
3675 break;
3676 }
3677 if (e_flags & EF_PARISC_TRAPNIL)
3678 strcat (buf, ", trapnil");
3679 if (e_flags & EF_PARISC_EXT)
3680 strcat (buf, ", ext");
3681 if (e_flags & EF_PARISC_LSB)
3682 strcat (buf, ", lsb");
3683 if (e_flags & EF_PARISC_WIDE)
3684 strcat (buf, ", wide");
3685 if (e_flags & EF_PARISC_NO_KABP)
3686 strcat (buf, ", no kabp");
3687 if (e_flags & EF_PARISC_LAZYSWAP)
3688 strcat (buf, ", lazyswap");
30800947 3689 break;
76da6bbe 3690
7d466069 3691 case EM_PJ:
2b0337b0 3692 case EM_PJ_OLD:
7d466069
ILT
3693 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3694 strcat (buf, ", new calling convention");
3695
3696 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3697 strcat (buf, ", gnu calling convention");
3698 break;
4d6ed7c8
NC
3699
3700 case EM_IA_64:
3701 if ((e_flags & EF_IA_64_ABI64))
3702 strcat (buf, ", 64-bit");
3703 else
3704 strcat (buf, ", 32-bit");
3705 if ((e_flags & EF_IA_64_REDUCEDFP))
3706 strcat (buf, ", reduced fp model");
3707 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3708 strcat (buf, ", no function descriptors, constant gp");
3709 else if ((e_flags & EF_IA_64_CONS_GP))
3710 strcat (buf, ", constant gp");
3711 if ((e_flags & EF_IA_64_ABSOLUTE))
3712 strcat (buf, ", absolute");
dda8d76d 3713 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3714 {
3715 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3716 strcat (buf, ", vms_linkages");
3717 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3718 {
3719 case EF_IA_64_VMS_COMCOD_SUCCESS:
3720 break;
3721 case EF_IA_64_VMS_COMCOD_WARNING:
3722 strcat (buf, ", warning");
3723 break;
3724 case EF_IA_64_VMS_COMCOD_ERROR:
3725 strcat (buf, ", error");
3726 break;
3727 case EF_IA_64_VMS_COMCOD_ABORT:
3728 strcat (buf, ", abort");
3729 break;
3730 default:
bee0ee85
NC
3731 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3732 e_flags & EF_IA_64_VMS_COMCOD);
3733 strcat (buf, ", <unknown>");
28f997cf
TG
3734 }
3735 }
4d6ed7c8 3736 break;
179d3252
JT
3737
3738 case EM_VAX:
3739 if ((e_flags & EF_VAX_NONPIC))
3740 strcat (buf, ", non-PIC");
3741 if ((e_flags & EF_VAX_DFLOAT))
3742 strcat (buf, ", D-Float");
3743 if ((e_flags & EF_VAX_GFLOAT))
3744 strcat (buf, ", G-Float");
3745 break;
c7927a3c 3746
619ed720
EB
3747 case EM_VISIUM:
3748 if (e_flags & EF_VISIUM_ARCH_MCM)
3749 strcat (buf, ", mcm");
3750 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3751 strcat (buf, ", mcm24");
3752 if (e_flags & EF_VISIUM_ARCH_GR6)
3753 strcat (buf, ", gr6");
3754 break;
3755
4046d87a 3756 case EM_RL78:
1740ba0c
NC
3757 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3758 {
3759 case E_FLAG_RL78_ANY_CPU: break;
3760 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3761 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3762 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3763 }
856ea05c
KP
3764 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3765 strcat (buf, ", 64-bit doubles");
4046d87a 3766 break;
0b4362b0 3767
c7927a3c
NC
3768 case EM_RX:
3769 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3770 strcat (buf, ", 64-bit doubles");
3771 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3772 strcat (buf, ", dsp");
d4cb0ea0 3773 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3774 strcat (buf, ", pid");
708e2187
NC
3775 if (e_flags & E_FLAG_RX_ABI)
3776 strcat (buf, ", RX ABI");
3525236c
NC
3777 if (e_flags & E_FLAG_RX_SINSNS_SET)
3778 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3779 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3780 if (e_flags & E_FLAG_RX_V2)
3781 strcat (buf, ", V2");
f87673e0
YS
3782 if (e_flags & E_FLAG_RX_V3)
3783 strcat (buf, ", V3");
d4cb0ea0 3784 break;
55786da2
AK
3785
3786 case EM_S390:
3787 if (e_flags & EF_S390_HIGH_GPRS)
3788 strcat (buf, ", highgprs");
d4cb0ea0 3789 break;
40b36596
JM
3790
3791 case EM_TI_C6000:
3792 if ((e_flags & EF_C6000_REL))
3793 strcat (buf, ", relocatable module");
d4cb0ea0 3794 break;
13761a11
NC
3795
3796 case EM_MSP430:
3797 strcat (buf, _(": architecture variant: "));
3798 switch (e_flags & EF_MSP430_MACH)
3799 {
3800 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3801 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3802 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3803 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3804 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3805 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3806 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3807 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3808 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3809 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3810 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3811 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3812 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3813 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3814 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3815 default:
3816 strcat (buf, _(": unknown")); break;
3817 }
3818
3819 if (e_flags & ~ EF_MSP430_MACH)
3820 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
3821 break;
3822
3823 case EM_Z80:
3824 switch (e_flags & EF_Z80_MACH_MSK)
3825 {
3826 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
3827 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
3828 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
3829 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
3830 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
3831 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 3832 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
3833 default:
3834 strcat (buf, _(", unknown")); break;
3835 }
3836 break;
252b5132
RH
3837 }
3838 }
3839
3840 return buf;
3841}
3842
252b5132 3843static const char *
dda8d76d 3844get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3845{
3846 static char buff[32];
3847
3848 switch (osabi)
3849 {
3850 case ELFOSABI_NONE: return "UNIX - System V";
3851 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3852 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3853 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3854 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3855 case ELFOSABI_AIX: return "UNIX - AIX";
3856 case ELFOSABI_IRIX: return "UNIX - IRIX";
3857 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3858 case ELFOSABI_TRU64: return "UNIX - TRU64";
3859 case ELFOSABI_MODESTO: return "Novell - Modesto";
3860 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3861 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3862 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3863 case ELFOSABI_AROS: return "AROS";
11636f9e 3864 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3865 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3866 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3867 default:
40b36596 3868 if (osabi >= 64)
dda8d76d 3869 switch (filedata->file_header.e_machine)
40b36596
JM
3870 {
3871 case EM_ARM:
3872 switch (osabi)
3873 {
3874 case ELFOSABI_ARM: return "ARM";
18a20338 3875 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3876 default:
3877 break;
3878 }
3879 break;
3880
3881 case EM_MSP430:
3882 case EM_MSP430_OLD:
619ed720 3883 case EM_VISIUM:
40b36596
JM
3884 switch (osabi)
3885 {
3886 case ELFOSABI_STANDALONE: return _("Standalone App");
3887 default:
3888 break;
3889 }
3890 break;
3891
3892 case EM_TI_C6000:
3893 switch (osabi)
3894 {
3895 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3896 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3897 default:
3898 break;
3899 }
3900 break;
3901
3902 default:
3903 break;
3904 }
e9e44622 3905 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3906 return buff;
3907 }
3908}
3909
a06ea964
NC
3910static const char *
3911get_aarch64_segment_type (unsigned long type)
3912{
3913 switch (type)
3914 {
32ec8896
NC
3915 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3916 default: return NULL;
a06ea964 3917 }
a06ea964
NC
3918}
3919
b294bdf8
MM
3920static const char *
3921get_arm_segment_type (unsigned long type)
3922{
3923 switch (type)
3924 {
32ec8896
NC
3925 case PT_ARM_EXIDX: return "EXIDX";
3926 default: return NULL;
b294bdf8 3927 }
b294bdf8
MM
3928}
3929
b4cbbe8f
AK
3930static const char *
3931get_s390_segment_type (unsigned long type)
3932{
3933 switch (type)
3934 {
3935 case PT_S390_PGSTE: return "S390_PGSTE";
3936 default: return NULL;
3937 }
3938}
3939
d3ba0551
AM
3940static const char *
3941get_mips_segment_type (unsigned long type)
252b5132
RH
3942{
3943 switch (type)
3944 {
32ec8896
NC
3945 case PT_MIPS_REGINFO: return "REGINFO";
3946 case PT_MIPS_RTPROC: return "RTPROC";
3947 case PT_MIPS_OPTIONS: return "OPTIONS";
3948 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3949 default: return NULL;
252b5132 3950 }
252b5132
RH
3951}
3952
103f02d3 3953static const char *
d3ba0551 3954get_parisc_segment_type (unsigned long type)
103f02d3
UD
3955{
3956 switch (type)
3957 {
103f02d3
UD
3958 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3959 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3960 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3961 default: return NULL;
103f02d3 3962 }
103f02d3
UD
3963}
3964
4d6ed7c8 3965static const char *
d3ba0551 3966get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3967{
3968 switch (type)
3969 {
3970 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3971 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 3972 default: return NULL;
4d6ed7c8 3973 }
4d6ed7c8
NC
3974}
3975
40b36596
JM
3976static const char *
3977get_tic6x_segment_type (unsigned long type)
3978{
3979 switch (type)
3980 {
32ec8896
NC
3981 case PT_C6000_PHATTR: return "C6000_PHATTR";
3982 default: return NULL;
40b36596 3983 }
40b36596
JM
3984}
3985
df3a023b
AM
3986static const char *
3987get_hpux_segment_type (unsigned long type, unsigned e_machine)
3988{
3989 if (e_machine == EM_PARISC)
3990 switch (type)
3991 {
3992 case PT_HP_TLS: return "HP_TLS";
3993 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3994 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3995 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3996 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3997 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3998 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3999 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4000 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4001 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4002 case PT_HP_PARALLEL: return "HP_PARALLEL";
4003 case PT_HP_FASTBIND: return "HP_FASTBIND";
4004 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4005 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4006 case PT_HP_STACK: return "HP_STACK";
4007 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4008 default: return NULL;
4009 }
4010
4011 if (e_machine == EM_IA_64)
4012 switch (type)
4013 {
4014 case PT_HP_TLS: return "HP_TLS";
4015 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4016 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4017 case PT_IA_64_HP_STACK: return "HP_STACK";
4018 default: return NULL;
4019 }
4020
4021 return NULL;
4022}
4023
5522f910
NC
4024static const char *
4025get_solaris_segment_type (unsigned long type)
4026{
4027 switch (type)
4028 {
4029 case 0x6464e550: return "PT_SUNW_UNWIND";
4030 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4031 case 0x6ffffff7: return "PT_LOSUNW";
4032 case 0x6ffffffa: return "PT_SUNWBSS";
4033 case 0x6ffffffb: return "PT_SUNWSTACK";
4034 case 0x6ffffffc: return "PT_SUNWDTRACE";
4035 case 0x6ffffffd: return "PT_SUNWCAP";
4036 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4037 default: return NULL;
5522f910
NC
4038 }
4039}
4040
252b5132 4041static const char *
dda8d76d 4042get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4043{
b34976b6 4044 static char buff[32];
252b5132
RH
4045
4046 switch (p_type)
4047 {
b34976b6
AM
4048 case PT_NULL: return "NULL";
4049 case PT_LOAD: return "LOAD";
252b5132 4050 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4051 case PT_INTERP: return "INTERP";
4052 case PT_NOTE: return "NOTE";
4053 case PT_SHLIB: return "SHLIB";
4054 case PT_PHDR: return "PHDR";
13ae64f3 4055 case PT_TLS: return "TLS";
32ec8896 4056 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4057 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4058 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4059 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4060
3eba3ef3
NC
4061 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4062 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4063 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4064
252b5132 4065 default:
df3a023b 4066 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4067 {
2cf0635d 4068 const char * result;
103f02d3 4069
dda8d76d 4070 switch (filedata->file_header.e_machine)
252b5132 4071 {
a06ea964
NC
4072 case EM_AARCH64:
4073 result = get_aarch64_segment_type (p_type);
4074 break;
b294bdf8
MM
4075 case EM_ARM:
4076 result = get_arm_segment_type (p_type);
4077 break;
252b5132 4078 case EM_MIPS:
4fe85591 4079 case EM_MIPS_RS3_LE:
252b5132
RH
4080 result = get_mips_segment_type (p_type);
4081 break;
103f02d3
UD
4082 case EM_PARISC:
4083 result = get_parisc_segment_type (p_type);
4084 break;
4d6ed7c8
NC
4085 case EM_IA_64:
4086 result = get_ia64_segment_type (p_type);
4087 break;
40b36596
JM
4088 case EM_TI_C6000:
4089 result = get_tic6x_segment_type (p_type);
4090 break;
b4cbbe8f
AK
4091 case EM_S390:
4092 case EM_S390_OLD:
4093 result = get_s390_segment_type (p_type);
4094 break;
252b5132
RH
4095 default:
4096 result = NULL;
4097 break;
4098 }
103f02d3 4099
252b5132
RH
4100 if (result != NULL)
4101 return result;
103f02d3 4102
1a9ccd70 4103 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4104 }
4105 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4106 {
df3a023b 4107 const char * result = NULL;
103f02d3 4108
df3a023b 4109 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4110 {
df3a023b
AM
4111 case ELFOSABI_GNU:
4112 case ELFOSABI_FREEBSD:
4113 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4114 {
4115 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4116 result = buff;
4117 }
103f02d3 4118 break;
df3a023b
AM
4119 case ELFOSABI_HPUX:
4120 result = get_hpux_segment_type (p_type,
4121 filedata->file_header.e_machine);
4122 break;
4123 case ELFOSABI_SOLARIS:
4124 result = get_solaris_segment_type (p_type);
00428cca 4125 break;
103f02d3 4126 default:
103f02d3
UD
4127 break;
4128 }
103f02d3
UD
4129 if (result != NULL)
4130 return result;
4131
1a9ccd70 4132 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4133 }
252b5132 4134 else
e9e44622 4135 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4136
4137 return buff;
4138 }
4139}
4140
53a346d8
CZ
4141static const char *
4142get_arc_section_type_name (unsigned int sh_type)
4143{
4144 switch (sh_type)
4145 {
4146 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4147 default:
4148 break;
4149 }
4150 return NULL;
4151}
4152
252b5132 4153static const char *
d3ba0551 4154get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4155{
4156 switch (sh_type)
4157 {
b34976b6
AM
4158 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4159 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4160 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4161 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4162 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4163 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4164 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4165 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4166 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4167 case SHT_MIPS_RELD: return "MIPS_RELD";
4168 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4169 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4170 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4171 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4172 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4173 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4174 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4175 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4176 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4177 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4178 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4179 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4180 case SHT_MIPS_LINE: return "MIPS_LINE";
4181 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4182 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4183 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4184 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4185 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4186 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4187 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4188 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4189 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4190 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4191 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4192 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4193 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4194 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4195 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4196 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4197 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4198 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4199 default:
4200 break;
4201 }
4202 return NULL;
4203}
4204
103f02d3 4205static const char *
d3ba0551 4206get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4207{
4208 switch (sh_type)
4209 {
4210 case SHT_PARISC_EXT: return "PARISC_EXT";
4211 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4212 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4213 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4214 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4215 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4216 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4217 default: return NULL;
103f02d3 4218 }
103f02d3
UD
4219}
4220
4d6ed7c8 4221static const char *
dda8d76d 4222get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4223{
18bd398b 4224 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4225 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4226 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4227
4d6ed7c8
NC
4228 switch (sh_type)
4229 {
148b93f2
NC
4230 case SHT_IA_64_EXT: return "IA_64_EXT";
4231 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4232 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4233 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4234 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4235 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4236 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4237 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4238 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4239 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4240 default:
4241 break;
4242 }
4243 return NULL;
4244}
4245
d2b2c203
DJ
4246static const char *
4247get_x86_64_section_type_name (unsigned int sh_type)
4248{
4249 switch (sh_type)
4250 {
4251 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4252 default: return NULL;
d2b2c203 4253 }
d2b2c203
DJ
4254}
4255
a06ea964
NC
4256static const char *
4257get_aarch64_section_type_name (unsigned int sh_type)
4258{
4259 switch (sh_type)
4260 {
32ec8896
NC
4261 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4262 default: return NULL;
a06ea964 4263 }
a06ea964
NC
4264}
4265
40a18ebd
NC
4266static const char *
4267get_arm_section_type_name (unsigned int sh_type)
4268{
4269 switch (sh_type)
4270 {
7f6fed87
NC
4271 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4272 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4273 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4274 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4275 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4276 default: return NULL;
40a18ebd 4277 }
40a18ebd
NC
4278}
4279
40b36596
JM
4280static const char *
4281get_tic6x_section_type_name (unsigned int sh_type)
4282{
4283 switch (sh_type)
4284 {
32ec8896
NC
4285 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4286 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4287 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4288 case SHT_TI_ICODE: return "TI_ICODE";
4289 case SHT_TI_XREF: return "TI_XREF";
4290 case SHT_TI_HANDLER: return "TI_HANDLER";
4291 case SHT_TI_INITINFO: return "TI_INITINFO";
4292 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4293 default: return NULL;
40b36596 4294 }
40b36596
JM
4295}
4296
13761a11 4297static const char *
b0191216 4298get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4299{
4300 switch (sh_type)
4301 {
32ec8896
NC
4302 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4303 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4304 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4305 default: return NULL;
13761a11
NC
4306 }
4307}
4308
fe944acf
FT
4309static const char *
4310get_nfp_section_type_name (unsigned int sh_type)
4311{
4312 switch (sh_type)
4313 {
4314 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4315 case SHT_NFP_INITREG: return "NFP_INITREG";
4316 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4317 default: return NULL;
4318 }
4319}
4320
685080f2
NC
4321static const char *
4322get_v850_section_type_name (unsigned int sh_type)
4323{
4324 switch (sh_type)
4325 {
32ec8896
NC
4326 case SHT_V850_SCOMMON: return "V850 Small Common";
4327 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4328 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4329 case SHT_RENESAS_IOP: return "RENESAS IOP";
4330 case SHT_RENESAS_INFO: return "RENESAS INFO";
4331 default: return NULL;
685080f2
NC
4332 }
4333}
4334
2dc8dd17
JW
4335static const char *
4336get_riscv_section_type_name (unsigned int sh_type)
4337{
4338 switch (sh_type)
4339 {
4340 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4341 default: return NULL;
4342 }
4343}
4344
0861f561
CQ
4345static const char *
4346get_csky_section_type_name (unsigned int sh_type)
4347{
4348 switch (sh_type)
4349 {
4350 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4351 default: return NULL;
4352 }
4353}
4354
252b5132 4355static const char *
dda8d76d 4356get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4357{
b34976b6 4358 static char buff[32];
9fb71ee4 4359 const char * result;
252b5132
RH
4360
4361 switch (sh_type)
4362 {
4363 case SHT_NULL: return "NULL";
4364 case SHT_PROGBITS: return "PROGBITS";
4365 case SHT_SYMTAB: return "SYMTAB";
4366 case SHT_STRTAB: return "STRTAB";
4367 case SHT_RELA: return "RELA";
4368 case SHT_HASH: return "HASH";
4369 case SHT_DYNAMIC: return "DYNAMIC";
4370 case SHT_NOTE: return "NOTE";
4371 case SHT_NOBITS: return "NOBITS";
4372 case SHT_REL: return "REL";
4373 case SHT_SHLIB: return "SHLIB";
4374 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4375 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4376 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4377 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4378 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4379 case SHT_GROUP: return "GROUP";
67ce483b 4380 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4381 case SHT_GNU_verdef: return "VERDEF";
4382 case SHT_GNU_verneed: return "VERNEED";
4383 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4384 case 0x6ffffff0: return "VERSYM";
4385 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4386 case 0x7ffffffd: return "AUXILIARY";
4387 case 0x7fffffff: return "FILTER";
047b2264 4388 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4389
4390 default:
4391 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4392 {
dda8d76d 4393 switch (filedata->file_header.e_machine)
252b5132 4394 {
53a346d8
CZ
4395 case EM_ARC:
4396 case EM_ARC_COMPACT:
4397 case EM_ARC_COMPACT2:
4398 result = get_arc_section_type_name (sh_type);
4399 break;
252b5132 4400 case EM_MIPS:
4fe85591 4401 case EM_MIPS_RS3_LE:
252b5132
RH
4402 result = get_mips_section_type_name (sh_type);
4403 break;
103f02d3
UD
4404 case EM_PARISC:
4405 result = get_parisc_section_type_name (sh_type);
4406 break;
4d6ed7c8 4407 case EM_IA_64:
dda8d76d 4408 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4409 break;
d2b2c203 4410 case EM_X86_64:
8a9036a4 4411 case EM_L1OM:
7a9068fe 4412 case EM_K1OM:
d2b2c203
DJ
4413 result = get_x86_64_section_type_name (sh_type);
4414 break;
a06ea964
NC
4415 case EM_AARCH64:
4416 result = get_aarch64_section_type_name (sh_type);
4417 break;
40a18ebd
NC
4418 case EM_ARM:
4419 result = get_arm_section_type_name (sh_type);
4420 break;
40b36596
JM
4421 case EM_TI_C6000:
4422 result = get_tic6x_section_type_name (sh_type);
4423 break;
13761a11 4424 case EM_MSP430:
b0191216 4425 result = get_msp430_section_type_name (sh_type);
13761a11 4426 break;
fe944acf
FT
4427 case EM_NFP:
4428 result = get_nfp_section_type_name (sh_type);
4429 break;
685080f2
NC
4430 case EM_V800:
4431 case EM_V850:
4432 case EM_CYGNUS_V850:
4433 result = get_v850_section_type_name (sh_type);
4434 break;
2dc8dd17
JW
4435 case EM_RISCV:
4436 result = get_riscv_section_type_name (sh_type);
4437 break;
0861f561
CQ
4438 case EM_CSKY:
4439 result = get_csky_section_type_name (sh_type);
4440 break;
252b5132
RH
4441 default:
4442 result = NULL;
4443 break;
4444 }
4445
4446 if (result != NULL)
4447 return result;
4448
9fb71ee4 4449 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4450 }
4451 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4452 {
dda8d76d 4453 switch (filedata->file_header.e_machine)
148b93f2
NC
4454 {
4455 case EM_IA_64:
dda8d76d 4456 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4457 break;
4458 default:
dda8d76d 4459 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4460 result = get_solaris_section_type (sh_type);
4461 else
1b4b80bf
NC
4462 {
4463 switch (sh_type)
4464 {
4465 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4466 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4467 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4468 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4469 default:
4470 result = NULL;
4471 break;
4472 }
4473 }
148b93f2
NC
4474 break;
4475 }
4476
4477 if (result != NULL)
4478 return result;
4479
9fb71ee4 4480 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4481 }
252b5132 4482 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4483 {
dda8d76d 4484 switch (filedata->file_header.e_machine)
685080f2
NC
4485 {
4486 case EM_V800:
4487 case EM_V850:
4488 case EM_CYGNUS_V850:
9fb71ee4 4489 result = get_v850_section_type_name (sh_type);
a9fb83be 4490 break;
685080f2 4491 default:
9fb71ee4 4492 result = NULL;
685080f2
NC
4493 break;
4494 }
4495
9fb71ee4
NC
4496 if (result != NULL)
4497 return result;
4498
4499 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4500 }
252b5132 4501 else
a7dbfd1c
NC
4502 /* This message is probably going to be displayed in a 15
4503 character wide field, so put the hex value first. */
4504 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4505
252b5132
RH
4506 return buff;
4507 }
4508}
4509
79bc120c
NC
4510enum long_option_values
4511{
4512 OPTION_DEBUG_DUMP = 512,
4513 OPTION_DYN_SYMS,
0f03783c 4514 OPTION_LTO_SYMS,
79bc120c
NC
4515 OPTION_DWARF_DEPTH,
4516 OPTION_DWARF_START,
4517 OPTION_DWARF_CHECK,
4518 OPTION_CTF_DUMP,
4519 OPTION_CTF_PARENT,
4520 OPTION_CTF_SYMBOLS,
4521 OPTION_CTF_STRINGS,
4522 OPTION_WITH_SYMBOL_VERSIONS,
4523 OPTION_RECURSE_LIMIT,
4524 OPTION_NO_RECURSE_LIMIT,
4525 OPTION_NO_DEMANGLING
4526};
2979dc34 4527
85b1c36d 4528static struct option options[] =
252b5132 4529{
79bc120c
NC
4530 /* Note - This table is alpha-sorted on the 'val'
4531 field in order to make adding new options easier. */
4532 {"arch-specific", no_argument, 0, 'A'},
b34976b6 4533 {"all", no_argument, 0, 'a'},
79bc120c
NC
4534 {"demangle", optional_argument, 0, 'C'},
4535 {"archive-index", no_argument, 0, 'c'},
4536 {"use-dynamic", no_argument, 0, 'D'},
4537 {"dynamic", no_argument, 0, 'd'},
b34976b6 4538 {"headers", no_argument, 0, 'e'},
79bc120c
NC
4539 {"section-groups", no_argument, 0, 'g'},
4540 {"help", no_argument, 0, 'H'},
4541 {"file-header", no_argument, 0, 'h'},
b34976b6 4542 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
4543 {"lint", no_argument, 0, 'L'},
4544 {"enable-checks", no_argument, 0, 'L'},
4545 {"program-headers", no_argument, 0, 'l'},
b34976b6 4546 {"segments", no_argument, 0, 'l'},
595cf52e 4547 {"full-section-name",no_argument, 0, 'N'},
79bc120c
NC
4548 {"notes", no_argument, 0, 'n'},
4549 {"string-dump", required_argument, 0, 'p'},
4550 {"relocated-dump", required_argument, 0, 'R'},
4551 {"relocs", no_argument, 0, 'r'},
4552 {"section-headers", no_argument, 0, 'S'},
4553 {"sections", no_argument, 0, 'S'},
b34976b6
AM
4554 {"symbols", no_argument, 0, 's'},
4555 {"syms", no_argument, 0, 's'},
79bc120c
NC
4556 {"silent-truncation",no_argument, 0, 'T'},
4557 {"section-details", no_argument, 0, 't'},
09c11c86 4558 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
4559 {"version-info", no_argument, 0, 'V'},
4560 {"version", no_argument, 0, 'v'},
4561 {"wide", no_argument, 0, 'W'},
b34976b6 4562 {"hex-dump", required_argument, 0, 'x'},
0e602686 4563 {"decompress", no_argument, 0, 'z'},
252b5132 4564
79bc120c
NC
4565 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
4566 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
4567 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4568 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4569 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 4570 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 4571 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
4572 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4573 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4574 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 4575#ifdef ENABLE_LIBCTF
d344b407 4576 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
4577 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
4578 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
4579 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 4580#endif
7d9813f1 4581
b34976b6 4582 {0, no_argument, 0, 0}
252b5132
RH
4583};
4584
4585static void
2cf0635d 4586usage (FILE * stream)
252b5132 4587{
92f01d61
JM
4588 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4589 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4590 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4591 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4592 -h --file-header Display the ELF file header\n\
4593 -l --program-headers Display the program headers\n\
4594 --segments An alias for --program-headers\n\
4595 -S --section-headers Display the sections' header\n\
4596 --sections An alias for --section-headers\n\
f5842774 4597 -g --section-groups Display the section groups\n\
5477e8a0 4598 -t --section-details Display the section details\n\
8b53311e
NC
4599 -e --headers Equivalent to: -h -l -S\n\
4600 -s --syms Display the symbol table\n\
3f08eb35 4601 --symbols An alias for --syms\n\
1b513401 4602 --dyn-syms Display the dynamic symbol table\n\
0f03783c 4603 --lto-syms Display LTO symbol tables\n\
79bc120c
NC
4604 -C --demangle[=STYLE] Decode low-level symbol names into user-level names\n\
4605 The STYLE, if specified, can be `auto' (the default),\n\
4606 `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
4607 or `gnat'\n\
4608 --no-demangle Do not demangle low-level symbol names. (This is the default)\n\
4609 --recurse-limit Enable a demangling recursion limit. (This is the default)\n\
4610 --no-recurse-limit Disable a demangling recursion limit\n\
8b53311e
NC
4611 -n --notes Display the core notes (if present)\n\
4612 -r --relocs Display the relocations (if present)\n\
4613 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4614 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4615 -V --version-info Display the version sections (if present)\n\
1b31d05e 4616 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4617 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4618 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
1b513401 4619 -L --lint|--enable-checks Display warning messages for possible problems\n\
09c11c86
NC
4620 -x --hex-dump=<number|name>\n\
4621 Dump the contents of section <number|name> as bytes\n\
4622 -p --string-dump=<number|name>\n\
4623 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4624 -R --relocated-dump=<number|name>\n\
4625 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4626 -z --decompress Decompress section before dumping it\n\
c46b7066 4627 -w[lLiaprmfFsoORtUuTgAck] or\n\
1ed06042 4628 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
e4b7104b 4629 =frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,\n\
657d0d47 4630 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
c46b7066 4631 =addr,=cu_index,=links]\n\
dda8d76d 4632 Display the contents of DWARF debug sections\n"));
c46b7066
NC
4633#if DEFAULT_FOR_FOLLOW_LINKS
4634 fprintf (stream, _("\
4635 -wK,--debug-dump=follow-links Follow links to separate debug info files (default)\n\
4636 -wN,--debug-dump=no-follow-links Do not follow links to separate debug info files\n\
4637"));
4638#else
4639 fprintf (stream, _("\
4640 -wK,--debug-dump=follow-links Follow links to separate debug info files\n\
4641 -wN,--debug-dump=no-follow-links Do not follow links to separate debug info files (default)\n\
4642"));
4643#endif
fd2f0033
TT
4644 fprintf (stream, _("\
4645 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4646 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4647 or deeper\n"));
094e34f2 4648#ifdef ENABLE_LIBCTF
7d9813f1
NA
4649 fprintf (stream, _("\
4650 --ctf=<number|name> Display CTF info from section <number|name>\n\
4651 --ctf-parent=<number|name>\n\
4652 Use section <number|name> as the CTF parent\n\n\
4653 --ctf-symbols=<number|name>\n\
4654 Use section <number|name> as the CTF external symtab\n\n\
4655 --ctf-strings=<number|name>\n\
4656 Use section <number|name> as the CTF external strtab\n\n"));
094e34f2 4657#endif
7d9813f1 4658
252b5132 4659#ifdef SUPPORT_DISASSEMBLY
92f01d61 4660 fprintf (stream, _("\
09c11c86
NC
4661 -i --instruction-dump=<number|name>\n\
4662 Disassemble the contents of section <number|name>\n"));
252b5132 4663#endif
92f01d61 4664 fprintf (stream, _("\
8b53311e
NC
4665 -I --histogram Display histogram of bucket list lengths\n\
4666 -W --wide Allow output width to exceed 80 characters\n\
0942c7ab 4667 -T --silent-truncation If a symbol name is truncated, do not add a suffix [...]\n\
07012eee 4668 @<file> Read options from <file>\n\
8b53311e
NC
4669 -H --help Display this information\n\
4670 -v --version Display the version number of readelf\n"));
1118d252 4671
92f01d61
JM
4672 if (REPORT_BUGS_TO[0] && stream == stdout)
4673 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4674
92f01d61 4675 exit (stream == stdout ? 0 : 1);
252b5132
RH
4676}
4677
18bd398b
NC
4678/* Record the fact that the user wants the contents of section number
4679 SECTION to be displayed using the method(s) encoded as flags bits
4680 in TYPE. Note, TYPE can be zero if we are creating the array for
4681 the first time. */
4682
252b5132 4683static void
6431e409
AM
4684request_dump_bynumber (struct dump_data *dumpdata,
4685 unsigned int section, dump_type type)
252b5132 4686{
6431e409 4687 if (section >= dumpdata->num_dump_sects)
252b5132 4688 {
2cf0635d 4689 dump_type * new_dump_sects;
252b5132 4690
3f5e193b 4691 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4692 sizeof (* new_dump_sects));
252b5132
RH
4693
4694 if (new_dump_sects == NULL)
591a748a 4695 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4696 else
4697 {
6431e409 4698 if (dumpdata->dump_sects)
21b65bac
NC
4699 {
4700 /* Copy current flag settings. */
6431e409
AM
4701 memcpy (new_dump_sects, dumpdata->dump_sects,
4702 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4703
6431e409 4704 free (dumpdata->dump_sects);
21b65bac 4705 }
252b5132 4706
6431e409
AM
4707 dumpdata->dump_sects = new_dump_sects;
4708 dumpdata->num_dump_sects = section + 1;
252b5132
RH
4709 }
4710 }
4711
6431e409
AM
4712 if (dumpdata->dump_sects)
4713 dumpdata->dump_sects[section] |= type;
252b5132
RH
4714}
4715
aef1f6d0
DJ
4716/* Request a dump by section name. */
4717
4718static void
2cf0635d 4719request_dump_byname (const char * section, dump_type type)
aef1f6d0 4720{
2cf0635d 4721 struct dump_list_entry * new_request;
aef1f6d0 4722
3f5e193b
NC
4723 new_request = (struct dump_list_entry *)
4724 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4725 if (!new_request)
591a748a 4726 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4727
4728 new_request->name = strdup (section);
4729 if (!new_request->name)
591a748a 4730 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4731
4732 new_request->type = type;
4733
4734 new_request->next = dump_sects_byname;
4735 dump_sects_byname = new_request;
4736}
4737
cf13d699 4738static inline void
6431e409 4739request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
4740{
4741 int section;
4742 char * cp;
4743
4744 do_dump++;
4745 section = strtoul (optarg, & cp, 0);
4746
4747 if (! *cp && section >= 0)
6431e409 4748 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
4749 else
4750 request_dump_byname (optarg, type);
4751}
4752
252b5132 4753static void
6431e409 4754parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
4755{
4756 int c;
4757
4758 if (argc < 2)
92f01d61 4759 usage (stderr);
252b5132
RH
4760
4761 while ((c = getopt_long
79bc120c 4762 (argc, argv, "ACDHILNR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4763 {
252b5132
RH
4764 switch (c)
4765 {
4766 case 0:
4767 /* Long options. */
4768 break;
4769 case 'H':
92f01d61 4770 usage (stdout);
252b5132
RH
4771 break;
4772
4773 case 'a':
32ec8896
NC
4774 do_syms = TRUE;
4775 do_reloc = TRUE;
4776 do_unwind = TRUE;
4777 do_dynamic = TRUE;
4778 do_header = TRUE;
4779 do_sections = TRUE;
4780 do_section_groups = TRUE;
4781 do_segments = TRUE;
4782 do_version = TRUE;
4783 do_histogram = TRUE;
4784 do_arch = TRUE;
4785 do_notes = TRUE;
252b5132 4786 break;
79bc120c 4787
f5842774 4788 case 'g':
32ec8896 4789 do_section_groups = TRUE;
f5842774 4790 break;
5477e8a0 4791 case 't':
595cf52e 4792 case 'N':
32ec8896
NC
4793 do_sections = TRUE;
4794 do_section_details = TRUE;
595cf52e 4795 break;
252b5132 4796 case 'e':
32ec8896
NC
4797 do_header = TRUE;
4798 do_sections = TRUE;
4799 do_segments = TRUE;
252b5132 4800 break;
a952a375 4801 case 'A':
32ec8896 4802 do_arch = TRUE;
a952a375 4803 break;
252b5132 4804 case 'D':
32ec8896 4805 do_using_dynamic = TRUE;
252b5132
RH
4806 break;
4807 case 'r':
32ec8896 4808 do_reloc = TRUE;
252b5132 4809 break;
4d6ed7c8 4810 case 'u':
32ec8896 4811 do_unwind = TRUE;
4d6ed7c8 4812 break;
252b5132 4813 case 'h':
32ec8896 4814 do_header = TRUE;
252b5132
RH
4815 break;
4816 case 'l':
32ec8896 4817 do_segments = TRUE;
252b5132
RH
4818 break;
4819 case 's':
32ec8896 4820 do_syms = TRUE;
252b5132
RH
4821 break;
4822 case 'S':
32ec8896 4823 do_sections = TRUE;
252b5132
RH
4824 break;
4825 case 'd':
32ec8896 4826 do_dynamic = TRUE;
252b5132 4827 break;
a952a375 4828 case 'I':
32ec8896 4829 do_histogram = TRUE;
a952a375 4830 break;
779fe533 4831 case 'n':
32ec8896 4832 do_notes = TRUE;
779fe533 4833 break;
4145f1d5 4834 case 'c':
32ec8896 4835 do_archive_index = TRUE;
4145f1d5 4836 break;
1b513401
NC
4837 case 'L':
4838 do_checks = TRUE;
4839 break;
252b5132 4840 case 'x':
6431e409 4841 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 4842 break;
09c11c86 4843 case 'p':
6431e409 4844 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
4845 break;
4846 case 'R':
6431e409 4847 request_dump (dumpdata, RELOC_DUMP);
09c11c86 4848 break;
0e602686 4849 case 'z':
32ec8896 4850 decompress_dumps = TRUE;
0e602686 4851 break;
252b5132 4852 case 'w':
32ec8896 4853 do_dump = TRUE;
0f03783c 4854 if (optarg == NULL)
613ff48b 4855 {
32ec8896 4856 do_debugging = TRUE;
613ff48b
CC
4857 dwarf_select_sections_all ();
4858 }
252b5132
RH
4859 else
4860 {
32ec8896 4861 do_debugging = FALSE;
4cb93e3b 4862 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4863 }
4864 break;
2979dc34 4865 case OPTION_DEBUG_DUMP:
32ec8896 4866 do_dump = TRUE;
0f03783c 4867 if (optarg == NULL)
32ec8896 4868 do_debugging = TRUE;
2979dc34
JJ
4869 else
4870 {
32ec8896 4871 do_debugging = FALSE;
4cb93e3b 4872 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4873 }
4874 break;
fd2f0033
TT
4875 case OPTION_DWARF_DEPTH:
4876 {
4877 char *cp;
4878
4879 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4880 }
4881 break;
4882 case OPTION_DWARF_START:
4883 {
4884 char *cp;
4885
4886 dwarf_start_die = strtoul (optarg, & cp, 0);
4887 }
4888 break;
4723351a 4889 case OPTION_DWARF_CHECK:
32ec8896 4890 dwarf_check = TRUE;
4723351a 4891 break;
7d9813f1
NA
4892 case OPTION_CTF_DUMP:
4893 do_ctf = TRUE;
6431e409 4894 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
4895 break;
4896 case OPTION_CTF_SYMBOLS:
df16e041 4897 free (dump_ctf_symtab_name);
7d9813f1
NA
4898 dump_ctf_symtab_name = strdup (optarg);
4899 break;
4900 case OPTION_CTF_STRINGS:
df16e041 4901 free (dump_ctf_strtab_name);
7d9813f1
NA
4902 dump_ctf_strtab_name = strdup (optarg);
4903 break;
4904 case OPTION_CTF_PARENT:
df16e041 4905 free (dump_ctf_parent_name);
7d9813f1
NA
4906 dump_ctf_parent_name = strdup (optarg);
4907 break;
2c610e4b 4908 case OPTION_DYN_SYMS:
32ec8896 4909 do_dyn_syms = TRUE;
2c610e4b 4910 break;
0f03783c
NC
4911 case OPTION_LTO_SYMS:
4912 do_lto_syms = TRUE;
4913 break;
252b5132
RH
4914#ifdef SUPPORT_DISASSEMBLY
4915 case 'i':
6431e409 4916 request_dump (dumpdata, DISASS_DUMP);
cf13d699 4917 break;
252b5132
RH
4918#endif
4919 case 'v':
4920 print_version (program_name);
4921 break;
4922 case 'V':
32ec8896 4923 do_version = TRUE;
252b5132 4924 break;
d974e256 4925 case 'W':
32ec8896 4926 do_wide = TRUE;
d974e256 4927 break;
0942c7ab
NC
4928 case 'T':
4929 do_not_show_symbol_truncation = TRUE;
4930 break;
79bc120c
NC
4931 case 'C':
4932 do_demangle = TRUE;
4933 if (optarg != NULL)
4934 {
4935 enum demangling_styles style;
4936
4937 style = cplus_demangle_name_to_style (optarg);
4938 if (style == unknown_demangling)
4939 error (_("unknown demangling style `%s'"), optarg);
4940
4941 cplus_demangle_set_style (style);
4942 }
4943 break;
4944 case OPTION_NO_DEMANGLING:
4945 do_demangle = FALSE;
4946 break;
4947 case OPTION_RECURSE_LIMIT:
4948 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
4949 break;
4950 case OPTION_NO_RECURSE_LIMIT:
4951 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
4952 break;
4953 case OPTION_WITH_SYMBOL_VERSIONS:
4954 /* Ignored for backward compatibility. */
4955 break;
b9e920ec 4956
252b5132 4957 default:
252b5132
RH
4958 /* xgettext:c-format */
4959 error (_("Invalid option '-%c'\n"), c);
1a0670f3 4960 /* Fall through. */
252b5132 4961 case '?':
92f01d61 4962 usage (stderr);
252b5132
RH
4963 }
4964 }
4965
4d6ed7c8 4966 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4967 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4968 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 4969 && !do_section_groups && !do_archive_index
0f03783c 4970 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
4971 {
4972 if (do_checks)
4973 {
4974 check_all = TRUE;
4975 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = TRUE;
4976 do_segments = do_header = do_dump = do_version = TRUE;
4977 do_histogram = do_debugging = do_arch = do_notes = TRUE;
4978 do_section_groups = do_archive_index = do_dyn_syms = TRUE;
0f03783c 4979 do_lto_syms = TRUE;
1b513401
NC
4980 }
4981 else
4982 usage (stderr);
4983 }
252b5132
RH
4984}
4985
4986static const char *
d3ba0551 4987get_elf_class (unsigned int elf_class)
252b5132 4988{
b34976b6 4989 static char buff[32];
103f02d3 4990
252b5132
RH
4991 switch (elf_class)
4992 {
4993 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4994 case ELFCLASS32: return "ELF32";
4995 case ELFCLASS64: return "ELF64";
ab5e7794 4996 default:
e9e44622 4997 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4998 return buff;
252b5132
RH
4999 }
5000}
5001
5002static const char *
d3ba0551 5003get_data_encoding (unsigned int encoding)
252b5132 5004{
b34976b6 5005 static char buff[32];
103f02d3 5006
252b5132
RH
5007 switch (encoding)
5008 {
5009 case ELFDATANONE: return _("none");
33c63f9d
CM
5010 case ELFDATA2LSB: return _("2's complement, little endian");
5011 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5012 default:
e9e44622 5013 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5014 return buff;
252b5132
RH
5015 }
5016}
5017
dda8d76d 5018/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5019
32ec8896 5020static bfd_boolean
dda8d76d 5021process_file_header (Filedata * filedata)
252b5132 5022{
dda8d76d
NC
5023 Elf_Internal_Ehdr * header = & filedata->file_header;
5024
5025 if ( header->e_ident[EI_MAG0] != ELFMAG0
5026 || header->e_ident[EI_MAG1] != ELFMAG1
5027 || header->e_ident[EI_MAG2] != ELFMAG2
5028 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5029 {
5030 error
5031 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
32ec8896 5032 return FALSE;
252b5132
RH
5033 }
5034
955ff7fc 5035 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5036
252b5132
RH
5037 if (do_header)
5038 {
32ec8896 5039 unsigned i;
252b5132
RH
5040
5041 printf (_("ELF Header:\n"));
5042 printf (_(" Magic: "));
b34976b6 5043 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5044 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5045 printf ("\n");
5046 printf (_(" Class: %s\n"),
dda8d76d 5047 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5048 printf (_(" Data: %s\n"),
dda8d76d 5049 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5050 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5051 header->e_ident[EI_VERSION],
5052 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5053 ? _(" (current)")
dda8d76d 5054 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5055 ? _(" <unknown>")
789be9f7 5056 : "")));
252b5132 5057 printf (_(" OS/ABI: %s\n"),
dda8d76d 5058 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5059 printf (_(" ABI Version: %d\n"),
dda8d76d 5060 header->e_ident[EI_ABIVERSION]);
252b5132 5061 printf (_(" Type: %s\n"),
dda8d76d 5062 get_file_type (header->e_type));
252b5132 5063 printf (_(" Machine: %s\n"),
dda8d76d 5064 get_machine_name (header->e_machine));
252b5132 5065 printf (_(" Version: 0x%lx\n"),
e8a64888 5066 header->e_version);
76da6bbe 5067
f7a99963 5068 printf (_(" Entry point address: "));
e8a64888 5069 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5070 printf (_("\n Start of program headers: "));
e8a64888 5071 print_vma (header->e_phoff, DEC);
f7a99963 5072 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5073 print_vma (header->e_shoff, DEC);
f7a99963 5074 printf (_(" (bytes into file)\n"));
76da6bbe 5075
252b5132 5076 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5077 header->e_flags,
dda8d76d 5078 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5079 printf (_(" Size of this header: %u (bytes)\n"),
5080 header->e_ehsize);
5081 printf (_(" Size of program headers: %u (bytes)\n"),
5082 header->e_phentsize);
5083 printf (_(" Number of program headers: %u"),
5084 header->e_phnum);
dda8d76d
NC
5085 if (filedata->section_headers != NULL
5086 && header->e_phnum == PN_XNUM
5087 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
5088 {
5089 header->e_phnum = filedata->section_headers[0].sh_info;
5090 printf (" (%u)", header->e_phnum);
5091 }
2046a35d 5092 putc ('\n', stdout);
e8a64888
AM
5093 printf (_(" Size of section headers: %u (bytes)\n"),
5094 header->e_shentsize);
5095 printf (_(" Number of section headers: %u"),
5096 header->e_shnum);
dda8d76d 5097 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5098 {
5099 header->e_shnum = filedata->section_headers[0].sh_size;
5100 printf (" (%u)", header->e_shnum);
5101 }
560f3c1c 5102 putc ('\n', stdout);
e8a64888
AM
5103 printf (_(" Section header string table index: %u"),
5104 header->e_shstrndx);
dda8d76d
NC
5105 if (filedata->section_headers != NULL
5106 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5107 {
5108 header->e_shstrndx = filedata->section_headers[0].sh_link;
5109 printf (" (%u)", header->e_shstrndx);
5110 }
5111 if (header->e_shstrndx != SHN_UNDEF
5112 && header->e_shstrndx >= header->e_shnum)
5113 {
5114 header->e_shstrndx = SHN_UNDEF;
5115 printf (_(" <corrupt: out of range>"));
5116 }
560f3c1c
AM
5117 putc ('\n', stdout);
5118 }
5119
dda8d76d 5120 if (filedata->section_headers != NULL)
560f3c1c 5121 {
dda8d76d
NC
5122 if (header->e_phnum == PN_XNUM
5123 && filedata->section_headers[0].sh_info != 0)
5124 header->e_phnum = filedata->section_headers[0].sh_info;
5125 if (header->e_shnum == SHN_UNDEF)
5126 header->e_shnum = filedata->section_headers[0].sh_size;
5127 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5128 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5129 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
5130 header->e_shstrndx = SHN_UNDEF;
5131 free (filedata->section_headers);
5132 filedata->section_headers = NULL;
252b5132 5133 }
103f02d3 5134
32ec8896 5135 return TRUE;
9ea033b2
NC
5136}
5137
dda8d76d
NC
5138/* Read in the program headers from FILEDATA and store them in PHEADERS.
5139 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5140
e0a31db1 5141static bfd_boolean
dda8d76d 5142get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5143{
2cf0635d
NC
5144 Elf32_External_Phdr * phdrs;
5145 Elf32_External_Phdr * external;
5146 Elf_Internal_Phdr * internal;
b34976b6 5147 unsigned int i;
dda8d76d
NC
5148 unsigned int size = filedata->file_header.e_phentsize;
5149 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5150
5151 /* PR binutils/17531: Cope with unexpected section header sizes. */
5152 if (size == 0 || num == 0)
5153 return FALSE;
5154 if (size < sizeof * phdrs)
5155 {
5156 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5157 return FALSE;
5158 }
5159 if (size > sizeof * phdrs)
5160 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5161
dda8d76d 5162 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5163 size, num, _("program headers"));
5164 if (phdrs == NULL)
5165 return FALSE;
9ea033b2 5166
91d6fa6a 5167 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5168 i < filedata->file_header.e_phnum;
b34976b6 5169 i++, internal++, external++)
252b5132 5170 {
9ea033b2
NC
5171 internal->p_type = BYTE_GET (external->p_type);
5172 internal->p_offset = BYTE_GET (external->p_offset);
5173 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5174 internal->p_paddr = BYTE_GET (external->p_paddr);
5175 internal->p_filesz = BYTE_GET (external->p_filesz);
5176 internal->p_memsz = BYTE_GET (external->p_memsz);
5177 internal->p_flags = BYTE_GET (external->p_flags);
5178 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5179 }
5180
9ea033b2 5181 free (phdrs);
e0a31db1 5182 return TRUE;
252b5132
RH
5183}
5184
dda8d76d
NC
5185/* Read in the program headers from FILEDATA and store them in PHEADERS.
5186 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5187
e0a31db1 5188static bfd_boolean
dda8d76d 5189get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5190{
2cf0635d
NC
5191 Elf64_External_Phdr * phdrs;
5192 Elf64_External_Phdr * external;
5193 Elf_Internal_Phdr * internal;
b34976b6 5194 unsigned int i;
dda8d76d
NC
5195 unsigned int size = filedata->file_header.e_phentsize;
5196 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5197
5198 /* PR binutils/17531: Cope with unexpected section header sizes. */
5199 if (size == 0 || num == 0)
5200 return FALSE;
5201 if (size < sizeof * phdrs)
5202 {
5203 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5204 return FALSE;
5205 }
5206 if (size > sizeof * phdrs)
5207 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5208
dda8d76d 5209 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5210 size, num, _("program headers"));
a6e9f9df 5211 if (!phdrs)
e0a31db1 5212 return FALSE;
9ea033b2 5213
91d6fa6a 5214 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5215 i < filedata->file_header.e_phnum;
b34976b6 5216 i++, internal++, external++)
9ea033b2
NC
5217 {
5218 internal->p_type = BYTE_GET (external->p_type);
5219 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5220 internal->p_offset = BYTE_GET (external->p_offset);
5221 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5222 internal->p_paddr = BYTE_GET (external->p_paddr);
5223 internal->p_filesz = BYTE_GET (external->p_filesz);
5224 internal->p_memsz = BYTE_GET (external->p_memsz);
5225 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5226 }
5227
5228 free (phdrs);
e0a31db1 5229 return TRUE;
9ea033b2 5230}
252b5132 5231
32ec8896 5232/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5233
32ec8896 5234static bfd_boolean
dda8d76d 5235get_program_headers (Filedata * filedata)
d93f0186 5236{
2cf0635d 5237 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5238
5239 /* Check cache of prior read. */
dda8d76d 5240 if (filedata->program_headers != NULL)
32ec8896 5241 return TRUE;
d93f0186 5242
82156ab7
NC
5243 /* Be kind to memory checkers by looking for
5244 e_phnum values which we know must be invalid. */
dda8d76d 5245 if (filedata->file_header.e_phnum
82156ab7 5246 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5247 >= filedata->file_size)
82156ab7
NC
5248 {
5249 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5250 filedata->file_header.e_phnum);
82156ab7
NC
5251 return FALSE;
5252 }
d93f0186 5253
dda8d76d 5254 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5255 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5256 if (phdrs == NULL)
5257 {
8b73c356 5258 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5259 filedata->file_header.e_phnum);
32ec8896 5260 return FALSE;
d93f0186
NC
5261 }
5262
5263 if (is_32bit_elf
dda8d76d
NC
5264 ? get_32bit_program_headers (filedata, phdrs)
5265 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5266 {
dda8d76d 5267 filedata->program_headers = phdrs;
32ec8896 5268 return TRUE;
d93f0186
NC
5269 }
5270
5271 free (phdrs);
32ec8896 5272 return FALSE;
d93f0186
NC
5273}
5274
32ec8896 5275/* Returns TRUE if the program headers were loaded. */
2f62977e 5276
32ec8896 5277static bfd_boolean
dda8d76d 5278process_program_headers (Filedata * filedata)
252b5132 5279{
2cf0635d 5280 Elf_Internal_Phdr * segment;
b34976b6 5281 unsigned int i;
1a9ccd70 5282 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5283
978c4450
AM
5284 filedata->dynamic_addr = 0;
5285 filedata->dynamic_size = 0;
663f67df 5286
dda8d76d 5287 if (filedata->file_header.e_phnum == 0)
252b5132 5288 {
82f2dbf7 5289 /* PR binutils/12467. */
dda8d76d 5290 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5291 {
5292 warn (_("possibly corrupt ELF header - it has a non-zero program"
5293 " header offset, but no program headers\n"));
5294 return FALSE;
5295 }
82f2dbf7 5296 else if (do_segments)
252b5132 5297 printf (_("\nThere are no program headers in this file.\n"));
32ec8896 5298 return TRUE;
252b5132
RH
5299 }
5300
5301 if (do_segments && !do_header)
5302 {
dda8d76d
NC
5303 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
5304 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5305 printf (ngettext ("There is %d program header, starting at offset %s\n",
5306 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5307 filedata->file_header.e_phnum),
5308 filedata->file_header.e_phnum,
5309 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5310 }
5311
dda8d76d 5312 if (! get_program_headers (filedata))
6b4bf3bc 5313 return TRUE;
103f02d3 5314
252b5132
RH
5315 if (do_segments)
5316 {
dda8d76d 5317 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5318 printf (_("\nProgram Headers:\n"));
5319 else
5320 printf (_("\nProgram Headers:\n"));
76da6bbe 5321
f7a99963
NC
5322 if (is_32bit_elf)
5323 printf
5324 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5325 else if (do_wide)
5326 printf
5327 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5328 else
5329 {
5330 printf
5331 (_(" Type Offset VirtAddr PhysAddr\n"));
5332 printf
5333 (_(" FileSiz MemSiz Flags Align\n"));
5334 }
252b5132
RH
5335 }
5336
dda8d76d
NC
5337 for (i = 0, segment = filedata->program_headers;
5338 i < filedata->file_header.e_phnum;
b34976b6 5339 i++, segment++)
252b5132
RH
5340 {
5341 if (do_segments)
5342 {
dda8d76d 5343 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5344
5345 if (is_32bit_elf)
5346 {
5347 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5348 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5349 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5350 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5351 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5352 printf ("%c%c%c ",
5353 (segment->p_flags & PF_R ? 'R' : ' '),
5354 (segment->p_flags & PF_W ? 'W' : ' '),
5355 (segment->p_flags & PF_X ? 'E' : ' '));
5356 printf ("%#lx", (unsigned long) segment->p_align);
5357 }
d974e256
JJ
5358 else if (do_wide)
5359 {
5360 if ((unsigned long) segment->p_offset == segment->p_offset)
5361 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5362 else
5363 {
5364 print_vma (segment->p_offset, FULL_HEX);
5365 putchar (' ');
5366 }
5367
5368 print_vma (segment->p_vaddr, FULL_HEX);
5369 putchar (' ');
5370 print_vma (segment->p_paddr, FULL_HEX);
5371 putchar (' ');
5372
5373 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5374 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5375 else
5376 {
5377 print_vma (segment->p_filesz, FULL_HEX);
5378 putchar (' ');
5379 }
5380
5381 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5382 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5383 else
5384 {
f48e6c45 5385 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5386 }
5387
5388 printf (" %c%c%c ",
5389 (segment->p_flags & PF_R ? 'R' : ' '),
5390 (segment->p_flags & PF_W ? 'W' : ' '),
5391 (segment->p_flags & PF_X ? 'E' : ' '));
5392
5393 if ((unsigned long) segment->p_align == segment->p_align)
5394 printf ("%#lx", (unsigned long) segment->p_align);
5395 else
5396 {
5397 print_vma (segment->p_align, PREFIX_HEX);
5398 }
5399 }
f7a99963
NC
5400 else
5401 {
5402 print_vma (segment->p_offset, FULL_HEX);
5403 putchar (' ');
5404 print_vma (segment->p_vaddr, FULL_HEX);
5405 putchar (' ');
5406 print_vma (segment->p_paddr, FULL_HEX);
5407 printf ("\n ");
5408 print_vma (segment->p_filesz, FULL_HEX);
5409 putchar (' ');
5410 print_vma (segment->p_memsz, FULL_HEX);
5411 printf (" %c%c%c ",
5412 (segment->p_flags & PF_R ? 'R' : ' '),
5413 (segment->p_flags & PF_W ? 'W' : ' '),
5414 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5415 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5416 }
252b5132 5417
1a9ccd70
NC
5418 putc ('\n', stdout);
5419 }
f54498b4 5420
252b5132
RH
5421 switch (segment->p_type)
5422 {
1a9ccd70 5423 case PT_LOAD:
502d895c
NC
5424#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5425 required by the ELF standard, several programs, including the Linux
5426 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5427 if (previous_load
5428 && previous_load->p_vaddr > segment->p_vaddr)
5429 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5430#endif
1a9ccd70
NC
5431 if (segment->p_memsz < segment->p_filesz)
5432 error (_("the segment's file size is larger than its memory size\n"));
5433 previous_load = segment;
5434 break;
5435
5436 case PT_PHDR:
5437 /* PR 20815 - Verify that the program header is loaded into memory. */
5438 if (i > 0 && previous_load != NULL)
5439 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5440 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5441 {
5442 unsigned int j;
5443
dda8d76d 5444 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5445 {
5446 Elf_Internal_Phdr *load = filedata->program_headers + j;
5447 if (load->p_type == PT_LOAD
5448 && load->p_offset <= segment->p_offset
5449 && (load->p_offset + load->p_filesz
5450 >= segment->p_offset + segment->p_filesz)
5451 && load->p_vaddr <= segment->p_vaddr
5452 && (load->p_vaddr + load->p_filesz
5453 >= segment->p_vaddr + segment->p_filesz))
5454 break;
5455 }
dda8d76d 5456 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5457 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5458 }
5459 break;
5460
252b5132 5461 case PT_DYNAMIC:
978c4450 5462 if (filedata->dynamic_addr)
252b5132
RH
5463 error (_("more than one dynamic segment\n"));
5464
20737c13
AM
5465 /* By default, assume that the .dynamic section is the first
5466 section in the DYNAMIC segment. */
978c4450
AM
5467 filedata->dynamic_addr = segment->p_offset;
5468 filedata->dynamic_size = segment->p_filesz;
20737c13 5469
b2d38a17
NC
5470 /* Try to locate the .dynamic section. If there is
5471 a section header table, we can easily locate it. */
dda8d76d 5472 if (filedata->section_headers != NULL)
b2d38a17 5473 {
2cf0635d 5474 Elf_Internal_Shdr * sec;
b2d38a17 5475
dda8d76d 5476 sec = find_section (filedata, ".dynamic");
89fac5e3 5477 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5478 {
28f997cf
TG
5479 /* A corresponding .dynamic section is expected, but on
5480 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5481 if (!is_ia64_vms (filedata))
28f997cf 5482 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5483 break;
5484 }
5485
42bb2e33 5486 if (sec->sh_type == SHT_NOBITS)
20737c13 5487 {
978c4450 5488 filedata->dynamic_size = 0;
20737c13
AM
5489 break;
5490 }
42bb2e33 5491
978c4450
AM
5492 filedata->dynamic_addr = sec->sh_offset;
5493 filedata->dynamic_size = sec->sh_size;
b2d38a17 5494
8ac10c5b
L
5495 /* The PT_DYNAMIC segment, which is used by the run-time
5496 loader, should exactly match the .dynamic section. */
5497 if (do_checks
5498 && (filedata->dynamic_addr != segment->p_offset
5499 || filedata->dynamic_size != segment->p_filesz))
5500 warn (_("\
5501the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 5502 }
39e224f6
MW
5503
5504 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5505 segment. Check this after matching against the section headers
5506 so we don't warn on debuginfo file (which have NOBITS .dynamic
5507 sections). */
978c4450
AM
5508 if (filedata->dynamic_addr > filedata->file_size
5509 || (filedata->dynamic_size
5510 > filedata->file_size - filedata->dynamic_addr))
39e224f6
MW
5511 {
5512 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
978c4450 5513 filedata->dynamic_addr = filedata->dynamic_size = 0;
39e224f6 5514 }
252b5132
RH
5515 break;
5516
5517 case PT_INTERP:
978c4450
AM
5518 if (fseek (filedata->handle,
5519 filedata->archive_file_offset + (long) segment->p_offset,
fb52b2f4 5520 SEEK_SET))
252b5132
RH
5521 error (_("Unable to find program interpreter name\n"));
5522 else
5523 {
f8eae8b2 5524 char fmt [32];
9495b2e6 5525 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
5526
5527 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 5528 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 5529
978c4450
AM
5530 filedata->program_interpreter[0] = 0;
5531 if (fscanf (filedata->handle, fmt,
5532 filedata->program_interpreter) <= 0)
7bd7b3ef 5533 error (_("Unable to read program interpreter name\n"));
252b5132
RH
5534
5535 if (do_segments)
f54498b4 5536 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 5537 filedata->program_interpreter);
252b5132
RH
5538 }
5539 break;
5540 }
252b5132
RH
5541 }
5542
dda8d76d
NC
5543 if (do_segments
5544 && filedata->section_headers != NULL
5545 && filedata->string_table != NULL)
252b5132
RH
5546 {
5547 printf (_("\n Section to Segment mapping:\n"));
5548 printf (_(" Segment Sections...\n"));
5549
dda8d76d 5550 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5551 {
9ad5cbcf 5552 unsigned int j;
2cf0635d 5553 Elf_Internal_Shdr * section;
252b5132 5554
dda8d76d
NC
5555 segment = filedata->program_headers + i;
5556 section = filedata->section_headers + 1;
252b5132
RH
5557
5558 printf (" %2.2d ", i);
5559
dda8d76d 5560 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5561 {
f4638467
AM
5562 if (!ELF_TBSS_SPECIAL (section, segment)
5563 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5564 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5565 }
5566
5567 putc ('\n',stdout);
5568 }
5569 }
5570
32ec8896 5571 return TRUE;
252b5132
RH
5572}
5573
5574
d93f0186
NC
5575/* Find the file offset corresponding to VMA by using the program headers. */
5576
5577static long
dda8d76d 5578offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5579{
2cf0635d 5580 Elf_Internal_Phdr * seg;
d93f0186 5581
dda8d76d 5582 if (! get_program_headers (filedata))
d93f0186
NC
5583 {
5584 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5585 return (long) vma;
5586 }
5587
dda8d76d
NC
5588 for (seg = filedata->program_headers;
5589 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5590 ++seg)
5591 {
5592 if (seg->p_type != PT_LOAD)
5593 continue;
5594
5595 if (vma >= (seg->p_vaddr & -seg->p_align)
5596 && vma + size <= seg->p_vaddr + seg->p_filesz)
5597 return vma - seg->p_vaddr + seg->p_offset;
5598 }
5599
5600 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5601 (unsigned long) vma);
d93f0186
NC
5602 return (long) vma;
5603}
5604
5605
dda8d76d
NC
5606/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5607 If PROBE is true, this is just a probe and we do not generate any error
5608 messages if the load fails. */
049b0c3a
NC
5609
5610static bfd_boolean
dda8d76d 5611get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
252b5132 5612{
2cf0635d
NC
5613 Elf32_External_Shdr * shdrs;
5614 Elf_Internal_Shdr * internal;
dda8d76d
NC
5615 unsigned int i;
5616 unsigned int size = filedata->file_header.e_shentsize;
5617 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5618
5619 /* PR binutils/17531: Cope with unexpected section header sizes. */
5620 if (size == 0 || num == 0)
5621 return FALSE;
5622 if (size < sizeof * shdrs)
5623 {
5624 if (! probe)
5625 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5626 return FALSE;
5627 }
5628 if (!probe && size > sizeof * shdrs)
5629 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5630
dda8d76d 5631 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5632 size, num,
5633 probe ? NULL : _("section headers"));
5634 if (shdrs == NULL)
5635 return FALSE;
252b5132 5636
dda8d76d
NC
5637 free (filedata->section_headers);
5638 filedata->section_headers = (Elf_Internal_Shdr *)
5639 cmalloc (num, sizeof (Elf_Internal_Shdr));
5640 if (filedata->section_headers == NULL)
252b5132 5641 {
049b0c3a 5642 if (!probe)
8b73c356 5643 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5644 free (shdrs);
049b0c3a 5645 return FALSE;
252b5132
RH
5646 }
5647
dda8d76d 5648 for (i = 0, internal = filedata->section_headers;
560f3c1c 5649 i < num;
b34976b6 5650 i++, internal++)
252b5132
RH
5651 {
5652 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5653 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5654 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5655 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5656 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5657 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5658 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5659 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5660 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5661 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5662 if (!probe && internal->sh_link > num)
5663 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5664 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5665 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5666 }
5667
5668 free (shdrs);
049b0c3a 5669 return TRUE;
252b5132
RH
5670}
5671
dda8d76d
NC
5672/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5673
049b0c3a 5674static bfd_boolean
dda8d76d 5675get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
9ea033b2 5676{
dda8d76d
NC
5677 Elf64_External_Shdr * shdrs;
5678 Elf_Internal_Shdr * internal;
5679 unsigned int i;
5680 unsigned int size = filedata->file_header.e_shentsize;
5681 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5682
5683 /* PR binutils/17531: Cope with unexpected section header sizes. */
5684 if (size == 0 || num == 0)
5685 return FALSE;
dda8d76d 5686
049b0c3a
NC
5687 if (size < sizeof * shdrs)
5688 {
5689 if (! probe)
5690 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5691 return FALSE;
5692 }
dda8d76d 5693
049b0c3a
NC
5694 if (! probe && size > sizeof * shdrs)
5695 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5696
dda8d76d
NC
5697 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5698 filedata->file_header.e_shoff,
049b0c3a
NC
5699 size, num,
5700 probe ? NULL : _("section headers"));
5701 if (shdrs == NULL)
5702 return FALSE;
9ea033b2 5703
dda8d76d
NC
5704 free (filedata->section_headers);
5705 filedata->section_headers = (Elf_Internal_Shdr *)
5706 cmalloc (num, sizeof (Elf_Internal_Shdr));
5707 if (filedata->section_headers == NULL)
9ea033b2 5708 {
049b0c3a 5709 if (! probe)
8b73c356 5710 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5711 free (shdrs);
049b0c3a 5712 return FALSE;
9ea033b2
NC
5713 }
5714
dda8d76d 5715 for (i = 0, internal = filedata->section_headers;
560f3c1c 5716 i < num;
b34976b6 5717 i++, internal++)
9ea033b2
NC
5718 {
5719 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5720 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5721 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5722 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5723 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5724 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5725 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5726 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5727 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5728 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5729 if (!probe && internal->sh_link > num)
5730 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5731 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5732 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5733 }
5734
5735 free (shdrs);
049b0c3a 5736 return TRUE;
9ea033b2
NC
5737}
5738
252b5132 5739static Elf_Internal_Sym *
dda8d76d
NC
5740get_32bit_elf_symbols (Filedata * filedata,
5741 Elf_Internal_Shdr * section,
5742 unsigned long * num_syms_return)
252b5132 5743{
ba5cdace 5744 unsigned long number = 0;
dd24e3da 5745 Elf32_External_Sym * esyms = NULL;
ba5cdace 5746 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5747 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5748 Elf_Internal_Sym * psym;
b34976b6 5749 unsigned int j;
e3d39609 5750 elf_section_list * entry;
252b5132 5751
c9c1d674
EG
5752 if (section->sh_size == 0)
5753 {
5754 if (num_syms_return != NULL)
5755 * num_syms_return = 0;
5756 return NULL;
5757 }
5758
dd24e3da 5759 /* Run some sanity checks first. */
c9c1d674 5760 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5761 {
c9c1d674 5762 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5763 printable_section_name (filedata, section),
5764 (unsigned long) section->sh_entsize);
ba5cdace 5765 goto exit_point;
dd24e3da
NC
5766 }
5767
dda8d76d 5768 if (section->sh_size > filedata->file_size)
f54498b4
NC
5769 {
5770 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5771 printable_section_name (filedata, section),
5772 (unsigned long) section->sh_size);
f54498b4
NC
5773 goto exit_point;
5774 }
5775
dd24e3da
NC
5776 number = section->sh_size / section->sh_entsize;
5777
5778 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5779 {
c9c1d674 5780 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5781 (unsigned long) section->sh_size,
dda8d76d 5782 printable_section_name (filedata, section),
8066deb1 5783 (unsigned long) section->sh_entsize);
ba5cdace 5784 goto exit_point;
dd24e3da
NC
5785 }
5786
dda8d76d 5787 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5788 section->sh_size, _("symbols"));
dd24e3da 5789 if (esyms == NULL)
ba5cdace 5790 goto exit_point;
252b5132 5791
e3d39609 5792 shndx = NULL;
978c4450 5793 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5794 {
5795 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5796 continue;
5797
5798 if (shndx != NULL)
5799 {
5800 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5801 free (shndx);
5802 }
5803
5804 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5805 entry->hdr->sh_offset,
5806 1, entry->hdr->sh_size,
5807 _("symbol table section indices"));
5808 if (shndx == NULL)
5809 goto exit_point;
5810
5811 /* PR17531: file: heap-buffer-overflow */
5812 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5813 {
5814 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5815 printable_section_name (filedata, entry->hdr),
5816 (unsigned long) entry->hdr->sh_size,
5817 (unsigned long) section->sh_size);
5818 goto exit_point;
c9c1d674 5819 }
e3d39609 5820 }
9ad5cbcf 5821
3f5e193b 5822 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5823
5824 if (isyms == NULL)
5825 {
8b73c356
NC
5826 error (_("Out of memory reading %lu symbols\n"),
5827 (unsigned long) number);
dd24e3da 5828 goto exit_point;
252b5132
RH
5829 }
5830
dd24e3da 5831 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5832 {
5833 psym->st_name = BYTE_GET (esyms[j].st_name);
5834 psym->st_value = BYTE_GET (esyms[j].st_value);
5835 psym->st_size = BYTE_GET (esyms[j].st_size);
5836 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5837 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5838 psym->st_shndx
5839 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5840 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5841 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5842 psym->st_info = BYTE_GET (esyms[j].st_info);
5843 psym->st_other = BYTE_GET (esyms[j].st_other);
5844 }
5845
dd24e3da 5846 exit_point:
e3d39609
NC
5847 free (shndx);
5848 free (esyms);
252b5132 5849
ba5cdace
NC
5850 if (num_syms_return != NULL)
5851 * num_syms_return = isyms == NULL ? 0 : number;
5852
252b5132
RH
5853 return isyms;
5854}
5855
9ea033b2 5856static Elf_Internal_Sym *
dda8d76d
NC
5857get_64bit_elf_symbols (Filedata * filedata,
5858 Elf_Internal_Shdr * section,
5859 unsigned long * num_syms_return)
9ea033b2 5860{
ba5cdace
NC
5861 unsigned long number = 0;
5862 Elf64_External_Sym * esyms = NULL;
5863 Elf_External_Sym_Shndx * shndx = NULL;
5864 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5865 Elf_Internal_Sym * psym;
b34976b6 5866 unsigned int j;
e3d39609 5867 elf_section_list * entry;
9ea033b2 5868
c9c1d674
EG
5869 if (section->sh_size == 0)
5870 {
5871 if (num_syms_return != NULL)
5872 * num_syms_return = 0;
5873 return NULL;
5874 }
5875
dd24e3da 5876 /* Run some sanity checks first. */
c9c1d674 5877 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5878 {
c9c1d674 5879 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5880 printable_section_name (filedata, section),
8066deb1 5881 (unsigned long) section->sh_entsize);
ba5cdace 5882 goto exit_point;
dd24e3da
NC
5883 }
5884
dda8d76d 5885 if (section->sh_size > filedata->file_size)
f54498b4
NC
5886 {
5887 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5888 printable_section_name (filedata, section),
8066deb1 5889 (unsigned long) section->sh_size);
f54498b4
NC
5890 goto exit_point;
5891 }
5892
dd24e3da
NC
5893 number = section->sh_size / section->sh_entsize;
5894
5895 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5896 {
c9c1d674 5897 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5898 (unsigned long) section->sh_size,
dda8d76d 5899 printable_section_name (filedata, section),
8066deb1 5900 (unsigned long) section->sh_entsize);
ba5cdace 5901 goto exit_point;
dd24e3da
NC
5902 }
5903
dda8d76d 5904 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5905 section->sh_size, _("symbols"));
a6e9f9df 5906 if (!esyms)
ba5cdace 5907 goto exit_point;
9ea033b2 5908
e3d39609 5909 shndx = NULL;
978c4450 5910 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5911 {
5912 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5913 continue;
5914
5915 if (shndx != NULL)
5916 {
5917 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5918 free (shndx);
c9c1d674 5919 }
e3d39609
NC
5920
5921 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5922 entry->hdr->sh_offset,
5923 1, entry->hdr->sh_size,
5924 _("symbol table section indices"));
5925 if (shndx == NULL)
5926 goto exit_point;
5927
5928 /* PR17531: file: heap-buffer-overflow */
5929 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5930 {
5931 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5932 printable_section_name (filedata, entry->hdr),
5933 (unsigned long) entry->hdr->sh_size,
5934 (unsigned long) section->sh_size);
5935 goto exit_point;
5936 }
5937 }
9ad5cbcf 5938
3f5e193b 5939 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5940
5941 if (isyms == NULL)
5942 {
8b73c356
NC
5943 error (_("Out of memory reading %lu symbols\n"),
5944 (unsigned long) number);
ba5cdace 5945 goto exit_point;
9ea033b2
NC
5946 }
5947
ba5cdace 5948 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5949 {
5950 psym->st_name = BYTE_GET (esyms[j].st_name);
5951 psym->st_info = BYTE_GET (esyms[j].st_info);
5952 psym->st_other = BYTE_GET (esyms[j].st_other);
5953 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5954
4fbb74a6 5955 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5956 psym->st_shndx
5957 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5958 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5959 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5960
66543521
AM
5961 psym->st_value = BYTE_GET (esyms[j].st_value);
5962 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5963 }
5964
ba5cdace 5965 exit_point:
e3d39609
NC
5966 free (shndx);
5967 free (esyms);
ba5cdace
NC
5968
5969 if (num_syms_return != NULL)
5970 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5971
5972 return isyms;
5973}
5974
d1133906 5975static const char *
dda8d76d 5976get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 5977{
5477e8a0 5978 static char buff[1024];
2cf0635d 5979 char * p = buff;
32ec8896
NC
5980 unsigned int field_size = is_32bit_elf ? 8 : 16;
5981 signed int sindex;
5982 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5983 bfd_vma os_flags = 0;
5984 bfd_vma proc_flags = 0;
5985 bfd_vma unknown_flags = 0;
148b93f2 5986 static const struct
5477e8a0 5987 {
2cf0635d 5988 const char * str;
32ec8896 5989 unsigned int len;
5477e8a0
L
5990 }
5991 flags [] =
5992 {
cfcac11d
NC
5993 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5994 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5995 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5996 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5997 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5998 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5999 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6000 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6001 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6002 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6003 /* IA-64 specific. */
6004 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6005 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6006 /* IA-64 OpenVMS specific. */
6007 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6008 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6009 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6010 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6011 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6012 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6013 /* Generic. */
cfcac11d 6014 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6015 /* SPARC specific. */
77115a4a 6016 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6017 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6018 /* ARM specific. */
6019 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6020 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6021 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6022 /* GNU specific. */
6023 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6024 /* VLE specific. */
6025 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6026 /* GNU specific. */
6027 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6028 };
6029
6030 if (do_section_details)
6031 {
8d5ff12c
L
6032 sprintf (buff, "[%*.*lx]: ",
6033 field_size, field_size, (unsigned long) sh_flags);
6034 p += field_size + 4;
5477e8a0 6035 }
76da6bbe 6036
d1133906
NC
6037 while (sh_flags)
6038 {
6039 bfd_vma flag;
6040
6041 flag = sh_flags & - sh_flags;
6042 sh_flags &= ~ flag;
76da6bbe 6043
5477e8a0 6044 if (do_section_details)
d1133906 6045 {
5477e8a0
L
6046 switch (flag)
6047 {
91d6fa6a
NC
6048 case SHF_WRITE: sindex = 0; break;
6049 case SHF_ALLOC: sindex = 1; break;
6050 case SHF_EXECINSTR: sindex = 2; break;
6051 case SHF_MERGE: sindex = 3; break;
6052 case SHF_STRINGS: sindex = 4; break;
6053 case SHF_INFO_LINK: sindex = 5; break;
6054 case SHF_LINK_ORDER: sindex = 6; break;
6055 case SHF_OS_NONCONFORMING: sindex = 7; break;
6056 case SHF_GROUP: sindex = 8; break;
6057 case SHF_TLS: sindex = 9; break;
18ae9cc1 6058 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6059 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6060
5477e8a0 6061 default:
91d6fa6a 6062 sindex = -1;
dda8d76d 6063 switch (filedata->file_header.e_machine)
148b93f2 6064 {
cfcac11d 6065 case EM_IA_64:
148b93f2 6066 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6067 sindex = 10;
148b93f2 6068 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6069 sindex = 11;
148b93f2 6070#ifdef BFD64
dda8d76d 6071 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6072 switch (flag)
6073 {
91d6fa6a
NC
6074 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6075 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6076 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6077 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6078 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6079 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6080 default: break;
6081 }
6082#endif
cfcac11d
NC
6083 break;
6084
caa83f8b 6085 case EM_386:
22abe556 6086 case EM_IAMCU:
caa83f8b 6087 case EM_X86_64:
7f502d6c 6088 case EM_L1OM:
7a9068fe 6089 case EM_K1OM:
cfcac11d
NC
6090 case EM_OLD_SPARCV9:
6091 case EM_SPARC32PLUS:
6092 case EM_SPARCV9:
6093 case EM_SPARC:
18ae9cc1 6094 if (flag == SHF_ORDERED)
91d6fa6a 6095 sindex = 19;
cfcac11d 6096 break;
ac4c9b04
MG
6097
6098 case EM_ARM:
6099 switch (flag)
6100 {
6101 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6102 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6103 case SHF_COMDEF: sindex = 23; break;
6104 default: break;
6105 }
6106 break;
83eef883
AFB
6107 case EM_PPC:
6108 if (flag == SHF_PPC_VLE)
6109 sindex = 25;
6110 break;
99fabbc9
JL
6111 default:
6112 break;
6113 }
ac4c9b04 6114
99fabbc9
JL
6115 switch (filedata->file_header.e_ident[EI_OSABI])
6116 {
6117 case ELFOSABI_GNU:
6118 case ELFOSABI_FREEBSD:
6119 if (flag == SHF_GNU_RETAIN)
6120 sindex = 26;
6121 /* Fall through */
6122 case ELFOSABI_NONE:
6123 if (flag == SHF_GNU_MBIND)
6124 /* We should not recognize SHF_GNU_MBIND for
6125 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6126 not set the EI_OSABI header byte. */
6127 sindex = 24;
6128 break;
cfcac11d
NC
6129 default:
6130 break;
148b93f2 6131 }
99fabbc9 6132 break;
5477e8a0
L
6133 }
6134
91d6fa6a 6135 if (sindex != -1)
5477e8a0 6136 {
8d5ff12c
L
6137 if (p != buff + field_size + 4)
6138 {
6139 if (size < (10 + 2))
bee0ee85
NC
6140 {
6141 warn (_("Internal error: not enough buffer room for section flag info"));
6142 return _("<unknown>");
6143 }
8d5ff12c
L
6144 size -= 2;
6145 *p++ = ',';
6146 *p++ = ' ';
6147 }
6148
91d6fa6a
NC
6149 size -= flags [sindex].len;
6150 p = stpcpy (p, flags [sindex].str);
5477e8a0 6151 }
3b22753a 6152 else if (flag & SHF_MASKOS)
8d5ff12c 6153 os_flags |= flag;
d1133906 6154 else if (flag & SHF_MASKPROC)
8d5ff12c 6155 proc_flags |= flag;
d1133906 6156 else
8d5ff12c 6157 unknown_flags |= flag;
5477e8a0
L
6158 }
6159 else
6160 {
6161 switch (flag)
6162 {
6163 case SHF_WRITE: *p = 'W'; break;
6164 case SHF_ALLOC: *p = 'A'; break;
6165 case SHF_EXECINSTR: *p = 'X'; break;
6166 case SHF_MERGE: *p = 'M'; break;
6167 case SHF_STRINGS: *p = 'S'; break;
6168 case SHF_INFO_LINK: *p = 'I'; break;
6169 case SHF_LINK_ORDER: *p = 'L'; break;
6170 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6171 case SHF_GROUP: *p = 'G'; break;
6172 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6173 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6174 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6175
6176 default:
dda8d76d
NC
6177 if ((filedata->file_header.e_machine == EM_X86_64
6178 || filedata->file_header.e_machine == EM_L1OM
6179 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6180 && flag == SHF_X86_64_LARGE)
6181 *p = 'l';
dda8d76d 6182 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6183 && flag == SHF_ARM_PURECODE)
99fabbc9 6184 *p = 'y';
dda8d76d 6185 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6186 && flag == SHF_PPC_VLE)
99fabbc9 6187 *p = 'v';
5477e8a0
L
6188 else if (flag & SHF_MASKOS)
6189 {
99fabbc9
JL
6190 switch (filedata->file_header.e_ident[EI_OSABI])
6191 {
6192 case ELFOSABI_GNU:
6193 case ELFOSABI_FREEBSD:
6194 if (flag == SHF_GNU_RETAIN)
6195 {
6196 *p = 'R';
6197 break;
6198 }
6199 /* Fall through */
6200 case ELFOSABI_NONE:
6201 if (flag == SHF_GNU_MBIND)
6202 {
6203 /* We should not recognize SHF_GNU_MBIND for
6204 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6205 not set the EI_OSABI header byte. */
6206 *p = 'D';
6207 break;
6208 }
6209 /* Fall through */
6210 default:
6211 *p = 'o';
6212 sh_flags &= ~SHF_MASKOS;
6213 break;
6214 }
5477e8a0
L
6215 }
6216 else if (flag & SHF_MASKPROC)
6217 {
6218 *p = 'p';
6219 sh_flags &= ~ SHF_MASKPROC;
6220 }
6221 else
6222 *p = 'x';
6223 break;
6224 }
6225 p++;
d1133906
NC
6226 }
6227 }
76da6bbe 6228
8d5ff12c
L
6229 if (do_section_details)
6230 {
6231 if (os_flags)
6232 {
6233 size -= 5 + field_size;
6234 if (p != buff + field_size + 4)
6235 {
6236 if (size < (2 + 1))
bee0ee85
NC
6237 {
6238 warn (_("Internal error: not enough buffer room for section flag info"));
6239 return _("<unknown>");
6240 }
8d5ff12c
L
6241 size -= 2;
6242 *p++ = ',';
6243 *p++ = ' ';
6244 }
6245 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6246 (unsigned long) os_flags);
6247 p += 5 + field_size;
6248 }
6249 if (proc_flags)
6250 {
6251 size -= 7 + field_size;
6252 if (p != buff + field_size + 4)
6253 {
6254 if (size < (2 + 1))
bee0ee85
NC
6255 {
6256 warn (_("Internal error: not enough buffer room for section flag info"));
6257 return _("<unknown>");
6258 }
8d5ff12c
L
6259 size -= 2;
6260 *p++ = ',';
6261 *p++ = ' ';
6262 }
6263 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6264 (unsigned long) proc_flags);
6265 p += 7 + field_size;
6266 }
6267 if (unknown_flags)
6268 {
6269 size -= 10 + field_size;
6270 if (p != buff + field_size + 4)
6271 {
6272 if (size < (2 + 1))
bee0ee85
NC
6273 {
6274 warn (_("Internal error: not enough buffer room for section flag info"));
6275 return _("<unknown>");
6276 }
8d5ff12c
L
6277 size -= 2;
6278 *p++ = ',';
6279 *p++ = ' ';
6280 }
2b692964 6281 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6282 (unsigned long) unknown_flags);
6283 p += 10 + field_size;
6284 }
6285 }
6286
e9e44622 6287 *p = '\0';
d1133906
NC
6288 return buff;
6289}
6290
5844b465 6291static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6292get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6293{
6294 if (is_32bit_elf)
6295 {
6296 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6297
ebdf1ebf
NC
6298 if (size < sizeof (* echdr))
6299 {
6300 error (_("Compressed section is too small even for a compression header\n"));
6301 return 0;
6302 }
6303
77115a4a
L
6304 chdr->ch_type = BYTE_GET (echdr->ch_type);
6305 chdr->ch_size = BYTE_GET (echdr->ch_size);
6306 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6307 return sizeof (*echdr);
6308 }
6309 else
6310 {
6311 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6312
ebdf1ebf
NC
6313 if (size < sizeof (* echdr))
6314 {
6315 error (_("Compressed section is too small even for a compression header\n"));
6316 return 0;
6317 }
6318
77115a4a
L
6319 chdr->ch_type = BYTE_GET (echdr->ch_type);
6320 chdr->ch_size = BYTE_GET (echdr->ch_size);
6321 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6322 return sizeof (*echdr);
6323 }
6324}
6325
32ec8896 6326static bfd_boolean
dda8d76d 6327process_section_headers (Filedata * filedata)
252b5132 6328{
2cf0635d 6329 Elf_Internal_Shdr * section;
b34976b6 6330 unsigned int i;
252b5132 6331
8fb879cd 6332 free (filedata->section_headers);
dda8d76d 6333 filedata->section_headers = NULL;
978c4450
AM
6334 free (filedata->dynamic_symbols);
6335 filedata->dynamic_symbols = NULL;
6336 filedata->num_dynamic_syms = 0;
6337 free (filedata->dynamic_strings);
6338 filedata->dynamic_strings = NULL;
6339 filedata->dynamic_strings_length = 0;
6340 free (filedata->dynamic_syminfo);
6341 filedata->dynamic_syminfo = NULL;
6342 while (filedata->symtab_shndx_list != NULL)
8ff66993 6343 {
978c4450
AM
6344 elf_section_list *next = filedata->symtab_shndx_list->next;
6345 free (filedata->symtab_shndx_list);
6346 filedata->symtab_shndx_list = next;
8ff66993 6347 }
252b5132 6348
dda8d76d 6349 if (filedata->file_header.e_shnum == 0)
252b5132 6350 {
82f2dbf7 6351 /* PR binutils/12467. */
dda8d76d 6352 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6353 {
6354 warn (_("possibly corrupt ELF file header - it has a non-zero"
6355 " section header offset, but no section headers\n"));
6356 return FALSE;
6357 }
82f2dbf7 6358 else if (do_sections)
252b5132
RH
6359 printf (_("\nThere are no sections in this file.\n"));
6360
32ec8896 6361 return TRUE;
252b5132
RH
6362 }
6363
6364 if (do_sections && !do_header)
d3a49aa8
AM
6365 printf (ngettext ("There is %d section header, "
6366 "starting at offset 0x%lx:\n",
6367 "There are %d section headers, "
6368 "starting at offset 0x%lx:\n",
dda8d76d
NC
6369 filedata->file_header.e_shnum),
6370 filedata->file_header.e_shnum,
6371 (unsigned long) filedata->file_header.e_shoff);
252b5132 6372
9ea033b2
NC
6373 if (is_32bit_elf)
6374 {
dda8d76d 6375 if (! get_32bit_section_headers (filedata, FALSE))
32ec8896
NC
6376 return FALSE;
6377 }
6378 else
6379 {
dda8d76d 6380 if (! get_64bit_section_headers (filedata, FALSE))
32ec8896 6381 return FALSE;
9ea033b2 6382 }
252b5132
RH
6383
6384 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6385 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6386 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6387 {
dda8d76d 6388 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6389
c256ffe7
JJ
6390 if (section->sh_size != 0)
6391 {
dda8d76d
NC
6392 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6393 1, section->sh_size,
6394 _("string table"));
0de14b54 6395
dda8d76d 6396 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6397 }
252b5132
RH
6398 }
6399
6400 /* Scan the sections for the dynamic symbol table
e3c8793a 6401 and dynamic string table and debug sections. */
89fac5e3 6402 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6403 switch (filedata->file_header.e_machine)
89fac5e3
RS
6404 {
6405 case EM_MIPS:
6406 case EM_MIPS_RS3_LE:
6407 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6408 FDE addresses. However, the ABI also has a semi-official ILP32
6409 variant for which the normal FDE address size rules apply.
6410
6411 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6412 section, where XX is the size of longs in bits. Unfortunately,
6413 earlier compilers provided no way of distinguishing ILP32 objects
6414 from LP64 objects, so if there's any doubt, we should assume that
6415 the official LP64 form is being used. */
dda8d76d
NC
6416 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6417 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6418 eh_addr_size = 8;
6419 break;
0f56a26a
DD
6420
6421 case EM_H8_300:
6422 case EM_H8_300H:
dda8d76d 6423 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6424 {
6425 case E_H8_MACH_H8300:
6426 case E_H8_MACH_H8300HN:
6427 case E_H8_MACH_H8300SN:
6428 case E_H8_MACH_H8300SXN:
6429 eh_addr_size = 2;
6430 break;
6431 case E_H8_MACH_H8300H:
6432 case E_H8_MACH_H8300S:
6433 case E_H8_MACH_H8300SX:
6434 eh_addr_size = 4;
6435 break;
6436 }
f4236fe4
DD
6437 break;
6438
ff7eeb89 6439 case EM_M32C_OLD:
f4236fe4 6440 case EM_M32C:
dda8d76d 6441 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6442 {
6443 case EF_M32C_CPU_M16C:
6444 eh_addr_size = 2;
6445 break;
6446 }
6447 break;
89fac5e3
RS
6448 }
6449
76ca31c0
NC
6450#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6451 do \
6452 { \
6453 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6454 if (section->sh_entsize != expected_entsize) \
9dd3a467 6455 { \
76ca31c0
NC
6456 char buf[40]; \
6457 sprintf_vma (buf, section->sh_entsize); \
6458 /* Note: coded this way so that there is a single string for \
6459 translation. */ \
6460 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6461 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6462 (unsigned) expected_entsize); \
9dd3a467 6463 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6464 } \
6465 } \
08d8fa11 6466 while (0)
9dd3a467
NC
6467
6468#define CHECK_ENTSIZE(section, i, type) \
1b513401 6469 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
6470 sizeof (Elf64_External_##type))
6471
dda8d76d
NC
6472 for (i = 0, section = filedata->section_headers;
6473 i < filedata->file_header.e_shnum;
b34976b6 6474 i++, section++)
252b5132 6475 {
b9e920ec 6476 char * name = SECTION_NAME_PRINT (section);
252b5132 6477
1b513401
NC
6478 /* Run some sanity checks on the headers and
6479 possibly fill in some file data as well. */
6480 switch (section->sh_type)
252b5132 6481 {
1b513401 6482 case SHT_DYNSYM:
978c4450 6483 if (filedata->dynamic_symbols != NULL)
252b5132
RH
6484 {
6485 error (_("File contains multiple dynamic symbol tables\n"));
6486 continue;
6487 }
6488
08d8fa11 6489 CHECK_ENTSIZE (section, i, Sym);
978c4450
AM
6490 filedata->dynamic_symbols
6491 = GET_ELF_SYMBOLS (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 6492 filedata->dynamic_symtab_section = section;
1b513401
NC
6493 break;
6494
6495 case SHT_STRTAB:
6496 if (streq (name, ".dynstr"))
252b5132 6497 {
1b513401
NC
6498 if (filedata->dynamic_strings != NULL)
6499 {
6500 error (_("File contains multiple dynamic string tables\n"));
6501 continue;
6502 }
6503
6504 filedata->dynamic_strings
6505 = (char *) get_data (NULL, filedata, section->sh_offset,
6506 1, section->sh_size, _("dynamic strings"));
6507 filedata->dynamic_strings_length
6508 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 6509 filedata->dynamic_strtab_section = section;
252b5132 6510 }
1b513401
NC
6511 break;
6512
6513 case SHT_SYMTAB_SHNDX:
6514 {
6515 elf_section_list * entry = xmalloc (sizeof * entry);
6516
6517 entry->hdr = section;
6518 entry->next = filedata->symtab_shndx_list;
6519 filedata->symtab_shndx_list = entry;
6520 }
6521 break;
6522
6523 case SHT_SYMTAB:
6524 CHECK_ENTSIZE (section, i, Sym);
6525 break;
6526
6527 case SHT_GROUP:
6528 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6529 break;
252b5132 6530
1b513401
NC
6531 case SHT_REL:
6532 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 6533 if (do_checks && section->sh_size == 0)
1b513401
NC
6534 warn (_("Section '%s': zero-sized relocation section\n"), name);
6535 break;
6536
6537 case SHT_RELA:
6538 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 6539 if (do_checks && section->sh_size == 0)
1b513401
NC
6540 warn (_("Section '%s': zero-sized relocation section\n"), name);
6541 break;
6542
6543 case SHT_NOTE:
6544 case SHT_PROGBITS:
546cb2d8
NC
6545 /* Having a zero sized section is not illegal according to the
6546 ELF standard, but it might be an indication that something
6547 is wrong. So issue a warning if we are running in lint mode. */
6548 if (do_checks && section->sh_size == 0)
1b513401
NC
6549 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
6550 break;
6551
6552 default:
6553 break;
6554 }
6555
6556 if ((do_debugging || do_debug_info || do_debug_abbrevs
6557 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
6558 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
6559 || do_debug_str || do_debug_str_offsets || do_debug_loc
6560 || do_debug_ranges
1b513401
NC
6561 || do_debug_addr || do_debug_cu_index || do_debug_links)
6562 && (const_strneq (name, ".debug_")
6563 || const_strneq (name, ".zdebug_")))
252b5132 6564 {
1b315056
CS
6565 if (name[1] == 'z')
6566 name += sizeof (".zdebug_") - 1;
6567 else
6568 name += sizeof (".debug_") - 1;
252b5132
RH
6569
6570 if (do_debugging
4723351a
CC
6571 || (do_debug_info && const_strneq (name, "info"))
6572 || (do_debug_info && const_strneq (name, "types"))
6573 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
6574 || (do_debug_lines && strcmp (name, "line") == 0)
6575 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
6576 || (do_debug_pubnames && const_strneq (name, "pubnames"))
6577 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
6578 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
6579 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
6580 || (do_debug_aranges && const_strneq (name, "aranges"))
6581 || (do_debug_ranges && const_strneq (name, "ranges"))
77145576 6582 || (do_debug_ranges && const_strneq (name, "rnglists"))
4723351a
CC
6583 || (do_debug_frames && const_strneq (name, "frame"))
6584 || (do_debug_macinfo && const_strneq (name, "macinfo"))
6585 || (do_debug_macinfo && const_strneq (name, "macro"))
6586 || (do_debug_str && const_strneq (name, "str"))
e38332c2 6587 || (do_debug_links && const_strneq (name, "sup"))
e4b7104b 6588 || (do_debug_str_offsets && const_strneq (name, "str_offsets"))
4723351a 6589 || (do_debug_loc && const_strneq (name, "loc"))
77145576 6590 || (do_debug_loc && const_strneq (name, "loclists"))
657d0d47
CC
6591 || (do_debug_addr && const_strneq (name, "addr"))
6592 || (do_debug_cu_index && const_strneq (name, "cu_index"))
6593 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 6594 )
6431e409 6595 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6596 }
a262ae96 6597 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6598 else if ((do_debugging || do_debug_info)
0112cd26 6599 && const_strneq (name, ".gnu.linkonce.wi."))
6431e409 6600 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6601 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6602 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6603 else if (do_gdb_index && (streq (name, ".gdb_index")
6604 || streq (name, ".debug_names")))
6431e409 6605 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6606 /* Trace sections for Itanium VMS. */
6607 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6608 || do_trace_aranges)
6609 && const_strneq (name, ".trace_"))
6610 {
6611 name += sizeof (".trace_") - 1;
6612
6613 if (do_debugging
6614 || (do_trace_info && streq (name, "info"))
6615 || (do_trace_abbrevs && streq (name, "abbrev"))
6616 || (do_trace_aranges && streq (name, "aranges"))
6617 )
6431e409 6618 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6619 }
dda8d76d
NC
6620 else if ((do_debugging || do_debug_links)
6621 && (const_strneq (name, ".gnu_debuglink")
6622 || const_strneq (name, ".gnu_debugaltlink")))
6431e409 6623 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6624 }
6625
6626 if (! do_sections)
32ec8896 6627 return TRUE;
252b5132 6628
dda8d76d 6629 if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6630 printf (_("\nSection Headers:\n"));
6631 else
6632 printf (_("\nSection Header:\n"));
76da6bbe 6633
f7a99963 6634 if (is_32bit_elf)
595cf52e 6635 {
5477e8a0 6636 if (do_section_details)
595cf52e
L
6637 {
6638 printf (_(" [Nr] Name\n"));
5477e8a0 6639 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6640 }
6641 else
6642 printf
6643 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6644 }
d974e256 6645 else if (do_wide)
595cf52e 6646 {
5477e8a0 6647 if (do_section_details)
595cf52e
L
6648 {
6649 printf (_(" [Nr] Name\n"));
5477e8a0 6650 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6651 }
6652 else
6653 printf
6654 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6655 }
f7a99963
NC
6656 else
6657 {
5477e8a0 6658 if (do_section_details)
595cf52e
L
6659 {
6660 printf (_(" [Nr] Name\n"));
5477e8a0
L
6661 printf (_(" Type Address Offset Link\n"));
6662 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6663 }
6664 else
6665 {
6666 printf (_(" [Nr] Name Type Address Offset\n"));
6667 printf (_(" Size EntSize Flags Link Info Align\n"));
6668 }
f7a99963 6669 }
252b5132 6670
5477e8a0
L
6671 if (do_section_details)
6672 printf (_(" Flags\n"));
6673
dda8d76d
NC
6674 for (i = 0, section = filedata->section_headers;
6675 i < filedata->file_header.e_shnum;
b34976b6 6676 i++, section++)
252b5132 6677 {
dd905818
NC
6678 /* Run some sanity checks on the section header. */
6679
6680 /* Check the sh_link field. */
6681 switch (section->sh_type)
6682 {
285e3f99
AM
6683 case SHT_REL:
6684 case SHT_RELA:
6685 if (section->sh_link == 0
6686 && (filedata->file_header.e_type == ET_EXEC
6687 || filedata->file_header.e_type == ET_DYN))
6688 /* A dynamic relocation section where all entries use a
6689 zero symbol index need not specify a symtab section. */
6690 break;
6691 /* Fall through. */
dd905818
NC
6692 case SHT_SYMTAB_SHNDX:
6693 case SHT_GROUP:
6694 case SHT_HASH:
6695 case SHT_GNU_HASH:
6696 case SHT_GNU_versym:
285e3f99 6697 if (section->sh_link == 0
dda8d76d
NC
6698 || section->sh_link >= filedata->file_header.e_shnum
6699 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6700 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6701 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6702 i, section->sh_link);
6703 break;
6704
6705 case SHT_DYNAMIC:
6706 case SHT_SYMTAB:
6707 case SHT_DYNSYM:
6708 case SHT_GNU_verneed:
6709 case SHT_GNU_verdef:
6710 case SHT_GNU_LIBLIST:
285e3f99 6711 if (section->sh_link == 0
dda8d76d
NC
6712 || section->sh_link >= filedata->file_header.e_shnum
6713 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6714 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6715 i, section->sh_link);
6716 break;
6717
6718 case SHT_INIT_ARRAY:
6719 case SHT_FINI_ARRAY:
6720 case SHT_PREINIT_ARRAY:
6721 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6722 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6723 i, section->sh_link);
6724 break;
6725
6726 default:
6727 /* FIXME: Add support for target specific section types. */
6728#if 0 /* Currently we do not check other section types as there are too
6729 many special cases. Stab sections for example have a type
6730 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6731 section. */
6732 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6733 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6734 i, section->sh_link);
6735#endif
6736 break;
6737 }
6738
6739 /* Check the sh_info field. */
6740 switch (section->sh_type)
6741 {
6742 case SHT_REL:
6743 case SHT_RELA:
285e3f99
AM
6744 if (section->sh_info == 0
6745 && (filedata->file_header.e_type == ET_EXEC
6746 || filedata->file_header.e_type == ET_DYN))
6747 /* Dynamic relocations apply to segments, so they do not
6748 need to specify the section they relocate. */
6749 break;
6750 if (section->sh_info == 0
dda8d76d
NC
6751 || section->sh_info >= filedata->file_header.e_shnum
6752 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6753 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6754 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6755 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6756 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6757 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6758 /* FIXME: Are other section types valid ? */
dda8d76d 6759 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6760 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6761 i, section->sh_info);
dd905818
NC
6762 break;
6763
6764 case SHT_DYNAMIC:
6765 case SHT_HASH:
6766 case SHT_SYMTAB_SHNDX:
6767 case SHT_INIT_ARRAY:
6768 case SHT_FINI_ARRAY:
6769 case SHT_PREINIT_ARRAY:
6770 if (section->sh_info != 0)
6771 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6772 i, section->sh_info);
6773 break;
6774
6775 case SHT_GROUP:
6776 case SHT_SYMTAB:
6777 case SHT_DYNSYM:
6778 /* A symbol index - we assume that it is valid. */
6779 break;
6780
6781 default:
6782 /* FIXME: Add support for target specific section types. */
6783 if (section->sh_type == SHT_NOBITS)
6784 /* NOBITS section headers with non-zero sh_info fields can be
6785 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6786 information. The stripped sections have their headers
6787 preserved but their types set to SHT_NOBITS. So do not check
6788 this type of section. */
dd905818
NC
6789 ;
6790 else if (section->sh_flags & SHF_INFO_LINK)
6791 {
dda8d76d 6792 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6793 warn (_("[%2u]: Expected link to another section in info field"), i);
6794 }
a91e1603
L
6795 else if (section->sh_type < SHT_LOOS
6796 && (section->sh_flags & SHF_GNU_MBIND) == 0
6797 && section->sh_info != 0)
dd905818
NC
6798 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6799 i, section->sh_info);
6800 break;
6801 }
6802
3e6b6445 6803 /* Check the sh_size field. */
dda8d76d 6804 if (section->sh_size > filedata->file_size
3e6b6445
NC
6805 && section->sh_type != SHT_NOBITS
6806 && section->sh_type != SHT_NULL
6807 && section->sh_type < SHT_LOOS)
6808 warn (_("Size of section %u is larger than the entire file!\n"), i);
6809
7bfd842d 6810 printf (" [%2u] ", i);
5477e8a0 6811 if (do_section_details)
dda8d76d 6812 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6813 else
b9e920ec 6814 print_symbol (-17, SECTION_NAME_PRINT (section));
0b4362b0 6815
ea52a088 6816 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6817 get_section_type_name (filedata, section->sh_type));
0b4362b0 6818
f7a99963
NC
6819 if (is_32bit_elf)
6820 {
cfcac11d
NC
6821 const char * link_too_big = NULL;
6822
f7a99963 6823 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6824
f7a99963
NC
6825 printf ( " %6.6lx %6.6lx %2.2lx",
6826 (unsigned long) section->sh_offset,
6827 (unsigned long) section->sh_size,
6828 (unsigned long) section->sh_entsize);
d1133906 6829
5477e8a0
L
6830 if (do_section_details)
6831 fputs (" ", stdout);
6832 else
dda8d76d 6833 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6834
dda8d76d 6835 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6836 {
6837 link_too_big = "";
6838 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6839 an error but it can have special values in Solaris binaries. */
dda8d76d 6840 switch (filedata->file_header.e_machine)
cfcac11d 6841 {
caa83f8b 6842 case EM_386:
22abe556 6843 case EM_IAMCU:
caa83f8b 6844 case EM_X86_64:
7f502d6c 6845 case EM_L1OM:
7a9068fe 6846 case EM_K1OM:
cfcac11d
NC
6847 case EM_OLD_SPARCV9:
6848 case EM_SPARC32PLUS:
6849 case EM_SPARCV9:
6850 case EM_SPARC:
6851 if (section->sh_link == (SHN_BEFORE & 0xffff))
6852 link_too_big = "BEFORE";
6853 else if (section->sh_link == (SHN_AFTER & 0xffff))
6854 link_too_big = "AFTER";
6855 break;
6856 default:
6857 break;
6858 }
6859 }
6860
6861 if (do_section_details)
6862 {
6863 if (link_too_big != NULL && * link_too_big)
6864 printf ("<%s> ", link_too_big);
6865 else
6866 printf ("%2u ", section->sh_link);
6867 printf ("%3u %2lu\n", section->sh_info,
6868 (unsigned long) section->sh_addralign);
6869 }
6870 else
6871 printf ("%2u %3u %2lu\n",
6872 section->sh_link,
6873 section->sh_info,
6874 (unsigned long) section->sh_addralign);
6875
6876 if (link_too_big && ! * link_too_big)
6877 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6878 i, section->sh_link);
f7a99963 6879 }
d974e256
JJ
6880 else if (do_wide)
6881 {
6882 print_vma (section->sh_addr, LONG_HEX);
6883
6884 if ((long) section->sh_offset == section->sh_offset)
6885 printf (" %6.6lx", (unsigned long) section->sh_offset);
6886 else
6887 {
6888 putchar (' ');
6889 print_vma (section->sh_offset, LONG_HEX);
6890 }
6891
6892 if ((unsigned long) section->sh_size == section->sh_size)
6893 printf (" %6.6lx", (unsigned long) section->sh_size);
6894 else
6895 {
6896 putchar (' ');
6897 print_vma (section->sh_size, LONG_HEX);
6898 }
6899
6900 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6901 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6902 else
6903 {
6904 putchar (' ');
6905 print_vma (section->sh_entsize, LONG_HEX);
6906 }
6907
5477e8a0
L
6908 if (do_section_details)
6909 fputs (" ", stdout);
6910 else
dda8d76d 6911 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6912
72de5009 6913 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6914
6915 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6916 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6917 else
6918 {
6919 print_vma (section->sh_addralign, DEC);
6920 putchar ('\n');
6921 }
6922 }
5477e8a0 6923 else if (do_section_details)
595cf52e 6924 {
55cc53e9 6925 putchar (' ');
595cf52e
L
6926 print_vma (section->sh_addr, LONG_HEX);
6927 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 6928 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
6929 else
6930 {
6931 printf (" ");
6932 print_vma (section->sh_offset, LONG_HEX);
6933 }
72de5009 6934 printf (" %u\n ", section->sh_link);
595cf52e 6935 print_vma (section->sh_size, LONG_HEX);
5477e8a0 6936 putchar (' ');
595cf52e
L
6937 print_vma (section->sh_entsize, LONG_HEX);
6938
72de5009
AM
6939 printf (" %-16u %lu\n",
6940 section->sh_info,
595cf52e
L
6941 (unsigned long) section->sh_addralign);
6942 }
f7a99963
NC
6943 else
6944 {
6945 putchar (' ');
6946 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
6947 if ((long) section->sh_offset == section->sh_offset)
6948 printf (" %8.8lx", (unsigned long) section->sh_offset);
6949 else
6950 {
6951 printf (" ");
6952 print_vma (section->sh_offset, LONG_HEX);
6953 }
f7a99963
NC
6954 printf ("\n ");
6955 print_vma (section->sh_size, LONG_HEX);
6956 printf (" ");
6957 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 6958
dda8d76d 6959 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6960
72de5009
AM
6961 printf (" %2u %3u %lu\n",
6962 section->sh_link,
6963 section->sh_info,
f7a99963
NC
6964 (unsigned long) section->sh_addralign);
6965 }
5477e8a0
L
6966
6967 if (do_section_details)
77115a4a 6968 {
dda8d76d 6969 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
6970 if ((section->sh_flags & SHF_COMPRESSED) != 0)
6971 {
6972 /* Minimum section size is 12 bytes for 32-bit compression
6973 header + 12 bytes for compressed data header. */
6974 unsigned char buf[24];
d8024a91 6975
77115a4a 6976 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 6977 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
6978 sizeof (buf), _("compression header")))
6979 {
6980 Elf_Internal_Chdr chdr;
d8024a91 6981
5844b465
NC
6982 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
6983 printf (_(" [<corrupt>]\n"));
77115a4a 6984 else
5844b465
NC
6985 {
6986 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
6987 printf (" ZLIB, ");
6988 else
6989 printf (_(" [<unknown>: 0x%x], "),
6990 chdr.ch_type);
6991 print_vma (chdr.ch_size, LONG_HEX);
6992 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
6993 }
77115a4a
L
6994 }
6995 }
6996 }
252b5132
RH
6997 }
6998
5477e8a0 6999 if (!do_section_details)
3dbcc61d 7000 {
9fb71ee4
NC
7001 /* The ordering of the letters shown here matches the ordering of the
7002 corresponding SHF_xxx values, and hence the order in which these
7003 letters will be displayed to the user. */
7004 printf (_("Key to Flags:\n\
7005 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7006 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7007 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7008 switch (filedata->file_header.e_ident[EI_OSABI])
7009 {
7010 case ELFOSABI_GNU:
7011 case ELFOSABI_FREEBSD:
7012 printf (_("R (retain), "));
7013 /* Fall through */
7014 case ELFOSABI_NONE:
7015 printf (_("D (mbind), "));
7016 break;
7017 default:
7018 break;
7019 }
dda8d76d
NC
7020 if (filedata->file_header.e_machine == EM_X86_64
7021 || filedata->file_header.e_machine == EM_L1OM
7022 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7023 printf (_("l (large), "));
dda8d76d 7024 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7025 printf (_("y (purecode), "));
dda8d76d 7026 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7027 printf (_("v (VLE), "));
9fb71ee4 7028 printf ("p (processor specific)\n");
0b4362b0 7029 }
d1133906 7030
32ec8896 7031 return TRUE;
252b5132
RH
7032}
7033
28d13567
AM
7034static bfd_boolean
7035get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7036 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7037 char **strtab, unsigned long *strtablen)
7038{
7039 *strtab = NULL;
7040 *strtablen = 0;
7041 *symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms);
7042
7043 if (*symtab == NULL)
7044 return FALSE;
7045
7046 if (symsec->sh_link != 0)
7047 {
7048 Elf_Internal_Shdr *strsec;
7049
7050 if (symsec->sh_link >= filedata->file_header.e_shnum)
7051 {
7052 error (_("Bad sh_link in symbol table section\n"));
7053 free (*symtab);
7054 *symtab = NULL;
7055 *nsyms = 0;
7056 return FALSE;
7057 }
7058
7059 strsec = filedata->section_headers + symsec->sh_link;
7060
7061 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7062 1, strsec->sh_size, _("string table"));
7063 if (*strtab == NULL)
7064 {
7065 free (*symtab);
7066 *symtab = NULL;
7067 *nsyms = 0;
7068 return FALSE;
7069 }
7070 *strtablen = strsec->sh_size;
7071 }
7072 return TRUE;
7073}
7074
f5842774
L
7075static const char *
7076get_group_flags (unsigned int flags)
7077{
1449284b 7078 static char buff[128];
220453ec 7079
6d913794
NC
7080 if (flags == 0)
7081 return "";
7082 else if (flags == GRP_COMDAT)
7083 return "COMDAT ";
f5842774 7084
89246a0e
AM
7085 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7086 flags,
7087 flags & GRP_MASKOS ? _("<OS specific>") : "",
7088 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7089 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7090 ? _("<unknown>") : ""));
6d913794 7091
f5842774
L
7092 return buff;
7093}
7094
32ec8896 7095static bfd_boolean
dda8d76d 7096process_section_groups (Filedata * filedata)
f5842774 7097{
2cf0635d 7098 Elf_Internal_Shdr * section;
f5842774 7099 unsigned int i;
2cf0635d
NC
7100 struct group * group;
7101 Elf_Internal_Shdr * symtab_sec;
7102 Elf_Internal_Shdr * strtab_sec;
7103 Elf_Internal_Sym * symtab;
ba5cdace 7104 unsigned long num_syms;
2cf0635d 7105 char * strtab;
c256ffe7 7106 size_t strtab_size;
d1f5c6e3
L
7107
7108 /* Don't process section groups unless needed. */
7109 if (!do_unwind && !do_section_groups)
32ec8896 7110 return TRUE;
f5842774 7111
dda8d76d 7112 if (filedata->file_header.e_shnum == 0)
f5842774
L
7113 {
7114 if (do_section_groups)
82f2dbf7 7115 printf (_("\nThere are no sections to group in this file.\n"));
f5842774 7116
32ec8896 7117 return TRUE;
f5842774
L
7118 }
7119
dda8d76d 7120 if (filedata->section_headers == NULL)
f5842774
L
7121 {
7122 error (_("Section headers are not available!\n"));
fa1908fd 7123 /* PR 13622: This can happen with a corrupt ELF header. */
32ec8896 7124 return FALSE;
f5842774
L
7125 }
7126
978c4450
AM
7127 filedata->section_headers_groups
7128 = (struct group **) calloc (filedata->file_header.e_shnum,
7129 sizeof (struct group *));
e4b17d5c 7130
978c4450 7131 if (filedata->section_headers_groups == NULL)
e4b17d5c 7132 {
8b73c356 7133 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7134 filedata->file_header.e_shnum);
32ec8896 7135 return FALSE;
e4b17d5c
L
7136 }
7137
f5842774 7138 /* Scan the sections for the group section. */
978c4450 7139 filedata->group_count = 0;
dda8d76d
NC
7140 for (i = 0, section = filedata->section_headers;
7141 i < filedata->file_header.e_shnum;
f5842774 7142 i++, section++)
e4b17d5c 7143 if (section->sh_type == SHT_GROUP)
978c4450 7144 filedata->group_count++;
e4b17d5c 7145
978c4450 7146 if (filedata->group_count == 0)
d1f5c6e3
L
7147 {
7148 if (do_section_groups)
7149 printf (_("\nThere are no section groups in this file.\n"));
7150
32ec8896 7151 return TRUE;
d1f5c6e3
L
7152 }
7153
978c4450
AM
7154 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7155 sizeof (struct group));
e4b17d5c 7156
978c4450 7157 if (filedata->section_groups == NULL)
e4b17d5c 7158 {
8b73c356 7159 error (_("Out of memory reading %lu groups\n"),
978c4450 7160 (unsigned long) filedata->group_count);
32ec8896 7161 return FALSE;
e4b17d5c
L
7162 }
7163
d1f5c6e3
L
7164 symtab_sec = NULL;
7165 strtab_sec = NULL;
7166 symtab = NULL;
ba5cdace 7167 num_syms = 0;
d1f5c6e3 7168 strtab = NULL;
c256ffe7 7169 strtab_size = 0;
978c4450 7170 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7171 i < filedata->file_header.e_shnum;
e4b17d5c 7172 i++, section++)
f5842774
L
7173 {
7174 if (section->sh_type == SHT_GROUP)
7175 {
dda8d76d 7176 const char * name = printable_section_name (filedata, section);
74e1a04b 7177 const char * group_name;
2cf0635d
NC
7178 unsigned char * start;
7179 unsigned char * indices;
f5842774 7180 unsigned int entry, j, size;
2cf0635d
NC
7181 Elf_Internal_Shdr * sec;
7182 Elf_Internal_Sym * sym;
f5842774
L
7183
7184 /* Get the symbol table. */
dda8d76d
NC
7185 if (section->sh_link >= filedata->file_header.e_shnum
7186 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7187 != SHT_SYMTAB))
f5842774
L
7188 {
7189 error (_("Bad sh_link in group section `%s'\n"), name);
7190 continue;
7191 }
d1f5c6e3
L
7192
7193 if (symtab_sec != sec)
7194 {
7195 symtab_sec = sec;
9db70fc3 7196 free (symtab);
dda8d76d 7197 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 7198 }
f5842774 7199
dd24e3da
NC
7200 if (symtab == NULL)
7201 {
7202 error (_("Corrupt header in group section `%s'\n"), name);
7203 continue;
7204 }
7205
ba5cdace
NC
7206 if (section->sh_info >= num_syms)
7207 {
7208 error (_("Bad sh_info in group section `%s'\n"), name);
7209 continue;
7210 }
7211
f5842774
L
7212 sym = symtab + section->sh_info;
7213
7214 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7215 {
4fbb74a6 7216 if (sym->st_shndx == 0
dda8d76d 7217 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7218 {
7219 error (_("Bad sh_info in group section `%s'\n"), name);
7220 continue;
7221 }
ba2685cc 7222
b9e920ec
AM
7223 group_name = SECTION_NAME_PRINT (filedata->section_headers
7224 + sym->st_shndx);
c256ffe7 7225 strtab_sec = NULL;
9db70fc3 7226 free (strtab);
f5842774 7227 strtab = NULL;
c256ffe7 7228 strtab_size = 0;
f5842774
L
7229 }
7230 else
7231 {
7232 /* Get the string table. */
dda8d76d 7233 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7234 {
7235 strtab_sec = NULL;
9db70fc3 7236 free (strtab);
c256ffe7
JJ
7237 strtab = NULL;
7238 strtab_size = 0;
7239 }
7240 else if (strtab_sec
dda8d76d 7241 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7242 {
7243 strtab_sec = sec;
9db70fc3 7244 free (strtab);
071436c6 7245
dda8d76d 7246 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7247 1, strtab_sec->sh_size,
7248 _("string table"));
c256ffe7 7249 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7250 }
c256ffe7 7251 group_name = sym->st_name < strtab_size
2b692964 7252 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7253 }
7254
c9c1d674
EG
7255 /* PR 17531: file: loop. */
7256 if (section->sh_entsize > section->sh_size)
7257 {
7258 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7259 printable_section_name (filedata, section),
8066deb1
AM
7260 (unsigned long) section->sh_entsize,
7261 (unsigned long) section->sh_size);
61dd8e19 7262 continue;
c9c1d674
EG
7263 }
7264
dda8d76d 7265 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7266 1, section->sh_size,
7267 _("section data"));
59245841
NC
7268 if (start == NULL)
7269 continue;
f5842774
L
7270
7271 indices = start;
7272 size = (section->sh_size / section->sh_entsize) - 1;
7273 entry = byte_get (indices, 4);
7274 indices += 4;
e4b17d5c
L
7275
7276 if (do_section_groups)
7277 {
2b692964 7278 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7279 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7280
e4b17d5c
L
7281 printf (_(" [Index] Name\n"));
7282 }
7283
7284 group->group_index = i;
7285
f5842774
L
7286 for (j = 0; j < size; j++)
7287 {
2cf0635d 7288 struct group_list * g;
e4b17d5c 7289
f5842774
L
7290 entry = byte_get (indices, 4);
7291 indices += 4;
7292
dda8d76d 7293 if (entry >= filedata->file_header.e_shnum)
391cb864 7294 {
57028622
NC
7295 static unsigned num_group_errors = 0;
7296
7297 if (num_group_errors ++ < 10)
7298 {
7299 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7300 entry, i, filedata->file_header.e_shnum - 1);
57028622 7301 if (num_group_errors == 10)
67ce483b 7302 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7303 }
391cb864
L
7304 continue;
7305 }
391cb864 7306
978c4450 7307 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7308 {
d1f5c6e3
L
7309 if (entry)
7310 {
57028622
NC
7311 static unsigned num_errs = 0;
7312
7313 if (num_errs ++ < 10)
7314 {
7315 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7316 entry, i,
978c4450 7317 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7318 if (num_errs == 10)
7319 warn (_("Further error messages about already contained group sections suppressed\n"));
7320 }
d1f5c6e3
L
7321 continue;
7322 }
7323 else
7324 {
7325 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7326 section group. We just warn it the first time
d1f5c6e3 7327 and ignore it afterwards. */
32ec8896 7328 static bfd_boolean warned = FALSE;
d1f5c6e3
L
7329 if (!warned)
7330 {
7331 error (_("section 0 in group section [%5u]\n"),
978c4450 7332 filedata->section_headers_groups [entry]->group_index);
32ec8896 7333 warned = TRUE;
d1f5c6e3
L
7334 }
7335 }
e4b17d5c
L
7336 }
7337
978c4450 7338 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7339
7340 if (do_section_groups)
7341 {
dda8d76d
NC
7342 sec = filedata->section_headers + entry;
7343 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7344 }
7345
3f5e193b 7346 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7347 g->section_index = entry;
7348 g->next = group->root;
7349 group->root = g;
f5842774
L
7350 }
7351
9db70fc3 7352 free (start);
e4b17d5c
L
7353
7354 group++;
f5842774
L
7355 }
7356 }
7357
9db70fc3
AM
7358 free (symtab);
7359 free (strtab);
32ec8896 7360 return TRUE;
f5842774
L
7361}
7362
28f997cf
TG
7363/* Data used to display dynamic fixups. */
7364
7365struct ia64_vms_dynfixup
7366{
7367 bfd_vma needed_ident; /* Library ident number. */
7368 bfd_vma needed; /* Index in the dstrtab of the library name. */
7369 bfd_vma fixup_needed; /* Index of the library. */
7370 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7371 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7372};
7373
7374/* Data used to display dynamic relocations. */
7375
7376struct ia64_vms_dynimgrela
7377{
7378 bfd_vma img_rela_cnt; /* Number of relocations. */
7379 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7380};
7381
7382/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7383 library). */
7384
32ec8896 7385static bfd_boolean
dda8d76d
NC
7386dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7387 struct ia64_vms_dynfixup * fixup,
7388 const char * strtab,
7389 unsigned int strtab_sz)
28f997cf 7390{
32ec8896 7391 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7392 long i;
32ec8896 7393 const char * lib_name;
28f997cf 7394
978c4450
AM
7395 imfs = get_data (NULL, filedata,
7396 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7397 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7398 _("dynamic section image fixups"));
7399 if (!imfs)
32ec8896 7400 return FALSE;
28f997cf
TG
7401
7402 if (fixup->needed < strtab_sz)
7403 lib_name = strtab + fixup->needed;
7404 else
7405 {
32ec8896 7406 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7407 (unsigned long) fixup->needed);
28f997cf
TG
7408 lib_name = "???";
7409 }
736990c4 7410
28f997cf
TG
7411 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7412 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7413 printf
7414 (_("Seg Offset Type SymVec DataType\n"));
7415
7416 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7417 {
7418 unsigned int type;
7419 const char *rtype;
7420
7421 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7422 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7423 type = BYTE_GET (imfs [i].type);
7424 rtype = elf_ia64_reloc_type (type);
7425 if (rtype == NULL)
7426 printf (" 0x%08x ", type);
7427 else
7428 printf (" %-32s ", rtype);
7429 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7430 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7431 }
7432
7433 free (imfs);
32ec8896 7434 return TRUE;
28f997cf
TG
7435}
7436
7437/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7438
32ec8896 7439static bfd_boolean
dda8d76d 7440dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7441{
7442 Elf64_External_VMS_IMAGE_RELA *imrs;
7443 long i;
7444
978c4450
AM
7445 imrs = get_data (NULL, filedata,
7446 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 7447 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7448 _("dynamic section image relocations"));
28f997cf 7449 if (!imrs)
32ec8896 7450 return FALSE;
28f997cf
TG
7451
7452 printf (_("\nImage relocs\n"));
7453 printf
7454 (_("Seg Offset Type Addend Seg Sym Off\n"));
7455
7456 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7457 {
7458 unsigned int type;
7459 const char *rtype;
7460
7461 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7462 printf ("%08" BFD_VMA_FMT "x ",
7463 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7464 type = BYTE_GET (imrs [i].type);
7465 rtype = elf_ia64_reloc_type (type);
7466 if (rtype == NULL)
7467 printf ("0x%08x ", type);
7468 else
7469 printf ("%-31s ", rtype);
7470 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7471 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7472 printf ("%08" BFD_VMA_FMT "x\n",
7473 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7474 }
7475
7476 free (imrs);
32ec8896 7477 return TRUE;
28f997cf
TG
7478}
7479
7480/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7481
32ec8896 7482static bfd_boolean
dda8d76d 7483process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7484{
7485 struct ia64_vms_dynfixup fixup;
7486 struct ia64_vms_dynimgrela imgrela;
7487 Elf_Internal_Dyn *entry;
28f997cf
TG
7488 bfd_vma strtab_off = 0;
7489 bfd_vma strtab_sz = 0;
7490 char *strtab = NULL;
32ec8896 7491 bfd_boolean res = TRUE;
28f997cf
TG
7492
7493 memset (&fixup, 0, sizeof (fixup));
7494 memset (&imgrela, 0, sizeof (imgrela));
7495
7496 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
7497 for (entry = filedata->dynamic_section;
7498 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
7499 entry++)
7500 {
7501 switch (entry->d_tag)
7502 {
7503 case DT_IA_64_VMS_STRTAB_OFFSET:
7504 strtab_off = entry->d_un.d_val;
7505 break;
7506 case DT_STRSZ:
7507 strtab_sz = entry->d_un.d_val;
7508 if (strtab == NULL)
978c4450
AM
7509 strtab = get_data (NULL, filedata,
7510 filedata->dynamic_addr + strtab_off,
28f997cf 7511 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7512 if (strtab == NULL)
7513 strtab_sz = 0;
28f997cf
TG
7514 break;
7515
7516 case DT_IA_64_VMS_NEEDED_IDENT:
7517 fixup.needed_ident = entry->d_un.d_val;
7518 break;
7519 case DT_NEEDED:
7520 fixup.needed = entry->d_un.d_val;
7521 break;
7522 case DT_IA_64_VMS_FIXUP_NEEDED:
7523 fixup.fixup_needed = entry->d_un.d_val;
7524 break;
7525 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7526 fixup.fixup_rela_cnt = entry->d_un.d_val;
7527 break;
7528 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7529 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7530 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
32ec8896 7531 res = FALSE;
28f997cf 7532 break;
28f997cf
TG
7533 case DT_IA_64_VMS_IMG_RELA_CNT:
7534 imgrela.img_rela_cnt = entry->d_un.d_val;
7535 break;
7536 case DT_IA_64_VMS_IMG_RELA_OFF:
7537 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7538 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
32ec8896 7539 res = FALSE;
28f997cf
TG
7540 break;
7541
7542 default:
7543 break;
7544 }
7545 }
7546
9db70fc3 7547 free (strtab);
28f997cf
TG
7548
7549 return res;
7550}
7551
85b1c36d 7552static struct
566b0d53 7553{
2cf0635d 7554 const char * name;
566b0d53
L
7555 int reloc;
7556 int size;
7557 int rela;
32ec8896
NC
7558}
7559 dynamic_relocations [] =
566b0d53 7560{
32ec8896
NC
7561 { "REL", DT_REL, DT_RELSZ, FALSE },
7562 { "RELA", DT_RELA, DT_RELASZ, TRUE },
7563 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7564};
7565
252b5132 7566/* Process the reloc section. */
18bd398b 7567
32ec8896 7568static bfd_boolean
dda8d76d 7569process_relocs (Filedata * filedata)
252b5132 7570{
b34976b6
AM
7571 unsigned long rel_size;
7572 unsigned long rel_offset;
252b5132 7573
252b5132 7574 if (!do_reloc)
32ec8896 7575 return TRUE;
252b5132
RH
7576
7577 if (do_using_dynamic)
7578 {
32ec8896 7579 int is_rela;
2cf0635d 7580 const char * name;
32ec8896 7581 bfd_boolean has_dynamic_reloc;
566b0d53 7582 unsigned int i;
0de14b54 7583
32ec8896 7584 has_dynamic_reloc = FALSE;
252b5132 7585
566b0d53 7586 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7587 {
566b0d53
L
7588 is_rela = dynamic_relocations [i].rela;
7589 name = dynamic_relocations [i].name;
978c4450
AM
7590 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
7591 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 7592
32ec8896
NC
7593 if (rel_size)
7594 has_dynamic_reloc = TRUE;
566b0d53
L
7595
7596 if (is_rela == UNKNOWN)
aa903cfb 7597 {
566b0d53 7598 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 7599 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
7600 {
7601 case DT_REL:
7602 is_rela = FALSE;
7603 break;
7604 case DT_RELA:
7605 is_rela = TRUE;
7606 break;
7607 }
aa903cfb 7608 }
252b5132 7609
566b0d53
L
7610 if (rel_size)
7611 {
7612 printf
7613 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7614 name, rel_offset, rel_size);
252b5132 7615
dda8d76d
NC
7616 dump_relocations (filedata,
7617 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7618 rel_size,
978c4450
AM
7619 filedata->dynamic_symbols,
7620 filedata->num_dynamic_syms,
7621 filedata->dynamic_strings,
7622 filedata->dynamic_strings_length,
32ec8896 7623 is_rela, TRUE /* is_dynamic */);
566b0d53 7624 }
252b5132 7625 }
566b0d53 7626
dda8d76d
NC
7627 if (is_ia64_vms (filedata))
7628 if (process_ia64_vms_dynamic_relocs (filedata))
32ec8896 7629 has_dynamic_reloc = TRUE;
28f997cf 7630
566b0d53 7631 if (! has_dynamic_reloc)
252b5132
RH
7632 printf (_("\nThere are no dynamic relocations in this file.\n"));
7633 }
7634 else
7635 {
2cf0635d 7636 Elf_Internal_Shdr * section;
b34976b6 7637 unsigned long i;
32ec8896 7638 bfd_boolean found = FALSE;
252b5132 7639
dda8d76d
NC
7640 for (i = 0, section = filedata->section_headers;
7641 i < filedata->file_header.e_shnum;
b34976b6 7642 i++, section++)
252b5132
RH
7643 {
7644 if ( section->sh_type != SHT_RELA
7645 && section->sh_type != SHT_REL)
7646 continue;
7647
7648 rel_offset = section->sh_offset;
7649 rel_size = section->sh_size;
7650
7651 if (rel_size)
7652 {
b34976b6 7653 int is_rela;
d3a49aa8 7654 unsigned long num_rela;
103f02d3 7655
252b5132
RH
7656 printf (_("\nRelocation section "));
7657
dda8d76d 7658 if (filedata->string_table == NULL)
19936277 7659 printf ("%d", section->sh_name);
252b5132 7660 else
dda8d76d 7661 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7662
d3a49aa8
AM
7663 num_rela = rel_size / section->sh_entsize;
7664 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7665 " at offset 0x%lx contains %lu entries:\n",
7666 num_rela),
7667 rel_offset, num_rela);
252b5132 7668
d79b3d50
NC
7669 is_rela = section->sh_type == SHT_RELA;
7670
4fbb74a6 7671 if (section->sh_link != 0
dda8d76d 7672 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7673 {
2cf0635d
NC
7674 Elf_Internal_Shdr * symsec;
7675 Elf_Internal_Sym * symtab;
d79b3d50 7676 unsigned long nsyms;
c256ffe7 7677 unsigned long strtablen = 0;
2cf0635d 7678 char * strtab = NULL;
57346661 7679
dda8d76d 7680 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7681 if (symsec->sh_type != SHT_SYMTAB
7682 && symsec->sh_type != SHT_DYNSYM)
7683 continue;
7684
28d13567
AM
7685 if (!get_symtab (filedata, symsec,
7686 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7687 continue;
252b5132 7688
dda8d76d 7689 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7690 symtab, nsyms, strtab, strtablen,
7691 is_rela,
7692 symsec->sh_type == SHT_DYNSYM);
9db70fc3 7693 free (strtab);
d79b3d50
NC
7694 free (symtab);
7695 }
7696 else
dda8d76d 7697 dump_relocations (filedata, rel_offset, rel_size,
32ec8896
NC
7698 NULL, 0, NULL, 0, is_rela,
7699 FALSE /* is_dynamic */);
252b5132 7700
32ec8896 7701 found = TRUE;
252b5132
RH
7702 }
7703 }
7704
7705 if (! found)
45ac8f4f
NC
7706 {
7707 /* Users sometimes forget the -D option, so try to be helpful. */
7708 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7709 {
978c4450 7710 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f
NC
7711 {
7712 printf (_("\nThere are no static relocations in this file."));
7713 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7714
7715 break;
7716 }
7717 }
7718 if (i == ARRAY_SIZE (dynamic_relocations))
7719 printf (_("\nThere are no relocations in this file.\n"));
7720 }
252b5132
RH
7721 }
7722
32ec8896 7723 return TRUE;
252b5132
RH
7724}
7725
4d6ed7c8
NC
7726/* An absolute address consists of a section and an offset. If the
7727 section is NULL, the offset itself is the address, otherwise, the
7728 address equals to LOAD_ADDRESS(section) + offset. */
7729
7730struct absaddr
948f632f
DA
7731{
7732 unsigned short section;
7733 bfd_vma offset;
7734};
4d6ed7c8 7735
948f632f
DA
7736/* Find the nearest symbol at or below ADDR. Returns the symbol
7737 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7738
4d6ed7c8 7739static void
dda8d76d
NC
7740find_symbol_for_address (Filedata * filedata,
7741 Elf_Internal_Sym * symtab,
7742 unsigned long nsyms,
7743 const char * strtab,
7744 unsigned long strtab_size,
7745 struct absaddr addr,
7746 const char ** symname,
7747 bfd_vma * offset)
4d6ed7c8 7748{
d3ba0551 7749 bfd_vma dist = 0x100000;
2cf0635d 7750 Elf_Internal_Sym * sym;
948f632f
DA
7751 Elf_Internal_Sym * beg;
7752 Elf_Internal_Sym * end;
2cf0635d 7753 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7754
0b6ae522 7755 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7756 beg = symtab;
7757 end = symtab + nsyms;
0b6ae522 7758
948f632f 7759 while (beg < end)
4d6ed7c8 7760 {
948f632f
DA
7761 bfd_vma value;
7762
7763 sym = beg + (end - beg) / 2;
0b6ae522 7764
948f632f 7765 value = sym->st_value;
0b6ae522
DJ
7766 REMOVE_ARCH_BITS (value);
7767
948f632f 7768 if (sym->st_name != 0
4d6ed7c8 7769 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7770 && addr.offset >= value
7771 && addr.offset - value < dist)
4d6ed7c8
NC
7772 {
7773 best = sym;
0b6ae522 7774 dist = addr.offset - value;
4d6ed7c8
NC
7775 if (!dist)
7776 break;
7777 }
948f632f
DA
7778
7779 if (addr.offset < value)
7780 end = sym;
7781 else
7782 beg = sym + 1;
4d6ed7c8 7783 }
1b31d05e 7784
4d6ed7c8
NC
7785 if (best)
7786 {
57346661 7787 *symname = (best->st_name >= strtab_size
2b692964 7788 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7789 *offset = dist;
7790 return;
7791 }
1b31d05e 7792
4d6ed7c8
NC
7793 *symname = NULL;
7794 *offset = addr.offset;
7795}
7796
32ec8896 7797static /* signed */ int
948f632f
DA
7798symcmp (const void *p, const void *q)
7799{
7800 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7801 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7802
7803 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7804}
7805
7806/* Process the unwind section. */
7807
7808#include "unwind-ia64.h"
7809
7810struct ia64_unw_table_entry
7811{
7812 struct absaddr start;
7813 struct absaddr end;
7814 struct absaddr info;
7815};
7816
7817struct ia64_unw_aux_info
7818{
32ec8896
NC
7819 struct ia64_unw_table_entry * table; /* Unwind table. */
7820 unsigned long table_len; /* Length of unwind table. */
7821 unsigned char * info; /* Unwind info. */
7822 unsigned long info_size; /* Size of unwind info. */
7823 bfd_vma info_addr; /* Starting address of unwind info. */
7824 bfd_vma seg_base; /* Starting address of segment. */
7825 Elf_Internal_Sym * symtab; /* The symbol table. */
7826 unsigned long nsyms; /* Number of symbols. */
7827 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7828 unsigned long nfuns; /* Number of entries in funtab. */
7829 char * strtab; /* The string table. */
7830 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7831};
7832
32ec8896 7833static bfd_boolean
dda8d76d 7834dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7835{
2cf0635d 7836 struct ia64_unw_table_entry * tp;
948f632f 7837 unsigned long j, nfuns;
4d6ed7c8 7838 int in_body;
32ec8896 7839 bfd_boolean res = TRUE;
7036c0e1 7840
948f632f
DA
7841 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7842 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7843 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7844 aux->funtab[nfuns++] = aux->symtab[j];
7845 aux->nfuns = nfuns;
7846 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7847
4d6ed7c8
NC
7848 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7849 {
7850 bfd_vma stamp;
7851 bfd_vma offset;
2cf0635d
NC
7852 const unsigned char * dp;
7853 const unsigned char * head;
53774b7e 7854 const unsigned char * end;
2cf0635d 7855 const char * procname;
4d6ed7c8 7856
dda8d76d 7857 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7858 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7859
7860 fputs ("\n<", stdout);
7861
7862 if (procname)
7863 {
7864 fputs (procname, stdout);
7865
7866 if (offset)
7867 printf ("+%lx", (unsigned long) offset);
7868 }
7869
7870 fputs (">: [", stdout);
7871 print_vma (tp->start.offset, PREFIX_HEX);
7872 fputc ('-', stdout);
7873 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7874 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7875 (unsigned long) (tp->info.offset - aux->seg_base));
7876
53774b7e
NC
7877 /* PR 17531: file: 86232b32. */
7878 if (aux->info == NULL)
7879 continue;
7880
97c0a079
AM
7881 offset = tp->info.offset;
7882 if (tp->info.section)
7883 {
7884 if (tp->info.section >= filedata->file_header.e_shnum)
7885 {
7886 warn (_("Invalid section %u in table entry %ld\n"),
7887 tp->info.section, (long) (tp - aux->table));
7888 res = FALSE;
7889 continue;
7890 }
7891 offset += filedata->section_headers[tp->info.section].sh_addr;
7892 }
7893 offset -= aux->info_addr;
53774b7e 7894 /* PR 17531: file: 0997b4d1. */
90679903
AM
7895 if (offset >= aux->info_size
7896 || aux->info_size - offset < 8)
53774b7e
NC
7897 {
7898 warn (_("Invalid offset %lx in table entry %ld\n"),
7899 (long) tp->info.offset, (long) (tp - aux->table));
32ec8896 7900 res = FALSE;
53774b7e
NC
7901 continue;
7902 }
7903
97c0a079 7904 head = aux->info + offset;
a4a00738 7905 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 7906
86f55779 7907 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
7908 (unsigned) UNW_VER (stamp),
7909 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
7910 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
7911 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 7912 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
7913
7914 if (UNW_VER (stamp) != 1)
7915 {
2b692964 7916 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
7917 continue;
7918 }
7919
7920 in_body = 0;
53774b7e
NC
7921 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
7922 /* PR 17531: file: 16ceda89. */
7923 if (end > aux->info + aux->info_size)
7924 end = aux->info + aux->info_size;
7925 for (dp = head + 8; dp < end;)
b4477bc8 7926 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 7927 }
948f632f
DA
7928
7929 free (aux->funtab);
32ec8896
NC
7930
7931 return res;
4d6ed7c8
NC
7932}
7933
53774b7e 7934static bfd_boolean
dda8d76d
NC
7935slurp_ia64_unwind_table (Filedata * filedata,
7936 struct ia64_unw_aux_info * aux,
7937 Elf_Internal_Shdr * sec)
4d6ed7c8 7938{
89fac5e3 7939 unsigned long size, nrelas, i;
2cf0635d
NC
7940 Elf_Internal_Phdr * seg;
7941 struct ia64_unw_table_entry * tep;
7942 Elf_Internal_Shdr * relsec;
7943 Elf_Internal_Rela * rela;
7944 Elf_Internal_Rela * rp;
7945 unsigned char * table;
7946 unsigned char * tp;
7947 Elf_Internal_Sym * sym;
7948 const char * relname;
4d6ed7c8 7949
53774b7e
NC
7950 aux->table_len = 0;
7951
4d6ed7c8
NC
7952 /* First, find the starting address of the segment that includes
7953 this section: */
7954
dda8d76d 7955 if (filedata->file_header.e_phnum)
4d6ed7c8 7956 {
dda8d76d 7957 if (! get_program_headers (filedata))
53774b7e 7958 return FALSE;
4d6ed7c8 7959
dda8d76d
NC
7960 for (seg = filedata->program_headers;
7961 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 7962 ++seg)
4d6ed7c8
NC
7963 {
7964 if (seg->p_type != PT_LOAD)
7965 continue;
7966
7967 if (sec->sh_addr >= seg->p_vaddr
7968 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7969 {
7970 aux->seg_base = seg->p_vaddr;
7971 break;
7972 }
7973 }
4d6ed7c8
NC
7974 }
7975
7976 /* Second, build the unwind table from the contents of the unwind section: */
7977 size = sec->sh_size;
dda8d76d 7978 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7979 _("unwind table"));
a6e9f9df 7980 if (!table)
53774b7e 7981 return FALSE;
4d6ed7c8 7982
53774b7e 7983 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 7984 aux->table = (struct ia64_unw_table_entry *)
53774b7e 7985 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 7986 tep = aux->table;
53774b7e
NC
7987
7988 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
7989 {
7990 tep->start.section = SHN_UNDEF;
7991 tep->end.section = SHN_UNDEF;
7992 tep->info.section = SHN_UNDEF;
c6a0c689
AM
7993 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7994 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7995 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
7996 tep->start.offset += aux->seg_base;
7997 tep->end.offset += aux->seg_base;
7998 tep->info.offset += aux->seg_base;
7999 }
8000 free (table);
8001
41e92641 8002 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8003 for (relsec = filedata->section_headers;
8004 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8005 ++relsec)
8006 {
8007 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8008 || relsec->sh_info >= filedata->file_header.e_shnum
8009 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8010 continue;
8011
dda8d76d 8012 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8013 & rela, & nrelas))
53774b7e
NC
8014 {
8015 free (aux->table);
8016 aux->table = NULL;
8017 aux->table_len = 0;
8018 return FALSE;
8019 }
4d6ed7c8
NC
8020
8021 for (rp = rela; rp < rela + nrelas; ++rp)
8022 {
4770fb94 8023 unsigned int sym_ndx;
726bd37d
AM
8024 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8025 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8026
82b1b41b
NC
8027 /* PR 17531: file: 9fa67536. */
8028 if (relname == NULL)
8029 {
726bd37d 8030 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8031 continue;
8032 }
948f632f 8033
0112cd26 8034 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 8035 {
82b1b41b 8036 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8037 continue;
8038 }
8039
89fac5e3 8040 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8041
53774b7e
NC
8042 /* PR 17531: file: 5bc8d9bf. */
8043 if (i >= aux->table_len)
8044 {
8045 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8046 continue;
8047 }
8048
4770fb94
AM
8049 sym_ndx = get_reloc_symindex (rp->r_info);
8050 if (sym_ndx >= aux->nsyms)
8051 {
8052 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8053 sym_ndx);
8054 continue;
8055 }
8056 sym = aux->symtab + sym_ndx;
8057
53774b7e 8058 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8059 {
8060 case 0:
8061 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8062 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8063 break;
8064 case 1:
8065 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8066 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8067 break;
8068 case 2:
8069 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8070 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8071 break;
8072 default:
8073 break;
8074 }
8075 }
8076
8077 free (rela);
8078 }
8079
53774b7e 8080 return TRUE;
4d6ed7c8
NC
8081}
8082
32ec8896 8083static bfd_boolean
dda8d76d 8084ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8085{
2cf0635d
NC
8086 Elf_Internal_Shdr * sec;
8087 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8088 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8089 struct ia64_unw_aux_info aux;
32ec8896 8090 bfd_boolean res = TRUE;
f1467e33 8091
4d6ed7c8
NC
8092 memset (& aux, 0, sizeof (aux));
8093
dda8d76d 8094 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8095 {
28d13567 8096 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8097 {
28d13567 8098 if (aux.symtab)
4082ef84 8099 {
28d13567
AM
8100 error (_("Multiple symbol tables encountered\n"));
8101 free (aux.symtab);
8102 aux.symtab = NULL;
4082ef84 8103 free (aux.strtab);
28d13567 8104 aux.strtab = NULL;
4082ef84 8105 }
28d13567
AM
8106 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8107 &aux.strtab, &aux.strtab_size))
8108 return FALSE;
4d6ed7c8
NC
8109 }
8110 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8111 unwcount++;
8112 }
8113
8114 if (!unwcount)
8115 printf (_("\nThere are no unwind sections in this file.\n"));
8116
8117 while (unwcount-- > 0)
8118 {
2cf0635d 8119 char * suffix;
579f31ac
JJ
8120 size_t len, len2;
8121
dda8d76d
NC
8122 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8123 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8124 if (sec->sh_type == SHT_IA_64_UNWIND)
8125 {
8126 unwsec = sec;
8127 break;
8128 }
4082ef84
NC
8129 /* We have already counted the number of SHT_IA64_UNWIND
8130 sections so the loop above should never fail. */
8131 assert (unwsec != NULL);
579f31ac
JJ
8132
8133 unwstart = i + 1;
8134 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8135
e4b17d5c
L
8136 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8137 {
8138 /* We need to find which section group it is in. */
4082ef84 8139 struct group_list * g;
e4b17d5c 8140
978c4450
AM
8141 if (filedata->section_headers_groups == NULL
8142 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8143 i = filedata->file_header.e_shnum;
4082ef84 8144 else
e4b17d5c 8145 {
978c4450 8146 g = filedata->section_headers_groups[i]->root;
18bd398b 8147
4082ef84
NC
8148 for (; g != NULL; g = g->next)
8149 {
dda8d76d 8150 sec = filedata->section_headers + g->section_index;
e4b17d5c 8151
b9e920ec
AM
8152 if (SECTION_NAME_VALID (sec)
8153 && streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
4082ef84
NC
8154 break;
8155 }
8156
8157 if (g == NULL)
dda8d76d 8158 i = filedata->file_header.e_shnum;
4082ef84 8159 }
e4b17d5c 8160 }
b9e920ec
AM
8161 else if (SECTION_NAME_VALID (unwsec)
8162 && strneq (SECTION_NAME (unwsec),
8163 ELF_STRING_ia64_unwind_once, len))
579f31ac 8164 {
18bd398b 8165 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
8166 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
8167 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8168 for (i = 0, sec = filedata->section_headers;
8169 i < filedata->file_header.e_shnum;
579f31ac 8170 ++i, ++sec)
b9e920ec
AM
8171 if (SECTION_NAME_VALID (sec)
8172 && strneq (SECTION_NAME (sec),
8173 ELF_STRING_ia64_unwind_info_once, len2)
18bd398b 8174 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8175 break;
8176 }
8177 else
8178 {
8179 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8180 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8181 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8182 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8183 suffix = "";
b9e920ec
AM
8184 if (SECTION_NAME_VALID (unwsec)
8185 && strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac 8186 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8187 for (i = 0, sec = filedata->section_headers;
8188 i < filedata->file_header.e_shnum;
579f31ac 8189 ++i, ++sec)
b9e920ec
AM
8190 if (SECTION_NAME_VALID (sec)
8191 && strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
18bd398b 8192 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8193 break;
8194 }
8195
dda8d76d 8196 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8197 {
8198 printf (_("\nCould not find unwind info section for "));
8199
dda8d76d 8200 if (filedata->string_table == NULL)
579f31ac
JJ
8201 printf ("%d", unwsec->sh_name);
8202 else
dda8d76d 8203 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8204 }
8205 else
4d6ed7c8 8206 {
4d6ed7c8 8207 aux.info_addr = sec->sh_addr;
dda8d76d 8208 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8209 sec->sh_size,
8210 _("unwind info"));
59245841 8211 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8212
579f31ac 8213 printf (_("\nUnwind section "));
4d6ed7c8 8214
dda8d76d 8215 if (filedata->string_table == NULL)
579f31ac
JJ
8216 printf ("%d", unwsec->sh_name);
8217 else
dda8d76d 8218 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8219
579f31ac 8220 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8221 (unsigned long) unwsec->sh_offset,
89fac5e3 8222 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8223
dda8d76d 8224 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8225 && aux.table_len > 0)
dda8d76d 8226 dump_ia64_unwind (filedata, & aux);
579f31ac 8227
9db70fc3
AM
8228 free ((char *) aux.table);
8229 free ((char *) aux.info);
579f31ac
JJ
8230 aux.table = NULL;
8231 aux.info = NULL;
8232 }
4d6ed7c8 8233 }
4d6ed7c8 8234
9db70fc3
AM
8235 free (aux.symtab);
8236 free ((char *) aux.strtab);
32ec8896
NC
8237
8238 return res;
4d6ed7c8
NC
8239}
8240
3f5e193b 8241struct hppa_unw_table_entry
32ec8896
NC
8242{
8243 struct absaddr start;
8244 struct absaddr end;
8245 unsigned int Cannot_unwind:1; /* 0 */
8246 unsigned int Millicode:1; /* 1 */
8247 unsigned int Millicode_save_sr0:1; /* 2 */
8248 unsigned int Region_description:2; /* 3..4 */
8249 unsigned int reserved1:1; /* 5 */
8250 unsigned int Entry_SR:1; /* 6 */
8251 unsigned int Entry_FR:4; /* Number saved 7..10 */
8252 unsigned int Entry_GR:5; /* Number saved 11..15 */
8253 unsigned int Args_stored:1; /* 16 */
8254 unsigned int Variable_Frame:1; /* 17 */
8255 unsigned int Separate_Package_Body:1; /* 18 */
8256 unsigned int Frame_Extension_Millicode:1; /* 19 */
8257 unsigned int Stack_Overflow_Check:1; /* 20 */
8258 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8259 unsigned int Ada_Region:1; /* 22 */
8260 unsigned int cxx_info:1; /* 23 */
8261 unsigned int cxx_try_catch:1; /* 24 */
8262 unsigned int sched_entry_seq:1; /* 25 */
8263 unsigned int reserved2:1; /* 26 */
8264 unsigned int Save_SP:1; /* 27 */
8265 unsigned int Save_RP:1; /* 28 */
8266 unsigned int Save_MRP_in_frame:1; /* 29 */
8267 unsigned int extn_ptr_defined:1; /* 30 */
8268 unsigned int Cleanup_defined:1; /* 31 */
8269
8270 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8271 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8272 unsigned int Large_frame:1; /* 2 */
8273 unsigned int Pseudo_SP_Set:1; /* 3 */
8274 unsigned int reserved4:1; /* 4 */
8275 unsigned int Total_frame_size:27; /* 5..31 */
8276};
3f5e193b 8277
57346661 8278struct hppa_unw_aux_info
948f632f 8279{
32ec8896
NC
8280 struct hppa_unw_table_entry * table; /* Unwind table. */
8281 unsigned long table_len; /* Length of unwind table. */
8282 bfd_vma seg_base; /* Starting address of segment. */
8283 Elf_Internal_Sym * symtab; /* The symbol table. */
8284 unsigned long nsyms; /* Number of symbols. */
8285 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8286 unsigned long nfuns; /* Number of entries in funtab. */
8287 char * strtab; /* The string table. */
8288 unsigned long strtab_size; /* Size of string table. */
948f632f 8289};
57346661 8290
32ec8896 8291static bfd_boolean
dda8d76d 8292dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8293{
2cf0635d 8294 struct hppa_unw_table_entry * tp;
948f632f 8295 unsigned long j, nfuns;
32ec8896 8296 bfd_boolean res = TRUE;
948f632f
DA
8297
8298 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8299 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8300 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8301 aux->funtab[nfuns++] = aux->symtab[j];
8302 aux->nfuns = nfuns;
8303 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8304
57346661
AM
8305 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8306 {
8307 bfd_vma offset;
2cf0635d 8308 const char * procname;
57346661 8309
dda8d76d 8310 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8311 aux->strtab_size, tp->start, &procname,
8312 &offset);
8313
8314 fputs ("\n<", stdout);
8315
8316 if (procname)
8317 {
8318 fputs (procname, stdout);
8319
8320 if (offset)
8321 printf ("+%lx", (unsigned long) offset);
8322 }
8323
8324 fputs (">: [", stdout);
8325 print_vma (tp->start.offset, PREFIX_HEX);
8326 fputc ('-', stdout);
8327 print_vma (tp->end.offset, PREFIX_HEX);
8328 printf ("]\n\t");
8329
18bd398b
NC
8330#define PF(_m) if (tp->_m) printf (#_m " ");
8331#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8332 PF(Cannot_unwind);
8333 PF(Millicode);
8334 PF(Millicode_save_sr0);
18bd398b 8335 /* PV(Region_description); */
57346661
AM
8336 PF(Entry_SR);
8337 PV(Entry_FR);
8338 PV(Entry_GR);
8339 PF(Args_stored);
8340 PF(Variable_Frame);
8341 PF(Separate_Package_Body);
8342 PF(Frame_Extension_Millicode);
8343 PF(Stack_Overflow_Check);
8344 PF(Two_Instruction_SP_Increment);
8345 PF(Ada_Region);
8346 PF(cxx_info);
8347 PF(cxx_try_catch);
8348 PF(sched_entry_seq);
8349 PF(Save_SP);
8350 PF(Save_RP);
8351 PF(Save_MRP_in_frame);
8352 PF(extn_ptr_defined);
8353 PF(Cleanup_defined);
8354 PF(MPE_XL_interrupt_marker);
8355 PF(HP_UX_interrupt_marker);
8356 PF(Large_frame);
8357 PF(Pseudo_SP_Set);
8358 PV(Total_frame_size);
8359#undef PF
8360#undef PV
8361 }
8362
18bd398b 8363 printf ("\n");
948f632f
DA
8364
8365 free (aux->funtab);
32ec8896
NC
8366
8367 return res;
57346661
AM
8368}
8369
32ec8896 8370static bfd_boolean
dda8d76d
NC
8371slurp_hppa_unwind_table (Filedata * filedata,
8372 struct hppa_unw_aux_info * aux,
8373 Elf_Internal_Shdr * sec)
57346661 8374{
1c0751b2 8375 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8376 Elf_Internal_Phdr * seg;
8377 struct hppa_unw_table_entry * tep;
8378 Elf_Internal_Shdr * relsec;
8379 Elf_Internal_Rela * rela;
8380 Elf_Internal_Rela * rp;
8381 unsigned char * table;
8382 unsigned char * tp;
8383 Elf_Internal_Sym * sym;
8384 const char * relname;
57346661 8385
57346661
AM
8386 /* First, find the starting address of the segment that includes
8387 this section. */
dda8d76d 8388 if (filedata->file_header.e_phnum)
57346661 8389 {
dda8d76d 8390 if (! get_program_headers (filedata))
32ec8896 8391 return FALSE;
57346661 8392
dda8d76d
NC
8393 for (seg = filedata->program_headers;
8394 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8395 ++seg)
8396 {
8397 if (seg->p_type != PT_LOAD)
8398 continue;
8399
8400 if (sec->sh_addr >= seg->p_vaddr
8401 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8402 {
8403 aux->seg_base = seg->p_vaddr;
8404 break;
8405 }
8406 }
8407 }
8408
8409 /* Second, build the unwind table from the contents of the unwind
8410 section. */
8411 size = sec->sh_size;
dda8d76d 8412 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8413 _("unwind table"));
57346661 8414 if (!table)
32ec8896 8415 return FALSE;
57346661 8416
1c0751b2
DA
8417 unw_ent_size = 16;
8418 nentries = size / unw_ent_size;
8419 size = unw_ent_size * nentries;
57346661 8420
e3fdc001 8421 aux->table_len = nentries;
3f5e193b
NC
8422 tep = aux->table = (struct hppa_unw_table_entry *)
8423 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8424
1c0751b2 8425 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8426 {
8427 unsigned int tmp1, tmp2;
8428
8429 tep->start.section = SHN_UNDEF;
8430 tep->end.section = SHN_UNDEF;
8431
1c0751b2
DA
8432 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8433 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8434 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8435 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8436
8437 tep->start.offset += aux->seg_base;
8438 tep->end.offset += aux->seg_base;
57346661
AM
8439
8440 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8441 tep->Millicode = (tmp1 >> 30) & 0x1;
8442 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8443 tep->Region_description = (tmp1 >> 27) & 0x3;
8444 tep->reserved1 = (tmp1 >> 26) & 0x1;
8445 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8446 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8447 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8448 tep->Args_stored = (tmp1 >> 15) & 0x1;
8449 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8450 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8451 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8452 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8453 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8454 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8455 tep->cxx_info = (tmp1 >> 8) & 0x1;
8456 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8457 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8458 tep->reserved2 = (tmp1 >> 5) & 0x1;
8459 tep->Save_SP = (tmp1 >> 4) & 0x1;
8460 tep->Save_RP = (tmp1 >> 3) & 0x1;
8461 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8462 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8463 tep->Cleanup_defined = tmp1 & 0x1;
8464
8465 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8466 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8467 tep->Large_frame = (tmp2 >> 29) & 0x1;
8468 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8469 tep->reserved4 = (tmp2 >> 27) & 0x1;
8470 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8471 }
8472 free (table);
8473
8474 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8475 for (relsec = filedata->section_headers;
8476 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8477 ++relsec)
8478 {
8479 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8480 || relsec->sh_info >= filedata->file_header.e_shnum
8481 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8482 continue;
8483
dda8d76d 8484 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8485 & rela, & nrelas))
32ec8896 8486 return FALSE;
57346661
AM
8487
8488 for (rp = rela; rp < rela + nrelas; ++rp)
8489 {
4770fb94 8490 unsigned int sym_ndx;
726bd37d
AM
8491 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8492 relname = elf_hppa_reloc_type (r_type);
57346661 8493
726bd37d
AM
8494 if (relname == NULL)
8495 {
8496 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8497 continue;
8498 }
8499
57346661 8500 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 8501 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661 8502 {
726bd37d 8503 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8504 continue;
8505 }
8506
8507 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8508 if (i >= aux->table_len)
8509 {
8510 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8511 continue;
8512 }
57346661 8513
4770fb94
AM
8514 sym_ndx = get_reloc_symindex (rp->r_info);
8515 if (sym_ndx >= aux->nsyms)
8516 {
8517 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8518 sym_ndx);
8519 continue;
8520 }
8521 sym = aux->symtab + sym_ndx;
8522
43f6cd05 8523 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8524 {
8525 case 0:
8526 aux->table[i].start.section = sym->st_shndx;
1e456d54 8527 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8528 break;
8529 case 1:
8530 aux->table[i].end.section = sym->st_shndx;
1e456d54 8531 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8532 break;
8533 default:
8534 break;
8535 }
8536 }
8537
8538 free (rela);
8539 }
8540
32ec8896 8541 return TRUE;
57346661
AM
8542}
8543
32ec8896 8544static bfd_boolean
dda8d76d 8545hppa_process_unwind (Filedata * filedata)
57346661 8546{
57346661 8547 struct hppa_unw_aux_info aux;
2cf0635d 8548 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8549 Elf_Internal_Shdr * sec;
18bd398b 8550 unsigned long i;
32ec8896 8551 bfd_boolean res = TRUE;
57346661 8552
dda8d76d 8553 if (filedata->string_table == NULL)
32ec8896 8554 return FALSE;
1b31d05e
NC
8555
8556 memset (& aux, 0, sizeof (aux));
57346661 8557
dda8d76d 8558 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8559 {
28d13567 8560 if (sec->sh_type == SHT_SYMTAB)
57346661 8561 {
28d13567 8562 if (aux.symtab)
4082ef84 8563 {
28d13567
AM
8564 error (_("Multiple symbol tables encountered\n"));
8565 free (aux.symtab);
8566 aux.symtab = NULL;
4082ef84 8567 free (aux.strtab);
28d13567 8568 aux.strtab = NULL;
4082ef84 8569 }
28d13567
AM
8570 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8571 &aux.strtab, &aux.strtab_size))
8572 return FALSE;
57346661 8573 }
b9e920ec
AM
8574 else if (SECTION_NAME_VALID (sec)
8575 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8576 unwsec = sec;
8577 }
8578
8579 if (!unwsec)
8580 printf (_("\nThere are no unwind sections in this file.\n"));
8581
dda8d76d 8582 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8583 {
b9e920ec
AM
8584 if (SECTION_NAME_VALID (sec)
8585 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8586 {
43f6cd05 8587 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8588
d3a49aa8
AM
8589 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8590 "contains %lu entry:\n",
8591 "\nUnwind section '%s' at offset 0x%lx "
8592 "contains %lu entries:\n",
8593 num_unwind),
dda8d76d 8594 printable_section_name (filedata, sec),
57346661 8595 (unsigned long) sec->sh_offset,
d3a49aa8 8596 num_unwind);
57346661 8597
dda8d76d 8598 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
32ec8896 8599 res = FALSE;
66b09c7e
S
8600
8601 if (res && aux.table_len > 0)
32ec8896 8602 {
dda8d76d 8603 if (! dump_hppa_unwind (filedata, &aux))
32ec8896
NC
8604 res = FALSE;
8605 }
57346661 8606
9db70fc3 8607 free ((char *) aux.table);
57346661
AM
8608 aux.table = NULL;
8609 }
8610 }
8611
9db70fc3
AM
8612 free (aux.symtab);
8613 free ((char *) aux.strtab);
32ec8896
NC
8614
8615 return res;
57346661
AM
8616}
8617
0b6ae522
DJ
8618struct arm_section
8619{
a734115a
NC
8620 unsigned char * data; /* The unwind data. */
8621 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8622 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8623 unsigned long nrelas; /* The number of relocations. */
8624 unsigned int rel_type; /* REL or RELA ? */
8625 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8626};
8627
8628struct arm_unw_aux_info
8629{
dda8d76d 8630 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8631 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8632 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8633 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8634 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8635 char * strtab; /* The file's string table. */
8636 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8637};
8638
8639static const char *
dda8d76d
NC
8640arm_print_vma_and_name (Filedata * filedata,
8641 struct arm_unw_aux_info * aux,
8642 bfd_vma fn,
8643 struct absaddr addr)
0b6ae522
DJ
8644{
8645 const char *procname;
8646 bfd_vma sym_offset;
8647
8648 if (addr.section == SHN_UNDEF)
8649 addr.offset = fn;
8650
dda8d76d 8651 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8652 aux->strtab_size, addr, &procname,
8653 &sym_offset);
8654
8655 print_vma (fn, PREFIX_HEX);
8656
8657 if (procname)
8658 {
8659 fputs (" <", stdout);
8660 fputs (procname, stdout);
8661
8662 if (sym_offset)
8663 printf ("+0x%lx", (unsigned long) sym_offset);
8664 fputc ('>', stdout);
8665 }
8666
8667 return procname;
8668}
8669
8670static void
8671arm_free_section (struct arm_section *arm_sec)
8672{
9db70fc3
AM
8673 free (arm_sec->data);
8674 free (arm_sec->rela);
0b6ae522
DJ
8675}
8676
a734115a
NC
8677/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8678 cached section and install SEC instead.
8679 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8680 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8681 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8682 relocation's offset in ADDR.
1b31d05e
NC
8683 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8684 into the string table of the symbol associated with the reloc. If no
8685 reloc was applied store -1 there.
8686 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
8687
8688static bfd_boolean
dda8d76d
NC
8689get_unwind_section_word (Filedata * filedata,
8690 struct arm_unw_aux_info * aux,
1b31d05e
NC
8691 struct arm_section * arm_sec,
8692 Elf_Internal_Shdr * sec,
8693 bfd_vma word_offset,
8694 unsigned int * wordp,
8695 struct absaddr * addr,
8696 bfd_vma * sym_name)
0b6ae522
DJ
8697{
8698 Elf_Internal_Rela *rp;
8699 Elf_Internal_Sym *sym;
8700 const char * relname;
8701 unsigned int word;
8702 bfd_boolean wrapped;
8703
e0a31db1
NC
8704 if (sec == NULL || arm_sec == NULL)
8705 return FALSE;
8706
0b6ae522
DJ
8707 addr->section = SHN_UNDEF;
8708 addr->offset = 0;
8709
1b31d05e
NC
8710 if (sym_name != NULL)
8711 *sym_name = (bfd_vma) -1;
8712
a734115a 8713 /* If necessary, update the section cache. */
0b6ae522
DJ
8714 if (sec != arm_sec->sec)
8715 {
8716 Elf_Internal_Shdr *relsec;
8717
8718 arm_free_section (arm_sec);
8719
8720 arm_sec->sec = sec;
dda8d76d 8721 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8722 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8723 arm_sec->rela = NULL;
8724 arm_sec->nrelas = 0;
8725
dda8d76d
NC
8726 for (relsec = filedata->section_headers;
8727 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8728 ++relsec)
8729 {
dda8d76d
NC
8730 if (relsec->sh_info >= filedata->file_header.e_shnum
8731 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8732 /* PR 15745: Check the section type as well. */
8733 || (relsec->sh_type != SHT_REL
8734 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8735 continue;
8736
a734115a 8737 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8738 if (relsec->sh_type == SHT_REL)
8739 {
dda8d76d 8740 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8741 relsec->sh_size,
8742 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8743 return FALSE;
0b6ae522 8744 }
1ae40aa4 8745 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8746 {
dda8d76d 8747 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8748 relsec->sh_size,
8749 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8750 return FALSE;
0b6ae522 8751 }
1ae40aa4 8752 break;
0b6ae522
DJ
8753 }
8754
8755 arm_sec->next_rela = arm_sec->rela;
8756 }
8757
a734115a 8758 /* If there is no unwind data we can do nothing. */
0b6ae522 8759 if (arm_sec->data == NULL)
a734115a 8760 return FALSE;
0b6ae522 8761
e0a31db1 8762 /* If the offset is invalid then fail. */
f32ba729
NC
8763 if (/* PR 21343 *//* PR 18879 */
8764 sec->sh_size < 4
8765 || word_offset > (sec->sh_size - 4)
1a915552 8766 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
8767 return FALSE;
8768
a734115a 8769 /* Get the word at the required offset. */
0b6ae522
DJ
8770 word = byte_get (arm_sec->data + word_offset, 4);
8771
0eff7165
NC
8772 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8773 if (arm_sec->rela == NULL)
8774 {
8775 * wordp = word;
8776 return TRUE;
8777 }
8778
a734115a 8779 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
8780 wrapped = FALSE;
8781 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8782 {
8783 bfd_vma prelval, offset;
8784
8785 if (rp->r_offset > word_offset && !wrapped)
8786 {
8787 rp = arm_sec->rela;
8788 wrapped = TRUE;
8789 }
8790 if (rp->r_offset > word_offset)
8791 break;
8792
8793 if (rp->r_offset & 3)
8794 {
8795 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8796 (unsigned long) rp->r_offset);
8797 continue;
8798 }
8799
8800 if (rp->r_offset < word_offset)
8801 continue;
8802
74e1a04b
NC
8803 /* PR 17531: file: 027-161405-0.004 */
8804 if (aux->symtab == NULL)
8805 continue;
8806
0b6ae522
DJ
8807 if (arm_sec->rel_type == SHT_REL)
8808 {
8809 offset = word & 0x7fffffff;
8810 if (offset & 0x40000000)
8811 offset |= ~ (bfd_vma) 0x7fffffff;
8812 }
a734115a 8813 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8814 offset = rp->r_addend;
a734115a 8815 else
74e1a04b
NC
8816 {
8817 error (_("Unknown section relocation type %d encountered\n"),
8818 arm_sec->rel_type);
8819 break;
8820 }
0b6ae522 8821
071436c6
NC
8822 /* PR 17531 file: 027-1241568-0.004. */
8823 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8824 {
8825 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8826 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8827 break;
8828 }
8829
8830 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8831 offset += sym->st_value;
8832 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8833
a734115a 8834 /* Check that we are processing the expected reloc type. */
dda8d76d 8835 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8836 {
8837 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8838 if (relname == NULL)
8839 {
8840 warn (_("Skipping unknown ARM relocation type: %d\n"),
8841 (int) ELF32_R_TYPE (rp->r_info));
8842 continue;
8843 }
a734115a
NC
8844
8845 if (streq (relname, "R_ARM_NONE"))
8846 continue;
0b4362b0 8847
a734115a
NC
8848 if (! streq (relname, "R_ARM_PREL31"))
8849 {
071436c6 8850 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8851 continue;
8852 }
8853 }
dda8d76d 8854 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8855 {
8856 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8857 if (relname == NULL)
8858 {
8859 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8860 (int) ELF32_R_TYPE (rp->r_info));
8861 continue;
8862 }
0b4362b0 8863
a734115a
NC
8864 if (streq (relname, "R_C6000_NONE"))
8865 continue;
8866
8867 if (! streq (relname, "R_C6000_PREL31"))
8868 {
071436c6 8869 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8870 continue;
8871 }
8872
8873 prelval >>= 1;
8874 }
8875 else
74e1a04b
NC
8876 {
8877 /* This function currently only supports ARM and TI unwinders. */
8878 warn (_("Only TI and ARM unwinders are currently supported\n"));
8879 break;
8880 }
fa197c1c 8881
0b6ae522
DJ
8882 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
8883 addr->section = sym->st_shndx;
8884 addr->offset = offset;
74e1a04b 8885
1b31d05e
NC
8886 if (sym_name)
8887 * sym_name = sym->st_name;
0b6ae522
DJ
8888 break;
8889 }
8890
8891 *wordp = word;
8892 arm_sec->next_rela = rp;
8893
a734115a 8894 return TRUE;
0b6ae522
DJ
8895}
8896
a734115a
NC
8897static const char *tic6x_unwind_regnames[16] =
8898{
0b4362b0
RM
8899 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
8900 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
8901 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
8902};
fa197c1c 8903
0b6ae522 8904static void
fa197c1c 8905decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 8906{
fa197c1c
PB
8907 int i;
8908
8909 for (i = 12; mask; mask >>= 1, i--)
8910 {
8911 if (mask & 1)
8912 {
8913 fputs (tic6x_unwind_regnames[i], stdout);
8914 if (mask > 1)
8915 fputs (", ", stdout);
8916 }
8917 }
8918}
0b6ae522
DJ
8919
8920#define ADVANCE \
8921 if (remaining == 0 && more_words) \
8922 { \
8923 data_offset += 4; \
dda8d76d 8924 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 8925 data_offset, & word, & addr, NULL)) \
32ec8896 8926 return FALSE; \
0b6ae522
DJ
8927 remaining = 4; \
8928 more_words--; \
8929 } \
8930
8931#define GET_OP(OP) \
8932 ADVANCE; \
8933 if (remaining) \
8934 { \
8935 remaining--; \
8936 (OP) = word >> 24; \
8937 word <<= 8; \
8938 } \
8939 else \
8940 { \
2b692964 8941 printf (_("[Truncated opcode]\n")); \
32ec8896 8942 return FALSE; \
0b6ae522 8943 } \
cc5914eb 8944 printf ("0x%02x ", OP)
0b6ae522 8945
32ec8896 8946static bfd_boolean
dda8d76d
NC
8947decode_arm_unwind_bytecode (Filedata * filedata,
8948 struct arm_unw_aux_info * aux,
948f632f
DA
8949 unsigned int word,
8950 unsigned int remaining,
8951 unsigned int more_words,
8952 bfd_vma data_offset,
8953 Elf_Internal_Shdr * data_sec,
8954 struct arm_section * data_arm_sec)
fa197c1c
PB
8955{
8956 struct absaddr addr;
32ec8896 8957 bfd_boolean res = TRUE;
0b6ae522
DJ
8958
8959 /* Decode the unwinding instructions. */
8960 while (1)
8961 {
8962 unsigned int op, op2;
8963
8964 ADVANCE;
8965 if (remaining == 0)
8966 break;
8967 remaining--;
8968 op = word >> 24;
8969 word <<= 8;
8970
cc5914eb 8971 printf (" 0x%02x ", op);
0b6ae522
DJ
8972
8973 if ((op & 0xc0) == 0x00)
8974 {
8975 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8976
cc5914eb 8977 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
8978 }
8979 else if ((op & 0xc0) == 0x40)
8980 {
8981 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8982
cc5914eb 8983 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
8984 }
8985 else if ((op & 0xf0) == 0x80)
8986 {
8987 GET_OP (op2);
8988 if (op == 0x80 && op2 == 0)
8989 printf (_("Refuse to unwind"));
8990 else
8991 {
8992 unsigned int mask = ((op & 0x0f) << 8) | op2;
32ec8896 8993 bfd_boolean first = TRUE;
0b6ae522 8994 int i;
2b692964 8995
0b6ae522
DJ
8996 printf ("pop {");
8997 for (i = 0; i < 12; i++)
8998 if (mask & (1 << i))
8999 {
9000 if (first)
32ec8896 9001 first = FALSE;
0b6ae522
DJ
9002 else
9003 printf (", ");
9004 printf ("r%d", 4 + i);
9005 }
9006 printf ("}");
9007 }
9008 }
9009 else if ((op & 0xf0) == 0x90)
9010 {
9011 if (op == 0x9d || op == 0x9f)
9012 printf (_(" [Reserved]"));
9013 else
cc5914eb 9014 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9015 }
9016 else if ((op & 0xf0) == 0xa0)
9017 {
9018 int end = 4 + (op & 0x07);
32ec8896 9019 bfd_boolean first = TRUE;
0b6ae522 9020 int i;
61865e30 9021
0b6ae522
DJ
9022 printf (" pop {");
9023 for (i = 4; i <= end; i++)
9024 {
9025 if (first)
32ec8896 9026 first = FALSE;
0b6ae522
DJ
9027 else
9028 printf (", ");
9029 printf ("r%d", i);
9030 }
9031 if (op & 0x08)
9032 {
1b31d05e 9033 if (!first)
0b6ae522
DJ
9034 printf (", ");
9035 printf ("r14");
9036 }
9037 printf ("}");
9038 }
9039 else if (op == 0xb0)
9040 printf (_(" finish"));
9041 else if (op == 0xb1)
9042 {
9043 GET_OP (op2);
9044 if (op2 == 0 || (op2 & 0xf0) != 0)
9045 printf (_("[Spare]"));
9046 else
9047 {
9048 unsigned int mask = op2 & 0x0f;
32ec8896 9049 bfd_boolean first = TRUE;
0b6ae522 9050 int i;
61865e30 9051
0b6ae522
DJ
9052 printf ("pop {");
9053 for (i = 0; i < 12; i++)
9054 if (mask & (1 << i))
9055 {
9056 if (first)
32ec8896 9057 first = FALSE;
0b6ae522
DJ
9058 else
9059 printf (", ");
9060 printf ("r%d", i);
9061 }
9062 printf ("}");
9063 }
9064 }
9065 else if (op == 0xb2)
9066 {
b115cf96 9067 unsigned char buf[9];
0b6ae522
DJ
9068 unsigned int i, len;
9069 unsigned long offset;
61865e30 9070
b115cf96 9071 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9072 {
9073 GET_OP (buf[i]);
9074 if ((buf[i] & 0x80) == 0)
9075 break;
9076 }
4082ef84 9077 if (i == sizeof (buf))
32ec8896 9078 {
27a45f42 9079 error (_("corrupt change to vsp\n"));
32ec8896
NC
9080 res = FALSE;
9081 }
4082ef84
NC
9082 else
9083 {
cd30bcef 9084 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
4082ef84
NC
9085 assert (len == i + 1);
9086 offset = offset * 4 + 0x204;
9087 printf ("vsp = vsp + %ld", offset);
9088 }
0b6ae522 9089 }
61865e30 9090 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9091 {
61865e30
NC
9092 unsigned int first, last;
9093
9094 GET_OP (op2);
9095 first = op2 >> 4;
9096 last = op2 & 0x0f;
9097 if (op == 0xc8)
9098 first = first + 16;
9099 printf ("pop {D%d", first);
9100 if (last)
9101 printf ("-D%d", first + last);
9102 printf ("}");
9103 }
9104 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9105 {
9106 unsigned int count = op & 0x07;
9107
9108 printf ("pop {D8");
9109 if (count)
9110 printf ("-D%d", 8 + count);
9111 printf ("}");
9112 }
9113 else if (op >= 0xc0 && op <= 0xc5)
9114 {
9115 unsigned int count = op & 0x07;
9116
9117 printf (" pop {wR10");
9118 if (count)
9119 printf ("-wR%d", 10 + count);
9120 printf ("}");
9121 }
9122 else if (op == 0xc6)
9123 {
9124 unsigned int first, last;
9125
9126 GET_OP (op2);
9127 first = op2 >> 4;
9128 last = op2 & 0x0f;
9129 printf ("pop {wR%d", first);
9130 if (last)
9131 printf ("-wR%d", first + last);
9132 printf ("}");
9133 }
9134 else if (op == 0xc7)
9135 {
9136 GET_OP (op2);
9137 if (op2 == 0 || (op2 & 0xf0) != 0)
9138 printf (_("[Spare]"));
0b6ae522
DJ
9139 else
9140 {
61865e30 9141 unsigned int mask = op2 & 0x0f;
32ec8896 9142 bfd_boolean first = TRUE;
61865e30
NC
9143 int i;
9144
9145 printf ("pop {");
9146 for (i = 0; i < 4; i++)
9147 if (mask & (1 << i))
9148 {
9149 if (first)
32ec8896 9150 first = FALSE;
61865e30
NC
9151 else
9152 printf (", ");
9153 printf ("wCGR%d", i);
9154 }
9155 printf ("}");
0b6ae522
DJ
9156 }
9157 }
61865e30 9158 else
32ec8896
NC
9159 {
9160 printf (_(" [unsupported opcode]"));
9161 res = FALSE;
9162 }
9163
0b6ae522
DJ
9164 printf ("\n");
9165 }
32ec8896
NC
9166
9167 return res;
fa197c1c
PB
9168}
9169
32ec8896 9170static bfd_boolean
dda8d76d
NC
9171decode_tic6x_unwind_bytecode (Filedata * filedata,
9172 struct arm_unw_aux_info * aux,
948f632f
DA
9173 unsigned int word,
9174 unsigned int remaining,
9175 unsigned int more_words,
9176 bfd_vma data_offset,
9177 Elf_Internal_Shdr * data_sec,
9178 struct arm_section * data_arm_sec)
fa197c1c
PB
9179{
9180 struct absaddr addr;
9181
9182 /* Decode the unwinding instructions. */
9183 while (1)
9184 {
9185 unsigned int op, op2;
9186
9187 ADVANCE;
9188 if (remaining == 0)
9189 break;
9190 remaining--;
9191 op = word >> 24;
9192 word <<= 8;
9193
9cf03b7e 9194 printf (" 0x%02x ", op);
fa197c1c
PB
9195
9196 if ((op & 0xc0) == 0x00)
9197 {
9198 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9199 printf (" sp = sp + %d", offset);
fa197c1c
PB
9200 }
9201 else if ((op & 0xc0) == 0x80)
9202 {
9203 GET_OP (op2);
9204 if (op == 0x80 && op2 == 0)
9205 printf (_("Refuse to unwind"));
9206 else
9207 {
9208 unsigned int mask = ((op & 0x1f) << 8) | op2;
9209 if (op & 0x20)
9210 printf ("pop compact {");
9211 else
9212 printf ("pop {");
9213
9214 decode_tic6x_unwind_regmask (mask);
9215 printf("}");
9216 }
9217 }
9218 else if ((op & 0xf0) == 0xc0)
9219 {
9220 unsigned int reg;
9221 unsigned int nregs;
9222 unsigned int i;
9223 const char *name;
a734115a
NC
9224 struct
9225 {
32ec8896
NC
9226 unsigned int offset;
9227 unsigned int reg;
fa197c1c
PB
9228 } regpos[16];
9229
9230 /* Scan entire instruction first so that GET_OP output is not
9231 interleaved with disassembly. */
9232 nregs = 0;
9233 for (i = 0; nregs < (op & 0xf); i++)
9234 {
9235 GET_OP (op2);
9236 reg = op2 >> 4;
9237 if (reg != 0xf)
9238 {
9239 regpos[nregs].offset = i * 2;
9240 regpos[nregs].reg = reg;
9241 nregs++;
9242 }
9243
9244 reg = op2 & 0xf;
9245 if (reg != 0xf)
9246 {
9247 regpos[nregs].offset = i * 2 + 1;
9248 regpos[nregs].reg = reg;
9249 nregs++;
9250 }
9251 }
9252
9253 printf (_("pop frame {"));
18344509 9254 if (nregs == 0)
fa197c1c 9255 {
18344509
NC
9256 printf (_("*corrupt* - no registers specified"));
9257 }
9258 else
9259 {
9260 reg = nregs - 1;
9261 for (i = i * 2; i > 0; i--)
fa197c1c 9262 {
18344509
NC
9263 if (regpos[reg].offset == i - 1)
9264 {
9265 name = tic6x_unwind_regnames[regpos[reg].reg];
9266 if (reg > 0)
9267 reg--;
9268 }
9269 else
9270 name = _("[pad]");
fa197c1c 9271
18344509
NC
9272 fputs (name, stdout);
9273 if (i > 1)
9274 printf (", ");
9275 }
fa197c1c
PB
9276 }
9277
9278 printf ("}");
9279 }
9280 else if (op == 0xd0)
9281 printf (" MOV FP, SP");
9282 else if (op == 0xd1)
9283 printf (" __c6xabi_pop_rts");
9284 else if (op == 0xd2)
9285 {
9286 unsigned char buf[9];
9287 unsigned int i, len;
9288 unsigned long offset;
a734115a 9289
fa197c1c
PB
9290 for (i = 0; i < sizeof (buf); i++)
9291 {
9292 GET_OP (buf[i]);
9293 if ((buf[i] & 0x80) == 0)
9294 break;
9295 }
0eff7165
NC
9296 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9297 if (i == sizeof (buf))
9298 {
0eff7165 9299 warn (_("Corrupt stack pointer adjustment detected\n"));
32ec8896 9300 return FALSE;
0eff7165 9301 }
948f632f 9302
cd30bcef 9303 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
fa197c1c
PB
9304 assert (len == i + 1);
9305 offset = offset * 8 + 0x408;
9306 printf (_("sp = sp + %ld"), offset);
9307 }
9308 else if ((op & 0xf0) == 0xe0)
9309 {
9310 if ((op & 0x0f) == 7)
9311 printf (" RETURN");
9312 else
9313 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9314 }
9315 else
9316 {
9317 printf (_(" [unsupported opcode]"));
9318 }
9319 putchar ('\n');
9320 }
32ec8896
NC
9321
9322 return TRUE;
fa197c1c
PB
9323}
9324
9325static bfd_vma
dda8d76d 9326arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9327{
9328 bfd_vma offset;
9329
9330 offset = word & 0x7fffffff;
9331 if (offset & 0x40000000)
9332 offset |= ~ (bfd_vma) 0x7fffffff;
9333
dda8d76d 9334 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9335 offset <<= 1;
9336
9337 return offset + where;
9338}
9339
32ec8896 9340static bfd_boolean
dda8d76d
NC
9341decode_arm_unwind (Filedata * filedata,
9342 struct arm_unw_aux_info * aux,
1b31d05e
NC
9343 unsigned int word,
9344 unsigned int remaining,
9345 bfd_vma data_offset,
9346 Elf_Internal_Shdr * data_sec,
9347 struct arm_section * data_arm_sec)
fa197c1c
PB
9348{
9349 int per_index;
9350 unsigned int more_words = 0;
37e14bc3 9351 struct absaddr addr;
1b31d05e 9352 bfd_vma sym_name = (bfd_vma) -1;
97953bab 9353 bfd_boolean res = TRUE;
fa197c1c
PB
9354
9355 if (remaining == 0)
9356 {
1b31d05e
NC
9357 /* Fetch the first word.
9358 Note - when decoding an object file the address extracted
9359 here will always be 0. So we also pass in the sym_name
9360 parameter so that we can find the symbol associated with
9361 the personality routine. */
dda8d76d 9362 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9363 & word, & addr, & sym_name))
32ec8896 9364 return FALSE;
1b31d05e 9365
fa197c1c
PB
9366 remaining = 4;
9367 }
c93dbb25
CZ
9368 else
9369 {
9370 addr.section = SHN_UNDEF;
9371 addr.offset = 0;
9372 }
fa197c1c
PB
9373
9374 if ((word & 0x80000000) == 0)
9375 {
9376 /* Expand prel31 for personality routine. */
9377 bfd_vma fn;
9378 const char *procname;
9379
dda8d76d 9380 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9381 printf (_(" Personality routine: "));
1b31d05e
NC
9382 if (fn == 0
9383 && addr.section == SHN_UNDEF && addr.offset == 0
9384 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9385 {
9386 procname = aux->strtab + sym_name;
9387 print_vma (fn, PREFIX_HEX);
9388 if (procname)
9389 {
9390 fputs (" <", stdout);
9391 fputs (procname, stdout);
9392 fputc ('>', stdout);
9393 }
9394 }
9395 else
dda8d76d 9396 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9397 fputc ('\n', stdout);
9398
9399 /* The GCC personality routines use the standard compact
9400 encoding, starting with one byte giving the number of
9401 words. */
9402 if (procname != NULL
9403 && (const_strneq (procname, "__gcc_personality_v0")
9404 || const_strneq (procname, "__gxx_personality_v0")
9405 || const_strneq (procname, "__gcj_personality_v0")
9406 || const_strneq (procname, "__gnu_objc_personality_v0")))
9407 {
9408 remaining = 0;
9409 more_words = 1;
9410 ADVANCE;
9411 if (!remaining)
9412 {
9413 printf (_(" [Truncated data]\n"));
32ec8896 9414 return FALSE;
fa197c1c
PB
9415 }
9416 more_words = word >> 24;
9417 word <<= 8;
9418 remaining--;
9419 per_index = -1;
9420 }
9421 else
32ec8896 9422 return TRUE;
fa197c1c
PB
9423 }
9424 else
9425 {
1b31d05e 9426 /* ARM EHABI Section 6.3:
0b4362b0 9427
1b31d05e 9428 An exception-handling table entry for the compact model looks like:
0b4362b0 9429
1b31d05e
NC
9430 31 30-28 27-24 23-0
9431 -- ----- ----- ----
9432 1 0 index Data for personalityRoutine[index] */
9433
dda8d76d 9434 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9435 && (word & 0x70000000))
32ec8896
NC
9436 {
9437 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
9438 res = FALSE;
9439 }
1b31d05e 9440
fa197c1c 9441 per_index = (word >> 24) & 0x7f;
1b31d05e 9442 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9443 if (per_index == 0)
9444 {
9445 more_words = 0;
9446 word <<= 8;
9447 remaining--;
9448 }
9449 else if (per_index < 3)
9450 {
9451 more_words = (word >> 16) & 0xff;
9452 word <<= 16;
9453 remaining -= 2;
9454 }
9455 }
9456
dda8d76d 9457 switch (filedata->file_header.e_machine)
fa197c1c
PB
9458 {
9459 case EM_ARM:
9460 if (per_index < 3)
9461 {
dda8d76d 9462 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9463 data_offset, data_sec, data_arm_sec))
9464 res = FALSE;
fa197c1c
PB
9465 }
9466 else
1b31d05e
NC
9467 {
9468 warn (_("Unknown ARM compact model index encountered\n"));
9469 printf (_(" [reserved]\n"));
32ec8896 9470 res = FALSE;
1b31d05e 9471 }
fa197c1c
PB
9472 break;
9473
9474 case EM_TI_C6000:
9475 if (per_index < 3)
9476 {
dda8d76d 9477 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9478 data_offset, data_sec, data_arm_sec))
9479 res = FALSE;
fa197c1c
PB
9480 }
9481 else if (per_index < 5)
9482 {
9483 if (((word >> 17) & 0x7f) == 0x7f)
9484 printf (_(" Restore stack from frame pointer\n"));
9485 else
9486 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9487 printf (_(" Registers restored: "));
9488 if (per_index == 4)
9489 printf (" (compact) ");
9490 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9491 putchar ('\n');
9492 printf (_(" Return register: %s\n"),
9493 tic6x_unwind_regnames[word & 0xf]);
9494 }
9495 else
1b31d05e 9496 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9497 break;
9498
9499 default:
74e1a04b 9500 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9501 filedata->file_header.e_machine);
32ec8896 9502 res = FALSE;
fa197c1c 9503 }
0b6ae522
DJ
9504
9505 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9506
9507 return res;
0b6ae522
DJ
9508}
9509
32ec8896 9510static bfd_boolean
dda8d76d
NC
9511dump_arm_unwind (Filedata * filedata,
9512 struct arm_unw_aux_info * aux,
9513 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9514{
9515 struct arm_section exidx_arm_sec, extab_arm_sec;
9516 unsigned int i, exidx_len;
948f632f 9517 unsigned long j, nfuns;
32ec8896 9518 bfd_boolean res = TRUE;
0b6ae522
DJ
9519
9520 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9521 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9522 exidx_len = exidx_sec->sh_size / 8;
9523
948f632f
DA
9524 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9525 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9526 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9527 aux->funtab[nfuns++] = aux->symtab[j];
9528 aux->nfuns = nfuns;
9529 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9530
0b6ae522
DJ
9531 for (i = 0; i < exidx_len; i++)
9532 {
9533 unsigned int exidx_fn, exidx_entry;
9534 struct absaddr fn_addr, entry_addr;
9535 bfd_vma fn;
9536
9537 fputc ('\n', stdout);
9538
dda8d76d 9539 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9540 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9541 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9542 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9543 {
948f632f 9544 free (aux->funtab);
1b31d05e
NC
9545 arm_free_section (& exidx_arm_sec);
9546 arm_free_section (& extab_arm_sec);
32ec8896 9547 return FALSE;
0b6ae522
DJ
9548 }
9549
83c257ca
NC
9550 /* ARM EHABI, Section 5:
9551 An index table entry consists of 2 words.
9552 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9553 if (exidx_fn & 0x80000000)
32ec8896
NC
9554 {
9555 warn (_("corrupt index table entry: %x\n"), exidx_fn);
9556 res = FALSE;
9557 }
83c257ca 9558
dda8d76d 9559 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9560
dda8d76d 9561 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9562 fputs (": ", stdout);
9563
9564 if (exidx_entry == 1)
9565 {
9566 print_vma (exidx_entry, PREFIX_HEX);
9567 fputs (" [cantunwind]\n", stdout);
9568 }
9569 else if (exidx_entry & 0x80000000)
9570 {
9571 print_vma (exidx_entry, PREFIX_HEX);
9572 fputc ('\n', stdout);
dda8d76d 9573 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9574 }
9575 else
9576 {
8f73510c 9577 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9578 Elf_Internal_Shdr *table_sec;
9579
9580 fputs ("@", stdout);
dda8d76d 9581 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9582 print_vma (table, PREFIX_HEX);
9583 printf ("\n");
9584
9585 /* Locate the matching .ARM.extab. */
9586 if (entry_addr.section != SHN_UNDEF
dda8d76d 9587 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9588 {
dda8d76d 9589 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9590 table_offset = entry_addr.offset;
1a915552
NC
9591 /* PR 18879 */
9592 if (table_offset > table_sec->sh_size
9593 || ((bfd_signed_vma) table_offset) < 0)
9594 {
9595 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9596 (unsigned long) table_offset,
dda8d76d 9597 printable_section_name (filedata, table_sec));
32ec8896 9598 res = FALSE;
1a915552
NC
9599 continue;
9600 }
0b6ae522
DJ
9601 }
9602 else
9603 {
dda8d76d 9604 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9605 if (table_sec != NULL)
9606 table_offset = table - table_sec->sh_addr;
9607 }
32ec8896 9608
0b6ae522
DJ
9609 if (table_sec == NULL)
9610 {
9611 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9612 (unsigned long) table);
32ec8896 9613 res = FALSE;
0b6ae522
DJ
9614 continue;
9615 }
32ec8896 9616
dda8d76d 9617 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896
NC
9618 &extab_arm_sec))
9619 res = FALSE;
0b6ae522
DJ
9620 }
9621 }
9622
9623 printf ("\n");
9624
948f632f 9625 free (aux->funtab);
0b6ae522
DJ
9626 arm_free_section (&exidx_arm_sec);
9627 arm_free_section (&extab_arm_sec);
32ec8896
NC
9628
9629 return res;
0b6ae522
DJ
9630}
9631
fa197c1c 9632/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9633
32ec8896 9634static bfd_boolean
dda8d76d 9635arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9636{
9637 struct arm_unw_aux_info aux;
9638 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9639 Elf_Internal_Shdr *sec;
9640 unsigned long i;
fa197c1c 9641 unsigned int sec_type;
32ec8896 9642 bfd_boolean res = TRUE;
0b6ae522 9643
dda8d76d 9644 switch (filedata->file_header.e_machine)
fa197c1c
PB
9645 {
9646 case EM_ARM:
9647 sec_type = SHT_ARM_EXIDX;
9648 break;
9649
9650 case EM_TI_C6000:
9651 sec_type = SHT_C6000_UNWIND;
9652 break;
9653
0b4362b0 9654 default:
74e1a04b 9655 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9656 filedata->file_header.e_machine);
32ec8896 9657 return FALSE;
fa197c1c
PB
9658 }
9659
dda8d76d 9660 if (filedata->string_table == NULL)
32ec8896 9661 return FALSE;
1b31d05e
NC
9662
9663 memset (& aux, 0, sizeof (aux));
dda8d76d 9664 aux.filedata = filedata;
0b6ae522 9665
dda8d76d 9666 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9667 {
28d13567 9668 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9669 {
28d13567 9670 if (aux.symtab)
74e1a04b 9671 {
28d13567
AM
9672 error (_("Multiple symbol tables encountered\n"));
9673 free (aux.symtab);
9674 aux.symtab = NULL;
74e1a04b 9675 free (aux.strtab);
28d13567 9676 aux.strtab = NULL;
74e1a04b 9677 }
28d13567
AM
9678 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9679 &aux.strtab, &aux.strtab_size))
9680 return FALSE;
0b6ae522 9681 }
fa197c1c 9682 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9683 unwsec = sec;
9684 }
9685
1b31d05e 9686 if (unwsec == NULL)
0b6ae522 9687 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9688 else
dda8d76d 9689 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9690 {
9691 if (sec->sh_type == sec_type)
9692 {
d3a49aa8
AM
9693 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9694 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9695 "contains %lu entry:\n",
9696 "\nUnwind section '%s' at offset 0x%lx "
9697 "contains %lu entries:\n",
9698 num_unwind),
dda8d76d 9699 printable_section_name (filedata, sec),
1b31d05e 9700 (unsigned long) sec->sh_offset,
d3a49aa8 9701 num_unwind);
0b6ae522 9702
dda8d76d 9703 if (! dump_arm_unwind (filedata, &aux, sec))
32ec8896 9704 res = FALSE;
1b31d05e
NC
9705 }
9706 }
0b6ae522 9707
9db70fc3
AM
9708 free (aux.symtab);
9709 free ((char *) aux.strtab);
32ec8896
NC
9710
9711 return res;
0b6ae522
DJ
9712}
9713
32ec8896 9714static bfd_boolean
dda8d76d 9715process_unwind (Filedata * filedata)
57346661 9716{
2cf0635d
NC
9717 struct unwind_handler
9718 {
32ec8896 9719 unsigned int machtype;
dda8d76d 9720 bfd_boolean (* handler)(Filedata *);
2cf0635d
NC
9721 } handlers[] =
9722 {
0b6ae522 9723 { EM_ARM, arm_process_unwind },
57346661
AM
9724 { EM_IA_64, ia64_process_unwind },
9725 { EM_PARISC, hppa_process_unwind },
fa197c1c 9726 { EM_TI_C6000, arm_process_unwind },
32ec8896 9727 { 0, NULL }
57346661
AM
9728 };
9729 int i;
9730
9731 if (!do_unwind)
32ec8896 9732 return TRUE;
57346661
AM
9733
9734 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9735 if (filedata->file_header.e_machine == handlers[i].machtype)
9736 return handlers[i].handler (filedata);
57346661 9737
1b31d05e 9738 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9739 get_machine_name (filedata->file_header.e_machine));
32ec8896 9740 return TRUE;
57346661
AM
9741}
9742
37c18eed
SD
9743static void
9744dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
9745{
9746 switch (entry->d_tag)
9747 {
9748 case DT_AARCH64_BTI_PLT:
1dbade74 9749 case DT_AARCH64_PAC_PLT:
37c18eed
SD
9750 break;
9751 default:
9752 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9753 break;
9754 }
9755 putchar ('\n');
9756}
9757
252b5132 9758static void
978c4450 9759dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
9760{
9761 switch (entry->d_tag)
9762 {
9763 case DT_MIPS_FLAGS:
9764 if (entry->d_un.d_val == 0)
4b68bca3 9765 printf (_("NONE"));
252b5132
RH
9766 else
9767 {
9768 static const char * opts[] =
9769 {
9770 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9771 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9772 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9773 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9774 "RLD_ORDER_SAFE"
9775 };
9776 unsigned int cnt;
32ec8896 9777 bfd_boolean first = TRUE;
2b692964 9778
60bca95a 9779 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9780 if (entry->d_un.d_val & (1 << cnt))
9781 {
9782 printf ("%s%s", first ? "" : " ", opts[cnt]);
32ec8896 9783 first = FALSE;
252b5132 9784 }
252b5132
RH
9785 }
9786 break;
103f02d3 9787
252b5132 9788 case DT_MIPS_IVERSION:
978c4450
AM
9789 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
9790 printf (_("Interface Version: %s"),
9791 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 9792 else
76ca31c0
NC
9793 {
9794 char buf[40];
9795 sprintf_vma (buf, entry->d_un.d_ptr);
9796 /* Note: coded this way so that there is a single string for translation. */
9797 printf (_("<corrupt: %s>"), buf);
9798 }
252b5132 9799 break;
103f02d3 9800
252b5132
RH
9801 case DT_MIPS_TIME_STAMP:
9802 {
d5b07ef4 9803 char timebuf[128];
2cf0635d 9804 struct tm * tmp;
91d6fa6a 9805 time_t atime = entry->d_un.d_val;
82b1b41b 9806
91d6fa6a 9807 tmp = gmtime (&atime);
82b1b41b
NC
9808 /* PR 17531: file: 6accc532. */
9809 if (tmp == NULL)
9810 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9811 else
9812 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9813 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9814 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9815 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9816 }
9817 break;
103f02d3 9818
252b5132
RH
9819 case DT_MIPS_RLD_VERSION:
9820 case DT_MIPS_LOCAL_GOTNO:
9821 case DT_MIPS_CONFLICTNO:
9822 case DT_MIPS_LIBLISTNO:
9823 case DT_MIPS_SYMTABNO:
9824 case DT_MIPS_UNREFEXTNO:
9825 case DT_MIPS_HIPAGENO:
9826 case DT_MIPS_DELTA_CLASS_NO:
9827 case DT_MIPS_DELTA_INSTANCE_NO:
9828 case DT_MIPS_DELTA_RELOC_NO:
9829 case DT_MIPS_DELTA_SYM_NO:
9830 case DT_MIPS_DELTA_CLASSSYM_NO:
9831 case DT_MIPS_COMPACT_SIZE:
c69075ac 9832 print_vma (entry->d_un.d_val, DEC);
252b5132 9833 break;
103f02d3 9834
f16a9783 9835 case DT_MIPS_XHASH:
978c4450
AM
9836 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
9837 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
9838 /* Falls through. */
9839
103f02d3 9840 default:
4b68bca3 9841 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9842 }
4b68bca3 9843 putchar ('\n');
103f02d3
UD
9844}
9845
103f02d3 9846static void
2cf0635d 9847dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9848{
9849 switch (entry->d_tag)
9850 {
9851 case DT_HP_DLD_FLAGS:
9852 {
9853 static struct
9854 {
9855 long int bit;
2cf0635d 9856 const char * str;
5e220199
NC
9857 }
9858 flags[] =
9859 {
9860 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9861 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9862 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9863 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9864 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9865 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9866 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9867 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9868 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9869 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9870 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9871 { DT_HP_GST, "HP_GST" },
9872 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
9873 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
9874 { DT_HP_NODELETE, "HP_NODELETE" },
9875 { DT_HP_GROUP, "HP_GROUP" },
9876 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 9877 };
32ec8896 9878 bfd_boolean first = TRUE;
5e220199 9879 size_t cnt;
f7a99963 9880 bfd_vma val = entry->d_un.d_val;
103f02d3 9881
60bca95a 9882 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 9883 if (val & flags[cnt].bit)
30800947
NC
9884 {
9885 if (! first)
9886 putchar (' ');
9887 fputs (flags[cnt].str, stdout);
32ec8896 9888 first = FALSE;
30800947
NC
9889 val ^= flags[cnt].bit;
9890 }
76da6bbe 9891
103f02d3 9892 if (val != 0 || first)
f7a99963
NC
9893 {
9894 if (! first)
9895 putchar (' ');
9896 print_vma (val, HEX);
9897 }
103f02d3
UD
9898 }
9899 break;
76da6bbe 9900
252b5132 9901 default:
f7a99963
NC
9902 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9903 break;
252b5132 9904 }
35b1837e 9905 putchar ('\n');
252b5132
RH
9906}
9907
28f997cf
TG
9908#ifdef BFD64
9909
9910/* VMS vs Unix time offset and factor. */
9911
9912#define VMS_EPOCH_OFFSET 35067168000000000LL
9913#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
9914#ifndef INT64_MIN
9915#define INT64_MIN (-9223372036854775807LL - 1)
9916#endif
28f997cf
TG
9917
9918/* Display a VMS time in a human readable format. */
9919
9920static void
9921print_vms_time (bfd_int64_t vmstime)
9922{
dccc31de 9923 struct tm *tm = NULL;
28f997cf
TG
9924 time_t unxtime;
9925
dccc31de
AM
9926 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
9927 {
9928 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
9929 unxtime = vmstime;
9930 if (unxtime == vmstime)
9931 tm = gmtime (&unxtime);
9932 }
9933 if (tm != NULL)
9934 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
9935 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
9936 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
9937}
9938#endif /* BFD64 */
9939
ecc51f48 9940static void
2cf0635d 9941dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
9942{
9943 switch (entry->d_tag)
9944 {
0de14b54 9945 case DT_IA_64_PLT_RESERVE:
bdf4d63a 9946 /* First 3 slots reserved. */
ecc51f48
NC
9947 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9948 printf (" -- ");
9949 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
9950 break;
9951
28f997cf
TG
9952 case DT_IA_64_VMS_LINKTIME:
9953#ifdef BFD64
9954 print_vms_time (entry->d_un.d_val);
9955#endif
9956 break;
9957
9958 case DT_IA_64_VMS_LNKFLAGS:
9959 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9960 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
9961 printf (" CALL_DEBUG");
9962 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
9963 printf (" NOP0BUFS");
9964 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
9965 printf (" P0IMAGE");
9966 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
9967 printf (" MKTHREADS");
9968 if (entry->d_un.d_val & VMS_LF_UPCALLS)
9969 printf (" UPCALLS");
9970 if (entry->d_un.d_val & VMS_LF_IMGSTA)
9971 printf (" IMGSTA");
9972 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
9973 printf (" INITIALIZE");
9974 if (entry->d_un.d_val & VMS_LF_MAIN)
9975 printf (" MAIN");
9976 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
9977 printf (" EXE_INIT");
9978 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
9979 printf (" TBK_IN_IMG");
9980 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
9981 printf (" DBG_IN_IMG");
9982 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
9983 printf (" TBK_IN_DSF");
9984 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
9985 printf (" DBG_IN_DSF");
9986 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
9987 printf (" SIGNATURES");
9988 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
9989 printf (" REL_SEG_OFF");
9990 break;
9991
bdf4d63a
JJ
9992 default:
9993 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9994 break;
ecc51f48 9995 }
bdf4d63a 9996 putchar ('\n');
ecc51f48
NC
9997}
9998
32ec8896 9999static bfd_boolean
dda8d76d 10000get_32bit_dynamic_section (Filedata * filedata)
252b5132 10001{
2cf0635d
NC
10002 Elf32_External_Dyn * edyn;
10003 Elf32_External_Dyn * ext;
10004 Elf_Internal_Dyn * entry;
103f02d3 10005
978c4450
AM
10006 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10007 filedata->dynamic_addr, 1,
10008 filedata->dynamic_size,
10009 _("dynamic section"));
a6e9f9df 10010 if (!edyn)
32ec8896 10011 return FALSE;
103f02d3 10012
071436c6
NC
10013 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10014 might not have the luxury of section headers. Look for the DT_NULL
10015 terminator to determine the number of entries. */
978c4450
AM
10016 for (ext = edyn, filedata->dynamic_nent = 0;
10017 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10018 ext++)
10019 {
978c4450 10020 filedata->dynamic_nent++;
ba2685cc
AM
10021 if (BYTE_GET (ext->d_tag) == DT_NULL)
10022 break;
10023 }
252b5132 10024
978c4450
AM
10025 filedata->dynamic_section
10026 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10027 if (filedata->dynamic_section == NULL)
252b5132 10028 {
8b73c356 10029 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10030 (unsigned long) filedata->dynamic_nent);
9ea033b2 10031 free (edyn);
32ec8896 10032 return FALSE;
9ea033b2 10033 }
252b5132 10034
978c4450
AM
10035 for (ext = edyn, entry = filedata->dynamic_section;
10036 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10037 ext++, entry++)
9ea033b2 10038 {
fb514b26
AM
10039 entry->d_tag = BYTE_GET (ext->d_tag);
10040 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10041 }
10042
9ea033b2
NC
10043 free (edyn);
10044
32ec8896 10045 return TRUE;
9ea033b2
NC
10046}
10047
32ec8896 10048static bfd_boolean
dda8d76d 10049get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10050{
2cf0635d
NC
10051 Elf64_External_Dyn * edyn;
10052 Elf64_External_Dyn * ext;
10053 Elf_Internal_Dyn * entry;
103f02d3 10054
071436c6 10055 /* Read in the data. */
978c4450
AM
10056 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10057 filedata->dynamic_addr, 1,
10058 filedata->dynamic_size,
10059 _("dynamic section"));
a6e9f9df 10060 if (!edyn)
32ec8896 10061 return FALSE;
103f02d3 10062
071436c6
NC
10063 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10064 might not have the luxury of section headers. Look for the DT_NULL
10065 terminator to determine the number of entries. */
978c4450 10066 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10067 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10068 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10069 ext++)
10070 {
978c4450 10071 filedata->dynamic_nent++;
66543521 10072 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10073 break;
10074 }
252b5132 10075
978c4450
AM
10076 filedata->dynamic_section
10077 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10078 if (filedata->dynamic_section == NULL)
252b5132 10079 {
8b73c356 10080 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10081 (unsigned long) filedata->dynamic_nent);
252b5132 10082 free (edyn);
32ec8896 10083 return FALSE;
252b5132
RH
10084 }
10085
071436c6 10086 /* Convert from external to internal formats. */
978c4450
AM
10087 for (ext = edyn, entry = filedata->dynamic_section;
10088 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10089 ext++, entry++)
252b5132 10090 {
66543521
AM
10091 entry->d_tag = BYTE_GET (ext->d_tag);
10092 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10093 }
10094
10095 free (edyn);
10096
32ec8896 10097 return TRUE;
9ea033b2
NC
10098}
10099
e9e44622
JJ
10100static void
10101print_dynamic_flags (bfd_vma flags)
d1133906 10102{
32ec8896 10103 bfd_boolean first = TRUE;
13ae64f3 10104
d1133906
NC
10105 while (flags)
10106 {
10107 bfd_vma flag;
10108
10109 flag = flags & - flags;
10110 flags &= ~ flag;
10111
e9e44622 10112 if (first)
32ec8896 10113 first = FALSE;
e9e44622
JJ
10114 else
10115 putc (' ', stdout);
13ae64f3 10116
d1133906
NC
10117 switch (flag)
10118 {
e9e44622
JJ
10119 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10120 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10121 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10122 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10123 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10124 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10125 }
10126 }
e9e44622 10127 puts ("");
d1133906
NC
10128}
10129
10ca4b04
L
10130static bfd_vma *
10131get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10132{
10133 unsigned char * e_data;
10134 bfd_vma * i_data;
10135
10136 /* If the size_t type is smaller than the bfd_size_type, eg because
10137 you are building a 32-bit tool on a 64-bit host, then make sure
10138 that when (number) is cast to (size_t) no information is lost. */
10139 if (sizeof (size_t) < sizeof (bfd_size_type)
10140 && (bfd_size_type) ((size_t) number) != number)
10141 {
10142 error (_("Size truncation prevents reading %s elements of size %u\n"),
10143 bfd_vmatoa ("u", number), ent_size);
10144 return NULL;
10145 }
10146
10147 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10148 attempting to allocate memory when the read is bound to fail. */
10149 if (ent_size * number > filedata->file_size)
10150 {
10151 error (_("Invalid number of dynamic entries: %s\n"),
10152 bfd_vmatoa ("u", number));
10153 return NULL;
10154 }
10155
10156 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10157 if (e_data == NULL)
10158 {
10159 error (_("Out of memory reading %s dynamic entries\n"),
10160 bfd_vmatoa ("u", number));
10161 return NULL;
10162 }
10163
10164 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10165 {
10166 error (_("Unable to read in %s bytes of dynamic data\n"),
10167 bfd_vmatoa ("u", number * ent_size));
10168 free (e_data);
10169 return NULL;
10170 }
10171
10172 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10173 if (i_data == NULL)
10174 {
10175 error (_("Out of memory allocating space for %s dynamic entries\n"),
10176 bfd_vmatoa ("u", number));
10177 free (e_data);
10178 return NULL;
10179 }
10180
10181 while (number--)
10182 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10183
10184 free (e_data);
10185
10186 return i_data;
10187}
10188
10189static unsigned long
10190get_num_dynamic_syms (Filedata * filedata)
10191{
10192 unsigned long num_of_syms = 0;
10193
10194 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10195 return num_of_syms;
10196
978c4450 10197 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10198 {
10199 unsigned char nb[8];
10200 unsigned char nc[8];
10201 unsigned int hash_ent_size = 4;
10202
10203 if ((filedata->file_header.e_machine == EM_ALPHA
10204 || filedata->file_header.e_machine == EM_S390
10205 || filedata->file_header.e_machine == EM_S390_OLD)
10206 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10207 hash_ent_size = 8;
10208
10209 if (fseek (filedata->handle,
978c4450
AM
10210 (filedata->archive_file_offset
10211 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10212 sizeof nb + sizeof nc)),
10213 SEEK_SET))
10214 {
10215 error (_("Unable to seek to start of dynamic information\n"));
10216 goto no_hash;
10217 }
10218
10219 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10220 {
10221 error (_("Failed to read in number of buckets\n"));
10222 goto no_hash;
10223 }
10224
10225 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10226 {
10227 error (_("Failed to read in number of chains\n"));
10228 goto no_hash;
10229 }
10230
978c4450
AM
10231 filedata->nbuckets = byte_get (nb, hash_ent_size);
10232 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10233
2482f306
AM
10234 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10235 {
10236 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10237 hash_ent_size);
10238 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10239 hash_ent_size);
001890e1 10240
2482f306
AM
10241 if (filedata->buckets != NULL && filedata->chains != NULL)
10242 num_of_syms = filedata->nchains;
10243 }
ceb9bf11 10244 no_hash:
10ca4b04
L
10245 if (num_of_syms == 0)
10246 {
9db70fc3
AM
10247 free (filedata->buckets);
10248 filedata->buckets = NULL;
10249 free (filedata->chains);
10250 filedata->chains = NULL;
978c4450 10251 filedata->nbuckets = 0;
10ca4b04
L
10252 }
10253 }
10254
978c4450 10255 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10256 {
10257 unsigned char nb[16];
10258 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10259 bfd_vma buckets_vma;
10260 unsigned long hn;
10ca4b04
L
10261
10262 if (fseek (filedata->handle,
978c4450
AM
10263 (filedata->archive_file_offset
10264 + offset_from_vma (filedata,
10265 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10266 sizeof nb)),
10267 SEEK_SET))
10268 {
10269 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10270 goto no_gnu_hash;
10271 }
10272
10273 if (fread (nb, 16, 1, filedata->handle) != 1)
10274 {
10275 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10276 goto no_gnu_hash;
10277 }
10278
978c4450
AM
10279 filedata->ngnubuckets = byte_get (nb, 4);
10280 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10281 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10282 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10283 if (is_32bit_elf)
10284 buckets_vma += bitmaskwords * 4;
10285 else
10286 buckets_vma += bitmaskwords * 8;
10287
10288 if (fseek (filedata->handle,
978c4450 10289 (filedata->archive_file_offset
10ca4b04
L
10290 + offset_from_vma (filedata, buckets_vma, 4)),
10291 SEEK_SET))
10292 {
10293 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10294 goto no_gnu_hash;
10295 }
10296
978c4450
AM
10297 filedata->gnubuckets
10298 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10299
978c4450 10300 if (filedata->gnubuckets == NULL)
90837ea7 10301 goto no_gnu_hash;
10ca4b04 10302
978c4450
AM
10303 for (i = 0; i < filedata->ngnubuckets; i++)
10304 if (filedata->gnubuckets[i] != 0)
10ca4b04 10305 {
978c4450 10306 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10307 goto no_gnu_hash;
10ca4b04 10308
978c4450
AM
10309 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10310 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10311 }
10312
10313 if (maxchain == 0xffffffff)
90837ea7 10314 goto no_gnu_hash;
10ca4b04 10315
978c4450 10316 maxchain -= filedata->gnusymidx;
10ca4b04
L
10317
10318 if (fseek (filedata->handle,
978c4450
AM
10319 (filedata->archive_file_offset
10320 + offset_from_vma (filedata,
10321 buckets_vma + 4 * (filedata->ngnubuckets
10322 + maxchain),
10323 4)),
10ca4b04
L
10324 SEEK_SET))
10325 {
10326 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10327 goto no_gnu_hash;
10328 }
10329
10330 do
10331 {
10332 if (fread (nb, 4, 1, filedata->handle) != 1)
10333 {
10334 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10335 goto no_gnu_hash;
10336 }
10337
10338 if (maxchain + 1 == 0)
90837ea7 10339 goto no_gnu_hash;
10ca4b04
L
10340
10341 ++maxchain;
10342 }
10343 while ((byte_get (nb, 4) & 1) == 0);
10344
10345 if (fseek (filedata->handle,
978c4450
AM
10346 (filedata->archive_file_offset
10347 + offset_from_vma (filedata, (buckets_vma
10348 + 4 * filedata->ngnubuckets),
10349 4)),
10ca4b04
L
10350 SEEK_SET))
10351 {
10352 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10353 goto no_gnu_hash;
10354 }
10355
978c4450
AM
10356 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10357 filedata->ngnuchains = maxchain;
10ca4b04 10358
978c4450 10359 if (filedata->gnuchains == NULL)
90837ea7 10360 goto no_gnu_hash;
10ca4b04 10361
978c4450 10362 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10363 {
10364 if (fseek (filedata->handle,
978c4450 10365 (filedata->archive_file_offset
10ca4b04 10366 + offset_from_vma (filedata, (buckets_vma
978c4450 10367 + 4 * (filedata->ngnubuckets
10ca4b04
L
10368 + maxchain)), 4)),
10369 SEEK_SET))
10370 {
10371 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10372 goto no_gnu_hash;
10373 }
10374
978c4450 10375 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10376 if (filedata->mipsxlat == NULL)
10377 goto no_gnu_hash;
10ca4b04
L
10378 }
10379
978c4450
AM
10380 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10381 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10382 {
978c4450
AM
10383 bfd_vma si = filedata->gnubuckets[hn];
10384 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10385
10386 do
10387 {
978c4450 10388 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 10389 {
c31ab5a0
AM
10390 if (off < filedata->ngnuchains
10391 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 10392 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
10393 }
10394 else
10395 {
10396 if (si >= num_of_syms)
10397 num_of_syms = si + 1;
10398 }
10399 si++;
10400 }
978c4450
AM
10401 while (off < filedata->ngnuchains
10402 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
10403 }
10404
90837ea7 10405 if (num_of_syms == 0)
10ca4b04 10406 {
90837ea7 10407 no_gnu_hash:
9db70fc3
AM
10408 free (filedata->mipsxlat);
10409 filedata->mipsxlat = NULL;
10410 free (filedata->gnuchains);
10411 filedata->gnuchains = NULL;
10412 free (filedata->gnubuckets);
10413 filedata->gnubuckets = NULL;
978c4450
AM
10414 filedata->ngnubuckets = 0;
10415 filedata->ngnuchains = 0;
10ca4b04
L
10416 }
10417 }
10418
10419 return num_of_syms;
10420}
10421
b2d38a17
NC
10422/* Parse and display the contents of the dynamic section. */
10423
32ec8896 10424static bfd_boolean
dda8d76d 10425process_dynamic_section (Filedata * filedata)
9ea033b2 10426{
2cf0635d 10427 Elf_Internal_Dyn * entry;
9ea033b2 10428
978c4450 10429 if (filedata->dynamic_size == 0)
9ea033b2
NC
10430 {
10431 if (do_dynamic)
b2d38a17 10432 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2 10433
32ec8896 10434 return TRUE;
9ea033b2
NC
10435 }
10436
10437 if (is_32bit_elf)
10438 {
dda8d76d 10439 if (! get_32bit_dynamic_section (filedata))
32ec8896
NC
10440 return FALSE;
10441 }
10442 else
10443 {
dda8d76d 10444 if (! get_64bit_dynamic_section (filedata))
32ec8896 10445 return FALSE;
9ea033b2 10446 }
9ea033b2 10447
252b5132 10448 /* Find the appropriate symbol table. */
978c4450 10449 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 10450 {
2482f306
AM
10451 unsigned long num_of_syms;
10452
978c4450
AM
10453 for (entry = filedata->dynamic_section;
10454 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10455 ++entry)
10ca4b04 10456 if (entry->d_tag == DT_SYMTAB)
978c4450 10457 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 10458 else if (entry->d_tag == DT_SYMENT)
978c4450 10459 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 10460 else if (entry->d_tag == DT_HASH)
978c4450 10461 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 10462 else if (entry->d_tag == DT_GNU_HASH)
978c4450 10463 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
10464 else if ((filedata->file_header.e_machine == EM_MIPS
10465 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10466 && entry->d_tag == DT_MIPS_XHASH)
10467 {
978c4450
AM
10468 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10469 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 10470 }
252b5132 10471
2482f306
AM
10472 num_of_syms = get_num_dynamic_syms (filedata);
10473
10474 if (num_of_syms != 0
10475 && filedata->dynamic_symbols == NULL
10476 && filedata->dynamic_info[DT_SYMTAB]
978c4450 10477 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
10478 {
10479 Elf_Internal_Phdr *seg;
2482f306 10480 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 10481
2482f306
AM
10482 if (! get_program_headers (filedata))
10483 {
10484 error (_("Cannot interpret virtual addresses "
10485 "without program headers.\n"));
10486 return FALSE;
10487 }
252b5132 10488
2482f306
AM
10489 for (seg = filedata->program_headers;
10490 seg < filedata->program_headers + filedata->file_header.e_phnum;
10491 ++seg)
10492 {
10493 if (seg->p_type != PT_LOAD)
10494 continue;
252b5132 10495
2482f306
AM
10496 if (seg->p_offset + seg->p_filesz > filedata->file_size)
10497 {
10498 /* See PR 21379 for a reproducer. */
10499 error (_("Invalid PT_LOAD entry\n"));
10500 return FALSE;
10501 }
252b5132 10502
2482f306
AM
10503 if (vma >= (seg->p_vaddr & -seg->p_align)
10504 && vma < seg->p_vaddr + seg->p_filesz)
10505 {
10506 /* Since we do not know how big the symbol table is,
10507 we default to reading in up to the end of PT_LOAD
10508 segment and processing that. This is overkill, I
10509 know, but it should work. */
10510 Elf_Internal_Shdr section;
10511 section.sh_offset = (vma - seg->p_vaddr
10512 + seg->p_offset);
10513 section.sh_size = (num_of_syms
10514 * filedata->dynamic_info[DT_SYMENT]);
10515 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
10516
10517 if (do_checks
10518 && filedata->dynamic_symtab_section != NULL
10519 && ((filedata->dynamic_symtab_section->sh_offset
10520 != section.sh_offset)
10521 || (filedata->dynamic_symtab_section->sh_size
10522 != section.sh_size)
10523 || (filedata->dynamic_symtab_section->sh_entsize
10524 != section.sh_entsize)))
10525 warn (_("\
10526the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
10527
2482f306
AM
10528 section.sh_name = filedata->string_table_length;
10529 filedata->dynamic_symbols
10530 = GET_ELF_SYMBOLS (filedata, &section,
10531 &filedata->num_dynamic_syms);
10532 if (filedata->dynamic_symbols == NULL
10533 || filedata->num_dynamic_syms != num_of_syms)
10534 {
10535 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
10536 return FALSE;
10537 }
10538 break;
10539 }
10540 }
10541 }
10542 }
252b5132
RH
10543
10544 /* Similarly find a string table. */
978c4450
AM
10545 if (filedata->dynamic_strings == NULL)
10546 for (entry = filedata->dynamic_section;
10547 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
10548 ++entry)
10549 {
10550 if (entry->d_tag == DT_STRTAB)
978c4450 10551 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 10552
10ca4b04 10553 if (entry->d_tag == DT_STRSZ)
978c4450 10554 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10555
978c4450
AM
10556 if (filedata->dynamic_info[DT_STRTAB]
10557 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
10558 {
10559 unsigned long offset;
978c4450 10560 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
10561
10562 offset = offset_from_vma (filedata,
978c4450 10563 filedata->dynamic_info[DT_STRTAB],
10ca4b04 10564 str_tab_len);
8ac10c5b
L
10565 if (do_checks
10566 && filedata->dynamic_strtab_section
10567 && ((filedata->dynamic_strtab_section->sh_offset
10568 != (file_ptr) offset)
10569 || (filedata->dynamic_strtab_section->sh_size
10570 != str_tab_len)))
10571 warn (_("\
10572the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
10573
978c4450
AM
10574 filedata->dynamic_strings
10575 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
10576 _("dynamic string table"));
10577 if (filedata->dynamic_strings == NULL)
10ca4b04
L
10578 {
10579 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10580 break;
10581 }
e3d39609 10582
978c4450 10583 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
10584 break;
10585 }
10586 }
252b5132
RH
10587
10588 /* And find the syminfo section if available. */
978c4450 10589 if (filedata->dynamic_syminfo == NULL)
252b5132 10590 {
3e8bba36 10591 unsigned long syminsz = 0;
252b5132 10592
978c4450
AM
10593 for (entry = filedata->dynamic_section;
10594 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10595 ++entry)
252b5132
RH
10596 {
10597 if (entry->d_tag == DT_SYMINENT)
10598 {
10599 /* Note: these braces are necessary to avoid a syntax
10600 error from the SunOS4 C compiler. */
049b0c3a
NC
10601 /* PR binutils/17531: A corrupt file can trigger this test.
10602 So do not use an assert, instead generate an error message. */
10603 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10604 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10605 (int) entry->d_un.d_val);
252b5132
RH
10606 }
10607 else if (entry->d_tag == DT_SYMINSZ)
10608 syminsz = entry->d_un.d_val;
10609 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
10610 filedata->dynamic_syminfo_offset
10611 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
10612 }
10613
978c4450 10614 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 10615 {
2cf0635d
NC
10616 Elf_External_Syminfo * extsyminfo;
10617 Elf_External_Syminfo * extsym;
10618 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10619
10620 /* There is a syminfo section. Read the data. */
3f5e193b 10621 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
10622 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
10623 1, syminsz, _("symbol information"));
a6e9f9df 10624 if (!extsyminfo)
32ec8896 10625 return FALSE;
252b5132 10626
978c4450 10627 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
10628 {
10629 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 10630 free (filedata->dynamic_syminfo);
e3d39609 10631 }
978c4450
AM
10632 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
10633 if (filedata->dynamic_syminfo == NULL)
252b5132 10634 {
2482f306
AM
10635 error (_("Out of memory allocating %lu bytes "
10636 "for dynamic symbol info\n"),
8b73c356 10637 (unsigned long) syminsz);
32ec8896 10638 return FALSE;
252b5132
RH
10639 }
10640
2482f306
AM
10641 filedata->dynamic_syminfo_nent
10642 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 10643 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
10644 syminfo < (filedata->dynamic_syminfo
10645 + filedata->dynamic_syminfo_nent);
86dba8ee 10646 ++syminfo, ++extsym)
252b5132 10647 {
86dba8ee
AM
10648 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10649 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10650 }
10651
10652 free (extsyminfo);
10653 }
10654 }
10655
978c4450 10656 if (do_dynamic && filedata->dynamic_addr)
d3a49aa8
AM
10657 printf (ngettext ("\nDynamic section at offset 0x%lx "
10658 "contains %lu entry:\n",
10659 "\nDynamic section at offset 0x%lx "
10660 "contains %lu entries:\n",
978c4450
AM
10661 filedata->dynamic_nent),
10662 filedata->dynamic_addr, (unsigned long) filedata->dynamic_nent);
252b5132
RH
10663 if (do_dynamic)
10664 printf (_(" Tag Type Name/Value\n"));
10665
978c4450
AM
10666 for (entry = filedata->dynamic_section;
10667 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10668 entry++)
252b5132
RH
10669 {
10670 if (do_dynamic)
f7a99963 10671 {
2cf0635d 10672 const char * dtype;
e699b9ff 10673
f7a99963
NC
10674 putchar (' ');
10675 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10676 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10677 printf (" (%s)%*s", dtype,
32ec8896 10678 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10679 }
252b5132
RH
10680
10681 switch (entry->d_tag)
10682 {
d1133906
NC
10683 case DT_FLAGS:
10684 if (do_dynamic)
e9e44622 10685 print_dynamic_flags (entry->d_un.d_val);
d1133906 10686 break;
76da6bbe 10687
252b5132
RH
10688 case DT_AUXILIARY:
10689 case DT_FILTER:
019148e4
L
10690 case DT_CONFIG:
10691 case DT_DEPAUDIT:
10692 case DT_AUDIT:
252b5132
RH
10693 if (do_dynamic)
10694 {
019148e4 10695 switch (entry->d_tag)
b34976b6 10696 {
019148e4
L
10697 case DT_AUXILIARY:
10698 printf (_("Auxiliary library"));
10699 break;
10700
10701 case DT_FILTER:
10702 printf (_("Filter library"));
10703 break;
10704
b34976b6 10705 case DT_CONFIG:
019148e4
L
10706 printf (_("Configuration file"));
10707 break;
10708
10709 case DT_DEPAUDIT:
10710 printf (_("Dependency audit library"));
10711 break;
10712
10713 case DT_AUDIT:
10714 printf (_("Audit library"));
10715 break;
10716 }
252b5132 10717
978c4450
AM
10718 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10719 printf (": [%s]\n",
10720 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 10721 else
f7a99963
NC
10722 {
10723 printf (": ");
10724 print_vma (entry->d_un.d_val, PREFIX_HEX);
10725 putchar ('\n');
10726 }
252b5132
RH
10727 }
10728 break;
10729
dcefbbbd 10730 case DT_FEATURE:
252b5132
RH
10731 if (do_dynamic)
10732 {
10733 printf (_("Flags:"));
86f55779 10734
252b5132
RH
10735 if (entry->d_un.d_val == 0)
10736 printf (_(" None\n"));
10737 else
10738 {
10739 unsigned long int val = entry->d_un.d_val;
86f55779 10740
252b5132
RH
10741 if (val & DTF_1_PARINIT)
10742 {
10743 printf (" PARINIT");
10744 val ^= DTF_1_PARINIT;
10745 }
dcefbbbd
L
10746 if (val & DTF_1_CONFEXP)
10747 {
10748 printf (" CONFEXP");
10749 val ^= DTF_1_CONFEXP;
10750 }
252b5132
RH
10751 if (val != 0)
10752 printf (" %lx", val);
10753 puts ("");
10754 }
10755 }
10756 break;
10757
10758 case DT_POSFLAG_1:
10759 if (do_dynamic)
10760 {
10761 printf (_("Flags:"));
86f55779 10762
252b5132
RH
10763 if (entry->d_un.d_val == 0)
10764 printf (_(" None\n"));
10765 else
10766 {
10767 unsigned long int val = entry->d_un.d_val;
86f55779 10768
252b5132
RH
10769 if (val & DF_P1_LAZYLOAD)
10770 {
10771 printf (" LAZYLOAD");
10772 val ^= DF_P1_LAZYLOAD;
10773 }
10774 if (val & DF_P1_GROUPPERM)
10775 {
10776 printf (" GROUPPERM");
10777 val ^= DF_P1_GROUPPERM;
10778 }
10779 if (val != 0)
10780 printf (" %lx", val);
10781 puts ("");
10782 }
10783 }
10784 break;
10785
10786 case DT_FLAGS_1:
10787 if (do_dynamic)
10788 {
10789 printf (_("Flags:"));
10790 if (entry->d_un.d_val == 0)
10791 printf (_(" None\n"));
10792 else
10793 {
10794 unsigned long int val = entry->d_un.d_val;
86f55779 10795
252b5132
RH
10796 if (val & DF_1_NOW)
10797 {
10798 printf (" NOW");
10799 val ^= DF_1_NOW;
10800 }
10801 if (val & DF_1_GLOBAL)
10802 {
10803 printf (" GLOBAL");
10804 val ^= DF_1_GLOBAL;
10805 }
10806 if (val & DF_1_GROUP)
10807 {
10808 printf (" GROUP");
10809 val ^= DF_1_GROUP;
10810 }
10811 if (val & DF_1_NODELETE)
10812 {
10813 printf (" NODELETE");
10814 val ^= DF_1_NODELETE;
10815 }
10816 if (val & DF_1_LOADFLTR)
10817 {
10818 printf (" LOADFLTR");
10819 val ^= DF_1_LOADFLTR;
10820 }
10821 if (val & DF_1_INITFIRST)
10822 {
10823 printf (" INITFIRST");
10824 val ^= DF_1_INITFIRST;
10825 }
10826 if (val & DF_1_NOOPEN)
10827 {
10828 printf (" NOOPEN");
10829 val ^= DF_1_NOOPEN;
10830 }
10831 if (val & DF_1_ORIGIN)
10832 {
10833 printf (" ORIGIN");
10834 val ^= DF_1_ORIGIN;
10835 }
10836 if (val & DF_1_DIRECT)
10837 {
10838 printf (" DIRECT");
10839 val ^= DF_1_DIRECT;
10840 }
10841 if (val & DF_1_TRANS)
10842 {
10843 printf (" TRANS");
10844 val ^= DF_1_TRANS;
10845 }
10846 if (val & DF_1_INTERPOSE)
10847 {
10848 printf (" INTERPOSE");
10849 val ^= DF_1_INTERPOSE;
10850 }
f7db6139 10851 if (val & DF_1_NODEFLIB)
dcefbbbd 10852 {
f7db6139
L
10853 printf (" NODEFLIB");
10854 val ^= DF_1_NODEFLIB;
dcefbbbd
L
10855 }
10856 if (val & DF_1_NODUMP)
10857 {
10858 printf (" NODUMP");
10859 val ^= DF_1_NODUMP;
10860 }
34b60028 10861 if (val & DF_1_CONFALT)
dcefbbbd 10862 {
34b60028
L
10863 printf (" CONFALT");
10864 val ^= DF_1_CONFALT;
10865 }
10866 if (val & DF_1_ENDFILTEE)
10867 {
10868 printf (" ENDFILTEE");
10869 val ^= DF_1_ENDFILTEE;
10870 }
10871 if (val & DF_1_DISPRELDNE)
10872 {
10873 printf (" DISPRELDNE");
10874 val ^= DF_1_DISPRELDNE;
10875 }
10876 if (val & DF_1_DISPRELPND)
10877 {
10878 printf (" DISPRELPND");
10879 val ^= DF_1_DISPRELPND;
10880 }
10881 if (val & DF_1_NODIRECT)
10882 {
10883 printf (" NODIRECT");
10884 val ^= DF_1_NODIRECT;
10885 }
10886 if (val & DF_1_IGNMULDEF)
10887 {
10888 printf (" IGNMULDEF");
10889 val ^= DF_1_IGNMULDEF;
10890 }
10891 if (val & DF_1_NOKSYMS)
10892 {
10893 printf (" NOKSYMS");
10894 val ^= DF_1_NOKSYMS;
10895 }
10896 if (val & DF_1_NOHDR)
10897 {
10898 printf (" NOHDR");
10899 val ^= DF_1_NOHDR;
10900 }
10901 if (val & DF_1_EDITED)
10902 {
10903 printf (" EDITED");
10904 val ^= DF_1_EDITED;
10905 }
10906 if (val & DF_1_NORELOC)
10907 {
10908 printf (" NORELOC");
10909 val ^= DF_1_NORELOC;
10910 }
10911 if (val & DF_1_SYMINTPOSE)
10912 {
10913 printf (" SYMINTPOSE");
10914 val ^= DF_1_SYMINTPOSE;
10915 }
10916 if (val & DF_1_GLOBAUDIT)
10917 {
10918 printf (" GLOBAUDIT");
10919 val ^= DF_1_GLOBAUDIT;
10920 }
10921 if (val & DF_1_SINGLETON)
10922 {
10923 printf (" SINGLETON");
10924 val ^= DF_1_SINGLETON;
dcefbbbd 10925 }
5c383f02
RO
10926 if (val & DF_1_STUB)
10927 {
10928 printf (" STUB");
10929 val ^= DF_1_STUB;
10930 }
10931 if (val & DF_1_PIE)
10932 {
10933 printf (" PIE");
10934 val ^= DF_1_PIE;
10935 }
b1202ffa
L
10936 if (val & DF_1_KMOD)
10937 {
10938 printf (" KMOD");
10939 val ^= DF_1_KMOD;
10940 }
10941 if (val & DF_1_WEAKFILTER)
10942 {
10943 printf (" WEAKFILTER");
10944 val ^= DF_1_WEAKFILTER;
10945 }
10946 if (val & DF_1_NOCOMMON)
10947 {
10948 printf (" NOCOMMON");
10949 val ^= DF_1_NOCOMMON;
10950 }
252b5132
RH
10951 if (val != 0)
10952 printf (" %lx", val);
10953 puts ("");
10954 }
10955 }
10956 break;
10957
10958 case DT_PLTREL:
978c4450 10959 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 10960 if (do_dynamic)
dda8d76d 10961 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
10962 break;
10963
10964 case DT_NULL :
10965 case DT_NEEDED :
10966 case DT_PLTGOT :
10967 case DT_HASH :
10968 case DT_STRTAB :
10969 case DT_SYMTAB :
10970 case DT_RELA :
10971 case DT_INIT :
10972 case DT_FINI :
10973 case DT_SONAME :
10974 case DT_RPATH :
10975 case DT_SYMBOLIC:
10976 case DT_REL :
10977 case DT_DEBUG :
10978 case DT_TEXTREL :
10979 case DT_JMPREL :
019148e4 10980 case DT_RUNPATH :
978c4450 10981 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
10982
10983 if (do_dynamic)
10984 {
2cf0635d 10985 char * name;
252b5132 10986
978c4450
AM
10987 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10988 name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 10989 else
d79b3d50 10990 name = NULL;
252b5132
RH
10991
10992 if (name)
10993 {
10994 switch (entry->d_tag)
10995 {
10996 case DT_NEEDED:
10997 printf (_("Shared library: [%s]"), name);
10998
978c4450 10999 if (streq (name, filedata->program_interpreter))
f7a99963 11000 printf (_(" program interpreter"));
252b5132
RH
11001 break;
11002
11003 case DT_SONAME:
f7a99963 11004 printf (_("Library soname: [%s]"), name);
252b5132
RH
11005 break;
11006
11007 case DT_RPATH:
f7a99963 11008 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11009 break;
11010
019148e4
L
11011 case DT_RUNPATH:
11012 printf (_("Library runpath: [%s]"), name);
11013 break;
11014
252b5132 11015 default:
f7a99963
NC
11016 print_vma (entry->d_un.d_val, PREFIX_HEX);
11017 break;
252b5132
RH
11018 }
11019 }
11020 else
f7a99963
NC
11021 print_vma (entry->d_un.d_val, PREFIX_HEX);
11022
11023 putchar ('\n');
252b5132
RH
11024 }
11025 break;
11026
11027 case DT_PLTRELSZ:
11028 case DT_RELASZ :
11029 case DT_STRSZ :
11030 case DT_RELSZ :
11031 case DT_RELAENT :
11032 case DT_SYMENT :
11033 case DT_RELENT :
978c4450 11034 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11035 /* Fall through. */
252b5132
RH
11036 case DT_PLTPADSZ:
11037 case DT_MOVEENT :
11038 case DT_MOVESZ :
11039 case DT_INIT_ARRAYSZ:
11040 case DT_FINI_ARRAYSZ:
047b2264
JJ
11041 case DT_GNU_CONFLICTSZ:
11042 case DT_GNU_LIBLISTSZ:
252b5132 11043 if (do_dynamic)
f7a99963
NC
11044 {
11045 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11046 printf (_(" (bytes)\n"));
f7a99963 11047 }
252b5132
RH
11048 break;
11049
11050 case DT_VERDEFNUM:
11051 case DT_VERNEEDNUM:
11052 case DT_RELACOUNT:
11053 case DT_RELCOUNT:
11054 if (do_dynamic)
f7a99963
NC
11055 {
11056 print_vma (entry->d_un.d_val, UNSIGNED);
11057 putchar ('\n');
11058 }
252b5132
RH
11059 break;
11060
11061 case DT_SYMINSZ:
11062 case DT_SYMINENT:
11063 case DT_SYMINFO:
11064 case DT_USED:
11065 case DT_INIT_ARRAY:
11066 case DT_FINI_ARRAY:
11067 if (do_dynamic)
11068 {
d79b3d50 11069 if (entry->d_tag == DT_USED
978c4450 11070 && VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
252b5132 11071 {
978c4450 11072 char * name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11073
b34976b6 11074 if (*name)
252b5132
RH
11075 {
11076 printf (_("Not needed object: [%s]\n"), name);
11077 break;
11078 }
11079 }
103f02d3 11080
f7a99963
NC
11081 print_vma (entry->d_un.d_val, PREFIX_HEX);
11082 putchar ('\n');
252b5132
RH
11083 }
11084 break;
11085
11086 case DT_BIND_NOW:
11087 /* The value of this entry is ignored. */
35b1837e
AM
11088 if (do_dynamic)
11089 putchar ('\n');
252b5132 11090 break;
103f02d3 11091
047b2264
JJ
11092 case DT_GNU_PRELINKED:
11093 if (do_dynamic)
11094 {
2cf0635d 11095 struct tm * tmp;
91d6fa6a 11096 time_t atime = entry->d_un.d_val;
047b2264 11097
91d6fa6a 11098 tmp = gmtime (&atime);
071436c6
NC
11099 /* PR 17533 file: 041-1244816-0.004. */
11100 if (tmp == NULL)
5a2cbcf4
L
11101 printf (_("<corrupt time val: %lx"),
11102 (unsigned long) atime);
071436c6
NC
11103 else
11104 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11105 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11106 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11107
11108 }
11109 break;
11110
fdc90cb4 11111 case DT_GNU_HASH:
978c4450 11112 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11113 if (do_dynamic)
11114 {
11115 print_vma (entry->d_un.d_val, PREFIX_HEX);
11116 putchar ('\n');
11117 }
11118 break;
11119
a5da3dee
VDM
11120 case DT_GNU_FLAGS_1:
11121 if (do_dynamic)
11122 {
11123 printf (_("Flags:"));
11124 if (entry->d_un.d_val == 0)
11125 printf (_(" None\n"));
11126 else
11127 {
11128 unsigned long int val = entry->d_un.d_val;
11129
11130 if (val & DF_GNU_1_UNIQUE)
11131 {
11132 printf (" UNIQUE");
11133 val ^= DF_GNU_1_UNIQUE;
11134 }
11135 if (val != 0)
11136 printf (" %lx", val);
11137 puts ("");
11138 }
11139 }
11140 break;
11141
252b5132
RH
11142 default:
11143 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11144 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11145 = entry->d_un.d_val;
252b5132
RH
11146
11147 if (do_dynamic)
11148 {
dda8d76d 11149 switch (filedata->file_header.e_machine)
252b5132 11150 {
37c18eed
SD
11151 case EM_AARCH64:
11152 dynamic_section_aarch64_val (entry);
11153 break;
252b5132 11154 case EM_MIPS:
4fe85591 11155 case EM_MIPS_RS3_LE:
978c4450 11156 dynamic_section_mips_val (filedata, entry);
252b5132 11157 break;
103f02d3 11158 case EM_PARISC:
b2d38a17 11159 dynamic_section_parisc_val (entry);
103f02d3 11160 break;
ecc51f48 11161 case EM_IA_64:
b2d38a17 11162 dynamic_section_ia64_val (entry);
ecc51f48 11163 break;
252b5132 11164 default:
f7a99963
NC
11165 print_vma (entry->d_un.d_val, PREFIX_HEX);
11166 putchar ('\n');
252b5132
RH
11167 }
11168 }
11169 break;
11170 }
11171 }
11172
32ec8896 11173 return TRUE;
252b5132
RH
11174}
11175
11176static char *
d3ba0551 11177get_ver_flags (unsigned int flags)
252b5132 11178{
6d4f21f6 11179 static char buff[128];
252b5132
RH
11180
11181 buff[0] = 0;
11182
11183 if (flags == 0)
11184 return _("none");
11185
11186 if (flags & VER_FLG_BASE)
7bb1ad17 11187 strcat (buff, "BASE");
252b5132
RH
11188
11189 if (flags & VER_FLG_WEAK)
11190 {
11191 if (flags & VER_FLG_BASE)
7bb1ad17 11192 strcat (buff, " | ");
252b5132 11193
7bb1ad17 11194 strcat (buff, "WEAK");
252b5132
RH
11195 }
11196
44ec90b9
RO
11197 if (flags & VER_FLG_INFO)
11198 {
11199 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11200 strcat (buff, " | ");
44ec90b9 11201
7bb1ad17 11202 strcat (buff, "INFO");
44ec90b9
RO
11203 }
11204
11205 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11206 {
11207 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11208 strcat (buff, " | ");
11209
11210 strcat (buff, _("<unknown>"));
11211 }
252b5132
RH
11212
11213 return buff;
11214}
11215
11216/* Display the contents of the version sections. */
98fb390a 11217
32ec8896 11218static bfd_boolean
dda8d76d 11219process_version_sections (Filedata * filedata)
252b5132 11220{
2cf0635d 11221 Elf_Internal_Shdr * section;
b34976b6 11222 unsigned i;
32ec8896 11223 bfd_boolean found = FALSE;
252b5132
RH
11224
11225 if (! do_version)
32ec8896 11226 return TRUE;
252b5132 11227
dda8d76d
NC
11228 for (i = 0, section = filedata->section_headers;
11229 i < filedata->file_header.e_shnum;
b34976b6 11230 i++, section++)
252b5132
RH
11231 {
11232 switch (section->sh_type)
11233 {
11234 case SHT_GNU_verdef:
11235 {
2cf0635d 11236 Elf_External_Verdef * edefs;
452bf675
AM
11237 unsigned long idx;
11238 unsigned long cnt;
2cf0635d 11239 char * endbuf;
252b5132 11240
32ec8896 11241 found = TRUE;
252b5132 11242
d3a49aa8
AM
11243 printf (ngettext ("\nVersion definition section '%s' "
11244 "contains %u entry:\n",
11245 "\nVersion definition section '%s' "
11246 "contains %u entries:\n",
11247 section->sh_info),
dda8d76d 11248 printable_section_name (filedata, section),
74e1a04b 11249 section->sh_info);
252b5132 11250
ae9ac79e 11251 printf (_(" Addr: 0x"));
252b5132 11252 printf_vma (section->sh_addr);
233f82cf 11253 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11254 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11255 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11256
3f5e193b 11257 edefs = (Elf_External_Verdef *)
dda8d76d 11258 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11259 _("version definition section"));
a6e9f9df
AM
11260 if (!edefs)
11261 break;
59245841 11262 endbuf = (char *) edefs + section->sh_size;
252b5132 11263
1445030f 11264 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11265 {
2cf0635d
NC
11266 char * vstart;
11267 Elf_External_Verdef * edef;
b34976b6 11268 Elf_Internal_Verdef ent;
2cf0635d 11269 Elf_External_Verdaux * eaux;
b34976b6 11270 Elf_Internal_Verdaux aux;
452bf675 11271 unsigned long isum;
b34976b6 11272 int j;
103f02d3 11273
252b5132 11274 vstart = ((char *) edefs) + idx;
54806181
AM
11275 if (vstart + sizeof (*edef) > endbuf)
11276 break;
252b5132
RH
11277
11278 edef = (Elf_External_Verdef *) vstart;
11279
11280 ent.vd_version = BYTE_GET (edef->vd_version);
11281 ent.vd_flags = BYTE_GET (edef->vd_flags);
11282 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11283 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11284 ent.vd_hash = BYTE_GET (edef->vd_hash);
11285 ent.vd_aux = BYTE_GET (edef->vd_aux);
11286 ent.vd_next = BYTE_GET (edef->vd_next);
11287
452bf675 11288 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11289 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11290
11291 printf (_(" Index: %d Cnt: %d "),
11292 ent.vd_ndx, ent.vd_cnt);
11293
452bf675 11294 /* Check for overflow. */
1445030f 11295 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11296 break;
11297
252b5132
RH
11298 vstart += ent.vd_aux;
11299
1445030f
AM
11300 if (vstart + sizeof (*eaux) > endbuf)
11301 break;
252b5132
RH
11302 eaux = (Elf_External_Verdaux *) vstart;
11303
11304 aux.vda_name = BYTE_GET (eaux->vda_name);
11305 aux.vda_next = BYTE_GET (eaux->vda_next);
11306
978c4450
AM
11307 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
11308 printf (_("Name: %s\n"),
11309 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132
RH
11310 else
11311 printf (_("Name index: %ld\n"), aux.vda_name);
11312
11313 isum = idx + ent.vd_aux;
11314
b34976b6 11315 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11316 {
1445030f
AM
11317 if (aux.vda_next < sizeof (*eaux)
11318 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11319 {
11320 warn (_("Invalid vda_next field of %lx\n"),
11321 aux.vda_next);
11322 j = ent.vd_cnt;
11323 break;
11324 }
dd24e3da 11325 /* Check for overflow. */
7e26601c 11326 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11327 break;
11328
252b5132
RH
11329 isum += aux.vda_next;
11330 vstart += aux.vda_next;
11331
54806181
AM
11332 if (vstart + sizeof (*eaux) > endbuf)
11333 break;
1445030f 11334 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11335
11336 aux.vda_name = BYTE_GET (eaux->vda_name);
11337 aux.vda_next = BYTE_GET (eaux->vda_next);
11338
978c4450 11339 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
452bf675 11340 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450
AM
11341 isum, j,
11342 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132 11343 else
452bf675 11344 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11345 isum, j, aux.vda_name);
11346 }
dd24e3da 11347
54806181
AM
11348 if (j < ent.vd_cnt)
11349 printf (_(" Version def aux past end of section\n"));
252b5132 11350
c9f02c3e
MR
11351 /* PR 17531:
11352 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11353 if (ent.vd_next < sizeof (*edef)
11354 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11355 {
11356 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11357 cnt = section->sh_info;
11358 break;
11359 }
452bf675 11360 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11361 break;
11362
252b5132
RH
11363 idx += ent.vd_next;
11364 }
dd24e3da 11365
54806181
AM
11366 if (cnt < section->sh_info)
11367 printf (_(" Version definition past end of section\n"));
252b5132
RH
11368
11369 free (edefs);
11370 }
11371 break;
103f02d3 11372
252b5132
RH
11373 case SHT_GNU_verneed:
11374 {
2cf0635d 11375 Elf_External_Verneed * eneed;
452bf675
AM
11376 unsigned long idx;
11377 unsigned long cnt;
2cf0635d 11378 char * endbuf;
252b5132 11379
32ec8896 11380 found = TRUE;
252b5132 11381
d3a49aa8
AM
11382 printf (ngettext ("\nVersion needs section '%s' "
11383 "contains %u entry:\n",
11384 "\nVersion needs section '%s' "
11385 "contains %u entries:\n",
11386 section->sh_info),
dda8d76d 11387 printable_section_name (filedata, section), section->sh_info);
252b5132
RH
11388
11389 printf (_(" Addr: 0x"));
11390 printf_vma (section->sh_addr);
72de5009 11391 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11392 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11393 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11394
dda8d76d 11395 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11396 section->sh_offset, 1,
11397 section->sh_size,
9cf03b7e 11398 _("Version Needs section"));
a6e9f9df
AM
11399 if (!eneed)
11400 break;
59245841 11401 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11402
11403 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11404 {
2cf0635d 11405 Elf_External_Verneed * entry;
b34976b6 11406 Elf_Internal_Verneed ent;
452bf675 11407 unsigned long isum;
b34976b6 11408 int j;
2cf0635d 11409 char * vstart;
252b5132
RH
11410
11411 vstart = ((char *) eneed) + idx;
54806181
AM
11412 if (vstart + sizeof (*entry) > endbuf)
11413 break;
252b5132
RH
11414
11415 entry = (Elf_External_Verneed *) vstart;
11416
11417 ent.vn_version = BYTE_GET (entry->vn_version);
11418 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11419 ent.vn_file = BYTE_GET (entry->vn_file);
11420 ent.vn_aux = BYTE_GET (entry->vn_aux);
11421 ent.vn_next = BYTE_GET (entry->vn_next);
11422
452bf675 11423 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11424
978c4450
AM
11425 if (VALID_DYNAMIC_NAME (filedata, ent.vn_file))
11426 printf (_(" File: %s"),
11427 GET_DYNAMIC_NAME (filedata, ent.vn_file));
252b5132
RH
11428 else
11429 printf (_(" File: %lx"), ent.vn_file);
11430
11431 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11432
dd24e3da 11433 /* Check for overflow. */
7e26601c 11434 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11435 break;
252b5132
RH
11436 vstart += ent.vn_aux;
11437
11438 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11439 {
2cf0635d 11440 Elf_External_Vernaux * eaux;
b34976b6 11441 Elf_Internal_Vernaux aux;
252b5132 11442
54806181
AM
11443 if (vstart + sizeof (*eaux) > endbuf)
11444 break;
252b5132
RH
11445 eaux = (Elf_External_Vernaux *) vstart;
11446
11447 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11448 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11449 aux.vna_other = BYTE_GET (eaux->vna_other);
11450 aux.vna_name = BYTE_GET (eaux->vna_name);
11451 aux.vna_next = BYTE_GET (eaux->vna_next);
11452
978c4450 11453 if (VALID_DYNAMIC_NAME (filedata, aux.vna_name))
452bf675 11454 printf (_(" %#06lx: Name: %s"),
978c4450 11455 isum, GET_DYNAMIC_NAME (filedata, aux.vna_name));
252b5132 11456 else
452bf675 11457 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11458 isum, aux.vna_name);
11459
11460 printf (_(" Flags: %s Version: %d\n"),
11461 get_ver_flags (aux.vna_flags), aux.vna_other);
11462
1445030f
AM
11463 if (aux.vna_next < sizeof (*eaux)
11464 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11465 {
11466 warn (_("Invalid vna_next field of %lx\n"),
11467 aux.vna_next);
11468 j = ent.vn_cnt;
11469 break;
11470 }
1445030f
AM
11471 /* Check for overflow. */
11472 if (aux.vna_next > (size_t) (endbuf - vstart))
11473 break;
252b5132
RH
11474 isum += aux.vna_next;
11475 vstart += aux.vna_next;
11476 }
9cf03b7e 11477
54806181 11478 if (j < ent.vn_cnt)
f9a6a8f0 11479 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 11480
1445030f
AM
11481 if (ent.vn_next < sizeof (*entry)
11482 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11483 {
452bf675 11484 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11485 cnt = section->sh_info;
11486 break;
11487 }
1445030f
AM
11488 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11489 break;
252b5132
RH
11490 idx += ent.vn_next;
11491 }
9cf03b7e 11492
54806181 11493 if (cnt < section->sh_info)
9cf03b7e 11494 warn (_("Missing Version Needs information\n"));
103f02d3 11495
252b5132
RH
11496 free (eneed);
11497 }
11498 break;
11499
11500 case SHT_GNU_versym:
11501 {
2cf0635d 11502 Elf_Internal_Shdr * link_section;
8b73c356
NC
11503 size_t total;
11504 unsigned int cnt;
2cf0635d
NC
11505 unsigned char * edata;
11506 unsigned short * data;
11507 char * strtab;
11508 Elf_Internal_Sym * symbols;
11509 Elf_Internal_Shdr * string_sec;
ba5cdace 11510 unsigned long num_syms;
d3ba0551 11511 long off;
252b5132 11512
dda8d76d 11513 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11514 break;
11515
dda8d76d 11516 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11517 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11518
dda8d76d 11519 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11520 break;
11521
32ec8896 11522 found = TRUE;
252b5132 11523
dda8d76d 11524 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
11525 if (symbols == NULL)
11526 break;
252b5132 11527
dda8d76d 11528 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11529
dda8d76d 11530 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11531 string_sec->sh_size,
11532 _("version string table"));
a6e9f9df 11533 if (!strtab)
0429c154
MS
11534 {
11535 free (symbols);
11536 break;
11537 }
252b5132 11538
d3a49aa8
AM
11539 printf (ngettext ("\nVersion symbols section '%s' "
11540 "contains %lu entry:\n",
11541 "\nVersion symbols section '%s' "
11542 "contains %lu entries:\n",
11543 total),
dda8d76d 11544 printable_section_name (filedata, section), (unsigned long) total);
252b5132 11545
ae9ac79e 11546 printf (_(" Addr: 0x"));
252b5132 11547 printf_vma (section->sh_addr);
72de5009 11548 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11549 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11550 printable_section_name (filedata, link_section));
252b5132 11551
dda8d76d 11552 off = offset_from_vma (filedata,
978c4450 11553 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11554 total * sizeof (short));
95099889
AM
11555 edata = (unsigned char *) get_data (NULL, filedata, off,
11556 sizeof (short), total,
11557 _("version symbol data"));
a6e9f9df
AM
11558 if (!edata)
11559 {
11560 free (strtab);
0429c154 11561 free (symbols);
a6e9f9df
AM
11562 break;
11563 }
252b5132 11564
3f5e193b 11565 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11566
11567 for (cnt = total; cnt --;)
b34976b6
AM
11568 data[cnt] = byte_get (edata + cnt * sizeof (short),
11569 sizeof (short));
252b5132
RH
11570
11571 free (edata);
11572
11573 for (cnt = 0; cnt < total; cnt += 4)
11574 {
11575 int j, nn;
ab273396
AM
11576 char *name;
11577 char *invalid = _("*invalid*");
252b5132
RH
11578
11579 printf (" %03x:", cnt);
11580
11581 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11582 switch (data[cnt + j])
252b5132
RH
11583 {
11584 case 0:
11585 fputs (_(" 0 (*local*) "), stdout);
11586 break;
11587
11588 case 1:
11589 fputs (_(" 1 (*global*) "), stdout);
11590 break;
11591
11592 default:
c244d050
NC
11593 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11594 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11595
dd24e3da 11596 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11597 array, break to avoid an out-of-bounds read. */
11598 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11599 {
11600 warn (_("invalid index into symbol array\n"));
11601 break;
11602 }
11603
ab273396 11604 name = NULL;
978c4450 11605 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11606 {
b34976b6
AM
11607 Elf_Internal_Verneed ivn;
11608 unsigned long offset;
252b5132 11609
d93f0186 11610 offset = offset_from_vma
978c4450
AM
11611 (filedata,
11612 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11613 sizeof (Elf_External_Verneed));
252b5132 11614
b34976b6 11615 do
252b5132 11616 {
b34976b6
AM
11617 Elf_Internal_Vernaux ivna;
11618 Elf_External_Verneed evn;
11619 Elf_External_Vernaux evna;
11620 unsigned long a_off;
252b5132 11621
dda8d76d 11622 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11623 _("version need")) == NULL)
11624 break;
0b4362b0 11625
252b5132
RH
11626 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11627 ivn.vn_next = BYTE_GET (evn.vn_next);
11628
11629 a_off = offset + ivn.vn_aux;
11630
11631 do
11632 {
dda8d76d 11633 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11634 1, _("version need aux (2)")) == NULL)
11635 {
11636 ivna.vna_next = 0;
11637 ivna.vna_other = 0;
11638 }
11639 else
11640 {
11641 ivna.vna_next = BYTE_GET (evna.vna_next);
11642 ivna.vna_other = BYTE_GET (evna.vna_other);
11643 }
252b5132
RH
11644
11645 a_off += ivna.vna_next;
11646 }
b34976b6 11647 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11648 && ivna.vna_next != 0);
11649
b34976b6 11650 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11651 {
11652 ivna.vna_name = BYTE_GET (evna.vna_name);
11653
54806181 11654 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11655 name = invalid;
54806181
AM
11656 else
11657 name = strtab + ivna.vna_name;
252b5132
RH
11658 break;
11659 }
11660
11661 offset += ivn.vn_next;
11662 }
11663 while (ivn.vn_next);
11664 }
00d93f34 11665
ab273396 11666 if (data[cnt + j] != 0x8001
978c4450 11667 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 11668 {
b34976b6
AM
11669 Elf_Internal_Verdef ivd;
11670 Elf_External_Verdef evd;
11671 unsigned long offset;
252b5132 11672
d93f0186 11673 offset = offset_from_vma
978c4450
AM
11674 (filedata,
11675 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 11676 sizeof evd);
252b5132
RH
11677
11678 do
11679 {
dda8d76d 11680 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
11681 _("version def")) == NULL)
11682 {
11683 ivd.vd_next = 0;
948f632f 11684 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
11685 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
11686 break;
59245841
NC
11687 }
11688 else
11689 {
11690 ivd.vd_next = BYTE_GET (evd.vd_next);
11691 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11692 }
252b5132
RH
11693
11694 offset += ivd.vd_next;
11695 }
c244d050 11696 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
11697 && ivd.vd_next != 0);
11698
c244d050 11699 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 11700 {
b34976b6
AM
11701 Elf_External_Verdaux evda;
11702 Elf_Internal_Verdaux ivda;
252b5132
RH
11703
11704 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11705
dda8d76d 11706 if (get_data (&evda, filedata,
59245841
NC
11707 offset - ivd.vd_next + ivd.vd_aux,
11708 sizeof (evda), 1,
11709 _("version def aux")) == NULL)
11710 break;
252b5132
RH
11711
11712 ivda.vda_name = BYTE_GET (evda.vda_name);
11713
54806181 11714 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
11715 name = invalid;
11716 else if (name != NULL && name != invalid)
11717 name = _("*both*");
54806181
AM
11718 else
11719 name = strtab + ivda.vda_name;
252b5132
RH
11720 }
11721 }
ab273396
AM
11722 if (name != NULL)
11723 nn += printf ("(%s%-*s",
11724 name,
11725 12 - (int) strlen (name),
11726 ")");
252b5132
RH
11727
11728 if (nn < 18)
11729 printf ("%*c", 18 - nn, ' ');
11730 }
11731
11732 putchar ('\n');
11733 }
11734
11735 free (data);
11736 free (strtab);
11737 free (symbols);
11738 }
11739 break;
103f02d3 11740
252b5132
RH
11741 default:
11742 break;
11743 }
11744 }
11745
11746 if (! found)
11747 printf (_("\nNo version information found in this file.\n"));
11748
32ec8896 11749 return TRUE;
252b5132
RH
11750}
11751
d1133906 11752static const char *
dda8d76d 11753get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 11754{
89246a0e 11755 static char buff[64];
252b5132
RH
11756
11757 switch (binding)
11758 {
b34976b6
AM
11759 case STB_LOCAL: return "LOCAL";
11760 case STB_GLOBAL: return "GLOBAL";
11761 case STB_WEAK: return "WEAK";
252b5132
RH
11762 default:
11763 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
11764 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
11765 binding);
252b5132 11766 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
11767 {
11768 if (binding == STB_GNU_UNIQUE
df3a023b 11769 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
11770 return "UNIQUE";
11771 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
11772 }
252b5132 11773 else
e9e44622 11774 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
11775 return buff;
11776 }
11777}
11778
d1133906 11779static const char *
dda8d76d 11780get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 11781{
89246a0e 11782 static char buff[64];
252b5132
RH
11783
11784 switch (type)
11785 {
b34976b6
AM
11786 case STT_NOTYPE: return "NOTYPE";
11787 case STT_OBJECT: return "OBJECT";
11788 case STT_FUNC: return "FUNC";
11789 case STT_SECTION: return "SECTION";
11790 case STT_FILE: return "FILE";
11791 case STT_COMMON: return "COMMON";
11792 case STT_TLS: return "TLS";
15ab5209
DB
11793 case STT_RELC: return "RELC";
11794 case STT_SRELC: return "SRELC";
252b5132
RH
11795 default:
11796 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 11797 {
dda8d76d 11798 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 11799 return "THUMB_FUNC";
103f02d3 11800
dda8d76d 11801 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
11802 return "REGISTER";
11803
dda8d76d 11804 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
11805 return "PARISC_MILLI";
11806
e9e44622 11807 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 11808 }
252b5132 11809 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 11810 {
dda8d76d 11811 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
11812 {
11813 if (type == STT_HP_OPAQUE)
11814 return "HP_OPAQUE";
11815 if (type == STT_HP_STUB)
11816 return "HP_STUB";
11817 }
11818
d8045f23 11819 if (type == STT_GNU_IFUNC
dda8d76d 11820 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 11821 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
11822 return "IFUNC";
11823
e9e44622 11824 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 11825 }
252b5132 11826 else
e9e44622 11827 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
11828 return buff;
11829 }
11830}
11831
d1133906 11832static const char *
d3ba0551 11833get_symbol_visibility (unsigned int visibility)
d1133906
NC
11834{
11835 switch (visibility)
11836 {
b34976b6
AM
11837 case STV_DEFAULT: return "DEFAULT";
11838 case STV_INTERNAL: return "INTERNAL";
11839 case STV_HIDDEN: return "HIDDEN";
d1133906 11840 case STV_PROTECTED: return "PROTECTED";
bee0ee85 11841 default:
27a45f42 11842 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 11843 return _("<unknown>");
d1133906
NC
11844 }
11845}
11846
2057d69d
CZ
11847static const char *
11848get_alpha_symbol_other (unsigned int other)
9abca702 11849{
2057d69d
CZ
11850 switch (other)
11851 {
11852 case STO_ALPHA_NOPV: return "NOPV";
11853 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
11854 default:
27a45f42 11855 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 11856 return _("<unknown>");
9abca702 11857 }
2057d69d
CZ
11858}
11859
fd85a6a1
NC
11860static const char *
11861get_solaris_symbol_visibility (unsigned int visibility)
11862{
11863 switch (visibility)
11864 {
11865 case 4: return "EXPORTED";
11866 case 5: return "SINGLETON";
11867 case 6: return "ELIMINATE";
11868 default: return get_symbol_visibility (visibility);
11869 }
11870}
11871
2301ed1c
SN
11872static const char *
11873get_aarch64_symbol_other (unsigned int other)
11874{
11875 static char buf[32];
11876
11877 if (other & STO_AARCH64_VARIANT_PCS)
11878 {
11879 other &= ~STO_AARCH64_VARIANT_PCS;
11880 if (other == 0)
11881 return "VARIANT_PCS";
11882 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
11883 return buf;
11884 }
11885 return NULL;
11886}
11887
5e2b0d47
NC
11888static const char *
11889get_mips_symbol_other (unsigned int other)
11890{
11891 switch (other)
11892 {
32ec8896
NC
11893 case STO_OPTIONAL: return "OPTIONAL";
11894 case STO_MIPS_PLT: return "MIPS PLT";
11895 case STO_MIPS_PIC: return "MIPS PIC";
11896 case STO_MICROMIPS: return "MICROMIPS";
11897 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
11898 case STO_MIPS16: return "MIPS16";
11899 default: return NULL;
5e2b0d47
NC
11900 }
11901}
11902
28f997cf 11903static const char *
dda8d76d 11904get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 11905{
dda8d76d 11906 if (is_ia64_vms (filedata))
28f997cf
TG
11907 {
11908 static char res[32];
11909
11910 res[0] = 0;
11911
11912 /* Function types is for images and .STB files only. */
dda8d76d 11913 switch (filedata->file_header.e_type)
28f997cf
TG
11914 {
11915 case ET_DYN:
11916 case ET_EXEC:
11917 switch (VMS_ST_FUNC_TYPE (other))
11918 {
11919 case VMS_SFT_CODE_ADDR:
11920 strcat (res, " CA");
11921 break;
11922 case VMS_SFT_SYMV_IDX:
11923 strcat (res, " VEC");
11924 break;
11925 case VMS_SFT_FD:
11926 strcat (res, " FD");
11927 break;
11928 case VMS_SFT_RESERVE:
11929 strcat (res, " RSV");
11930 break;
11931 default:
bee0ee85
NC
11932 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
11933 VMS_ST_FUNC_TYPE (other));
11934 strcat (res, " <unknown>");
11935 break;
28f997cf
TG
11936 }
11937 break;
11938 default:
11939 break;
11940 }
11941 switch (VMS_ST_LINKAGE (other))
11942 {
11943 case VMS_STL_IGNORE:
11944 strcat (res, " IGN");
11945 break;
11946 case VMS_STL_RESERVE:
11947 strcat (res, " RSV");
11948 break;
11949 case VMS_STL_STD:
11950 strcat (res, " STD");
11951 break;
11952 case VMS_STL_LNK:
11953 strcat (res, " LNK");
11954 break;
11955 default:
bee0ee85
NC
11956 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
11957 VMS_ST_LINKAGE (other));
11958 strcat (res, " <unknown>");
11959 break;
28f997cf
TG
11960 }
11961
11962 if (res[0] != 0)
11963 return res + 1;
11964 else
11965 return res;
11966 }
11967 return NULL;
11968}
11969
6911b7dc
AM
11970static const char *
11971get_ppc64_symbol_other (unsigned int other)
11972{
14732552
AM
11973 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
11974 return NULL;
11975
11976 other >>= STO_PPC64_LOCAL_BIT;
11977 if (other <= 6)
6911b7dc 11978 {
89246a0e 11979 static char buf[64];
14732552
AM
11980 if (other >= 2)
11981 other = ppc64_decode_local_entry (other);
11982 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
11983 return buf;
11984 }
11985 return NULL;
11986}
11987
5e2b0d47 11988static const char *
dda8d76d 11989get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
11990{
11991 const char * result = NULL;
89246a0e 11992 static char buff [64];
5e2b0d47
NC
11993
11994 if (other == 0)
11995 return "";
11996
dda8d76d 11997 switch (filedata->file_header.e_machine)
5e2b0d47 11998 {
2057d69d
CZ
11999 case EM_ALPHA:
12000 result = get_alpha_symbol_other (other);
12001 break;
2301ed1c
SN
12002 case EM_AARCH64:
12003 result = get_aarch64_symbol_other (other);
12004 break;
5e2b0d47
NC
12005 case EM_MIPS:
12006 result = get_mips_symbol_other (other);
28f997cf
TG
12007 break;
12008 case EM_IA_64:
dda8d76d 12009 result = get_ia64_symbol_other (filedata, other);
28f997cf 12010 break;
6911b7dc
AM
12011 case EM_PPC64:
12012 result = get_ppc64_symbol_other (other);
12013 break;
5e2b0d47 12014 default:
fd85a6a1 12015 result = NULL;
5e2b0d47
NC
12016 break;
12017 }
12018
12019 if (result)
12020 return result;
12021
12022 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12023 return buff;
12024}
12025
d1133906 12026static const char *
dda8d76d 12027get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12028{
b34976b6 12029 static char buff[32];
5cf1065c 12030
252b5132
RH
12031 switch (type)
12032 {
b34976b6
AM
12033 case SHN_UNDEF: return "UND";
12034 case SHN_ABS: return "ABS";
12035 case SHN_COMMON: return "COM";
252b5132 12036 default:
9ce701e2 12037 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12038 && filedata->file_header.e_machine == EM_IA_64
12039 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12040 return "ANSI_COM";
12041 else if ((filedata->file_header.e_machine == EM_X86_64
12042 || filedata->file_header.e_machine == EM_L1OM
12043 || filedata->file_header.e_machine == EM_K1OM)
12044 && type == SHN_X86_64_LCOMMON)
12045 return "LARGE_COM";
12046 else if ((type == SHN_MIPS_SCOMMON
12047 && filedata->file_header.e_machine == EM_MIPS)
12048 || (type == SHN_TIC6X_SCOMMON
12049 && filedata->file_header.e_machine == EM_TI_C6000))
12050 return "SCOM";
12051 else if (type == SHN_MIPS_SUNDEFINED
12052 && filedata->file_header.e_machine == EM_MIPS)
12053 return "SUND";
12054 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12055 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12056 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12057 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12058 else if (type >= SHN_LORESERVE)
12059 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12060 else if (filedata->file_header.e_shnum != 0
12061 && type >= filedata->file_header.e_shnum)
12062 sprintf (buff, _("bad section index[%3d]"), type);
12063 else
12064 sprintf (buff, "%3d", type);
12065 break;
fd85a6a1
NC
12066 }
12067
10ca4b04 12068 return buff;
6bd1a22c
L
12069}
12070
bb4d2ac2 12071static const char *
dda8d76d 12072get_symbol_version_string (Filedata * filedata,
1449284b
NC
12073 bfd_boolean is_dynsym,
12074 const char * strtab,
12075 unsigned long int strtab_size,
12076 unsigned int si,
12077 Elf_Internal_Sym * psym,
12078 enum versioned_symbol_info * sym_info,
12079 unsigned short * vna_other)
bb4d2ac2 12080{
ab273396
AM
12081 unsigned char data[2];
12082 unsigned short vers_data;
12083 unsigned long offset;
7a815dd5 12084 unsigned short max_vd_ndx;
bb4d2ac2 12085
ab273396 12086 if (!is_dynsym
978c4450 12087 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12088 return NULL;
bb4d2ac2 12089
978c4450
AM
12090 offset = offset_from_vma (filedata,
12091 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12092 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12093
dda8d76d 12094 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12095 sizeof (data), 1, _("version data")) == NULL)
12096 return NULL;
12097
12098 vers_data = byte_get (data, 2);
bb4d2ac2 12099
1f6f5dba 12100 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12101 return NULL;
bb4d2ac2 12102
0b8b7609 12103 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12104 max_vd_ndx = 0;
12105
ab273396
AM
12106 /* Usually we'd only see verdef for defined symbols, and verneed for
12107 undefined symbols. However, symbols defined by the linker in
12108 .dynbss for variables copied from a shared library in order to
12109 avoid text relocations are defined yet have verneed. We could
12110 use a heuristic to detect the special case, for example, check
12111 for verneed first on symbols defined in SHT_NOBITS sections, but
12112 it is simpler and more reliable to just look for both verdef and
12113 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12114
ab273396
AM
12115 if (psym->st_shndx != SHN_UNDEF
12116 && vers_data != 0x8001
978c4450 12117 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12118 {
12119 Elf_Internal_Verdef ivd;
12120 Elf_Internal_Verdaux ivda;
12121 Elf_External_Verdaux evda;
12122 unsigned long off;
bb4d2ac2 12123
dda8d76d 12124 off = offset_from_vma (filedata,
978c4450 12125 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12126 sizeof (Elf_External_Verdef));
12127
12128 do
bb4d2ac2 12129 {
ab273396
AM
12130 Elf_External_Verdef evd;
12131
dda8d76d 12132 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12133 _("version def")) == NULL)
12134 {
12135 ivd.vd_ndx = 0;
12136 ivd.vd_aux = 0;
12137 ivd.vd_next = 0;
1f6f5dba 12138 ivd.vd_flags = 0;
ab273396
AM
12139 }
12140 else
bb4d2ac2 12141 {
ab273396
AM
12142 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12143 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12144 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12145 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12146 }
bb4d2ac2 12147
7a815dd5
L
12148 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12149 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12150
ab273396
AM
12151 off += ivd.vd_next;
12152 }
12153 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12154
ab273396
AM
12155 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12156 {
9abca702 12157 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12158 return NULL;
12159
ab273396
AM
12160 off -= ivd.vd_next;
12161 off += ivd.vd_aux;
bb4d2ac2 12162
dda8d76d 12163 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12164 _("version def aux")) != NULL)
12165 {
12166 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12167
ab273396 12168 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12169 return (ivda.vda_name < strtab_size
12170 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12171 }
12172 }
12173 }
bb4d2ac2 12174
978c4450 12175 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12176 {
12177 Elf_External_Verneed evn;
12178 Elf_Internal_Verneed ivn;
12179 Elf_Internal_Vernaux ivna;
bb4d2ac2 12180
dda8d76d 12181 offset = offset_from_vma (filedata,
978c4450 12182 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12183 sizeof evn);
12184 do
12185 {
12186 unsigned long vna_off;
bb4d2ac2 12187
dda8d76d 12188 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12189 _("version need")) == NULL)
12190 {
12191 ivna.vna_next = 0;
12192 ivna.vna_other = 0;
12193 ivna.vna_name = 0;
12194 break;
12195 }
bb4d2ac2 12196
ab273396
AM
12197 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12198 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12199
ab273396 12200 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12201
ab273396
AM
12202 do
12203 {
12204 Elf_External_Vernaux evna;
bb4d2ac2 12205
dda8d76d 12206 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12207 _("version need aux (3)")) == NULL)
bb4d2ac2 12208 {
ab273396
AM
12209 ivna.vna_next = 0;
12210 ivna.vna_other = 0;
12211 ivna.vna_name = 0;
bb4d2ac2 12212 }
bb4d2ac2 12213 else
bb4d2ac2 12214 {
ab273396
AM
12215 ivna.vna_other = BYTE_GET (evna.vna_other);
12216 ivna.vna_next = BYTE_GET (evna.vna_next);
12217 ivna.vna_name = BYTE_GET (evna.vna_name);
12218 }
bb4d2ac2 12219
ab273396
AM
12220 vna_off += ivna.vna_next;
12221 }
12222 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12223
ab273396
AM
12224 if (ivna.vna_other == vers_data)
12225 break;
bb4d2ac2 12226
ab273396
AM
12227 offset += ivn.vn_next;
12228 }
12229 while (ivn.vn_next != 0);
bb4d2ac2 12230
ab273396
AM
12231 if (ivna.vna_other == vers_data)
12232 {
12233 *sym_info = symbol_undefined;
12234 *vna_other = ivna.vna_other;
12235 return (ivna.vna_name < strtab_size
12236 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12237 }
7a815dd5
L
12238 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12239 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12240 return _("<corrupt>");
bb4d2ac2 12241 }
ab273396 12242 return NULL;
bb4d2ac2
L
12243}
12244
10ca4b04
L
12245static void
12246print_dynamic_symbol (Filedata *filedata, unsigned long si,
12247 Elf_Internal_Sym *symtab,
12248 Elf_Internal_Shdr *section,
12249 char *strtab, size_t strtab_size)
252b5132 12250{
10ca4b04
L
12251 const char *version_string;
12252 enum versioned_symbol_info sym_info;
12253 unsigned short vna_other;
12254 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 12255
10ca4b04
L
12256 printf ("%6ld: ", si);
12257 print_vma (psym->st_value, LONG_HEX);
12258 putchar (' ');
12259 print_vma (psym->st_size, DEC_5);
12260 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12261 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12262 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12263 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12264 else
252b5132 12265 {
10ca4b04 12266 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12267
10ca4b04
L
12268 printf (" %-7s", get_symbol_visibility (vis));
12269 /* Check to see if any other bits in the st_other field are set.
12270 Note - displaying this information disrupts the layout of the
12271 table being generated, but for the moment this case is very rare. */
12272 if (psym->st_other ^ vis)
12273 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12274 }
10ca4b04 12275 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab
NC
12276
12277 bfd_boolean is_valid = VALID_SYMBOL_NAME (strtab, strtab_size,
12278 psym->st_name);
12279 const char * sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
10ca4b04
L
12280
12281 version_string
12282 = get_symbol_version_string (filedata,
12283 (section == NULL
12284 || section->sh_type == SHT_DYNSYM),
12285 strtab, strtab_size, si,
12286 psym, &sym_info, &vna_other);
b9e920ec 12287
0942c7ab
NC
12288 int len_avail = 21;
12289 if (! do_wide && version_string != NULL)
12290 {
ddb43bab 12291 char buffer[16];
0942c7ab 12292
ddb43bab 12293 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
12294
12295 if (sym_info == symbol_undefined)
12296 len_avail -= sprintf (buffer," (%d)", vna_other);
12297 else if (sym_info != symbol_hidden)
12298 len_avail -= 1;
12299 }
12300
12301 print_symbol (len_avail, sstr);
b9e920ec 12302
10ca4b04
L
12303 if (version_string)
12304 {
12305 if (sym_info == symbol_undefined)
12306 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12307 else
10ca4b04
L
12308 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12309 version_string);
12310 }
6bd1a22c 12311
10ca4b04 12312 putchar ('\n');
6bd1a22c 12313
10ca4b04
L
12314 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12315 && section != NULL
12316 && si >= section->sh_info
12317 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12318 && filedata->file_header.e_machine != EM_MIPS
12319 /* Solaris binaries have been found to violate this requirement as
12320 well. Not sure if this is a bug or an ABI requirement. */
12321 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12322 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12323 si, printable_section_name (filedata, section), section->sh_info);
12324}
f16a9783 12325
0f03783c
NC
12326static const char *
12327get_lto_kind (unsigned int kind)
12328{
12329 switch (kind)
12330 {
12331 case 0: return "DEF";
12332 case 1: return "WEAKDEF";
12333 case 2: return "UNDEF";
12334 case 3: return "WEAKUNDEF";
12335 case 4: return "COMMON";
12336 default:
12337 break;
12338 }
12339
12340 static char buffer[30];
12341 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
12342 sprintf (buffer, "<unknown: %u>", kind);
12343 return buffer;
12344}
12345
12346static const char *
12347get_lto_visibility (unsigned int visibility)
12348{
12349 switch (visibility)
12350 {
12351 case 0: return "DEFAULT";
12352 case 1: return "PROTECTED";
12353 case 2: return "INTERNAL";
12354 case 3: return "HIDDEN";
12355 default:
12356 break;
12357 }
12358
12359 static char buffer[30];
12360 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
12361 sprintf (buffer, "<unknown: %u>", visibility);
12362 return buffer;
12363}
12364
12365static const char *
12366get_lto_sym_type (unsigned int sym_type)
12367{
12368 switch (sym_type)
12369 {
12370 case 0: return "UNKNOWN";
12371 case 1: return "FUNCTION";
12372 case 2: return "VARIABLE";
12373 default:
12374 break;
12375 }
12376
12377 static char buffer[30];
12378 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
12379 sprintf (buffer, "<unknown: %u>", sym_type);
12380 return buffer;
12381}
12382
12383/* Display an LTO format symbol table.
12384 FIXME: The format of LTO symbol tables is not formalized.
12385 So this code could need changing in the future. */
12386
12387static bfd_boolean
12388display_lto_symtab (Filedata * filedata,
12389 Elf_Internal_Shdr * section)
12390{
12391 if (section->sh_size == 0)
12392 {
12393 printf (_("\nLTO Symbol table '%s' is empty!\n"),
12394 printable_section_name (filedata, section));
12395 return TRUE;
12396 }
12397
12398 if (section->sh_size > filedata->file_size)
12399 {
12400 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
12401 printable_section_name (filedata, section),
12402 (unsigned long) section->sh_size);
12403 return FALSE;
12404 }
12405
12406 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
12407 section->sh_size, 1, _("LTO symbols"));
12408 if (alloced_data == NULL)
12409 return FALSE;
12410
12411 /* Look for extended data for the symbol table. */
12412 Elf_Internal_Shdr * ext;
12413 void * ext_data_orig = NULL;
12414 char * ext_data = NULL;
12415 char * ext_data_end = NULL;
12416 char * ext_name = NULL;
12417
12418 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
b9e920ec 12419 SECTION_NAME (section) + sizeof (".gnu.lto_.symtab.") - 1) > 0
0f03783c
NC
12420 && ext_name != NULL /* Paranoia. */
12421 && (ext = find_section (filedata, ext_name)) != NULL)
12422 {
12423 if (ext->sh_size < 3)
12424 error (_("LTO Symbol extension table '%s' is empty!\n"),
12425 printable_section_name (filedata, ext));
12426 else
12427 {
12428 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
12429 ext->sh_size, 1,
12430 _("LTO ext symbol data"));
12431 if (ext_data != NULL)
12432 {
12433 ext_data_end = ext_data + ext->sh_size;
12434 if (* ext_data++ != 1)
12435 error (_("Unexpected version number in symbol extension table\n"));
12436 }
12437 }
12438 }
b9e920ec 12439
0f03783c
NC
12440 const unsigned char * data = (const unsigned char *) alloced_data;
12441 const unsigned char * end = data + section->sh_size;
12442
12443 if (ext_data_orig != NULL)
12444 {
12445 if (do_wide)
12446 printf (_("\nLTO Symbol table '%s' and extension table '%s' contain:\n"),
12447 printable_section_name (filedata, section),
12448 printable_section_name (filedata, ext));
12449 else
12450 {
12451 printf (_("\nLTO Symbol table '%s'\n"),
12452 printable_section_name (filedata, section));
12453 printf (_(" and extension table '%s' contain:\n"),
12454 printable_section_name (filedata, ext));
12455 }
12456 }
12457 else
12458 printf (_("\nLTO Symbol table '%s' contains:\n"),
12459 printable_section_name (filedata, section));
b9e920ec 12460
0f03783c
NC
12461
12462 /* FIXME: Add a wide version. */
b9e920ec 12463 if (ext_data_orig != NULL)
0f03783c
NC
12464 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
12465 else
12466 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
12467
12468 /* FIXME: We do not handle style prefixes. */
12469
12470 while (data < end)
12471 {
12472 const unsigned char * sym_name = data;
12473 data += strnlen ((const char *) sym_name, end - data) + 1;
12474 if (data >= end)
12475 goto fail;
12476
12477 const unsigned char * comdat_key = data;
12478 data += strnlen ((const char *) comdat_key, end - data) + 1;
12479 if (data >= end)
12480 goto fail;
12481
12482 if (data + 2 + 8 + 4 > end)
12483 goto fail;
12484
12485 unsigned int kind = *data++;
12486 unsigned int visibility = *data++;
12487
12488 elf_vma size = byte_get (data, 8);
12489 data += 8;
12490
12491 elf_vma slot = byte_get (data, 4);
12492 data += 4;
12493
12494 if (ext_data != NULL)
12495 {
12496 if (ext_data < (ext_data_end - 1))
12497 {
12498 unsigned int sym_type = * ext_data ++;
12499 unsigned int sec_kind = * ext_data ++;
12500
12501 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
12502 * comdat_key == 0 ? "-" : (char *) comdat_key,
12503 get_lto_kind (kind),
12504 get_lto_visibility (visibility),
12505 (long) size,
12506 (long) slot,
12507 get_lto_sym_type (sym_type),
12508 (long) sec_kind);
12509 print_symbol (6, (const char *) sym_name);
12510 }
12511 else
12512 {
12513 error (_("Ran out of LTO symbol extension data\n"));
12514 ext_data = NULL;
12515 /* FIXME: return FAIL result ? */
12516 }
12517 }
12518 else
12519 {
12520 printf (" %10s %10s %11s %08lx %08lx _",
12521 * comdat_key == 0 ? "-" : (char *) comdat_key,
12522 get_lto_kind (kind),
12523 get_lto_visibility (visibility),
12524 (long) size,
12525 (long) slot);
12526 print_symbol (21, (const char *) sym_name);
12527 }
12528 putchar ('\n');
12529 }
12530
12531 if (ext_data != NULL && ext_data < ext_data_end)
12532 {
12533 error (_("Data remains in the LTO symbol extension table\n"));
12534 goto fail;
12535 }
12536
12537 free (alloced_data);
12538 free (ext_data_orig);
12539 free (ext_name);
12540 return TRUE;
b9e920ec 12541
0f03783c
NC
12542 fail:
12543 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
12544 free (alloced_data);
12545 free (ext_data_orig);
12546 free (ext_name);
12547 return FALSE;
12548}
12549
12550/* Display LTO symbol tables. */
12551
12552static bfd_boolean
12553process_lto_symbol_tables (Filedata * filedata)
12554{
12555 Elf_Internal_Shdr * section;
12556 unsigned int i;
12557 bfd_boolean res = TRUE;
12558
12559 if (!do_lto_syms)
12560 return TRUE;
12561
12562 if (filedata->section_headers == NULL)
12563 return TRUE;
12564
12565 for (i = 0, section = filedata->section_headers;
12566 i < filedata->file_header.e_shnum;
12567 i++, section++)
b9e920ec
AM
12568 if (SECTION_NAME_VALID (section)
12569 && CONST_STRNEQ (SECTION_NAME (section), ".gnu.lto_.symtab."))
0f03783c
NC
12570 res &= display_lto_symtab (filedata, section);
12571
b9e920ec 12572 return res;
0f03783c
NC
12573}
12574
10ca4b04 12575/* Dump the symbol table. */
0f03783c 12576
10ca4b04
L
12577static bfd_boolean
12578process_symbol_table (Filedata * filedata)
12579{
12580 Elf_Internal_Shdr * section;
f16a9783 12581
10ca4b04
L
12582 if (!do_syms && !do_dyn_syms && !do_histogram)
12583 return TRUE;
6bd1a22c 12584
978c4450 12585 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
12586 && do_syms
12587 && do_using_dynamic
978c4450
AM
12588 && filedata->dynamic_strings != NULL
12589 && filedata->dynamic_symbols != NULL)
6bd1a22c 12590 {
10ca4b04 12591 unsigned long si;
6bd1a22c 12592
10ca4b04
L
12593 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12594 "\nSymbol table for image contains %lu entries:\n",
978c4450
AM
12595 filedata->num_dynamic_syms),
12596 filedata->num_dynamic_syms);
10ca4b04
L
12597 if (is_32bit_elf)
12598 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12599 else
12600 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12601
978c4450
AM
12602 for (si = 0; si < filedata->num_dynamic_syms; si++)
12603 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
12604 filedata->dynamic_strings,
12605 filedata->dynamic_strings_length);
252b5132 12606 }
8b73c356 12607 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 12608 && filedata->section_headers != NULL)
252b5132 12609 {
b34976b6 12610 unsigned int i;
252b5132 12611
dda8d76d
NC
12612 for (i = 0, section = filedata->section_headers;
12613 i < filedata->file_header.e_shnum;
252b5132
RH
12614 i++, section++)
12615 {
2cf0635d 12616 char * strtab = NULL;
c256ffe7 12617 unsigned long int strtab_size = 0;
2cf0635d 12618 Elf_Internal_Sym * symtab;
ef3df110 12619 unsigned long si, num_syms;
252b5132 12620
2c610e4b
L
12621 if ((section->sh_type != SHT_SYMTAB
12622 && section->sh_type != SHT_DYNSYM)
12623 || (!do_syms
12624 && section->sh_type == SHT_SYMTAB))
252b5132
RH
12625 continue;
12626
dd24e3da
NC
12627 if (section->sh_entsize == 0)
12628 {
12629 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 12630 printable_section_name (filedata, section));
dd24e3da
NC
12631 continue;
12632 }
12633
d3a49aa8
AM
12634 num_syms = section->sh_size / section->sh_entsize;
12635 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
12636 "\nSymbol table '%s' contains %lu entries:\n",
12637 num_syms),
dda8d76d 12638 printable_section_name (filedata, section),
d3a49aa8 12639 num_syms);
dd24e3da 12640
f7a99963 12641 if (is_32bit_elf)
ca47b30c 12642 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 12643 else
ca47b30c 12644 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 12645
dda8d76d 12646 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
12647 if (symtab == NULL)
12648 continue;
12649
dda8d76d 12650 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 12651 {
dda8d76d
NC
12652 strtab = filedata->string_table;
12653 strtab_size = filedata->string_table_length;
c256ffe7 12654 }
dda8d76d 12655 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 12656 {
2cf0635d 12657 Elf_Internal_Shdr * string_sec;
252b5132 12658
dda8d76d 12659 string_sec = filedata->section_headers + section->sh_link;
252b5132 12660
dda8d76d 12661 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
12662 1, string_sec->sh_size,
12663 _("string table"));
c256ffe7 12664 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
12665 }
12666
10ca4b04
L
12667 for (si = 0; si < num_syms; si++)
12668 print_dynamic_symbol (filedata, si, symtab, section,
12669 strtab, strtab_size);
252b5132
RH
12670
12671 free (symtab);
dda8d76d 12672 if (strtab != filedata->string_table)
252b5132
RH
12673 free (strtab);
12674 }
12675 }
12676 else if (do_syms)
12677 printf
12678 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
12679
978c4450 12680 if (do_histogram && filedata->buckets != NULL)
252b5132 12681 {
2cf0635d
NC
12682 unsigned long * lengths;
12683 unsigned long * counts;
66543521
AM
12684 unsigned long hn;
12685 bfd_vma si;
12686 unsigned long maxlength = 0;
12687 unsigned long nzero_counts = 0;
12688 unsigned long nsyms = 0;
6bd6a03d 12689 char *visited;
252b5132 12690
d3a49aa8
AM
12691 printf (ngettext ("\nHistogram for bucket list length "
12692 "(total of %lu bucket):\n",
12693 "\nHistogram for bucket list length "
12694 "(total of %lu buckets):\n",
978c4450
AM
12695 (unsigned long) filedata->nbuckets),
12696 (unsigned long) filedata->nbuckets);
252b5132 12697
978c4450
AM
12698 lengths = (unsigned long *) calloc (filedata->nbuckets,
12699 sizeof (*lengths));
252b5132
RH
12700 if (lengths == NULL)
12701 {
8b73c356 12702 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 12703 goto err_out;
252b5132 12704 }
978c4450
AM
12705 visited = xcmalloc (filedata->nchains, 1);
12706 memset (visited, 0, filedata->nchains);
8b73c356
NC
12707
12708 printf (_(" Length Number %% of total Coverage\n"));
978c4450 12709 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 12710 {
978c4450 12711 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 12712 {
b34976b6 12713 ++nsyms;
252b5132 12714 if (maxlength < ++lengths[hn])
b34976b6 12715 ++maxlength;
978c4450 12716 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
12717 {
12718 error (_("histogram chain is corrupt\n"));
12719 break;
12720 }
12721 visited[si] = 1;
252b5132
RH
12722 }
12723 }
6bd6a03d 12724 free (visited);
252b5132 12725
3f5e193b 12726 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
12727 if (counts == NULL)
12728 {
b2e951ec 12729 free (lengths);
8b73c356 12730 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 12731 goto err_out;
252b5132
RH
12732 }
12733
978c4450 12734 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 12735 ++counts[lengths[hn]];
252b5132 12736
978c4450 12737 if (filedata->nbuckets > 0)
252b5132 12738 {
66543521
AM
12739 unsigned long i;
12740 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12741 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 12742 for (i = 1; i <= maxlength; ++i)
103f02d3 12743 {
66543521
AM
12744 nzero_counts += counts[i] * i;
12745 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12746 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
12747 (nzero_counts * 100.0) / nsyms);
12748 }
252b5132
RH
12749 }
12750
12751 free (counts);
12752 free (lengths);
12753 }
12754
978c4450
AM
12755 free (filedata->buckets);
12756 filedata->buckets = NULL;
12757 filedata->nbuckets = 0;
12758 free (filedata->chains);
12759 filedata->chains = NULL;
252b5132 12760
978c4450 12761 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 12762 {
2cf0635d
NC
12763 unsigned long * lengths;
12764 unsigned long * counts;
fdc90cb4
JJ
12765 unsigned long hn;
12766 unsigned long maxlength = 0;
12767 unsigned long nzero_counts = 0;
12768 unsigned long nsyms = 0;
fdc90cb4 12769
f16a9783 12770 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 12771 "(total of %lu bucket):\n",
f16a9783 12772 "\nHistogram for `%s' bucket list length "
d3a49aa8 12773 "(total of %lu buckets):\n",
978c4450
AM
12774 (unsigned long) filedata->ngnubuckets),
12775 GNU_HASH_SECTION_NAME (filedata),
12776 (unsigned long) filedata->ngnubuckets);
8b73c356 12777
978c4450
AM
12778 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
12779 sizeof (*lengths));
fdc90cb4
JJ
12780 if (lengths == NULL)
12781 {
8b73c356 12782 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 12783 goto err_out;
fdc90cb4
JJ
12784 }
12785
fdc90cb4
JJ
12786 printf (_(" Length Number %% of total Coverage\n"));
12787
978c4450
AM
12788 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
12789 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
12790 {
12791 bfd_vma off, length = 1;
12792
978c4450 12793 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 12794 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
12795 off < filedata->ngnuchains
12796 && (filedata->gnuchains[off] & 1) == 0;
071436c6 12797 ++off)
fdc90cb4
JJ
12798 ++length;
12799 lengths[hn] = length;
12800 if (length > maxlength)
12801 maxlength = length;
12802 nsyms += length;
12803 }
12804
3f5e193b 12805 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
12806 if (counts == NULL)
12807 {
b2e951ec 12808 free (lengths);
8b73c356 12809 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 12810 goto err_out;
fdc90cb4
JJ
12811 }
12812
978c4450 12813 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
12814 ++counts[lengths[hn]];
12815
978c4450 12816 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
12817 {
12818 unsigned long j;
12819 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12820 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
12821 for (j = 1; j <= maxlength; ++j)
12822 {
12823 nzero_counts += counts[j] * j;
12824 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12825 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
12826 (nzero_counts * 100.0) / nsyms);
12827 }
12828 }
12829
12830 free (counts);
12831 free (lengths);
fdc90cb4 12832 }
978c4450
AM
12833 free (filedata->gnubuckets);
12834 filedata->gnubuckets = NULL;
12835 filedata->ngnubuckets = 0;
12836 free (filedata->gnuchains);
12837 filedata->gnuchains = NULL;
12838 filedata->ngnuchains = 0;
12839 free (filedata->mipsxlat);
12840 filedata->mipsxlat = NULL;
32ec8896 12841 return TRUE;
fd486f32
AM
12842
12843 err_out:
978c4450
AM
12844 free (filedata->gnubuckets);
12845 filedata->gnubuckets = NULL;
12846 filedata->ngnubuckets = 0;
12847 free (filedata->gnuchains);
12848 filedata->gnuchains = NULL;
12849 filedata->ngnuchains = 0;
12850 free (filedata->mipsxlat);
12851 filedata->mipsxlat = NULL;
12852 free (filedata->buckets);
12853 filedata->buckets = NULL;
12854 filedata->nbuckets = 0;
12855 free (filedata->chains);
12856 filedata->chains = NULL;
fd486f32 12857 return FALSE;
252b5132
RH
12858}
12859
32ec8896 12860static bfd_boolean
dda8d76d 12861process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
252b5132 12862{
b4c96d0d 12863 unsigned int i;
252b5132 12864
978c4450 12865 if (filedata->dynamic_syminfo == NULL
252b5132
RH
12866 || !do_dynamic)
12867 /* No syminfo, this is ok. */
32ec8896 12868 return TRUE;
252b5132
RH
12869
12870 /* There better should be a dynamic symbol section. */
978c4450 12871 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
32ec8896 12872 return FALSE;
252b5132 12873
978c4450 12874 if (filedata->dynamic_addr)
d3a49aa8
AM
12875 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
12876 "contains %d entry:\n",
12877 "\nDynamic info segment at offset 0x%lx "
12878 "contains %d entries:\n",
978c4450
AM
12879 filedata->dynamic_syminfo_nent),
12880 filedata->dynamic_syminfo_offset, filedata->dynamic_syminfo_nent);
252b5132
RH
12881
12882 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 12883 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 12884 {
978c4450 12885 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 12886
31104126 12887 printf ("%4d: ", i);
978c4450 12888 if (i >= filedata->num_dynamic_syms)
4082ef84 12889 printf (_("<corrupt index>"));
978c4450
AM
12890 else if (VALID_DYNAMIC_NAME (filedata, filedata->dynamic_symbols[i].st_name))
12891 print_symbol (30, GET_DYNAMIC_NAME (filedata,
12892 filedata->dynamic_symbols[i].st_name));
d79b3d50 12893 else
978c4450 12894 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 12895 putchar (' ');
252b5132 12896
978c4450 12897 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
12898 {
12899 case SYMINFO_BT_SELF:
12900 fputs ("SELF ", stdout);
12901 break;
12902 case SYMINFO_BT_PARENT:
12903 fputs ("PARENT ", stdout);
12904 break;
12905 default:
978c4450
AM
12906 if (filedata->dynamic_syminfo[i].si_boundto > 0
12907 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
12908 && VALID_DYNAMIC_NAME (filedata,
12909 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 12910 {
978c4450
AM
12911 print_symbol (10, GET_DYNAMIC_NAME (filedata,
12912 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
12913 putchar (' ' );
12914 }
252b5132 12915 else
978c4450 12916 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
12917 break;
12918 }
12919
12920 if (flags & SYMINFO_FLG_DIRECT)
12921 printf (" DIRECT");
12922 if (flags & SYMINFO_FLG_PASSTHRU)
12923 printf (" PASSTHRU");
12924 if (flags & SYMINFO_FLG_COPY)
12925 printf (" COPY");
12926 if (flags & SYMINFO_FLG_LAZYLOAD)
12927 printf (" LAZYLOAD");
12928
12929 puts ("");
12930 }
12931
32ec8896 12932 return TRUE;
252b5132
RH
12933}
12934
75802ccb
CE
12935/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
12936 is contained by the region START .. END. The types of ADDR, START
12937 and END should all be the same. Note both ADDR + NELEM and END
12938 point to just beyond the end of the regions that are being tested. */
12939#define IN_RANGE(START,END,ADDR,NELEM) \
12940 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 12941
cf13d699
NC
12942/* Check to see if the given reloc needs to be handled in a target specific
12943 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
12944 FALSE.
12945
12946 If called with reloc == NULL, then this is a signal that reloc processing
12947 for the current section has finished, and any saved state should be
12948 discarded. */
09c11c86 12949
cf13d699 12950static bfd_boolean
dda8d76d
NC
12951target_specific_reloc_handling (Filedata * filedata,
12952 Elf_Internal_Rela * reloc,
12953 unsigned char * start,
12954 unsigned char * end,
12955 Elf_Internal_Sym * symtab,
12956 unsigned long num_syms)
252b5132 12957{
f84ce13b
NC
12958 unsigned int reloc_type = 0;
12959 unsigned long sym_index = 0;
12960
12961 if (reloc)
12962 {
dda8d76d 12963 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
12964 sym_index = get_reloc_symindex (reloc->r_info);
12965 }
252b5132 12966
dda8d76d 12967 switch (filedata->file_header.e_machine)
252b5132 12968 {
13761a11
NC
12969 case EM_MSP430:
12970 case EM_MSP430_OLD:
12971 {
12972 static Elf_Internal_Sym * saved_sym = NULL;
12973
f84ce13b
NC
12974 if (reloc == NULL)
12975 {
12976 saved_sym = NULL;
12977 return TRUE;
12978 }
12979
13761a11
NC
12980 switch (reloc_type)
12981 {
12982 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 12983 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 12984 if (uses_msp430x_relocs (filedata))
13761a11 12985 break;
1a0670f3 12986 /* Fall through. */
13761a11 12987 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 12988 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
12989 /* PR 21139. */
12990 if (sym_index >= num_syms)
12991 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
12992 sym_index);
12993 else
12994 saved_sym = symtab + sym_index;
13761a11
NC
12995 return TRUE;
12996
12997 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
12998 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
12999 goto handle_sym_diff;
0b4362b0 13000
13761a11
NC
13001 case 5: /* R_MSP430_16_BYTE */
13002 case 9: /* R_MSP430_8 */
7d81bc93 13003 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13004 if (uses_msp430x_relocs (filedata))
13761a11
NC
13005 break;
13006 goto handle_sym_diff;
13007
13008 case 2: /* R_MSP430_ABS16 */
13009 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13010 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13011 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13012 break;
13013 goto handle_sym_diff;
0b4362b0 13014
13761a11
NC
13015 handle_sym_diff:
13016 if (saved_sym != NULL)
13017 {
13018 bfd_vma value;
5a805384 13019 unsigned int reloc_size = 0;
7d81bc93
JL
13020 int leb_ret = 0;
13021 switch (reloc_type)
13022 {
13023 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13024 reloc_size = 4;
13025 break;
13026 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13027 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384
AM
13028 if (reloc->r_offset < (size_t) (end - start))
13029 read_leb128 (start + reloc->r_offset, end, FALSE,
13030 &reloc_size, &leb_ret);
7d81bc93
JL
13031 break;
13032 default:
13033 reloc_size = 2;
13034 break;
13035 }
13761a11 13036
5a805384 13037 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13038 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13039 "ULEB128 value\n"),
13040 (long) reloc->r_offset);
13041 else if (sym_index >= num_syms)
f84ce13b
NC
13042 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13043 sym_index);
03f7786e 13044 else
f84ce13b
NC
13045 {
13046 value = reloc->r_addend + (symtab[sym_index].st_value
13047 - saved_sym->st_value);
13048
b32e566b 13049 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13050 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13051 else
13052 /* PR 21137 */
13053 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13054 (long) reloc->r_offset);
f84ce13b 13055 }
13761a11
NC
13056
13057 saved_sym = NULL;
13058 return TRUE;
13059 }
13060 break;
13061
13062 default:
13063 if (saved_sym != NULL)
071436c6 13064 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
13065 break;
13066 }
13067 break;
13068 }
13069
cf13d699
NC
13070 case EM_MN10300:
13071 case EM_CYGNUS_MN10300:
13072 {
13073 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 13074
f84ce13b
NC
13075 if (reloc == NULL)
13076 {
13077 saved_sym = NULL;
13078 return TRUE;
13079 }
13080
cf13d699
NC
13081 switch (reloc_type)
13082 {
13083 case 34: /* R_MN10300_ALIGN */
13084 return TRUE;
13085 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
13086 if (sym_index >= num_syms)
13087 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
13088 sym_index);
13089 else
13090 saved_sym = symtab + sym_index;
cf13d699 13091 return TRUE;
f84ce13b 13092
cf13d699
NC
13093 case 1: /* R_MN10300_32 */
13094 case 2: /* R_MN10300_16 */
13095 if (saved_sym != NULL)
13096 {
03f7786e 13097 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 13098 bfd_vma value;
252b5132 13099
f84ce13b
NC
13100 if (sym_index >= num_syms)
13101 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
13102 sym_index);
03f7786e 13103 else
f84ce13b
NC
13104 {
13105 value = reloc->r_addend + (symtab[sym_index].st_value
13106 - saved_sym->st_value);
13107
b32e566b 13108 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13109 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13110 else
13111 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
13112 (long) reloc->r_offset);
f84ce13b 13113 }
252b5132 13114
cf13d699
NC
13115 saved_sym = NULL;
13116 return TRUE;
13117 }
13118 break;
13119 default:
13120 if (saved_sym != NULL)
071436c6 13121 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
13122 break;
13123 }
13124 break;
13125 }
6ff71e76
NC
13126
13127 case EM_RL78:
13128 {
13129 static bfd_vma saved_sym1 = 0;
13130 static bfd_vma saved_sym2 = 0;
13131 static bfd_vma value;
13132
f84ce13b
NC
13133 if (reloc == NULL)
13134 {
13135 saved_sym1 = saved_sym2 = 0;
13136 return TRUE;
13137 }
13138
6ff71e76
NC
13139 switch (reloc_type)
13140 {
13141 case 0x80: /* R_RL78_SYM. */
13142 saved_sym1 = saved_sym2;
f84ce13b
NC
13143 if (sym_index >= num_syms)
13144 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
13145 sym_index);
13146 else
13147 {
13148 saved_sym2 = symtab[sym_index].st_value;
13149 saved_sym2 += reloc->r_addend;
13150 }
6ff71e76
NC
13151 return TRUE;
13152
13153 case 0x83: /* R_RL78_OPsub. */
13154 value = saved_sym1 - saved_sym2;
13155 saved_sym2 = saved_sym1 = 0;
13156 return TRUE;
13157 break;
13158
13159 case 0x41: /* R_RL78_ABS32. */
b32e566b 13160 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 13161 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
13162 else
13163 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13164 (long) reloc->r_offset);
6ff71e76
NC
13165 value = 0;
13166 return TRUE;
13167
13168 case 0x43: /* R_RL78_ABS16. */
b32e566b 13169 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 13170 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
13171 else
13172 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13173 (long) reloc->r_offset);
6ff71e76
NC
13174 value = 0;
13175 return TRUE;
13176
13177 default:
13178 break;
13179 }
13180 break;
13181 }
252b5132
RH
13182 }
13183
cf13d699 13184 return FALSE;
252b5132
RH
13185}
13186
aca88567
NC
13187/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
13188 DWARF debug sections. This is a target specific test. Note - we do not
13189 go through the whole including-target-headers-multiple-times route, (as
13190 we have already done with <elf/h8.h>) because this would become very
13191 messy and even then this function would have to contain target specific
13192 information (the names of the relocs instead of their numeric values).
13193 FIXME: This is not the correct way to solve this problem. The proper way
13194 is to have target specific reloc sizing and typing functions created by
13195 the reloc-macros.h header, in the same way that it already creates the
13196 reloc naming functions. */
13197
13198static bfd_boolean
dda8d76d 13199is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13200{
d347c9df 13201 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13202 switch (filedata->file_header.e_machine)
aca88567 13203 {
41e92641 13204 case EM_386:
22abe556 13205 case EM_IAMCU:
41e92641 13206 return reloc_type == 1; /* R_386_32. */
aca88567
NC
13207 case EM_68K:
13208 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
13209 case EM_860:
13210 return reloc_type == 1; /* R_860_32. */
13211 case EM_960:
13212 return reloc_type == 2; /* R_960_32. */
a06ea964 13213 case EM_AARCH64:
9282b95a
JW
13214 return (reloc_type == 258
13215 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
13216 case EM_BPF:
13217 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
13218 case EM_ADAPTEVA_EPIPHANY:
13219 return reloc_type == 3;
aca88567 13220 case EM_ALPHA:
137b6b5f 13221 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
13222 case EM_ARC:
13223 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
13224 case EM_ARC_COMPACT:
13225 case EM_ARC_COMPACT2:
13226 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
13227 case EM_ARM:
13228 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 13229 case EM_AVR_OLD:
aca88567
NC
13230 case EM_AVR:
13231 return reloc_type == 1;
13232 case EM_BLACKFIN:
13233 return reloc_type == 0x12; /* R_byte4_data. */
13234 case EM_CRIS:
13235 return reloc_type == 3; /* R_CRIS_32. */
13236 case EM_CR16:
13237 return reloc_type == 3; /* R_CR16_NUM32. */
13238 case EM_CRX:
13239 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
13240 case EM_CSKY:
13241 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
13242 case EM_CYGNUS_FRV:
13243 return reloc_type == 1;
41e92641
NC
13244 case EM_CYGNUS_D10V:
13245 case EM_D10V:
13246 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
13247 case EM_CYGNUS_D30V:
13248 case EM_D30V:
13249 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
13250 case EM_DLX:
13251 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
13252 case EM_CYGNUS_FR30:
13253 case EM_FR30:
13254 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
13255 case EM_FT32:
13256 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
13257 case EM_H8S:
13258 case EM_H8_300:
13259 case EM_H8_300H:
13260 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 13261 case EM_IA_64:
262cdac7
AM
13262 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
13263 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
13264 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
13265 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
13266 case EM_IP2K_OLD:
13267 case EM_IP2K:
13268 return reloc_type == 2; /* R_IP2K_32. */
13269 case EM_IQ2000:
13270 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
13271 case EM_LATTICEMICO32:
13272 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 13273 case EM_M32C_OLD:
aca88567
NC
13274 case EM_M32C:
13275 return reloc_type == 3; /* R_M32C_32. */
13276 case EM_M32R:
13277 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
13278 case EM_68HC11:
13279 case EM_68HC12:
13280 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 13281 case EM_S12Z:
2849d19f
JD
13282 return reloc_type == 7 || /* R_S12Z_EXT32 */
13283 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
13284 case EM_MCORE:
13285 return reloc_type == 1; /* R_MCORE_ADDR32. */
13286 case EM_CYGNUS_MEP:
13287 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
13288 case EM_METAG:
13289 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
13290 case EM_MICROBLAZE:
13291 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
13292 case EM_MIPS:
13293 return reloc_type == 2; /* R_MIPS_32. */
13294 case EM_MMIX:
13295 return reloc_type == 4; /* R_MMIX_32. */
13296 case EM_CYGNUS_MN10200:
13297 case EM_MN10200:
13298 return reloc_type == 1; /* R_MN10200_32. */
13299 case EM_CYGNUS_MN10300:
13300 case EM_MN10300:
13301 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
13302 case EM_MOXIE:
13303 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
13304 case EM_MSP430_OLD:
13305 case EM_MSP430:
13761a11 13306 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
13307 case EM_MT:
13308 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
13309 case EM_NDS32:
13310 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 13311 case EM_ALTERA_NIOS2:
36591ba1 13312 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
13313 case EM_NIOS32:
13314 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
13315 case EM_OR1K:
13316 return reloc_type == 1; /* R_OR1K_32. */
aca88567 13317 case EM_PARISC:
9abca702 13318 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 13319 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 13320 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
13321 case EM_PJ:
13322 case EM_PJ_OLD:
13323 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
13324 case EM_PPC64:
13325 return reloc_type == 1; /* R_PPC64_ADDR32. */
13326 case EM_PPC:
13327 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
13328 case EM_TI_PRU:
13329 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
13330 case EM_RISCV:
13331 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
13332 case EM_RL78:
13333 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
13334 case EM_RX:
13335 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
13336 case EM_S370:
13337 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
13338 case EM_S390_OLD:
13339 case EM_S390:
13340 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
13341 case EM_SCORE:
13342 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
13343 case EM_SH:
13344 return reloc_type == 1; /* R_SH_DIR32. */
13345 case EM_SPARC32PLUS:
13346 case EM_SPARCV9:
13347 case EM_SPARC:
13348 return reloc_type == 3 /* R_SPARC_32. */
13349 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
13350 case EM_SPU:
13351 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
13352 case EM_TI_C6000:
13353 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
13354 case EM_TILEGX:
13355 return reloc_type == 2; /* R_TILEGX_32. */
13356 case EM_TILEPRO:
13357 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
13358 case EM_CYGNUS_V850:
13359 case EM_V850:
13360 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
13361 case EM_V800:
13362 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
13363 case EM_VAX:
13364 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
13365 case EM_VISIUM:
13366 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
13367 case EM_WEBASSEMBLY:
13368 return reloc_type == 1; /* R_WASM32_32. */
aca88567 13369 case EM_X86_64:
8a9036a4 13370 case EM_L1OM:
7a9068fe 13371 case EM_K1OM:
aca88567 13372 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
13373 case EM_XC16X:
13374 case EM_C166:
13375 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
13376 case EM_XGATE:
13377 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
13378 case EM_XSTORMY16:
13379 return reloc_type == 1; /* R_XSTROMY16_32. */
13380 case EM_XTENSA_OLD:
13381 case EM_XTENSA:
13382 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
13383 case EM_Z80:
13384 return reloc_type == 6; /* R_Z80_32. */
aca88567 13385 default:
bee0ee85
NC
13386 {
13387 static unsigned int prev_warn = 0;
13388
13389 /* Avoid repeating the same warning multiple times. */
dda8d76d 13390 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 13391 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
13392 filedata->file_header.e_machine);
13393 prev_warn = filedata->file_header.e_machine;
bee0ee85
NC
13394 return FALSE;
13395 }
aca88567
NC
13396 }
13397}
13398
13399/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13400 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
13401
13402static bfd_boolean
dda8d76d 13403is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13404{
dda8d76d 13405 switch (filedata->file_header.e_machine)
d347c9df 13406 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 13407 {
41e92641 13408 case EM_386:
22abe556 13409 case EM_IAMCU:
3e0873ac 13410 return reloc_type == 2; /* R_386_PC32. */
aca88567 13411 case EM_68K:
3e0873ac 13412 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
13413 case EM_AARCH64:
13414 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
13415 case EM_ADAPTEVA_EPIPHANY:
13416 return reloc_type == 6;
aca88567
NC
13417 case EM_ALPHA:
13418 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
13419 case EM_ARC_COMPACT:
13420 case EM_ARC_COMPACT2:
13421 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 13422 case EM_ARM:
3e0873ac 13423 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
13424 case EM_AVR_OLD:
13425 case EM_AVR:
13426 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
13427 case EM_MICROBLAZE:
13428 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
13429 case EM_OR1K:
13430 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 13431 case EM_PARISC:
85acf597 13432 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
13433 case EM_PPC:
13434 return reloc_type == 26; /* R_PPC_REL32. */
13435 case EM_PPC64:
3e0873ac 13436 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
13437 case EM_RISCV:
13438 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
13439 case EM_S390_OLD:
13440 case EM_S390:
3e0873ac 13441 return reloc_type == 5; /* R_390_PC32. */
aca88567 13442 case EM_SH:
3e0873ac 13443 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
13444 case EM_SPARC32PLUS:
13445 case EM_SPARCV9:
13446 case EM_SPARC:
3e0873ac 13447 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
13448 case EM_SPU:
13449 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
13450 case EM_TILEGX:
13451 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
13452 case EM_TILEPRO:
13453 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
13454 case EM_VISIUM:
13455 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 13456 case EM_X86_64:
8a9036a4 13457 case EM_L1OM:
7a9068fe 13458 case EM_K1OM:
3e0873ac 13459 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
13460 case EM_VAX:
13461 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
13462 case EM_XTENSA_OLD:
13463 case EM_XTENSA:
13464 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
13465 default:
13466 /* Do not abort or issue an error message here. Not all targets use
13467 pc-relative 32-bit relocs in their DWARF debug information and we
13468 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
13469 more helpful warning message will be generated by apply_relocations
13470 anyway, so just return. */
aca88567
NC
13471 return FALSE;
13472 }
13473}
13474
13475/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13476 a 64-bit absolute RELA relocation used in DWARF debug sections. */
13477
13478static bfd_boolean
dda8d76d 13479is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13480{
dda8d76d 13481 switch (filedata->file_header.e_machine)
aca88567 13482 {
a06ea964
NC
13483 case EM_AARCH64:
13484 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
13485 case EM_ALPHA:
13486 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 13487 case EM_IA_64:
262cdac7
AM
13488 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
13489 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
13490 case EM_PARISC:
13491 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
13492 case EM_PPC64:
13493 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
13494 case EM_RISCV:
13495 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
13496 case EM_SPARC32PLUS:
13497 case EM_SPARCV9:
13498 case EM_SPARC:
714da62f
NC
13499 return reloc_type == 32 /* R_SPARC_64. */
13500 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 13501 case EM_X86_64:
8a9036a4 13502 case EM_L1OM:
7a9068fe 13503 case EM_K1OM:
aca88567 13504 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
13505 case EM_S390_OLD:
13506 case EM_S390:
aa137e4d
NC
13507 return reloc_type == 22; /* R_S390_64. */
13508 case EM_TILEGX:
13509 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 13510 case EM_MIPS:
aa137e4d 13511 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
13512 default:
13513 return FALSE;
13514 }
13515}
13516
85acf597
RH
13517/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
13518 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
13519
13520static bfd_boolean
dda8d76d 13521is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 13522{
dda8d76d 13523 switch (filedata->file_header.e_machine)
85acf597 13524 {
a06ea964
NC
13525 case EM_AARCH64:
13526 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 13527 case EM_ALPHA:
aa137e4d 13528 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 13529 case EM_IA_64:
262cdac7
AM
13530 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
13531 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 13532 case EM_PARISC:
aa137e4d 13533 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 13534 case EM_PPC64:
aa137e4d 13535 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
13536 case EM_SPARC32PLUS:
13537 case EM_SPARCV9:
13538 case EM_SPARC:
aa137e4d 13539 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 13540 case EM_X86_64:
8a9036a4 13541 case EM_L1OM:
7a9068fe 13542 case EM_K1OM:
aa137e4d 13543 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
13544 case EM_S390_OLD:
13545 case EM_S390:
aa137e4d
NC
13546 return reloc_type == 23; /* R_S390_PC64. */
13547 case EM_TILEGX:
13548 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
13549 default:
13550 return FALSE;
13551 }
13552}
13553
4dc3c23d
AM
13554/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13555 a 24-bit absolute RELA relocation used in DWARF debug sections. */
13556
13557static bfd_boolean
dda8d76d 13558is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 13559{
dda8d76d 13560 switch (filedata->file_header.e_machine)
4dc3c23d
AM
13561 {
13562 case EM_CYGNUS_MN10200:
13563 case EM_MN10200:
13564 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
13565 case EM_FT32:
13566 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
13567 case EM_Z80:
13568 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d
AM
13569 default:
13570 return FALSE;
13571 }
13572}
13573
aca88567
NC
13574/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13575 a 16-bit absolute RELA relocation used in DWARF debug sections. */
13576
13577static bfd_boolean
dda8d76d 13578is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 13579{
d347c9df 13580 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13581 switch (filedata->file_header.e_machine)
4b78141a 13582 {
886a2506
NC
13583 case EM_ARC:
13584 case EM_ARC_COMPACT:
13585 case EM_ARC_COMPACT2:
13586 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
13587 case EM_ADAPTEVA_EPIPHANY:
13588 return reloc_type == 5;
aca88567
NC
13589 case EM_AVR_OLD:
13590 case EM_AVR:
13591 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
13592 case EM_CYGNUS_D10V:
13593 case EM_D10V:
13594 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
13595 case EM_FT32:
13596 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
13597 case EM_H8S:
13598 case EM_H8_300:
13599 case EM_H8_300H:
aca88567
NC
13600 return reloc_type == R_H8_DIR16;
13601 case EM_IP2K_OLD:
13602 case EM_IP2K:
13603 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 13604 case EM_M32C_OLD:
f4236fe4
DD
13605 case EM_M32C:
13606 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
13607 case EM_CYGNUS_MN10200:
13608 case EM_MN10200:
13609 return reloc_type == 2; /* R_MN10200_16. */
13610 case EM_CYGNUS_MN10300:
13611 case EM_MN10300:
13612 return reloc_type == 2; /* R_MN10300_16. */
aca88567 13613 case EM_MSP430:
dda8d76d 13614 if (uses_msp430x_relocs (filedata))
13761a11 13615 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 13616 /* Fall through. */
78c8d46c 13617 case EM_MSP430_OLD:
aca88567 13618 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
13619 case EM_NDS32:
13620 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 13621 case EM_ALTERA_NIOS2:
36591ba1 13622 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
13623 case EM_NIOS32:
13624 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
13625 case EM_OR1K:
13626 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
13627 case EM_RISCV:
13628 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
13629 case EM_TI_PRU:
13630 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
13631 case EM_TI_C6000:
13632 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
13633 case EM_VISIUM:
13634 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
13635 case EM_XC16X:
13636 case EM_C166:
13637 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
13638 case EM_XGATE:
13639 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
13640 case EM_Z80:
13641 return reloc_type == 4; /* R_Z80_16. */
4b78141a 13642 default:
aca88567 13643 return FALSE;
4b78141a
NC
13644 }
13645}
13646
39e07931
AS
13647/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13648 a 8-bit absolute RELA relocation used in DWARF debug sections. */
13649
13650static bfd_boolean
13651is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13652{
13653 switch (filedata->file_header.e_machine)
13654 {
13655 case EM_RISCV:
13656 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
13657 case EM_Z80:
13658 return reloc_type == 1; /* R_Z80_8. */
39e07931
AS
13659 default:
13660 return FALSE;
13661 }
13662}
13663
13664/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13665 a 6-bit absolute RELA relocation used in DWARF debug sections. */
13666
13667static bfd_boolean
13668is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13669{
13670 switch (filedata->file_header.e_machine)
13671 {
13672 case EM_RISCV:
13673 return reloc_type == 53; /* R_RISCV_SET6. */
13674 default:
13675 return FALSE;
13676 }
13677}
13678
03336641
JW
13679/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13680 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
13681
13682static bfd_boolean
13683is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13684{
13685 /* Please keep this table alpha-sorted for ease of visual lookup. */
13686 switch (filedata->file_header.e_machine)
13687 {
13688 case EM_RISCV:
13689 return reloc_type == 35; /* R_RISCV_ADD32. */
13690 default:
13691 return FALSE;
13692 }
13693}
13694
13695/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13696 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
13697
13698static bfd_boolean
13699is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13700{
13701 /* Please keep this table alpha-sorted for ease of visual lookup. */
13702 switch (filedata->file_header.e_machine)
13703 {
13704 case EM_RISCV:
13705 return reloc_type == 39; /* R_RISCV_SUB32. */
13706 default:
13707 return FALSE;
13708 }
13709}
13710
13711/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13712 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
13713
13714static bfd_boolean
13715is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13716{
13717 /* Please keep this table alpha-sorted for ease of visual lookup. */
13718 switch (filedata->file_header.e_machine)
13719 {
13720 case EM_RISCV:
13721 return reloc_type == 36; /* R_RISCV_ADD64. */
13722 default:
13723 return FALSE;
13724 }
13725}
13726
13727/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13728 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
13729
13730static bfd_boolean
13731is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13732{
13733 /* Please keep this table alpha-sorted for ease of visual lookup. */
13734 switch (filedata->file_header.e_machine)
13735 {
13736 case EM_RISCV:
13737 return reloc_type == 40; /* R_RISCV_SUB64. */
13738 default:
13739 return FALSE;
13740 }
13741}
13742
13743/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13744 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
13745
13746static bfd_boolean
13747is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13748{
13749 /* Please keep this table alpha-sorted for ease of visual lookup. */
13750 switch (filedata->file_header.e_machine)
13751 {
13752 case EM_RISCV:
13753 return reloc_type == 34; /* R_RISCV_ADD16. */
13754 default:
13755 return FALSE;
13756 }
13757}
13758
13759/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13760 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
13761
13762static bfd_boolean
13763is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13764{
13765 /* Please keep this table alpha-sorted for ease of visual lookup. */
13766 switch (filedata->file_header.e_machine)
13767 {
13768 case EM_RISCV:
13769 return reloc_type == 38; /* R_RISCV_SUB16. */
13770 default:
13771 return FALSE;
13772 }
13773}
13774
13775/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13776 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
13777
13778static bfd_boolean
13779is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13780{
13781 /* Please keep this table alpha-sorted for ease of visual lookup. */
13782 switch (filedata->file_header.e_machine)
13783 {
13784 case EM_RISCV:
13785 return reloc_type == 33; /* R_RISCV_ADD8. */
13786 default:
13787 return FALSE;
13788 }
13789}
13790
13791/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13792 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
13793
13794static bfd_boolean
13795is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13796{
13797 /* Please keep this table alpha-sorted for ease of visual lookup. */
13798 switch (filedata->file_header.e_machine)
13799 {
13800 case EM_RISCV:
13801 return reloc_type == 37; /* R_RISCV_SUB8. */
13802 default:
13803 return FALSE;
13804 }
13805}
13806
39e07931
AS
13807/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13808 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
13809
13810static bfd_boolean
13811is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13812{
13813 switch (filedata->file_header.e_machine)
13814 {
13815 case EM_RISCV:
13816 return reloc_type == 52; /* R_RISCV_SUB6. */
13817 default:
13818 return FALSE;
13819 }
13820}
13821
2a7b2e88
JK
13822/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
13823 relocation entries (possibly formerly used for SHT_GROUP sections). */
13824
13825static bfd_boolean
dda8d76d 13826is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 13827{
dda8d76d 13828 switch (filedata->file_header.e_machine)
2a7b2e88 13829 {
cb8f3167 13830 case EM_386: /* R_386_NONE. */
d347c9df 13831 case EM_68K: /* R_68K_NONE. */
cfb8c092 13832 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
13833 case EM_ALPHA: /* R_ALPHA_NONE. */
13834 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 13835 case EM_ARC: /* R_ARC_NONE. */
886a2506 13836 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 13837 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 13838 case EM_ARM: /* R_ARM_NONE. */
d347c9df 13839 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 13840 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
13841 case EM_FT32: /* R_FT32_NONE. */
13842 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 13843 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
13844 case EM_L1OM: /* R_X86_64_NONE. */
13845 case EM_M32R: /* R_M32R_NONE. */
13846 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 13847 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 13848 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
13849 case EM_NIOS32: /* R_NIOS_NONE. */
13850 case EM_OR1K: /* R_OR1K_NONE. */
13851 case EM_PARISC: /* R_PARISC_NONE. */
13852 case EM_PPC64: /* R_PPC64_NONE. */
13853 case EM_PPC: /* R_PPC_NONE. */
e23eba97 13854 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
13855 case EM_S390: /* R_390_NONE. */
13856 case EM_S390_OLD:
13857 case EM_SH: /* R_SH_NONE. */
13858 case EM_SPARC32PLUS:
13859 case EM_SPARC: /* R_SPARC_NONE. */
13860 case EM_SPARCV9:
aa137e4d
NC
13861 case EM_TILEGX: /* R_TILEGX_NONE. */
13862 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
13863 case EM_TI_C6000:/* R_C6000_NONE. */
13864 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 13865 case EM_XC16X:
6655dba2 13866 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 13867 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 13868 return reloc_type == 0;
d347c9df 13869
a06ea964
NC
13870 case EM_AARCH64:
13871 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
13872 case EM_AVR_OLD:
13873 case EM_AVR:
13874 return (reloc_type == 0 /* R_AVR_NONE. */
13875 || reloc_type == 30 /* R_AVR_DIFF8. */
13876 || reloc_type == 31 /* R_AVR_DIFF16. */
13877 || reloc_type == 32 /* R_AVR_DIFF32. */);
13878 case EM_METAG:
13879 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
13880 case EM_NDS32:
13881 return (reloc_type == 0 /* R_XTENSA_NONE. */
13882 || reloc_type == 204 /* R_NDS32_DIFF8. */
13883 || reloc_type == 205 /* R_NDS32_DIFF16. */
13884 || reloc_type == 206 /* R_NDS32_DIFF32. */
13885 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
13886 case EM_TI_PRU:
13887 return (reloc_type == 0 /* R_PRU_NONE. */
13888 || reloc_type == 65 /* R_PRU_DIFF8. */
13889 || reloc_type == 66 /* R_PRU_DIFF16. */
13890 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
13891 case EM_XTENSA_OLD:
13892 case EM_XTENSA:
4dc3c23d
AM
13893 return (reloc_type == 0 /* R_XTENSA_NONE. */
13894 || reloc_type == 17 /* R_XTENSA_DIFF8. */
13895 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
13896 || reloc_type == 19 /* R_XTENSA_DIFF32. */
13897 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
13898 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
13899 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
13900 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
13901 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
13902 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88
JK
13903 }
13904 return FALSE;
13905}
13906
d1c4b12b
NC
13907/* Returns TRUE if there is a relocation against
13908 section NAME at OFFSET bytes. */
13909
13910bfd_boolean
13911reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
13912{
13913 Elf_Internal_Rela * relocs;
13914 Elf_Internal_Rela * rp;
13915
13916 if (dsec == NULL || dsec->reloc_info == NULL)
13917 return FALSE;
13918
13919 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
13920
13921 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
13922 if (rp->r_offset == offset)
13923 return TRUE;
13924
13925 return FALSE;
13926}
13927
cf13d699 13928/* Apply relocations to a section.
32ec8896
NC
13929 Returns TRUE upon success, FALSE otherwise.
13930 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
13931 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
13932 will be set to the number of relocs loaded.
13933
cf13d699 13934 Note: So far support has been added only for those relocations
32ec8896
NC
13935 which can be found in debug sections. FIXME: Add support for
13936 more relocations ? */
1b315056 13937
32ec8896 13938static bfd_boolean
dda8d76d 13939apply_relocations (Filedata * filedata,
d1c4b12b
NC
13940 const Elf_Internal_Shdr * section,
13941 unsigned char * start,
13942 bfd_size_type size,
1449284b 13943 void ** relocs_return,
d1c4b12b 13944 unsigned long * num_relocs_return)
1b315056 13945{
cf13d699 13946 Elf_Internal_Shdr * relsec;
0d2a7a93 13947 unsigned char * end = start + size;
cb8f3167 13948
d1c4b12b
NC
13949 if (relocs_return != NULL)
13950 {
13951 * (Elf_Internal_Rela **) relocs_return = NULL;
13952 * num_relocs_return = 0;
13953 }
13954
dda8d76d 13955 if (filedata->file_header.e_type != ET_REL)
32ec8896
NC
13956 /* No relocs to apply. */
13957 return TRUE;
1b315056 13958
cf13d699 13959 /* Find the reloc section associated with the section. */
dda8d76d
NC
13960 for (relsec = filedata->section_headers;
13961 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 13962 ++relsec)
252b5132 13963 {
41e92641
NC
13964 bfd_boolean is_rela;
13965 unsigned long num_relocs;
2cf0635d
NC
13966 Elf_Internal_Rela * relocs;
13967 Elf_Internal_Rela * rp;
13968 Elf_Internal_Shdr * symsec;
13969 Elf_Internal_Sym * symtab;
ba5cdace 13970 unsigned long num_syms;
2cf0635d 13971 Elf_Internal_Sym * sym;
252b5132 13972
41e92641 13973 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13974 || relsec->sh_info >= filedata->file_header.e_shnum
13975 || filedata->section_headers + relsec->sh_info != section
c256ffe7 13976 || relsec->sh_size == 0
dda8d76d 13977 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 13978 continue;
428409d5 13979
a788aedd
AM
13980 symsec = filedata->section_headers + relsec->sh_link;
13981 if (symsec->sh_type != SHT_SYMTAB
13982 && symsec->sh_type != SHT_DYNSYM)
13983 return FALSE;
13984
41e92641
NC
13985 is_rela = relsec->sh_type == SHT_RELA;
13986
13987 if (is_rela)
13988 {
dda8d76d 13989 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 13990 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13991 return FALSE;
41e92641
NC
13992 }
13993 else
13994 {
dda8d76d 13995 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 13996 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13997 return FALSE;
41e92641
NC
13998 }
13999
14000 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14001 if (filedata->file_header.e_machine == EM_SH)
41e92641 14002 is_rela = FALSE;
428409d5 14003
dda8d76d 14004 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 14005
41e92641 14006 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14007 {
41e92641
NC
14008 bfd_vma addend;
14009 unsigned int reloc_type;
14010 unsigned int reloc_size;
03336641
JW
14011 bfd_boolean reloc_inplace = FALSE;
14012 bfd_boolean reloc_subtract = FALSE;
91d6fa6a 14013 unsigned char * rloc;
ba5cdace 14014 unsigned long sym_index;
4b78141a 14015
dda8d76d 14016 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14017
dda8d76d 14018 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14019 continue;
dda8d76d 14020 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14021 continue;
dda8d76d
NC
14022 else if (is_32bit_abs_reloc (filedata, reloc_type)
14023 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14024 reloc_size = 4;
dda8d76d
NC
14025 else if (is_64bit_abs_reloc (filedata, reloc_type)
14026 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14027 reloc_size = 8;
dda8d76d 14028 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14029 reloc_size = 3;
dda8d76d 14030 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14031 reloc_size = 2;
39e07931
AS
14032 else if (is_8bit_abs_reloc (filedata, reloc_type)
14033 || is_6bit_abs_reloc (filedata, reloc_type))
14034 reloc_size = 1;
03336641
JW
14035 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14036 reloc_type))
14037 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14038 {
14039 reloc_size = 4;
14040 reloc_inplace = TRUE;
14041 }
14042 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14043 reloc_type))
14044 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14045 {
14046 reloc_size = 8;
14047 reloc_inplace = TRUE;
14048 }
14049 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14050 reloc_type))
14051 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14052 {
14053 reloc_size = 2;
14054 reloc_inplace = TRUE;
14055 }
14056 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14057 reloc_type))
14058 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14059 {
14060 reloc_size = 1;
14061 reloc_inplace = TRUE;
14062 }
39e07931
AS
14063 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
14064 reloc_type)))
14065 {
14066 reloc_size = 1;
14067 reloc_inplace = TRUE;
14068 }
aca88567 14069 else
4b78141a 14070 {
bee0ee85 14071 static unsigned int prev_reloc = 0;
dda8d76d 14072
bee0ee85
NC
14073 if (reloc_type != prev_reloc)
14074 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 14075 reloc_type, printable_section_name (filedata, section));
bee0ee85 14076 prev_reloc = reloc_type;
4b78141a
NC
14077 continue;
14078 }
103f02d3 14079
91d6fa6a 14080 rloc = start + rp->r_offset;
75802ccb 14081 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
14082 {
14083 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
14084 (unsigned long) rp->r_offset,
dda8d76d 14085 printable_section_name (filedata, section));
700dd8b7
L
14086 continue;
14087 }
103f02d3 14088
ba5cdace
NC
14089 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
14090 if (sym_index >= num_syms)
14091 {
14092 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 14093 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
14094 continue;
14095 }
14096 sym = symtab + sym_index;
41e92641
NC
14097
14098 /* If the reloc has a symbol associated with it,
55f25fc3
L
14099 make sure that it is of an appropriate type.
14100
14101 Relocations against symbols without type can happen.
14102 Gcc -feliminate-dwarf2-dups may generate symbols
14103 without type for debug info.
14104
14105 Icc generates relocations against function symbols
14106 instead of local labels.
14107
14108 Relocations against object symbols can happen, eg when
14109 referencing a global array. For an example of this see
14110 the _clz.o binary in libgcc.a. */
aca88567 14111 if (sym != symtab
b8871f35 14112 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 14113 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 14114 {
d3a49aa8 14115 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
14116 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
14117 printable_section_name (filedata, relsec),
d3a49aa8 14118 (long int)(rp - relocs));
aca88567 14119 continue;
5b18a4bc 14120 }
252b5132 14121
4dc3c23d
AM
14122 addend = 0;
14123 if (is_rela)
14124 addend += rp->r_addend;
c47320c3
AM
14125 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
14126 partial_inplace. */
4dc3c23d 14127 if (!is_rela
dda8d76d 14128 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 14129 && reloc_type == 1)
dda8d76d
NC
14130 || ((filedata->file_header.e_machine == EM_PJ
14131 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 14132 && reloc_type == 1)
dda8d76d
NC
14133 || ((filedata->file_header.e_machine == EM_D30V
14134 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
14135 && reloc_type == 12)
14136 || reloc_inplace)
39e07931
AS
14137 {
14138 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
14139 addend += byte_get (rloc, reloc_size) & 0x3f;
14140 else
14141 addend += byte_get (rloc, reloc_size);
14142 }
cb8f3167 14143
dda8d76d
NC
14144 if (is_32bit_pcrel_reloc (filedata, reloc_type)
14145 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
14146 {
14147 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 14148 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 14149 addend -= 8;
91d6fa6a 14150 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
14151 reloc_size);
14152 }
39e07931
AS
14153 else if (is_6bit_abs_reloc (filedata, reloc_type)
14154 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
14155 {
14156 if (reloc_subtract)
14157 addend -= sym->st_value;
14158 else
14159 addend += sym->st_value;
14160 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
14161 byte_put (rloc, addend, reloc_size);
14162 }
03336641
JW
14163 else if (reloc_subtract)
14164 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 14165 else
91d6fa6a 14166 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 14167 }
252b5132 14168
5b18a4bc 14169 free (symtab);
f84ce13b
NC
14170 /* Let the target specific reloc processing code know that
14171 we have finished with these relocs. */
dda8d76d 14172 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
14173
14174 if (relocs_return)
14175 {
14176 * (Elf_Internal_Rela **) relocs_return = relocs;
14177 * num_relocs_return = num_relocs;
14178 }
14179 else
14180 free (relocs);
14181
5b18a4bc
NC
14182 break;
14183 }
32ec8896 14184
dfc616fa 14185 return TRUE;
5b18a4bc 14186}
103f02d3 14187
cf13d699 14188#ifdef SUPPORT_DISASSEMBLY
32ec8896 14189static bfd_boolean
dda8d76d 14190disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14191{
dda8d76d 14192 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 14193
74e1a04b 14194 /* FIXME: XXX -- to be done --- XXX */
cf13d699 14195
32ec8896 14196 return TRUE;
cf13d699
NC
14197}
14198#endif
14199
14200/* Reads in the contents of SECTION from FILE, returning a pointer
14201 to a malloc'ed buffer or NULL if something went wrong. */
14202
14203static char *
dda8d76d 14204get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14205{
dda8d76d 14206 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
14207
14208 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
14209 {
c6b78c96 14210 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 14211 printable_section_name (filedata, section));
cf13d699
NC
14212 return NULL;
14213 }
14214
dda8d76d 14215 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 14216 _("section contents"));
cf13d699
NC
14217}
14218
0e602686
NC
14219/* Uncompresses a section that was compressed using zlib, in place. */
14220
14221static bfd_boolean
dda8d76d
NC
14222uncompress_section_contents (unsigned char ** buffer,
14223 dwarf_size_type uncompressed_size,
14224 dwarf_size_type * size)
0e602686
NC
14225{
14226 dwarf_size_type compressed_size = *size;
14227 unsigned char * compressed_buffer = *buffer;
14228 unsigned char * uncompressed_buffer;
14229 z_stream strm;
14230 int rc;
14231
14232 /* It is possible the section consists of several compressed
14233 buffers concatenated together, so we uncompress in a loop. */
14234 /* PR 18313: The state field in the z_stream structure is supposed
14235 to be invisible to the user (ie us), but some compilers will
14236 still complain about it being used without initialisation. So
14237 we first zero the entire z_stream structure and then set the fields
14238 that we need. */
14239 memset (& strm, 0, sizeof strm);
14240 strm.avail_in = compressed_size;
14241 strm.next_in = (Bytef *) compressed_buffer;
14242 strm.avail_out = uncompressed_size;
14243 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
14244
14245 rc = inflateInit (& strm);
14246 while (strm.avail_in > 0)
14247 {
14248 if (rc != Z_OK)
3624a6c1 14249 break;
0e602686
NC
14250 strm.next_out = ((Bytef *) uncompressed_buffer
14251 + (uncompressed_size - strm.avail_out));
14252 rc = inflate (&strm, Z_FINISH);
14253 if (rc != Z_STREAM_END)
3624a6c1 14254 break;
0e602686
NC
14255 rc = inflateReset (& strm);
14256 }
ad92f33d
AM
14257 if (inflateEnd (& strm) != Z_OK
14258 || rc != Z_OK
0e602686
NC
14259 || strm.avail_out != 0)
14260 goto fail;
14261
14262 *buffer = uncompressed_buffer;
14263 *size = uncompressed_size;
14264 return TRUE;
14265
14266 fail:
14267 free (uncompressed_buffer);
14268 /* Indicate decompression failure. */
14269 *buffer = NULL;
14270 return FALSE;
14271}
dd24e3da 14272
32ec8896 14273static bfd_boolean
dda8d76d 14274dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14275{
0e602686
NC
14276 Elf_Internal_Shdr * relsec;
14277 bfd_size_type num_bytes;
fd8008d8
L
14278 unsigned char * data;
14279 unsigned char * end;
14280 unsigned char * real_start;
14281 unsigned char * start;
0e602686 14282 bfd_boolean some_strings_shown;
cf13d699 14283
dda8d76d 14284 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14285 if (start == NULL)
c6b78c96
NC
14286 /* PR 21820: Do not fail if the section was empty. */
14287 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
14288
0e602686 14289 num_bytes = section->sh_size;
cf13d699 14290
dda8d76d 14291 printf (_("\nString dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 14292
0e602686
NC
14293 if (decompress_dumps)
14294 {
14295 dwarf_size_type new_size = num_bytes;
14296 dwarf_size_type uncompressed_size = 0;
14297
14298 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14299 {
14300 Elf_Internal_Chdr chdr;
14301 unsigned int compression_header_size
ebdf1ebf
NC
14302 = get_compression_header (& chdr, (unsigned char *) start,
14303 num_bytes);
5844b465
NC
14304 if (compression_header_size == 0)
14305 /* An error message will have already been generated
14306 by get_compression_header. */
14307 goto error_out;
0e602686 14308
813dabb9 14309 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14310 {
813dabb9 14311 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14312 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14313 goto error_out;
813dabb9 14314 }
813dabb9
L
14315 uncompressed_size = chdr.ch_size;
14316 start += compression_header_size;
14317 new_size -= compression_header_size;
0e602686
NC
14318 }
14319 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14320 {
14321 /* Read the zlib header. In this case, it should be "ZLIB"
14322 followed by the uncompressed section size, 8 bytes in
14323 big-endian order. */
14324 uncompressed_size = start[4]; uncompressed_size <<= 8;
14325 uncompressed_size += start[5]; uncompressed_size <<= 8;
14326 uncompressed_size += start[6]; uncompressed_size <<= 8;
14327 uncompressed_size += start[7]; uncompressed_size <<= 8;
14328 uncompressed_size += start[8]; uncompressed_size <<= 8;
14329 uncompressed_size += start[9]; uncompressed_size <<= 8;
14330 uncompressed_size += start[10]; uncompressed_size <<= 8;
14331 uncompressed_size += start[11];
14332 start += 12;
14333 new_size -= 12;
14334 }
14335
1835f746
NC
14336 if (uncompressed_size)
14337 {
14338 if (uncompress_section_contents (& start,
14339 uncompressed_size, & new_size))
14340 num_bytes = new_size;
14341 else
14342 {
14343 error (_("Unable to decompress section %s\n"),
dda8d76d 14344 printable_section_name (filedata, section));
f761cb13 14345 goto error_out;
1835f746
NC
14346 }
14347 }
bc303e5d
NC
14348 else
14349 start = real_start;
0e602686 14350 }
fd8008d8 14351
cf13d699
NC
14352 /* If the section being dumped has relocations against it the user might
14353 be expecting these relocations to have been applied. Check for this
14354 case and issue a warning message in order to avoid confusion.
14355 FIXME: Maybe we ought to have an option that dumps a section with
14356 relocs applied ? */
dda8d76d
NC
14357 for (relsec = filedata->section_headers;
14358 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14359 ++relsec)
14360 {
14361 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14362 || relsec->sh_info >= filedata->file_header.e_shnum
14363 || filedata->section_headers + relsec->sh_info != section
cf13d699 14364 || relsec->sh_size == 0
dda8d76d 14365 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14366 continue;
14367
14368 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14369 break;
14370 }
14371
cf13d699
NC
14372 data = start;
14373 end = start + num_bytes;
14374 some_strings_shown = FALSE;
14375
ba3265d0
NC
14376#ifdef HAVE_MBSTATE_T
14377 mbstate_t state;
14378 /* Initialise the multibyte conversion state. */
14379 memset (& state, 0, sizeof (state));
14380#endif
14381
14382 bfd_boolean continuing = FALSE;
14383
cf13d699
NC
14384 while (data < end)
14385 {
14386 while (!ISPRINT (* data))
14387 if (++ data >= end)
14388 break;
14389
14390 if (data < end)
14391 {
071436c6
NC
14392 size_t maxlen = end - data;
14393
ba3265d0
NC
14394 if (continuing)
14395 {
14396 printf (" ");
14397 continuing = FALSE;
14398 }
14399 else
14400 {
d1ce973e 14401 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
14402 }
14403
4082ef84
NC
14404 if (maxlen > 0)
14405 {
f3da8a96 14406 char c = 0;
ba3265d0
NC
14407
14408 while (maxlen)
14409 {
14410 c = *data++;
14411
14412 if (c == 0)
14413 break;
14414
14415 /* PR 25543: Treat new-lines as string-ending characters. */
14416 if (c == '\n')
14417 {
14418 printf ("\\n\n");
14419 if (*data != 0)
14420 continuing = TRUE;
14421 break;
14422 }
14423
14424 /* Do not print control characters directly as they can affect terminal
14425 settings. Such characters usually appear in the names generated
14426 by the assembler for local labels. */
14427 if (ISCNTRL (c))
14428 {
14429 printf ("^%c", c + 0x40);
14430 }
14431 else if (ISPRINT (c))
14432 {
14433 putchar (c);
14434 }
14435 else
14436 {
14437 size_t n;
14438#ifdef HAVE_MBSTATE_T
14439 wchar_t w;
14440#endif
14441 /* Let printf do the hard work of displaying multibyte characters. */
14442 printf ("%.1s", data - 1);
14443#ifdef HAVE_MBSTATE_T
14444 /* Try to find out how many bytes made up the character that was
14445 just printed. Advance the symbol pointer past the bytes that
14446 were displayed. */
14447 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
14448#else
14449 n = 1;
14450#endif
14451 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
14452 data += (n - 1);
14453 }
14454 }
14455
14456 if (c != '\n')
14457 putchar ('\n');
4082ef84
NC
14458 }
14459 else
14460 {
14461 printf (_("<corrupt>\n"));
14462 data = end;
14463 }
cf13d699
NC
14464 some_strings_shown = TRUE;
14465 }
14466 }
14467
14468 if (! some_strings_shown)
14469 printf (_(" No strings found in this section."));
14470
0e602686 14471 free (real_start);
cf13d699
NC
14472
14473 putchar ('\n');
32ec8896 14474 return TRUE;
f761cb13
AM
14475
14476error_out:
14477 free (real_start);
14478 return FALSE;
cf13d699
NC
14479}
14480
32ec8896 14481static bfd_boolean
dda8d76d
NC
14482dump_section_as_bytes (Elf_Internal_Shdr * section,
14483 Filedata * filedata,
14484 bfd_boolean relocate)
cf13d699
NC
14485{
14486 Elf_Internal_Shdr * relsec;
0e602686
NC
14487 bfd_size_type bytes;
14488 bfd_size_type section_size;
14489 bfd_vma addr;
14490 unsigned char * data;
14491 unsigned char * real_start;
14492 unsigned char * start;
14493
dda8d76d 14494 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14495 if (start == NULL)
c6b78c96
NC
14496 /* PR 21820: Do not fail if the section was empty. */
14497 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
32ec8896 14498
0e602686 14499 section_size = section->sh_size;
cf13d699 14500
dda8d76d 14501 printf (_("\nHex dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 14502
0e602686
NC
14503 if (decompress_dumps)
14504 {
14505 dwarf_size_type new_size = section_size;
14506 dwarf_size_type uncompressed_size = 0;
14507
14508 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14509 {
14510 Elf_Internal_Chdr chdr;
14511 unsigned int compression_header_size
ebdf1ebf 14512 = get_compression_header (& chdr, start, section_size);
0e602686 14513
5844b465
NC
14514 if (compression_header_size == 0)
14515 /* An error message will have already been generated
14516 by get_compression_header. */
14517 goto error_out;
14518
813dabb9 14519 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14520 {
813dabb9 14521 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14522 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14523 goto error_out;
0e602686 14524 }
813dabb9
L
14525 uncompressed_size = chdr.ch_size;
14526 start += compression_header_size;
14527 new_size -= compression_header_size;
0e602686
NC
14528 }
14529 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14530 {
14531 /* Read the zlib header. In this case, it should be "ZLIB"
14532 followed by the uncompressed section size, 8 bytes in
14533 big-endian order. */
14534 uncompressed_size = start[4]; uncompressed_size <<= 8;
14535 uncompressed_size += start[5]; uncompressed_size <<= 8;
14536 uncompressed_size += start[6]; uncompressed_size <<= 8;
14537 uncompressed_size += start[7]; uncompressed_size <<= 8;
14538 uncompressed_size += start[8]; uncompressed_size <<= 8;
14539 uncompressed_size += start[9]; uncompressed_size <<= 8;
14540 uncompressed_size += start[10]; uncompressed_size <<= 8;
14541 uncompressed_size += start[11];
14542 start += 12;
14543 new_size -= 12;
14544 }
14545
f055032e
NC
14546 if (uncompressed_size)
14547 {
14548 if (uncompress_section_contents (& start, uncompressed_size,
14549 & new_size))
bc303e5d
NC
14550 {
14551 section_size = new_size;
14552 }
f055032e
NC
14553 else
14554 {
14555 error (_("Unable to decompress section %s\n"),
dda8d76d 14556 printable_section_name (filedata, section));
bc303e5d 14557 /* FIXME: Print the section anyway ? */
f761cb13 14558 goto error_out;
f055032e
NC
14559 }
14560 }
bc303e5d
NC
14561 else
14562 start = real_start;
0e602686 14563 }
14ae95f2 14564
cf13d699
NC
14565 if (relocate)
14566 {
dda8d76d 14567 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 14568 goto error_out;
cf13d699
NC
14569 }
14570 else
14571 {
14572 /* If the section being dumped has relocations against it the user might
14573 be expecting these relocations to have been applied. Check for this
14574 case and issue a warning message in order to avoid confusion.
14575 FIXME: Maybe we ought to have an option that dumps a section with
14576 relocs applied ? */
dda8d76d
NC
14577 for (relsec = filedata->section_headers;
14578 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14579 ++relsec)
14580 {
14581 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14582 || relsec->sh_info >= filedata->file_header.e_shnum
14583 || filedata->section_headers + relsec->sh_info != section
cf13d699 14584 || relsec->sh_size == 0
dda8d76d 14585 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14586 continue;
14587
14588 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14589 break;
14590 }
14591 }
14592
14593 addr = section->sh_addr;
0e602686 14594 bytes = section_size;
cf13d699
NC
14595 data = start;
14596
14597 while (bytes)
14598 {
14599 int j;
14600 int k;
14601 int lbytes;
14602
14603 lbytes = (bytes > 16 ? 16 : bytes);
14604
14605 printf (" 0x%8.8lx ", (unsigned long) addr);
14606
14607 for (j = 0; j < 16; j++)
14608 {
14609 if (j < lbytes)
14610 printf ("%2.2x", data[j]);
14611 else
14612 printf (" ");
14613
14614 if ((j & 3) == 3)
14615 printf (" ");
14616 }
14617
14618 for (j = 0; j < lbytes; j++)
14619 {
14620 k = data[j];
14621 if (k >= ' ' && k < 0x7f)
14622 printf ("%c", k);
14623 else
14624 printf (".");
14625 }
14626
14627 putchar ('\n');
14628
14629 data += lbytes;
14630 addr += lbytes;
14631 bytes -= lbytes;
14632 }
14633
0e602686 14634 free (real_start);
cf13d699
NC
14635
14636 putchar ('\n');
32ec8896 14637 return TRUE;
f761cb13
AM
14638
14639 error_out:
14640 free (real_start);
14641 return FALSE;
cf13d699
NC
14642}
14643
094e34f2 14644#ifdef ENABLE_LIBCTF
7d9813f1
NA
14645static ctf_sect_t *
14646shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
14647{
b9e920ec 14648 buf->cts_name = SECTION_NAME_PRINT (shdr);
7d9813f1
NA
14649 buf->cts_size = shdr->sh_size;
14650 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
14651
14652 return buf;
14653}
14654
14655/* Formatting callback function passed to ctf_dump. Returns either the pointer
14656 it is passed, or a pointer to newly-allocated storage, in which case
14657 dump_ctf() will free it when it no longer needs it. */
14658
2f6ecaed
NA
14659static char *
14660dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14661 char *s, void *arg)
7d9813f1 14662{
3e50a591 14663 const char *blanks = arg;
7d9813f1
NA
14664 char *new_s;
14665
3e50a591 14666 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
14667 return s;
14668 return new_s;
14669}
14670
926c9e76
NA
14671/* Dump CTF errors/warnings. */
14672static void
139633c3 14673dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
14674{
14675 ctf_next_t *it = NULL;
14676 char *errtext;
14677 int is_warning;
14678 int err;
14679
14680 /* Dump accumulated errors and warnings. */
14681 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
14682 {
5e9b84f7 14683 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
14684 errtext);
14685 free (errtext);
14686 }
14687 if (err != ECTF_NEXT_END)
14688 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
14689}
14690
2f6ecaed
NA
14691/* Dump one CTF archive member. */
14692
14693static int
139633c3 14694dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
2f6ecaed 14695{
139633c3 14696 ctf_dict_t *parent = (ctf_dict_t *) arg;
2f6ecaed
NA
14697 const char *things[] = {"Header", "Labels", "Data objects",
14698 "Function objects", "Variables", "Types", "Strings",
14699 ""};
14700 const char **thing;
14701 size_t i;
8b37e7b6 14702 int err = 0;
2f6ecaed
NA
14703
14704 /* Only print out the name of non-default-named archive members.
14705 The name .ctf appears everywhere, even for things that aren't
14706 really archives, so printing it out is liable to be confusing.
14707
14708 The parent, if there is one, is the default-owned archive member:
14709 avoid importing it into itself. (This does no harm, but looks
14710 confusing.) */
14711
14712 if (strcmp (name, ".ctf") != 0)
14713 {
14714 printf (_("\nCTF archive member: %s:\n"), name);
14715 ctf_import (ctf, parent);
14716 }
14717
14718 for (i = 0, thing = things; *thing[0]; thing++, i++)
14719 {
14720 ctf_dump_state_t *s = NULL;
14721 char *item;
14722
14723 printf ("\n %s:\n", *thing);
14724 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
14725 (void *) " ")) != NULL)
14726 {
14727 printf ("%s\n", item);
14728 free (item);
14729 }
14730
14731 if (ctf_errno (ctf))
14732 {
14733 error (_("Iteration failed: %s, %s\n"), *thing,
14734 ctf_errmsg (ctf_errno (ctf)));
8b37e7b6
NA
14735 err = 1;
14736 goto out;
2f6ecaed
NA
14737 }
14738 }
8b37e7b6
NA
14739
14740 out:
926c9e76 14741 dump_ctf_errs (ctf);
8b37e7b6 14742 return err;
2f6ecaed
NA
14743}
14744
7d9813f1
NA
14745static bfd_boolean
14746dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
14747{
14748 Elf_Internal_Shdr * parent_sec = NULL;
14749 Elf_Internal_Shdr * symtab_sec = NULL;
14750 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
14751 void * data = NULL;
14752 void * symdata = NULL;
14753 void * strdata = NULL;
14754 void * parentdata = NULL;
14755 ctf_sect_t ctfsect, symsect, strsect, parentsect;
14756 ctf_sect_t * symsectp = NULL;
14757 ctf_sect_t * strsectp = NULL;
2f6ecaed
NA
14758 ctf_archive_t * ctfa = NULL;
14759 ctf_archive_t * parenta = NULL, *lookparent;
139633c3 14760 ctf_dict_t * parent = NULL;
7d9813f1 14761
7d9813f1
NA
14762 int err;
14763 bfd_boolean ret = FALSE;
7d9813f1
NA
14764
14765 shdr_to_ctf_sect (&ctfsect, section, filedata);
14766 data = get_section_contents (section, filedata);
14767 ctfsect.cts_data = data;
14768
616febde 14769 if (!dump_ctf_symtab_name)
3d16b64e 14770 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
14771
14772 if (!dump_ctf_strtab_name)
3d16b64e 14773 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
14774
14775 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
14776 {
14777 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
14778 {
14779 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
14780 goto fail;
14781 }
14782 if ((symdata = (void *) get_data (NULL, filedata,
14783 symtab_sec->sh_offset, 1,
14784 symtab_sec->sh_size,
14785 _("symbols"))) == NULL)
14786 goto fail;
14787 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
14788 symsect.cts_data = symdata;
14789 }
df16e041 14790 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
14791 {
14792 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
14793 {
14794 error (_("No string table section named %s\n"),
14795 dump_ctf_strtab_name);
14796 goto fail;
14797 }
14798 if ((strdata = (void *) get_data (NULL, filedata,
14799 strtab_sec->sh_offset, 1,
14800 strtab_sec->sh_size,
14801 _("strings"))) == NULL)
14802 goto fail;
14803 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
14804 strsect.cts_data = strdata;
14805 }
14806 if (dump_ctf_parent_name)
14807 {
14808 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
14809 {
14810 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
14811 goto fail;
14812 }
14813 if ((parentdata = (void *) get_data (NULL, filedata,
14814 parent_sec->sh_offset, 1,
14815 parent_sec->sh_size,
14816 _("CTF parent"))) == NULL)
14817 goto fail;
14818 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
14819 parentsect.cts_data = parentdata;
14820 }
14821
2f6ecaed
NA
14822 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
14823 libctf papers over the difference, so we can pretend it is always an
14824 archive. Possibly open the parent as well, if one was specified. */
7d9813f1 14825
2f6ecaed 14826 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 14827 {
926c9e76 14828 dump_ctf_errs (NULL);
7d9813f1
NA
14829 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14830 goto fail;
14831 }
14832
96c61be5
NA
14833 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
14834 != ELFDATA2MSB);
14835
7d9813f1
NA
14836 if (parentdata)
14837 {
2f6ecaed
NA
14838 if ((parenta = ctf_arc_bufopen (&parentsect, symsectp, strsectp,
14839 &err)) == NULL)
7d9813f1 14840 {
926c9e76 14841 dump_ctf_errs (NULL);
7d9813f1
NA
14842 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14843 goto fail;
14844 }
2f6ecaed
NA
14845 lookparent = parenta;
14846 }
14847 else
14848 lookparent = ctfa;
7d9813f1 14849
2f6ecaed
NA
14850 /* Assume that the applicable parent archive member is the default one.
14851 (This is what all known implementations are expected to do, if they
14852 put CTFs and their parents in archives together.) */
ae41200b 14853 if ((parent = ctf_dict_open (lookparent, NULL, &err)) == NULL)
2f6ecaed 14854 {
926c9e76 14855 dump_ctf_errs (NULL);
2f6ecaed
NA
14856 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14857 goto fail;
7d9813f1
NA
14858 }
14859
14860 ret = TRUE;
14861
14862 printf (_("\nDump of CTF section '%s':\n"),
14863 printable_section_name (filedata, section));
14864
83d59285
NA
14865 if ((err = ctf_archive_iter (ctfa, dump_ctf_archive_member, parent)) != 0)
14866 {
14867 dump_ctf_errs (NULL);
14868 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
14869 ret = FALSE;
14870 }
7d9813f1
NA
14871
14872 fail:
139633c3 14873 ctf_dict_close (parent);
2f6ecaed
NA
14874 ctf_close (ctfa);
14875 ctf_close (parenta);
7d9813f1
NA
14876 free (parentdata);
14877 free (data);
14878 free (symdata);
14879 free (strdata);
14880 return ret;
14881}
094e34f2 14882#endif
7d9813f1 14883
32ec8896 14884static bfd_boolean
dda8d76d
NC
14885load_specific_debug_section (enum dwarf_section_display_enum debug,
14886 const Elf_Internal_Shdr * sec,
14887 void * data)
1007acb3 14888{
2cf0635d 14889 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 14890 char buf [64];
dda8d76d 14891 Filedata * filedata = (Filedata *) data;
9abca702 14892
19e6b90e 14893 if (section->start != NULL)
dda8d76d
NC
14894 {
14895 /* If it is already loaded, do nothing. */
14896 if (streq (section->filename, filedata->file_name))
14897 return TRUE;
14898 free (section->start);
14899 }
1007acb3 14900
19e6b90e
L
14901 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
14902 section->address = sec->sh_addr;
dda8d76d
NC
14903 section->filename = filedata->file_name;
14904 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
14905 sec->sh_offset, 1,
14906 sec->sh_size, buf);
59245841
NC
14907 if (section->start == NULL)
14908 section->size = 0;
14909 else
14910 {
77115a4a
L
14911 unsigned char *start = section->start;
14912 dwarf_size_type size = sec->sh_size;
dab394de 14913 dwarf_size_type uncompressed_size = 0;
77115a4a
L
14914
14915 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
14916 {
14917 Elf_Internal_Chdr chdr;
d8024a91
NC
14918 unsigned int compression_header_size;
14919
f53be977
L
14920 if (size < (is_32bit_elf
14921 ? sizeof (Elf32_External_Chdr)
14922 : sizeof (Elf64_External_Chdr)))
d8024a91 14923 {
55be8fd0 14924 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 14925 section->name);
32ec8896 14926 return FALSE;
d8024a91
NC
14927 }
14928
ebdf1ebf 14929 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
14930 if (compression_header_size == 0)
14931 /* An error message will have already been generated
14932 by get_compression_header. */
14933 return FALSE;
d8024a91 14934
813dabb9
L
14935 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
14936 {
14937 warn (_("section '%s' has unsupported compress type: %d\n"),
14938 section->name, chdr.ch_type);
32ec8896 14939 return FALSE;
813dabb9 14940 }
dab394de 14941 uncompressed_size = chdr.ch_size;
77115a4a
L
14942 start += compression_header_size;
14943 size -= compression_header_size;
14944 }
dab394de
L
14945 else if (size > 12 && streq ((char *) start, "ZLIB"))
14946 {
14947 /* Read the zlib header. In this case, it should be "ZLIB"
14948 followed by the uncompressed section size, 8 bytes in
14949 big-endian order. */
14950 uncompressed_size = start[4]; uncompressed_size <<= 8;
14951 uncompressed_size += start[5]; uncompressed_size <<= 8;
14952 uncompressed_size += start[6]; uncompressed_size <<= 8;
14953 uncompressed_size += start[7]; uncompressed_size <<= 8;
14954 uncompressed_size += start[8]; uncompressed_size <<= 8;
14955 uncompressed_size += start[9]; uncompressed_size <<= 8;
14956 uncompressed_size += start[10]; uncompressed_size <<= 8;
14957 uncompressed_size += start[11];
14958 start += 12;
14959 size -= 12;
14960 }
14961
1835f746 14962 if (uncompressed_size)
77115a4a 14963 {
1835f746
NC
14964 if (uncompress_section_contents (&start, uncompressed_size,
14965 &size))
14966 {
14967 /* Free the compressed buffer, update the section buffer
14968 and the section size if uncompress is successful. */
14969 free (section->start);
14970 section->start = start;
14971 }
14972 else
14973 {
14974 error (_("Unable to decompress section %s\n"),
dda8d76d 14975 printable_section_name (filedata, sec));
32ec8896 14976 return FALSE;
1835f746 14977 }
77115a4a 14978 }
bc303e5d 14979
77115a4a 14980 section->size = size;
59245841 14981 }
4a114e3e 14982
1b315056 14983 if (section->start == NULL)
32ec8896 14984 return FALSE;
1b315056 14985
19e6b90e 14986 if (debug_displays [debug].relocate)
32ec8896 14987 {
dda8d76d 14988 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896
NC
14989 & section->reloc_info, & section->num_relocs))
14990 return FALSE;
14991 }
d1c4b12b
NC
14992 else
14993 {
14994 section->reloc_info = NULL;
14995 section->num_relocs = 0;
14996 }
1007acb3 14997
32ec8896 14998 return TRUE;
1007acb3
L
14999}
15000
301a9420
AM
15001#if HAVE_LIBDEBUGINFOD
15002/* Return a hex string representation of the build-id. */
15003unsigned char *
15004get_build_id (void * data)
15005{
15006 Filedata * filedata = (Filedata *)data;
15007 Elf_Internal_Shdr * shdr;
15008 unsigned long i;
15009
55be8fd0
NC
15010 /* Iterate through notes to find note.gnu.build-id.
15011 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15012 for (i = 0, shdr = filedata->section_headers;
15013 i < filedata->file_header.e_shnum && shdr != NULL;
15014 i++, shdr++)
15015 {
15016 if (shdr->sh_type != SHT_NOTE)
15017 continue;
15018
15019 char * next;
15020 char * end;
15021 size_t data_remaining;
15022 size_t min_notesz;
15023 Elf_External_Note * enote;
15024 Elf_Internal_Note inote;
15025
15026 bfd_vma offset = shdr->sh_offset;
15027 bfd_vma align = shdr->sh_addralign;
15028 bfd_vma length = shdr->sh_size;
15029
15030 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15031 if (enote == NULL)
15032 continue;
15033
15034 if (align < 4)
15035 align = 4;
15036 else if (align != 4 && align != 8)
f761cb13
AM
15037 {
15038 free (enote);
15039 continue;
15040 }
301a9420
AM
15041
15042 end = (char *) enote + length;
15043 data_remaining = end - (char *) enote;
15044
15045 if (!is_ia64_vms (filedata))
15046 {
15047 min_notesz = offsetof (Elf_External_Note, name);
15048 if (data_remaining < min_notesz)
15049 {
55be8fd0
NC
15050 warn (_("\
15051malformed note encountered in section %s whilst scanning for build-id note\n"),
15052 printable_section_name (filedata, shdr));
f761cb13 15053 free (enote);
55be8fd0 15054 continue;
301a9420
AM
15055 }
15056 data_remaining -= min_notesz;
15057
15058 inote.type = BYTE_GET (enote->type);
15059 inote.namesz = BYTE_GET (enote->namesz);
15060 inote.namedata = enote->name;
15061 inote.descsz = BYTE_GET (enote->descsz);
15062 inote.descdata = ((char *) enote
15063 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15064 inote.descpos = offset + (inote.descdata - (char *) enote);
15065 next = ((char *) enote
15066 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15067 }
15068 else
15069 {
15070 Elf64_External_VMS_Note *vms_enote;
15071
15072 /* PR binutils/15191
15073 Make sure that there is enough data to read. */
15074 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15075 if (data_remaining < min_notesz)
15076 {
55be8fd0
NC
15077 warn (_("\
15078malformed note encountered in section %s whilst scanning for build-id note\n"),
15079 printable_section_name (filedata, shdr));
f761cb13 15080 free (enote);
55be8fd0 15081 continue;
301a9420
AM
15082 }
15083 data_remaining -= min_notesz;
15084
15085 vms_enote = (Elf64_External_VMS_Note *) enote;
15086 inote.type = BYTE_GET (vms_enote->type);
15087 inote.namesz = BYTE_GET (vms_enote->namesz);
15088 inote.namedata = vms_enote->name;
15089 inote.descsz = BYTE_GET (vms_enote->descsz);
15090 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15091 inote.descpos = offset + (inote.descdata - (char *) enote);
15092 next = inote.descdata + align_power (inote.descsz, 3);
15093 }
15094
15095 /* Skip malformed notes. */
15096 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
15097 || (size_t) (inote.descdata - inote.namedata) > data_remaining
15098 || (size_t) (next - inote.descdata) < inote.descsz
15099 || ((size_t) (next - inote.descdata)
15100 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
15101 {
55be8fd0
NC
15102 warn (_("\
15103malformed note encountered in section %s whilst scanning for build-id note\n"),
15104 printable_section_name (filedata, shdr));
f761cb13 15105 free (enote);
301a9420
AM
15106 continue;
15107 }
15108
15109 /* Check if this is the build-id note. If so then convert the build-id
15110 bytes to a hex string. */
15111 if (inote.namesz > 0
15112 && const_strneq (inote.namedata, "GNU")
15113 && inote.type == NT_GNU_BUILD_ID)
15114 {
15115 unsigned long j;
15116 char * build_id;
15117
15118 build_id = malloc (inote.descsz * 2 + 1);
15119 if (build_id == NULL)
f761cb13
AM
15120 {
15121 free (enote);
15122 return NULL;
15123 }
301a9420
AM
15124
15125 for (j = 0; j < inote.descsz; ++j)
15126 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
15127 build_id[inote.descsz * 2] = '\0';
f761cb13 15128 free (enote);
301a9420 15129
55be8fd0 15130 return (unsigned char *) build_id;
301a9420 15131 }
f761cb13 15132 free (enote);
301a9420
AM
15133 }
15134
15135 return NULL;
15136}
15137#endif /* HAVE_LIBDEBUGINFOD */
15138
657d0d47
CC
15139/* If this is not NULL, load_debug_section will only look for sections
15140 within the list of sections given here. */
32ec8896 15141static unsigned int * section_subset = NULL;
657d0d47 15142
32ec8896 15143bfd_boolean
dda8d76d 15144load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 15145{
2cf0635d
NC
15146 struct dwarf_section * section = &debug_displays [debug].section;
15147 Elf_Internal_Shdr * sec;
dda8d76d
NC
15148 Filedata * filedata = (Filedata *) data;
15149
f425ec66
NC
15150 /* Without section headers we cannot find any sections. */
15151 if (filedata->section_headers == NULL)
15152 return FALSE;
15153
9c1ce108
AM
15154 if (filedata->string_table == NULL
15155 && filedata->file_header.e_shstrndx != SHN_UNDEF
15156 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
15157 {
15158 Elf_Internal_Shdr * strs;
15159
15160 /* Read in the string table, so that we have section names to scan. */
15161 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
15162
4dff97b2 15163 if (strs != NULL && strs->sh_size != 0)
dda8d76d 15164 {
9c1ce108
AM
15165 filedata->string_table
15166 = (char *) get_data (NULL, filedata, strs->sh_offset,
15167 1, strs->sh_size, _("string table"));
dda8d76d 15168
9c1ce108
AM
15169 filedata->string_table_length
15170 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
15171 }
15172 }
d966045b
DJ
15173
15174 /* Locate the debug section. */
dda8d76d 15175 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
15176 if (sec != NULL)
15177 section->name = section->uncompressed_name;
15178 else
15179 {
dda8d76d 15180 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
15181 if (sec != NULL)
15182 section->name = section->compressed_name;
15183 }
15184 if (sec == NULL)
32ec8896 15185 return FALSE;
d966045b 15186
657d0d47
CC
15187 /* If we're loading from a subset of sections, and we've loaded
15188 a section matching this name before, it's likely that it's a
15189 different one. */
15190 if (section_subset != NULL)
15191 free_debug_section (debug);
15192
dda8d76d 15193 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
15194}
15195
19e6b90e
L
15196void
15197free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 15198{
2cf0635d 15199 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 15200
19e6b90e
L
15201 if (section->start == NULL)
15202 return;
1007acb3 15203
19e6b90e
L
15204 free ((char *) section->start);
15205 section->start = NULL;
15206 section->address = 0;
15207 section->size = 0;
a788aedd 15208
9db70fc3
AM
15209 free (section->reloc_info);
15210 section->reloc_info = NULL;
15211 section->num_relocs = 0;
1007acb3
L
15212}
15213
32ec8896 15214static bfd_boolean
dda8d76d 15215display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 15216{
b9e920ec 15217 char * name = SECTION_NAME_VALID (section) ? SECTION_NAME (section) : "";
dda8d76d 15218 const char * print_name = printable_section_name (filedata, section);
19e6b90e 15219 bfd_size_type length;
32ec8896 15220 bfd_boolean result = TRUE;
3f5e193b 15221 int i;
1007acb3 15222
19e6b90e
L
15223 length = section->sh_size;
15224 if (length == 0)
1007acb3 15225 {
74e1a04b 15226 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
32ec8896 15227 return TRUE;
1007acb3 15228 }
5dff79d8
NC
15229 if (section->sh_type == SHT_NOBITS)
15230 {
15231 /* There is no point in dumping the contents of a debugging section
15232 which has the NOBITS type - the bits in the file will be random.
15233 This can happen when a file containing a .eh_frame section is
15234 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
15235 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
15236 print_name);
32ec8896 15237 return FALSE;
5dff79d8 15238 }
1007acb3 15239
0112cd26 15240 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 15241 name = ".debug_info";
1007acb3 15242
19e6b90e
L
15243 /* See if we know how to display the contents of this section. */
15244 for (i = 0; i < max; i++)
d85bf2ba
NC
15245 {
15246 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
15247 struct dwarf_section_display * display = debug_displays + i;
15248 struct dwarf_section * sec = & display->section;
d966045b 15249
d85bf2ba
NC
15250 if (streq (sec->uncompressed_name, name)
15251 || (id == line && const_strneq (name, ".debug_line."))
15252 || streq (sec->compressed_name, name))
15253 {
15254 bfd_boolean secondary = (section != find_section (filedata, name));
1007acb3 15255
d85bf2ba
NC
15256 if (secondary)
15257 free_debug_section (id);
dda8d76d 15258
d85bf2ba
NC
15259 if (i == line && const_strneq (name, ".debug_line."))
15260 sec->name = name;
15261 else if (streq (sec->uncompressed_name, name))
15262 sec->name = sec->uncompressed_name;
15263 else
15264 sec->name = sec->compressed_name;
657d0d47 15265
d85bf2ba
NC
15266 if (load_specific_debug_section (id, section, filedata))
15267 {
15268 /* If this debug section is part of a CU/TU set in a .dwp file,
15269 restrict load_debug_section to the sections in that set. */
15270 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 15271
d85bf2ba 15272 result &= display->display (sec, filedata);
657d0d47 15273
d85bf2ba 15274 section_subset = NULL;
1007acb3 15275
d85bf2ba
NC
15276 if (secondary || (id != info && id != abbrev))
15277 free_debug_section (id);
15278 }
15279 break;
15280 }
15281 }
1007acb3 15282
19e6b90e 15283 if (i == max)
1007acb3 15284 {
74e1a04b 15285 printf (_("Unrecognized debug section: %s\n"), print_name);
32ec8896 15286 result = FALSE;
1007acb3
L
15287 }
15288
19e6b90e 15289 return result;
5b18a4bc 15290}
103f02d3 15291
aef1f6d0
DJ
15292/* Set DUMP_SECTS for all sections where dumps were requested
15293 based on section name. */
15294
15295static void
dda8d76d 15296initialise_dumps_byname (Filedata * filedata)
aef1f6d0 15297{
2cf0635d 15298 struct dump_list_entry * cur;
aef1f6d0
DJ
15299
15300 for (cur = dump_sects_byname; cur; cur = cur->next)
15301 {
15302 unsigned int i;
32ec8896 15303 bfd_boolean any = FALSE;
aef1f6d0 15304
dda8d76d 15305 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
15306 if (SECTION_NAME_VALID (filedata->section_headers + i)
15307 && streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 15308 {
6431e409 15309 request_dump_bynumber (&filedata->dump, i, cur->type);
32ec8896 15310 any = TRUE;
aef1f6d0
DJ
15311 }
15312
15313 if (!any)
15314 warn (_("Section '%s' was not dumped because it does not exist!\n"),
15315 cur->name);
15316 }
15317}
15318
32ec8896 15319static bfd_boolean
dda8d76d 15320process_section_contents (Filedata * filedata)
5b18a4bc 15321{
2cf0635d 15322 Elf_Internal_Shdr * section;
19e6b90e 15323 unsigned int i;
32ec8896 15324 bfd_boolean res = TRUE;
103f02d3 15325
19e6b90e 15326 if (! do_dump)
32ec8896 15327 return TRUE;
103f02d3 15328
dda8d76d 15329 initialise_dumps_byname (filedata);
aef1f6d0 15330
dda8d76d 15331 for (i = 0, section = filedata->section_headers;
6431e409 15332 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
15333 i++, section++)
15334 {
6431e409 15335 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 15336
19e6b90e 15337#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
15338 if (dump & DISASS_DUMP)
15339 {
15340 if (! disassemble_section (section, filedata))
15341 res = FALSE;
15342 }
19e6b90e 15343#endif
dda8d76d 15344 if (dump & HEX_DUMP)
32ec8896 15345 {
dda8d76d 15346 if (! dump_section_as_bytes (section, filedata, FALSE))
32ec8896
NC
15347 res = FALSE;
15348 }
103f02d3 15349
dda8d76d 15350 if (dump & RELOC_DUMP)
32ec8896 15351 {
dda8d76d 15352 if (! dump_section_as_bytes (section, filedata, TRUE))
32ec8896
NC
15353 res = FALSE;
15354 }
09c11c86 15355
dda8d76d 15356 if (dump & STRING_DUMP)
32ec8896 15357 {
dda8d76d 15358 if (! dump_section_as_strings (section, filedata))
32ec8896
NC
15359 res = FALSE;
15360 }
cf13d699 15361
dda8d76d 15362 if (dump & DEBUG_DUMP)
32ec8896 15363 {
dda8d76d 15364 if (! display_debug_section (i, section, filedata))
32ec8896
NC
15365 res = FALSE;
15366 }
7d9813f1 15367
094e34f2 15368#ifdef ENABLE_LIBCTF
7d9813f1
NA
15369 if (dump & CTF_DUMP)
15370 {
15371 if (! dump_section_as_ctf (section, filedata))
15372 res = FALSE;
15373 }
094e34f2 15374#endif
5b18a4bc 15375 }
103f02d3 15376
19e6b90e
L
15377 /* Check to see if the user requested a
15378 dump of a section that does not exist. */
6431e409 15379 while (i < filedata->dump.num_dump_sects)
0ee3043f 15380 {
6431e409 15381 if (filedata->dump.dump_sects[i])
32ec8896
NC
15382 {
15383 warn (_("Section %d was not dumped because it does not exist!\n"), i);
15384 res = FALSE;
15385 }
0ee3043f
NC
15386 i++;
15387 }
32ec8896
NC
15388
15389 return res;
5b18a4bc 15390}
103f02d3 15391
5b18a4bc 15392static void
19e6b90e 15393process_mips_fpe_exception (int mask)
5b18a4bc 15394{
19e6b90e
L
15395 if (mask)
15396 {
32ec8896
NC
15397 bfd_boolean first = TRUE;
15398
19e6b90e 15399 if (mask & OEX_FPU_INEX)
32ec8896 15400 fputs ("INEX", stdout), first = FALSE;
19e6b90e 15401 if (mask & OEX_FPU_UFLO)
32ec8896 15402 printf ("%sUFLO", first ? "" : "|"), first = FALSE;
19e6b90e 15403 if (mask & OEX_FPU_OFLO)
32ec8896 15404 printf ("%sOFLO", first ? "" : "|"), first = FALSE;
19e6b90e 15405 if (mask & OEX_FPU_DIV0)
32ec8896 15406 printf ("%sDIV0", first ? "" : "|"), first = FALSE;
19e6b90e
L
15407 if (mask & OEX_FPU_INVAL)
15408 printf ("%sINVAL", first ? "" : "|");
15409 }
5b18a4bc 15410 else
19e6b90e 15411 fputs ("0", stdout);
5b18a4bc 15412}
103f02d3 15413
f6f0e17b
NC
15414/* Display's the value of TAG at location P. If TAG is
15415 greater than 0 it is assumed to be an unknown tag, and
15416 a message is printed to this effect. Otherwise it is
15417 assumed that a message has already been printed.
15418
15419 If the bottom bit of TAG is set it assumed to have a
15420 string value, otherwise it is assumed to have an integer
15421 value.
15422
15423 Returns an updated P pointing to the first unread byte
15424 beyond the end of TAG's value.
15425
15426 Reads at or beyond END will not be made. */
15427
15428static unsigned char *
60abdbed 15429display_tag_value (signed int tag,
f6f0e17b
NC
15430 unsigned char * p,
15431 const unsigned char * const end)
15432{
15433 unsigned long val;
15434
15435 if (tag > 0)
15436 printf (" Tag_unknown_%d: ", tag);
15437
15438 if (p >= end)
15439 {
4082ef84 15440 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
15441 }
15442 else if (tag & 1)
15443 {
071436c6
NC
15444 /* PR 17531 file: 027-19978-0.004. */
15445 size_t maxlen = (end - p) - 1;
15446
15447 putchar ('"');
4082ef84
NC
15448 if (maxlen > 0)
15449 {
15450 print_symbol ((int) maxlen, (const char *) p);
15451 p += strnlen ((char *) p, maxlen) + 1;
15452 }
15453 else
15454 {
15455 printf (_("<corrupt string tag>"));
15456 p = (unsigned char *) end;
15457 }
071436c6 15458 printf ("\"\n");
f6f0e17b
NC
15459 }
15460 else
15461 {
cd30bcef 15462 READ_ULEB (val, p, end);
f6f0e17b
NC
15463 printf ("%ld (0x%lx)\n", val, val);
15464 }
15465
4082ef84 15466 assert (p <= end);
f6f0e17b
NC
15467 return p;
15468}
15469
53a346d8
CZ
15470/* ARC ABI attributes section. */
15471
15472static unsigned char *
15473display_arc_attribute (unsigned char * p,
15474 const unsigned char * const end)
15475{
15476 unsigned int tag;
53a346d8
CZ
15477 unsigned int val;
15478
cd30bcef 15479 READ_ULEB (tag, p, end);
53a346d8
CZ
15480
15481 switch (tag)
15482 {
15483 case Tag_ARC_PCS_config:
cd30bcef 15484 READ_ULEB (val, p, end);
53a346d8
CZ
15485 printf (" Tag_ARC_PCS_config: ");
15486 switch (val)
15487 {
15488 case 0:
15489 printf (_("Absent/Non standard\n"));
15490 break;
15491 case 1:
15492 printf (_("Bare metal/mwdt\n"));
15493 break;
15494 case 2:
15495 printf (_("Bare metal/newlib\n"));
15496 break;
15497 case 3:
15498 printf (_("Linux/uclibc\n"));
15499 break;
15500 case 4:
15501 printf (_("Linux/glibc\n"));
15502 break;
15503 default:
15504 printf (_("Unknown\n"));
15505 break;
15506 }
15507 break;
15508
15509 case Tag_ARC_CPU_base:
cd30bcef 15510 READ_ULEB (val, p, end);
53a346d8
CZ
15511 printf (" Tag_ARC_CPU_base: ");
15512 switch (val)
15513 {
15514 default:
15515 case TAG_CPU_NONE:
15516 printf (_("Absent\n"));
15517 break;
15518 case TAG_CPU_ARC6xx:
15519 printf ("ARC6xx\n");
15520 break;
15521 case TAG_CPU_ARC7xx:
15522 printf ("ARC7xx\n");
15523 break;
15524 case TAG_CPU_ARCEM:
15525 printf ("ARCEM\n");
15526 break;
15527 case TAG_CPU_ARCHS:
15528 printf ("ARCHS\n");
15529 break;
15530 }
15531 break;
15532
15533 case Tag_ARC_CPU_variation:
cd30bcef 15534 READ_ULEB (val, p, end);
53a346d8
CZ
15535 printf (" Tag_ARC_CPU_variation: ");
15536 switch (val)
15537 {
15538 default:
15539 if (val > 0 && val < 16)
53a346d8 15540 printf ("Core%d\n", val);
d8cbc93b
JL
15541 else
15542 printf ("Unknown\n");
15543 break;
15544
53a346d8
CZ
15545 case 0:
15546 printf (_("Absent\n"));
15547 break;
15548 }
15549 break;
15550
15551 case Tag_ARC_CPU_name:
15552 printf (" Tag_ARC_CPU_name: ");
15553 p = display_tag_value (-1, p, end);
15554 break;
15555
15556 case Tag_ARC_ABI_rf16:
cd30bcef 15557 READ_ULEB (val, p, end);
53a346d8
CZ
15558 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
15559 break;
15560
15561 case Tag_ARC_ABI_osver:
cd30bcef 15562 READ_ULEB (val, p, end);
53a346d8
CZ
15563 printf (" Tag_ARC_ABI_osver: v%d\n", val);
15564 break;
15565
15566 case Tag_ARC_ABI_pic:
15567 case Tag_ARC_ABI_sda:
cd30bcef 15568 READ_ULEB (val, p, end);
53a346d8
CZ
15569 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
15570 : " Tag_ARC_ABI_pic: ");
15571 switch (val)
15572 {
15573 case 0:
15574 printf (_("Absent\n"));
15575 break;
15576 case 1:
15577 printf ("MWDT\n");
15578 break;
15579 case 2:
15580 printf ("GNU\n");
15581 break;
15582 default:
15583 printf (_("Unknown\n"));
15584 break;
15585 }
15586 break;
15587
15588 case Tag_ARC_ABI_tls:
cd30bcef 15589 READ_ULEB (val, p, end);
53a346d8
CZ
15590 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
15591 break;
15592
15593 case Tag_ARC_ABI_enumsize:
cd30bcef 15594 READ_ULEB (val, p, end);
53a346d8
CZ
15595 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
15596 _("smallest"));
15597 break;
15598
15599 case Tag_ARC_ABI_exceptions:
cd30bcef 15600 READ_ULEB (val, p, end);
53a346d8
CZ
15601 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
15602 : _("default"));
15603 break;
15604
15605 case Tag_ARC_ABI_double_size:
cd30bcef 15606 READ_ULEB (val, p, end);
53a346d8
CZ
15607 printf (" Tag_ARC_ABI_double_size: %d\n", val);
15608 break;
15609
15610 case Tag_ARC_ISA_config:
15611 printf (" Tag_ARC_ISA_config: ");
15612 p = display_tag_value (-1, p, end);
15613 break;
15614
15615 case Tag_ARC_ISA_apex:
15616 printf (" Tag_ARC_ISA_apex: ");
15617 p = display_tag_value (-1, p, end);
15618 break;
15619
15620 case Tag_ARC_ISA_mpy_option:
cd30bcef 15621 READ_ULEB (val, p, end);
53a346d8
CZ
15622 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
15623 break;
15624
db1e1b45 15625 case Tag_ARC_ATR_version:
cd30bcef 15626 READ_ULEB (val, p, end);
db1e1b45 15627 printf (" Tag_ARC_ATR_version: %d\n", val);
15628 break;
15629
53a346d8
CZ
15630 default:
15631 return display_tag_value (tag & 1, p, end);
15632 }
15633
15634 return p;
15635}
15636
11c1ff18
PB
15637/* ARM EABI attributes section. */
15638typedef struct
15639{
70e99720 15640 unsigned int tag;
2cf0635d 15641 const char * name;
11c1ff18 15642 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 15643 unsigned int type;
288f0ba2 15644 const char *const *table;
11c1ff18
PB
15645} arm_attr_public_tag;
15646
288f0ba2 15647static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 15648 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 15649 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 15650 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
288f0ba2
AM
15651static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
15652static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 15653 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 15654static const char *const arm_attr_tag_FP_arch[] =
bca38921 15655 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 15656 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
15657static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
15658static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
15659 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
15660 "NEON for ARMv8.1"};
288f0ba2 15661static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
15662 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
15663 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 15664static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 15665 {"V6", "SB", "TLS", "Unused"};
288f0ba2 15666static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 15667 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 15668static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 15669 {"Absolute", "PC-relative", "None"};
288f0ba2 15670static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 15671 {"None", "direct", "GOT-indirect"};
288f0ba2 15672static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 15673 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
15674static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
15675static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 15676 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
15677static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
15678static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
15679static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 15680 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 15681static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 15682 {"Unused", "small", "int", "forced to int"};
288f0ba2 15683static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 15684 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 15685static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 15686 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 15687static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 15688 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 15689static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
15690 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15691 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 15692static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
15693 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15694 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
15695static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
15696static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 15697 {"Not Allowed", "Allowed"};
288f0ba2 15698static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 15699 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 15700static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 15701 {"Follow architecture", "Allowed"};
288f0ba2 15702static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 15703 {"Not Allowed", "Allowed"};
288f0ba2 15704static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 15705 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 15706 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
15707static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
15708static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 15709 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 15710 "TrustZone and Virtualization Extensions"};
288f0ba2 15711static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 15712 {"Not Allowed", "Allowed"};
11c1ff18 15713
288f0ba2 15714static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
15715 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
15716
11c1ff18
PB
15717#define LOOKUP(id, name) \
15718 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 15719static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
15720{
15721 {4, "CPU_raw_name", 1, NULL},
15722 {5, "CPU_name", 1, NULL},
15723 LOOKUP(6, CPU_arch),
15724 {7, "CPU_arch_profile", 0, NULL},
15725 LOOKUP(8, ARM_ISA_use),
15726 LOOKUP(9, THUMB_ISA_use),
75375b3e 15727 LOOKUP(10, FP_arch),
11c1ff18 15728 LOOKUP(11, WMMX_arch),
f5f53991
AS
15729 LOOKUP(12, Advanced_SIMD_arch),
15730 LOOKUP(13, PCS_config),
11c1ff18
PB
15731 LOOKUP(14, ABI_PCS_R9_use),
15732 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 15733 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
15734 LOOKUP(17, ABI_PCS_GOT_use),
15735 LOOKUP(18, ABI_PCS_wchar_t),
15736 LOOKUP(19, ABI_FP_rounding),
15737 LOOKUP(20, ABI_FP_denormal),
15738 LOOKUP(21, ABI_FP_exceptions),
15739 LOOKUP(22, ABI_FP_user_exceptions),
15740 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
15741 {24, "ABI_align_needed", 0, NULL},
15742 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
15743 LOOKUP(26, ABI_enum_size),
15744 LOOKUP(27, ABI_HardFP_use),
15745 LOOKUP(28, ABI_VFP_args),
15746 LOOKUP(29, ABI_WMMX_args),
15747 LOOKUP(30, ABI_optimization_goals),
15748 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 15749 {32, "compatibility", 0, NULL},
f5f53991 15750 LOOKUP(34, CPU_unaligned_access),
75375b3e 15751 LOOKUP(36, FP_HP_extension),
8e79c3df 15752 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
15753 LOOKUP(42, MPextension_use),
15754 LOOKUP(44, DIV_use),
15afaa63 15755 LOOKUP(46, DSP_extension),
a7ad558c 15756 LOOKUP(48, MVE_arch),
f5f53991
AS
15757 {64, "nodefaults", 0, NULL},
15758 {65, "also_compatible_with", 0, NULL},
15759 LOOKUP(66, T2EE_use),
15760 {67, "conformance", 1, NULL},
15761 LOOKUP(68, Virtualization_use),
cd21e546 15762 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
15763};
15764#undef LOOKUP
15765
11c1ff18 15766static unsigned char *
f6f0e17b
NC
15767display_arm_attribute (unsigned char * p,
15768 const unsigned char * const end)
11c1ff18 15769{
70e99720 15770 unsigned int tag;
70e99720 15771 unsigned int val;
2cf0635d 15772 arm_attr_public_tag * attr;
11c1ff18 15773 unsigned i;
70e99720 15774 unsigned int type;
11c1ff18 15775
cd30bcef 15776 READ_ULEB (tag, p, end);
11c1ff18 15777 attr = NULL;
2cf0635d 15778 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
15779 {
15780 if (arm_attr_public_tags[i].tag == tag)
15781 {
15782 attr = &arm_attr_public_tags[i];
15783 break;
15784 }
15785 }
15786
15787 if (attr)
15788 {
15789 printf (" Tag_%s: ", attr->name);
15790 switch (attr->type)
15791 {
15792 case 0:
15793 switch (tag)
15794 {
15795 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 15796 READ_ULEB (val, p, end);
11c1ff18
PB
15797 switch (val)
15798 {
2b692964
NC
15799 case 0: printf (_("None\n")); break;
15800 case 'A': printf (_("Application\n")); break;
15801 case 'R': printf (_("Realtime\n")); break;
15802 case 'M': printf (_("Microcontroller\n")); break;
15803 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
15804 default: printf ("??? (%d)\n", val); break;
15805 }
15806 break;
15807
75375b3e 15808 case 24: /* Tag_align_needed. */
cd30bcef 15809 READ_ULEB (val, p, end);
75375b3e
MGD
15810 switch (val)
15811 {
2b692964
NC
15812 case 0: printf (_("None\n")); break;
15813 case 1: printf (_("8-byte\n")); break;
15814 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
15815 case 3: printf ("??? 3\n"); break;
15816 default:
15817 if (val <= 12)
dd24e3da 15818 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15819 1 << val);
15820 else
15821 printf ("??? (%d)\n", val);
15822 break;
15823 }
15824 break;
15825
15826 case 25: /* Tag_align_preserved. */
cd30bcef 15827 READ_ULEB (val, p, end);
75375b3e
MGD
15828 switch (val)
15829 {
2b692964
NC
15830 case 0: printf (_("None\n")); break;
15831 case 1: printf (_("8-byte, except leaf SP\n")); break;
15832 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
15833 case 3: printf ("??? 3\n"); break;
15834 default:
15835 if (val <= 12)
dd24e3da 15836 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15837 1 << val);
15838 else
15839 printf ("??? (%d)\n", val);
15840 break;
15841 }
15842 break;
15843
11c1ff18 15844 case 32: /* Tag_compatibility. */
071436c6 15845 {
cd30bcef 15846 READ_ULEB (val, p, end);
071436c6 15847 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
15848 if (p < end - 1)
15849 {
15850 size_t maxlen = (end - p) - 1;
15851
15852 print_symbol ((int) maxlen, (const char *) p);
15853 p += strnlen ((char *) p, maxlen) + 1;
15854 }
15855 else
15856 {
15857 printf (_("<corrupt>"));
15858 p = (unsigned char *) end;
15859 }
071436c6 15860 putchar ('\n');
071436c6 15861 }
11c1ff18
PB
15862 break;
15863
f5f53991 15864 case 64: /* Tag_nodefaults. */
541a3cbd
NC
15865 /* PR 17531: file: 001-505008-0.01. */
15866 if (p < end)
15867 p++;
2b692964 15868 printf (_("True\n"));
f5f53991
AS
15869 break;
15870
15871 case 65: /* Tag_also_compatible_with. */
cd30bcef 15872 READ_ULEB (val, p, end);
f5f53991
AS
15873 if (val == 6 /* Tag_CPU_arch. */)
15874 {
cd30bcef 15875 READ_ULEB (val, p, end);
071436c6 15876 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
15877 printf ("??? (%d)\n", val);
15878 else
15879 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
15880 }
15881 else
15882 printf ("???\n");
071436c6
NC
15883 while (p < end && *(p++) != '\0' /* NUL terminator. */)
15884 ;
f5f53991
AS
15885 break;
15886
11c1ff18 15887 default:
bee0ee85
NC
15888 printf (_("<unknown: %d>\n"), tag);
15889 break;
11c1ff18
PB
15890 }
15891 return p;
15892
15893 case 1:
f6f0e17b 15894 return display_tag_value (-1, p, end);
11c1ff18 15895 case 2:
f6f0e17b 15896 return display_tag_value (0, p, end);
11c1ff18
PB
15897
15898 default:
15899 assert (attr->type & 0x80);
cd30bcef 15900 READ_ULEB (val, p, end);
11c1ff18
PB
15901 type = attr->type & 0x7f;
15902 if (val >= type)
15903 printf ("??? (%d)\n", val);
15904 else
15905 printf ("%s\n", attr->table[val]);
15906 return p;
15907 }
15908 }
11c1ff18 15909
f6f0e17b 15910 return display_tag_value (tag, p, end);
11c1ff18
PB
15911}
15912
104d59d1 15913static unsigned char *
60bca95a 15914display_gnu_attribute (unsigned char * p,
60abdbed 15915 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 15916 const unsigned char * const end)
104d59d1 15917{
cd30bcef 15918 unsigned int tag;
60abdbed 15919 unsigned int val;
104d59d1 15920
cd30bcef 15921 READ_ULEB (tag, p, end);
104d59d1
JM
15922
15923 /* Tag_compatibility is the only generic GNU attribute defined at
15924 present. */
15925 if (tag == 32)
15926 {
cd30bcef 15927 READ_ULEB (val, p, end);
071436c6
NC
15928
15929 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
15930 if (p == end)
15931 {
071436c6 15932 printf (_("<corrupt>\n"));
f6f0e17b
NC
15933 warn (_("corrupt vendor attribute\n"));
15934 }
15935 else
15936 {
4082ef84
NC
15937 if (p < end - 1)
15938 {
15939 size_t maxlen = (end - p) - 1;
071436c6 15940
4082ef84
NC
15941 print_symbol ((int) maxlen, (const char *) p);
15942 p += strnlen ((char *) p, maxlen) + 1;
15943 }
15944 else
15945 {
15946 printf (_("<corrupt>"));
15947 p = (unsigned char *) end;
15948 }
071436c6 15949 putchar ('\n');
f6f0e17b 15950 }
104d59d1
JM
15951 return p;
15952 }
15953
15954 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 15955 return display_proc_gnu_attribute (p, tag, end);
104d59d1 15956
f6f0e17b 15957 return display_tag_value (tag, p, end);
104d59d1
JM
15958}
15959
85f7484a
PB
15960static unsigned char *
15961display_m68k_gnu_attribute (unsigned char * p,
15962 unsigned int tag,
15963 const unsigned char * const end)
15964{
15965 unsigned int val;
15966
15967 if (tag == Tag_GNU_M68K_ABI_FP)
15968 {
15969 printf (" Tag_GNU_M68K_ABI_FP: ");
15970 if (p == end)
15971 {
15972 printf (_("<corrupt>\n"));
15973 return p;
15974 }
15975 READ_ULEB (val, p, end);
15976
15977 if (val > 3)
15978 printf ("(%#x), ", val);
15979
15980 switch (val & 3)
15981 {
15982 case 0:
15983 printf (_("unspecified hard/soft float\n"));
15984 break;
15985 case 1:
15986 printf (_("hard float\n"));
15987 break;
15988 case 2:
15989 printf (_("soft float\n"));
15990 break;
15991 }
15992 return p;
15993 }
15994
15995 return display_tag_value (tag & 1, p, end);
15996}
15997
34c8bcba 15998static unsigned char *
f6f0e17b 15999display_power_gnu_attribute (unsigned char * p,
60abdbed 16000 unsigned int tag,
f6f0e17b 16001 const unsigned char * const end)
34c8bcba 16002{
005d79fd 16003 unsigned int val;
34c8bcba
JM
16004
16005 if (tag == Tag_GNU_Power_ABI_FP)
16006 {
34c8bcba 16007 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16008 if (p == end)
005d79fd
AM
16009 {
16010 printf (_("<corrupt>\n"));
16011 return p;
16012 }
cd30bcef 16013 READ_ULEB (val, p, end);
60bca95a 16014
005d79fd
AM
16015 if (val > 15)
16016 printf ("(%#x), ", val);
16017
16018 switch (val & 3)
34c8bcba
JM
16019 {
16020 case 0:
005d79fd 16021 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16022 break;
16023 case 1:
005d79fd 16024 printf (_("hard float, "));
34c8bcba
JM
16025 break;
16026 case 2:
005d79fd 16027 printf (_("soft float, "));
34c8bcba 16028 break;
3c7b9897 16029 case 3:
005d79fd 16030 printf (_("single-precision hard float, "));
3c7b9897 16031 break;
005d79fd
AM
16032 }
16033
16034 switch (val & 0xC)
16035 {
16036 case 0:
16037 printf (_("unspecified long double\n"));
16038 break;
16039 case 4:
16040 printf (_("128-bit IBM long double\n"));
16041 break;
16042 case 8:
16043 printf (_("64-bit long double\n"));
16044 break;
16045 case 12:
16046 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16047 break;
16048 }
16049 return p;
005d79fd 16050 }
34c8bcba 16051
c6e65352
DJ
16052 if (tag == Tag_GNU_Power_ABI_Vector)
16053 {
c6e65352 16054 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 16055 if (p == end)
005d79fd
AM
16056 {
16057 printf (_("<corrupt>\n"));
16058 return p;
16059 }
cd30bcef 16060 READ_ULEB (val, p, end);
005d79fd
AM
16061
16062 if (val > 3)
16063 printf ("(%#x), ", val);
16064
16065 switch (val & 3)
c6e65352
DJ
16066 {
16067 case 0:
005d79fd 16068 printf (_("unspecified\n"));
c6e65352
DJ
16069 break;
16070 case 1:
005d79fd 16071 printf (_("generic\n"));
c6e65352
DJ
16072 break;
16073 case 2:
16074 printf ("AltiVec\n");
16075 break;
16076 case 3:
16077 printf ("SPE\n");
16078 break;
c6e65352
DJ
16079 }
16080 return p;
005d79fd 16081 }
c6e65352 16082
f82e0623
NF
16083 if (tag == Tag_GNU_Power_ABI_Struct_Return)
16084 {
005d79fd 16085 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 16086 if (p == end)
f6f0e17b 16087 {
005d79fd 16088 printf (_("<corrupt>\n"));
f6f0e17b
NC
16089 return p;
16090 }
cd30bcef 16091 READ_ULEB (val, p, end);
0b4362b0 16092
005d79fd
AM
16093 if (val > 2)
16094 printf ("(%#x), ", val);
16095
16096 switch (val & 3)
16097 {
16098 case 0:
16099 printf (_("unspecified\n"));
16100 break;
16101 case 1:
16102 printf ("r3/r4\n");
16103 break;
16104 case 2:
16105 printf (_("memory\n"));
16106 break;
16107 case 3:
16108 printf ("???\n");
16109 break;
16110 }
f82e0623
NF
16111 return p;
16112 }
16113
f6f0e17b 16114 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
16115}
16116
643f7afb
AK
16117static unsigned char *
16118display_s390_gnu_attribute (unsigned char * p,
60abdbed 16119 unsigned int tag,
643f7afb
AK
16120 const unsigned char * const end)
16121{
cd30bcef 16122 unsigned int val;
643f7afb
AK
16123
16124 if (tag == Tag_GNU_S390_ABI_Vector)
16125 {
643f7afb 16126 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 16127 READ_ULEB (val, p, end);
643f7afb
AK
16128
16129 switch (val)
16130 {
16131 case 0:
16132 printf (_("any\n"));
16133 break;
16134 case 1:
16135 printf (_("software\n"));
16136 break;
16137 case 2:
16138 printf (_("hardware\n"));
16139 break;
16140 default:
16141 printf ("??? (%d)\n", val);
16142 break;
16143 }
16144 return p;
16145 }
16146
16147 return display_tag_value (tag & 1, p, end);
16148}
16149
9e8c70f9 16150static void
60abdbed 16151display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
16152{
16153 if (mask)
16154 {
32ec8896 16155 bfd_boolean first = TRUE;
071436c6 16156
9e8c70f9 16157 if (mask & ELF_SPARC_HWCAP_MUL32)
32ec8896 16158 fputs ("mul32", stdout), first = FALSE;
9e8c70f9 16159 if (mask & ELF_SPARC_HWCAP_DIV32)
32ec8896 16160 printf ("%sdiv32", first ? "" : "|"), first = FALSE;
9e8c70f9 16161 if (mask & ELF_SPARC_HWCAP_FSMULD)
32ec8896 16162 printf ("%sfsmuld", first ? "" : "|"), first = FALSE;
9e8c70f9 16163 if (mask & ELF_SPARC_HWCAP_V8PLUS)
32ec8896 16164 printf ("%sv8plus", first ? "" : "|"), first = FALSE;
9e8c70f9 16165 if (mask & ELF_SPARC_HWCAP_POPC)
32ec8896 16166 printf ("%spopc", first ? "" : "|"), first = FALSE;
9e8c70f9 16167 if (mask & ELF_SPARC_HWCAP_VIS)
32ec8896 16168 printf ("%svis", first ? "" : "|"), first = FALSE;
9e8c70f9 16169 if (mask & ELF_SPARC_HWCAP_VIS2)
32ec8896 16170 printf ("%svis2", first ? "" : "|"), first = FALSE;
9e8c70f9 16171 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
32ec8896 16172 printf ("%sASIBlkInit", first ? "" : "|"), first = FALSE;
9e8c70f9 16173 if (mask & ELF_SPARC_HWCAP_FMAF)
32ec8896 16174 printf ("%sfmaf", first ? "" : "|"), first = FALSE;
9e8c70f9 16175 if (mask & ELF_SPARC_HWCAP_VIS3)
32ec8896 16176 printf ("%svis3", first ? "" : "|"), first = FALSE;
9e8c70f9 16177 if (mask & ELF_SPARC_HWCAP_HPC)
32ec8896 16178 printf ("%shpc", first ? "" : "|"), first = FALSE;
9e8c70f9 16179 if (mask & ELF_SPARC_HWCAP_RANDOM)
32ec8896 16180 printf ("%srandom", first ? "" : "|"), first = FALSE;
9e8c70f9 16181 if (mask & ELF_SPARC_HWCAP_TRANS)
32ec8896 16182 printf ("%strans", first ? "" : "|"), first = FALSE;
9e8c70f9 16183 if (mask & ELF_SPARC_HWCAP_FJFMAU)
32ec8896 16184 printf ("%sfjfmau", first ? "" : "|"), first = FALSE;
9e8c70f9 16185 if (mask & ELF_SPARC_HWCAP_IMA)
32ec8896 16186 printf ("%sima", first ? "" : "|"), first = FALSE;
9e8c70f9 16187 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
32ec8896 16188 printf ("%scspare", first ? "" : "|"), first = FALSE;
9e8c70f9
DM
16189 }
16190 else
071436c6
NC
16191 fputc ('0', stdout);
16192 fputc ('\n', stdout);
9e8c70f9
DM
16193}
16194
3d68f91c 16195static void
60abdbed 16196display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
16197{
16198 if (mask)
16199 {
32ec8896 16200 bfd_boolean first = TRUE;
071436c6 16201
3d68f91c 16202 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
32ec8896 16203 fputs ("fjathplus", stdout), first = FALSE;
3d68f91c 16204 if (mask & ELF_SPARC_HWCAP2_VIS3B)
32ec8896 16205 printf ("%svis3b", first ? "" : "|"), first = FALSE;
3d68f91c 16206 if (mask & ELF_SPARC_HWCAP2_ADP)
32ec8896 16207 printf ("%sadp", first ? "" : "|"), first = FALSE;
3d68f91c 16208 if (mask & ELF_SPARC_HWCAP2_SPARC5)
32ec8896 16209 printf ("%ssparc5", first ? "" : "|"), first = FALSE;
3d68f91c 16210 if (mask & ELF_SPARC_HWCAP2_MWAIT)
32ec8896 16211 printf ("%smwait", first ? "" : "|"), first = FALSE;
3d68f91c 16212 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
32ec8896 16213 printf ("%sxmpmul", first ? "" : "|"), first = FALSE;
3d68f91c 16214 if (mask & ELF_SPARC_HWCAP2_XMONT)
32ec8896 16215 printf ("%sxmont2", first ? "" : "|"), first = FALSE;
3d68f91c 16216 if (mask & ELF_SPARC_HWCAP2_NSEC)
32ec8896 16217 printf ("%snsec", first ? "" : "|"), first = FALSE;
3d68f91c 16218 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
32ec8896 16219 printf ("%sfjathhpc", first ? "" : "|"), first = FALSE;
3d68f91c 16220 if (mask & ELF_SPARC_HWCAP2_FJDES)
32ec8896 16221 printf ("%sfjdes", first ? "" : "|"), first = FALSE;
3d68f91c 16222 if (mask & ELF_SPARC_HWCAP2_FJAES)
32ec8896 16223 printf ("%sfjaes", first ? "" : "|"), first = FALSE;
3d68f91c
JM
16224 }
16225 else
071436c6
NC
16226 fputc ('0', stdout);
16227 fputc ('\n', stdout);
3d68f91c
JM
16228}
16229
9e8c70f9 16230static unsigned char *
f6f0e17b 16231display_sparc_gnu_attribute (unsigned char * p,
60abdbed 16232 unsigned int tag,
f6f0e17b 16233 const unsigned char * const end)
9e8c70f9 16234{
cd30bcef 16235 unsigned int val;
3d68f91c 16236
9e8c70f9
DM
16237 if (tag == Tag_GNU_Sparc_HWCAPS)
16238 {
cd30bcef 16239 READ_ULEB (val, p, end);
9e8c70f9 16240 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
16241 display_sparc_hwcaps (val);
16242 return p;
3d68f91c
JM
16243 }
16244 if (tag == Tag_GNU_Sparc_HWCAPS2)
16245 {
cd30bcef 16246 READ_ULEB (val, p, end);
3d68f91c
JM
16247 printf (" Tag_GNU_Sparc_HWCAPS2: ");
16248 display_sparc_hwcaps2 (val);
16249 return p;
16250 }
9e8c70f9 16251
f6f0e17b 16252 return display_tag_value (tag, p, end);
9e8c70f9
DM
16253}
16254
351cdf24 16255static void
32ec8896 16256print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
16257{
16258 switch (val)
16259 {
16260 case Val_GNU_MIPS_ABI_FP_ANY:
16261 printf (_("Hard or soft float\n"));
16262 break;
16263 case Val_GNU_MIPS_ABI_FP_DOUBLE:
16264 printf (_("Hard float (double precision)\n"));
16265 break;
16266 case Val_GNU_MIPS_ABI_FP_SINGLE:
16267 printf (_("Hard float (single precision)\n"));
16268 break;
16269 case Val_GNU_MIPS_ABI_FP_SOFT:
16270 printf (_("Soft float\n"));
16271 break;
16272 case Val_GNU_MIPS_ABI_FP_OLD_64:
16273 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
16274 break;
16275 case Val_GNU_MIPS_ABI_FP_XX:
16276 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
16277 break;
16278 case Val_GNU_MIPS_ABI_FP_64:
16279 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
16280 break;
16281 case Val_GNU_MIPS_ABI_FP_64A:
16282 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
16283 break;
3350cc01
CM
16284 case Val_GNU_MIPS_ABI_FP_NAN2008:
16285 printf (_("NaN 2008 compatibility\n"));
16286 break;
351cdf24
MF
16287 default:
16288 printf ("??? (%d)\n", val);
16289 break;
16290 }
16291}
16292
2cf19d5c 16293static unsigned char *
f6f0e17b 16294display_mips_gnu_attribute (unsigned char * p,
60abdbed 16295 unsigned int tag,
f6f0e17b 16296 const unsigned char * const end)
2cf19d5c 16297{
2cf19d5c
JM
16298 if (tag == Tag_GNU_MIPS_ABI_FP)
16299 {
32ec8896 16300 unsigned int val;
f6f0e17b 16301
2cf19d5c 16302 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 16303 READ_ULEB (val, p, end);
351cdf24 16304 print_mips_fp_abi_value (val);
2cf19d5c
JM
16305 return p;
16306 }
16307
a9f58168
CF
16308 if (tag == Tag_GNU_MIPS_ABI_MSA)
16309 {
32ec8896 16310 unsigned int val;
a9f58168 16311
a9f58168 16312 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 16313 READ_ULEB (val, p, end);
a9f58168
CF
16314
16315 switch (val)
16316 {
16317 case Val_GNU_MIPS_ABI_MSA_ANY:
16318 printf (_("Any MSA or not\n"));
16319 break;
16320 case Val_GNU_MIPS_ABI_MSA_128:
16321 printf (_("128-bit MSA\n"));
16322 break;
16323 default:
16324 printf ("??? (%d)\n", val);
16325 break;
16326 }
16327 return p;
16328 }
16329
f6f0e17b 16330 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
16331}
16332
59e6276b 16333static unsigned char *
f6f0e17b
NC
16334display_tic6x_attribute (unsigned char * p,
16335 const unsigned char * const end)
59e6276b 16336{
60abdbed 16337 unsigned int tag;
cd30bcef 16338 unsigned int val;
59e6276b 16339
cd30bcef 16340 READ_ULEB (tag, p, end);
59e6276b
JM
16341
16342 switch (tag)
16343 {
75fa6dc1 16344 case Tag_ISA:
75fa6dc1 16345 printf (" Tag_ISA: ");
cd30bcef 16346 READ_ULEB (val, p, end);
59e6276b
JM
16347
16348 switch (val)
16349 {
75fa6dc1 16350 case C6XABI_Tag_ISA_none:
59e6276b
JM
16351 printf (_("None\n"));
16352 break;
75fa6dc1 16353 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
16354 printf ("C62x\n");
16355 break;
75fa6dc1 16356 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
16357 printf ("C67x\n");
16358 break;
75fa6dc1 16359 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
16360 printf ("C67x+\n");
16361 break;
75fa6dc1 16362 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
16363 printf ("C64x\n");
16364 break;
75fa6dc1 16365 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
16366 printf ("C64x+\n");
16367 break;
75fa6dc1 16368 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
16369 printf ("C674x\n");
16370 break;
16371 default:
16372 printf ("??? (%d)\n", val);
16373 break;
16374 }
16375 return p;
16376
87779176 16377 case Tag_ABI_wchar_t:
87779176 16378 printf (" Tag_ABI_wchar_t: ");
cd30bcef 16379 READ_ULEB (val, p, end);
87779176
JM
16380 switch (val)
16381 {
16382 case 0:
16383 printf (_("Not used\n"));
16384 break;
16385 case 1:
16386 printf (_("2 bytes\n"));
16387 break;
16388 case 2:
16389 printf (_("4 bytes\n"));
16390 break;
16391 default:
16392 printf ("??? (%d)\n", val);
16393 break;
16394 }
16395 return p;
16396
16397 case Tag_ABI_stack_align_needed:
87779176 16398 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 16399 READ_ULEB (val, p, end);
87779176
JM
16400 switch (val)
16401 {
16402 case 0:
16403 printf (_("8-byte\n"));
16404 break;
16405 case 1:
16406 printf (_("16-byte\n"));
16407 break;
16408 default:
16409 printf ("??? (%d)\n", val);
16410 break;
16411 }
16412 return p;
16413
16414 case Tag_ABI_stack_align_preserved:
cd30bcef 16415 READ_ULEB (val, p, end);
87779176
JM
16416 printf (" Tag_ABI_stack_align_preserved: ");
16417 switch (val)
16418 {
16419 case 0:
16420 printf (_("8-byte\n"));
16421 break;
16422 case 1:
16423 printf (_("16-byte\n"));
16424 break;
16425 default:
16426 printf ("??? (%d)\n", val);
16427 break;
16428 }
16429 return p;
16430
b5593623 16431 case Tag_ABI_DSBT:
cd30bcef 16432 READ_ULEB (val, p, end);
b5593623
JM
16433 printf (" Tag_ABI_DSBT: ");
16434 switch (val)
16435 {
16436 case 0:
16437 printf (_("DSBT addressing not used\n"));
16438 break;
16439 case 1:
16440 printf (_("DSBT addressing used\n"));
16441 break;
16442 default:
16443 printf ("??? (%d)\n", val);
16444 break;
16445 }
16446 return p;
16447
87779176 16448 case Tag_ABI_PID:
cd30bcef 16449 READ_ULEB (val, p, end);
87779176
JM
16450 printf (" Tag_ABI_PID: ");
16451 switch (val)
16452 {
16453 case 0:
16454 printf (_("Data addressing position-dependent\n"));
16455 break;
16456 case 1:
16457 printf (_("Data addressing position-independent, GOT near DP\n"));
16458 break;
16459 case 2:
16460 printf (_("Data addressing position-independent, GOT far from DP\n"));
16461 break;
16462 default:
16463 printf ("??? (%d)\n", val);
16464 break;
16465 }
16466 return p;
16467
16468 case Tag_ABI_PIC:
cd30bcef 16469 READ_ULEB (val, p, end);
87779176
JM
16470 printf (" Tag_ABI_PIC: ");
16471 switch (val)
16472 {
16473 case 0:
16474 printf (_("Code addressing position-dependent\n"));
16475 break;
16476 case 1:
16477 printf (_("Code addressing position-independent\n"));
16478 break;
16479 default:
16480 printf ("??? (%d)\n", val);
16481 break;
16482 }
16483 return p;
16484
16485 case Tag_ABI_array_object_alignment:
cd30bcef 16486 READ_ULEB (val, p, end);
87779176
JM
16487 printf (" Tag_ABI_array_object_alignment: ");
16488 switch (val)
16489 {
16490 case 0:
16491 printf (_("8-byte\n"));
16492 break;
16493 case 1:
16494 printf (_("4-byte\n"));
16495 break;
16496 case 2:
16497 printf (_("16-byte\n"));
16498 break;
16499 default:
16500 printf ("??? (%d)\n", val);
16501 break;
16502 }
16503 return p;
16504
16505 case Tag_ABI_array_object_align_expected:
cd30bcef 16506 READ_ULEB (val, p, end);
87779176
JM
16507 printf (" Tag_ABI_array_object_align_expected: ");
16508 switch (val)
16509 {
16510 case 0:
16511 printf (_("8-byte\n"));
16512 break;
16513 case 1:
16514 printf (_("4-byte\n"));
16515 break;
16516 case 2:
16517 printf (_("16-byte\n"));
16518 break;
16519 default:
16520 printf ("??? (%d)\n", val);
16521 break;
16522 }
16523 return p;
16524
3cbd1c06 16525 case Tag_ABI_compatibility:
071436c6 16526 {
cd30bcef 16527 READ_ULEB (val, p, end);
071436c6 16528 printf (" Tag_ABI_compatibility: ");
071436c6 16529 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16530 if (p < end - 1)
16531 {
16532 size_t maxlen = (end - p) - 1;
16533
16534 print_symbol ((int) maxlen, (const char *) p);
16535 p += strnlen ((char *) p, maxlen) + 1;
16536 }
16537 else
16538 {
16539 printf (_("<corrupt>"));
16540 p = (unsigned char *) end;
16541 }
071436c6 16542 putchar ('\n');
071436c6
NC
16543 return p;
16544 }
87779176
JM
16545
16546 case Tag_ABI_conformance:
071436c6 16547 {
4082ef84
NC
16548 printf (" Tag_ABI_conformance: \"");
16549 if (p < end - 1)
16550 {
16551 size_t maxlen = (end - p) - 1;
071436c6 16552
4082ef84
NC
16553 print_symbol ((int) maxlen, (const char *) p);
16554 p += strnlen ((char *) p, maxlen) + 1;
16555 }
16556 else
16557 {
16558 printf (_("<corrupt>"));
16559 p = (unsigned char *) end;
16560 }
071436c6 16561 printf ("\"\n");
071436c6
NC
16562 return p;
16563 }
59e6276b
JM
16564 }
16565
f6f0e17b
NC
16566 return display_tag_value (tag, p, end);
16567}
59e6276b 16568
f6f0e17b 16569static void
60abdbed 16570display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
16571{
16572 unsigned long addr = 0;
16573 size_t bytes = end - p;
16574
feceaa59 16575 assert (end >= p);
f6f0e17b 16576 while (bytes)
87779176 16577 {
f6f0e17b
NC
16578 int j;
16579 int k;
16580 int lbytes = (bytes > 16 ? 16 : bytes);
16581
16582 printf (" 0x%8.8lx ", addr);
16583
16584 for (j = 0; j < 16; j++)
16585 {
16586 if (j < lbytes)
16587 printf ("%2.2x", p[j]);
16588 else
16589 printf (" ");
16590
16591 if ((j & 3) == 3)
16592 printf (" ");
16593 }
16594
16595 for (j = 0; j < lbytes; j++)
16596 {
16597 k = p[j];
16598 if (k >= ' ' && k < 0x7f)
16599 printf ("%c", k);
16600 else
16601 printf (".");
16602 }
16603
16604 putchar ('\n');
16605
16606 p += lbytes;
16607 bytes -= lbytes;
16608 addr += lbytes;
87779176 16609 }
59e6276b 16610
f6f0e17b 16611 putchar ('\n');
59e6276b
JM
16612}
16613
13761a11 16614static unsigned char *
b0191216 16615display_msp430_attribute (unsigned char * p,
13761a11
NC
16616 const unsigned char * const end)
16617{
60abdbed
NC
16618 unsigned int val;
16619 unsigned int tag;
13761a11 16620
cd30bcef 16621 READ_ULEB (tag, p, end);
0b4362b0 16622
13761a11
NC
16623 switch (tag)
16624 {
16625 case OFBA_MSPABI_Tag_ISA:
13761a11 16626 printf (" Tag_ISA: ");
cd30bcef 16627 READ_ULEB (val, p, end);
13761a11
NC
16628 switch (val)
16629 {
16630 case 0: printf (_("None\n")); break;
16631 case 1: printf (_("MSP430\n")); break;
16632 case 2: printf (_("MSP430X\n")); break;
16633 default: printf ("??? (%d)\n", val); break;
16634 }
16635 break;
16636
16637 case OFBA_MSPABI_Tag_Code_Model:
13761a11 16638 printf (" Tag_Code_Model: ");
cd30bcef 16639 READ_ULEB (val, p, end);
13761a11
NC
16640 switch (val)
16641 {
16642 case 0: printf (_("None\n")); break;
16643 case 1: printf (_("Small\n")); break;
16644 case 2: printf (_("Large\n")); break;
16645 default: printf ("??? (%d)\n", val); break;
16646 }
16647 break;
16648
16649 case OFBA_MSPABI_Tag_Data_Model:
13761a11 16650 printf (" Tag_Data_Model: ");
cd30bcef 16651 READ_ULEB (val, p, end);
13761a11
NC
16652 switch (val)
16653 {
16654 case 0: printf (_("None\n")); break;
16655 case 1: printf (_("Small\n")); break;
16656 case 2: printf (_("Large\n")); break;
16657 case 3: printf (_("Restricted Large\n")); break;
16658 default: printf ("??? (%d)\n", val); break;
16659 }
16660 break;
16661
16662 default:
16663 printf (_(" <unknown tag %d>: "), tag);
16664
16665 if (tag & 1)
16666 {
071436c6 16667 putchar ('"');
4082ef84
NC
16668 if (p < end - 1)
16669 {
16670 size_t maxlen = (end - p) - 1;
16671
16672 print_symbol ((int) maxlen, (const char *) p);
16673 p += strnlen ((char *) p, maxlen) + 1;
16674 }
16675 else
16676 {
16677 printf (_("<corrupt>"));
16678 p = (unsigned char *) end;
16679 }
071436c6 16680 printf ("\"\n");
13761a11
NC
16681 }
16682 else
16683 {
cd30bcef 16684 READ_ULEB (val, p, end);
13761a11
NC
16685 printf ("%d (0x%x)\n", val, val);
16686 }
16687 break;
16688 }
16689
4082ef84 16690 assert (p <= end);
13761a11
NC
16691 return p;
16692}
16693
c0ea7c52
JL
16694static unsigned char *
16695display_msp430_gnu_attribute (unsigned char * p,
16696 unsigned int tag,
16697 const unsigned char * const end)
16698{
16699 if (tag == Tag_GNU_MSP430_Data_Region)
16700 {
cd30bcef 16701 unsigned int val;
c0ea7c52 16702
c0ea7c52 16703 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 16704 READ_ULEB (val, p, end);
c0ea7c52
JL
16705
16706 switch (val)
16707 {
16708 case Val_GNU_MSP430_Data_Region_Any:
16709 printf (_("Any Region\n"));
16710 break;
16711 case Val_GNU_MSP430_Data_Region_Lower:
16712 printf (_("Lower Region Only\n"));
16713 break;
16714 default:
cd30bcef 16715 printf ("??? (%u)\n", val);
c0ea7c52
JL
16716 }
16717 return p;
16718 }
16719 return display_tag_value (tag & 1, p, end);
16720}
16721
2dc8dd17
JW
16722struct riscv_attr_tag_t {
16723 const char *name;
cd30bcef 16724 unsigned int tag;
2dc8dd17
JW
16725};
16726
16727static struct riscv_attr_tag_t riscv_attr_tag[] =
16728{
16729#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
16730 T(arch),
16731 T(priv_spec),
16732 T(priv_spec_minor),
16733 T(priv_spec_revision),
16734 T(unaligned_access),
16735 T(stack_align),
16736#undef T
16737};
16738
16739static unsigned char *
16740display_riscv_attribute (unsigned char *p,
16741 const unsigned char * const end)
16742{
cd30bcef
AM
16743 unsigned int val;
16744 unsigned int tag;
2dc8dd17
JW
16745 struct riscv_attr_tag_t *attr = NULL;
16746 unsigned i;
16747
cd30bcef 16748 READ_ULEB (tag, p, end);
2dc8dd17
JW
16749
16750 /* Find the name of attribute. */
16751 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
16752 {
16753 if (riscv_attr_tag[i].tag == tag)
16754 {
16755 attr = &riscv_attr_tag[i];
16756 break;
16757 }
16758 }
16759
16760 if (attr)
16761 printf (" %s: ", attr->name);
16762 else
16763 return display_tag_value (tag, p, end);
16764
16765 switch (tag)
16766 {
16767 case Tag_RISCV_priv_spec:
16768 case Tag_RISCV_priv_spec_minor:
16769 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
16770 READ_ULEB (val, p, end);
16771 printf (_("%u\n"), val);
2dc8dd17
JW
16772 break;
16773 case Tag_RISCV_unaligned_access:
cd30bcef 16774 READ_ULEB (val, p, end);
2dc8dd17
JW
16775 switch (val)
16776 {
16777 case 0:
16778 printf (_("No unaligned access\n"));
16779 break;
16780 case 1:
16781 printf (_("Unaligned access\n"));
16782 break;
16783 }
16784 break;
16785 case Tag_RISCV_stack_align:
cd30bcef
AM
16786 READ_ULEB (val, p, end);
16787 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
16788 break;
16789 case Tag_RISCV_arch:
16790 p = display_tag_value (-1, p, end);
16791 break;
16792 default:
16793 return display_tag_value (tag, p, end);
16794 }
16795
16796 return p;
16797}
16798
0861f561
CQ
16799static unsigned char *
16800display_csky_attribute (unsigned char * p,
16801 const unsigned char * const end)
16802{
16803 unsigned int tag;
16804 unsigned int val;
16805 READ_ULEB (tag, p, end);
16806
16807 if (tag >= Tag_CSKY_MAX)
16808 {
16809 return display_tag_value (-1, p, end);
16810 }
16811
16812 switch (tag)
16813 {
16814 case Tag_CSKY_ARCH_NAME:
16815 printf (" Tag_CSKY_ARCH_NAME:\t\t");
16816 return display_tag_value (-1, p, end);
16817 case Tag_CSKY_CPU_NAME:
16818 printf (" Tag_CSKY_CPU_NAME:\t\t");
16819 return display_tag_value (-1, p, end);
16820
16821 case Tag_CSKY_ISA_FLAGS:
16822 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
16823 return display_tag_value (0, p, end);
16824 case Tag_CSKY_ISA_EXT_FLAGS:
16825 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
16826 return display_tag_value (0, p, end);
16827
16828 case Tag_CSKY_DSP_VERSION:
16829 printf (" Tag_CSKY_DSP_VERSION:\t\t");
16830 READ_ULEB (val, p, end);
16831 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
16832 printf ("DSP Extension\n");
16833 else if (val == VAL_CSKY_DSP_VERSION_2)
16834 printf ("DSP 2.0\n");
16835 break;
16836
16837 case Tag_CSKY_VDSP_VERSION:
16838 printf (" Tag_CSKY_VDSP_VERSION:\t");
16839 READ_ULEB (val, p, end);
16840 printf ("VDSP Version %d\n", val);
16841 break;
16842
16843 case Tag_CSKY_FPU_VERSION:
16844 printf (" Tag_CSKY_FPU_VERSION:\t\t");
16845 READ_ULEB (val, p, end);
16846 if (val == VAL_CSKY_FPU_VERSION_1)
16847 printf ("ABIV1 FPU Version 1\n");
16848 else if (val == VAL_CSKY_FPU_VERSION_2)
16849 printf ("FPU Version 2\n");
16850 break;
16851
16852 case Tag_CSKY_FPU_ABI:
16853 printf (" Tag_CSKY_FPU_ABI:\t\t");
16854 READ_ULEB (val, p, end);
16855 if (val == VAL_CSKY_FPU_ABI_HARD)
16856 printf ("Hard\n");
16857 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
16858 printf ("SoftFP\n");
16859 else if (val == VAL_CSKY_FPU_ABI_SOFT)
16860 printf ("Soft\n");
16861 break;
16862 case Tag_CSKY_FPU_ROUNDING:
16863 READ_ULEB (val, p, end);
16864 if (val == 1) {
16865 printf (" Tag_CSKY_FPU_ROUNDING:\t");
16866 printf ("Needed\n");
16867 }
16868 break;
16869 case Tag_CSKY_FPU_DENORMAL:
16870 READ_ULEB (val, p, end);
16871 if (val == 1) {
16872 printf (" Tag_CSKY_FPU_DENORMAL:\t");
16873 printf ("Needed\n");
16874 }
16875 break;
16876 case Tag_CSKY_FPU_Exception:
16877 READ_ULEB (val, p, end);
16878 if (val == 1) {
16879 printf (" Tag_CSKY_FPU_Exception:\t");
16880 printf ("Needed\n");
16881 }
16882 break;
16883 case Tag_CSKY_FPU_NUMBER_MODULE:
16884 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
16885 return display_tag_value (-1, p, end);
16886 case Tag_CSKY_FPU_HARDFP:
16887 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
16888 READ_ULEB (val, p, end);
16889 if (val & VAL_CSKY_FPU_HARDFP_HALF)
16890 printf (" Half");
16891 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
16892 printf (" Single");
16893 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
16894 printf (" Double");
16895 printf ("\n");
16896 break;
16897 default:
16898 return display_tag_value (tag, p, end);
16899 }
16900 return p;
16901}
16902
32ec8896 16903static bfd_boolean
dda8d76d 16904process_attributes (Filedata * filedata,
60bca95a 16905 const char * public_name,
104d59d1 16906 unsigned int proc_type,
f6f0e17b 16907 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 16908 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 16909{
2cf0635d 16910 Elf_Internal_Shdr * sect;
11c1ff18 16911 unsigned i;
32ec8896 16912 bfd_boolean res = TRUE;
11c1ff18
PB
16913
16914 /* Find the section header so that we get the size. */
dda8d76d
NC
16915 for (i = 0, sect = filedata->section_headers;
16916 i < filedata->file_header.e_shnum;
11c1ff18
PB
16917 i++, sect++)
16918 {
071436c6
NC
16919 unsigned char * contents;
16920 unsigned char * p;
16921
104d59d1 16922 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
16923 continue;
16924
dda8d76d 16925 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 16926 sect->sh_size, _("attributes"));
60bca95a 16927 if (contents == NULL)
32ec8896
NC
16928 {
16929 res = FALSE;
16930 continue;
16931 }
60bca95a 16932
11c1ff18 16933 p = contents;
60abdbed
NC
16934 /* The first character is the version of the attributes.
16935 Currently only version 1, (aka 'A') is recognised here. */
16936 if (*p != 'A')
32ec8896
NC
16937 {
16938 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
16939 res = FALSE;
16940 }
60abdbed 16941 else
11c1ff18 16942 {
071436c6
NC
16943 bfd_vma section_len;
16944
16945 section_len = sect->sh_size - 1;
11c1ff18 16946 p++;
60bca95a 16947
071436c6 16948 while (section_len > 0)
11c1ff18 16949 {
071436c6 16950 bfd_vma attr_len;
e9847026 16951 unsigned int namelen;
11c1ff18 16952 bfd_boolean public_section;
104d59d1 16953 bfd_boolean gnu_section;
11c1ff18 16954
071436c6 16955 if (section_len <= 4)
e0a31db1
NC
16956 {
16957 error (_("Tag section ends prematurely\n"));
32ec8896 16958 res = FALSE;
e0a31db1
NC
16959 break;
16960 }
071436c6 16961 attr_len = byte_get (p, 4);
11c1ff18 16962 p += 4;
60bca95a 16963
071436c6 16964 if (attr_len > section_len)
11c1ff18 16965 {
071436c6
NC
16966 error (_("Bad attribute length (%u > %u)\n"),
16967 (unsigned) attr_len, (unsigned) section_len);
16968 attr_len = section_len;
32ec8896 16969 res = FALSE;
11c1ff18 16970 }
74e1a04b 16971 /* PR 17531: file: 001-101425-0.004 */
071436c6 16972 else if (attr_len < 5)
74e1a04b 16973 {
071436c6 16974 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
32ec8896 16975 res = FALSE;
74e1a04b
NC
16976 break;
16977 }
e9847026 16978
071436c6
NC
16979 section_len -= attr_len;
16980 attr_len -= 4;
16981
16982 namelen = strnlen ((char *) p, attr_len) + 1;
16983 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
16984 {
16985 error (_("Corrupt attribute section name\n"));
32ec8896 16986 res = FALSE;
e9847026
NC
16987 break;
16988 }
16989
071436c6
NC
16990 printf (_("Attribute Section: "));
16991 print_symbol (INT_MAX, (const char *) p);
16992 putchar ('\n');
60bca95a
NC
16993
16994 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
16995 public_section = TRUE;
16996 else
16997 public_section = FALSE;
60bca95a
NC
16998
16999 if (streq ((char *) p, "gnu"))
104d59d1
JM
17000 gnu_section = TRUE;
17001 else
17002 gnu_section = FALSE;
60bca95a 17003
11c1ff18 17004 p += namelen;
071436c6 17005 attr_len -= namelen;
e0a31db1 17006
071436c6 17007 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17008 {
e0a31db1 17009 int tag;
cd30bcef 17010 unsigned int val;
11c1ff18 17011 bfd_vma size;
071436c6 17012 unsigned char * end;
60bca95a 17013
e0a31db1 17014 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17015 if (attr_len < 6)
e0a31db1
NC
17016 {
17017 error (_("Unused bytes at end of section\n"));
32ec8896 17018 res = FALSE;
e0a31db1
NC
17019 section_len = 0;
17020 break;
17021 }
17022
17023 tag = *(p++);
11c1ff18 17024 size = byte_get (p, 4);
071436c6 17025 if (size > attr_len)
11c1ff18 17026 {
e9847026 17027 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17028 (unsigned) size, (unsigned) attr_len);
32ec8896 17029 res = FALSE;
071436c6 17030 size = attr_len;
11c1ff18 17031 }
e0a31db1
NC
17032 /* PR binutils/17531: Safe handling of corrupt files. */
17033 if (size < 6)
17034 {
17035 error (_("Bad subsection length (%u < 6)\n"),
17036 (unsigned) size);
32ec8896 17037 res = FALSE;
e0a31db1
NC
17038 section_len = 0;
17039 break;
17040 }
60bca95a 17041
071436c6 17042 attr_len -= size;
11c1ff18 17043 end = p + size - 1;
071436c6 17044 assert (end <= contents + sect->sh_size);
11c1ff18 17045 p += 4;
60bca95a 17046
11c1ff18
PB
17047 switch (tag)
17048 {
17049 case 1:
2b692964 17050 printf (_("File Attributes\n"));
11c1ff18
PB
17051 break;
17052 case 2:
2b692964 17053 printf (_("Section Attributes:"));
11c1ff18
PB
17054 goto do_numlist;
17055 case 3:
2b692964 17056 printf (_("Symbol Attributes:"));
1a0670f3 17057 /* Fall through. */
11c1ff18
PB
17058 do_numlist:
17059 for (;;)
17060 {
cd30bcef 17061 READ_ULEB (val, p, end);
11c1ff18
PB
17062 if (val == 0)
17063 break;
17064 printf (" %d", val);
17065 }
17066 printf ("\n");
17067 break;
17068 default:
2b692964 17069 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
17070 public_section = FALSE;
17071 break;
17072 }
60bca95a 17073
071436c6 17074 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
17075 {
17076 while (p < end)
f6f0e17b 17077 p = display_pub_attribute (p, end);
60abdbed 17078 assert (p == end);
104d59d1 17079 }
071436c6 17080 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
17081 {
17082 while (p < end)
17083 p = display_gnu_attribute (p,
f6f0e17b
NC
17084 display_proc_gnu_attribute,
17085 end);
60abdbed 17086 assert (p == end);
11c1ff18 17087 }
071436c6 17088 else if (p < end)
11c1ff18 17089 {
071436c6 17090 printf (_(" Unknown attribute:\n"));
f6f0e17b 17091 display_raw_attribute (p, end);
11c1ff18
PB
17092 p = end;
17093 }
071436c6
NC
17094 else
17095 attr_len = 0;
11c1ff18
PB
17096 }
17097 }
17098 }
d70c5fc7 17099
60bca95a 17100 free (contents);
11c1ff18 17101 }
32ec8896
NC
17102
17103 return res;
11c1ff18
PB
17104}
17105
ccb4c951
RS
17106/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
17107 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
17108 and return the VMA of the next entry, or -1 if there was a problem.
17109 Does not read from DATA_END or beyond. */
ccb4c951
RS
17110
17111static bfd_vma
82b1b41b
NC
17112print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
17113 unsigned char * data_end)
ccb4c951
RS
17114{
17115 printf (" ");
17116 print_vma (addr, LONG_HEX);
17117 printf (" ");
17118 if (addr < pltgot + 0xfff0)
17119 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
17120 else
17121 printf ("%10s", "");
17122 printf (" ");
17123 if (data == NULL)
2b692964 17124 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
17125 else
17126 {
17127 bfd_vma entry;
82b1b41b 17128 unsigned char * from = data + addr - pltgot;
ccb4c951 17129
82b1b41b
NC
17130 if (from + (is_32bit_elf ? 4 : 8) > data_end)
17131 {
17132 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
17133 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
17134 return (bfd_vma) -1;
17135 }
17136 else
17137 {
17138 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17139 print_vma (entry, LONG_HEX);
17140 }
ccb4c951
RS
17141 }
17142 return addr + (is_32bit_elf ? 4 : 8);
17143}
17144
861fb55a
DJ
17145/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
17146 PLTGOT. Print the Address and Initial fields of an entry at VMA
17147 ADDR and return the VMA of the next entry. */
17148
17149static bfd_vma
2cf0635d 17150print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
17151{
17152 printf (" ");
17153 print_vma (addr, LONG_HEX);
17154 printf (" ");
17155 if (data == NULL)
2b692964 17156 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
17157 else
17158 {
17159 bfd_vma entry;
17160
17161 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17162 print_vma (entry, LONG_HEX);
17163 }
17164 return addr + (is_32bit_elf ? 4 : 8);
17165}
17166
351cdf24
MF
17167static void
17168print_mips_ases (unsigned int mask)
17169{
17170 if (mask & AFL_ASE_DSP)
17171 fputs ("\n\tDSP ASE", stdout);
17172 if (mask & AFL_ASE_DSPR2)
17173 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
17174 if (mask & AFL_ASE_DSPR3)
17175 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
17176 if (mask & AFL_ASE_EVA)
17177 fputs ("\n\tEnhanced VA Scheme", stdout);
17178 if (mask & AFL_ASE_MCU)
17179 fputs ("\n\tMCU (MicroController) ASE", stdout);
17180 if (mask & AFL_ASE_MDMX)
17181 fputs ("\n\tMDMX ASE", stdout);
17182 if (mask & AFL_ASE_MIPS3D)
17183 fputs ("\n\tMIPS-3D ASE", stdout);
17184 if (mask & AFL_ASE_MT)
17185 fputs ("\n\tMT ASE", stdout);
17186 if (mask & AFL_ASE_SMARTMIPS)
17187 fputs ("\n\tSmartMIPS ASE", stdout);
17188 if (mask & AFL_ASE_VIRT)
17189 fputs ("\n\tVZ ASE", stdout);
17190 if (mask & AFL_ASE_MSA)
17191 fputs ("\n\tMSA ASE", stdout);
17192 if (mask & AFL_ASE_MIPS16)
17193 fputs ("\n\tMIPS16 ASE", stdout);
17194 if (mask & AFL_ASE_MICROMIPS)
17195 fputs ("\n\tMICROMIPS ASE", stdout);
17196 if (mask & AFL_ASE_XPA)
17197 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
17198 if (mask & AFL_ASE_MIPS16E2)
17199 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
17200 if (mask & AFL_ASE_CRC)
17201 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
17202 if (mask & AFL_ASE_GINV)
17203 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
17204 if (mask & AFL_ASE_LOONGSON_MMI)
17205 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
17206 if (mask & AFL_ASE_LOONGSON_CAM)
17207 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
17208 if (mask & AFL_ASE_LOONGSON_EXT)
17209 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
17210 if (mask & AFL_ASE_LOONGSON_EXT2)
17211 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
17212 if (mask == 0)
17213 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
17214 else if ((mask & ~AFL_ASE_MASK) != 0)
17215 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
17216}
17217
17218static void
17219print_mips_isa_ext (unsigned int isa_ext)
17220{
17221 switch (isa_ext)
17222 {
17223 case 0:
17224 fputs (_("None"), stdout);
17225 break;
17226 case AFL_EXT_XLR:
17227 fputs ("RMI XLR", stdout);
17228 break;
2c629856
N
17229 case AFL_EXT_OCTEON3:
17230 fputs ("Cavium Networks Octeon3", stdout);
17231 break;
351cdf24
MF
17232 case AFL_EXT_OCTEON2:
17233 fputs ("Cavium Networks Octeon2", stdout);
17234 break;
17235 case AFL_EXT_OCTEONP:
17236 fputs ("Cavium Networks OcteonP", stdout);
17237 break;
351cdf24
MF
17238 case AFL_EXT_OCTEON:
17239 fputs ("Cavium Networks Octeon", stdout);
17240 break;
17241 case AFL_EXT_5900:
17242 fputs ("Toshiba R5900", stdout);
17243 break;
17244 case AFL_EXT_4650:
17245 fputs ("MIPS R4650", stdout);
17246 break;
17247 case AFL_EXT_4010:
17248 fputs ("LSI R4010", stdout);
17249 break;
17250 case AFL_EXT_4100:
17251 fputs ("NEC VR4100", stdout);
17252 break;
17253 case AFL_EXT_3900:
17254 fputs ("Toshiba R3900", stdout);
17255 break;
17256 case AFL_EXT_10000:
17257 fputs ("MIPS R10000", stdout);
17258 break;
17259 case AFL_EXT_SB1:
17260 fputs ("Broadcom SB-1", stdout);
17261 break;
17262 case AFL_EXT_4111:
17263 fputs ("NEC VR4111/VR4181", stdout);
17264 break;
17265 case AFL_EXT_4120:
17266 fputs ("NEC VR4120", stdout);
17267 break;
17268 case AFL_EXT_5400:
17269 fputs ("NEC VR5400", stdout);
17270 break;
17271 case AFL_EXT_5500:
17272 fputs ("NEC VR5500", stdout);
17273 break;
17274 case AFL_EXT_LOONGSON_2E:
17275 fputs ("ST Microelectronics Loongson 2E", stdout);
17276 break;
17277 case AFL_EXT_LOONGSON_2F:
17278 fputs ("ST Microelectronics Loongson 2F", stdout);
17279 break;
38bf472a
MR
17280 case AFL_EXT_INTERAPTIV_MR2:
17281 fputs ("Imagination interAptiv MR2", stdout);
17282 break;
351cdf24 17283 default:
00ac7aa0 17284 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
17285 }
17286}
17287
32ec8896 17288static signed int
351cdf24
MF
17289get_mips_reg_size (int reg_size)
17290{
17291 return (reg_size == AFL_REG_NONE) ? 0
17292 : (reg_size == AFL_REG_32) ? 32
17293 : (reg_size == AFL_REG_64) ? 64
17294 : (reg_size == AFL_REG_128) ? 128
17295 : -1;
17296}
17297
32ec8896 17298static bfd_boolean
dda8d76d 17299process_mips_specific (Filedata * filedata)
5b18a4bc 17300{
2cf0635d 17301 Elf_Internal_Dyn * entry;
351cdf24 17302 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
17303 size_t liblist_offset = 0;
17304 size_t liblistno = 0;
17305 size_t conflictsno = 0;
17306 size_t options_offset = 0;
17307 size_t conflicts_offset = 0;
861fb55a
DJ
17308 size_t pltrelsz = 0;
17309 size_t pltrel = 0;
ccb4c951 17310 bfd_vma pltgot = 0;
861fb55a
DJ
17311 bfd_vma mips_pltgot = 0;
17312 bfd_vma jmprel = 0;
ccb4c951
RS
17313 bfd_vma local_gotno = 0;
17314 bfd_vma gotsym = 0;
17315 bfd_vma symtabno = 0;
32ec8896 17316 bfd_boolean res = TRUE;
103f02d3 17317
dda8d76d 17318 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896
NC
17319 display_mips_gnu_attribute))
17320 res = FALSE;
2cf19d5c 17321
dda8d76d 17322 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
17323
17324 if (sect != NULL)
17325 {
17326 Elf_External_ABIFlags_v0 *abiflags_ext;
17327 Elf_Internal_ABIFlags_v0 abiflags_in;
17328
17329 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
17330 {
17331 error (_("Corrupt MIPS ABI Flags section.\n"));
17332 res = FALSE;
17333 }
351cdf24
MF
17334 else
17335 {
dda8d76d 17336 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
17337 sect->sh_size, _("MIPS ABI Flags section"));
17338 if (abiflags_ext)
17339 {
17340 abiflags_in.version = BYTE_GET (abiflags_ext->version);
17341 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
17342 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
17343 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
17344 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
17345 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
17346 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
17347 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
17348 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
17349 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
17350 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
17351
17352 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
17353 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
17354 if (abiflags_in.isa_rev > 1)
17355 printf ("r%d", abiflags_in.isa_rev);
17356 printf ("\nGPR size: %d",
17357 get_mips_reg_size (abiflags_in.gpr_size));
17358 printf ("\nCPR1 size: %d",
17359 get_mips_reg_size (abiflags_in.cpr1_size));
17360 printf ("\nCPR2 size: %d",
17361 get_mips_reg_size (abiflags_in.cpr2_size));
17362 fputs ("\nFP ABI: ", stdout);
17363 print_mips_fp_abi_value (abiflags_in.fp_abi);
17364 fputs ("ISA Extension: ", stdout);
17365 print_mips_isa_ext (abiflags_in.isa_ext);
17366 fputs ("\nASEs:", stdout);
17367 print_mips_ases (abiflags_in.ases);
17368 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
17369 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
17370 fputc ('\n', stdout);
17371 free (abiflags_ext);
17372 }
17373 }
17374 }
17375
19e6b90e 17376 /* We have a lot of special sections. Thanks SGI! */
978c4450 17377 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
17378 {
17379 /* No dynamic information available. See if there is static GOT. */
dda8d76d 17380 sect = find_section (filedata, ".got");
bbdd9a68
MR
17381 if (sect != NULL)
17382 {
17383 unsigned char *data_end;
17384 unsigned char *data;
17385 bfd_vma ent, end;
17386 int addr_size;
17387
17388 pltgot = sect->sh_addr;
17389
17390 ent = pltgot;
17391 addr_size = (is_32bit_elf ? 4 : 8);
17392 end = pltgot + sect->sh_size;
17393
dda8d76d 17394 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
17395 end - pltgot, 1,
17396 _("Global Offset Table data"));
17397 /* PR 12855: Null data is handled gracefully throughout. */
17398 data_end = data + (end - pltgot);
17399
17400 printf (_("\nStatic GOT:\n"));
17401 printf (_(" Canonical gp value: "));
17402 print_vma (ent + 0x7ff0, LONG_HEX);
17403 printf ("\n\n");
17404
17405 /* In a dynamic binary GOT[0] is reserved for the dynamic
17406 loader to store the lazy resolver pointer, however in
17407 a static binary it may well have been omitted and GOT
17408 reduced to a table of addresses.
17409 PR 21344: Check for the entry being fully available
17410 before fetching it. */
17411 if (data
17412 && data + ent - pltgot + addr_size <= data_end
17413 && byte_get (data + ent - pltgot, addr_size) == 0)
17414 {
17415 printf (_(" Reserved entries:\n"));
17416 printf (_(" %*s %10s %*s\n"),
17417 addr_size * 2, _("Address"), _("Access"),
17418 addr_size * 2, _("Value"));
17419 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17420 printf ("\n");
17421 if (ent == (bfd_vma) -1)
17422 goto sgot_print_fail;
17423
17424 /* Check for the MSB of GOT[1] being set, identifying a
17425 GNU object. This entry will be used by some runtime
17426 loaders, to store the module pointer. Otherwise this
17427 is an ordinary local entry.
17428 PR 21344: Check for the entry being fully available
17429 before fetching it. */
17430 if (data
17431 && data + ent - pltgot + addr_size <= data_end
17432 && (byte_get (data + ent - pltgot, addr_size)
17433 >> (addr_size * 8 - 1)) != 0)
17434 {
17435 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17436 printf ("\n");
17437 if (ent == (bfd_vma) -1)
17438 goto sgot_print_fail;
17439 }
17440 printf ("\n");
17441 }
17442
f17e9d8a 17443 if (data != NULL && ent < end)
bbdd9a68
MR
17444 {
17445 printf (_(" Local entries:\n"));
17446 printf (" %*s %10s %*s\n",
17447 addr_size * 2, _("Address"), _("Access"),
17448 addr_size * 2, _("Value"));
17449 while (ent < end)
17450 {
17451 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17452 printf ("\n");
17453 if (ent == (bfd_vma) -1)
17454 goto sgot_print_fail;
17455 }
17456 printf ("\n");
17457 }
17458
17459 sgot_print_fail:
9db70fc3 17460 free (data);
bbdd9a68
MR
17461 }
17462 return res;
17463 }
252b5132 17464
978c4450 17465 for (entry = filedata->dynamic_section;
071436c6 17466 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
17467 (entry < filedata->dynamic_section + filedata->dynamic_nent
17468 && entry->d_tag != DT_NULL);
071436c6 17469 ++entry)
252b5132
RH
17470 switch (entry->d_tag)
17471 {
17472 case DT_MIPS_LIBLIST:
d93f0186 17473 liblist_offset
dda8d76d 17474 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17475 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
17476 break;
17477 case DT_MIPS_LIBLISTNO:
17478 liblistno = entry->d_un.d_val;
17479 break;
17480 case DT_MIPS_OPTIONS:
dda8d76d 17481 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
17482 break;
17483 case DT_MIPS_CONFLICT:
d93f0186 17484 conflicts_offset
dda8d76d 17485 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17486 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
17487 break;
17488 case DT_MIPS_CONFLICTNO:
17489 conflictsno = entry->d_un.d_val;
17490 break;
ccb4c951 17491 case DT_PLTGOT:
861fb55a
DJ
17492 pltgot = entry->d_un.d_ptr;
17493 break;
ccb4c951
RS
17494 case DT_MIPS_LOCAL_GOTNO:
17495 local_gotno = entry->d_un.d_val;
17496 break;
17497 case DT_MIPS_GOTSYM:
17498 gotsym = entry->d_un.d_val;
17499 break;
17500 case DT_MIPS_SYMTABNO:
17501 symtabno = entry->d_un.d_val;
17502 break;
861fb55a
DJ
17503 case DT_MIPS_PLTGOT:
17504 mips_pltgot = entry->d_un.d_ptr;
17505 break;
17506 case DT_PLTREL:
17507 pltrel = entry->d_un.d_val;
17508 break;
17509 case DT_PLTRELSZ:
17510 pltrelsz = entry->d_un.d_val;
17511 break;
17512 case DT_JMPREL:
17513 jmprel = entry->d_un.d_ptr;
17514 break;
252b5132
RH
17515 default:
17516 break;
17517 }
17518
17519 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
17520 {
2cf0635d 17521 Elf32_External_Lib * elib;
252b5132
RH
17522 size_t cnt;
17523
dda8d76d 17524 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
17525 sizeof (Elf32_External_Lib),
17526 liblistno,
17527 _("liblist section data"));
a6e9f9df 17528 if (elib)
252b5132 17529 {
d3a49aa8
AM
17530 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
17531 "\nSection '.liblist' contains %lu entries:\n",
17532 (unsigned long) liblistno),
a6e9f9df 17533 (unsigned long) liblistno);
2b692964 17534 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
17535 stdout);
17536
17537 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 17538 {
a6e9f9df 17539 Elf32_Lib liblist;
91d6fa6a 17540 time_t atime;
d5b07ef4 17541 char timebuf[128];
2cf0635d 17542 struct tm * tmp;
a6e9f9df
AM
17543
17544 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17545 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
17546 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17547 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17548 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17549
91d6fa6a 17550 tmp = gmtime (&atime);
e9e44622
JJ
17551 snprintf (timebuf, sizeof (timebuf),
17552 "%04u-%02u-%02uT%02u:%02u:%02u",
17553 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17554 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 17555
31104126 17556 printf ("%3lu: ", (unsigned long) cnt);
978c4450
AM
17557 if (VALID_DYNAMIC_NAME (filedata, liblist.l_name))
17558 print_symbol (20, GET_DYNAMIC_NAME (filedata, liblist.l_name));
d79b3d50 17559 else
2b692964 17560 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
17561 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
17562 liblist.l_version);
a6e9f9df
AM
17563
17564 if (liblist.l_flags == 0)
2b692964 17565 puts (_(" NONE"));
a6e9f9df
AM
17566 else
17567 {
17568 static const struct
252b5132 17569 {
2cf0635d 17570 const char * name;
a6e9f9df 17571 int bit;
252b5132 17572 }
a6e9f9df
AM
17573 l_flags_vals[] =
17574 {
17575 { " EXACT_MATCH", LL_EXACT_MATCH },
17576 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
17577 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
17578 { " EXPORTS", LL_EXPORTS },
17579 { " DELAY_LOAD", LL_DELAY_LOAD },
17580 { " DELTA", LL_DELTA }
17581 };
17582 int flags = liblist.l_flags;
17583 size_t fcnt;
17584
60bca95a 17585 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
17586 if ((flags & l_flags_vals[fcnt].bit) != 0)
17587 {
17588 fputs (l_flags_vals[fcnt].name, stdout);
17589 flags ^= l_flags_vals[fcnt].bit;
17590 }
17591 if (flags != 0)
17592 printf (" %#x", (unsigned int) flags);
252b5132 17593
a6e9f9df
AM
17594 puts ("");
17595 }
252b5132 17596 }
252b5132 17597
a6e9f9df
AM
17598 free (elib);
17599 }
32ec8896
NC
17600 else
17601 res = FALSE;
252b5132
RH
17602 }
17603
17604 if (options_offset != 0)
17605 {
2cf0635d 17606 Elf_External_Options * eopt;
252b5132
RH
17607 size_t offset;
17608 int cnt;
dda8d76d 17609 sect = filedata->section_headers;
252b5132
RH
17610
17611 /* Find the section header so that we get the size. */
dda8d76d 17612 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 17613 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
17614 if (sect == NULL)
17615 {
17616 error (_("No MIPS_OPTIONS header found\n"));
32ec8896 17617 return FALSE;
071436c6 17618 }
7fc0c668
NC
17619 /* PR 24243 */
17620 if (sect->sh_size < sizeof (* eopt))
17621 {
17622 error (_("The MIPS options section is too small.\n"));
17623 return FALSE;
17624 }
252b5132 17625
dda8d76d 17626 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 17627 sect->sh_size, _("options"));
a6e9f9df 17628 if (eopt)
252b5132 17629 {
fd17d1e6 17630 Elf_Internal_Options option;
76da6bbe 17631
a6e9f9df 17632 offset = cnt = 0;
82b1b41b 17633 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 17634 {
2cf0635d 17635 Elf_External_Options * eoption;
fd17d1e6 17636 unsigned int optsize;
252b5132 17637
a6e9f9df 17638 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 17639
fd17d1e6 17640 optsize = BYTE_GET (eoption->size);
76da6bbe 17641
82b1b41b 17642 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
17643 if (optsize < sizeof (* eopt)
17644 || optsize > sect->sh_size - offset)
82b1b41b 17645 {
645f43a8 17646 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 17647 optsize);
645f43a8 17648 free (eopt);
32ec8896 17649 return FALSE;
82b1b41b 17650 }
fd17d1e6 17651 offset += optsize;
a6e9f9df
AM
17652 ++cnt;
17653 }
252b5132 17654
d3a49aa8
AM
17655 printf (ngettext ("\nSection '%s' contains %d entry:\n",
17656 "\nSection '%s' contains %d entries:\n",
17657 cnt),
dda8d76d 17658 printable_section_name (filedata, sect), cnt);
76da6bbe 17659
82b1b41b 17660 offset = 0;
a6e9f9df 17661 while (cnt-- > 0)
252b5132 17662 {
a6e9f9df 17663 size_t len;
fd17d1e6
AM
17664 Elf_External_Options * eoption;
17665
17666 eoption = (Elf_External_Options *) ((char *) eopt + offset);
17667
17668 option.kind = BYTE_GET (eoption->kind);
17669 option.size = BYTE_GET (eoption->size);
17670 option.section = BYTE_GET (eoption->section);
17671 option.info = BYTE_GET (eoption->info);
a6e9f9df 17672
fd17d1e6 17673 switch (option.kind)
252b5132 17674 {
a6e9f9df
AM
17675 case ODK_NULL:
17676 /* This shouldn't happen. */
d0c4e780 17677 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 17678 option.section, option.info);
a6e9f9df 17679 break;
2e6be59c 17680
a6e9f9df
AM
17681 case ODK_REGINFO:
17682 printf (" REGINFO ");
dda8d76d 17683 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 17684 {
2cf0635d 17685 Elf32_External_RegInfo * ereg;
b34976b6 17686 Elf32_RegInfo reginfo;
a6e9f9df 17687
2e6be59c 17688 /* 32bit form. */
fd17d1e6
AM
17689 if (option.size < (sizeof (Elf_External_Options)
17690 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
17691 {
17692 printf (_("<corrupt>\n"));
17693 error (_("Truncated MIPS REGINFO option\n"));
17694 cnt = 0;
17695 break;
17696 }
17697
fd17d1e6 17698 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 17699
a6e9f9df
AM
17700 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17701 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17702 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17703 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17704 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
17705 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
17706
d0c4e780
AM
17707 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
17708 reginfo.ri_gprmask, reginfo.ri_gp_value);
17709 printf (" "
17710 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
17711 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
17712 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17713 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17714 }
17715 else
17716 {
17717 /* 64 bit form. */
2cf0635d 17718 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
17719 Elf64_Internal_RegInfo reginfo;
17720
fd17d1e6
AM
17721 if (option.size < (sizeof (Elf_External_Options)
17722 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
17723 {
17724 printf (_("<corrupt>\n"));
17725 error (_("Truncated MIPS REGINFO option\n"));
17726 cnt = 0;
17727 break;
17728 }
17729
fd17d1e6 17730 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
17731 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17732 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17733 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17734 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17735 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 17736 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 17737
d0c4e780
AM
17738 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
17739 reginfo.ri_gprmask, reginfo.ri_gp_value);
17740 printf (" "
17741 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
17742 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
17743 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17744 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17745 }
fd17d1e6 17746 offset += option.size;
a6e9f9df 17747 continue;
2e6be59c 17748
a6e9f9df
AM
17749 case ODK_EXCEPTIONS:
17750 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 17751 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 17752 fputs (") fpe_max(", stdout);
fd17d1e6 17753 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
17754 fputs (")", stdout);
17755
fd17d1e6 17756 if (option.info & OEX_PAGE0)
a6e9f9df 17757 fputs (" PAGE0", stdout);
fd17d1e6 17758 if (option.info & OEX_SMM)
a6e9f9df 17759 fputs (" SMM", stdout);
fd17d1e6 17760 if (option.info & OEX_FPDBUG)
a6e9f9df 17761 fputs (" FPDBUG", stdout);
fd17d1e6 17762 if (option.info & OEX_DISMISS)
a6e9f9df
AM
17763 fputs (" DISMISS", stdout);
17764 break;
2e6be59c 17765
a6e9f9df
AM
17766 case ODK_PAD:
17767 fputs (" PAD ", stdout);
fd17d1e6 17768 if (option.info & OPAD_PREFIX)
a6e9f9df 17769 fputs (" PREFIX", stdout);
fd17d1e6 17770 if (option.info & OPAD_POSTFIX)
a6e9f9df 17771 fputs (" POSTFIX", stdout);
fd17d1e6 17772 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
17773 fputs (" SYMBOL", stdout);
17774 break;
2e6be59c 17775
a6e9f9df
AM
17776 case ODK_HWPATCH:
17777 fputs (" HWPATCH ", stdout);
fd17d1e6 17778 if (option.info & OHW_R4KEOP)
a6e9f9df 17779 fputs (" R4KEOP", stdout);
fd17d1e6 17780 if (option.info & OHW_R8KPFETCH)
a6e9f9df 17781 fputs (" R8KPFETCH", stdout);
fd17d1e6 17782 if (option.info & OHW_R5KEOP)
a6e9f9df 17783 fputs (" R5KEOP", stdout);
fd17d1e6 17784 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
17785 fputs (" R5KCVTL", stdout);
17786 break;
2e6be59c 17787
a6e9f9df
AM
17788 case ODK_FILL:
17789 fputs (" FILL ", stdout);
17790 /* XXX Print content of info word? */
17791 break;
2e6be59c 17792
a6e9f9df
AM
17793 case ODK_TAGS:
17794 fputs (" TAGS ", stdout);
17795 /* XXX Print content of info word? */
17796 break;
2e6be59c 17797
a6e9f9df
AM
17798 case ODK_HWAND:
17799 fputs (" HWAND ", stdout);
fd17d1e6 17800 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 17801 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 17802 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
17803 fputs (" R4KEOP_CLEAN", stdout);
17804 break;
2e6be59c 17805
a6e9f9df
AM
17806 case ODK_HWOR:
17807 fputs (" HWOR ", stdout);
fd17d1e6 17808 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 17809 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 17810 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
17811 fputs (" R4KEOP_CLEAN", stdout);
17812 break;
2e6be59c 17813
a6e9f9df 17814 case ODK_GP_GROUP:
d0c4e780 17815 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
17816 option.info & OGP_GROUP,
17817 (option.info & OGP_SELF) >> 16);
a6e9f9df 17818 break;
2e6be59c 17819
a6e9f9df 17820 case ODK_IDENT:
d0c4e780 17821 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
17822 option.info & OGP_GROUP,
17823 (option.info & OGP_SELF) >> 16);
a6e9f9df 17824 break;
2e6be59c 17825
a6e9f9df
AM
17826 default:
17827 /* This shouldn't happen. */
d0c4e780 17828 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 17829 option.kind, option.section, option.info);
a6e9f9df 17830 break;
252b5132 17831 }
a6e9f9df 17832
2cf0635d 17833 len = sizeof (* eopt);
fd17d1e6 17834 while (len < option.size)
82b1b41b 17835 {
fd17d1e6 17836 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 17837
82b1b41b
NC
17838 if (ISPRINT (datum))
17839 printf ("%c", datum);
17840 else
17841 printf ("\\%03o", datum);
17842 len ++;
17843 }
a6e9f9df 17844 fputs ("\n", stdout);
82b1b41b 17845
fd17d1e6 17846 offset += option.size;
252b5132 17847 }
a6e9f9df 17848 free (eopt);
252b5132 17849 }
32ec8896
NC
17850 else
17851 res = FALSE;
252b5132
RH
17852 }
17853
17854 if (conflicts_offset != 0 && conflictsno != 0)
17855 {
2cf0635d 17856 Elf32_Conflict * iconf;
252b5132
RH
17857 size_t cnt;
17858
978c4450 17859 if (filedata->dynamic_symbols == NULL)
252b5132 17860 {
591a748a 17861 error (_("conflict list found without a dynamic symbol table\n"));
32ec8896 17862 return FALSE;
252b5132
RH
17863 }
17864
7296a62a
NC
17865 /* PR 21345 - print a slightly more helpful error message
17866 if we are sure that the cmalloc will fail. */
645f43a8 17867 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
17868 {
17869 error (_("Overlarge number of conflicts detected: %lx\n"),
17870 (long) conflictsno);
17871 return FALSE;
17872 }
17873
3f5e193b 17874 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
17875 if (iconf == NULL)
17876 {
8b73c356 17877 error (_("Out of memory allocating space for dynamic conflicts\n"));
32ec8896 17878 return FALSE;
252b5132
RH
17879 }
17880
9ea033b2 17881 if (is_32bit_elf)
252b5132 17882 {
2cf0635d 17883 Elf32_External_Conflict * econf32;
a6e9f9df 17884
3f5e193b 17885 econf32 = (Elf32_External_Conflict *)
95099889
AM
17886 get_data (NULL, filedata, conflicts_offset,
17887 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 17888 if (!econf32)
5a814d6d
AM
17889 {
17890 free (iconf);
17891 return FALSE;
17892 }
252b5132
RH
17893
17894 for (cnt = 0; cnt < conflictsno; ++cnt)
17895 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
17896
17897 free (econf32);
252b5132
RH
17898 }
17899 else
17900 {
2cf0635d 17901 Elf64_External_Conflict * econf64;
a6e9f9df 17902
3f5e193b 17903 econf64 = (Elf64_External_Conflict *)
95099889
AM
17904 get_data (NULL, filedata, conflicts_offset,
17905 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 17906 if (!econf64)
5a814d6d
AM
17907 {
17908 free (iconf);
17909 return FALSE;
17910 }
252b5132
RH
17911
17912 for (cnt = 0; cnt < conflictsno; ++cnt)
17913 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
17914
17915 free (econf64);
252b5132
RH
17916 }
17917
d3a49aa8
AM
17918 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
17919 "\nSection '.conflict' contains %lu entries:\n",
17920 (unsigned long) conflictsno),
c7e7ca54 17921 (unsigned long) conflictsno);
252b5132
RH
17922 puts (_(" Num: Index Value Name"));
17923
17924 for (cnt = 0; cnt < conflictsno; ++cnt)
17925 {
b34976b6 17926 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 17927
978c4450 17928 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 17929 printf (_("<corrupt symbol index>"));
d79b3d50 17930 else
e0a31db1
NC
17931 {
17932 Elf_Internal_Sym * psym;
17933
978c4450 17934 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
17935 print_vma (psym->st_value, FULL_HEX);
17936 putchar (' ');
978c4450
AM
17937 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17938 print_symbol (25, GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17939 else
17940 printf (_("<corrupt: %14ld>"), psym->st_name);
17941 }
31104126 17942 putchar ('\n');
252b5132
RH
17943 }
17944
252b5132
RH
17945 free (iconf);
17946 }
17947
ccb4c951
RS
17948 if (pltgot != 0 && local_gotno != 0)
17949 {
91d6fa6a 17950 bfd_vma ent, local_end, global_end;
bbeee7ea 17951 size_t i, offset;
2cf0635d 17952 unsigned char * data;
82b1b41b 17953 unsigned char * data_end;
bbeee7ea 17954 int addr_size;
ccb4c951 17955
91d6fa6a 17956 ent = pltgot;
ccb4c951
RS
17957 addr_size = (is_32bit_elf ? 4 : 8);
17958 local_end = pltgot + local_gotno * addr_size;
ccb4c951 17959
74e1a04b
NC
17960 /* PR binutils/17533 file: 012-111227-0.004 */
17961 if (symtabno < gotsym)
17962 {
17963 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 17964 (unsigned long) gotsym, (unsigned long) symtabno);
32ec8896 17965 return FALSE;
74e1a04b 17966 }
82b1b41b 17967
74e1a04b 17968 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
17969 /* PR 17531: file: 54c91a34. */
17970 if (global_end < local_end)
17971 {
17972 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
32ec8896 17973 return FALSE;
82b1b41b 17974 }
948f632f 17975
dda8d76d
NC
17976 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
17977 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
17978 global_end - pltgot, 1,
17979 _("Global Offset Table data"));
919383ac 17980 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 17981 data_end = data + (global_end - pltgot);
59245841 17982
ccb4c951
RS
17983 printf (_("\nPrimary GOT:\n"));
17984 printf (_(" Canonical gp value: "));
17985 print_vma (pltgot + 0x7ff0, LONG_HEX);
17986 printf ("\n\n");
17987
17988 printf (_(" Reserved entries:\n"));
17989 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
17990 addr_size * 2, _("Address"), _("Access"),
17991 addr_size * 2, _("Initial"));
82b1b41b 17992 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 17993 printf (_(" Lazy resolver\n"));
82b1b41b
NC
17994 if (ent == (bfd_vma) -1)
17995 goto got_print_fail;
75ec1fdb 17996
c4ab9505
MR
17997 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
17998 This entry will be used by some runtime loaders, to store the
17999 module pointer. Otherwise this is an ordinary local entry.
18000 PR 21344: Check for the entry being fully available before
18001 fetching it. */
18002 if (data
18003 && data + ent - pltgot + addr_size <= data_end
18004 && (byte_get (data + ent - pltgot, addr_size)
18005 >> (addr_size * 8 - 1)) != 0)
18006 {
18007 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18008 printf (_(" Module pointer (GNU extension)\n"));
18009 if (ent == (bfd_vma) -1)
18010 goto got_print_fail;
ccb4c951
RS
18011 }
18012 printf ("\n");
18013
f17e9d8a 18014 if (data != NULL && ent < local_end)
ccb4c951
RS
18015 {
18016 printf (_(" Local entries:\n"));
cc5914eb 18017 printf (" %*s %10s %*s\n",
2b692964
NC
18018 addr_size * 2, _("Address"), _("Access"),
18019 addr_size * 2, _("Initial"));
91d6fa6a 18020 while (ent < local_end)
ccb4c951 18021 {
82b1b41b 18022 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18023 printf ("\n");
82b1b41b
NC
18024 if (ent == (bfd_vma) -1)
18025 goto got_print_fail;
ccb4c951
RS
18026 }
18027 printf ("\n");
18028 }
18029
f17e9d8a 18030 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18031 {
18032 int sym_width;
18033
18034 printf (_(" Global entries:\n"));
cc5914eb 18035 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18036 addr_size * 2, _("Address"),
18037 _("Access"),
2b692964 18038 addr_size * 2, _("Initial"),
9cf03b7e
NC
18039 addr_size * 2, _("Sym.Val."),
18040 _("Type"),
18041 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18042 _("Ndx"), _("Name"));
0b4362b0 18043
ccb4c951 18044 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18045
ccb4c951
RS
18046 for (i = gotsym; i < symtabno; i++)
18047 {
82b1b41b 18048 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18049 printf (" ");
e0a31db1 18050
978c4450 18051 if (filedata->dynamic_symbols == NULL)
e0a31db1 18052 printf (_("<no dynamic symbols>"));
978c4450 18053 else if (i < filedata->num_dynamic_syms)
e0a31db1 18054 {
978c4450 18055 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
18056
18057 print_vma (psym->st_value, LONG_HEX);
18058 printf (" %-7s %3s ",
dda8d76d
NC
18059 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18060 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 18061
978c4450
AM
18062 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18063 print_symbol (sym_width,
18064 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18065 else
18066 printf (_("<corrupt: %14ld>"), psym->st_name);
18067 }
ccb4c951 18068 else
7fc5ac57
JBG
18069 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
18070 (unsigned long) i);
e0a31db1 18071
ccb4c951 18072 printf ("\n");
82b1b41b
NC
18073 if (ent == (bfd_vma) -1)
18074 break;
ccb4c951
RS
18075 }
18076 printf ("\n");
18077 }
18078
82b1b41b 18079 got_print_fail:
9db70fc3 18080 free (data);
ccb4c951
RS
18081 }
18082
861fb55a
DJ
18083 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
18084 {
91d6fa6a 18085 bfd_vma ent, end;
861fb55a
DJ
18086 size_t offset, rel_offset;
18087 unsigned long count, i;
2cf0635d 18088 unsigned char * data;
861fb55a 18089 int addr_size, sym_width;
2cf0635d 18090 Elf_Internal_Rela * rels;
861fb55a 18091
dda8d76d 18092 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
18093 if (pltrel == DT_RELA)
18094 {
dda8d76d 18095 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 18096 return FALSE;
861fb55a
DJ
18097 }
18098 else
18099 {
dda8d76d 18100 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 18101 return FALSE;
861fb55a
DJ
18102 }
18103
91d6fa6a 18104 ent = mips_pltgot;
861fb55a
DJ
18105 addr_size = (is_32bit_elf ? 4 : 8);
18106 end = mips_pltgot + (2 + count) * addr_size;
18107
dda8d76d
NC
18108 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
18109 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 18110 1, _("Procedure Linkage Table data"));
59245841 18111 if (data == NULL)
288f0ba2
AM
18112 {
18113 free (rels);
18114 return FALSE;
18115 }
59245841 18116
9cf03b7e 18117 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
18118 printf (_(" Reserved entries:\n"));
18119 printf (_(" %*s %*s Purpose\n"),
2b692964 18120 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 18121 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18122 printf (_(" PLT lazy resolver\n"));
91d6fa6a 18123 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18124 printf (_(" Module pointer\n"));
861fb55a
DJ
18125 printf ("\n");
18126
18127 printf (_(" Entries:\n"));
cc5914eb 18128 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
18129 addr_size * 2, _("Address"),
18130 addr_size * 2, _("Initial"),
18131 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
18132 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
18133 for (i = 0; i < count; i++)
18134 {
df97ab2a 18135 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 18136
91d6fa6a 18137 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 18138 printf (" ");
e0a31db1 18139
978c4450 18140 if (idx >= filedata->num_dynamic_syms)
df97ab2a 18141 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 18142 else
e0a31db1 18143 {
978c4450 18144 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
18145
18146 print_vma (psym->st_value, LONG_HEX);
18147 printf (" %-7s %3s ",
dda8d76d
NC
18148 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18149 get_symbol_index_type (filedata, psym->st_shndx));
978c4450
AM
18150 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18151 print_symbol (sym_width,
18152 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18153 else
18154 printf (_("<corrupt: %14ld>"), psym->st_name);
18155 }
861fb55a
DJ
18156 printf ("\n");
18157 }
18158 printf ("\n");
18159
9db70fc3 18160 free (data);
861fb55a
DJ
18161 free (rels);
18162 }
18163
32ec8896 18164 return res;
252b5132
RH
18165}
18166
32ec8896 18167static bfd_boolean
dda8d76d 18168process_nds32_specific (Filedata * filedata)
35c08157
KLC
18169{
18170 Elf_Internal_Shdr *sect = NULL;
18171
dda8d76d 18172 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 18173 if (sect != NULL && sect->sh_size >= 4)
35c08157 18174 {
9c7b8e9b
AM
18175 unsigned char *buf;
18176 unsigned int flag;
35c08157
KLC
18177
18178 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
18179 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
18180 _("NDS32 elf flags section"));
35c08157 18181
9c7b8e9b 18182 if (buf == NULL)
32ec8896
NC
18183 return FALSE;
18184
9c7b8e9b
AM
18185 flag = byte_get (buf, 4);
18186 free (buf);
18187 switch (flag & 0x3)
35c08157
KLC
18188 {
18189 case 0:
18190 printf ("(VEC_SIZE):\tNo entry.\n");
18191 break;
18192 case 1:
18193 printf ("(VEC_SIZE):\t4 bytes\n");
18194 break;
18195 case 2:
18196 printf ("(VEC_SIZE):\t16 bytes\n");
18197 break;
18198 case 3:
18199 printf ("(VEC_SIZE):\treserved\n");
18200 break;
18201 }
18202 }
18203
18204 return TRUE;
18205}
18206
32ec8896 18207static bfd_boolean
dda8d76d 18208process_gnu_liblist (Filedata * filedata)
047b2264 18209{
2cf0635d
NC
18210 Elf_Internal_Shdr * section;
18211 Elf_Internal_Shdr * string_sec;
18212 Elf32_External_Lib * elib;
18213 char * strtab;
c256ffe7 18214 size_t strtab_size;
047b2264 18215 size_t cnt;
d3a49aa8 18216 unsigned long num_liblist;
047b2264 18217 unsigned i;
32ec8896 18218 bfd_boolean res = TRUE;
047b2264
JJ
18219
18220 if (! do_arch)
32ec8896 18221 return TRUE;
047b2264 18222
dda8d76d
NC
18223 for (i = 0, section = filedata->section_headers;
18224 i < filedata->file_header.e_shnum;
b34976b6 18225 i++, section++)
047b2264
JJ
18226 {
18227 switch (section->sh_type)
18228 {
18229 case SHT_GNU_LIBLIST:
dda8d76d 18230 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
18231 break;
18232
3f5e193b 18233 elib = (Elf32_External_Lib *)
dda8d76d 18234 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 18235 _("liblist section data"));
047b2264
JJ
18236
18237 if (elib == NULL)
32ec8896
NC
18238 {
18239 res = FALSE;
18240 break;
18241 }
047b2264 18242
dda8d76d
NC
18243 string_sec = filedata->section_headers + section->sh_link;
18244 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
18245 string_sec->sh_size,
18246 _("liblist string table"));
047b2264
JJ
18247 if (strtab == NULL
18248 || section->sh_entsize != sizeof (Elf32_External_Lib))
18249 {
18250 free (elib);
2842702f 18251 free (strtab);
32ec8896 18252 res = FALSE;
047b2264
JJ
18253 break;
18254 }
59245841 18255 strtab_size = string_sec->sh_size;
047b2264 18256
d3a49aa8
AM
18257 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
18258 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
18259 "\nLibrary list section '%s' contains %lu entries:\n",
18260 num_liblist),
dda8d76d 18261 printable_section_name (filedata, section),
d3a49aa8 18262 num_liblist);
047b2264 18263
2b692964 18264 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
18265
18266 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
18267 ++cnt)
18268 {
18269 Elf32_Lib liblist;
91d6fa6a 18270 time_t atime;
d5b07ef4 18271 char timebuf[128];
2cf0635d 18272 struct tm * tmp;
047b2264
JJ
18273
18274 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18275 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
18276 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18277 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18278 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18279
91d6fa6a 18280 tmp = gmtime (&atime);
e9e44622
JJ
18281 snprintf (timebuf, sizeof (timebuf),
18282 "%04u-%02u-%02uT%02u:%02u:%02u",
18283 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18284 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
18285
18286 printf ("%3lu: ", (unsigned long) cnt);
18287 if (do_wide)
c256ffe7 18288 printf ("%-20s", liblist.l_name < strtab_size
2b692964 18289 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 18290 else
c256ffe7 18291 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 18292 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
18293 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
18294 liblist.l_version, liblist.l_flags);
18295 }
18296
18297 free (elib);
2842702f 18298 free (strtab);
047b2264
JJ
18299 }
18300 }
18301
32ec8896 18302 return res;
047b2264
JJ
18303}
18304
9437c45b 18305static const char *
dda8d76d 18306get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
18307{
18308 static char buff[64];
103f02d3 18309
dda8d76d 18310 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
18311 switch (e_type)
18312 {
57346661 18313 case NT_AUXV:
1ec5cd37 18314 return _("NT_AUXV (auxiliary vector)");
57346661 18315 case NT_PRSTATUS:
1ec5cd37 18316 return _("NT_PRSTATUS (prstatus structure)");
57346661 18317 case NT_FPREGSET:
1ec5cd37 18318 return _("NT_FPREGSET (floating point registers)");
57346661 18319 case NT_PRPSINFO:
1ec5cd37 18320 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 18321 case NT_TASKSTRUCT:
1ec5cd37 18322 return _("NT_TASKSTRUCT (task structure)");
57346661 18323 case NT_PRXFPREG:
1ec5cd37 18324 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
18325 case NT_PPC_VMX:
18326 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
18327 case NT_PPC_VSX:
18328 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
18329 case NT_PPC_TAR:
18330 return _("NT_PPC_TAR (ppc TAR register)");
18331 case NT_PPC_PPR:
18332 return _("NT_PPC_PPR (ppc PPR register)");
18333 case NT_PPC_DSCR:
18334 return _("NT_PPC_DSCR (ppc DSCR register)");
18335 case NT_PPC_EBB:
18336 return _("NT_PPC_EBB (ppc EBB registers)");
18337 case NT_PPC_PMU:
18338 return _("NT_PPC_PMU (ppc PMU registers)");
18339 case NT_PPC_TM_CGPR:
18340 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
18341 case NT_PPC_TM_CFPR:
18342 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
18343 case NT_PPC_TM_CVMX:
18344 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
18345 case NT_PPC_TM_CVSX:
3fd21718 18346 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
18347 case NT_PPC_TM_SPR:
18348 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
18349 case NT_PPC_TM_CTAR:
18350 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
18351 case NT_PPC_TM_CPPR:
18352 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
18353 case NT_PPC_TM_CDSCR:
18354 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
18355 case NT_386_TLS:
18356 return _("NT_386_TLS (x86 TLS information)");
18357 case NT_386_IOPERM:
18358 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
18359 case NT_X86_XSTATE:
18360 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
18361 case NT_X86_CET:
18362 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
18363 case NT_S390_HIGH_GPRS:
18364 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
18365 case NT_S390_TIMER:
18366 return _("NT_S390_TIMER (s390 timer register)");
18367 case NT_S390_TODCMP:
18368 return _("NT_S390_TODCMP (s390 TOD comparator register)");
18369 case NT_S390_TODPREG:
18370 return _("NT_S390_TODPREG (s390 TOD programmable register)");
18371 case NT_S390_CTRS:
18372 return _("NT_S390_CTRS (s390 control registers)");
18373 case NT_S390_PREFIX:
18374 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
18375 case NT_S390_LAST_BREAK:
18376 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
18377 case NT_S390_SYSTEM_CALL:
18378 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
18379 case NT_S390_TDB:
18380 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
18381 case NT_S390_VXRS_LOW:
18382 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
18383 case NT_S390_VXRS_HIGH:
18384 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
18385 case NT_S390_GS_CB:
18386 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
18387 case NT_S390_GS_BC:
18388 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
18389 case NT_ARM_VFP:
18390 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
18391 case NT_ARM_TLS:
18392 return _("NT_ARM_TLS (AArch TLS registers)");
18393 case NT_ARM_HW_BREAK:
18394 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
18395 case NT_ARM_HW_WATCH:
18396 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
27456742
AK
18397 case NT_ARC_V2:
18398 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
57346661 18399 case NT_PSTATUS:
1ec5cd37 18400 return _("NT_PSTATUS (pstatus structure)");
57346661 18401 case NT_FPREGS:
1ec5cd37 18402 return _("NT_FPREGS (floating point registers)");
57346661 18403 case NT_PSINFO:
1ec5cd37 18404 return _("NT_PSINFO (psinfo structure)");
57346661 18405 case NT_LWPSTATUS:
1ec5cd37 18406 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 18407 case NT_LWPSINFO:
1ec5cd37 18408 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 18409 case NT_WIN32PSTATUS:
1ec5cd37 18410 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
18411 case NT_SIGINFO:
18412 return _("NT_SIGINFO (siginfo_t data)");
18413 case NT_FILE:
18414 return _("NT_FILE (mapped files)");
1ec5cd37
NC
18415 default:
18416 break;
18417 }
18418 else
18419 switch (e_type)
18420 {
18421 case NT_VERSION:
18422 return _("NT_VERSION (version)");
18423 case NT_ARCH:
18424 return _("NT_ARCH (architecture)");
9ef920e9 18425 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 18426 return _("OPEN");
9ef920e9 18427 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 18428 return _("func");
1ec5cd37
NC
18429 default:
18430 break;
18431 }
18432
e9e44622 18433 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 18434 return buff;
779fe533
NC
18435}
18436
32ec8896 18437static bfd_boolean
9ece1fa9
TT
18438print_core_note (Elf_Internal_Note *pnote)
18439{
18440 unsigned int addr_size = is_32bit_elf ? 4 : 8;
18441 bfd_vma count, page_size;
18442 unsigned char *descdata, *filenames, *descend;
18443
18444 if (pnote->type != NT_FILE)
04ac15ab
AS
18445 {
18446 if (do_wide)
18447 printf ("\n");
18448 return TRUE;
18449 }
9ece1fa9
TT
18450
18451#ifndef BFD64
18452 if (!is_32bit_elf)
18453 {
18454 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
18455 /* Still "successful". */
32ec8896 18456 return TRUE;
9ece1fa9
TT
18457 }
18458#endif
18459
18460 if (pnote->descsz < 2 * addr_size)
18461 {
32ec8896
NC
18462 error (_(" Malformed note - too short for header\n"));
18463 return FALSE;
9ece1fa9
TT
18464 }
18465
18466 descdata = (unsigned char *) pnote->descdata;
18467 descend = descdata + pnote->descsz;
18468
18469 if (descdata[pnote->descsz - 1] != '\0')
18470 {
32ec8896
NC
18471 error (_(" Malformed note - does not end with \\0\n"));
18472 return FALSE;
9ece1fa9
TT
18473 }
18474
18475 count = byte_get (descdata, addr_size);
18476 descdata += addr_size;
18477
18478 page_size = byte_get (descdata, addr_size);
18479 descdata += addr_size;
18480
5396a86e
AM
18481 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
18482 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 18483 {
32ec8896
NC
18484 error (_(" Malformed note - too short for supplied file count\n"));
18485 return FALSE;
9ece1fa9
TT
18486 }
18487
18488 printf (_(" Page size: "));
18489 print_vma (page_size, DEC);
18490 printf ("\n");
18491
18492 printf (_(" %*s%*s%*s\n"),
18493 (int) (2 + 2 * addr_size), _("Start"),
18494 (int) (4 + 2 * addr_size), _("End"),
18495 (int) (4 + 2 * addr_size), _("Page Offset"));
18496 filenames = descdata + count * 3 * addr_size;
595712bb 18497 while (count-- > 0)
9ece1fa9
TT
18498 {
18499 bfd_vma start, end, file_ofs;
18500
18501 if (filenames == descend)
18502 {
32ec8896
NC
18503 error (_(" Malformed note - filenames end too early\n"));
18504 return FALSE;
9ece1fa9
TT
18505 }
18506
18507 start = byte_get (descdata, addr_size);
18508 descdata += addr_size;
18509 end = byte_get (descdata, addr_size);
18510 descdata += addr_size;
18511 file_ofs = byte_get (descdata, addr_size);
18512 descdata += addr_size;
18513
18514 printf (" ");
18515 print_vma (start, FULL_HEX);
18516 printf (" ");
18517 print_vma (end, FULL_HEX);
18518 printf (" ");
18519 print_vma (file_ofs, FULL_HEX);
18520 printf ("\n %s\n", filenames);
18521
18522 filenames += 1 + strlen ((char *) filenames);
18523 }
18524
32ec8896 18525 return TRUE;
9ece1fa9
TT
18526}
18527
1118d252
RM
18528static const char *
18529get_gnu_elf_note_type (unsigned e_type)
18530{
1449284b 18531 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
18532 switch (e_type)
18533 {
18534 case NT_GNU_ABI_TAG:
18535 return _("NT_GNU_ABI_TAG (ABI version tag)");
18536 case NT_GNU_HWCAP:
18537 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
18538 case NT_GNU_BUILD_ID:
18539 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
18540 case NT_GNU_GOLD_VERSION:
18541 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
18542 case NT_GNU_PROPERTY_TYPE_0:
18543 return _("NT_GNU_PROPERTY_TYPE_0");
18544 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
18545 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
18546 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
18547 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 18548 default:
1449284b
NC
18549 {
18550 static char buff[64];
1118d252 18551
1449284b
NC
18552 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18553 return buff;
18554 }
18555 }
1118d252
RM
18556}
18557
a9eafb08
L
18558static void
18559decode_x86_compat_isa (unsigned int bitmask)
18560{
18561 while (bitmask)
18562 {
18563 unsigned int bit = bitmask & (- bitmask);
18564
18565 bitmask &= ~ bit;
18566 switch (bit)
18567 {
18568 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
18569 printf ("i486");
18570 break;
18571 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
18572 printf ("586");
18573 break;
18574 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
18575 printf ("686");
18576 break;
18577 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
18578 printf ("SSE");
18579 break;
18580 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
18581 printf ("SSE2");
18582 break;
18583 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
18584 printf ("SSE3");
18585 break;
18586 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
18587 printf ("SSSE3");
18588 break;
18589 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
18590 printf ("SSE4_1");
18591 break;
18592 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
18593 printf ("SSE4_2");
18594 break;
18595 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
18596 printf ("AVX");
18597 break;
18598 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
18599 printf ("AVX2");
18600 break;
18601 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
18602 printf ("AVX512F");
18603 break;
18604 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
18605 printf ("AVX512CD");
18606 break;
18607 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
18608 printf ("AVX512ER");
18609 break;
18610 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
18611 printf ("AVX512PF");
18612 break;
18613 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
18614 printf ("AVX512VL");
18615 break;
18616 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
18617 printf ("AVX512DQ");
18618 break;
18619 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
18620 printf ("AVX512BW");
18621 break;
65b3d26e
L
18622 default:
18623 printf (_("<unknown: %x>"), bit);
18624 break;
a9eafb08
L
18625 }
18626 if (bitmask)
18627 printf (", ");
18628 }
18629}
18630
9ef920e9 18631static void
32930e4e 18632decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 18633{
0a59decb 18634 if (!bitmask)
90c745dc
L
18635 {
18636 printf (_("<None>"));
18637 return;
18638 }
90c745dc 18639
9ef920e9
NC
18640 while (bitmask)
18641 {
1fc87489 18642 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
18643
18644 bitmask &= ~ bit;
18645 switch (bit)
18646 {
32930e4e 18647 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
18648 printf ("CMOV");
18649 break;
32930e4e 18650 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
18651 printf ("SSE");
18652 break;
32930e4e 18653 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
18654 printf ("SSE2");
18655 break;
32930e4e 18656 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
18657 printf ("SSE3");
18658 break;
32930e4e 18659 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
18660 printf ("SSSE3");
18661 break;
32930e4e 18662 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
18663 printf ("SSE4_1");
18664 break;
32930e4e 18665 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
18666 printf ("SSE4_2");
18667 break;
32930e4e 18668 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
18669 printf ("AVX");
18670 break;
32930e4e 18671 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
18672 printf ("AVX2");
18673 break;
32930e4e 18674 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
18675 printf ("FMA");
18676 break;
32930e4e 18677 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
18678 printf ("AVX512F");
18679 break;
32930e4e 18680 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
18681 printf ("AVX512CD");
18682 break;
32930e4e 18683 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
18684 printf ("AVX512ER");
18685 break;
32930e4e 18686 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
18687 printf ("AVX512PF");
18688 break;
32930e4e 18689 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
18690 printf ("AVX512VL");
18691 break;
32930e4e 18692 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
18693 printf ("AVX512DQ");
18694 break;
32930e4e 18695 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
18696 printf ("AVX512BW");
18697 break;
32930e4e 18698 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
18699 printf ("AVX512_4FMAPS");
18700 break;
32930e4e 18701 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
18702 printf ("AVX512_4VNNIW");
18703 break;
32930e4e 18704 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
18705 printf ("AVX512_BITALG");
18706 break;
32930e4e 18707 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
18708 printf ("AVX512_IFMA");
18709 break;
32930e4e 18710 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
18711 printf ("AVX512_VBMI");
18712 break;
32930e4e 18713 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
18714 printf ("AVX512_VBMI2");
18715 break;
32930e4e 18716 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
18717 printf ("AVX512_VNNI");
18718 break;
32930e4e 18719 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
18720 printf ("AVX512_BF16");
18721 break;
65b3d26e
L
18722 default:
18723 printf (_("<unknown: %x>"), bit);
18724 break;
9ef920e9
NC
18725 }
18726 if (bitmask)
18727 printf (", ");
18728 }
18729}
18730
32930e4e
L
18731static void
18732decode_x86_isa (unsigned int bitmask)
18733{
32930e4e
L
18734 while (bitmask)
18735 {
18736 unsigned int bit = bitmask & (- bitmask);
18737
18738 bitmask &= ~ bit;
18739 switch (bit)
18740 {
b0ab0693
L
18741 case GNU_PROPERTY_X86_ISA_1_BASELINE:
18742 printf ("x86-64-baseline");
18743 break;
32930e4e
L
18744 case GNU_PROPERTY_X86_ISA_1_V2:
18745 printf ("x86-64-v2");
18746 break;
18747 case GNU_PROPERTY_X86_ISA_1_V3:
18748 printf ("x86-64-v3");
18749 break;
18750 case GNU_PROPERTY_X86_ISA_1_V4:
18751 printf ("x86-64-v4");
18752 break;
18753 default:
18754 printf (_("<unknown: %x>"), bit);
18755 break;
18756 }
18757 if (bitmask)
18758 printf (", ");
18759 }
18760}
18761
ee2fdd6f 18762static void
a9eafb08 18763decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 18764{
0a59decb 18765 if (!bitmask)
90c745dc
L
18766 {
18767 printf (_("<None>"));
18768 return;
18769 }
90c745dc 18770
ee2fdd6f
L
18771 while (bitmask)
18772 {
18773 unsigned int bit = bitmask & (- bitmask);
18774
18775 bitmask &= ~ bit;
18776 switch (bit)
18777 {
18778 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 18779 printf ("IBT");
ee2fdd6f 18780 break;
48580982 18781 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 18782 printf ("SHSTK");
48580982 18783 break;
279d901e
L
18784 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
18785 printf ("LAM_U48");
18786 break;
18787 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
18788 printf ("LAM_U57");
18789 break;
ee2fdd6f
L
18790 default:
18791 printf (_("<unknown: %x>"), bit);
18792 break;
18793 }
18794 if (bitmask)
18795 printf (", ");
18796 }
18797}
18798
a9eafb08
L
18799static void
18800decode_x86_feature_2 (unsigned int bitmask)
18801{
0a59decb 18802 if (!bitmask)
90c745dc
L
18803 {
18804 printf (_("<None>"));
18805 return;
18806 }
90c745dc 18807
a9eafb08
L
18808 while (bitmask)
18809 {
18810 unsigned int bit = bitmask & (- bitmask);
18811
18812 bitmask &= ~ bit;
18813 switch (bit)
18814 {
18815 case GNU_PROPERTY_X86_FEATURE_2_X86:
18816 printf ("x86");
18817 break;
18818 case GNU_PROPERTY_X86_FEATURE_2_X87:
18819 printf ("x87");
18820 break;
18821 case GNU_PROPERTY_X86_FEATURE_2_MMX:
18822 printf ("MMX");
18823 break;
18824 case GNU_PROPERTY_X86_FEATURE_2_XMM:
18825 printf ("XMM");
18826 break;
18827 case GNU_PROPERTY_X86_FEATURE_2_YMM:
18828 printf ("YMM");
18829 break;
18830 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
18831 printf ("ZMM");
18832 break;
a308b89d
L
18833 case GNU_PROPERTY_X86_FEATURE_2_TMM:
18834 printf ("TMM");
18835 break;
32930e4e
L
18836 case GNU_PROPERTY_X86_FEATURE_2_MASK:
18837 printf ("MASK");
18838 break;
a9eafb08
L
18839 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
18840 printf ("FXSR");
18841 break;
18842 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
18843 printf ("XSAVE");
18844 break;
18845 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
18846 printf ("XSAVEOPT");
18847 break;
18848 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
18849 printf ("XSAVEC");
18850 break;
65b3d26e
L
18851 default:
18852 printf (_("<unknown: %x>"), bit);
18853 break;
a9eafb08
L
18854 }
18855 if (bitmask)
18856 printf (", ");
18857 }
18858}
18859
cd702818
SD
18860static void
18861decode_aarch64_feature_1_and (unsigned int bitmask)
18862{
18863 while (bitmask)
18864 {
18865 unsigned int bit = bitmask & (- bitmask);
18866
18867 bitmask &= ~ bit;
18868 switch (bit)
18869 {
18870 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
18871 printf ("BTI");
18872 break;
18873
18874 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
18875 printf ("PAC");
18876 break;
18877
18878 default:
18879 printf (_("<unknown: %x>"), bit);
18880 break;
18881 }
18882 if (bitmask)
18883 printf (", ");
18884 }
18885}
18886
9ef920e9 18887static void
dda8d76d 18888print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
18889{
18890 unsigned char * ptr = (unsigned char *) pnote->descdata;
18891 unsigned char * ptr_end = ptr + pnote->descsz;
18892 unsigned int size = is_32bit_elf ? 4 : 8;
18893
18894 printf (_(" Properties: "));
18895
1fc87489 18896 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
18897 {
18898 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
18899 return;
18900 }
18901
6ab2c4ed 18902 while (ptr < ptr_end)
9ef920e9 18903 {
1fc87489 18904 unsigned int j;
6ab2c4ed
MC
18905 unsigned int type;
18906 unsigned int datasz;
18907
18908 if ((size_t) (ptr_end - ptr) < 8)
18909 {
18910 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
18911 break;
18912 }
18913
18914 type = byte_get (ptr, 4);
18915 datasz = byte_get (ptr + 4, 4);
9ef920e9 18916
1fc87489 18917 ptr += 8;
9ef920e9 18918
6ab2c4ed 18919 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 18920 {
1fc87489
L
18921 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
18922 type, datasz);
9ef920e9 18923 break;
1fc87489 18924 }
9ef920e9 18925
1fc87489
L
18926 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
18927 {
dda8d76d
NC
18928 if (filedata->file_header.e_machine == EM_X86_64
18929 || filedata->file_header.e_machine == EM_IAMCU
18930 || filedata->file_header.e_machine == EM_386)
1fc87489 18931 {
aa7bca9b
L
18932 unsigned int bitmask;
18933
18934 if (datasz == 4)
0a59decb 18935 bitmask = byte_get (ptr, 4);
aa7bca9b
L
18936 else
18937 bitmask = 0;
18938
1fc87489
L
18939 switch (type)
18940 {
18941 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 18942 if (datasz != 4)
aa7bca9b
L
18943 printf (_("x86 ISA used: <corrupt length: %#x> "),
18944 datasz);
1fc87489 18945 else
aa7bca9b
L
18946 {
18947 printf ("x86 ISA used: ");
18948 decode_x86_isa (bitmask);
18949 }
1fc87489 18950 goto next;
9ef920e9 18951
1fc87489 18952 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 18953 if (datasz != 4)
aa7bca9b
L
18954 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18955 datasz);
1fc87489 18956 else
aa7bca9b
L
18957 {
18958 printf ("x86 ISA needed: ");
18959 decode_x86_isa (bitmask);
18960 }
1fc87489 18961 goto next;
9ef920e9 18962
ee2fdd6f 18963 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 18964 if (datasz != 4)
aa7bca9b
L
18965 printf (_("x86 feature: <corrupt length: %#x> "),
18966 datasz);
ee2fdd6f 18967 else
aa7bca9b
L
18968 {
18969 printf ("x86 feature: ");
a9eafb08
L
18970 decode_x86_feature_1 (bitmask);
18971 }
18972 goto next;
18973
18974 case GNU_PROPERTY_X86_FEATURE_2_USED:
18975 if (datasz != 4)
18976 printf (_("x86 feature used: <corrupt length: %#x> "),
18977 datasz);
18978 else
18979 {
18980 printf ("x86 feature used: ");
18981 decode_x86_feature_2 (bitmask);
18982 }
18983 goto next;
18984
18985 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
18986 if (datasz != 4)
18987 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
18988 else
18989 {
18990 printf ("x86 feature needed: ");
18991 decode_x86_feature_2 (bitmask);
18992 }
18993 goto next;
18994
18995 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
18996 if (datasz != 4)
18997 printf (_("x86 ISA used: <corrupt length: %#x> "),
18998 datasz);
18999 else
19000 {
19001 printf ("x86 ISA used: ");
19002 decode_x86_compat_isa (bitmask);
19003 }
19004 goto next;
19005
19006 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
19007 if (datasz != 4)
19008 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19009 datasz);
19010 else
19011 {
19012 printf ("x86 ISA needed: ");
19013 decode_x86_compat_isa (bitmask);
aa7bca9b 19014 }
ee2fdd6f
L
19015 goto next;
19016
32930e4e
L
19017 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
19018 if (datasz != 4)
19019 printf (_("x86 ISA used: <corrupt length: %#x> "),
19020 datasz);
19021 else
19022 {
19023 printf ("x86 ISA used: ");
19024 decode_x86_compat_2_isa (bitmask);
19025 }
19026 goto next;
19027
19028 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
19029 if (datasz != 4)
19030 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19031 datasz);
19032 else
19033 {
19034 printf ("x86 ISA needed: ");
19035 decode_x86_compat_2_isa (bitmask);
19036 }
19037 goto next;
19038
1fc87489
L
19039 default:
19040 break;
19041 }
19042 }
cd702818
SD
19043 else if (filedata->file_header.e_machine == EM_AARCH64)
19044 {
19045 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
19046 {
19047 printf ("AArch64 feature: ");
19048 if (datasz != 4)
19049 printf (_("<corrupt length: %#x> "), datasz);
19050 else
19051 decode_aarch64_feature_1_and (byte_get (ptr, 4));
19052 goto next;
19053 }
19054 }
1fc87489
L
19055 }
19056 else
19057 {
19058 switch (type)
9ef920e9 19059 {
1fc87489
L
19060 case GNU_PROPERTY_STACK_SIZE:
19061 printf (_("stack size: "));
19062 if (datasz != size)
19063 printf (_("<corrupt length: %#x> "), datasz);
19064 else
19065 printf ("%#lx", (unsigned long) byte_get (ptr, size));
19066 goto next;
19067
19068 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
19069 printf ("no copy on protected ");
19070 if (datasz)
19071 printf (_("<corrupt length: %#x> "), datasz);
19072 goto next;
19073
19074 default:
9ef920e9
NC
19075 break;
19076 }
9ef920e9
NC
19077 }
19078
1fc87489
L
19079 if (type < GNU_PROPERTY_LOPROC)
19080 printf (_("<unknown type %#x data: "), type);
19081 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 19082 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
19083 else
19084 printf (_("<application-specific type %#x data: "), type);
19085 for (j = 0; j < datasz; ++j)
19086 printf ("%02x ", ptr[j] & 0xff);
19087 printf (">");
19088
dc1e8a47 19089 next:
9ef920e9 19090 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
19091 if (ptr == ptr_end)
19092 break;
1fc87489 19093
6ab2c4ed
MC
19094 if (do_wide)
19095 printf (", ");
19096 else
19097 printf ("\n\t");
9ef920e9
NC
19098 }
19099
19100 printf ("\n");
19101}
19102
32ec8896 19103static bfd_boolean
dda8d76d 19104print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 19105{
1449284b 19106 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
19107 switch (pnote->type)
19108 {
19109 case NT_GNU_BUILD_ID:
19110 {
19111 unsigned long i;
19112
19113 printf (_(" Build ID: "));
19114 for (i = 0; i < pnote->descsz; ++i)
19115 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 19116 printf ("\n");
664f90a3
TT
19117 }
19118 break;
19119
19120 case NT_GNU_ABI_TAG:
19121 {
19122 unsigned long os, major, minor, subminor;
19123 const char *osname;
19124
3102e897
NC
19125 /* PR 17531: file: 030-599401-0.004. */
19126 if (pnote->descsz < 16)
19127 {
19128 printf (_(" <corrupt GNU_ABI_TAG>\n"));
19129 break;
19130 }
19131
664f90a3
TT
19132 os = byte_get ((unsigned char *) pnote->descdata, 4);
19133 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19134 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
19135 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
19136
19137 switch (os)
19138 {
19139 case GNU_ABI_TAG_LINUX:
19140 osname = "Linux";
19141 break;
19142 case GNU_ABI_TAG_HURD:
19143 osname = "Hurd";
19144 break;
19145 case GNU_ABI_TAG_SOLARIS:
19146 osname = "Solaris";
19147 break;
19148 case GNU_ABI_TAG_FREEBSD:
19149 osname = "FreeBSD";
19150 break;
19151 case GNU_ABI_TAG_NETBSD:
19152 osname = "NetBSD";
19153 break;
14ae95f2
RM
19154 case GNU_ABI_TAG_SYLLABLE:
19155 osname = "Syllable";
19156 break;
19157 case GNU_ABI_TAG_NACL:
19158 osname = "NaCl";
19159 break;
664f90a3
TT
19160 default:
19161 osname = "Unknown";
19162 break;
19163 }
19164
19165 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
19166 major, minor, subminor);
19167 }
19168 break;
926c5385
CC
19169
19170 case NT_GNU_GOLD_VERSION:
19171 {
19172 unsigned long i;
19173
19174 printf (_(" Version: "));
19175 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
19176 printf ("%c", pnote->descdata[i]);
19177 printf ("\n");
19178 }
19179 break;
1449284b
NC
19180
19181 case NT_GNU_HWCAP:
19182 {
19183 unsigned long num_entries, mask;
19184
19185 /* Hardware capabilities information. Word 0 is the number of entries.
19186 Word 1 is a bitmask of enabled entries. The rest of the descriptor
19187 is a series of entries, where each entry is a single byte followed
19188 by a nul terminated string. The byte gives the bit number to test
19189 if enabled in the bitmask. */
19190 printf (_(" Hardware Capabilities: "));
19191 if (pnote->descsz < 8)
19192 {
32ec8896
NC
19193 error (_("<corrupt GNU_HWCAP>\n"));
19194 return FALSE;
1449284b
NC
19195 }
19196 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
19197 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19198 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
19199 /* FIXME: Add code to display the entries... */
19200 }
19201 break;
19202
9ef920e9 19203 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 19204 print_gnu_property_note (filedata, pnote);
9ef920e9 19205 break;
9abca702 19206
1449284b
NC
19207 default:
19208 /* Handle unrecognised types. An error message should have already been
19209 created by get_gnu_elf_note_type(), so all that we need to do is to
19210 display the data. */
19211 {
19212 unsigned long i;
19213
19214 printf (_(" Description data: "));
19215 for (i = 0; i < pnote->descsz; ++i)
19216 printf ("%02x ", pnote->descdata[i] & 0xff);
19217 printf ("\n");
19218 }
19219 break;
664f90a3
TT
19220 }
19221
32ec8896 19222 return TRUE;
664f90a3
TT
19223}
19224
685080f2
NC
19225static const char *
19226get_v850_elf_note_type (enum v850_notes n_type)
19227{
19228 static char buff[64];
19229
19230 switch (n_type)
19231 {
19232 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
19233 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
19234 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
19235 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
19236 case V850_NOTE_CACHE_INFO: return _("Use of cache");
19237 case V850_NOTE_MMU_INFO: return _("Use of MMU");
19238 default:
19239 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
19240 return buff;
19241 }
19242}
19243
32ec8896 19244static bfd_boolean
685080f2
NC
19245print_v850_note (Elf_Internal_Note * pnote)
19246{
19247 unsigned int val;
19248
19249 if (pnote->descsz != 4)
32ec8896
NC
19250 return FALSE;
19251
685080f2
NC
19252 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
19253
19254 if (val == 0)
19255 {
19256 printf (_("not set\n"));
32ec8896 19257 return TRUE;
685080f2
NC
19258 }
19259
19260 switch (pnote->type)
19261 {
19262 case V850_NOTE_ALIGNMENT:
19263 switch (val)
19264 {
32ec8896
NC
19265 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return TRUE;
19266 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return TRUE;
685080f2
NC
19267 }
19268 break;
14ae95f2 19269
685080f2
NC
19270 case V850_NOTE_DATA_SIZE:
19271 switch (val)
19272 {
32ec8896
NC
19273 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return TRUE;
19274 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return TRUE;
685080f2
NC
19275 }
19276 break;
14ae95f2 19277
685080f2
NC
19278 case V850_NOTE_FPU_INFO:
19279 switch (val)
19280 {
32ec8896
NC
19281 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return TRUE;
19282 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return TRUE;
685080f2
NC
19283 }
19284 break;
14ae95f2 19285
685080f2
NC
19286 case V850_NOTE_MMU_INFO:
19287 case V850_NOTE_CACHE_INFO:
19288 case V850_NOTE_SIMD_INFO:
19289 if (val == EF_RH850_SIMD)
19290 {
19291 printf (_("yes\n"));
32ec8896 19292 return TRUE;
685080f2
NC
19293 }
19294 break;
19295
19296 default:
19297 /* An 'unknown note type' message will already have been displayed. */
19298 break;
19299 }
19300
19301 printf (_("unknown value: %x\n"), val);
32ec8896 19302 return FALSE;
685080f2
NC
19303}
19304
32ec8896 19305static bfd_boolean
c6056a74
SF
19306process_netbsd_elf_note (Elf_Internal_Note * pnote)
19307{
19308 unsigned int version;
19309
19310 switch (pnote->type)
19311 {
19312 case NT_NETBSD_IDENT:
b966f55f
AM
19313 if (pnote->descsz < 1)
19314 break;
c6056a74
SF
19315 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19316 if ((version / 10000) % 100)
b966f55f 19317 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
19318 version, version / 100000000, (version / 1000000) % 100,
19319 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 19320 'A' + (version / 10000) % 26);
c6056a74
SF
19321 else
19322 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 19323 version, version / 100000000, (version / 1000000) % 100,
15f205b1 19324 (version / 100) % 100);
32ec8896 19325 return TRUE;
c6056a74
SF
19326
19327 case NT_NETBSD_MARCH:
9abca702 19328 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 19329 pnote->descdata);
32ec8896 19330 return TRUE;
c6056a74 19331
9abca702
CZ
19332#ifdef NT_NETBSD_PAX
19333 case NT_NETBSD_PAX:
b966f55f
AM
19334 if (pnote->descsz < 1)
19335 break;
9abca702
CZ
19336 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19337 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
19338 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
19339 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
19340 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
19341 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
19342 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
19343 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
19344 return TRUE;
19345#endif
c6056a74 19346 }
b966f55f
AM
19347
19348 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
19349 pnote->descsz, pnote->type);
19350 return FALSE;
c6056a74
SF
19351}
19352
f4ddf30f 19353static const char *
dda8d76d 19354get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 19355{
f4ddf30f
JB
19356 switch (e_type)
19357 {
19358 case NT_FREEBSD_THRMISC:
19359 return _("NT_THRMISC (thrmisc structure)");
19360 case NT_FREEBSD_PROCSTAT_PROC:
19361 return _("NT_PROCSTAT_PROC (proc data)");
19362 case NT_FREEBSD_PROCSTAT_FILES:
19363 return _("NT_PROCSTAT_FILES (files data)");
19364 case NT_FREEBSD_PROCSTAT_VMMAP:
19365 return _("NT_PROCSTAT_VMMAP (vmmap data)");
19366 case NT_FREEBSD_PROCSTAT_GROUPS:
19367 return _("NT_PROCSTAT_GROUPS (groups data)");
19368 case NT_FREEBSD_PROCSTAT_UMASK:
19369 return _("NT_PROCSTAT_UMASK (umask data)");
19370 case NT_FREEBSD_PROCSTAT_RLIMIT:
19371 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
19372 case NT_FREEBSD_PROCSTAT_OSREL:
19373 return _("NT_PROCSTAT_OSREL (osreldate data)");
19374 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
19375 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
19376 case NT_FREEBSD_PROCSTAT_AUXV:
19377 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
19378 case NT_FREEBSD_PTLWPINFO:
19379 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 19380 }
dda8d76d 19381 return get_note_type (filedata, e_type);
f4ddf30f
JB
19382}
19383
9437c45b 19384static const char *
dda8d76d 19385get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
19386{
19387 static char buff[64];
19388
540e6170
CZ
19389 switch (e_type)
19390 {
19391 case NT_NETBSDCORE_PROCINFO:
19392 /* NetBSD core "procinfo" structure. */
19393 return _("NetBSD procinfo structure");
9437c45b 19394
540e6170
CZ
19395#ifdef NT_NETBSDCORE_AUXV
19396 case NT_NETBSDCORE_AUXV:
19397 return _("NetBSD ELF auxiliary vector data");
19398#endif
9437c45b 19399
06d949ec
KR
19400#ifdef NT_NETBSDCORE_LWPSTATUS
19401 case NT_NETBSDCORE_LWPSTATUS:
19402 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
19403#endif
19404
540e6170 19405 default:
06d949ec 19406 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
19407 defined for NetBSD core files. If the note type is less
19408 than the start of the machine-dependent note types, we don't
19409 understand it. */
19410
19411 if (e_type < NT_NETBSDCORE_FIRSTMACH)
19412 {
19413 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19414 return buff;
19415 }
19416 break;
9437c45b
JT
19417 }
19418
dda8d76d 19419 switch (filedata->file_header.e_machine)
9437c45b
JT
19420 {
19421 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
19422 and PT_GETFPREGS == mach+2. */
19423
19424 case EM_OLD_ALPHA:
19425 case EM_ALPHA:
19426 case EM_SPARC:
19427 case EM_SPARC32PLUS:
19428 case EM_SPARCV9:
19429 switch (e_type)
19430 {
2b692964 19431 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 19432 return _("PT_GETREGS (reg structure)");
2b692964 19433 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 19434 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19435 default:
19436 break;
19437 }
19438 break;
19439
c0d38b0e
CZ
19440 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
19441 There's also old PT___GETREGS40 == mach + 1 for old reg
19442 structure which lacks GBR. */
19443 case EM_SH:
19444 switch (e_type)
19445 {
19446 case NT_NETBSDCORE_FIRSTMACH + 1:
19447 return _("PT___GETREGS40 (old reg structure)");
19448 case NT_NETBSDCORE_FIRSTMACH + 3:
19449 return _("PT_GETREGS (reg structure)");
19450 case NT_NETBSDCORE_FIRSTMACH + 5:
19451 return _("PT_GETFPREGS (fpreg structure)");
19452 default:
19453 break;
19454 }
19455 break;
19456
9437c45b
JT
19457 /* On all other arch's, PT_GETREGS == mach+1 and
19458 PT_GETFPREGS == mach+3. */
19459 default:
19460 switch (e_type)
19461 {
2b692964 19462 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 19463 return _("PT_GETREGS (reg structure)");
2b692964 19464 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 19465 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19466 default:
19467 break;
19468 }
19469 }
19470
9cf03b7e 19471 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 19472 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
19473 return buff;
19474}
19475
70616151
TT
19476static const char *
19477get_stapsdt_note_type (unsigned e_type)
19478{
19479 static char buff[64];
19480
19481 switch (e_type)
19482 {
19483 case NT_STAPSDT:
19484 return _("NT_STAPSDT (SystemTap probe descriptors)");
19485
19486 default:
19487 break;
19488 }
19489
19490 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19491 return buff;
19492}
19493
32ec8896 19494static bfd_boolean
c6a9fc58
TT
19495print_stapsdt_note (Elf_Internal_Note *pnote)
19496{
3ca60c57
NC
19497 size_t len, maxlen;
19498 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
19499 char *data = pnote->descdata;
19500 char *data_end = pnote->descdata + pnote->descsz;
19501 bfd_vma pc, base_addr, semaphore;
19502 char *provider, *probe, *arg_fmt;
19503
3ca60c57
NC
19504 if (pnote->descsz < (addr_size * 3))
19505 goto stapdt_note_too_small;
19506
c6a9fc58
TT
19507 pc = byte_get ((unsigned char *) data, addr_size);
19508 data += addr_size;
3ca60c57 19509
c6a9fc58
TT
19510 base_addr = byte_get ((unsigned char *) data, addr_size);
19511 data += addr_size;
3ca60c57 19512
c6a9fc58
TT
19513 semaphore = byte_get ((unsigned char *) data, addr_size);
19514 data += addr_size;
19515
3ca60c57
NC
19516 if (data >= data_end)
19517 goto stapdt_note_too_small;
19518 maxlen = data_end - data;
19519 len = strnlen (data, maxlen);
19520 if (len < maxlen)
19521 {
19522 provider = data;
19523 data += len + 1;
19524 }
19525 else
19526 goto stapdt_note_too_small;
19527
19528 if (data >= data_end)
19529 goto stapdt_note_too_small;
19530 maxlen = data_end - data;
19531 len = strnlen (data, maxlen);
19532 if (len < maxlen)
19533 {
19534 probe = data;
19535 data += len + 1;
19536 }
19537 else
19538 goto stapdt_note_too_small;
9abca702 19539
3ca60c57
NC
19540 if (data >= data_end)
19541 goto stapdt_note_too_small;
19542 maxlen = data_end - data;
19543 len = strnlen (data, maxlen);
19544 if (len < maxlen)
19545 {
19546 arg_fmt = data;
19547 data += len + 1;
19548 }
19549 else
19550 goto stapdt_note_too_small;
c6a9fc58
TT
19551
19552 printf (_(" Provider: %s\n"), provider);
19553 printf (_(" Name: %s\n"), probe);
19554 printf (_(" Location: "));
19555 print_vma (pc, FULL_HEX);
19556 printf (_(", Base: "));
19557 print_vma (base_addr, FULL_HEX);
19558 printf (_(", Semaphore: "));
19559 print_vma (semaphore, FULL_HEX);
9cf03b7e 19560 printf ("\n");
c6a9fc58
TT
19561 printf (_(" Arguments: %s\n"), arg_fmt);
19562
19563 return data == data_end;
3ca60c57
NC
19564
19565 stapdt_note_too_small:
19566 printf (_(" <corrupt - note is too small>\n"));
19567 error (_("corrupt stapdt note - the data size is too small\n"));
19568 return FALSE;
c6a9fc58
TT
19569}
19570
00e98fc7
TG
19571static const char *
19572get_ia64_vms_note_type (unsigned e_type)
19573{
19574 static char buff[64];
19575
19576 switch (e_type)
19577 {
19578 case NT_VMS_MHD:
19579 return _("NT_VMS_MHD (module header)");
19580 case NT_VMS_LNM:
19581 return _("NT_VMS_LNM (language name)");
19582 case NT_VMS_SRC:
19583 return _("NT_VMS_SRC (source files)");
19584 case NT_VMS_TITLE:
9cf03b7e 19585 return "NT_VMS_TITLE";
00e98fc7
TG
19586 case NT_VMS_EIDC:
19587 return _("NT_VMS_EIDC (consistency check)");
19588 case NT_VMS_FPMODE:
19589 return _("NT_VMS_FPMODE (FP mode)");
19590 case NT_VMS_LINKTIME:
9cf03b7e 19591 return "NT_VMS_LINKTIME";
00e98fc7
TG
19592 case NT_VMS_IMGNAM:
19593 return _("NT_VMS_IMGNAM (image name)");
19594 case NT_VMS_IMGID:
19595 return _("NT_VMS_IMGID (image id)");
19596 case NT_VMS_LINKID:
19597 return _("NT_VMS_LINKID (link id)");
19598 case NT_VMS_IMGBID:
19599 return _("NT_VMS_IMGBID (build id)");
19600 case NT_VMS_GSTNAM:
19601 return _("NT_VMS_GSTNAM (sym table name)");
19602 case NT_VMS_ORIG_DYN:
9cf03b7e 19603 return "NT_VMS_ORIG_DYN";
00e98fc7 19604 case NT_VMS_PATCHTIME:
9cf03b7e 19605 return "NT_VMS_PATCHTIME";
00e98fc7
TG
19606 default:
19607 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19608 return buff;
19609 }
19610}
19611
32ec8896 19612static bfd_boolean
00e98fc7
TG
19613print_ia64_vms_note (Elf_Internal_Note * pnote)
19614{
8d18bf79
NC
19615 int maxlen = pnote->descsz;
19616
19617 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
19618 goto desc_size_fail;
19619
00e98fc7
TG
19620 switch (pnote->type)
19621 {
19622 case NT_VMS_MHD:
8d18bf79
NC
19623 if (maxlen <= 36)
19624 goto desc_size_fail;
19625
19626 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
19627
19628 printf (_(" Creation date : %.17s\n"), pnote->descdata);
19629 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
19630 if (l + 34 < maxlen)
19631 {
19632 printf (_(" Module name : %s\n"), pnote->descdata + 34);
19633 if (l + 35 < maxlen)
19634 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
19635 else
19636 printf (_(" Module version : <missing>\n"));
19637 }
00e98fc7 19638 else
8d18bf79
NC
19639 {
19640 printf (_(" Module name : <missing>\n"));
19641 printf (_(" Module version : <missing>\n"));
19642 }
00e98fc7 19643 break;
8d18bf79 19644
00e98fc7 19645 case NT_VMS_LNM:
8d18bf79 19646 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19647 break;
8d18bf79 19648
00e98fc7
TG
19649#ifdef BFD64
19650 case NT_VMS_FPMODE:
9cf03b7e 19651 printf (_(" Floating Point mode: "));
8d18bf79
NC
19652 if (maxlen < 8)
19653 goto desc_size_fail;
19654 /* FIXME: Generate an error if descsz > 8 ? */
19655
4a5cb34f 19656 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 19657 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 19658 break;
8d18bf79 19659
00e98fc7
TG
19660 case NT_VMS_LINKTIME:
19661 printf (_(" Link time: "));
8d18bf79
NC
19662 if (maxlen < 8)
19663 goto desc_size_fail;
19664 /* FIXME: Generate an error if descsz > 8 ? */
19665
00e98fc7 19666 print_vms_time
8d18bf79 19667 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19668 printf ("\n");
19669 break;
8d18bf79 19670
00e98fc7
TG
19671 case NT_VMS_PATCHTIME:
19672 printf (_(" Patch time: "));
8d18bf79
NC
19673 if (maxlen < 8)
19674 goto desc_size_fail;
19675 /* FIXME: Generate an error if descsz > 8 ? */
19676
00e98fc7 19677 print_vms_time
8d18bf79 19678 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19679 printf ("\n");
19680 break;
8d18bf79 19681
00e98fc7 19682 case NT_VMS_ORIG_DYN:
8d18bf79
NC
19683 if (maxlen < 34)
19684 goto desc_size_fail;
19685
00e98fc7
TG
19686 printf (_(" Major id: %u, minor id: %u\n"),
19687 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
19688 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 19689 printf (_(" Last modified : "));
00e98fc7
TG
19690 print_vms_time
19691 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 19692 printf (_("\n Link flags : "));
4a5cb34f 19693 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 19694 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 19695 printf (_(" Header flags: 0x%08x\n"),
948f632f 19696 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 19697 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
19698 break;
19699#endif
8d18bf79 19700
00e98fc7 19701 case NT_VMS_IMGNAM:
8d18bf79 19702 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19703 break;
8d18bf79 19704
00e98fc7 19705 case NT_VMS_GSTNAM:
8d18bf79 19706 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19707 break;
8d18bf79 19708
00e98fc7 19709 case NT_VMS_IMGID:
8d18bf79 19710 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19711 break;
8d18bf79 19712
00e98fc7 19713 case NT_VMS_LINKID:
8d18bf79 19714 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19715 break;
8d18bf79 19716
00e98fc7 19717 default:
32ec8896 19718 return FALSE;
00e98fc7 19719 }
8d18bf79 19720
32ec8896 19721 return TRUE;
8d18bf79
NC
19722
19723 desc_size_fail:
19724 printf (_(" <corrupt - data size is too small>\n"));
19725 error (_("corrupt IA64 note: data size is too small\n"));
19726 return FALSE;
00e98fc7
TG
19727}
19728
fd486f32
AM
19729struct build_attr_cache {
19730 Filedata *filedata;
19731 char *strtab;
19732 unsigned long strtablen;
19733 Elf_Internal_Sym *symtab;
19734 unsigned long nsyms;
19735} ba_cache;
19736
6f156d7a
NC
19737/* Find the symbol associated with a build attribute that is attached
19738 to address OFFSET. If PNAME is non-NULL then store the name of
19739 the symbol (if found) in the provided pointer, Returns NULL if a
19740 symbol could not be found. */
c799a79d 19741
6f156d7a
NC
19742static Elf_Internal_Sym *
19743get_symbol_for_build_attribute (Filedata * filedata,
19744 unsigned long offset,
19745 bfd_boolean is_open_attr,
19746 const char ** pname)
9ef920e9 19747{
fd486f32
AM
19748 Elf_Internal_Sym *saved_sym = NULL;
19749 Elf_Internal_Sym *sym;
9ef920e9 19750
dda8d76d 19751 if (filedata->section_headers != NULL
fd486f32 19752 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 19753 {
c799a79d 19754 Elf_Internal_Shdr * symsec;
9ef920e9 19755
fd486f32
AM
19756 free (ba_cache.strtab);
19757 ba_cache.strtab = NULL;
19758 free (ba_cache.symtab);
19759 ba_cache.symtab = NULL;
19760
c799a79d 19761 /* Load the symbol and string sections. */
dda8d76d
NC
19762 for (symsec = filedata->section_headers;
19763 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 19764 symsec ++)
9ef920e9 19765 {
28d13567
AM
19766 if (symsec->sh_type == SHT_SYMTAB
19767 && get_symtab (filedata, symsec,
19768 &ba_cache.symtab, &ba_cache.nsyms,
19769 &ba_cache.strtab, &ba_cache.strtablen))
19770 break;
9ef920e9 19771 }
fd486f32 19772 ba_cache.filedata = filedata;
9ef920e9
NC
19773 }
19774
fd486f32 19775 if (ba_cache.symtab == NULL)
6f156d7a 19776 return NULL;
9ef920e9 19777
c799a79d 19778 /* Find a symbol whose value matches offset. */
fd486f32 19779 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
19780 if (sym->st_value == offset)
19781 {
fd486f32 19782 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
19783 /* Huh ? This should not happen. */
19784 continue;
9ef920e9 19785
fd486f32 19786 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 19787 continue;
9ef920e9 19788
8fd75781
NC
19789 /* The AArch64 and ARM architectures define mapping symbols
19790 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
19791 if (ba_cache.strtab[sym->st_name] == '$'
19792 && ba_cache.strtab[sym->st_name + 1] != 0
19793 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
19794 continue;
19795
c799a79d
NC
19796 if (is_open_attr)
19797 {
19798 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
19799 and FILE or OBJECT symbols over NOTYPE symbols. We skip
19800 FUNC symbols entirely. */
19801 switch (ELF_ST_TYPE (sym->st_info))
19802 {
c799a79d 19803 case STT_OBJECT:
6f156d7a 19804 case STT_FILE:
c799a79d 19805 saved_sym = sym;
6f156d7a
NC
19806 if (sym->st_size)
19807 {
19808 /* If the symbol has a size associated
19809 with it then we can stop searching. */
fd486f32 19810 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 19811 }
c799a79d 19812 continue;
9ef920e9 19813
c799a79d
NC
19814 case STT_FUNC:
19815 /* Ignore function symbols. */
19816 continue;
19817
19818 default:
19819 break;
19820 }
19821
19822 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 19823 {
c799a79d
NC
19824 case STB_GLOBAL:
19825 if (saved_sym == NULL
19826 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
19827 saved_sym = sym;
19828 break;
c871dade 19829
c799a79d
NC
19830 case STB_LOCAL:
19831 if (saved_sym == NULL)
19832 saved_sym = sym;
19833 break;
19834
19835 default:
9ef920e9
NC
19836 break;
19837 }
19838 }
c799a79d
NC
19839 else
19840 {
19841 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
19842 continue;
19843
19844 saved_sym = sym;
19845 break;
19846 }
19847 }
19848
6f156d7a 19849 if (saved_sym && pname)
fd486f32 19850 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
19851
19852 return saved_sym;
c799a79d
NC
19853}
19854
d20e98ab
NC
19855/* Returns true iff addr1 and addr2 are in the same section. */
19856
19857static bfd_boolean
19858same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
19859{
19860 Elf_Internal_Shdr * a1;
19861 Elf_Internal_Shdr * a2;
19862
19863 a1 = find_section_by_address (filedata, addr1);
19864 a2 = find_section_by_address (filedata, addr2);
9abca702 19865
d20e98ab
NC
19866 return a1 == a2 && a1 != NULL;
19867}
19868
c799a79d 19869static bfd_boolean
dda8d76d
NC
19870print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
19871 Filedata * filedata)
c799a79d 19872{
6f156d7a
NC
19873 static unsigned long global_offset = 0;
19874 static unsigned long global_end = 0;
19875 static unsigned long func_offset = 0;
19876 static unsigned long func_end = 0;
c871dade 19877
6f156d7a
NC
19878 Elf_Internal_Sym * sym;
19879 const char * name;
19880 unsigned long start;
19881 unsigned long end;
19882 bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
19883
19884 switch (pnote->descsz)
c799a79d 19885 {
6f156d7a
NC
19886 case 0:
19887 /* A zero-length description means that the range of
19888 the previous note of the same type should be used. */
c799a79d 19889 if (is_open_attr)
c871dade 19890 {
6f156d7a
NC
19891 if (global_end > global_offset)
19892 printf (_(" Applies to region from %#lx to %#lx\n"),
19893 global_offset, global_end);
19894 else
19895 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
19896 }
19897 else
19898 {
6f156d7a
NC
19899 if (func_end > func_offset)
19900 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
19901 else
19902 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 19903 }
6f156d7a 19904 return TRUE;
9ef920e9 19905
6f156d7a
NC
19906 case 4:
19907 start = byte_get ((unsigned char *) pnote->descdata, 4);
19908 end = 0;
19909 break;
19910
19911 case 8:
c74147bb
NC
19912 start = byte_get ((unsigned char *) pnote->descdata, 4);
19913 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
19914 break;
19915
19916 case 16:
19917 start = byte_get ((unsigned char *) pnote->descdata, 8);
19918 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
19919 break;
9abca702 19920
6f156d7a 19921 default:
c799a79d
NC
19922 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
19923 printf (_(" <invalid descsz>"));
19924 return FALSE;
19925 }
19926
6f156d7a
NC
19927 name = NULL;
19928 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
19929 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
19930 in order to avoid them being confused with the start address of the
19931 first function in the file... */
19932 if (sym == NULL && is_open_attr)
19933 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
19934 & name);
6f156d7a
NC
19935
19936 if (end == 0 && sym != NULL && sym->st_size > 0)
19937 end = start + sym->st_size;
c799a79d
NC
19938
19939 if (is_open_attr)
19940 {
d20e98ab
NC
19941 /* FIXME: Need to properly allow for section alignment.
19942 16 is just the alignment used on x86_64. */
19943 if (global_end > 0
19944 && start > BFD_ALIGN (global_end, 16)
19945 /* Build notes are not guaranteed to be organised in order of
19946 increasing address, but we should find the all of the notes
19947 for one section in the same place. */
19948 && same_section (filedata, start, global_end))
6f156d7a
NC
19949 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
19950 global_end + 1, start - 1);
19951
19952 printf (_(" Applies to region from %#lx"), start);
19953 global_offset = start;
19954
19955 if (end)
19956 {
19957 printf (_(" to %#lx"), end);
19958 global_end = end;
19959 }
c799a79d
NC
19960 }
19961 else
19962 {
6f156d7a
NC
19963 printf (_(" Applies to region from %#lx"), start);
19964 func_offset = start;
19965
19966 if (end)
19967 {
19968 printf (_(" to %#lx"), end);
19969 func_end = end;
19970 }
c799a79d
NC
19971 }
19972
6f156d7a
NC
19973 if (sym && name)
19974 printf (_(" (%s)"), name);
19975
19976 printf ("\n");
19977 return TRUE;
9ef920e9
NC
19978}
19979
19980static bfd_boolean
19981print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
19982{
1d15e434
NC
19983 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
19984 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
19985 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
19986 char name_type;
19987 char name_attribute;
1d15e434 19988 const char * expected_types;
9ef920e9
NC
19989 const char * name = pnote->namedata;
19990 const char * text;
88305e1b 19991 signed int left;
9ef920e9
NC
19992
19993 if (name == NULL || pnote->namesz < 2)
19994 {
19995 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 19996 print_symbol (-20, _(" <corrupt name>"));
9ef920e9
NC
19997 return FALSE;
19998 }
19999
6f156d7a
NC
20000 if (do_wide)
20001 left = 28;
20002 else
20003 left = 20;
88305e1b
NC
20004
20005 /* Version 2 of the spec adds a "GA" prefix to the name field. */
20006 if (name[0] == 'G' && name[1] == 'A')
20007 {
6f156d7a
NC
20008 if (pnote->namesz < 4)
20009 {
20010 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
20011 print_symbol (-20, _(" <corrupt name>"));
20012 return FALSE;
20013 }
20014
88305e1b
NC
20015 printf ("GA");
20016 name += 2;
20017 left -= 2;
20018 }
20019
9ef920e9
NC
20020 switch ((name_type = * name))
20021 {
20022 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20023 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20024 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20025 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20026 printf ("%c", * name);
88305e1b 20027 left --;
9ef920e9
NC
20028 break;
20029 default:
20030 error (_("unrecognised attribute type in name field: %d\n"), name_type);
20031 print_symbol (-20, _("<unknown name type>"));
20032 return FALSE;
20033 }
20034
9ef920e9
NC
20035 ++ name;
20036 text = NULL;
20037
20038 switch ((name_attribute = * name))
20039 {
20040 case GNU_BUILD_ATTRIBUTE_VERSION:
20041 text = _("<version>");
1d15e434 20042 expected_types = string_expected;
9ef920e9
NC
20043 ++ name;
20044 break;
20045 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20046 text = _("<stack prot>");
75d7d298 20047 expected_types = "!+*";
9ef920e9
NC
20048 ++ name;
20049 break;
20050 case GNU_BUILD_ATTRIBUTE_RELRO:
20051 text = _("<relro>");
1d15e434 20052 expected_types = bool_expected;
9ef920e9
NC
20053 ++ name;
20054 break;
20055 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
20056 text = _("<stack size>");
1d15e434 20057 expected_types = number_expected;
9ef920e9
NC
20058 ++ name;
20059 break;
20060 case GNU_BUILD_ATTRIBUTE_TOOL:
20061 text = _("<tool>");
1d15e434 20062 expected_types = string_expected;
9ef920e9
NC
20063 ++ name;
20064 break;
20065 case GNU_BUILD_ATTRIBUTE_ABI:
20066 text = _("<ABI>");
20067 expected_types = "$*";
20068 ++ name;
20069 break;
20070 case GNU_BUILD_ATTRIBUTE_PIC:
20071 text = _("<PIC>");
1d15e434 20072 expected_types = number_expected;
9ef920e9
NC
20073 ++ name;
20074 break;
a8be5506
NC
20075 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
20076 text = _("<short enum>");
1d15e434 20077 expected_types = bool_expected;
a8be5506
NC
20078 ++ name;
20079 break;
9ef920e9
NC
20080 default:
20081 if (ISPRINT (* name))
20082 {
20083 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
20084
20085 if (len > left && ! do_wide)
20086 len = left;
75d7d298 20087 printf ("%.*s:", len, name);
9ef920e9 20088 left -= len;
0dd6ae21 20089 name += len;
9ef920e9
NC
20090 }
20091 else
20092 {
3e6b6445 20093 static char tmpbuf [128];
88305e1b 20094
3e6b6445
NC
20095 error (_("unrecognised byte in name field: %d\n"), * name);
20096 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
20097 text = tmpbuf;
20098 name ++;
9ef920e9
NC
20099 }
20100 expected_types = "*$!+";
20101 break;
20102 }
20103
20104 if (text)
88305e1b 20105 left -= printf ("%s", text);
9ef920e9
NC
20106
20107 if (strchr (expected_types, name_type) == NULL)
75d7d298 20108 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
20109
20110 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
20111 {
20112 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
20113 (unsigned long) pnote->namesz,
20114 (long) (name - pnote->namedata));
20115 return FALSE;
20116 }
20117
20118 if (left < 1 && ! do_wide)
20119 return TRUE;
20120
20121 switch (name_type)
20122 {
20123 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20124 {
b06b2c92 20125 unsigned int bytes;
ddef72cd
NC
20126 unsigned long long val = 0;
20127 unsigned int shift = 0;
20128 char * decoded = NULL;
20129
b06b2c92
NC
20130 bytes = pnote->namesz - (name - pnote->namedata);
20131 if (bytes > 0)
20132 /* The -1 is because the name field is always 0 terminated, and we
20133 want to be able to ensure that the shift in the while loop below
20134 will not overflow. */
20135 -- bytes;
20136
ddef72cd
NC
20137 if (bytes > sizeof (val))
20138 {
3e6b6445
NC
20139 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
20140 bytes);
20141 bytes = sizeof (val);
ddef72cd 20142 }
3e6b6445
NC
20143 /* We do not bother to warn if bytes == 0 as this can
20144 happen with some early versions of the gcc plugin. */
9ef920e9
NC
20145
20146 while (bytes --)
20147 {
54b8331d 20148 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
20149
20150 val |= byte << shift;
9ef920e9
NC
20151 shift += 8;
20152 }
20153
75d7d298 20154 switch (name_attribute)
9ef920e9 20155 {
75d7d298 20156 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
20157 switch (val)
20158 {
75d7d298
NC
20159 case 0: decoded = "static"; break;
20160 case 1: decoded = "pic"; break;
20161 case 2: decoded = "PIC"; break;
20162 case 3: decoded = "pie"; break;
20163 case 4: decoded = "PIE"; break;
20164 default: break;
9ef920e9 20165 }
75d7d298
NC
20166 break;
20167 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20168 switch (val)
9ef920e9 20169 {
75d7d298
NC
20170 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
20171 case 0: decoded = "off"; break;
20172 case 1: decoded = "on"; break;
20173 case 2: decoded = "all"; break;
20174 case 3: decoded = "strong"; break;
20175 case 4: decoded = "explicit"; break;
20176 default: break;
9ef920e9 20177 }
75d7d298
NC
20178 break;
20179 default:
20180 break;
9ef920e9
NC
20181 }
20182
75d7d298 20183 if (decoded != NULL)
3e6b6445
NC
20184 {
20185 print_symbol (-left, decoded);
20186 left = 0;
20187 }
20188 else if (val == 0)
20189 {
20190 printf ("0x0");
20191 left -= 3;
20192 }
9ef920e9 20193 else
75d7d298
NC
20194 {
20195 if (do_wide)
ddef72cd 20196 left -= printf ("0x%llx", val);
75d7d298 20197 else
ddef72cd 20198 left -= printf ("0x%-.*llx", left, val);
75d7d298 20199 }
9ef920e9
NC
20200 }
20201 break;
20202 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20203 left -= print_symbol (- left, name);
20204 break;
20205 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20206 left -= print_symbol (- left, "true");
20207 break;
20208 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20209 left -= print_symbol (- left, "false");
20210 break;
20211 }
20212
20213 if (do_wide && left > 0)
20214 printf ("%-*s", left, " ");
9abca702 20215
9ef920e9
NC
20216 return TRUE;
20217}
20218
6d118b09
NC
20219/* Note that by the ELF standard, the name field is already null byte
20220 terminated, and namesz includes the terminating null byte.
20221 I.E. the value of namesz for the name "FSF" is 4.
20222
e3c8793a 20223 If the value of namesz is zero, there is no name present. */
9ef920e9 20224
32ec8896 20225static bfd_boolean
9ef920e9 20226process_note (Elf_Internal_Note * pnote,
dda8d76d 20227 Filedata * filedata)
779fe533 20228{
2cf0635d
NC
20229 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
20230 const char * nt;
9437c45b
JT
20231
20232 if (pnote->namesz == 0)
1ec5cd37
NC
20233 /* If there is no note name, then use the default set of
20234 note type strings. */
dda8d76d 20235 nt = get_note_type (filedata, pnote->type);
1ec5cd37 20236
1118d252
RM
20237 else if (const_strneq (pnote->namedata, "GNU"))
20238 /* GNU-specific object file notes. */
20239 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
20240
20241 else if (const_strneq (pnote->namedata, "FreeBSD"))
20242 /* FreeBSD-specific core file notes. */
dda8d76d 20243 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 20244
0112cd26 20245 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 20246 /* NetBSD-specific core file notes. */
dda8d76d 20247 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 20248
c6056a74
SF
20249 else if (const_strneq (pnote->namedata, "NetBSD"))
20250 /* NetBSD-specific core file notes. */
20251 return process_netbsd_elf_note (pnote);
20252
9abca702
CZ
20253 else if (const_strneq (pnote->namedata, "PaX"))
20254 /* NetBSD-specific core file notes. */
20255 return process_netbsd_elf_note (pnote);
20256
b15fa79e
AM
20257 else if (strneq (pnote->namedata, "SPU/", 4))
20258 {
20259 /* SPU-specific core file notes. */
20260 nt = pnote->namedata + 4;
20261 name = "SPU";
20262 }
20263
00e98fc7
TG
20264 else if (const_strneq (pnote->namedata, "IPF/VMS"))
20265 /* VMS/ia64-specific file notes. */
20266 nt = get_ia64_vms_note_type (pnote->type);
20267
70616151
TT
20268 else if (const_strneq (pnote->namedata, "stapsdt"))
20269 nt = get_stapsdt_note_type (pnote->type);
20270
9437c45b 20271 else
1ec5cd37
NC
20272 /* Don't recognize this note name; just use the default set of
20273 note type strings. */
dda8d76d 20274 nt = get_note_type (filedata, pnote->type);
9437c45b 20275
1449284b 20276 printf (" ");
9ef920e9 20277
483767a3
AM
20278 if (((const_strneq (pnote->namedata, "GA")
20279 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20280 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20281 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20282 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
20283 print_gnu_build_attribute_name (pnote);
20284 else
20285 print_symbol (-20, name);
20286
20287 if (do_wide)
20288 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
20289 else
20290 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7
TG
20291
20292 if (const_strneq (pnote->namedata, "IPF/VMS"))
20293 return print_ia64_vms_note (pnote);
664f90a3 20294 else if (const_strneq (pnote->namedata, "GNU"))
dda8d76d 20295 return print_gnu_note (filedata, pnote);
c6a9fc58
TT
20296 else if (const_strneq (pnote->namedata, "stapsdt"))
20297 return print_stapsdt_note (pnote);
9ece1fa9
TT
20298 else if (const_strneq (pnote->namedata, "CORE"))
20299 return print_core_note (pnote);
483767a3
AM
20300 else if (((const_strneq (pnote->namedata, "GA")
20301 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20302 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20303 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20304 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 20305 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 20306
9ef920e9 20307 if (pnote->descsz)
1449284b
NC
20308 {
20309 unsigned long i;
20310
20311 printf (_(" description data: "));
20312 for (i = 0; i < pnote->descsz; i++)
178d8719 20313 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
20314 if (!do_wide)
20315 printf ("\n");
1449284b
NC
20316 }
20317
9ef920e9
NC
20318 if (do_wide)
20319 printf ("\n");
20320
32ec8896 20321 return TRUE;
1449284b 20322}
6d118b09 20323
32ec8896 20324static bfd_boolean
dda8d76d
NC
20325process_notes_at (Filedata * filedata,
20326 Elf_Internal_Shdr * section,
20327 bfd_vma offset,
82ed9683
L
20328 bfd_vma length,
20329 bfd_vma align)
779fe533 20330{
2cf0635d
NC
20331 Elf_External_Note * pnotes;
20332 Elf_External_Note * external;
4dff97b2
NC
20333 char * end;
20334 bfd_boolean res = TRUE;
103f02d3 20335
779fe533 20336 if (length <= 0)
32ec8896 20337 return FALSE;
103f02d3 20338
1449284b
NC
20339 if (section)
20340 {
dda8d76d 20341 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 20342 if (pnotes)
32ec8896 20343 {
dda8d76d 20344 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
20345 {
20346 free (pnotes);
20347 return FALSE;
20348 }
32ec8896 20349 }
1449284b
NC
20350 }
20351 else
82ed9683 20352 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 20353 _("notes"));
4dff97b2 20354
dd24e3da 20355 if (pnotes == NULL)
32ec8896 20356 return FALSE;
779fe533 20357
103f02d3 20358 external = pnotes;
103f02d3 20359
1449284b 20360 if (section)
dda8d76d 20361 printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b
NC
20362 else
20363 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
20364 (unsigned long) offset, (unsigned long) length);
20365
82ed9683
L
20366 /* NB: Some note sections may have alignment value of 0 or 1. gABI
20367 specifies that notes should be aligned to 4 bytes in 32-bit
20368 objects and to 8 bytes in 64-bit objects. As a Linux extension,
20369 we also support 4 byte alignment in 64-bit objects. If section
20370 alignment is less than 4, we treate alignment as 4 bytes. */
20371 if (align < 4)
20372 align = 4;
20373 else if (align != 4 && align != 8)
20374 {
20375 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
20376 (long) align);
a788aedd 20377 free (pnotes);
82ed9683
L
20378 return FALSE;
20379 }
20380
dbe15e4e 20381 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 20382
c8071705
NC
20383 end = (char *) pnotes + length;
20384 while ((char *) external < end)
779fe533 20385 {
b34976b6 20386 Elf_Internal_Note inote;
15b42fb0 20387 size_t min_notesz;
4dff97b2 20388 char * next;
2cf0635d 20389 char * temp = NULL;
c8071705 20390 size_t data_remaining = end - (char *) external;
6d118b09 20391
dda8d76d 20392 if (!is_ia64_vms (filedata))
15b42fb0 20393 {
9dd3a467
NC
20394 /* PR binutils/15191
20395 Make sure that there is enough data to read. */
15b42fb0
AM
20396 min_notesz = offsetof (Elf_External_Note, name);
20397 if (data_remaining < min_notesz)
9dd3a467 20398 {
d3a49aa8
AM
20399 warn (ngettext ("Corrupt note: only %ld byte remains, "
20400 "not enough for a full note\n",
20401 "Corrupt note: only %ld bytes remain, "
20402 "not enough for a full note\n",
20403 data_remaining),
20404 (long) data_remaining);
9dd3a467
NC
20405 break;
20406 }
5396a86e
AM
20407 data_remaining -= min_notesz;
20408
15b42fb0
AM
20409 inote.type = BYTE_GET (external->type);
20410 inote.namesz = BYTE_GET (external->namesz);
20411 inote.namedata = external->name;
20412 inote.descsz = BYTE_GET (external->descsz);
276da9b3 20413 inote.descdata = ((char *) external
4dff97b2 20414 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 20415 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 20416 next = ((char *) external
4dff97b2 20417 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 20418 }
00e98fc7 20419 else
15b42fb0
AM
20420 {
20421 Elf64_External_VMS_Note *vms_external;
00e98fc7 20422
9dd3a467
NC
20423 /* PR binutils/15191
20424 Make sure that there is enough data to read. */
15b42fb0
AM
20425 min_notesz = offsetof (Elf64_External_VMS_Note, name);
20426 if (data_remaining < min_notesz)
9dd3a467 20427 {
d3a49aa8
AM
20428 warn (ngettext ("Corrupt note: only %ld byte remains, "
20429 "not enough for a full note\n",
20430 "Corrupt note: only %ld bytes remain, "
20431 "not enough for a full note\n",
20432 data_remaining),
20433 (long) data_remaining);
9dd3a467
NC
20434 break;
20435 }
5396a86e 20436 data_remaining -= min_notesz;
3e55a963 20437
15b42fb0
AM
20438 vms_external = (Elf64_External_VMS_Note *) external;
20439 inote.type = BYTE_GET (vms_external->type);
20440 inote.namesz = BYTE_GET (vms_external->namesz);
20441 inote.namedata = vms_external->name;
20442 inote.descsz = BYTE_GET (vms_external->descsz);
20443 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
20444 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20445 next = inote.descdata + align_power (inote.descsz, 3);
20446 }
20447
5396a86e
AM
20448 /* PR 17531: file: 3443835e. */
20449 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
20450 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
20451 || (size_t) (inote.descdata - inote.namedata) > data_remaining
20452 || (size_t) (next - inote.descdata) < inote.descsz
20453 || ((size_t) (next - inote.descdata)
20454 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 20455 {
15b42fb0 20456 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 20457 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
20458 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
20459 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
20460 break;
20461 }
20462
15b42fb0 20463 external = (Elf_External_Note *) next;
dd24e3da 20464
6d118b09
NC
20465 /* Verify that name is null terminated. It appears that at least
20466 one version of Linux (RedHat 6.0) generates corefiles that don't
20467 comply with the ELF spec by failing to include the null byte in
20468 namesz. */
18344509 20469 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 20470 {
5396a86e 20471 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 20472 {
5396a86e
AM
20473 temp = (char *) malloc (inote.namesz + 1);
20474 if (temp == NULL)
20475 {
20476 error (_("Out of memory allocating space for inote name\n"));
20477 res = FALSE;
20478 break;
20479 }
76da6bbe 20480
5396a86e
AM
20481 memcpy (temp, inote.namedata, inote.namesz);
20482 inote.namedata = temp;
20483 }
20484 inote.namedata[inote.namesz] = 0;
6d118b09
NC
20485 }
20486
dda8d76d 20487 if (! process_note (& inote, filedata))
6b4bf3bc 20488 res = FALSE;
103f02d3 20489
9db70fc3
AM
20490 free (temp);
20491 temp = NULL;
779fe533
NC
20492 }
20493
20494 free (pnotes);
103f02d3 20495
779fe533
NC
20496 return res;
20497}
20498
32ec8896 20499static bfd_boolean
dda8d76d 20500process_corefile_note_segments (Filedata * filedata)
779fe533 20501{
2cf0635d 20502 Elf_Internal_Phdr * segment;
b34976b6 20503 unsigned int i;
32ec8896 20504 bfd_boolean res = TRUE;
103f02d3 20505
dda8d76d 20506 if (! get_program_headers (filedata))
6b4bf3bc 20507 return TRUE;
103f02d3 20508
dda8d76d
NC
20509 for (i = 0, segment = filedata->program_headers;
20510 i < filedata->file_header.e_phnum;
b34976b6 20511 i++, segment++)
779fe533
NC
20512 {
20513 if (segment->p_type == PT_NOTE)
dda8d76d 20514 if (! process_notes_at (filedata, NULL,
32ec8896 20515 (bfd_vma) segment->p_offset,
82ed9683
L
20516 (bfd_vma) segment->p_filesz,
20517 (bfd_vma) segment->p_align))
32ec8896 20518 res = FALSE;
779fe533 20519 }
103f02d3 20520
779fe533
NC
20521 return res;
20522}
20523
32ec8896 20524static bfd_boolean
dda8d76d 20525process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
20526{
20527 Elf_External_Note * pnotes;
20528 Elf_External_Note * external;
c8071705 20529 char * end;
32ec8896 20530 bfd_boolean res = TRUE;
685080f2
NC
20531
20532 if (length <= 0)
32ec8896 20533 return FALSE;
685080f2 20534
dda8d76d 20535 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
20536 _("v850 notes"));
20537 if (pnotes == NULL)
32ec8896 20538 return FALSE;
685080f2
NC
20539
20540 external = pnotes;
c8071705 20541 end = (char*) pnotes + length;
685080f2
NC
20542
20543 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
20544 (unsigned long) offset, (unsigned long) length);
20545
c8071705 20546 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
20547 {
20548 Elf_External_Note * next;
20549 Elf_Internal_Note inote;
20550
20551 inote.type = BYTE_GET (external->type);
20552 inote.namesz = BYTE_GET (external->namesz);
20553 inote.namedata = external->name;
20554 inote.descsz = BYTE_GET (external->descsz);
20555 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
20556 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20557
c8071705
NC
20558 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
20559 {
20560 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
20561 inote.descdata = inote.namedata;
20562 inote.namesz = 0;
20563 }
20564
685080f2
NC
20565 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
20566
c8071705 20567 if ( ((char *) next > end)
685080f2
NC
20568 || ((char *) next < (char *) pnotes))
20569 {
20570 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
20571 (unsigned long) ((char *) external - (char *) pnotes));
20572 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20573 inote.type, inote.namesz, inote.descsz);
20574 break;
20575 }
20576
20577 external = next;
20578
20579 /* Prevent out-of-bounds indexing. */
c8071705 20580 if ( inote.namedata + inote.namesz > end
685080f2
NC
20581 || inote.namedata + inote.namesz < inote.namedata)
20582 {
20583 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
20584 (unsigned long) ((char *) external - (char *) pnotes));
20585 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20586 inote.type, inote.namesz, inote.descsz);
20587 break;
20588 }
20589
20590 printf (" %s: ", get_v850_elf_note_type (inote.type));
20591
20592 if (! print_v850_note (& inote))
20593 {
32ec8896 20594 res = FALSE;
685080f2
NC
20595 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
20596 inote.namesz, inote.descsz);
20597 }
20598 }
20599
20600 free (pnotes);
20601
20602 return res;
20603}
20604
32ec8896 20605static bfd_boolean
dda8d76d 20606process_note_sections (Filedata * filedata)
1ec5cd37 20607{
2cf0635d 20608 Elf_Internal_Shdr * section;
1ec5cd37 20609 unsigned long i;
32ec8896
NC
20610 unsigned int n = 0;
20611 bfd_boolean res = TRUE;
1ec5cd37 20612
dda8d76d
NC
20613 for (i = 0, section = filedata->section_headers;
20614 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 20615 i++, section++)
685080f2
NC
20616 {
20617 if (section->sh_type == SHT_NOTE)
20618 {
dda8d76d 20619 if (! process_notes_at (filedata, section,
32ec8896 20620 (bfd_vma) section->sh_offset,
82ed9683
L
20621 (bfd_vma) section->sh_size,
20622 (bfd_vma) section->sh_addralign))
32ec8896 20623 res = FALSE;
685080f2
NC
20624 n++;
20625 }
20626
dda8d76d
NC
20627 if (( filedata->file_header.e_machine == EM_V800
20628 || filedata->file_header.e_machine == EM_V850
20629 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
20630 && section->sh_type == SHT_RENESAS_INFO)
20631 {
dda8d76d 20632 if (! process_v850_notes (filedata,
32ec8896
NC
20633 (bfd_vma) section->sh_offset,
20634 (bfd_vma) section->sh_size))
20635 res = FALSE;
685080f2
NC
20636 n++;
20637 }
20638 }
df565f32
NC
20639
20640 if (n == 0)
20641 /* Try processing NOTE segments instead. */
dda8d76d 20642 return process_corefile_note_segments (filedata);
1ec5cd37
NC
20643
20644 return res;
20645}
20646
32ec8896 20647static bfd_boolean
dda8d76d 20648process_notes (Filedata * filedata)
779fe533
NC
20649{
20650 /* If we have not been asked to display the notes then do nothing. */
20651 if (! do_notes)
32ec8896 20652 return TRUE;
103f02d3 20653
dda8d76d
NC
20654 if (filedata->file_header.e_type != ET_CORE)
20655 return process_note_sections (filedata);
103f02d3 20656
779fe533 20657 /* No program headers means no NOTE segment. */
dda8d76d
NC
20658 if (filedata->file_header.e_phnum > 0)
20659 return process_corefile_note_segments (filedata);
779fe533 20660
1ec5cd37 20661 printf (_("No note segments present in the core file.\n"));
32ec8896 20662 return TRUE;
779fe533
NC
20663}
20664
60abdbed
NC
20665static unsigned char *
20666display_public_gnu_attributes (unsigned char * start,
20667 const unsigned char * const end)
20668{
20669 printf (_(" Unknown GNU attribute: %s\n"), start);
20670
20671 start += strnlen ((char *) start, end - start);
20672 display_raw_attribute (start, end);
20673
20674 return (unsigned char *) end;
20675}
20676
20677static unsigned char *
20678display_generic_attribute (unsigned char * start,
20679 unsigned int tag,
20680 const unsigned char * const end)
20681{
20682 if (tag == 0)
20683 return (unsigned char *) end;
20684
20685 return display_tag_value (tag, start, end);
20686}
20687
32ec8896 20688static bfd_boolean
dda8d76d 20689process_arch_specific (Filedata * filedata)
252b5132 20690{
a952a375 20691 if (! do_arch)
32ec8896 20692 return TRUE;
a952a375 20693
dda8d76d 20694 switch (filedata->file_header.e_machine)
252b5132 20695 {
53a346d8
CZ
20696 case EM_ARC:
20697 case EM_ARC_COMPACT:
20698 case EM_ARC_COMPACT2:
dda8d76d 20699 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
20700 display_arc_attribute,
20701 display_generic_attribute);
11c1ff18 20702 case EM_ARM:
dda8d76d 20703 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
20704 display_arm_attribute,
20705 display_generic_attribute);
20706
252b5132 20707 case EM_MIPS:
4fe85591 20708 case EM_MIPS_RS3_LE:
dda8d76d 20709 return process_mips_specific (filedata);
60abdbed
NC
20710
20711 case EM_MSP430:
dda8d76d 20712 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 20713 display_msp430_attribute,
c0ea7c52 20714 display_msp430_gnu_attribute);
60abdbed 20715
2dc8dd17
JW
20716 case EM_RISCV:
20717 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
20718 display_riscv_attribute,
20719 display_generic_attribute);
20720
35c08157 20721 case EM_NDS32:
dda8d76d 20722 return process_nds32_specific (filedata);
60abdbed 20723
85f7484a
PB
20724 case EM_68K:
20725 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
20726 display_m68k_gnu_attribute);
20727
34c8bcba 20728 case EM_PPC:
b82317dd 20729 case EM_PPC64:
dda8d76d 20730 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20731 display_power_gnu_attribute);
20732
643f7afb
AK
20733 case EM_S390:
20734 case EM_S390_OLD:
dda8d76d 20735 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20736 display_s390_gnu_attribute);
20737
9e8c70f9
DM
20738 case EM_SPARC:
20739 case EM_SPARC32PLUS:
20740 case EM_SPARCV9:
dda8d76d 20741 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20742 display_sparc_gnu_attribute);
20743
59e6276b 20744 case EM_TI_C6000:
dda8d76d 20745 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
20746 display_tic6x_attribute,
20747 display_generic_attribute);
20748
0861f561
CQ
20749 case EM_CSKY:
20750 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
20751 display_csky_attribute, NULL);
20752
252b5132 20753 default:
dda8d76d 20754 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
20755 display_public_gnu_attributes,
20756 display_generic_attribute);
252b5132 20757 }
252b5132
RH
20758}
20759
32ec8896 20760static bfd_boolean
dda8d76d 20761get_file_header (Filedata * filedata)
252b5132 20762{
9ea033b2 20763 /* Read in the identity array. */
dda8d76d 20764 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20765 return FALSE;
252b5132 20766
9ea033b2 20767 /* Determine how to read the rest of the header. */
dda8d76d 20768 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 20769 {
1a0670f3
AM
20770 default:
20771 case ELFDATANONE:
adab8cdc
AO
20772 case ELFDATA2LSB:
20773 byte_get = byte_get_little_endian;
20774 byte_put = byte_put_little_endian;
20775 break;
20776 case ELFDATA2MSB:
20777 byte_get = byte_get_big_endian;
20778 byte_put = byte_put_big_endian;
20779 break;
9ea033b2
NC
20780 }
20781
20782 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 20783 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
20784
20785 /* Read in the rest of the header. */
20786 if (is_32bit_elf)
20787 {
20788 Elf32_External_Ehdr ehdr32;
252b5132 20789
dda8d76d 20790 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20791 return FALSE;
103f02d3 20792
dda8d76d
NC
20793 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
20794 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
20795 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
20796 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
20797 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
20798 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
20799 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
20800 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
20801 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
20802 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
20803 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
20804 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
20805 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 20806 }
252b5132 20807 else
9ea033b2
NC
20808 {
20809 Elf64_External_Ehdr ehdr64;
a952a375
NC
20810
20811 /* If we have been compiled with sizeof (bfd_vma) == 4, then
20812 we will not be able to cope with the 64bit data found in
20813 64 ELF files. Detect this now and abort before we start
50c2245b 20814 overwriting things. */
a952a375
NC
20815 if (sizeof (bfd_vma) < 8)
20816 {
e3c8793a
NC
20817 error (_("This instance of readelf has been built without support for a\n\
2081864 bit data type and so it cannot read 64 bit ELF files.\n"));
32ec8896 20819 return FALSE;
a952a375 20820 }
103f02d3 20821
dda8d76d 20822 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20823 return FALSE;
103f02d3 20824
dda8d76d
NC
20825 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
20826 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
20827 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
20828 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
20829 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
20830 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
20831 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
20832 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
20833 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
20834 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
20835 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
20836 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
20837 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 20838 }
252b5132 20839
dda8d76d 20840 if (filedata->file_header.e_shoff)
7ece0d85
JJ
20841 {
20842 /* There may be some extensions in the first section header. Don't
20843 bomb if we can't read it. */
20844 if (is_32bit_elf)
dda8d76d 20845 get_32bit_section_headers (filedata, TRUE);
7ece0d85 20846 else
dda8d76d 20847 get_64bit_section_headers (filedata, TRUE);
7ece0d85 20848 }
560f3c1c 20849
32ec8896 20850 return TRUE;
252b5132
RH
20851}
20852
dda8d76d
NC
20853static void
20854close_file (Filedata * filedata)
20855{
20856 if (filedata)
20857 {
20858 if (filedata->handle)
20859 fclose (filedata->handle);
20860 free (filedata);
20861 }
20862}
20863
20864void
20865close_debug_file (void * data)
20866{
20867 close_file ((Filedata *) data);
20868}
20869
20870static Filedata *
20871open_file (const char * pathname)
20872{
20873 struct stat statbuf;
20874 Filedata * filedata = NULL;
20875
20876 if (stat (pathname, & statbuf) < 0
20877 || ! S_ISREG (statbuf.st_mode))
20878 goto fail;
20879
20880 filedata = calloc (1, sizeof * filedata);
20881 if (filedata == NULL)
20882 goto fail;
20883
20884 filedata->handle = fopen (pathname, "rb");
20885 if (filedata->handle == NULL)
20886 goto fail;
20887
20888 filedata->file_size = (bfd_size_type) statbuf.st_size;
20889 filedata->file_name = pathname;
20890
20891 if (! get_file_header (filedata))
20892 goto fail;
20893
20894 if (filedata->file_header.e_shoff)
20895 {
20896 bfd_boolean res;
20897
20898 /* Read the section headers again, this time for real. */
20899 if (is_32bit_elf)
20900 res = get_32bit_section_headers (filedata, FALSE);
20901 else
20902 res = get_64bit_section_headers (filedata, FALSE);
20903
20904 if (!res)
20905 goto fail;
20906 }
20907
20908 return filedata;
20909
20910 fail:
20911 if (filedata)
20912 {
20913 if (filedata->handle)
20914 fclose (filedata->handle);
20915 free (filedata);
20916 }
20917 return NULL;
20918}
20919
20920void *
20921open_debug_file (const char * pathname)
20922{
20923 return open_file (pathname);
20924}
20925
fb52b2f4
NC
20926/* Process one ELF object file according to the command line options.
20927 This file may actually be stored in an archive. The file is
32ec8896
NC
20928 positioned at the start of the ELF object. Returns TRUE if no
20929 problems were encountered, FALSE otherwise. */
fb52b2f4 20930
32ec8896 20931static bfd_boolean
dda8d76d 20932process_object (Filedata * filedata)
252b5132 20933{
24841daa 20934 bfd_boolean have_separate_files;
252b5132 20935 unsigned int i;
2482f306 20936 bfd_boolean res;
252b5132 20937
dda8d76d 20938 if (! get_file_header (filedata))
252b5132 20939 {
dda8d76d 20940 error (_("%s: Failed to read file header\n"), filedata->file_name);
32ec8896 20941 return FALSE;
252b5132
RH
20942 }
20943
20944 /* Initialise per file variables. */
978c4450
AM
20945 for (i = ARRAY_SIZE (filedata->version_info); i--;)
20946 filedata->version_info[i] = 0;
252b5132 20947
978c4450
AM
20948 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
20949 filedata->dynamic_info[i] = 0;
20950 filedata->dynamic_info_DT_GNU_HASH = 0;
20951 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
20952
20953 /* Process the file. */
20954 if (show_name)
dda8d76d 20955 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 20956
18bd398b
NC
20957 /* Initialise the dump_sects array from the cmdline_dump_sects array.
20958 Note we do this even if cmdline_dump_sects is empty because we
20959 must make sure that the dump_sets array is zeroed out before each
20960 object file is processed. */
6431e409
AM
20961 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
20962 memset (filedata->dump.dump_sects, 0,
20963 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20964
dda8d76d 20965 if (cmdline.num_dump_sects > 0)
18bd398b 20966 {
6431e409 20967 if (filedata->dump.num_dump_sects == 0)
18bd398b 20968 /* A sneaky way of allocating the dump_sects array. */
6431e409 20969 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
18bd398b 20970
6431e409
AM
20971 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
20972 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
20973 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20974 }
d70c5fc7 20975
dda8d76d 20976 if (! process_file_header (filedata))
32ec8896 20977 return FALSE;
252b5132 20978
dda8d76d 20979 if (! process_section_headers (filedata))
2f62977e 20980 {
32ec8896
NC
20981 /* Without loaded section headers we cannot process lots of things. */
20982 do_unwind = do_version = do_dump = do_arch = FALSE;
252b5132 20983
2f62977e 20984 if (! do_using_dynamic)
32ec8896 20985 do_syms = do_dyn_syms = do_reloc = FALSE;
2f62977e 20986 }
252b5132 20987
dda8d76d 20988 if (! process_section_groups (filedata))
32ec8896
NC
20989 /* Without loaded section groups we cannot process unwind. */
20990 do_unwind = FALSE;
d1f5c6e3 20991
2482f306
AM
20992 res = process_program_headers (filedata);
20993 if (res)
20994 res = process_dynamic_section (filedata);
252b5132 20995
dda8d76d 20996 if (! process_relocs (filedata))
32ec8896 20997 res = FALSE;
252b5132 20998
dda8d76d 20999 if (! process_unwind (filedata))
32ec8896 21000 res = FALSE;
4d6ed7c8 21001
dda8d76d 21002 if (! process_symbol_table (filedata))
32ec8896 21003 res = FALSE;
252b5132 21004
0f03783c
NC
21005 if (! process_lto_symbol_tables (filedata))
21006 res = FALSE;
b9e920ec 21007
dda8d76d 21008 if (! process_syminfo (filedata))
32ec8896 21009 res = FALSE;
252b5132 21010
dda8d76d 21011 if (! process_version_sections (filedata))
32ec8896 21012 res = FALSE;
252b5132 21013
82ed9683 21014 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 21015 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 21016 else
24841daa 21017 have_separate_files = FALSE;
dda8d76d
NC
21018
21019 if (! process_section_contents (filedata))
32ec8896 21020 res = FALSE;
f5842774 21021
24841daa 21022 if (have_separate_files)
dda8d76d 21023 {
24841daa
NC
21024 separate_info * d;
21025
21026 for (d = first_separate_info; d != NULL; d = d->next)
21027 {
21028 if (! process_section_headers (d->handle))
21029 res = FALSE;
21030 else if (! process_section_contents (d->handle))
21031 res = FALSE;
21032 }
21033
21034 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
21035 }
21036
21037 if (! process_notes (filedata))
32ec8896 21038 res = FALSE;
103f02d3 21039
dda8d76d 21040 if (! process_gnu_liblist (filedata))
32ec8896 21041 res = FALSE;
047b2264 21042
dda8d76d 21043 if (! process_arch_specific (filedata))
32ec8896 21044 res = FALSE;
252b5132 21045
dda8d76d
NC
21046 free (filedata->program_headers);
21047 filedata->program_headers = NULL;
d93f0186 21048
dda8d76d
NC
21049 free (filedata->section_headers);
21050 filedata->section_headers = NULL;
252b5132 21051
dda8d76d
NC
21052 free (filedata->string_table);
21053 filedata->string_table = NULL;
21054 filedata->string_table_length = 0;
252b5132 21055
9db70fc3
AM
21056 free (filedata->dump.dump_sects);
21057 filedata->dump.dump_sects = NULL;
21058 filedata->dump.num_dump_sects = 0;
a788aedd 21059
9db70fc3
AM
21060 free (filedata->dynamic_strings);
21061 filedata->dynamic_strings = NULL;
21062 filedata->dynamic_strings_length = 0;
252b5132 21063
9db70fc3
AM
21064 free (filedata->dynamic_symbols);
21065 filedata->dynamic_symbols = NULL;
21066 filedata->num_dynamic_syms = 0;
252b5132 21067
9db70fc3
AM
21068 free (filedata->dynamic_syminfo);
21069 filedata->dynamic_syminfo = NULL;
ff78d6d6 21070
9db70fc3
AM
21071 free (filedata->dynamic_section);
21072 filedata->dynamic_section = NULL;
293c573e 21073
978c4450 21074 while (filedata->symtab_shndx_list != NULL)
8fb879cd 21075 {
978c4450
AM
21076 elf_section_list *next = filedata->symtab_shndx_list->next;
21077 free (filedata->symtab_shndx_list);
21078 filedata->symtab_shndx_list = next;
8fb879cd
AM
21079 }
21080
9db70fc3
AM
21081 free (filedata->section_headers_groups);
21082 filedata->section_headers_groups = NULL;
e4b17d5c 21083
978c4450 21084 if (filedata->section_groups)
e4b17d5c 21085 {
2cf0635d
NC
21086 struct group_list * g;
21087 struct group_list * next;
e4b17d5c 21088
978c4450 21089 for (i = 0; i < filedata->group_count; i++)
e4b17d5c 21090 {
978c4450 21091 for (g = filedata->section_groups [i].root; g != NULL; g = next)
e4b17d5c
L
21092 {
21093 next = g->next;
21094 free (g);
21095 }
21096 }
21097
978c4450
AM
21098 free (filedata->section_groups);
21099 filedata->section_groups = NULL;
e4b17d5c
L
21100 }
21101
19e6b90e 21102 free_debug_memory ();
18bd398b 21103
32ec8896 21104 return res;
252b5132
RH
21105}
21106
2cf0635d 21107/* Process an ELF archive.
32ec8896
NC
21108 On entry the file is positioned just after the ARMAG string.
21109 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 21110
32ec8896 21111static bfd_boolean
dda8d76d 21112process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
2cf0635d
NC
21113{
21114 struct archive_info arch;
21115 struct archive_info nested_arch;
21116 size_t got;
32ec8896 21117 bfd_boolean ret = TRUE;
2cf0635d 21118
32ec8896 21119 show_name = TRUE;
2cf0635d
NC
21120
21121 /* The ARCH structure is used to hold information about this archive. */
21122 arch.file_name = NULL;
21123 arch.file = NULL;
21124 arch.index_array = NULL;
21125 arch.sym_table = NULL;
21126 arch.longnames = NULL;
21127
21128 /* The NESTED_ARCH structure is used as a single-item cache of information
21129 about a nested archive (when members of a thin archive reside within
21130 another regular archive file). */
21131 nested_arch.file_name = NULL;
21132 nested_arch.file = NULL;
21133 nested_arch.index_array = NULL;
21134 nested_arch.sym_table = NULL;
21135 nested_arch.longnames = NULL;
21136
dda8d76d 21137 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
21138 filedata->file_size, is_thin_archive,
21139 do_archive_index) != 0)
2cf0635d 21140 {
32ec8896 21141 ret = FALSE;
2cf0635d 21142 goto out;
4145f1d5 21143 }
fb52b2f4 21144
4145f1d5
NC
21145 if (do_archive_index)
21146 {
2cf0635d 21147 if (arch.sym_table == NULL)
1cb7d8b1
AM
21148 error (_("%s: unable to dump the index as none was found\n"),
21149 filedata->file_name);
4145f1d5
NC
21150 else
21151 {
591f7597 21152 unsigned long i, l;
4145f1d5
NC
21153 unsigned long current_pos;
21154
1cb7d8b1
AM
21155 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
21156 "in the symbol table)\n"),
21157 filedata->file_name, (unsigned long) arch.index_num,
21158 arch.sym_size);
dda8d76d
NC
21159
21160 current_pos = ftell (filedata->handle);
4145f1d5 21161
2cf0635d 21162 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 21163 {
1cb7d8b1
AM
21164 if (i == 0
21165 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
21166 {
21167 char * member_name
21168 = get_archive_member_name_at (&arch, arch.index_array[i],
21169 &nested_arch);
2cf0635d 21170
1cb7d8b1
AM
21171 if (member_name != NULL)
21172 {
21173 char * qualified_name
21174 = make_qualified_name (&arch, &nested_arch,
21175 member_name);
2cf0635d 21176
1cb7d8b1
AM
21177 if (qualified_name != NULL)
21178 {
21179 printf (_("Contents of binary %s at offset "),
21180 qualified_name);
c2a7d3f5
NC
21181 (void) print_vma (arch.index_array[i], PREFIX_HEX);
21182 putchar ('\n');
1cb7d8b1
AM
21183 free (qualified_name);
21184 }
fd486f32 21185 free (member_name);
4145f1d5
NC
21186 }
21187 }
2cf0635d
NC
21188
21189 if (l >= arch.sym_size)
4145f1d5 21190 {
1cb7d8b1
AM
21191 error (_("%s: end of the symbol table reached "
21192 "before the end of the index\n"),
dda8d76d 21193 filedata->file_name);
32ec8896 21194 ret = FALSE;
cb8f3167 21195 break;
4145f1d5 21196 }
591f7597 21197 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
21198 printf ("\t%.*s\n",
21199 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 21200 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
21201 }
21202
67ce483b 21203 if (arch.uses_64bit_indices)
c2a7d3f5
NC
21204 l = (l + 7) & ~ 7;
21205 else
21206 l += l & 1;
21207
2cf0635d 21208 if (l < arch.sym_size)
32ec8896 21209 {
d3a49aa8
AM
21210 error (ngettext ("%s: %ld byte remains in the symbol table, "
21211 "but without corresponding entries in "
21212 "the index table\n",
21213 "%s: %ld bytes remain in the symbol table, "
21214 "but without corresponding entries in "
21215 "the index table\n",
21216 arch.sym_size - l),
dda8d76d 21217 filedata->file_name, arch.sym_size - l);
32ec8896
NC
21218 ret = FALSE;
21219 }
4145f1d5 21220
dda8d76d 21221 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 21222 {
1cb7d8b1
AM
21223 error (_("%s: failed to seek back to start of object files "
21224 "in the archive\n"),
dda8d76d 21225 filedata->file_name);
32ec8896 21226 ret = FALSE;
2cf0635d 21227 goto out;
4145f1d5 21228 }
fb52b2f4 21229 }
4145f1d5
NC
21230
21231 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
21232 && !do_segments && !do_header && !do_dump && !do_version
21233 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 21234 && !do_section_groups && !do_dyn_syms)
2cf0635d 21235 {
32ec8896 21236 ret = TRUE; /* Archive index only. */
2cf0635d
NC
21237 goto out;
21238 }
fb52b2f4
NC
21239 }
21240
fb52b2f4
NC
21241 while (1)
21242 {
2cf0635d
NC
21243 char * name;
21244 size_t namelen;
21245 char * qualified_name;
21246
21247 /* Read the next archive header. */
dda8d76d 21248 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
21249 {
21250 error (_("%s: failed to seek to next archive header\n"),
21251 arch.file_name);
21252 ret = FALSE;
21253 break;
21254 }
dda8d76d 21255 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 21256 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
21257 {
21258 if (got == 0)
2cf0635d 21259 break;
28e817cc
NC
21260 /* PR 24049 - we cannot use filedata->file_name as this will
21261 have already been freed. */
21262 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 21263
1cb7d8b1
AM
21264 ret = FALSE;
21265 break;
21266 }
2cf0635d 21267 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
21268 {
21269 error (_("%s: did not find a valid archive header\n"),
21270 arch.file_name);
21271 ret = FALSE;
21272 break;
21273 }
2cf0635d
NC
21274
21275 arch.next_arhdr_offset += sizeof arch.arhdr;
21276
978c4450
AM
21277 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
21278 if (filedata->archive_file_size & 01)
21279 ++filedata->archive_file_size;
2cf0635d
NC
21280
21281 name = get_archive_member_name (&arch, &nested_arch);
21282 if (name == NULL)
fb52b2f4 21283 {
28e817cc 21284 error (_("%s: bad archive file name\n"), arch.file_name);
32ec8896 21285 ret = FALSE;
d989285c 21286 break;
fb52b2f4 21287 }
2cf0635d 21288 namelen = strlen (name);
fb52b2f4 21289
2cf0635d
NC
21290 qualified_name = make_qualified_name (&arch, &nested_arch, name);
21291 if (qualified_name == NULL)
fb52b2f4 21292 {
28e817cc 21293 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 21294 free (name);
32ec8896 21295 ret = FALSE;
d989285c 21296 break;
fb52b2f4
NC
21297 }
21298
2cf0635d 21299 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
21300 {
21301 /* This is a proxy for an external member of a thin archive. */
21302 Filedata * member_filedata;
21303 char * member_file_name = adjust_relative_path
dda8d76d 21304 (filedata->file_name, name, namelen);
32ec8896 21305
fd486f32 21306 free (name);
1cb7d8b1
AM
21307 if (member_file_name == NULL)
21308 {
fd486f32 21309 free (qualified_name);
1cb7d8b1
AM
21310 ret = FALSE;
21311 break;
21312 }
2cf0635d 21313
1cb7d8b1
AM
21314 member_filedata = open_file (member_file_name);
21315 if (member_filedata == NULL)
21316 {
21317 error (_("Input file '%s' is not readable.\n"), member_file_name);
21318 free (member_file_name);
fd486f32 21319 free (qualified_name);
1cb7d8b1
AM
21320 ret = FALSE;
21321 break;
21322 }
2cf0635d 21323
978c4450 21324 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 21325 member_filedata->file_name = qualified_name;
2cf0635d 21326
1cb7d8b1 21327 if (! process_object (member_filedata))
32ec8896 21328 ret = FALSE;
2cf0635d 21329
1cb7d8b1
AM
21330 close_file (member_filedata);
21331 free (member_file_name);
1cb7d8b1 21332 }
2cf0635d 21333 else if (is_thin_archive)
1cb7d8b1
AM
21334 {
21335 Filedata thin_filedata;
eb02c04d 21336
1cb7d8b1 21337 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 21338
a043396b
NC
21339 /* PR 15140: Allow for corrupt thin archives. */
21340 if (nested_arch.file == NULL)
21341 {
21342 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 21343 qualified_name, name);
fd486f32
AM
21344 free (qualified_name);
21345 free (name);
32ec8896 21346 ret = FALSE;
a043396b
NC
21347 break;
21348 }
fd486f32 21349 free (name);
a043396b 21350
1cb7d8b1 21351 /* This is a proxy for a member of a nested archive. */
978c4450
AM
21352 filedata->archive_file_offset
21353 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 21354
1cb7d8b1
AM
21355 /* The nested archive file will have been opened and setup by
21356 get_archive_member_name. */
978c4450
AM
21357 if (fseek (nested_arch.file, filedata->archive_file_offset,
21358 SEEK_SET) != 0)
1cb7d8b1
AM
21359 {
21360 error (_("%s: failed to seek to archive member.\n"),
21361 nested_arch.file_name);
fd486f32 21362 free (qualified_name);
1cb7d8b1
AM
21363 ret = FALSE;
21364 break;
21365 }
2cf0635d 21366
dda8d76d
NC
21367 thin_filedata.handle = nested_arch.file;
21368 thin_filedata.file_name = qualified_name;
9abca702 21369
1cb7d8b1 21370 if (! process_object (& thin_filedata))
32ec8896 21371 ret = FALSE;
1cb7d8b1 21372 }
2cf0635d 21373 else
1cb7d8b1 21374 {
fd486f32 21375 free (name);
978c4450 21376 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 21377 filedata->file_name = qualified_name;
1cb7d8b1 21378 if (! process_object (filedata))
32ec8896 21379 ret = FALSE;
978c4450 21380 arch.next_arhdr_offset += filedata->archive_file_size;
4c836627 21381 /* Stop looping with "negative" archive_file_size. */
978c4450 21382 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 21383 arch.next_arhdr_offset = -1ul;
1cb7d8b1 21384 }
fb52b2f4 21385
2cf0635d 21386 free (qualified_name);
fb52b2f4
NC
21387 }
21388
4145f1d5 21389 out:
2cf0635d
NC
21390 if (nested_arch.file != NULL)
21391 fclose (nested_arch.file);
21392 release_archive (&nested_arch);
21393 release_archive (&arch);
fb52b2f4 21394
d989285c 21395 return ret;
fb52b2f4
NC
21396}
21397
32ec8896 21398static bfd_boolean
2cf0635d 21399process_file (char * file_name)
fb52b2f4 21400{
dda8d76d 21401 Filedata * filedata = NULL;
fb52b2f4
NC
21402 struct stat statbuf;
21403 char armag[SARMAG];
32ec8896 21404 bfd_boolean ret = TRUE;
fb52b2f4
NC
21405
21406 if (stat (file_name, &statbuf) < 0)
21407 {
f24ddbdd
NC
21408 if (errno == ENOENT)
21409 error (_("'%s': No such file\n"), file_name);
21410 else
21411 error (_("Could not locate '%s'. System error message: %s\n"),
21412 file_name, strerror (errno));
32ec8896 21413 return FALSE;
f24ddbdd
NC
21414 }
21415
21416 if (! S_ISREG (statbuf.st_mode))
21417 {
21418 error (_("'%s' is not an ordinary file\n"), file_name);
32ec8896 21419 return FALSE;
fb52b2f4
NC
21420 }
21421
dda8d76d
NC
21422 filedata = calloc (1, sizeof * filedata);
21423 if (filedata == NULL)
21424 {
21425 error (_("Out of memory allocating file data structure\n"));
21426 return FALSE;
21427 }
21428
21429 filedata->file_name = file_name;
21430 filedata->handle = fopen (file_name, "rb");
21431 if (filedata->handle == NULL)
fb52b2f4 21432 {
f24ddbdd 21433 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 21434 free (filedata);
32ec8896 21435 return FALSE;
fb52b2f4
NC
21436 }
21437
dda8d76d 21438 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 21439 {
4145f1d5 21440 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
21441 fclose (filedata->handle);
21442 free (filedata);
32ec8896 21443 return FALSE;
fb52b2f4
NC
21444 }
21445
dda8d76d 21446 filedata->file_size = (bfd_size_type) statbuf.st_size;
f54498b4 21447
fb52b2f4 21448 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 21449 {
dda8d76d 21450 if (! process_archive (filedata, FALSE))
32ec8896
NC
21451 ret = FALSE;
21452 }
2cf0635d 21453 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 21454 {
dda8d76d 21455 if ( ! process_archive (filedata, TRUE))
32ec8896
NC
21456 ret = FALSE;
21457 }
fb52b2f4
NC
21458 else
21459 {
1b513401 21460 if (do_archive_index && !check_all)
4145f1d5
NC
21461 error (_("File %s is not an archive so its index cannot be displayed.\n"),
21462 file_name);
21463
dda8d76d 21464 rewind (filedata->handle);
978c4450 21465 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 21466
dda8d76d 21467 if (! process_object (filedata))
32ec8896 21468 ret = FALSE;
fb52b2f4
NC
21469 }
21470
dda8d76d 21471 fclose (filedata->handle);
8fb879cd
AM
21472 free (filedata->section_headers);
21473 free (filedata->program_headers);
21474 free (filedata->string_table);
6431e409 21475 free (filedata->dump.dump_sects);
dda8d76d 21476 free (filedata);
32ec8896 21477
fd486f32 21478 free (ba_cache.strtab);
1bd6175a 21479 ba_cache.strtab = NULL;
fd486f32 21480 free (ba_cache.symtab);
1bd6175a 21481 ba_cache.symtab = NULL;
fd486f32
AM
21482 ba_cache.filedata = NULL;
21483
fb52b2f4
NC
21484 return ret;
21485}
21486
252b5132
RH
21487#ifdef SUPPORT_DISASSEMBLY
21488/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 21489 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 21490 symbols. */
252b5132
RH
21491
21492void
2cf0635d 21493print_address (unsigned int addr, FILE * outfile)
252b5132
RH
21494{
21495 fprintf (outfile,"0x%8.8x", addr);
21496}
21497
e3c8793a 21498/* Needed by the i386 disassembler. */
dda8d76d 21499
252b5132
RH
21500void
21501db_task_printsym (unsigned int addr)
21502{
21503 print_address (addr, stderr);
21504}
21505#endif
21506
21507int
2cf0635d 21508main (int argc, char ** argv)
252b5132 21509{
ff78d6d6
L
21510 int err;
21511
252b5132
RH
21512#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
21513 setlocale (LC_MESSAGES, "");
3882b010
L
21514#endif
21515#if defined (HAVE_SETLOCALE)
21516 setlocale (LC_CTYPE, "");
252b5132
RH
21517#endif
21518 bindtextdomain (PACKAGE, LOCALEDIR);
21519 textdomain (PACKAGE);
21520
869b9d07
MM
21521 expandargv (&argc, &argv);
21522
dda8d76d 21523 parse_args (& cmdline, argc, argv);
59f14fc0 21524
18bd398b 21525 if (optind < (argc - 1))
1b513401
NC
21526 /* When displaying information for more than one file,
21527 prefix the information with the file name. */
32ec8896 21528 show_name = TRUE;
5656ba2c
L
21529 else if (optind >= argc)
21530 {
1b513401
NC
21531 /* Ensure that the warning is always displayed. */
21532 do_checks = TRUE;
21533
5656ba2c
L
21534 warn (_("Nothing to do.\n"));
21535 usage (stderr);
21536 }
18bd398b 21537
32ec8896 21538 err = FALSE;
252b5132 21539 while (optind < argc)
32ec8896
NC
21540 if (! process_file (argv[optind++]))
21541 err = TRUE;
252b5132 21542
9db70fc3 21543 free (cmdline.dump_sects);
252b5132 21544
7d9813f1
NA
21545 free (dump_ctf_symtab_name);
21546 free (dump_ctf_strtab_name);
21547 free (dump_ctf_parent_name);
21548
32ec8896 21549 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 21550}