]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
OpenRISC BFD fixups for Glibc:
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
b3adc24a 2 Copyright (C) 1998-2020 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056 46#include <zlib.h>
3bfcb652 47#ifdef HAVE_WCHAR_H
7bfd842d 48#include <wchar.h>
3bfcb652 49#endif
252b5132 50
a952a375 51#if __GNUC__ >= 2
19936277 52/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 53 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 54 Only do this if we believe that the compiler can support a 64 bit
a952a375 55 data type. For now we only rely on GCC being able to do this. */
19936277 56#define BFD64
a952a375
NC
57#endif
58
3db64b00
AM
59#include "bfd.h"
60#include "bucomm.h"
3284fe0c 61#include "elfcomm.h"
19e6b90e 62#include "dwarf.h"
7d9813f1 63#include "ctf-api.h"
252b5132
RH
64
65#include "elf/common.h"
66#include "elf/external.h"
67#include "elf/internal.h"
252b5132 68
4b78141a
NC
69
70/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
71 we can obtain the H8 reloc numbers. We need these for the
72 get_reloc_size() function. We include h8.h again after defining
73 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
74
75#include "elf/h8.h"
76#undef _ELF_H8_H
77
78/* Undo the effects of #including reloc-macros.h. */
79
80#undef START_RELOC_NUMBERS
81#undef RELOC_NUMBER
82#undef FAKE_RELOC
83#undef EMPTY_RELOC
84#undef END_RELOC_NUMBERS
85#undef _RELOC_MACROS_H
86
252b5132
RH
87/* The following headers use the elf/reloc-macros.h file to
88 automatically generate relocation recognition functions
89 such as elf_mips_reloc_type() */
90
91#define RELOC_MACROS_GEN_FUNC
92
a06ea964 93#include "elf/aarch64.h"
252b5132 94#include "elf/alpha.h"
3b16e843 95#include "elf/arc.h"
252b5132 96#include "elf/arm.h"
3b16e843 97#include "elf/avr.h"
1d65ded4 98#include "elf/bfin.h"
60bca95a 99#include "elf/cr16.h"
3b16e843 100#include "elf/cris.h"
1c0d3aa6 101#include "elf/crx.h"
b8891f8d 102#include "elf/csky.h"
252b5132
RH
103#include "elf/d10v.h"
104#include "elf/d30v.h"
d172d4ba 105#include "elf/dlx.h"
aca4efc7 106#include "elf/bpf.h"
cfb8c092 107#include "elf/epiphany.h"
252b5132 108#include "elf/fr30.h"
5c70f934 109#include "elf/frv.h"
3f8107ab 110#include "elf/ft32.h"
3b16e843
NC
111#include "elf/h8.h"
112#include "elf/hppa.h"
113#include "elf/i386.h"
f954747f
AM
114#include "elf/i370.h"
115#include "elf/i860.h"
116#include "elf/i960.h"
3b16e843 117#include "elf/ia64.h"
1e4cf259 118#include "elf/ip2k.h"
84e94c90 119#include "elf/lm32.h"
1c0d3aa6 120#include "elf/iq2000.h"
49f58d10 121#include "elf/m32c.h"
3b16e843
NC
122#include "elf/m32r.h"
123#include "elf/m68k.h"
75751cd9 124#include "elf/m68hc11.h"
7b4ae824 125#include "elf/s12z.h"
252b5132 126#include "elf/mcore.h"
15ab5209 127#include "elf/mep.h"
a3c62988 128#include "elf/metag.h"
7ba29e2a 129#include "elf/microblaze.h"
3b16e843 130#include "elf/mips.h"
3c3bdf30 131#include "elf/mmix.h"
3b16e843
NC
132#include "elf/mn10200.h"
133#include "elf/mn10300.h"
5506d11a 134#include "elf/moxie.h"
4970f871 135#include "elf/mt.h"
2469cfa2 136#include "elf/msp430.h"
35c08157 137#include "elf/nds32.h"
fe944acf 138#include "elf/nfp.h"
13761a11 139#include "elf/nios2.h"
73589c9d 140#include "elf/or1k.h"
7d466069 141#include "elf/pj.h"
3b16e843 142#include "elf/ppc.h"
c833c019 143#include "elf/ppc64.h"
2b100bb5 144#include "elf/pru.h"
03336641 145#include "elf/riscv.h"
99c513f6 146#include "elf/rl78.h"
c7927a3c 147#include "elf/rx.h"
a85d7ed0 148#include "elf/s390.h"
1c0d3aa6 149#include "elf/score.h"
3b16e843
NC
150#include "elf/sh.h"
151#include "elf/sparc.h"
e9f53129 152#include "elf/spu.h"
40b36596 153#include "elf/tic6x.h"
aa137e4d
NC
154#include "elf/tilegx.h"
155#include "elf/tilepro.h"
3b16e843 156#include "elf/v850.h"
179d3252 157#include "elf/vax.h"
619ed720 158#include "elf/visium.h"
f96bd6c2 159#include "elf/wasm32.h"
3b16e843 160#include "elf/x86-64.h"
c29aca4a 161#include "elf/xc16x.h"
f6c1a2d5 162#include "elf/xgate.h"
93fbbb04 163#include "elf/xstormy16.h"
88da6820 164#include "elf/xtensa.h"
6655dba2 165#include "elf/z80.h"
252b5132 166
252b5132 167#include "getopt.h"
566b0d53 168#include "libiberty.h"
09c11c86 169#include "safe-ctype.h"
2cf0635d 170#include "filenames.h"
252b5132 171
15b42fb0
AM
172#ifndef offsetof
173#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
174#endif
175
6a40cf0c
NC
176typedef struct elf_section_list
177{
dda8d76d
NC
178 Elf_Internal_Shdr * hdr;
179 struct elf_section_list * next;
6a40cf0c
NC
180} elf_section_list;
181
dda8d76d
NC
182/* Flag bits indicating particular types of dump. */
183#define HEX_DUMP (1 << 0) /* The -x command line switch. */
184#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
185#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
186#define STRING_DUMP (1 << 3) /* The -p command line switch. */
187#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 188#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
189
190typedef unsigned char dump_type;
191
192/* A linked list of the section names for which dumps were requested. */
193struct dump_list_entry
194{
195 char * name;
196 dump_type type;
197 struct dump_list_entry * next;
198};
199
6431e409
AM
200/* A dynamic array of flags indicating for which sections a dump
201 has been requested via command line switches. */
1b513401
NC
202struct dump_data
203{
6431e409
AM
204 dump_type * dump_sects;
205 unsigned int num_dump_sects;
206};
207
208static struct dump_data cmdline;
209
210static struct dump_list_entry * dump_sects_byname;
211
2cf0635d 212char * program_name = "readelf";
dda8d76d 213
32ec8896
NC
214static bfd_boolean show_name = FALSE;
215static bfd_boolean do_dynamic = FALSE;
216static bfd_boolean do_syms = FALSE;
217static bfd_boolean do_dyn_syms = FALSE;
218static bfd_boolean do_reloc = FALSE;
219static bfd_boolean do_sections = FALSE;
220static bfd_boolean do_section_groups = FALSE;
221static bfd_boolean do_section_details = FALSE;
222static bfd_boolean do_segments = FALSE;
223static bfd_boolean do_unwind = FALSE;
224static bfd_boolean do_using_dynamic = FALSE;
225static bfd_boolean do_header = FALSE;
226static bfd_boolean do_dump = FALSE;
227static bfd_boolean do_version = FALSE;
228static bfd_boolean do_histogram = FALSE;
229static bfd_boolean do_debugging = FALSE;
7d9813f1 230static bfd_boolean do_ctf = FALSE;
32ec8896
NC
231static bfd_boolean do_arch = FALSE;
232static bfd_boolean do_notes = FALSE;
233static bfd_boolean do_archive_index = FALSE;
1b513401 234static bfd_boolean check_all = FALSE;
32ec8896
NC
235static bfd_boolean is_32bit_elf = FALSE;
236static bfd_boolean decompress_dumps = FALSE;
252b5132 237
7d9813f1
NA
238static char *dump_ctf_parent_name;
239static char *dump_ctf_symtab_name;
240static char *dump_ctf_strtab_name;
241
e4b17d5c
L
242struct group_list
243{
dda8d76d
NC
244 struct group_list * next;
245 unsigned int section_index;
e4b17d5c
L
246};
247
248struct group
249{
dda8d76d
NC
250 struct group_list * root;
251 unsigned int group_index;
e4b17d5c
L
252};
253
978c4450
AM
254typedef struct filedata
255{
256 const char * file_name;
257 FILE * handle;
258 bfd_size_type file_size;
259 Elf_Internal_Ehdr file_header;
260 Elf_Internal_Shdr * section_headers;
261 Elf_Internal_Phdr * program_headers;
262 char * string_table;
263 unsigned long string_table_length;
264 unsigned long archive_file_offset;
265 unsigned long archive_file_size;
266 unsigned long dynamic_addr;
267 bfd_size_type dynamic_size;
268 size_t dynamic_nent;
269 Elf_Internal_Dyn * dynamic_section;
270 char * dynamic_strings;
271 unsigned long dynamic_strings_length;
272 unsigned long num_dynamic_syms;
273 Elf_Internal_Sym * dynamic_symbols;
274 bfd_vma version_info[16];
275 unsigned int dynamic_syminfo_nent;
276 Elf_Internal_Syminfo * dynamic_syminfo;
277 unsigned long dynamic_syminfo_offset;
278 bfd_size_type nbuckets;
279 bfd_size_type nchains;
280 bfd_vma * buckets;
281 bfd_vma * chains;
282 bfd_size_type ngnubuckets;
283 bfd_size_type ngnuchains;
284 bfd_vma * gnubuckets;
285 bfd_vma * gnuchains;
286 bfd_vma * mipsxlat;
287 bfd_vma gnusymidx;
288 char program_interpreter[PATH_MAX];
289 bfd_vma dynamic_info[DT_ENCODING];
290 bfd_vma dynamic_info_DT_GNU_HASH;
291 bfd_vma dynamic_info_DT_MIPS_XHASH;
292 elf_section_list * symtab_shndx_list;
293 size_t group_count;
294 struct group * section_groups;
295 struct group ** section_headers_groups;
296 /* A dynamic array of flags indicating for which sections a dump of
297 some kind has been requested. It is reset on a per-object file
298 basis and then initialised from the cmdline_dump_sects array,
299 the results of interpreting the -w switch, and the
300 dump_sects_byname list. */
301 struct dump_data dump;
302} Filedata;
aef1f6d0 303
c256ffe7 304/* How to print a vma value. */
843dd992
NC
305typedef enum print_mode
306{
307 HEX,
308 DEC,
309 DEC_5,
310 UNSIGNED,
311 PREFIX_HEX,
312 FULL_HEX,
313 LONG_HEX
314}
315print_mode;
316
bb4d2ac2
L
317/* Versioned symbol info. */
318enum versioned_symbol_info
319{
320 symbol_undefined,
321 symbol_hidden,
322 symbol_public
323};
324
32ec8896 325static const char * get_symbol_version_string
dda8d76d 326 (Filedata *, bfd_boolean, const char *, unsigned long, unsigned,
32ec8896 327 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 328
9c19a809
NC
329#define UNKNOWN -1
330
2b692964
NC
331#define SECTION_NAME(X) \
332 ((X) == NULL ? _("<none>") \
dda8d76d
NC
333 : filedata->string_table == NULL ? _("<no-strings>") \
334 : ((X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
335 : filedata->string_table + (X)->sh_name))
252b5132 336
ee42cf8c 337#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 338
ba5cdace
NC
339#define GET_ELF_SYMBOLS(file, section, sym_count) \
340 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
341 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 342
10ca4b04
L
343#define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
344 (strtab != NULL && offset < strtab_size)
978c4450
AM
345#define VALID_DYNAMIC_NAME(filedata, offset) \
346 VALID_SYMBOL_NAME (filedata->dynamic_strings, \
347 filedata->dynamic_strings_length, offset)
d79b3d50
NC
348/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
349 already been called and verified that the string exists. */
978c4450
AM
350#define GET_DYNAMIC_NAME(filedata, offset) \
351 (filedata->dynamic_strings + offset)
18bd398b 352
61865e30
NC
353#define REMOVE_ARCH_BITS(ADDR) \
354 do \
355 { \
dda8d76d 356 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
357 (ADDR) &= ~1; \
358 } \
359 while (0)
f16a9783
MS
360
361/* Get the correct GNU hash section name. */
978c4450
AM
362#define GNU_HASH_SECTION_NAME(filedata) \
363 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 364\f
66cfc0fd
AM
365/* Print a BFD_VMA to an internal buffer, for use in error messages.
366 BFD_FMA_FMT can't be used in translated strings. */
367
368static const char *
369bfd_vmatoa (char *fmtch, bfd_vma value)
370{
371 /* bfd_vmatoa is used more then once in a printf call for output.
372 Cycle through an array of buffers. */
373 static int buf_pos = 0;
374 static struct bfd_vmatoa_buf
375 {
376 char place[64];
377 } buf[4];
378 char *ret;
379 char fmt[32];
380
381 ret = buf[buf_pos++].place;
382 buf_pos %= ARRAY_SIZE (buf);
383
384 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
385 snprintf (ret, sizeof (buf[0].place), fmt, value);
386 return ret;
387}
388
dda8d76d
NC
389/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
390 OFFSET + the offset of the current archive member, if we are examining an
391 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
392 allocate a buffer using malloc and fill that. In either case return the
393 pointer to the start of the retrieved data or NULL if something went wrong.
394 If something does go wrong and REASON is not NULL then emit an error
395 message using REASON as part of the context. */
59245841 396
c256ffe7 397static void *
dda8d76d
NC
398get_data (void * var,
399 Filedata * filedata,
400 unsigned long offset,
401 bfd_size_type size,
402 bfd_size_type nmemb,
403 const char * reason)
a6e9f9df 404{
2cf0635d 405 void * mvar;
57028622 406 bfd_size_type amt = size * nmemb;
a6e9f9df 407
c256ffe7 408 if (size == 0 || nmemb == 0)
a6e9f9df
AM
409 return NULL;
410
57028622
NC
411 /* If the size_t type is smaller than the bfd_size_type, eg because
412 you are building a 32-bit tool on a 64-bit host, then make sure
413 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
414 if ((size_t) size != size
415 || (size_t) nmemb != nmemb
416 || (size_t) amt != amt)
57028622
NC
417 {
418 if (reason)
66cfc0fd
AM
419 error (_("Size truncation prevents reading %s"
420 " elements of size %s for %s\n"),
421 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
422 return NULL;
423 }
424
425 /* Check for size overflow. */
7c1c1904 426 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
427 {
428 if (reason)
66cfc0fd
AM
429 error (_("Size overflow prevents reading %s"
430 " elements of size %s for %s\n"),
431 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
432 return NULL;
433 }
434
c22b42ce 435 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 436 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
437 if (filedata->archive_file_offset > filedata->file_size
438 || offset > filedata->file_size - filedata->archive_file_offset
439 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 440 {
049b0c3a 441 if (reason)
66cfc0fd
AM
442 error (_("Reading %s bytes extends past end of file for %s\n"),
443 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
444 return NULL;
445 }
446
978c4450
AM
447 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
448 SEEK_SET))
071436c6
NC
449 {
450 if (reason)
c9c1d674 451 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 452 filedata->archive_file_offset + offset, reason);
071436c6
NC
453 return NULL;
454 }
455
a6e9f9df
AM
456 mvar = var;
457 if (mvar == NULL)
458 {
7c1c1904
AM
459 /* + 1 so that we can '\0' terminate invalid string table sections. */
460 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
461
462 if (mvar == NULL)
463 {
049b0c3a 464 if (reason)
66cfc0fd
AM
465 error (_("Out of memory allocating %s bytes for %s\n"),
466 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
467 return NULL;
468 }
c256ffe7 469
c9c1d674 470 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
471 }
472
dda8d76d 473 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 474 {
049b0c3a 475 if (reason)
66cfc0fd
AM
476 error (_("Unable to read in %s bytes of %s\n"),
477 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
478 if (mvar != var)
479 free (mvar);
480 return NULL;
481 }
482
483 return mvar;
484}
485
32ec8896
NC
486/* Print a VMA value in the MODE specified.
487 Returns the number of characters displayed. */
cb8f3167 488
32ec8896 489static unsigned int
14a91970 490print_vma (bfd_vma vma, print_mode mode)
66543521 491{
32ec8896 492 unsigned int nc = 0;
66543521 493
14a91970 494 switch (mode)
66543521 495 {
14a91970
AM
496 case FULL_HEX:
497 nc = printf ("0x");
1a0670f3 498 /* Fall through. */
14a91970 499 case LONG_HEX:
f7a99963 500#ifdef BFD64
14a91970 501 if (is_32bit_elf)
437c2fb7 502 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 503#endif
14a91970
AM
504 printf_vma (vma);
505 return nc + 16;
b19aac67 506
14a91970
AM
507 case DEC_5:
508 if (vma <= 99999)
509 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 510 /* Fall through. */
14a91970
AM
511 case PREFIX_HEX:
512 nc = printf ("0x");
1a0670f3 513 /* Fall through. */
14a91970
AM
514 case HEX:
515 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 516
14a91970
AM
517 case DEC:
518 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 519
14a91970
AM
520 case UNSIGNED:
521 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896
NC
522
523 default:
524 /* FIXME: Report unrecognised mode ? */
525 return 0;
f7a99963 526 }
f7a99963
NC
527}
528
7bfd842d 529/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 530 multibye characters (assuming the host environment supports them).
31104126 531
7bfd842d
NC
532 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
533
534 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
535 padding as necessary.
171191ba
NC
536
537 Returns the number of emitted characters. */
538
539static unsigned int
32ec8896 540print_symbol (signed int width, const char *symbol)
31104126 541{
171191ba 542 bfd_boolean extra_padding = FALSE;
32ec8896 543 signed int num_printed = 0;
3bfcb652 544#ifdef HAVE_MBSTATE_T
7bfd842d 545 mbstate_t state;
3bfcb652 546#endif
32ec8896 547 unsigned int width_remaining;
961c521f 548
7bfd842d 549 if (width < 0)
961c521f 550 {
88305e1b 551 /* Keep the width positive. This helps the code below. */
961c521f 552 width = - width;
171191ba 553 extra_padding = TRUE;
0b4362b0 554 }
56d8f8a9
NC
555 else if (width == 0)
556 return 0;
961c521f 557
7bfd842d
NC
558 if (do_wide)
559 /* Set the remaining width to a very large value.
560 This simplifies the code below. */
561 width_remaining = INT_MAX;
562 else
563 width_remaining = width;
cb8f3167 564
3bfcb652 565#ifdef HAVE_MBSTATE_T
7bfd842d
NC
566 /* Initialise the multibyte conversion state. */
567 memset (& state, 0, sizeof (state));
3bfcb652 568#endif
961c521f 569
7bfd842d
NC
570 while (width_remaining)
571 {
572 size_t n;
7bfd842d 573 const char c = *symbol++;
961c521f 574
7bfd842d 575 if (c == 0)
961c521f
NC
576 break;
577
7bfd842d
NC
578 /* Do not print control characters directly as they can affect terminal
579 settings. Such characters usually appear in the names generated
580 by the assembler for local labels. */
581 if (ISCNTRL (c))
961c521f 582 {
7bfd842d 583 if (width_remaining < 2)
961c521f
NC
584 break;
585
7bfd842d
NC
586 printf ("^%c", c + 0x40);
587 width_remaining -= 2;
171191ba 588 num_printed += 2;
961c521f 589 }
7bfd842d
NC
590 else if (ISPRINT (c))
591 {
592 putchar (c);
593 width_remaining --;
594 num_printed ++;
595 }
961c521f
NC
596 else
597 {
3bfcb652
NC
598#ifdef HAVE_MBSTATE_T
599 wchar_t w;
600#endif
7bfd842d
NC
601 /* Let printf do the hard work of displaying multibyte characters. */
602 printf ("%.1s", symbol - 1);
603 width_remaining --;
604 num_printed ++;
605
3bfcb652 606#ifdef HAVE_MBSTATE_T
7bfd842d
NC
607 /* Try to find out how many bytes made up the character that was
608 just printed. Advance the symbol pointer past the bytes that
609 were displayed. */
610 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
611#else
612 n = 1;
613#endif
7bfd842d
NC
614 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
615 symbol += (n - 1);
961c521f 616 }
961c521f 617 }
171191ba 618
7bfd842d 619 if (extra_padding && num_printed < width)
171191ba
NC
620 {
621 /* Fill in the remaining spaces. */
7bfd842d
NC
622 printf ("%-*s", width - num_printed, " ");
623 num_printed = width;
171191ba
NC
624 }
625
626 return num_printed;
31104126
NC
627}
628
1449284b 629/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
630 the given section's name. Like print_symbol, except that it does not try
631 to print multibyte characters, it just interprets them as hex values. */
632
633static const char *
dda8d76d 634printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b
NC
635{
636#define MAX_PRINT_SEC_NAME_LEN 128
637 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
638 const char * name = SECTION_NAME (sec);
639 char * buf = sec_name_buf;
640 char c;
641 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
642
643 while ((c = * name ++) != 0)
644 {
645 if (ISCNTRL (c))
646 {
647 if (remaining < 2)
648 break;
948f632f 649
74e1a04b
NC
650 * buf ++ = '^';
651 * buf ++ = c + 0x40;
652 remaining -= 2;
653 }
654 else if (ISPRINT (c))
655 {
656 * buf ++ = c;
657 remaining -= 1;
658 }
659 else
660 {
661 static char hex[17] = "0123456789ABCDEF";
662
663 if (remaining < 4)
664 break;
665 * buf ++ = '<';
666 * buf ++ = hex[(c & 0xf0) >> 4];
667 * buf ++ = hex[c & 0x0f];
668 * buf ++ = '>';
669 remaining -= 4;
670 }
671
672 if (remaining == 0)
673 break;
674 }
675
676 * buf = 0;
677 return sec_name_buf;
678}
679
680static const char *
dda8d76d 681printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 682{
dda8d76d 683 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
684 return _("<corrupt>");
685
dda8d76d 686 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
687}
688
89fac5e3
RS
689/* Return a pointer to section NAME, or NULL if no such section exists. */
690
691static Elf_Internal_Shdr *
dda8d76d 692find_section (Filedata * filedata, const char * name)
89fac5e3
RS
693{
694 unsigned int i;
695
68807c3c
NC
696 if (filedata->section_headers == NULL)
697 return NULL;
dda8d76d
NC
698
699 for (i = 0; i < filedata->file_header.e_shnum; i++)
700 if (streq (SECTION_NAME (filedata->section_headers + i), name))
701 return filedata->section_headers + i;
89fac5e3
RS
702
703 return NULL;
704}
705
0b6ae522
DJ
706/* Return a pointer to a section containing ADDR, or NULL if no such
707 section exists. */
708
709static Elf_Internal_Shdr *
dda8d76d 710find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
711{
712 unsigned int i;
713
68807c3c
NC
714 if (filedata->section_headers == NULL)
715 return NULL;
716
dda8d76d 717 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 718 {
dda8d76d
NC
719 Elf_Internal_Shdr *sec = filedata->section_headers + i;
720
0b6ae522
DJ
721 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
722 return sec;
723 }
724
725 return NULL;
726}
727
071436c6 728static Elf_Internal_Shdr *
dda8d76d 729find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
730{
731 unsigned int i;
732
68807c3c
NC
733 if (filedata->section_headers == NULL)
734 return NULL;
735
dda8d76d 736 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 737 {
dda8d76d
NC
738 Elf_Internal_Shdr *sec = filedata->section_headers + i;
739
071436c6
NC
740 if (sec->sh_type == type)
741 return sec;
742 }
743
744 return NULL;
745}
746
657d0d47
CC
747/* Return a pointer to section NAME, or NULL if no such section exists,
748 restricted to the list of sections given in SET. */
749
750static Elf_Internal_Shdr *
dda8d76d 751find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
752{
753 unsigned int i;
754
68807c3c
NC
755 if (filedata->section_headers == NULL)
756 return NULL;
757
657d0d47
CC
758 if (set != NULL)
759 {
760 while ((i = *set++) > 0)
b814a36d
NC
761 {
762 /* See PR 21156 for a reproducer. */
dda8d76d 763 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
764 continue; /* FIXME: Should we issue an error message ? */
765
dda8d76d
NC
766 if (streq (SECTION_NAME (filedata->section_headers + i), name))
767 return filedata->section_headers + i;
b814a36d 768 }
657d0d47
CC
769 }
770
dda8d76d 771 return find_section (filedata, name);
657d0d47
CC
772}
773
32ec8896 774/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
775 This OS has so many departures from the ELF standard that we test it at
776 many places. */
777
32ec8896 778static inline bfd_boolean
dda8d76d 779is_ia64_vms (Filedata * filedata)
28f997cf 780{
dda8d76d
NC
781 return filedata->file_header.e_machine == EM_IA_64
782 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
783}
784
bcedfee6 785/* Guess the relocation size commonly used by the specific machines. */
252b5132 786
32ec8896 787static bfd_boolean
2dc4cec1 788guess_is_rela (unsigned int e_machine)
252b5132 789{
9c19a809 790 switch (e_machine)
252b5132
RH
791 {
792 /* Targets that use REL relocations. */
252b5132 793 case EM_386:
22abe556 794 case EM_IAMCU:
f954747f 795 case EM_960:
e9f53129 796 case EM_ARM:
2b0337b0 797 case EM_D10V:
252b5132 798 case EM_CYGNUS_D10V:
e9f53129 799 case EM_DLX:
252b5132 800 case EM_MIPS:
4fe85591 801 case EM_MIPS_RS3_LE:
e9f53129 802 case EM_CYGNUS_M32R:
1c0d3aa6 803 case EM_SCORE:
f6c1a2d5 804 case EM_XGATE:
fe944acf 805 case EM_NFP:
aca4efc7 806 case EM_BPF:
9c19a809 807 return FALSE;
103f02d3 808
252b5132
RH
809 /* Targets that use RELA relocations. */
810 case EM_68K:
f954747f 811 case EM_860:
a06ea964 812 case EM_AARCH64:
cfb8c092 813 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
814 case EM_ALPHA:
815 case EM_ALTERA_NIOS2:
886a2506
NC
816 case EM_ARC:
817 case EM_ARC_COMPACT:
818 case EM_ARC_COMPACT2:
e9f53129
AM
819 case EM_AVR:
820 case EM_AVR_OLD:
821 case EM_BLACKFIN:
60bca95a 822 case EM_CR16:
e9f53129
AM
823 case EM_CRIS:
824 case EM_CRX:
b8891f8d 825 case EM_CSKY:
2b0337b0 826 case EM_D30V:
252b5132 827 case EM_CYGNUS_D30V:
2b0337b0 828 case EM_FR30:
3f8107ab 829 case EM_FT32:
252b5132 830 case EM_CYGNUS_FR30:
5c70f934 831 case EM_CYGNUS_FRV:
e9f53129
AM
832 case EM_H8S:
833 case EM_H8_300:
834 case EM_H8_300H:
800eeca4 835 case EM_IA_64:
1e4cf259
NC
836 case EM_IP2K:
837 case EM_IP2K_OLD:
3b36097d 838 case EM_IQ2000:
84e94c90 839 case EM_LATTICEMICO32:
ff7eeb89 840 case EM_M32C_OLD:
49f58d10 841 case EM_M32C:
e9f53129
AM
842 case EM_M32R:
843 case EM_MCORE:
15ab5209 844 case EM_CYGNUS_MEP:
a3c62988 845 case EM_METAG:
e9f53129
AM
846 case EM_MMIX:
847 case EM_MN10200:
848 case EM_CYGNUS_MN10200:
849 case EM_MN10300:
850 case EM_CYGNUS_MN10300:
5506d11a 851 case EM_MOXIE:
e9f53129
AM
852 case EM_MSP430:
853 case EM_MSP430_OLD:
d031aafb 854 case EM_MT:
35c08157 855 case EM_NDS32:
64fd6348 856 case EM_NIOS32:
73589c9d 857 case EM_OR1K:
e9f53129
AM
858 case EM_PPC64:
859 case EM_PPC:
2b100bb5 860 case EM_TI_PRU:
e23eba97 861 case EM_RISCV:
99c513f6 862 case EM_RL78:
c7927a3c 863 case EM_RX:
e9f53129
AM
864 case EM_S390:
865 case EM_S390_OLD:
866 case EM_SH:
867 case EM_SPARC:
868 case EM_SPARC32PLUS:
869 case EM_SPARCV9:
870 case EM_SPU:
40b36596 871 case EM_TI_C6000:
aa137e4d
NC
872 case EM_TILEGX:
873 case EM_TILEPRO:
708e2187 874 case EM_V800:
e9f53129
AM
875 case EM_V850:
876 case EM_CYGNUS_V850:
877 case EM_VAX:
619ed720 878 case EM_VISIUM:
e9f53129 879 case EM_X86_64:
8a9036a4 880 case EM_L1OM:
7a9068fe 881 case EM_K1OM:
e9f53129
AM
882 case EM_XSTORMY16:
883 case EM_XTENSA:
884 case EM_XTENSA_OLD:
7ba29e2a
NC
885 case EM_MICROBLAZE:
886 case EM_MICROBLAZE_OLD:
f96bd6c2 887 case EM_WEBASSEMBLY:
9c19a809 888 return TRUE;
103f02d3 889
e9f53129
AM
890 case EM_68HC05:
891 case EM_68HC08:
892 case EM_68HC11:
893 case EM_68HC16:
894 case EM_FX66:
895 case EM_ME16:
d1133906 896 case EM_MMA:
d1133906
NC
897 case EM_NCPU:
898 case EM_NDR1:
e9f53129 899 case EM_PCP:
d1133906 900 case EM_ST100:
e9f53129 901 case EM_ST19:
d1133906 902 case EM_ST7:
e9f53129
AM
903 case EM_ST9PLUS:
904 case EM_STARCORE:
d1133906 905 case EM_SVX:
e9f53129 906 case EM_TINYJ:
9c19a809
NC
907 default:
908 warn (_("Don't know about relocations on this machine architecture\n"));
909 return FALSE;
910 }
911}
252b5132 912
dda8d76d 913/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
914 Returns TRUE upon success, FALSE otherwise. If successful then a
915 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
916 and the number of relocs loaded is placed in *NRELASP. It is the caller's
917 responsibility to free the allocated buffer. */
918
919static bfd_boolean
dda8d76d
NC
920slurp_rela_relocs (Filedata * filedata,
921 unsigned long rel_offset,
922 unsigned long rel_size,
923 Elf_Internal_Rela ** relasp,
924 unsigned long * nrelasp)
9c19a809 925{
2cf0635d 926 Elf_Internal_Rela * relas;
8b73c356 927 size_t nrelas;
4d6ed7c8 928 unsigned int i;
252b5132 929
4d6ed7c8
NC
930 if (is_32bit_elf)
931 {
2cf0635d 932 Elf32_External_Rela * erelas;
103f02d3 933
dda8d76d 934 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 935 rel_size, _("32-bit relocation data"));
a6e9f9df 936 if (!erelas)
32ec8896 937 return FALSE;
252b5132 938
4d6ed7c8 939 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 940
3f5e193b
NC
941 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
942 sizeof (Elf_Internal_Rela));
103f02d3 943
4d6ed7c8
NC
944 if (relas == NULL)
945 {
c256ffe7 946 free (erelas);
591a748a 947 error (_("out of memory parsing relocs\n"));
32ec8896 948 return FALSE;
4d6ed7c8 949 }
103f02d3 950
4d6ed7c8
NC
951 for (i = 0; i < nrelas; i++)
952 {
953 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
954 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 955 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 956 }
103f02d3 957
4d6ed7c8
NC
958 free (erelas);
959 }
960 else
961 {
2cf0635d 962 Elf64_External_Rela * erelas;
103f02d3 963
dda8d76d 964 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 965 rel_size, _("64-bit relocation data"));
a6e9f9df 966 if (!erelas)
32ec8896 967 return FALSE;
4d6ed7c8
NC
968
969 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 970
3f5e193b
NC
971 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
972 sizeof (Elf_Internal_Rela));
103f02d3 973
4d6ed7c8
NC
974 if (relas == NULL)
975 {
c256ffe7 976 free (erelas);
591a748a 977 error (_("out of memory parsing relocs\n"));
32ec8896 978 return FALSE;
9c19a809 979 }
4d6ed7c8
NC
980
981 for (i = 0; i < nrelas; i++)
9c19a809 982 {
66543521
AM
983 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
984 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 985 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
986
987 /* The #ifdef BFD64 below is to prevent a compile time
988 warning. We know that if we do not have a 64 bit data
989 type that we will never execute this code anyway. */
990#ifdef BFD64
dda8d76d
NC
991 if (filedata->file_header.e_machine == EM_MIPS
992 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
993 {
994 /* In little-endian objects, r_info isn't really a
995 64-bit little-endian value: it has a 32-bit
996 little-endian symbol index followed by four
997 individual byte fields. Reorder INFO
998 accordingly. */
91d6fa6a
NC
999 bfd_vma inf = relas[i].r_info;
1000 inf = (((inf & 0xffffffff) << 32)
1001 | ((inf >> 56) & 0xff)
1002 | ((inf >> 40) & 0xff00)
1003 | ((inf >> 24) & 0xff0000)
1004 | ((inf >> 8) & 0xff000000));
1005 relas[i].r_info = inf;
861fb55a
DJ
1006 }
1007#endif /* BFD64 */
4d6ed7c8 1008 }
103f02d3 1009
4d6ed7c8
NC
1010 free (erelas);
1011 }
32ec8896 1012
4d6ed7c8
NC
1013 *relasp = relas;
1014 *nrelasp = nrelas;
32ec8896 1015 return TRUE;
4d6ed7c8 1016}
103f02d3 1017
dda8d76d 1018/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1019 Returns TRUE upon success, FALSE otherwise. If successful then a
1020 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1021 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1022 responsibility to free the allocated buffer. */
1023
1024static bfd_boolean
dda8d76d
NC
1025slurp_rel_relocs (Filedata * filedata,
1026 unsigned long rel_offset,
1027 unsigned long rel_size,
1028 Elf_Internal_Rela ** relsp,
1029 unsigned long * nrelsp)
4d6ed7c8 1030{
2cf0635d 1031 Elf_Internal_Rela * rels;
8b73c356 1032 size_t nrels;
4d6ed7c8 1033 unsigned int i;
103f02d3 1034
4d6ed7c8
NC
1035 if (is_32bit_elf)
1036 {
2cf0635d 1037 Elf32_External_Rel * erels;
103f02d3 1038
dda8d76d 1039 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1040 rel_size, _("32-bit relocation data"));
a6e9f9df 1041 if (!erels)
32ec8896 1042 return FALSE;
103f02d3 1043
4d6ed7c8 1044 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1045
3f5e193b 1046 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1047
4d6ed7c8
NC
1048 if (rels == NULL)
1049 {
c256ffe7 1050 free (erels);
591a748a 1051 error (_("out of memory parsing relocs\n"));
32ec8896 1052 return FALSE;
4d6ed7c8
NC
1053 }
1054
1055 for (i = 0; i < nrels; i++)
1056 {
1057 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1058 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1059 rels[i].r_addend = 0;
9ea033b2 1060 }
4d6ed7c8
NC
1061
1062 free (erels);
9c19a809
NC
1063 }
1064 else
1065 {
2cf0635d 1066 Elf64_External_Rel * erels;
9ea033b2 1067
dda8d76d 1068 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1069 rel_size, _("64-bit relocation data"));
a6e9f9df 1070 if (!erels)
32ec8896 1071 return FALSE;
103f02d3 1072
4d6ed7c8 1073 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1074
3f5e193b 1075 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1076
4d6ed7c8 1077 if (rels == NULL)
9c19a809 1078 {
c256ffe7 1079 free (erels);
591a748a 1080 error (_("out of memory parsing relocs\n"));
32ec8896 1081 return FALSE;
4d6ed7c8 1082 }
103f02d3 1083
4d6ed7c8
NC
1084 for (i = 0; i < nrels; i++)
1085 {
66543521
AM
1086 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1087 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1088 rels[i].r_addend = 0;
861fb55a
DJ
1089
1090 /* The #ifdef BFD64 below is to prevent a compile time
1091 warning. We know that if we do not have a 64 bit data
1092 type that we will never execute this code anyway. */
1093#ifdef BFD64
dda8d76d
NC
1094 if (filedata->file_header.e_machine == EM_MIPS
1095 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1096 {
1097 /* In little-endian objects, r_info isn't really a
1098 64-bit little-endian value: it has a 32-bit
1099 little-endian symbol index followed by four
1100 individual byte fields. Reorder INFO
1101 accordingly. */
91d6fa6a
NC
1102 bfd_vma inf = rels[i].r_info;
1103 inf = (((inf & 0xffffffff) << 32)
1104 | ((inf >> 56) & 0xff)
1105 | ((inf >> 40) & 0xff00)
1106 | ((inf >> 24) & 0xff0000)
1107 | ((inf >> 8) & 0xff000000));
1108 rels[i].r_info = inf;
861fb55a
DJ
1109 }
1110#endif /* BFD64 */
4d6ed7c8 1111 }
103f02d3 1112
4d6ed7c8
NC
1113 free (erels);
1114 }
32ec8896 1115
4d6ed7c8
NC
1116 *relsp = rels;
1117 *nrelsp = nrels;
32ec8896 1118 return TRUE;
4d6ed7c8 1119}
103f02d3 1120
aca88567
NC
1121/* Returns the reloc type extracted from the reloc info field. */
1122
1123static unsigned int
dda8d76d 1124get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1125{
1126 if (is_32bit_elf)
1127 return ELF32_R_TYPE (reloc_info);
1128
dda8d76d 1129 switch (filedata->file_header.e_machine)
aca88567
NC
1130 {
1131 case EM_MIPS:
1132 /* Note: We assume that reloc_info has already been adjusted for us. */
1133 return ELF64_MIPS_R_TYPE (reloc_info);
1134
1135 case EM_SPARCV9:
1136 return ELF64_R_TYPE_ID (reloc_info);
1137
1138 default:
1139 return ELF64_R_TYPE (reloc_info);
1140 }
1141}
1142
1143/* Return the symbol index extracted from the reloc info field. */
1144
1145static bfd_vma
1146get_reloc_symindex (bfd_vma reloc_info)
1147{
1148 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1149}
1150
13761a11 1151static inline bfd_boolean
dda8d76d 1152uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1153{
1154 return
dda8d76d 1155 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1156 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1157 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1158 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1159 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1160}
1161
d3ba0551
AM
1162/* Display the contents of the relocation data found at the specified
1163 offset. */
ee42cf8c 1164
32ec8896 1165static bfd_boolean
dda8d76d
NC
1166dump_relocations (Filedata * filedata,
1167 unsigned long rel_offset,
1168 unsigned long rel_size,
1169 Elf_Internal_Sym * symtab,
1170 unsigned long nsyms,
1171 char * strtab,
1172 unsigned long strtablen,
1173 int is_rela,
1174 bfd_boolean is_dynsym)
4d6ed7c8 1175{
32ec8896 1176 unsigned long i;
2cf0635d 1177 Elf_Internal_Rela * rels;
32ec8896 1178 bfd_boolean res = TRUE;
103f02d3 1179
4d6ed7c8 1180 if (is_rela == UNKNOWN)
dda8d76d 1181 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1182
4d6ed7c8
NC
1183 if (is_rela)
1184 {
dda8d76d 1185 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1186 return FALSE;
4d6ed7c8
NC
1187 }
1188 else
1189 {
dda8d76d 1190 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1191 return FALSE;
252b5132
RH
1192 }
1193
410f7a12
L
1194 if (is_32bit_elf)
1195 {
1196 if (is_rela)
2c71103e
NC
1197 {
1198 if (do_wide)
1199 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1200 else
1201 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1202 }
410f7a12 1203 else
2c71103e
NC
1204 {
1205 if (do_wide)
1206 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1207 else
1208 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1209 }
410f7a12 1210 }
252b5132 1211 else
410f7a12
L
1212 {
1213 if (is_rela)
2c71103e
NC
1214 {
1215 if (do_wide)
8beeaeb7 1216 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1217 else
1218 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1219 }
410f7a12 1220 else
2c71103e
NC
1221 {
1222 if (do_wide)
8beeaeb7 1223 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1224 else
1225 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1226 }
410f7a12 1227 }
252b5132
RH
1228
1229 for (i = 0; i < rel_size; i++)
1230 {
2cf0635d 1231 const char * rtype;
b34976b6 1232 bfd_vma offset;
91d6fa6a 1233 bfd_vma inf;
b34976b6
AM
1234 bfd_vma symtab_index;
1235 bfd_vma type;
103f02d3 1236
b34976b6 1237 offset = rels[i].r_offset;
91d6fa6a 1238 inf = rels[i].r_info;
103f02d3 1239
dda8d76d 1240 type = get_reloc_type (filedata, inf);
91d6fa6a 1241 symtab_index = get_reloc_symindex (inf);
252b5132 1242
410f7a12
L
1243 if (is_32bit_elf)
1244 {
39dbeff8
AM
1245 printf ("%8.8lx %8.8lx ",
1246 (unsigned long) offset & 0xffffffff,
91d6fa6a 1247 (unsigned long) inf & 0xffffffff);
410f7a12
L
1248 }
1249 else
1250 {
39dbeff8
AM
1251#if BFD_HOST_64BIT_LONG
1252 printf (do_wide
1253 ? "%16.16lx %16.16lx "
1254 : "%12.12lx %12.12lx ",
91d6fa6a 1255 offset, inf);
39dbeff8 1256#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1257#ifndef __MSVCRT__
39dbeff8
AM
1258 printf (do_wide
1259 ? "%16.16llx %16.16llx "
1260 : "%12.12llx %12.12llx ",
91d6fa6a 1261 offset, inf);
6e3d6dc1
NC
1262#else
1263 printf (do_wide
1264 ? "%16.16I64x %16.16I64x "
1265 : "%12.12I64x %12.12I64x ",
91d6fa6a 1266 offset, inf);
6e3d6dc1 1267#endif
39dbeff8 1268#else
2c71103e
NC
1269 printf (do_wide
1270 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1271 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1272 _bfd_int64_high (offset),
1273 _bfd_int64_low (offset),
91d6fa6a
NC
1274 _bfd_int64_high (inf),
1275 _bfd_int64_low (inf));
9ea033b2 1276#endif
410f7a12 1277 }
103f02d3 1278
dda8d76d 1279 switch (filedata->file_header.e_machine)
252b5132
RH
1280 {
1281 default:
1282 rtype = NULL;
1283 break;
1284
a06ea964
NC
1285 case EM_AARCH64:
1286 rtype = elf_aarch64_reloc_type (type);
1287 break;
1288
2b0337b0 1289 case EM_M32R:
252b5132 1290 case EM_CYGNUS_M32R:
9ea033b2 1291 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1292 break;
1293
1294 case EM_386:
22abe556 1295 case EM_IAMCU:
9ea033b2 1296 rtype = elf_i386_reloc_type (type);
252b5132
RH
1297 break;
1298
ba2685cc
AM
1299 case EM_68HC11:
1300 case EM_68HC12:
1301 rtype = elf_m68hc11_reloc_type (type);
1302 break;
75751cd9 1303
7b4ae824
JD
1304 case EM_S12Z:
1305 rtype = elf_s12z_reloc_type (type);
1306 break;
1307
252b5132 1308 case EM_68K:
9ea033b2 1309 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1310 break;
1311
f954747f
AM
1312 case EM_960:
1313 rtype = elf_i960_reloc_type (type);
1314 break;
1315
adde6300 1316 case EM_AVR:
2b0337b0 1317 case EM_AVR_OLD:
adde6300
AM
1318 rtype = elf_avr_reloc_type (type);
1319 break;
1320
9ea033b2
NC
1321 case EM_OLD_SPARCV9:
1322 case EM_SPARC32PLUS:
1323 case EM_SPARCV9:
252b5132 1324 case EM_SPARC:
9ea033b2 1325 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1326 break;
1327
e9f53129
AM
1328 case EM_SPU:
1329 rtype = elf_spu_reloc_type (type);
1330 break;
1331
708e2187
NC
1332 case EM_V800:
1333 rtype = v800_reloc_type (type);
1334 break;
2b0337b0 1335 case EM_V850:
252b5132 1336 case EM_CYGNUS_V850:
9ea033b2 1337 rtype = v850_reloc_type (type);
252b5132
RH
1338 break;
1339
2b0337b0 1340 case EM_D10V:
252b5132 1341 case EM_CYGNUS_D10V:
9ea033b2 1342 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1343 break;
1344
2b0337b0 1345 case EM_D30V:
252b5132 1346 case EM_CYGNUS_D30V:
9ea033b2 1347 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1348 break;
1349
d172d4ba
NC
1350 case EM_DLX:
1351 rtype = elf_dlx_reloc_type (type);
1352 break;
1353
252b5132 1354 case EM_SH:
9ea033b2 1355 rtype = elf_sh_reloc_type (type);
252b5132
RH
1356 break;
1357
2b0337b0 1358 case EM_MN10300:
252b5132 1359 case EM_CYGNUS_MN10300:
9ea033b2 1360 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1361 break;
1362
2b0337b0 1363 case EM_MN10200:
252b5132 1364 case EM_CYGNUS_MN10200:
9ea033b2 1365 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1366 break;
1367
2b0337b0 1368 case EM_FR30:
252b5132 1369 case EM_CYGNUS_FR30:
9ea033b2 1370 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1371 break;
1372
ba2685cc
AM
1373 case EM_CYGNUS_FRV:
1374 rtype = elf_frv_reloc_type (type);
1375 break;
5c70f934 1376
b8891f8d
AJ
1377 case EM_CSKY:
1378 rtype = elf_csky_reloc_type (type);
1379 break;
1380
3f8107ab
AM
1381 case EM_FT32:
1382 rtype = elf_ft32_reloc_type (type);
1383 break;
1384
252b5132 1385 case EM_MCORE:
9ea033b2 1386 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1387 break;
1388
3c3bdf30
NC
1389 case EM_MMIX:
1390 rtype = elf_mmix_reloc_type (type);
1391 break;
1392
5506d11a
AM
1393 case EM_MOXIE:
1394 rtype = elf_moxie_reloc_type (type);
1395 break;
1396
2469cfa2 1397 case EM_MSP430:
dda8d76d 1398 if (uses_msp430x_relocs (filedata))
13761a11
NC
1399 {
1400 rtype = elf_msp430x_reloc_type (type);
1401 break;
1402 }
1a0670f3 1403 /* Fall through. */
2469cfa2
NC
1404 case EM_MSP430_OLD:
1405 rtype = elf_msp430_reloc_type (type);
1406 break;
1407
35c08157
KLC
1408 case EM_NDS32:
1409 rtype = elf_nds32_reloc_type (type);
1410 break;
1411
252b5132 1412 case EM_PPC:
9ea033b2 1413 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1414 break;
1415
c833c019
AM
1416 case EM_PPC64:
1417 rtype = elf_ppc64_reloc_type (type);
1418 break;
1419
252b5132 1420 case EM_MIPS:
4fe85591 1421 case EM_MIPS_RS3_LE:
9ea033b2 1422 rtype = elf_mips_reloc_type (type);
252b5132
RH
1423 break;
1424
e23eba97
NC
1425 case EM_RISCV:
1426 rtype = elf_riscv_reloc_type (type);
1427 break;
1428
252b5132 1429 case EM_ALPHA:
9ea033b2 1430 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1431 break;
1432
1433 case EM_ARM:
9ea033b2 1434 rtype = elf_arm_reloc_type (type);
252b5132
RH
1435 break;
1436
584da044 1437 case EM_ARC:
886a2506
NC
1438 case EM_ARC_COMPACT:
1439 case EM_ARC_COMPACT2:
9ea033b2 1440 rtype = elf_arc_reloc_type (type);
252b5132
RH
1441 break;
1442
1443 case EM_PARISC:
69e617ca 1444 rtype = elf_hppa_reloc_type (type);
252b5132 1445 break;
7d466069 1446
b8720f9d
JL
1447 case EM_H8_300:
1448 case EM_H8_300H:
1449 case EM_H8S:
1450 rtype = elf_h8_reloc_type (type);
1451 break;
1452
73589c9d
CS
1453 case EM_OR1K:
1454 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1455 break;
1456
7d466069 1457 case EM_PJ:
2b0337b0 1458 case EM_PJ_OLD:
7d466069
ILT
1459 rtype = elf_pj_reloc_type (type);
1460 break;
800eeca4
JW
1461 case EM_IA_64:
1462 rtype = elf_ia64_reloc_type (type);
1463 break;
1b61cf92
HPN
1464
1465 case EM_CRIS:
1466 rtype = elf_cris_reloc_type (type);
1467 break;
535c37ff 1468
f954747f
AM
1469 case EM_860:
1470 rtype = elf_i860_reloc_type (type);
1471 break;
1472
bcedfee6 1473 case EM_X86_64:
8a9036a4 1474 case EM_L1OM:
7a9068fe 1475 case EM_K1OM:
bcedfee6
NC
1476 rtype = elf_x86_64_reloc_type (type);
1477 break;
a85d7ed0 1478
f954747f
AM
1479 case EM_S370:
1480 rtype = i370_reloc_type (type);
1481 break;
1482
53c7db4b
KH
1483 case EM_S390_OLD:
1484 case EM_S390:
1485 rtype = elf_s390_reloc_type (type);
1486 break;
93fbbb04 1487
1c0d3aa6
NC
1488 case EM_SCORE:
1489 rtype = elf_score_reloc_type (type);
1490 break;
1491
93fbbb04
GK
1492 case EM_XSTORMY16:
1493 rtype = elf_xstormy16_reloc_type (type);
1494 break;
179d3252 1495
1fe1f39c
NC
1496 case EM_CRX:
1497 rtype = elf_crx_reloc_type (type);
1498 break;
1499
179d3252
JT
1500 case EM_VAX:
1501 rtype = elf_vax_reloc_type (type);
1502 break;
1e4cf259 1503
619ed720
EB
1504 case EM_VISIUM:
1505 rtype = elf_visium_reloc_type (type);
1506 break;
1507
aca4efc7
JM
1508 case EM_BPF:
1509 rtype = elf_bpf_reloc_type (type);
1510 break;
1511
cfb8c092
NC
1512 case EM_ADAPTEVA_EPIPHANY:
1513 rtype = elf_epiphany_reloc_type (type);
1514 break;
1515
1e4cf259
NC
1516 case EM_IP2K:
1517 case EM_IP2K_OLD:
1518 rtype = elf_ip2k_reloc_type (type);
1519 break;
3b36097d
SC
1520
1521 case EM_IQ2000:
1522 rtype = elf_iq2000_reloc_type (type);
1523 break;
88da6820
NC
1524
1525 case EM_XTENSA_OLD:
1526 case EM_XTENSA:
1527 rtype = elf_xtensa_reloc_type (type);
1528 break;
a34e3ecb 1529
84e94c90
NC
1530 case EM_LATTICEMICO32:
1531 rtype = elf_lm32_reloc_type (type);
1532 break;
1533
ff7eeb89 1534 case EM_M32C_OLD:
49f58d10
JB
1535 case EM_M32C:
1536 rtype = elf_m32c_reloc_type (type);
1537 break;
1538
d031aafb
NS
1539 case EM_MT:
1540 rtype = elf_mt_reloc_type (type);
a34e3ecb 1541 break;
1d65ded4
CM
1542
1543 case EM_BLACKFIN:
1544 rtype = elf_bfin_reloc_type (type);
1545 break;
15ab5209
DB
1546
1547 case EM_CYGNUS_MEP:
1548 rtype = elf_mep_reloc_type (type);
1549 break;
60bca95a
NC
1550
1551 case EM_CR16:
1552 rtype = elf_cr16_reloc_type (type);
1553 break;
dd24e3da 1554
7ba29e2a
NC
1555 case EM_MICROBLAZE:
1556 case EM_MICROBLAZE_OLD:
1557 rtype = elf_microblaze_reloc_type (type);
1558 break;
c7927a3c 1559
99c513f6
DD
1560 case EM_RL78:
1561 rtype = elf_rl78_reloc_type (type);
1562 break;
1563
c7927a3c
NC
1564 case EM_RX:
1565 rtype = elf_rx_reloc_type (type);
1566 break;
c29aca4a 1567
a3c62988
NC
1568 case EM_METAG:
1569 rtype = elf_metag_reloc_type (type);
1570 break;
1571
c29aca4a
NC
1572 case EM_XC16X:
1573 case EM_C166:
1574 rtype = elf_xc16x_reloc_type (type);
1575 break;
40b36596
JM
1576
1577 case EM_TI_C6000:
1578 rtype = elf_tic6x_reloc_type (type);
1579 break;
aa137e4d
NC
1580
1581 case EM_TILEGX:
1582 rtype = elf_tilegx_reloc_type (type);
1583 break;
1584
1585 case EM_TILEPRO:
1586 rtype = elf_tilepro_reloc_type (type);
1587 break;
f6c1a2d5 1588
f96bd6c2
PC
1589 case EM_WEBASSEMBLY:
1590 rtype = elf_wasm32_reloc_type (type);
1591 break;
1592
f6c1a2d5
NC
1593 case EM_XGATE:
1594 rtype = elf_xgate_reloc_type (type);
1595 break;
36591ba1
SL
1596
1597 case EM_ALTERA_NIOS2:
1598 rtype = elf_nios2_reloc_type (type);
1599 break;
2b100bb5
DD
1600
1601 case EM_TI_PRU:
1602 rtype = elf_pru_reloc_type (type);
1603 break;
fe944acf
FT
1604
1605 case EM_NFP:
1606 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1607 rtype = elf_nfp3200_reloc_type (type);
1608 else
1609 rtype = elf_nfp_reloc_type (type);
1610 break;
6655dba2
SB
1611
1612 case EM_Z80:
1613 rtype = elf_z80_reloc_type (type);
1614 break;
252b5132
RH
1615 }
1616
1617 if (rtype == NULL)
39dbeff8 1618 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1619 else
5c144731 1620 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1621
dda8d76d 1622 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1623 && rtype != NULL
7ace3541
RH
1624 && streq (rtype, "R_ALPHA_LITUSE")
1625 && is_rela)
1626 {
1627 switch (rels[i].r_addend)
1628 {
1629 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1630 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1631 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1632 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1633 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1634 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1635 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1636 default: rtype = NULL;
1637 }
32ec8896 1638
7ace3541
RH
1639 if (rtype)
1640 printf (" (%s)", rtype);
1641 else
1642 {
1643 putchar (' ');
1644 printf (_("<unknown addend: %lx>"),
1645 (unsigned long) rels[i].r_addend);
32ec8896 1646 res = FALSE;
7ace3541
RH
1647 }
1648 }
1649 else if (symtab_index)
252b5132 1650 {
af3fc3bc 1651 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1652 {
27a45f42
AS
1653 error (_(" bad symbol index: %08lx in reloc\n"),
1654 (unsigned long) symtab_index);
32ec8896
NC
1655 res = FALSE;
1656 }
af3fc3bc 1657 else
19936277 1658 {
2cf0635d 1659 Elf_Internal_Sym * psym;
bb4d2ac2
L
1660 const char * version_string;
1661 enum versioned_symbol_info sym_info;
1662 unsigned short vna_other;
19936277 1663
af3fc3bc 1664 psym = symtab + symtab_index;
103f02d3 1665
bb4d2ac2 1666 version_string
dda8d76d 1667 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1668 strtab, strtablen,
1669 symtab_index,
1670 psym,
1671 &sym_info,
1672 &vna_other);
1673
af3fc3bc 1674 printf (" ");
171191ba 1675
d8045f23
NC
1676 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1677 {
1678 const char * name;
1679 unsigned int len;
1680 unsigned int width = is_32bit_elf ? 8 : 14;
1681
1682 /* Relocations against GNU_IFUNC symbols do not use the value
1683 of the symbol as the address to relocate against. Instead
1684 they invoke the function named by the symbol and use its
1685 result as the address for relocation.
1686
1687 To indicate this to the user, do not display the value of
1688 the symbol in the "Symbols's Value" field. Instead show
1689 its name followed by () as a hint that the symbol is
1690 invoked. */
1691
1692 if (strtab == NULL
1693 || psym->st_name == 0
1694 || psym->st_name >= strtablen)
1695 name = "??";
1696 else
1697 name = strtab + psym->st_name;
1698
1699 len = print_symbol (width, name);
bb4d2ac2
L
1700 if (version_string)
1701 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1702 version_string);
d8045f23
NC
1703 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1704 }
1705 else
1706 {
1707 print_vma (psym->st_value, LONG_HEX);
171191ba 1708
d8045f23
NC
1709 printf (is_32bit_elf ? " " : " ");
1710 }
103f02d3 1711
af3fc3bc 1712 if (psym->st_name == 0)
f1ef08cb 1713 {
2cf0635d 1714 const char * sec_name = "<null>";
f1ef08cb
AM
1715 char name_buf[40];
1716
1717 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1718 {
dda8d76d
NC
1719 if (psym->st_shndx < filedata->file_header.e_shnum)
1720 sec_name = SECTION_NAME (filedata->section_headers + psym->st_shndx);
f1ef08cb
AM
1721 else if (psym->st_shndx == SHN_ABS)
1722 sec_name = "ABS";
1723 else if (psym->st_shndx == SHN_COMMON)
1724 sec_name = "COMMON";
dda8d76d 1725 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1726 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1727 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1728 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1729 sec_name = "SCOMMON";
dda8d76d 1730 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1731 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1732 sec_name = "SUNDEF";
dda8d76d
NC
1733 else if ((filedata->file_header.e_machine == EM_X86_64
1734 || filedata->file_header.e_machine == EM_L1OM
1735 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1736 && psym->st_shndx == SHN_X86_64_LCOMMON)
1737 sec_name = "LARGE_COMMON";
dda8d76d
NC
1738 else if (filedata->file_header.e_machine == EM_IA_64
1739 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1740 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1741 sec_name = "ANSI_COM";
dda8d76d 1742 else if (is_ia64_vms (filedata)
148b93f2
NC
1743 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1744 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1745 else
1746 {
1747 sprintf (name_buf, "<section 0x%x>",
1748 (unsigned int) psym->st_shndx);
1749 sec_name = name_buf;
1750 }
1751 }
1752 print_symbol (22, sec_name);
1753 }
af3fc3bc 1754 else if (strtab == NULL)
d79b3d50 1755 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1756 else if (psym->st_name >= strtablen)
32ec8896 1757 {
27a45f42
AS
1758 error (_("<corrupt string table index: %3ld>\n"),
1759 psym->st_name);
32ec8896
NC
1760 res = FALSE;
1761 }
af3fc3bc 1762 else
bb4d2ac2
L
1763 {
1764 print_symbol (22, strtab + psym->st_name);
1765 if (version_string)
1766 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1767 version_string);
1768 }
103f02d3 1769
af3fc3bc 1770 if (is_rela)
171191ba 1771 {
7360e63f 1772 bfd_vma off = rels[i].r_addend;
171191ba 1773
7360e63f 1774 if ((bfd_signed_vma) off < 0)
598aaa76 1775 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1776 else
598aaa76 1777 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1778 }
19936277 1779 }
252b5132 1780 }
1b228002 1781 else if (is_rela)
f7a99963 1782 {
7360e63f 1783 bfd_vma off = rels[i].r_addend;
e04d7088
L
1784
1785 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1786 if ((bfd_signed_vma) off < 0)
e04d7088
L
1787 printf ("-%" BFD_VMA_FMT "x", - off);
1788 else
1789 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1790 }
252b5132 1791
dda8d76d 1792 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1793 && rtype != NULL
1794 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1795 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1796
252b5132 1797 putchar ('\n');
2c71103e 1798
aca88567 1799#ifdef BFD64
dda8d76d 1800 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1801 {
91d6fa6a
NC
1802 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1803 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1804 const char * rtype2 = elf_mips_reloc_type (type2);
1805 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1806
2c71103e
NC
1807 printf (" Type2: ");
1808
1809 if (rtype2 == NULL)
39dbeff8
AM
1810 printf (_("unrecognized: %-7lx"),
1811 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1812 else
1813 printf ("%-17.17s", rtype2);
1814
18bd398b 1815 printf ("\n Type3: ");
2c71103e
NC
1816
1817 if (rtype3 == NULL)
39dbeff8
AM
1818 printf (_("unrecognized: %-7lx"),
1819 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1820 else
1821 printf ("%-17.17s", rtype3);
1822
53c7db4b 1823 putchar ('\n');
2c71103e 1824 }
aca88567 1825#endif /* BFD64 */
252b5132
RH
1826 }
1827
c8286bd1 1828 free (rels);
32ec8896
NC
1829
1830 return res;
252b5132
RH
1831}
1832
37c18eed
SD
1833static const char *
1834get_aarch64_dynamic_type (unsigned long type)
1835{
1836 switch (type)
1837 {
1838 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 1839 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 1840 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
1841 default:
1842 return NULL;
1843 }
1844}
1845
252b5132 1846static const char *
d3ba0551 1847get_mips_dynamic_type (unsigned long type)
252b5132
RH
1848{
1849 switch (type)
1850 {
1851 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1852 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1853 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1854 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1855 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1856 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1857 case DT_MIPS_MSYM: return "MIPS_MSYM";
1858 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1859 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1860 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1861 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1862 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1863 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1864 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1865 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1866 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1867 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1868 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1869 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1870 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1871 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1872 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1873 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1874 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1875 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1876 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1877 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1878 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1879 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1880 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1881 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1882 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1883 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1884 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1885 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1886 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1887 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1888 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1889 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1890 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1891 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1892 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1893 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1894 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1895 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1896 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 1897 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
1898 default:
1899 return NULL;
1900 }
1901}
1902
9a097730 1903static const char *
d3ba0551 1904get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1905{
1906 switch (type)
1907 {
1908 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1909 default:
1910 return NULL;
1911 }
103f02d3
UD
1912}
1913
7490d522
AM
1914static const char *
1915get_ppc_dynamic_type (unsigned long type)
1916{
1917 switch (type)
1918 {
a7f2871e 1919 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1920 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1921 default:
1922 return NULL;
1923 }
1924}
1925
f1cb7e17 1926static const char *
d3ba0551 1927get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1928{
1929 switch (type)
1930 {
a7f2871e
AM
1931 case DT_PPC64_GLINK: return "PPC64_GLINK";
1932 case DT_PPC64_OPD: return "PPC64_OPD";
1933 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1934 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1935 default:
1936 return NULL;
1937 }
1938}
1939
103f02d3 1940static const char *
d3ba0551 1941get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1942{
1943 switch (type)
1944 {
1945 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1946 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1947 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1948 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1949 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1950 case DT_HP_PREINIT: return "HP_PREINIT";
1951 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1952 case DT_HP_NEEDED: return "HP_NEEDED";
1953 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1954 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1955 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1956 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1957 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1958 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1959 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1960 case DT_HP_FILTERED: return "HP_FILTERED";
1961 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1962 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1963 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1964 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1965 case DT_PLT: return "PLT";
1966 case DT_PLT_SIZE: return "PLT_SIZE";
1967 case DT_DLT: return "DLT";
1968 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1969 default:
1970 return NULL;
1971 }
1972}
9a097730 1973
ecc51f48 1974static const char *
d3ba0551 1975get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1976{
1977 switch (type)
1978 {
148b93f2
NC
1979 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1980 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1981 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1982 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1983 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1984 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1985 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1986 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1987 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1988 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1989 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1990 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1991 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1992 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1993 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1994 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1995 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1996 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1997 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1998 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1999 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2000 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2001 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2002 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2003 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2004 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2005 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2006 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2007 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2008 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2009 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2010 default:
2011 return NULL;
2012 }
2013}
2014
fd85a6a1
NC
2015static const char *
2016get_solaris_section_type (unsigned long type)
2017{
2018 switch (type)
2019 {
2020 case 0x6fffffee: return "SUNW_ancillary";
2021 case 0x6fffffef: return "SUNW_capchain";
2022 case 0x6ffffff0: return "SUNW_capinfo";
2023 case 0x6ffffff1: return "SUNW_symsort";
2024 case 0x6ffffff2: return "SUNW_tlssort";
2025 case 0x6ffffff3: return "SUNW_LDYNSYM";
2026 case 0x6ffffff4: return "SUNW_dof";
2027 case 0x6ffffff5: return "SUNW_cap";
2028 case 0x6ffffff6: return "SUNW_SIGNATURE";
2029 case 0x6ffffff7: return "SUNW_ANNOTATE";
2030 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2031 case 0x6ffffff9: return "SUNW_DEBUG";
2032 case 0x6ffffffa: return "SUNW_move";
2033 case 0x6ffffffb: return "SUNW_COMDAT";
2034 case 0x6ffffffc: return "SUNW_syminfo";
2035 case 0x6ffffffd: return "SUNW_verdef";
2036 case 0x6ffffffe: return "SUNW_verneed";
2037 case 0x6fffffff: return "SUNW_versym";
2038 case 0x70000000: return "SPARC_GOTDATA";
2039 default: return NULL;
2040 }
2041}
2042
fabcb361
RH
2043static const char *
2044get_alpha_dynamic_type (unsigned long type)
2045{
2046 switch (type)
2047 {
2048 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2049 default: return NULL;
fabcb361
RH
2050 }
2051}
2052
1c0d3aa6
NC
2053static const char *
2054get_score_dynamic_type (unsigned long type)
2055{
2056 switch (type)
2057 {
2058 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2059 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2060 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2061 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2062 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2063 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2064 default: return NULL;
1c0d3aa6
NC
2065 }
2066}
2067
40b36596
JM
2068static const char *
2069get_tic6x_dynamic_type (unsigned long type)
2070{
2071 switch (type)
2072 {
2073 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2074 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2075 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2076 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2077 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2078 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2079 default: return NULL;
40b36596
JM
2080 }
2081}
1c0d3aa6 2082
36591ba1
SL
2083static const char *
2084get_nios2_dynamic_type (unsigned long type)
2085{
2086 switch (type)
2087 {
2088 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2089 default: return NULL;
36591ba1
SL
2090 }
2091}
2092
fd85a6a1
NC
2093static const char *
2094get_solaris_dynamic_type (unsigned long type)
2095{
2096 switch (type)
2097 {
2098 case 0x6000000d: return "SUNW_AUXILIARY";
2099 case 0x6000000e: return "SUNW_RTLDINF";
2100 case 0x6000000f: return "SUNW_FILTER";
2101 case 0x60000010: return "SUNW_CAP";
2102 case 0x60000011: return "SUNW_SYMTAB";
2103 case 0x60000012: return "SUNW_SYMSZ";
2104 case 0x60000013: return "SUNW_SORTENT";
2105 case 0x60000014: return "SUNW_SYMSORT";
2106 case 0x60000015: return "SUNW_SYMSORTSZ";
2107 case 0x60000016: return "SUNW_TLSSORT";
2108 case 0x60000017: return "SUNW_TLSSORTSZ";
2109 case 0x60000018: return "SUNW_CAPINFO";
2110 case 0x60000019: return "SUNW_STRPAD";
2111 case 0x6000001a: return "SUNW_CAPCHAIN";
2112 case 0x6000001b: return "SUNW_LDMACH";
2113 case 0x6000001d: return "SUNW_CAPCHAINENT";
2114 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2115 case 0x60000021: return "SUNW_PARENT";
2116 case 0x60000023: return "SUNW_ASLR";
2117 case 0x60000025: return "SUNW_RELAX";
2118 case 0x60000029: return "SUNW_NXHEAP";
2119 case 0x6000002b: return "SUNW_NXSTACK";
2120
2121 case 0x70000001: return "SPARC_REGISTER";
2122 case 0x7ffffffd: return "AUXILIARY";
2123 case 0x7ffffffe: return "USED";
2124 case 0x7fffffff: return "FILTER";
2125
15f205b1 2126 default: return NULL;
fd85a6a1
NC
2127 }
2128}
2129
252b5132 2130static const char *
dda8d76d 2131get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2132{
e9e44622 2133 static char buff[64];
252b5132
RH
2134
2135 switch (type)
2136 {
2137 case DT_NULL: return "NULL";
2138 case DT_NEEDED: return "NEEDED";
2139 case DT_PLTRELSZ: return "PLTRELSZ";
2140 case DT_PLTGOT: return "PLTGOT";
2141 case DT_HASH: return "HASH";
2142 case DT_STRTAB: return "STRTAB";
2143 case DT_SYMTAB: return "SYMTAB";
2144 case DT_RELA: return "RELA";
2145 case DT_RELASZ: return "RELASZ";
2146 case DT_RELAENT: return "RELAENT";
2147 case DT_STRSZ: return "STRSZ";
2148 case DT_SYMENT: return "SYMENT";
2149 case DT_INIT: return "INIT";
2150 case DT_FINI: return "FINI";
2151 case DT_SONAME: return "SONAME";
2152 case DT_RPATH: return "RPATH";
2153 case DT_SYMBOLIC: return "SYMBOLIC";
2154 case DT_REL: return "REL";
2155 case DT_RELSZ: return "RELSZ";
2156 case DT_RELENT: return "RELENT";
2157 case DT_PLTREL: return "PLTREL";
2158 case DT_DEBUG: return "DEBUG";
2159 case DT_TEXTREL: return "TEXTREL";
2160 case DT_JMPREL: return "JMPREL";
2161 case DT_BIND_NOW: return "BIND_NOW";
2162 case DT_INIT_ARRAY: return "INIT_ARRAY";
2163 case DT_FINI_ARRAY: return "FINI_ARRAY";
2164 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2165 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2166 case DT_RUNPATH: return "RUNPATH";
2167 case DT_FLAGS: return "FLAGS";
2d0e6f43 2168
d1133906
NC
2169 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2170 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2171 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2172
05107a46 2173 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2174 case DT_PLTPADSZ: return "PLTPADSZ";
2175 case DT_MOVEENT: return "MOVEENT";
2176 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2177 case DT_FEATURE: return "FEATURE";
252b5132
RH
2178 case DT_POSFLAG_1: return "POSFLAG_1";
2179 case DT_SYMINSZ: return "SYMINSZ";
2180 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2181
252b5132 2182 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2183 case DT_CONFIG: return "CONFIG";
2184 case DT_DEPAUDIT: return "DEPAUDIT";
2185 case DT_AUDIT: return "AUDIT";
2186 case DT_PLTPAD: return "PLTPAD";
2187 case DT_MOVETAB: return "MOVETAB";
252b5132 2188 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2189
252b5132 2190 case DT_VERSYM: return "VERSYM";
103f02d3 2191
67a4f2b7
AO
2192 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2193 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2194 case DT_RELACOUNT: return "RELACOUNT";
2195 case DT_RELCOUNT: return "RELCOUNT";
2196 case DT_FLAGS_1: return "FLAGS_1";
2197 case DT_VERDEF: return "VERDEF";
2198 case DT_VERDEFNUM: return "VERDEFNUM";
2199 case DT_VERNEED: return "VERNEED";
2200 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2201
019148e4 2202 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2203 case DT_USED: return "USED";
2204 case DT_FILTER: return "FILTER";
103f02d3 2205
047b2264
JJ
2206 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2207 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2208 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2209 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2210 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2211 case DT_GNU_HASH: return "GNU_HASH";
047b2264 2212
252b5132
RH
2213 default:
2214 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2215 {
2cf0635d 2216 const char * result;
103f02d3 2217
dda8d76d 2218 switch (filedata->file_header.e_machine)
252b5132 2219 {
37c18eed
SD
2220 case EM_AARCH64:
2221 result = get_aarch64_dynamic_type (type);
2222 break;
252b5132 2223 case EM_MIPS:
4fe85591 2224 case EM_MIPS_RS3_LE:
252b5132
RH
2225 result = get_mips_dynamic_type (type);
2226 break;
9a097730
RH
2227 case EM_SPARCV9:
2228 result = get_sparc64_dynamic_type (type);
2229 break;
7490d522
AM
2230 case EM_PPC:
2231 result = get_ppc_dynamic_type (type);
2232 break;
f1cb7e17
AM
2233 case EM_PPC64:
2234 result = get_ppc64_dynamic_type (type);
2235 break;
ecc51f48
NC
2236 case EM_IA_64:
2237 result = get_ia64_dynamic_type (type);
2238 break;
fabcb361
RH
2239 case EM_ALPHA:
2240 result = get_alpha_dynamic_type (type);
2241 break;
1c0d3aa6
NC
2242 case EM_SCORE:
2243 result = get_score_dynamic_type (type);
2244 break;
40b36596
JM
2245 case EM_TI_C6000:
2246 result = get_tic6x_dynamic_type (type);
2247 break;
36591ba1
SL
2248 case EM_ALTERA_NIOS2:
2249 result = get_nios2_dynamic_type (type);
2250 break;
252b5132 2251 default:
dda8d76d 2252 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2253 result = get_solaris_dynamic_type (type);
2254 else
2255 result = NULL;
252b5132
RH
2256 break;
2257 }
2258
2259 if (result != NULL)
2260 return result;
2261
e9e44622 2262 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2263 }
eec8f817 2264 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2265 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2266 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2267 {
2cf0635d 2268 const char * result;
103f02d3 2269
dda8d76d 2270 switch (filedata->file_header.e_machine)
103f02d3
UD
2271 {
2272 case EM_PARISC:
2273 result = get_parisc_dynamic_type (type);
2274 break;
148b93f2
NC
2275 case EM_IA_64:
2276 result = get_ia64_dynamic_type (type);
2277 break;
103f02d3 2278 default:
dda8d76d 2279 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2280 result = get_solaris_dynamic_type (type);
2281 else
2282 result = NULL;
103f02d3
UD
2283 break;
2284 }
2285
2286 if (result != NULL)
2287 return result;
2288
e9e44622
JJ
2289 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2290 type);
103f02d3 2291 }
252b5132 2292 else
e9e44622 2293 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2294
252b5132
RH
2295 return buff;
2296 }
2297}
2298
2299static char *
d3ba0551 2300get_file_type (unsigned e_type)
252b5132 2301{
89246a0e 2302 static char buff[64];
252b5132
RH
2303
2304 switch (e_type)
2305 {
32ec8896
NC
2306 case ET_NONE: return _("NONE (None)");
2307 case ET_REL: return _("REL (Relocatable file)");
2308 case ET_EXEC: return _("EXEC (Executable file)");
2309 case ET_DYN: return _("DYN (Shared object file)");
2310 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2311
2312 default:
2313 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2314 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2315 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2316 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2317 else
e9e44622 2318 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2319 return buff;
2320 }
2321}
2322
2323static char *
d3ba0551 2324get_machine_name (unsigned e_machine)
252b5132 2325{
b34976b6 2326 static char buff[64]; /* XXX */
252b5132
RH
2327
2328 switch (e_machine)
2329 {
55e22ca8
NC
2330 /* Please keep this switch table sorted by increasing EM_ value. */
2331 /* 0 */
c45021f2
NC
2332 case EM_NONE: return _("None");
2333 case EM_M32: return "WE32100";
2334 case EM_SPARC: return "Sparc";
2335 case EM_386: return "Intel 80386";
2336 case EM_68K: return "MC68000";
2337 case EM_88K: return "MC88000";
22abe556 2338 case EM_IAMCU: return "Intel MCU";
fb70ec17 2339 case EM_860: return "Intel 80860";
c45021f2
NC
2340 case EM_MIPS: return "MIPS R3000";
2341 case EM_S370: return "IBM System/370";
55e22ca8 2342 /* 10 */
7036c0e1 2343 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2344 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2345 case EM_PARISC: return "HPPA";
55e22ca8 2346 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2347 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2348 case EM_960: return "Intel 80960";
c45021f2 2349 case EM_PPC: return "PowerPC";
55e22ca8 2350 /* 20 */
285d1771 2351 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2352 case EM_S390_OLD:
2353 case EM_S390: return "IBM S/390";
2354 case EM_SPU: return "SPU";
2355 /* 30 */
2356 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2357 case EM_FR20: return "Fujitsu FR20";
2358 case EM_RH32: return "TRW RH32";
b34976b6 2359 case EM_MCORE: return "MCORE";
55e22ca8 2360 /* 40 */
7036c0e1
AJ
2361 case EM_ARM: return "ARM";
2362 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2363 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2364 case EM_SPARCV9: return "Sparc v9";
2365 case EM_TRICORE: return "Siemens Tricore";
584da044 2366 case EM_ARC: return "ARC";
c2dcd04e
NC
2367 case EM_H8_300: return "Renesas H8/300";
2368 case EM_H8_300H: return "Renesas H8/300H";
2369 case EM_H8S: return "Renesas H8S";
2370 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2371 /* 50 */
30800947 2372 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2373 case EM_MIPS_X: return "Stanford MIPS-X";
2374 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2375 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2376 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2377 case EM_PCP: return "Siemens PCP";
2378 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2379 case EM_NDR1: return "Denso NDR1 microprocesspr";
2380 case EM_STARCORE: return "Motorola Star*Core processor";
2381 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2382 /* 60 */
7036c0e1
AJ
2383 case EM_ST100: return "STMicroelectronics ST100 processor";
2384 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2385 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2386 case EM_PDSP: return "Sony DSP processor";
2387 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2388 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2389 case EM_FX66: return "Siemens FX66 microcontroller";
2390 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2391 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2392 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2393 /* 70 */
7036c0e1
AJ
2394 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2395 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2396 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2397 case EM_SVX: return "Silicon Graphics SVx";
2398 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2399 case EM_VAX: return "Digital VAX";
1b61cf92 2400 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2401 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2402 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2403 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2404 /* 80 */
b34976b6 2405 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2406 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2407 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2408 case EM_AVR_OLD:
2409 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2410 case EM_CYGNUS_FR30:
2411 case EM_FR30: return "Fujitsu FR30";
2412 case EM_CYGNUS_D10V:
2413 case EM_D10V: return "d10v";
2414 case EM_CYGNUS_D30V:
2415 case EM_D30V: return "d30v";
2416 case EM_CYGNUS_V850:
2417 case EM_V850: return "Renesas V850";
2418 case EM_CYGNUS_M32R:
2419 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2420 case EM_CYGNUS_MN10300:
2421 case EM_MN10300: return "mn10300";
2422 /* 90 */
2423 case EM_CYGNUS_MN10200:
2424 case EM_MN10200: return "mn10200";
2425 case EM_PJ: return "picoJava";
73589c9d 2426 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2427 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2428 case EM_XTENSA_OLD:
2429 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2430 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2431 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2432 case EM_NS32K: return "National Semiconductor 32000 series";
2433 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2434 case EM_SNP1K: return "Trebia SNP 1000 processor";
2435 /* 100 */
9abca702 2436 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2437 case EM_IP2K_OLD:
2438 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2439 case EM_MAX: return "MAX Processor";
2440 case EM_CR: return "National Semiconductor CompactRISC";
2441 case EM_F2MC16: return "Fujitsu F2MC16";
2442 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2443 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2444 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2445 case EM_SEP: return "Sharp embedded microprocessor";
2446 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2447 /* 110 */
11636f9e
JM
2448 case EM_UNICORE: return "Unicore";
2449 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2450 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2451 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2452 case EM_CRX: return "National Semiconductor CRX microprocessor";
2453 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2454 case EM_C166:
d70c5fc7 2455 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2456 case EM_M16C: return "Renesas M16C series microprocessors";
2457 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2458 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2459 /* 120 */
2460 case EM_M32C: return "Renesas M32c";
2461 /* 130 */
11636f9e
JM
2462 case EM_TSK3000: return "Altium TSK3000 core";
2463 case EM_RS08: return "Freescale RS08 embedded processor";
2464 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2465 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2466 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2467 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2468 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2469 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2470 /* 140 */
11636f9e
JM
2471 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2472 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2473 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2474 case EM_TI_PRU: return "TI PRU I/O processor";
2475 /* 160 */
11636f9e
JM
2476 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2477 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2478 case EM_R32C: return "Renesas R32C series microprocessors";
2479 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2480 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2481 case EM_8051: return "Intel 8051 and variants";
2482 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2483 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2484 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2485 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2486 /* 170 */
11636f9e
JM
2487 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2488 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2489 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2490 case EM_RX: return "Renesas RX";
a3c62988 2491 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2492 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2493 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2494 case EM_CR16:
2495 case EM_MICROBLAZE:
2496 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2497 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2498 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2499 /* 180 */
2500 case EM_L1OM: return "Intel L1OM";
2501 case EM_K1OM: return "Intel K1OM";
2502 case EM_INTEL182: return "Intel (reserved)";
2503 case EM_AARCH64: return "AArch64";
2504 case EM_ARM184: return "ARM (reserved)";
2505 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2506 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2507 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2508 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2509 /* 190 */
11636f9e 2510 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2511 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2512 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2513 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2514 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2515 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2516 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2517 case EM_RL78: return "Renesas RL78";
6d913794 2518 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2519 case EM_78K0R: return "Renesas 78K0R";
2520 /* 200 */
6d913794 2521 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2522 case EM_BA1: return "Beyond BA1 CPU architecture";
2523 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2524 case EM_XCORE: return "XMOS xCORE processor family";
2525 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
55e22ca8 2526 /* 210 */
6d913794
NC
2527 case EM_KM32: return "KM211 KM32 32-bit processor";
2528 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2529 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2530 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2531 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2532 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2533 case EM_COGE: return "Cognitive Smart Memory Processor";
2534 case EM_COOL: return "Bluechip Systems CoolEngine";
2535 case EM_NORC: return "Nanoradio Optimized RISC";
2536 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2537 /* 220 */
15f205b1 2538 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2539 case EM_VISIUM: return "CDS VISIUMcore processor";
2540 case EM_FT32: return "FTDI Chip FT32";
2541 case EM_MOXIE: return "Moxie";
2542 case EM_AMDGPU: return "AMD GPU";
2543 case EM_RISCV: return "RISC-V";
2544 case EM_LANAI: return "Lanai 32-bit processor";
2545 case EM_BPF: return "Linux BPF";
fe944acf 2546 case EM_NFP: return "Netronome Flow Processor";
55e22ca8
NC
2547
2548 /* Large numbers... */
2549 case EM_MT: return "Morpho Techologies MT processor";
2550 case EM_ALPHA: return "Alpha";
2551 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2552 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2553 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2554 case EM_IQ2000: return "Vitesse IQ2000";
2555 case EM_M32C_OLD:
2556 case EM_NIOS32: return "Altera Nios";
2557 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2558 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2559 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2560 case EM_S12Z: return "Freescale S12Z";
b8891f8d 2561 case EM_CSKY: return "C-SKY";
55e22ca8 2562
252b5132 2563 default:
35d9dd2f 2564 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2565 return buff;
2566 }
2567}
2568
a9522a21
AB
2569static void
2570decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2571{
2572 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
2573 other compilers don't a specific architecture type in the e_flags, and
2574 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2575 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2576 architectures.
2577
2578 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2579 but also sets a specific architecture type in the e_flags field.
2580
2581 However, when decoding the flags we don't worry if we see an
2582 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2583 ARCEM architecture type. */
2584
2585 switch (e_flags & EF_ARC_MACH_MSK)
2586 {
2587 /* We only expect these to occur for EM_ARC_COMPACT2. */
2588 case EF_ARC_CPU_ARCV2EM:
2589 strcat (buf, ", ARC EM");
2590 break;
2591 case EF_ARC_CPU_ARCV2HS:
2592 strcat (buf, ", ARC HS");
2593 break;
2594
2595 /* We only expect these to occur for EM_ARC_COMPACT. */
2596 case E_ARC_MACH_ARC600:
2597 strcat (buf, ", ARC600");
2598 break;
2599 case E_ARC_MACH_ARC601:
2600 strcat (buf, ", ARC601");
2601 break;
2602 case E_ARC_MACH_ARC700:
2603 strcat (buf, ", ARC700");
2604 break;
2605
2606 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2607 new ELF with new architecture being read by an old version of
2608 readelf, or (c) An ELF built with non-GNU compiler that does not
2609 set the architecture in the e_flags. */
2610 default:
2611 if (e_machine == EM_ARC_COMPACT)
2612 strcat (buf, ", Unknown ARCompact");
2613 else
2614 strcat (buf, ", Unknown ARC");
2615 break;
2616 }
2617
2618 switch (e_flags & EF_ARC_OSABI_MSK)
2619 {
2620 case E_ARC_OSABI_ORIG:
2621 strcat (buf, ", (ABI:legacy)");
2622 break;
2623 case E_ARC_OSABI_V2:
2624 strcat (buf, ", (ABI:v2)");
2625 break;
2626 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2627 case E_ARC_OSABI_V3:
2628 strcat (buf, ", v3 no-legacy-syscalls ABI");
2629 break;
53a346d8
CZ
2630 case E_ARC_OSABI_V4:
2631 strcat (buf, ", v4 ABI");
2632 break;
a9522a21
AB
2633 default:
2634 strcat (buf, ", unrecognised ARC OSABI flag");
2635 break;
2636 }
2637}
2638
f3485b74 2639static void
d3ba0551 2640decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2641{
2642 unsigned eabi;
32ec8896 2643 bfd_boolean unknown = FALSE;
f3485b74
NC
2644
2645 eabi = EF_ARM_EABI_VERSION (e_flags);
2646 e_flags &= ~ EF_ARM_EABIMASK;
2647
2648 /* Handle "generic" ARM flags. */
2649 if (e_flags & EF_ARM_RELEXEC)
2650 {
2651 strcat (buf, ", relocatable executable");
2652 e_flags &= ~ EF_ARM_RELEXEC;
2653 }
76da6bbe 2654
18a20338
CL
2655 if (e_flags & EF_ARM_PIC)
2656 {
2657 strcat (buf, ", position independent");
2658 e_flags &= ~ EF_ARM_PIC;
2659 }
2660
f3485b74
NC
2661 /* Now handle EABI specific flags. */
2662 switch (eabi)
2663 {
2664 default:
2c71103e 2665 strcat (buf, ", <unrecognized EABI>");
f3485b74 2666 if (e_flags)
32ec8896 2667 unknown = TRUE;
f3485b74
NC
2668 break;
2669
2670 case EF_ARM_EABI_VER1:
a5bcd848 2671 strcat (buf, ", Version1 EABI");
f3485b74
NC
2672 while (e_flags)
2673 {
2674 unsigned flag;
76da6bbe 2675
f3485b74
NC
2676 /* Process flags one bit at a time. */
2677 flag = e_flags & - e_flags;
2678 e_flags &= ~ flag;
76da6bbe 2679
f3485b74
NC
2680 switch (flag)
2681 {
a5bcd848 2682 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2683 strcat (buf, ", sorted symbol tables");
2684 break;
76da6bbe 2685
f3485b74 2686 default:
32ec8896 2687 unknown = TRUE;
f3485b74
NC
2688 break;
2689 }
2690 }
2691 break;
76da6bbe 2692
a5bcd848
PB
2693 case EF_ARM_EABI_VER2:
2694 strcat (buf, ", Version2 EABI");
2695 while (e_flags)
2696 {
2697 unsigned flag;
2698
2699 /* Process flags one bit at a time. */
2700 flag = e_flags & - e_flags;
2701 e_flags &= ~ flag;
2702
2703 switch (flag)
2704 {
2705 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2706 strcat (buf, ", sorted symbol tables");
2707 break;
2708
2709 case EF_ARM_DYNSYMSUSESEGIDX:
2710 strcat (buf, ", dynamic symbols use segment index");
2711 break;
2712
2713 case EF_ARM_MAPSYMSFIRST:
2714 strcat (buf, ", mapping symbols precede others");
2715 break;
2716
2717 default:
32ec8896 2718 unknown = TRUE;
a5bcd848
PB
2719 break;
2720 }
2721 }
2722 break;
2723
d507cf36
PB
2724 case EF_ARM_EABI_VER3:
2725 strcat (buf, ", Version3 EABI");
8cb51566
PB
2726 break;
2727
2728 case EF_ARM_EABI_VER4:
2729 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2730 while (e_flags)
2731 {
2732 unsigned flag;
2733
2734 /* Process flags one bit at a time. */
2735 flag = e_flags & - e_flags;
2736 e_flags &= ~ flag;
2737
2738 switch (flag)
2739 {
2740 case EF_ARM_BE8:
2741 strcat (buf, ", BE8");
2742 break;
2743
2744 case EF_ARM_LE8:
2745 strcat (buf, ", LE8");
2746 break;
2747
2748 default:
32ec8896 2749 unknown = TRUE;
3bfcb652
NC
2750 break;
2751 }
3bfcb652
NC
2752 }
2753 break;
3a4a14e9
PB
2754
2755 case EF_ARM_EABI_VER5:
2756 strcat (buf, ", Version5 EABI");
d507cf36
PB
2757 while (e_flags)
2758 {
2759 unsigned flag;
2760
2761 /* Process flags one bit at a time. */
2762 flag = e_flags & - e_flags;
2763 e_flags &= ~ flag;
2764
2765 switch (flag)
2766 {
2767 case EF_ARM_BE8:
2768 strcat (buf, ", BE8");
2769 break;
2770
2771 case EF_ARM_LE8:
2772 strcat (buf, ", LE8");
2773 break;
2774
3bfcb652
NC
2775 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2776 strcat (buf, ", soft-float ABI");
2777 break;
2778
2779 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2780 strcat (buf, ", hard-float ABI");
2781 break;
2782
d507cf36 2783 default:
32ec8896 2784 unknown = TRUE;
d507cf36
PB
2785 break;
2786 }
2787 }
2788 break;
2789
f3485b74 2790 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2791 strcat (buf, ", GNU EABI");
f3485b74
NC
2792 while (e_flags)
2793 {
2794 unsigned flag;
76da6bbe 2795
f3485b74
NC
2796 /* Process flags one bit at a time. */
2797 flag = e_flags & - e_flags;
2798 e_flags &= ~ flag;
76da6bbe 2799
f3485b74
NC
2800 switch (flag)
2801 {
a5bcd848 2802 case EF_ARM_INTERWORK:
f3485b74
NC
2803 strcat (buf, ", interworking enabled");
2804 break;
76da6bbe 2805
a5bcd848 2806 case EF_ARM_APCS_26:
f3485b74
NC
2807 strcat (buf, ", uses APCS/26");
2808 break;
76da6bbe 2809
a5bcd848 2810 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2811 strcat (buf, ", uses APCS/float");
2812 break;
76da6bbe 2813
a5bcd848 2814 case EF_ARM_PIC:
f3485b74
NC
2815 strcat (buf, ", position independent");
2816 break;
76da6bbe 2817
a5bcd848 2818 case EF_ARM_ALIGN8:
f3485b74
NC
2819 strcat (buf, ", 8 bit structure alignment");
2820 break;
76da6bbe 2821
a5bcd848 2822 case EF_ARM_NEW_ABI:
f3485b74
NC
2823 strcat (buf, ", uses new ABI");
2824 break;
76da6bbe 2825
a5bcd848 2826 case EF_ARM_OLD_ABI:
f3485b74
NC
2827 strcat (buf, ", uses old ABI");
2828 break;
76da6bbe 2829
a5bcd848 2830 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2831 strcat (buf, ", software FP");
2832 break;
76da6bbe 2833
90e01f86
ILT
2834 case EF_ARM_VFP_FLOAT:
2835 strcat (buf, ", VFP");
2836 break;
2837
fde78edd
NC
2838 case EF_ARM_MAVERICK_FLOAT:
2839 strcat (buf, ", Maverick FP");
2840 break;
2841
f3485b74 2842 default:
32ec8896 2843 unknown = TRUE;
f3485b74
NC
2844 break;
2845 }
2846 }
2847 }
f3485b74
NC
2848
2849 if (unknown)
2b692964 2850 strcat (buf,_(", <unknown>"));
f3485b74
NC
2851}
2852
343433df
AB
2853static void
2854decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2855{
2856 --size; /* Leave space for null terminator. */
2857
2858 switch (e_flags & EF_AVR_MACH)
2859 {
2860 case E_AVR_MACH_AVR1:
2861 strncat (buf, ", avr:1", size);
2862 break;
2863 case E_AVR_MACH_AVR2:
2864 strncat (buf, ", avr:2", size);
2865 break;
2866 case E_AVR_MACH_AVR25:
2867 strncat (buf, ", avr:25", size);
2868 break;
2869 case E_AVR_MACH_AVR3:
2870 strncat (buf, ", avr:3", size);
2871 break;
2872 case E_AVR_MACH_AVR31:
2873 strncat (buf, ", avr:31", size);
2874 break;
2875 case E_AVR_MACH_AVR35:
2876 strncat (buf, ", avr:35", size);
2877 break;
2878 case E_AVR_MACH_AVR4:
2879 strncat (buf, ", avr:4", size);
2880 break;
2881 case E_AVR_MACH_AVR5:
2882 strncat (buf, ", avr:5", size);
2883 break;
2884 case E_AVR_MACH_AVR51:
2885 strncat (buf, ", avr:51", size);
2886 break;
2887 case E_AVR_MACH_AVR6:
2888 strncat (buf, ", avr:6", size);
2889 break;
2890 case E_AVR_MACH_AVRTINY:
2891 strncat (buf, ", avr:100", size);
2892 break;
2893 case E_AVR_MACH_XMEGA1:
2894 strncat (buf, ", avr:101", size);
2895 break;
2896 case E_AVR_MACH_XMEGA2:
2897 strncat (buf, ", avr:102", size);
2898 break;
2899 case E_AVR_MACH_XMEGA3:
2900 strncat (buf, ", avr:103", size);
2901 break;
2902 case E_AVR_MACH_XMEGA4:
2903 strncat (buf, ", avr:104", size);
2904 break;
2905 case E_AVR_MACH_XMEGA5:
2906 strncat (buf, ", avr:105", size);
2907 break;
2908 case E_AVR_MACH_XMEGA6:
2909 strncat (buf, ", avr:106", size);
2910 break;
2911 case E_AVR_MACH_XMEGA7:
2912 strncat (buf, ", avr:107", size);
2913 break;
2914 default:
2915 strncat (buf, ", avr:<unknown>", size);
2916 break;
2917 }
2918
2919 size -= strlen (buf);
2920 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2921 strncat (buf, ", link-relax", size);
2922}
2923
35c08157
KLC
2924static void
2925decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2926{
2927 unsigned abi;
2928 unsigned arch;
2929 unsigned config;
2930 unsigned version;
32ec8896
NC
2931 bfd_boolean has_fpu = FALSE;
2932 unsigned int r = 0;
35c08157
KLC
2933
2934 static const char *ABI_STRINGS[] =
2935 {
2936 "ABI v0", /* use r5 as return register; only used in N1213HC */
2937 "ABI v1", /* use r0 as return register */
2938 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2939 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2940 "AABI",
2941 "ABI2 FP+"
35c08157
KLC
2942 };
2943 static const char *VER_STRINGS[] =
2944 {
2945 "Andes ELF V1.3 or older",
2946 "Andes ELF V1.3.1",
2947 "Andes ELF V1.4"
2948 };
2949 static const char *ARCH_STRINGS[] =
2950 {
2951 "",
2952 "Andes Star v1.0",
2953 "Andes Star v2.0",
2954 "Andes Star v3.0",
2955 "Andes Star v3.0m"
2956 };
2957
2958 abi = EF_NDS_ABI & e_flags;
2959 arch = EF_NDS_ARCH & e_flags;
2960 config = EF_NDS_INST & e_flags;
2961 version = EF_NDS32_ELF_VERSION & e_flags;
2962
2963 memset (buf, 0, size);
2964
2965 switch (abi)
2966 {
2967 case E_NDS_ABI_V0:
2968 case E_NDS_ABI_V1:
2969 case E_NDS_ABI_V2:
2970 case E_NDS_ABI_V2FP:
2971 case E_NDS_ABI_AABI:
40c7a7cb 2972 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2973 /* In case there are holes in the array. */
2974 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2975 break;
2976
2977 default:
2978 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2979 break;
2980 }
2981
2982 switch (version)
2983 {
2984 case E_NDS32_ELF_VER_1_2:
2985 case E_NDS32_ELF_VER_1_3:
2986 case E_NDS32_ELF_VER_1_4:
2987 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2988 break;
2989
2990 default:
2991 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
2992 break;
2993 }
2994
2995 if (E_NDS_ABI_V0 == abi)
2996 {
2997 /* OLD ABI; only used in N1213HC, has performance extension 1. */
2998 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
2999 if (arch == E_NDS_ARCH_STAR_V1_0)
3000 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3001 return;
3002 }
3003
3004 switch (arch)
3005 {
3006 case E_NDS_ARCH_STAR_V1_0:
3007 case E_NDS_ARCH_STAR_V2_0:
3008 case E_NDS_ARCH_STAR_V3_0:
3009 case E_NDS_ARCH_STAR_V3_M:
3010 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3011 break;
3012
3013 default:
3014 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3015 /* ARCH version determines how the e_flags are interpreted.
3016 If it is unknown, we cannot proceed. */
3017 return;
3018 }
3019
3020 /* Newer ABI; Now handle architecture specific flags. */
3021 if (arch == E_NDS_ARCH_STAR_V1_0)
3022 {
3023 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3024 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3025
3026 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3027 r += snprintf (buf + r, size -r, ", MAC");
3028
3029 if (config & E_NDS32_HAS_DIV_INST)
3030 r += snprintf (buf + r, size -r, ", DIV");
3031
3032 if (config & E_NDS32_HAS_16BIT_INST)
3033 r += snprintf (buf + r, size -r, ", 16b");
3034 }
3035 else
3036 {
3037 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3038 {
3039 if (version <= E_NDS32_ELF_VER_1_3)
3040 r += snprintf (buf + r, size -r, ", [B8]");
3041 else
3042 r += snprintf (buf + r, size -r, ", EX9");
3043 }
3044
3045 if (config & E_NDS32_HAS_MAC_DX_INST)
3046 r += snprintf (buf + r, size -r, ", MAC_DX");
3047
3048 if (config & E_NDS32_HAS_DIV_DX_INST)
3049 r += snprintf (buf + r, size -r, ", DIV_DX");
3050
3051 if (config & E_NDS32_HAS_16BIT_INST)
3052 {
3053 if (version <= E_NDS32_ELF_VER_1_3)
3054 r += snprintf (buf + r, size -r, ", 16b");
3055 else
3056 r += snprintf (buf + r, size -r, ", IFC");
3057 }
3058 }
3059
3060 if (config & E_NDS32_HAS_EXT_INST)
3061 r += snprintf (buf + r, size -r, ", PERF1");
3062
3063 if (config & E_NDS32_HAS_EXT2_INST)
3064 r += snprintf (buf + r, size -r, ", PERF2");
3065
3066 if (config & E_NDS32_HAS_FPU_INST)
3067 {
32ec8896 3068 has_fpu = TRUE;
35c08157
KLC
3069 r += snprintf (buf + r, size -r, ", FPU_SP");
3070 }
3071
3072 if (config & E_NDS32_HAS_FPU_DP_INST)
3073 {
32ec8896 3074 has_fpu = TRUE;
35c08157
KLC
3075 r += snprintf (buf + r, size -r, ", FPU_DP");
3076 }
3077
3078 if (config & E_NDS32_HAS_FPU_MAC_INST)
3079 {
32ec8896 3080 has_fpu = TRUE;
35c08157
KLC
3081 r += snprintf (buf + r, size -r, ", FPU_MAC");
3082 }
3083
3084 if (has_fpu)
3085 {
3086 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3087 {
3088 case E_NDS32_FPU_REG_8SP_4DP:
3089 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3090 break;
3091 case E_NDS32_FPU_REG_16SP_8DP:
3092 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3093 break;
3094 case E_NDS32_FPU_REG_32SP_16DP:
3095 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3096 break;
3097 case E_NDS32_FPU_REG_32SP_32DP:
3098 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3099 break;
3100 }
3101 }
3102
3103 if (config & E_NDS32_HAS_AUDIO_INST)
3104 r += snprintf (buf + r, size -r, ", AUDIO");
3105
3106 if (config & E_NDS32_HAS_STRING_INST)
3107 r += snprintf (buf + r, size -r, ", STR");
3108
3109 if (config & E_NDS32_HAS_REDUCED_REGS)
3110 r += snprintf (buf + r, size -r, ", 16REG");
3111
3112 if (config & E_NDS32_HAS_VIDEO_INST)
3113 {
3114 if (version <= E_NDS32_ELF_VER_1_3)
3115 r += snprintf (buf + r, size -r, ", VIDEO");
3116 else
3117 r += snprintf (buf + r, size -r, ", SATURATION");
3118 }
3119
3120 if (config & E_NDS32_HAS_ENCRIPT_INST)
3121 r += snprintf (buf + r, size -r, ", ENCRP");
3122
3123 if (config & E_NDS32_HAS_L2C_INST)
3124 r += snprintf (buf + r, size -r, ", L2C");
3125}
3126
252b5132 3127static char *
dda8d76d 3128get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3129{
b34976b6 3130 static char buf[1024];
252b5132
RH
3131
3132 buf[0] = '\0';
76da6bbe 3133
252b5132
RH
3134 if (e_flags)
3135 {
3136 switch (e_machine)
3137 {
3138 default:
3139 break;
3140
886a2506 3141 case EM_ARC_COMPACT2:
886a2506 3142 case EM_ARC_COMPACT:
a9522a21
AB
3143 decode_ARC_machine_flags (e_flags, e_machine, buf);
3144 break;
886a2506 3145
f3485b74
NC
3146 case EM_ARM:
3147 decode_ARM_machine_flags (e_flags, buf);
3148 break;
76da6bbe 3149
343433df
AB
3150 case EM_AVR:
3151 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3152 break;
3153
781303ce
MF
3154 case EM_BLACKFIN:
3155 if (e_flags & EF_BFIN_PIC)
3156 strcat (buf, ", PIC");
3157
3158 if (e_flags & EF_BFIN_FDPIC)
3159 strcat (buf, ", FDPIC");
3160
3161 if (e_flags & EF_BFIN_CODE_IN_L1)
3162 strcat (buf, ", code in L1");
3163
3164 if (e_flags & EF_BFIN_DATA_IN_L1)
3165 strcat (buf, ", data in L1");
3166
3167 break;
3168
ec2dfb42
AO
3169 case EM_CYGNUS_FRV:
3170 switch (e_flags & EF_FRV_CPU_MASK)
3171 {
3172 case EF_FRV_CPU_GENERIC:
3173 break;
3174
3175 default:
3176 strcat (buf, ", fr???");
3177 break;
57346661 3178
ec2dfb42
AO
3179 case EF_FRV_CPU_FR300:
3180 strcat (buf, ", fr300");
3181 break;
3182
3183 case EF_FRV_CPU_FR400:
3184 strcat (buf, ", fr400");
3185 break;
3186 case EF_FRV_CPU_FR405:
3187 strcat (buf, ", fr405");
3188 break;
3189
3190 case EF_FRV_CPU_FR450:
3191 strcat (buf, ", fr450");
3192 break;
3193
3194 case EF_FRV_CPU_FR500:
3195 strcat (buf, ", fr500");
3196 break;
3197 case EF_FRV_CPU_FR550:
3198 strcat (buf, ", fr550");
3199 break;
3200
3201 case EF_FRV_CPU_SIMPLE:
3202 strcat (buf, ", simple");
3203 break;
3204 case EF_FRV_CPU_TOMCAT:
3205 strcat (buf, ", tomcat");
3206 break;
3207 }
1c877e87 3208 break;
ec2dfb42 3209
53c7db4b 3210 case EM_68K:
425c6cb0 3211 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3212 strcat (buf, ", m68000");
425c6cb0 3213 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3214 strcat (buf, ", cpu32");
3215 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3216 strcat (buf, ", fido_a");
425c6cb0 3217 else
266abb8f 3218 {
2cf0635d
NC
3219 char const * isa = _("unknown");
3220 char const * mac = _("unknown mac");
3221 char const * additional = NULL;
0112cd26 3222
c694fd50 3223 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3224 {
c694fd50 3225 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3226 isa = "A";
3227 additional = ", nodiv";
3228 break;
c694fd50 3229 case EF_M68K_CF_ISA_A:
266abb8f
NS
3230 isa = "A";
3231 break;
c694fd50 3232 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3233 isa = "A+";
3234 break;
c694fd50 3235 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3236 isa = "B";
3237 additional = ", nousp";
3238 break;
c694fd50 3239 case EF_M68K_CF_ISA_B:
266abb8f
NS
3240 isa = "B";
3241 break;
f608cd77
NS
3242 case EF_M68K_CF_ISA_C:
3243 isa = "C";
3244 break;
3245 case EF_M68K_CF_ISA_C_NODIV:
3246 isa = "C";
3247 additional = ", nodiv";
3248 break;
266abb8f
NS
3249 }
3250 strcat (buf, ", cf, isa ");
3251 strcat (buf, isa);
0b2e31dc
NS
3252 if (additional)
3253 strcat (buf, additional);
c694fd50 3254 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3255 strcat (buf, ", float");
c694fd50 3256 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3257 {
3258 case 0:
3259 mac = NULL;
3260 break;
c694fd50 3261 case EF_M68K_CF_MAC:
266abb8f
NS
3262 mac = "mac";
3263 break;
c694fd50 3264 case EF_M68K_CF_EMAC:
266abb8f
NS
3265 mac = "emac";
3266 break;
f608cd77
NS
3267 case EF_M68K_CF_EMAC_B:
3268 mac = "emac_b";
3269 break;
266abb8f
NS
3270 }
3271 if (mac)
3272 {
3273 strcat (buf, ", ");
3274 strcat (buf, mac);
3275 }
266abb8f 3276 }
53c7db4b 3277 break;
33c63f9d 3278
153a2776
NC
3279 case EM_CYGNUS_MEP:
3280 switch (e_flags & EF_MEP_CPU_MASK)
3281 {
3282 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3283 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3284 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3285 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3286 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3287 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3288 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3289 }
3290
3291 switch (e_flags & EF_MEP_COP_MASK)
3292 {
3293 case EF_MEP_COP_NONE: break;
3294 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3295 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3296 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3297 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3298 default: strcat (buf, _("<unknown MeP copro type>")); break;
3299 }
3300
3301 if (e_flags & EF_MEP_LIBRARY)
3302 strcat (buf, ", Built for Library");
3303
3304 if (e_flags & EF_MEP_INDEX_MASK)
3305 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3306 e_flags & EF_MEP_INDEX_MASK);
3307
3308 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3309 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3310 e_flags & ~ EF_MEP_ALL_FLAGS);
3311 break;
3312
252b5132
RH
3313 case EM_PPC:
3314 if (e_flags & EF_PPC_EMB)
3315 strcat (buf, ", emb");
3316
3317 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3318 strcat (buf, _(", relocatable"));
252b5132
RH
3319
3320 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3321 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3322 break;
3323
ee67d69a
AM
3324 case EM_PPC64:
3325 if (e_flags & EF_PPC64_ABI)
3326 {
3327 char abi[] = ", abiv0";
3328
3329 abi[6] += e_flags & EF_PPC64_ABI;
3330 strcat (buf, abi);
3331 }
3332 break;
3333
708e2187
NC
3334 case EM_V800:
3335 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3336 strcat (buf, ", RH850 ABI");
0b4362b0 3337
708e2187
NC
3338 if (e_flags & EF_V800_850E3)
3339 strcat (buf, ", V3 architecture");
3340
3341 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3342 strcat (buf, ", FPU not used");
3343
3344 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3345 strcat (buf, ", regmode: COMMON");
3346
3347 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3348 strcat (buf, ", r4 not used");
3349
3350 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3351 strcat (buf, ", r30 not used");
3352
3353 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3354 strcat (buf, ", r5 not used");
3355
3356 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3357 strcat (buf, ", r2 not used");
3358
3359 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3360 {
3361 switch (e_flags & - e_flags)
3362 {
3363 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3364 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3365 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3366 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3367 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3368 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3369 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3370 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3371 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3372 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3373 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3374 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3375 default: break;
3376 }
3377 }
3378 break;
3379
2b0337b0 3380 case EM_V850:
252b5132
RH
3381 case EM_CYGNUS_V850:
3382 switch (e_flags & EF_V850_ARCH)
3383 {
78c8d46c
NC
3384 case E_V850E3V5_ARCH:
3385 strcat (buf, ", v850e3v5");
3386 break;
1cd986c5
NC
3387 case E_V850E2V3_ARCH:
3388 strcat (buf, ", v850e2v3");
3389 break;
3390 case E_V850E2_ARCH:
3391 strcat (buf, ", v850e2");
3392 break;
3393 case E_V850E1_ARCH:
3394 strcat (buf, ", v850e1");
8ad30312 3395 break;
252b5132
RH
3396 case E_V850E_ARCH:
3397 strcat (buf, ", v850e");
3398 break;
252b5132
RH
3399 case E_V850_ARCH:
3400 strcat (buf, ", v850");
3401 break;
3402 default:
2b692964 3403 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3404 break;
3405 }
3406 break;
3407
2b0337b0 3408 case EM_M32R:
252b5132
RH
3409 case EM_CYGNUS_M32R:
3410 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3411 strcat (buf, ", m32r");
252b5132
RH
3412 break;
3413
3414 case EM_MIPS:
4fe85591 3415 case EM_MIPS_RS3_LE:
252b5132
RH
3416 if (e_flags & EF_MIPS_NOREORDER)
3417 strcat (buf, ", noreorder");
3418
3419 if (e_flags & EF_MIPS_PIC)
3420 strcat (buf, ", pic");
3421
3422 if (e_flags & EF_MIPS_CPIC)
3423 strcat (buf, ", cpic");
3424
d1bdd336
TS
3425 if (e_flags & EF_MIPS_UCODE)
3426 strcat (buf, ", ugen_reserved");
3427
252b5132
RH
3428 if (e_flags & EF_MIPS_ABI2)
3429 strcat (buf, ", abi2");
3430
43521d43
TS
3431 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3432 strcat (buf, ", odk first");
3433
a5d22d2a
TS
3434 if (e_flags & EF_MIPS_32BITMODE)
3435 strcat (buf, ", 32bitmode");
3436
ba92f887
MR
3437 if (e_flags & EF_MIPS_NAN2008)
3438 strcat (buf, ", nan2008");
3439
fef1b0b3
SE
3440 if (e_flags & EF_MIPS_FP64)
3441 strcat (buf, ", fp64");
3442
156c2f8b
NC
3443 switch ((e_flags & EF_MIPS_MACH))
3444 {
3445 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3446 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3447 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3448 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3449 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3450 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3451 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3452 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3453 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3454 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3455 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3456 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3457 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3458 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3459 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3460 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3461 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3462 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3463 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3464 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3465 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3466 case 0:
3467 /* We simply ignore the field in this case to avoid confusion:
3468 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3469 extension. */
3470 break;
2b692964 3471 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3472 }
43521d43
TS
3473
3474 switch ((e_flags & EF_MIPS_ABI))
3475 {
3476 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3477 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3478 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3479 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3480 case 0:
3481 /* We simply ignore the field in this case to avoid confusion:
3482 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3483 This means it is likely to be an o32 file, but not for
3484 sure. */
3485 break;
2b692964 3486 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3487 }
3488
3489 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3490 strcat (buf, ", mdmx");
3491
3492 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3493 strcat (buf, ", mips16");
3494
df58fc94
RS
3495 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3496 strcat (buf, ", micromips");
3497
43521d43
TS
3498 switch ((e_flags & EF_MIPS_ARCH))
3499 {
3500 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3501 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3502 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3503 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3504 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3505 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3506 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3507 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3508 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3509 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3510 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3511 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3512 }
252b5132 3513 break;
351b4b40 3514
35c08157
KLC
3515 case EM_NDS32:
3516 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3517 break;
3518
fe944acf
FT
3519 case EM_NFP:
3520 switch (EF_NFP_MACH (e_flags))
3521 {
3522 case E_NFP_MACH_3200:
3523 strcat (buf, ", NFP-32xx");
3524 break;
3525 case E_NFP_MACH_6000:
3526 strcat (buf, ", NFP-6xxx");
3527 break;
3528 }
3529 break;
3530
e23eba97
NC
3531 case EM_RISCV:
3532 if (e_flags & EF_RISCV_RVC)
3533 strcat (buf, ", RVC");
2922d21d 3534
7f999549
JW
3535 if (e_flags & EF_RISCV_RVE)
3536 strcat (buf, ", RVE");
3537
2922d21d
AW
3538 switch (e_flags & EF_RISCV_FLOAT_ABI)
3539 {
3540 case EF_RISCV_FLOAT_ABI_SOFT:
3541 strcat (buf, ", soft-float ABI");
3542 break;
3543
3544 case EF_RISCV_FLOAT_ABI_SINGLE:
3545 strcat (buf, ", single-float ABI");
3546 break;
3547
3548 case EF_RISCV_FLOAT_ABI_DOUBLE:
3549 strcat (buf, ", double-float ABI");
3550 break;
3551
3552 case EF_RISCV_FLOAT_ABI_QUAD:
3553 strcat (buf, ", quad-float ABI");
3554 break;
3555 }
e23eba97
NC
3556 break;
3557
ccde1100
AO
3558 case EM_SH:
3559 switch ((e_flags & EF_SH_MACH_MASK))
3560 {
3561 case EF_SH1: strcat (buf, ", sh1"); break;
3562 case EF_SH2: strcat (buf, ", sh2"); break;
3563 case EF_SH3: strcat (buf, ", sh3"); break;
3564 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3565 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3566 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3567 case EF_SH3E: strcat (buf, ", sh3e"); break;
3568 case EF_SH4: strcat (buf, ", sh4"); break;
3569 case EF_SH5: strcat (buf, ", sh5"); break;
3570 case EF_SH2E: strcat (buf, ", sh2e"); break;
3571 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3572 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3573 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3574 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3575 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3576 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3577 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3578 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3579 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3580 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3581 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3582 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3583 }
3584
cec6a5b8
MR
3585 if (e_flags & EF_SH_PIC)
3586 strcat (buf, ", pic");
3587
3588 if (e_flags & EF_SH_FDPIC)
3589 strcat (buf, ", fdpic");
ccde1100 3590 break;
948f632f 3591
73589c9d
CS
3592 case EM_OR1K:
3593 if (e_flags & EF_OR1K_NODELAY)
3594 strcat (buf, ", no delay");
3595 break;
57346661 3596
351b4b40
RH
3597 case EM_SPARCV9:
3598 if (e_flags & EF_SPARC_32PLUS)
3599 strcat (buf, ", v8+");
3600
3601 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3602 strcat (buf, ", ultrasparcI");
3603
3604 if (e_flags & EF_SPARC_SUN_US3)
3605 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3606
3607 if (e_flags & EF_SPARC_HAL_R1)
3608 strcat (buf, ", halr1");
3609
3610 if (e_flags & EF_SPARC_LEDATA)
3611 strcat (buf, ", ledata");
3612
3613 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3614 strcat (buf, ", tso");
3615
3616 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3617 strcat (buf, ", pso");
3618
3619 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3620 strcat (buf, ", rmo");
3621 break;
7d466069 3622
103f02d3
UD
3623 case EM_PARISC:
3624 switch (e_flags & EF_PARISC_ARCH)
3625 {
3626 case EFA_PARISC_1_0:
3627 strcpy (buf, ", PA-RISC 1.0");
3628 break;
3629 case EFA_PARISC_1_1:
3630 strcpy (buf, ", PA-RISC 1.1");
3631 break;
3632 case EFA_PARISC_2_0:
3633 strcpy (buf, ", PA-RISC 2.0");
3634 break;
3635 default:
3636 break;
3637 }
3638 if (e_flags & EF_PARISC_TRAPNIL)
3639 strcat (buf, ", trapnil");
3640 if (e_flags & EF_PARISC_EXT)
3641 strcat (buf, ", ext");
3642 if (e_flags & EF_PARISC_LSB)
3643 strcat (buf, ", lsb");
3644 if (e_flags & EF_PARISC_WIDE)
3645 strcat (buf, ", wide");
3646 if (e_flags & EF_PARISC_NO_KABP)
3647 strcat (buf, ", no kabp");
3648 if (e_flags & EF_PARISC_LAZYSWAP)
3649 strcat (buf, ", lazyswap");
30800947 3650 break;
76da6bbe 3651
7d466069 3652 case EM_PJ:
2b0337b0 3653 case EM_PJ_OLD:
7d466069
ILT
3654 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3655 strcat (buf, ", new calling convention");
3656
3657 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3658 strcat (buf, ", gnu calling convention");
3659 break;
4d6ed7c8
NC
3660
3661 case EM_IA_64:
3662 if ((e_flags & EF_IA_64_ABI64))
3663 strcat (buf, ", 64-bit");
3664 else
3665 strcat (buf, ", 32-bit");
3666 if ((e_flags & EF_IA_64_REDUCEDFP))
3667 strcat (buf, ", reduced fp model");
3668 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3669 strcat (buf, ", no function descriptors, constant gp");
3670 else if ((e_flags & EF_IA_64_CONS_GP))
3671 strcat (buf, ", constant gp");
3672 if ((e_flags & EF_IA_64_ABSOLUTE))
3673 strcat (buf, ", absolute");
dda8d76d 3674 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3675 {
3676 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3677 strcat (buf, ", vms_linkages");
3678 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3679 {
3680 case EF_IA_64_VMS_COMCOD_SUCCESS:
3681 break;
3682 case EF_IA_64_VMS_COMCOD_WARNING:
3683 strcat (buf, ", warning");
3684 break;
3685 case EF_IA_64_VMS_COMCOD_ERROR:
3686 strcat (buf, ", error");
3687 break;
3688 case EF_IA_64_VMS_COMCOD_ABORT:
3689 strcat (buf, ", abort");
3690 break;
3691 default:
bee0ee85
NC
3692 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3693 e_flags & EF_IA_64_VMS_COMCOD);
3694 strcat (buf, ", <unknown>");
28f997cf
TG
3695 }
3696 }
4d6ed7c8 3697 break;
179d3252
JT
3698
3699 case EM_VAX:
3700 if ((e_flags & EF_VAX_NONPIC))
3701 strcat (buf, ", non-PIC");
3702 if ((e_flags & EF_VAX_DFLOAT))
3703 strcat (buf, ", D-Float");
3704 if ((e_flags & EF_VAX_GFLOAT))
3705 strcat (buf, ", G-Float");
3706 break;
c7927a3c 3707
619ed720
EB
3708 case EM_VISIUM:
3709 if (e_flags & EF_VISIUM_ARCH_MCM)
3710 strcat (buf, ", mcm");
3711 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3712 strcat (buf, ", mcm24");
3713 if (e_flags & EF_VISIUM_ARCH_GR6)
3714 strcat (buf, ", gr6");
3715 break;
3716
4046d87a 3717 case EM_RL78:
1740ba0c
NC
3718 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3719 {
3720 case E_FLAG_RL78_ANY_CPU: break;
3721 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3722 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3723 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3724 }
856ea05c
KP
3725 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3726 strcat (buf, ", 64-bit doubles");
4046d87a 3727 break;
0b4362b0 3728
c7927a3c
NC
3729 case EM_RX:
3730 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3731 strcat (buf, ", 64-bit doubles");
3732 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3733 strcat (buf, ", dsp");
d4cb0ea0 3734 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3735 strcat (buf, ", pid");
708e2187
NC
3736 if (e_flags & E_FLAG_RX_ABI)
3737 strcat (buf, ", RX ABI");
3525236c
NC
3738 if (e_flags & E_FLAG_RX_SINSNS_SET)
3739 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3740 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3741 if (e_flags & E_FLAG_RX_V2)
3742 strcat (buf, ", V2");
f87673e0
YS
3743 if (e_flags & E_FLAG_RX_V3)
3744 strcat (buf, ", V3");
d4cb0ea0 3745 break;
55786da2
AK
3746
3747 case EM_S390:
3748 if (e_flags & EF_S390_HIGH_GPRS)
3749 strcat (buf, ", highgprs");
d4cb0ea0 3750 break;
40b36596
JM
3751
3752 case EM_TI_C6000:
3753 if ((e_flags & EF_C6000_REL))
3754 strcat (buf, ", relocatable module");
d4cb0ea0 3755 break;
13761a11
NC
3756
3757 case EM_MSP430:
3758 strcat (buf, _(": architecture variant: "));
3759 switch (e_flags & EF_MSP430_MACH)
3760 {
3761 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3762 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3763 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3764 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3765 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3766 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3767 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3768 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3769 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3770 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3771 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3772 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3773 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3774 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3775 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3776 default:
3777 strcat (buf, _(": unknown")); break;
3778 }
3779
3780 if (e_flags & ~ EF_MSP430_MACH)
3781 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
3782 break;
3783
3784 case EM_Z80:
3785 switch (e_flags & EF_Z80_MACH_MSK)
3786 {
3787 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
3788 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
3789 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
3790 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
3791 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
3792 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 3793 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
3794 default:
3795 strcat (buf, _(", unknown")); break;
3796 }
3797 break;
252b5132
RH
3798 }
3799 }
3800
3801 return buf;
3802}
3803
252b5132 3804static const char *
dda8d76d 3805get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3806{
3807 static char buff[32];
3808
3809 switch (osabi)
3810 {
3811 case ELFOSABI_NONE: return "UNIX - System V";
3812 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3813 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3814 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3815 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3816 case ELFOSABI_AIX: return "UNIX - AIX";
3817 case ELFOSABI_IRIX: return "UNIX - IRIX";
3818 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3819 case ELFOSABI_TRU64: return "UNIX - TRU64";
3820 case ELFOSABI_MODESTO: return "Novell - Modesto";
3821 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3822 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3823 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3824 case ELFOSABI_AROS: return "AROS";
11636f9e 3825 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3826 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3827 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3828 default:
40b36596 3829 if (osabi >= 64)
dda8d76d 3830 switch (filedata->file_header.e_machine)
40b36596
JM
3831 {
3832 case EM_ARM:
3833 switch (osabi)
3834 {
3835 case ELFOSABI_ARM: return "ARM";
18a20338 3836 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3837 default:
3838 break;
3839 }
3840 break;
3841
3842 case EM_MSP430:
3843 case EM_MSP430_OLD:
619ed720 3844 case EM_VISIUM:
40b36596
JM
3845 switch (osabi)
3846 {
3847 case ELFOSABI_STANDALONE: return _("Standalone App");
3848 default:
3849 break;
3850 }
3851 break;
3852
3853 case EM_TI_C6000:
3854 switch (osabi)
3855 {
3856 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3857 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3858 default:
3859 break;
3860 }
3861 break;
3862
3863 default:
3864 break;
3865 }
e9e44622 3866 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3867 return buff;
3868 }
3869}
3870
a06ea964
NC
3871static const char *
3872get_aarch64_segment_type (unsigned long type)
3873{
3874 switch (type)
3875 {
32ec8896
NC
3876 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3877 default: return NULL;
a06ea964 3878 }
a06ea964
NC
3879}
3880
b294bdf8
MM
3881static const char *
3882get_arm_segment_type (unsigned long type)
3883{
3884 switch (type)
3885 {
32ec8896
NC
3886 case PT_ARM_EXIDX: return "EXIDX";
3887 default: return NULL;
b294bdf8 3888 }
b294bdf8
MM
3889}
3890
b4cbbe8f
AK
3891static const char *
3892get_s390_segment_type (unsigned long type)
3893{
3894 switch (type)
3895 {
3896 case PT_S390_PGSTE: return "S390_PGSTE";
3897 default: return NULL;
3898 }
3899}
3900
d3ba0551
AM
3901static const char *
3902get_mips_segment_type (unsigned long type)
252b5132
RH
3903{
3904 switch (type)
3905 {
32ec8896
NC
3906 case PT_MIPS_REGINFO: return "REGINFO";
3907 case PT_MIPS_RTPROC: return "RTPROC";
3908 case PT_MIPS_OPTIONS: return "OPTIONS";
3909 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3910 default: return NULL;
252b5132 3911 }
252b5132
RH
3912}
3913
103f02d3 3914static const char *
d3ba0551 3915get_parisc_segment_type (unsigned long type)
103f02d3
UD
3916{
3917 switch (type)
3918 {
103f02d3
UD
3919 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3920 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3921 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3922 default: return NULL;
103f02d3 3923 }
103f02d3
UD
3924}
3925
4d6ed7c8 3926static const char *
d3ba0551 3927get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3928{
3929 switch (type)
3930 {
3931 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3932 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 3933 default: return NULL;
4d6ed7c8 3934 }
4d6ed7c8
NC
3935}
3936
40b36596
JM
3937static const char *
3938get_tic6x_segment_type (unsigned long type)
3939{
3940 switch (type)
3941 {
32ec8896
NC
3942 case PT_C6000_PHATTR: return "C6000_PHATTR";
3943 default: return NULL;
40b36596 3944 }
40b36596
JM
3945}
3946
df3a023b
AM
3947static const char *
3948get_hpux_segment_type (unsigned long type, unsigned e_machine)
3949{
3950 if (e_machine == EM_PARISC)
3951 switch (type)
3952 {
3953 case PT_HP_TLS: return "HP_TLS";
3954 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3955 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3956 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3957 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3958 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3959 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3960 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3961 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3962 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3963 case PT_HP_PARALLEL: return "HP_PARALLEL";
3964 case PT_HP_FASTBIND: return "HP_FASTBIND";
3965 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3966 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3967 case PT_HP_STACK: return "HP_STACK";
3968 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
3969 default: return NULL;
3970 }
3971
3972 if (e_machine == EM_IA_64)
3973 switch (type)
3974 {
3975 case PT_HP_TLS: return "HP_TLS";
3976 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3977 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3978 case PT_IA_64_HP_STACK: return "HP_STACK";
3979 default: return NULL;
3980 }
3981
3982 return NULL;
3983}
3984
5522f910
NC
3985static const char *
3986get_solaris_segment_type (unsigned long type)
3987{
3988 switch (type)
3989 {
3990 case 0x6464e550: return "PT_SUNW_UNWIND";
3991 case 0x6474e550: return "PT_SUNW_EH_FRAME";
3992 case 0x6ffffff7: return "PT_LOSUNW";
3993 case 0x6ffffffa: return "PT_SUNWBSS";
3994 case 0x6ffffffb: return "PT_SUNWSTACK";
3995 case 0x6ffffffc: return "PT_SUNWDTRACE";
3996 case 0x6ffffffd: return "PT_SUNWCAP";
3997 case 0x6fffffff: return "PT_HISUNW";
32ec8896 3998 default: return NULL;
5522f910
NC
3999 }
4000}
4001
252b5132 4002static const char *
dda8d76d 4003get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4004{
b34976b6 4005 static char buff[32];
252b5132
RH
4006
4007 switch (p_type)
4008 {
b34976b6
AM
4009 case PT_NULL: return "NULL";
4010 case PT_LOAD: return "LOAD";
252b5132 4011 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4012 case PT_INTERP: return "INTERP";
4013 case PT_NOTE: return "NOTE";
4014 case PT_SHLIB: return "SHLIB";
4015 case PT_PHDR: return "PHDR";
13ae64f3 4016 case PT_TLS: return "TLS";
32ec8896 4017 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4018 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4019 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4020 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4021
252b5132 4022 default:
df3a023b 4023 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4024 {
2cf0635d 4025 const char * result;
103f02d3 4026
dda8d76d 4027 switch (filedata->file_header.e_machine)
252b5132 4028 {
a06ea964
NC
4029 case EM_AARCH64:
4030 result = get_aarch64_segment_type (p_type);
4031 break;
b294bdf8
MM
4032 case EM_ARM:
4033 result = get_arm_segment_type (p_type);
4034 break;
252b5132 4035 case EM_MIPS:
4fe85591 4036 case EM_MIPS_RS3_LE:
252b5132
RH
4037 result = get_mips_segment_type (p_type);
4038 break;
103f02d3
UD
4039 case EM_PARISC:
4040 result = get_parisc_segment_type (p_type);
4041 break;
4d6ed7c8
NC
4042 case EM_IA_64:
4043 result = get_ia64_segment_type (p_type);
4044 break;
40b36596
JM
4045 case EM_TI_C6000:
4046 result = get_tic6x_segment_type (p_type);
4047 break;
b4cbbe8f
AK
4048 case EM_S390:
4049 case EM_S390_OLD:
4050 result = get_s390_segment_type (p_type);
4051 break;
252b5132
RH
4052 default:
4053 result = NULL;
4054 break;
4055 }
103f02d3 4056
252b5132
RH
4057 if (result != NULL)
4058 return result;
103f02d3 4059
1a9ccd70 4060 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4061 }
4062 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4063 {
df3a023b 4064 const char * result = NULL;
103f02d3 4065
df3a023b 4066 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4067 {
df3a023b
AM
4068 case ELFOSABI_GNU:
4069 case ELFOSABI_FREEBSD:
4070 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4071 {
4072 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4073 result = buff;
4074 }
103f02d3 4075 break;
df3a023b
AM
4076 case ELFOSABI_HPUX:
4077 result = get_hpux_segment_type (p_type,
4078 filedata->file_header.e_machine);
4079 break;
4080 case ELFOSABI_SOLARIS:
4081 result = get_solaris_segment_type (p_type);
00428cca 4082 break;
103f02d3 4083 default:
103f02d3
UD
4084 break;
4085 }
103f02d3
UD
4086 if (result != NULL)
4087 return result;
4088
1a9ccd70 4089 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4090 }
252b5132 4091 else
e9e44622 4092 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4093
4094 return buff;
4095 }
4096}
4097
53a346d8
CZ
4098static const char *
4099get_arc_section_type_name (unsigned int sh_type)
4100{
4101 switch (sh_type)
4102 {
4103 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4104 default:
4105 break;
4106 }
4107 return NULL;
4108}
4109
252b5132 4110static const char *
d3ba0551 4111get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4112{
4113 switch (sh_type)
4114 {
b34976b6
AM
4115 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4116 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4117 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4118 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4119 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4120 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4121 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4122 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4123 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4124 case SHT_MIPS_RELD: return "MIPS_RELD";
4125 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4126 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4127 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4128 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4129 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4130 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4131 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4132 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4133 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4134 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4135 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4136 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4137 case SHT_MIPS_LINE: return "MIPS_LINE";
4138 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4139 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4140 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4141 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4142 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4143 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4144 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4145 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4146 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4147 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4148 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4149 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4150 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4151 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4152 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4153 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4154 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4155 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4156 default:
4157 break;
4158 }
4159 return NULL;
4160}
4161
103f02d3 4162static const char *
d3ba0551 4163get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4164{
4165 switch (sh_type)
4166 {
4167 case SHT_PARISC_EXT: return "PARISC_EXT";
4168 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4169 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4170 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4171 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4172 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4173 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4174 default: return NULL;
103f02d3 4175 }
103f02d3
UD
4176}
4177
4d6ed7c8 4178static const char *
dda8d76d 4179get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4180{
18bd398b 4181 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4182 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4183 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4184
4d6ed7c8
NC
4185 switch (sh_type)
4186 {
148b93f2
NC
4187 case SHT_IA_64_EXT: return "IA_64_EXT";
4188 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4189 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4190 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4191 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4192 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4193 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4194 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4195 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4196 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4197 default:
4198 break;
4199 }
4200 return NULL;
4201}
4202
d2b2c203
DJ
4203static const char *
4204get_x86_64_section_type_name (unsigned int sh_type)
4205{
4206 switch (sh_type)
4207 {
4208 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4209 default: return NULL;
d2b2c203 4210 }
d2b2c203
DJ
4211}
4212
a06ea964
NC
4213static const char *
4214get_aarch64_section_type_name (unsigned int sh_type)
4215{
4216 switch (sh_type)
4217 {
32ec8896
NC
4218 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4219 default: return NULL;
a06ea964 4220 }
a06ea964
NC
4221}
4222
40a18ebd
NC
4223static const char *
4224get_arm_section_type_name (unsigned int sh_type)
4225{
4226 switch (sh_type)
4227 {
7f6fed87
NC
4228 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4229 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4230 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4231 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4232 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4233 default: return NULL;
40a18ebd 4234 }
40a18ebd
NC
4235}
4236
40b36596
JM
4237static const char *
4238get_tic6x_section_type_name (unsigned int sh_type)
4239{
4240 switch (sh_type)
4241 {
32ec8896
NC
4242 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4243 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4244 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4245 case SHT_TI_ICODE: return "TI_ICODE";
4246 case SHT_TI_XREF: return "TI_XREF";
4247 case SHT_TI_HANDLER: return "TI_HANDLER";
4248 case SHT_TI_INITINFO: return "TI_INITINFO";
4249 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4250 default: return NULL;
40b36596 4251 }
40b36596
JM
4252}
4253
13761a11
NC
4254static const char *
4255get_msp430x_section_type_name (unsigned int sh_type)
4256{
4257 switch (sh_type)
4258 {
32ec8896
NC
4259 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4260 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4261 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4262 default: return NULL;
13761a11
NC
4263 }
4264}
4265
fe944acf
FT
4266static const char *
4267get_nfp_section_type_name (unsigned int sh_type)
4268{
4269 switch (sh_type)
4270 {
4271 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4272 case SHT_NFP_INITREG: return "NFP_INITREG";
4273 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4274 default: return NULL;
4275 }
4276}
4277
685080f2
NC
4278static const char *
4279get_v850_section_type_name (unsigned int sh_type)
4280{
4281 switch (sh_type)
4282 {
32ec8896
NC
4283 case SHT_V850_SCOMMON: return "V850 Small Common";
4284 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4285 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4286 case SHT_RENESAS_IOP: return "RENESAS IOP";
4287 case SHT_RENESAS_INFO: return "RENESAS INFO";
4288 default: return NULL;
685080f2
NC
4289 }
4290}
4291
2dc8dd17
JW
4292static const char *
4293get_riscv_section_type_name (unsigned int sh_type)
4294{
4295 switch (sh_type)
4296 {
4297 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4298 default: return NULL;
4299 }
4300}
4301
252b5132 4302static const char *
dda8d76d 4303get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4304{
b34976b6 4305 static char buff[32];
9fb71ee4 4306 const char * result;
252b5132
RH
4307
4308 switch (sh_type)
4309 {
4310 case SHT_NULL: return "NULL";
4311 case SHT_PROGBITS: return "PROGBITS";
4312 case SHT_SYMTAB: return "SYMTAB";
4313 case SHT_STRTAB: return "STRTAB";
4314 case SHT_RELA: return "RELA";
4315 case SHT_HASH: return "HASH";
4316 case SHT_DYNAMIC: return "DYNAMIC";
4317 case SHT_NOTE: return "NOTE";
4318 case SHT_NOBITS: return "NOBITS";
4319 case SHT_REL: return "REL";
4320 case SHT_SHLIB: return "SHLIB";
4321 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4322 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4323 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4324 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4325 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4326 case SHT_GROUP: return "GROUP";
67ce483b 4327 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4328 case SHT_GNU_verdef: return "VERDEF";
4329 case SHT_GNU_verneed: return "VERNEED";
4330 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4331 case 0x6ffffff0: return "VERSYM";
4332 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4333 case 0x7ffffffd: return "AUXILIARY";
4334 case 0x7fffffff: return "FILTER";
047b2264 4335 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4336
4337 default:
4338 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4339 {
dda8d76d 4340 switch (filedata->file_header.e_machine)
252b5132 4341 {
53a346d8
CZ
4342 case EM_ARC:
4343 case EM_ARC_COMPACT:
4344 case EM_ARC_COMPACT2:
4345 result = get_arc_section_type_name (sh_type);
4346 break;
252b5132 4347 case EM_MIPS:
4fe85591 4348 case EM_MIPS_RS3_LE:
252b5132
RH
4349 result = get_mips_section_type_name (sh_type);
4350 break;
103f02d3
UD
4351 case EM_PARISC:
4352 result = get_parisc_section_type_name (sh_type);
4353 break;
4d6ed7c8 4354 case EM_IA_64:
dda8d76d 4355 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4356 break;
d2b2c203 4357 case EM_X86_64:
8a9036a4 4358 case EM_L1OM:
7a9068fe 4359 case EM_K1OM:
d2b2c203
DJ
4360 result = get_x86_64_section_type_name (sh_type);
4361 break;
a06ea964
NC
4362 case EM_AARCH64:
4363 result = get_aarch64_section_type_name (sh_type);
4364 break;
40a18ebd
NC
4365 case EM_ARM:
4366 result = get_arm_section_type_name (sh_type);
4367 break;
40b36596
JM
4368 case EM_TI_C6000:
4369 result = get_tic6x_section_type_name (sh_type);
4370 break;
13761a11
NC
4371 case EM_MSP430:
4372 result = get_msp430x_section_type_name (sh_type);
4373 break;
fe944acf
FT
4374 case EM_NFP:
4375 result = get_nfp_section_type_name (sh_type);
4376 break;
685080f2
NC
4377 case EM_V800:
4378 case EM_V850:
4379 case EM_CYGNUS_V850:
4380 result = get_v850_section_type_name (sh_type);
4381 break;
2dc8dd17
JW
4382 case EM_RISCV:
4383 result = get_riscv_section_type_name (sh_type);
4384 break;
252b5132
RH
4385 default:
4386 result = NULL;
4387 break;
4388 }
4389
4390 if (result != NULL)
4391 return result;
4392
9fb71ee4 4393 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4394 }
4395 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4396 {
dda8d76d 4397 switch (filedata->file_header.e_machine)
148b93f2
NC
4398 {
4399 case EM_IA_64:
dda8d76d 4400 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4401 break;
4402 default:
dda8d76d 4403 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4404 result = get_solaris_section_type (sh_type);
4405 else
1b4b80bf
NC
4406 {
4407 switch (sh_type)
4408 {
4409 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4410 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4411 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4412 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4413 default:
4414 result = NULL;
4415 break;
4416 }
4417 }
148b93f2
NC
4418 break;
4419 }
4420
4421 if (result != NULL)
4422 return result;
4423
9fb71ee4 4424 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4425 }
252b5132 4426 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4427 {
dda8d76d 4428 switch (filedata->file_header.e_machine)
685080f2
NC
4429 {
4430 case EM_V800:
4431 case EM_V850:
4432 case EM_CYGNUS_V850:
9fb71ee4 4433 result = get_v850_section_type_name (sh_type);
a9fb83be 4434 break;
685080f2 4435 default:
9fb71ee4 4436 result = NULL;
685080f2
NC
4437 break;
4438 }
4439
9fb71ee4
NC
4440 if (result != NULL)
4441 return result;
4442
4443 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4444 }
252b5132 4445 else
a7dbfd1c
NC
4446 /* This message is probably going to be displayed in a 15
4447 character wide field, so put the hex value first. */
4448 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4449
252b5132
RH
4450 return buff;
4451 }
4452}
4453
2979dc34 4454#define OPTION_DEBUG_DUMP 512
2c610e4b 4455#define OPTION_DYN_SYMS 513
fd2f0033
TT
4456#define OPTION_DWARF_DEPTH 514
4457#define OPTION_DWARF_START 515
4723351a 4458#define OPTION_DWARF_CHECK 516
7d9813f1
NA
4459#define OPTION_CTF_DUMP 517
4460#define OPTION_CTF_PARENT 518
4461#define OPTION_CTF_SYMBOLS 519
4462#define OPTION_CTF_STRINGS 520
2979dc34 4463
85b1c36d 4464static struct option options[] =
252b5132 4465{
b34976b6 4466 {"all", no_argument, 0, 'a'},
252b5132
RH
4467 {"file-header", no_argument, 0, 'h'},
4468 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
4469 {"headers", no_argument, 0, 'e'},
4470 {"histogram", no_argument, 0, 'I'},
4471 {"segments", no_argument, 0, 'l'},
4472 {"sections", no_argument, 0, 'S'},
252b5132 4473 {"section-headers", no_argument, 0, 'S'},
f5842774 4474 {"section-groups", no_argument, 0, 'g'},
5477e8a0 4475 {"section-details", no_argument, 0, 't'},
595cf52e 4476 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
4477 {"symbols", no_argument, 0, 's'},
4478 {"syms", no_argument, 0, 's'},
2c610e4b 4479 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
4480 {"relocs", no_argument, 0, 'r'},
4481 {"notes", no_argument, 0, 'n'},
4482 {"dynamic", no_argument, 0, 'd'},
1b513401
NC
4483 {"lint", no_argument, 0, 'L'},
4484 {"enable-checks", no_argument, 0, 'L'},
a952a375 4485 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
4486 {"version-info", no_argument, 0, 'V'},
4487 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 4488 {"unwind", no_argument, 0, 'u'},
4145f1d5 4489 {"archive-index", no_argument, 0, 'c'},
b34976b6 4490 {"hex-dump", required_argument, 0, 'x'},
cf13d699 4491 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 4492 {"string-dump", required_argument, 0, 'p'},
0e602686 4493 {"decompress", no_argument, 0, 'z'},
252b5132
RH
4494#ifdef SUPPORT_DISASSEMBLY
4495 {"instruction-dump", required_argument, 0, 'i'},
4496#endif
cf13d699 4497 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 4498
fd2f0033
TT
4499 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4500 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4501 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 4502
d344b407 4503 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
4504
4505 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
4506 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
4507 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
4508
b34976b6
AM
4509 {"version", no_argument, 0, 'v'},
4510 {"wide", no_argument, 0, 'W'},
4511 {"help", no_argument, 0, 'H'},
4512 {0, no_argument, 0, 0}
252b5132
RH
4513};
4514
4515static void
2cf0635d 4516usage (FILE * stream)
252b5132 4517{
92f01d61
JM
4518 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4519 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4520 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4521 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4522 -h --file-header Display the ELF file header\n\
4523 -l --program-headers Display the program headers\n\
4524 --segments An alias for --program-headers\n\
4525 -S --section-headers Display the sections' header\n\
4526 --sections An alias for --section-headers\n\
f5842774 4527 -g --section-groups Display the section groups\n\
5477e8a0 4528 -t --section-details Display the section details\n\
8b53311e
NC
4529 -e --headers Equivalent to: -h -l -S\n\
4530 -s --syms Display the symbol table\n\
3f08eb35 4531 --symbols An alias for --syms\n\
1b513401 4532 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
4533 -n --notes Display the core notes (if present)\n\
4534 -r --relocs Display the relocations (if present)\n\
4535 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4536 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4537 -V --version-info Display the version sections (if present)\n\
1b31d05e 4538 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4539 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4540 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
1b513401 4541 -L --lint|--enable-checks Display warning messages for possible problems\n\
09c11c86
NC
4542 -x --hex-dump=<number|name>\n\
4543 Dump the contents of section <number|name> as bytes\n\
4544 -p --string-dump=<number|name>\n\
4545 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4546 -R --relocated-dump=<number|name>\n\
4547 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4548 -z --decompress Decompress section before dumping it\n\
dda8d76d 4549 -w[lLiaprmfFsoRtUuTgAckK] or\n\
1ed06042 4550 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 4551 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47 4552 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
dda8d76d
NC
4553 =addr,=cu_index,=links,=follow-links]\n\
4554 Display the contents of DWARF debug sections\n"));
fd2f0033
TT
4555 fprintf (stream, _("\
4556 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4557 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4558 or deeper\n"));
7d9813f1
NA
4559 fprintf (stream, _("\
4560 --ctf=<number|name> Display CTF info from section <number|name>\n\
4561 --ctf-parent=<number|name>\n\
4562 Use section <number|name> as the CTF parent\n\n\
4563 --ctf-symbols=<number|name>\n\
4564 Use section <number|name> as the CTF external symtab\n\n\
4565 --ctf-strings=<number|name>\n\
4566 Use section <number|name> as the CTF external strtab\n\n"));
4567
252b5132 4568#ifdef SUPPORT_DISASSEMBLY
92f01d61 4569 fprintf (stream, _("\
09c11c86
NC
4570 -i --instruction-dump=<number|name>\n\
4571 Disassemble the contents of section <number|name>\n"));
252b5132 4572#endif
92f01d61 4573 fprintf (stream, _("\
8b53311e
NC
4574 -I --histogram Display histogram of bucket list lengths\n\
4575 -W --wide Allow output width to exceed 80 characters\n\
07012eee 4576 @<file> Read options from <file>\n\
8b53311e
NC
4577 -H --help Display this information\n\
4578 -v --version Display the version number of readelf\n"));
1118d252 4579
92f01d61
JM
4580 if (REPORT_BUGS_TO[0] && stream == stdout)
4581 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4582
92f01d61 4583 exit (stream == stdout ? 0 : 1);
252b5132
RH
4584}
4585
18bd398b
NC
4586/* Record the fact that the user wants the contents of section number
4587 SECTION to be displayed using the method(s) encoded as flags bits
4588 in TYPE. Note, TYPE can be zero if we are creating the array for
4589 the first time. */
4590
252b5132 4591static void
6431e409
AM
4592request_dump_bynumber (struct dump_data *dumpdata,
4593 unsigned int section, dump_type type)
252b5132 4594{
6431e409 4595 if (section >= dumpdata->num_dump_sects)
252b5132 4596 {
2cf0635d 4597 dump_type * new_dump_sects;
252b5132 4598
3f5e193b 4599 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4600 sizeof (* new_dump_sects));
252b5132
RH
4601
4602 if (new_dump_sects == NULL)
591a748a 4603 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4604 else
4605 {
6431e409 4606 if (dumpdata->dump_sects)
21b65bac
NC
4607 {
4608 /* Copy current flag settings. */
6431e409
AM
4609 memcpy (new_dump_sects, dumpdata->dump_sects,
4610 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4611
6431e409 4612 free (dumpdata->dump_sects);
21b65bac 4613 }
252b5132 4614
6431e409
AM
4615 dumpdata->dump_sects = new_dump_sects;
4616 dumpdata->num_dump_sects = section + 1;
252b5132
RH
4617 }
4618 }
4619
6431e409
AM
4620 if (dumpdata->dump_sects)
4621 dumpdata->dump_sects[section] |= type;
252b5132
RH
4622}
4623
aef1f6d0
DJ
4624/* Request a dump by section name. */
4625
4626static void
2cf0635d 4627request_dump_byname (const char * section, dump_type type)
aef1f6d0 4628{
2cf0635d 4629 struct dump_list_entry * new_request;
aef1f6d0 4630
3f5e193b
NC
4631 new_request = (struct dump_list_entry *)
4632 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4633 if (!new_request)
591a748a 4634 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4635
4636 new_request->name = strdup (section);
4637 if (!new_request->name)
591a748a 4638 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4639
4640 new_request->type = type;
4641
4642 new_request->next = dump_sects_byname;
4643 dump_sects_byname = new_request;
4644}
4645
cf13d699 4646static inline void
6431e409 4647request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
4648{
4649 int section;
4650 char * cp;
4651
4652 do_dump++;
4653 section = strtoul (optarg, & cp, 0);
4654
4655 if (! *cp && section >= 0)
6431e409 4656 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
4657 else
4658 request_dump_byname (optarg, type);
4659}
4660
252b5132 4661static void
6431e409 4662parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
4663{
4664 int c;
4665
4666 if (argc < 2)
92f01d61 4667 usage (stderr);
252b5132
RH
4668
4669 while ((c = getopt_long
1b513401 4670 (argc, argv, "ADHILNR:SVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4671 {
252b5132
RH
4672 switch (c)
4673 {
4674 case 0:
4675 /* Long options. */
4676 break;
4677 case 'H':
92f01d61 4678 usage (stdout);
252b5132
RH
4679 break;
4680
4681 case 'a':
32ec8896
NC
4682 do_syms = TRUE;
4683 do_reloc = TRUE;
4684 do_unwind = TRUE;
4685 do_dynamic = TRUE;
4686 do_header = TRUE;
4687 do_sections = TRUE;
4688 do_section_groups = TRUE;
4689 do_segments = TRUE;
4690 do_version = TRUE;
4691 do_histogram = TRUE;
4692 do_arch = TRUE;
4693 do_notes = TRUE;
252b5132 4694 break;
f5842774 4695 case 'g':
32ec8896 4696 do_section_groups = TRUE;
f5842774 4697 break;
5477e8a0 4698 case 't':
595cf52e 4699 case 'N':
32ec8896
NC
4700 do_sections = TRUE;
4701 do_section_details = TRUE;
595cf52e 4702 break;
252b5132 4703 case 'e':
32ec8896
NC
4704 do_header = TRUE;
4705 do_sections = TRUE;
4706 do_segments = TRUE;
252b5132 4707 break;
a952a375 4708 case 'A':
32ec8896 4709 do_arch = TRUE;
a952a375 4710 break;
252b5132 4711 case 'D':
32ec8896 4712 do_using_dynamic = TRUE;
252b5132
RH
4713 break;
4714 case 'r':
32ec8896 4715 do_reloc = TRUE;
252b5132 4716 break;
4d6ed7c8 4717 case 'u':
32ec8896 4718 do_unwind = TRUE;
4d6ed7c8 4719 break;
252b5132 4720 case 'h':
32ec8896 4721 do_header = TRUE;
252b5132
RH
4722 break;
4723 case 'l':
32ec8896 4724 do_segments = TRUE;
252b5132
RH
4725 break;
4726 case 's':
32ec8896 4727 do_syms = TRUE;
252b5132
RH
4728 break;
4729 case 'S':
32ec8896 4730 do_sections = TRUE;
252b5132
RH
4731 break;
4732 case 'd':
32ec8896 4733 do_dynamic = TRUE;
252b5132 4734 break;
a952a375 4735 case 'I':
32ec8896 4736 do_histogram = TRUE;
a952a375 4737 break;
779fe533 4738 case 'n':
32ec8896 4739 do_notes = TRUE;
779fe533 4740 break;
4145f1d5 4741 case 'c':
32ec8896 4742 do_archive_index = TRUE;
4145f1d5 4743 break;
1b513401
NC
4744 case 'L':
4745 do_checks = TRUE;
4746 break;
252b5132 4747 case 'x':
6431e409 4748 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 4749 break;
09c11c86 4750 case 'p':
6431e409 4751 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
4752 break;
4753 case 'R':
6431e409 4754 request_dump (dumpdata, RELOC_DUMP);
09c11c86 4755 break;
0e602686 4756 case 'z':
32ec8896 4757 decompress_dumps = TRUE;
0e602686 4758 break;
252b5132 4759 case 'w':
32ec8896 4760 do_dump = TRUE;
252b5132 4761 if (optarg == 0)
613ff48b 4762 {
32ec8896 4763 do_debugging = TRUE;
613ff48b
CC
4764 dwarf_select_sections_all ();
4765 }
252b5132
RH
4766 else
4767 {
32ec8896 4768 do_debugging = FALSE;
4cb93e3b 4769 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4770 }
4771 break;
2979dc34 4772 case OPTION_DEBUG_DUMP:
32ec8896 4773 do_dump = TRUE;
2979dc34 4774 if (optarg == 0)
32ec8896 4775 do_debugging = TRUE;
2979dc34
JJ
4776 else
4777 {
32ec8896 4778 do_debugging = FALSE;
4cb93e3b 4779 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4780 }
4781 break;
fd2f0033
TT
4782 case OPTION_DWARF_DEPTH:
4783 {
4784 char *cp;
4785
4786 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4787 }
4788 break;
4789 case OPTION_DWARF_START:
4790 {
4791 char *cp;
4792
4793 dwarf_start_die = strtoul (optarg, & cp, 0);
4794 }
4795 break;
4723351a 4796 case OPTION_DWARF_CHECK:
32ec8896 4797 dwarf_check = TRUE;
4723351a 4798 break;
7d9813f1
NA
4799 case OPTION_CTF_DUMP:
4800 do_ctf = TRUE;
6431e409 4801 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
4802 break;
4803 case OPTION_CTF_SYMBOLS:
4804 dump_ctf_symtab_name = strdup (optarg);
4805 break;
4806 case OPTION_CTF_STRINGS:
4807 dump_ctf_strtab_name = strdup (optarg);
4808 break;
4809 case OPTION_CTF_PARENT:
4810 dump_ctf_parent_name = strdup (optarg);
4811 break;
2c610e4b 4812 case OPTION_DYN_SYMS:
32ec8896 4813 do_dyn_syms = TRUE;
2c610e4b 4814 break;
252b5132
RH
4815#ifdef SUPPORT_DISASSEMBLY
4816 case 'i':
6431e409 4817 request_dump (dumpdata, DISASS_DUMP);
cf13d699 4818 break;
252b5132
RH
4819#endif
4820 case 'v':
4821 print_version (program_name);
4822 break;
4823 case 'V':
32ec8896 4824 do_version = TRUE;
252b5132 4825 break;
d974e256 4826 case 'W':
32ec8896 4827 do_wide = TRUE;
d974e256 4828 break;
252b5132 4829 default:
252b5132
RH
4830 /* xgettext:c-format */
4831 error (_("Invalid option '-%c'\n"), c);
1a0670f3 4832 /* Fall through. */
252b5132 4833 case '?':
92f01d61 4834 usage (stderr);
252b5132
RH
4835 }
4836 }
4837
4d6ed7c8 4838 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4839 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4840 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4841 && !do_section_groups && !do_archive_index
4842 && !do_dyn_syms)
1b513401
NC
4843 {
4844 if (do_checks)
4845 {
4846 check_all = TRUE;
4847 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = TRUE;
4848 do_segments = do_header = do_dump = do_version = TRUE;
4849 do_histogram = do_debugging = do_arch = do_notes = TRUE;
4850 do_section_groups = do_archive_index = do_dyn_syms = TRUE;
4851 }
4852 else
4853 usage (stderr);
4854 }
252b5132
RH
4855}
4856
4857static const char *
d3ba0551 4858get_elf_class (unsigned int elf_class)
252b5132 4859{
b34976b6 4860 static char buff[32];
103f02d3 4861
252b5132
RH
4862 switch (elf_class)
4863 {
4864 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4865 case ELFCLASS32: return "ELF32";
4866 case ELFCLASS64: return "ELF64";
ab5e7794 4867 default:
e9e44622 4868 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4869 return buff;
252b5132
RH
4870 }
4871}
4872
4873static const char *
d3ba0551 4874get_data_encoding (unsigned int encoding)
252b5132 4875{
b34976b6 4876 static char buff[32];
103f02d3 4877
252b5132
RH
4878 switch (encoding)
4879 {
4880 case ELFDATANONE: return _("none");
33c63f9d
CM
4881 case ELFDATA2LSB: return _("2's complement, little endian");
4882 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4883 default:
e9e44622 4884 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4885 return buff;
252b5132
RH
4886 }
4887}
4888
dda8d76d 4889/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 4890
32ec8896 4891static bfd_boolean
dda8d76d 4892process_file_header (Filedata * filedata)
252b5132 4893{
dda8d76d
NC
4894 Elf_Internal_Ehdr * header = & filedata->file_header;
4895
4896 if ( header->e_ident[EI_MAG0] != ELFMAG0
4897 || header->e_ident[EI_MAG1] != ELFMAG1
4898 || header->e_ident[EI_MAG2] != ELFMAG2
4899 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4900 {
4901 error
4902 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
32ec8896 4903 return FALSE;
252b5132
RH
4904 }
4905
955ff7fc 4906 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 4907
252b5132
RH
4908 if (do_header)
4909 {
32ec8896 4910 unsigned i;
252b5132
RH
4911
4912 printf (_("ELF Header:\n"));
4913 printf (_(" Magic: "));
b34976b6 4914 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 4915 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
4916 printf ("\n");
4917 printf (_(" Class: %s\n"),
dda8d76d 4918 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 4919 printf (_(" Data: %s\n"),
dda8d76d 4920 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 4921 printf (_(" Version: %d%s\n"),
dda8d76d
NC
4922 header->e_ident[EI_VERSION],
4923 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 4924 ? _(" (current)")
dda8d76d 4925 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 4926 ? _(" <unknown>")
789be9f7 4927 : "")));
252b5132 4928 printf (_(" OS/ABI: %s\n"),
dda8d76d 4929 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 4930 printf (_(" ABI Version: %d\n"),
dda8d76d 4931 header->e_ident[EI_ABIVERSION]);
252b5132 4932 printf (_(" Type: %s\n"),
dda8d76d 4933 get_file_type (header->e_type));
252b5132 4934 printf (_(" Machine: %s\n"),
dda8d76d 4935 get_machine_name (header->e_machine));
252b5132 4936 printf (_(" Version: 0x%lx\n"),
e8a64888 4937 header->e_version);
76da6bbe 4938
f7a99963 4939 printf (_(" Entry point address: "));
e8a64888 4940 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 4941 printf (_("\n Start of program headers: "));
e8a64888 4942 print_vma (header->e_phoff, DEC);
f7a99963 4943 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 4944 print_vma (header->e_shoff, DEC);
f7a99963 4945 printf (_(" (bytes into file)\n"));
76da6bbe 4946
252b5132 4947 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 4948 header->e_flags,
dda8d76d 4949 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
4950 printf (_(" Size of this header: %u (bytes)\n"),
4951 header->e_ehsize);
4952 printf (_(" Size of program headers: %u (bytes)\n"),
4953 header->e_phentsize);
4954 printf (_(" Number of program headers: %u"),
4955 header->e_phnum);
dda8d76d
NC
4956 if (filedata->section_headers != NULL
4957 && header->e_phnum == PN_XNUM
4958 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
4959 {
4960 header->e_phnum = filedata->section_headers[0].sh_info;
4961 printf (" (%u)", header->e_phnum);
4962 }
2046a35d 4963 putc ('\n', stdout);
e8a64888
AM
4964 printf (_(" Size of section headers: %u (bytes)\n"),
4965 header->e_shentsize);
4966 printf (_(" Number of section headers: %u"),
4967 header->e_shnum);
dda8d76d 4968 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
4969 {
4970 header->e_shnum = filedata->section_headers[0].sh_size;
4971 printf (" (%u)", header->e_shnum);
4972 }
560f3c1c 4973 putc ('\n', stdout);
e8a64888
AM
4974 printf (_(" Section header string table index: %u"),
4975 header->e_shstrndx);
dda8d76d
NC
4976 if (filedata->section_headers != NULL
4977 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
4978 {
4979 header->e_shstrndx = filedata->section_headers[0].sh_link;
4980 printf (" (%u)", header->e_shstrndx);
4981 }
4982 if (header->e_shstrndx != SHN_UNDEF
4983 && header->e_shstrndx >= header->e_shnum)
4984 {
4985 header->e_shstrndx = SHN_UNDEF;
4986 printf (_(" <corrupt: out of range>"));
4987 }
560f3c1c
AM
4988 putc ('\n', stdout);
4989 }
4990
dda8d76d 4991 if (filedata->section_headers != NULL)
560f3c1c 4992 {
dda8d76d
NC
4993 if (header->e_phnum == PN_XNUM
4994 && filedata->section_headers[0].sh_info != 0)
4995 header->e_phnum = filedata->section_headers[0].sh_info;
4996 if (header->e_shnum == SHN_UNDEF)
4997 header->e_shnum = filedata->section_headers[0].sh_size;
4998 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
4999 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5000 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
5001 header->e_shstrndx = SHN_UNDEF;
5002 free (filedata->section_headers);
5003 filedata->section_headers = NULL;
252b5132 5004 }
103f02d3 5005
32ec8896 5006 return TRUE;
9ea033b2
NC
5007}
5008
dda8d76d
NC
5009/* Read in the program headers from FILEDATA and store them in PHEADERS.
5010 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5011
e0a31db1 5012static bfd_boolean
dda8d76d 5013get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5014{
2cf0635d
NC
5015 Elf32_External_Phdr * phdrs;
5016 Elf32_External_Phdr * external;
5017 Elf_Internal_Phdr * internal;
b34976b6 5018 unsigned int i;
dda8d76d
NC
5019 unsigned int size = filedata->file_header.e_phentsize;
5020 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5021
5022 /* PR binutils/17531: Cope with unexpected section header sizes. */
5023 if (size == 0 || num == 0)
5024 return FALSE;
5025 if (size < sizeof * phdrs)
5026 {
5027 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5028 return FALSE;
5029 }
5030 if (size > sizeof * phdrs)
5031 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5032
dda8d76d 5033 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5034 size, num, _("program headers"));
5035 if (phdrs == NULL)
5036 return FALSE;
9ea033b2 5037
91d6fa6a 5038 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5039 i < filedata->file_header.e_phnum;
b34976b6 5040 i++, internal++, external++)
252b5132 5041 {
9ea033b2
NC
5042 internal->p_type = BYTE_GET (external->p_type);
5043 internal->p_offset = BYTE_GET (external->p_offset);
5044 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5045 internal->p_paddr = BYTE_GET (external->p_paddr);
5046 internal->p_filesz = BYTE_GET (external->p_filesz);
5047 internal->p_memsz = BYTE_GET (external->p_memsz);
5048 internal->p_flags = BYTE_GET (external->p_flags);
5049 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5050 }
5051
9ea033b2 5052 free (phdrs);
e0a31db1 5053 return TRUE;
252b5132
RH
5054}
5055
dda8d76d
NC
5056/* Read in the program headers from FILEDATA and store them in PHEADERS.
5057 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5058
e0a31db1 5059static bfd_boolean
dda8d76d 5060get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5061{
2cf0635d
NC
5062 Elf64_External_Phdr * phdrs;
5063 Elf64_External_Phdr * external;
5064 Elf_Internal_Phdr * internal;
b34976b6 5065 unsigned int i;
dda8d76d
NC
5066 unsigned int size = filedata->file_header.e_phentsize;
5067 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5068
5069 /* PR binutils/17531: Cope with unexpected section header sizes. */
5070 if (size == 0 || num == 0)
5071 return FALSE;
5072 if (size < sizeof * phdrs)
5073 {
5074 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5075 return FALSE;
5076 }
5077 if (size > sizeof * phdrs)
5078 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5079
dda8d76d 5080 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5081 size, num, _("program headers"));
a6e9f9df 5082 if (!phdrs)
e0a31db1 5083 return FALSE;
9ea033b2 5084
91d6fa6a 5085 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5086 i < filedata->file_header.e_phnum;
b34976b6 5087 i++, internal++, external++)
9ea033b2
NC
5088 {
5089 internal->p_type = BYTE_GET (external->p_type);
5090 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5091 internal->p_offset = BYTE_GET (external->p_offset);
5092 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5093 internal->p_paddr = BYTE_GET (external->p_paddr);
5094 internal->p_filesz = BYTE_GET (external->p_filesz);
5095 internal->p_memsz = BYTE_GET (external->p_memsz);
5096 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5097 }
5098
5099 free (phdrs);
e0a31db1 5100 return TRUE;
9ea033b2 5101}
252b5132 5102
32ec8896 5103/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5104
32ec8896 5105static bfd_boolean
dda8d76d 5106get_program_headers (Filedata * filedata)
d93f0186 5107{
2cf0635d 5108 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5109
5110 /* Check cache of prior read. */
dda8d76d 5111 if (filedata->program_headers != NULL)
32ec8896 5112 return TRUE;
d93f0186 5113
82156ab7
NC
5114 /* Be kind to memory checkers by looking for
5115 e_phnum values which we know must be invalid. */
dda8d76d 5116 if (filedata->file_header.e_phnum
82156ab7 5117 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5118 >= filedata->file_size)
82156ab7
NC
5119 {
5120 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5121 filedata->file_header.e_phnum);
82156ab7
NC
5122 return FALSE;
5123 }
d93f0186 5124
dda8d76d 5125 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5126 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5127 if (phdrs == NULL)
5128 {
8b73c356 5129 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5130 filedata->file_header.e_phnum);
32ec8896 5131 return FALSE;
d93f0186
NC
5132 }
5133
5134 if (is_32bit_elf
dda8d76d
NC
5135 ? get_32bit_program_headers (filedata, phdrs)
5136 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5137 {
dda8d76d 5138 filedata->program_headers = phdrs;
32ec8896 5139 return TRUE;
d93f0186
NC
5140 }
5141
5142 free (phdrs);
32ec8896 5143 return FALSE;
d93f0186
NC
5144}
5145
32ec8896 5146/* Returns TRUE if the program headers were loaded. */
2f62977e 5147
32ec8896 5148static bfd_boolean
dda8d76d 5149process_program_headers (Filedata * filedata)
252b5132 5150{
2cf0635d 5151 Elf_Internal_Phdr * segment;
b34976b6 5152 unsigned int i;
1a9ccd70 5153 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5154
978c4450
AM
5155 filedata->dynamic_addr = 0;
5156 filedata->dynamic_size = 0;
663f67df 5157
dda8d76d 5158 if (filedata->file_header.e_phnum == 0)
252b5132 5159 {
82f2dbf7 5160 /* PR binutils/12467. */
dda8d76d 5161 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5162 {
5163 warn (_("possibly corrupt ELF header - it has a non-zero program"
5164 " header offset, but no program headers\n"));
5165 return FALSE;
5166 }
82f2dbf7 5167 else if (do_segments)
252b5132 5168 printf (_("\nThere are no program headers in this file.\n"));
32ec8896 5169 return TRUE;
252b5132
RH
5170 }
5171
5172 if (do_segments && !do_header)
5173 {
dda8d76d
NC
5174 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
5175 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5176 printf (ngettext ("There is %d program header, starting at offset %s\n",
5177 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5178 filedata->file_header.e_phnum),
5179 filedata->file_header.e_phnum,
5180 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5181 }
5182
dda8d76d 5183 if (! get_program_headers (filedata))
6b4bf3bc 5184 return TRUE;
103f02d3 5185
252b5132
RH
5186 if (do_segments)
5187 {
dda8d76d 5188 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5189 printf (_("\nProgram Headers:\n"));
5190 else
5191 printf (_("\nProgram Headers:\n"));
76da6bbe 5192
f7a99963
NC
5193 if (is_32bit_elf)
5194 printf
5195 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5196 else if (do_wide)
5197 printf
5198 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5199 else
5200 {
5201 printf
5202 (_(" Type Offset VirtAddr PhysAddr\n"));
5203 printf
5204 (_(" FileSiz MemSiz Flags Align\n"));
5205 }
252b5132
RH
5206 }
5207
dda8d76d
NC
5208 for (i = 0, segment = filedata->program_headers;
5209 i < filedata->file_header.e_phnum;
b34976b6 5210 i++, segment++)
252b5132
RH
5211 {
5212 if (do_segments)
5213 {
dda8d76d 5214 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5215
5216 if (is_32bit_elf)
5217 {
5218 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5219 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5220 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5221 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5222 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5223 printf ("%c%c%c ",
5224 (segment->p_flags & PF_R ? 'R' : ' '),
5225 (segment->p_flags & PF_W ? 'W' : ' '),
5226 (segment->p_flags & PF_X ? 'E' : ' '));
5227 printf ("%#lx", (unsigned long) segment->p_align);
5228 }
d974e256
JJ
5229 else if (do_wide)
5230 {
5231 if ((unsigned long) segment->p_offset == segment->p_offset)
5232 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5233 else
5234 {
5235 print_vma (segment->p_offset, FULL_HEX);
5236 putchar (' ');
5237 }
5238
5239 print_vma (segment->p_vaddr, FULL_HEX);
5240 putchar (' ');
5241 print_vma (segment->p_paddr, FULL_HEX);
5242 putchar (' ');
5243
5244 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5245 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5246 else
5247 {
5248 print_vma (segment->p_filesz, FULL_HEX);
5249 putchar (' ');
5250 }
5251
5252 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5253 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5254 else
5255 {
f48e6c45 5256 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5257 }
5258
5259 printf (" %c%c%c ",
5260 (segment->p_flags & PF_R ? 'R' : ' '),
5261 (segment->p_flags & PF_W ? 'W' : ' '),
5262 (segment->p_flags & PF_X ? 'E' : ' '));
5263
5264 if ((unsigned long) segment->p_align == segment->p_align)
5265 printf ("%#lx", (unsigned long) segment->p_align);
5266 else
5267 {
5268 print_vma (segment->p_align, PREFIX_HEX);
5269 }
5270 }
f7a99963
NC
5271 else
5272 {
5273 print_vma (segment->p_offset, FULL_HEX);
5274 putchar (' ');
5275 print_vma (segment->p_vaddr, FULL_HEX);
5276 putchar (' ');
5277 print_vma (segment->p_paddr, FULL_HEX);
5278 printf ("\n ");
5279 print_vma (segment->p_filesz, FULL_HEX);
5280 putchar (' ');
5281 print_vma (segment->p_memsz, FULL_HEX);
5282 printf (" %c%c%c ",
5283 (segment->p_flags & PF_R ? 'R' : ' '),
5284 (segment->p_flags & PF_W ? 'W' : ' '),
5285 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5286 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5287 }
252b5132 5288
1a9ccd70
NC
5289 putc ('\n', stdout);
5290 }
f54498b4 5291
252b5132
RH
5292 switch (segment->p_type)
5293 {
1a9ccd70 5294 case PT_LOAD:
502d895c
NC
5295#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5296 required by the ELF standard, several programs, including the Linux
5297 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5298 if (previous_load
5299 && previous_load->p_vaddr > segment->p_vaddr)
5300 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5301#endif
1a9ccd70
NC
5302 if (segment->p_memsz < segment->p_filesz)
5303 error (_("the segment's file size is larger than its memory size\n"));
5304 previous_load = segment;
5305 break;
5306
5307 case PT_PHDR:
5308 /* PR 20815 - Verify that the program header is loaded into memory. */
5309 if (i > 0 && previous_load != NULL)
5310 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5311 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5312 {
5313 unsigned int j;
5314
dda8d76d 5315 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5316 {
5317 Elf_Internal_Phdr *load = filedata->program_headers + j;
5318 if (load->p_type == PT_LOAD
5319 && load->p_offset <= segment->p_offset
5320 && (load->p_offset + load->p_filesz
5321 >= segment->p_offset + segment->p_filesz)
5322 && load->p_vaddr <= segment->p_vaddr
5323 && (load->p_vaddr + load->p_filesz
5324 >= segment->p_vaddr + segment->p_filesz))
5325 break;
5326 }
dda8d76d 5327 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5328 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5329 }
5330 break;
5331
252b5132 5332 case PT_DYNAMIC:
978c4450 5333 if (filedata->dynamic_addr)
252b5132
RH
5334 error (_("more than one dynamic segment\n"));
5335
20737c13
AM
5336 /* By default, assume that the .dynamic section is the first
5337 section in the DYNAMIC segment. */
978c4450
AM
5338 filedata->dynamic_addr = segment->p_offset;
5339 filedata->dynamic_size = segment->p_filesz;
20737c13 5340
b2d38a17
NC
5341 /* Try to locate the .dynamic section. If there is
5342 a section header table, we can easily locate it. */
dda8d76d 5343 if (filedata->section_headers != NULL)
b2d38a17 5344 {
2cf0635d 5345 Elf_Internal_Shdr * sec;
b2d38a17 5346
dda8d76d 5347 sec = find_section (filedata, ".dynamic");
89fac5e3 5348 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5349 {
28f997cf
TG
5350 /* A corresponding .dynamic section is expected, but on
5351 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5352 if (!is_ia64_vms (filedata))
28f997cf 5353 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5354 break;
5355 }
5356
42bb2e33 5357 if (sec->sh_type == SHT_NOBITS)
20737c13 5358 {
978c4450 5359 filedata->dynamic_size = 0;
20737c13
AM
5360 break;
5361 }
42bb2e33 5362
978c4450
AM
5363 filedata->dynamic_addr = sec->sh_offset;
5364 filedata->dynamic_size = sec->sh_size;
b2d38a17 5365
978c4450
AM
5366 if (filedata->dynamic_addr < segment->p_offset
5367 || filedata->dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
5368 warn (_("the .dynamic section is not contained"
5369 " within the dynamic segment\n"));
978c4450 5370 else if (filedata->dynamic_addr > segment->p_offset)
20737c13
AM
5371 warn (_("the .dynamic section is not the first section"
5372 " in the dynamic segment.\n"));
b2d38a17 5373 }
39e224f6
MW
5374
5375 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5376 segment. Check this after matching against the section headers
5377 so we don't warn on debuginfo file (which have NOBITS .dynamic
5378 sections). */
978c4450
AM
5379 if (filedata->dynamic_addr > filedata->file_size
5380 || (filedata->dynamic_size
5381 > filedata->file_size - filedata->dynamic_addr))
39e224f6
MW
5382 {
5383 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
978c4450 5384 filedata->dynamic_addr = filedata->dynamic_size = 0;
39e224f6 5385 }
252b5132
RH
5386 break;
5387
5388 case PT_INTERP:
978c4450
AM
5389 if (fseek (filedata->handle,
5390 filedata->archive_file_offset + (long) segment->p_offset,
fb52b2f4 5391 SEEK_SET))
252b5132
RH
5392 error (_("Unable to find program interpreter name\n"));
5393 else
5394 {
f8eae8b2 5395 char fmt [32];
9495b2e6 5396 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
5397
5398 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 5399 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 5400
978c4450
AM
5401 filedata->program_interpreter[0] = 0;
5402 if (fscanf (filedata->handle, fmt,
5403 filedata->program_interpreter) <= 0)
7bd7b3ef 5404 error (_("Unable to read program interpreter name\n"));
252b5132
RH
5405
5406 if (do_segments)
f54498b4 5407 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 5408 filedata->program_interpreter);
252b5132
RH
5409 }
5410 break;
5411 }
252b5132
RH
5412 }
5413
dda8d76d
NC
5414 if (do_segments
5415 && filedata->section_headers != NULL
5416 && filedata->string_table != NULL)
252b5132
RH
5417 {
5418 printf (_("\n Section to Segment mapping:\n"));
5419 printf (_(" Segment Sections...\n"));
5420
dda8d76d 5421 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5422 {
9ad5cbcf 5423 unsigned int j;
2cf0635d 5424 Elf_Internal_Shdr * section;
252b5132 5425
dda8d76d
NC
5426 segment = filedata->program_headers + i;
5427 section = filedata->section_headers + 1;
252b5132
RH
5428
5429 printf (" %2.2d ", i);
5430
dda8d76d 5431 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5432 {
f4638467
AM
5433 if (!ELF_TBSS_SPECIAL (section, segment)
5434 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5435 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5436 }
5437
5438 putc ('\n',stdout);
5439 }
5440 }
5441
32ec8896 5442 return TRUE;
252b5132
RH
5443}
5444
5445
d93f0186
NC
5446/* Find the file offset corresponding to VMA by using the program headers. */
5447
5448static long
dda8d76d 5449offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5450{
2cf0635d 5451 Elf_Internal_Phdr * seg;
d93f0186 5452
dda8d76d 5453 if (! get_program_headers (filedata))
d93f0186
NC
5454 {
5455 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5456 return (long) vma;
5457 }
5458
dda8d76d
NC
5459 for (seg = filedata->program_headers;
5460 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5461 ++seg)
5462 {
5463 if (seg->p_type != PT_LOAD)
5464 continue;
5465
5466 if (vma >= (seg->p_vaddr & -seg->p_align)
5467 && vma + size <= seg->p_vaddr + seg->p_filesz)
5468 return vma - seg->p_vaddr + seg->p_offset;
5469 }
5470
5471 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5472 (unsigned long) vma);
d93f0186
NC
5473 return (long) vma;
5474}
5475
5476
dda8d76d
NC
5477/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5478 If PROBE is true, this is just a probe and we do not generate any error
5479 messages if the load fails. */
049b0c3a
NC
5480
5481static bfd_boolean
dda8d76d 5482get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
252b5132 5483{
2cf0635d
NC
5484 Elf32_External_Shdr * shdrs;
5485 Elf_Internal_Shdr * internal;
dda8d76d
NC
5486 unsigned int i;
5487 unsigned int size = filedata->file_header.e_shentsize;
5488 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5489
5490 /* PR binutils/17531: Cope with unexpected section header sizes. */
5491 if (size == 0 || num == 0)
5492 return FALSE;
5493 if (size < sizeof * shdrs)
5494 {
5495 if (! probe)
5496 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5497 return FALSE;
5498 }
5499 if (!probe && size > sizeof * shdrs)
5500 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5501
dda8d76d 5502 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5503 size, num,
5504 probe ? NULL : _("section headers"));
5505 if (shdrs == NULL)
5506 return FALSE;
252b5132 5507
dda8d76d
NC
5508 free (filedata->section_headers);
5509 filedata->section_headers = (Elf_Internal_Shdr *)
5510 cmalloc (num, sizeof (Elf_Internal_Shdr));
5511 if (filedata->section_headers == NULL)
252b5132 5512 {
049b0c3a 5513 if (!probe)
8b73c356 5514 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5515 free (shdrs);
049b0c3a 5516 return FALSE;
252b5132
RH
5517 }
5518
dda8d76d 5519 for (i = 0, internal = filedata->section_headers;
560f3c1c 5520 i < num;
b34976b6 5521 i++, internal++)
252b5132
RH
5522 {
5523 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5524 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5525 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5526 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5527 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5528 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5529 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5530 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5531 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5532 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5533 if (!probe && internal->sh_link > num)
5534 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5535 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5536 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5537 }
5538
5539 free (shdrs);
049b0c3a 5540 return TRUE;
252b5132
RH
5541}
5542
dda8d76d
NC
5543/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5544
049b0c3a 5545static bfd_boolean
dda8d76d 5546get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
9ea033b2 5547{
dda8d76d
NC
5548 Elf64_External_Shdr * shdrs;
5549 Elf_Internal_Shdr * internal;
5550 unsigned int i;
5551 unsigned int size = filedata->file_header.e_shentsize;
5552 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5553
5554 /* PR binutils/17531: Cope with unexpected section header sizes. */
5555 if (size == 0 || num == 0)
5556 return FALSE;
dda8d76d 5557
049b0c3a
NC
5558 if (size < sizeof * shdrs)
5559 {
5560 if (! probe)
5561 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5562 return FALSE;
5563 }
dda8d76d 5564
049b0c3a
NC
5565 if (! probe && size > sizeof * shdrs)
5566 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5567
dda8d76d
NC
5568 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5569 filedata->file_header.e_shoff,
049b0c3a
NC
5570 size, num,
5571 probe ? NULL : _("section headers"));
5572 if (shdrs == NULL)
5573 return FALSE;
9ea033b2 5574
dda8d76d
NC
5575 free (filedata->section_headers);
5576 filedata->section_headers = (Elf_Internal_Shdr *)
5577 cmalloc (num, sizeof (Elf_Internal_Shdr));
5578 if (filedata->section_headers == NULL)
9ea033b2 5579 {
049b0c3a 5580 if (! probe)
8b73c356 5581 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5582 free (shdrs);
049b0c3a 5583 return FALSE;
9ea033b2
NC
5584 }
5585
dda8d76d 5586 for (i = 0, internal = filedata->section_headers;
560f3c1c 5587 i < num;
b34976b6 5588 i++, internal++)
9ea033b2
NC
5589 {
5590 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5591 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5592 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5593 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5594 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5595 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5596 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5597 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5598 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5599 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5600 if (!probe && internal->sh_link > num)
5601 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5602 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5603 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5604 }
5605
5606 free (shdrs);
049b0c3a 5607 return TRUE;
9ea033b2
NC
5608}
5609
252b5132 5610static Elf_Internal_Sym *
dda8d76d
NC
5611get_32bit_elf_symbols (Filedata * filedata,
5612 Elf_Internal_Shdr * section,
5613 unsigned long * num_syms_return)
252b5132 5614{
ba5cdace 5615 unsigned long number = 0;
dd24e3da 5616 Elf32_External_Sym * esyms = NULL;
ba5cdace 5617 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5618 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5619 Elf_Internal_Sym * psym;
b34976b6 5620 unsigned int j;
e3d39609 5621 elf_section_list * entry;
252b5132 5622
c9c1d674
EG
5623 if (section->sh_size == 0)
5624 {
5625 if (num_syms_return != NULL)
5626 * num_syms_return = 0;
5627 return NULL;
5628 }
5629
dd24e3da 5630 /* Run some sanity checks first. */
c9c1d674 5631 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5632 {
c9c1d674 5633 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5634 printable_section_name (filedata, section),
5635 (unsigned long) section->sh_entsize);
ba5cdace 5636 goto exit_point;
dd24e3da
NC
5637 }
5638
dda8d76d 5639 if (section->sh_size > filedata->file_size)
f54498b4
NC
5640 {
5641 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5642 printable_section_name (filedata, section),
5643 (unsigned long) section->sh_size);
f54498b4
NC
5644 goto exit_point;
5645 }
5646
dd24e3da
NC
5647 number = section->sh_size / section->sh_entsize;
5648
5649 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5650 {
c9c1d674 5651 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5652 (unsigned long) section->sh_size,
dda8d76d 5653 printable_section_name (filedata, section),
8066deb1 5654 (unsigned long) section->sh_entsize);
ba5cdace 5655 goto exit_point;
dd24e3da
NC
5656 }
5657
dda8d76d 5658 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5659 section->sh_size, _("symbols"));
dd24e3da 5660 if (esyms == NULL)
ba5cdace 5661 goto exit_point;
252b5132 5662
e3d39609 5663 shndx = NULL;
978c4450 5664 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5665 {
5666 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5667 continue;
5668
5669 if (shndx != NULL)
5670 {
5671 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5672 free (shndx);
5673 }
5674
5675 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5676 entry->hdr->sh_offset,
5677 1, entry->hdr->sh_size,
5678 _("symbol table section indices"));
5679 if (shndx == NULL)
5680 goto exit_point;
5681
5682 /* PR17531: file: heap-buffer-overflow */
5683 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5684 {
5685 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5686 printable_section_name (filedata, entry->hdr),
5687 (unsigned long) entry->hdr->sh_size,
5688 (unsigned long) section->sh_size);
5689 goto exit_point;
c9c1d674 5690 }
e3d39609 5691 }
9ad5cbcf 5692
3f5e193b 5693 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5694
5695 if (isyms == NULL)
5696 {
8b73c356
NC
5697 error (_("Out of memory reading %lu symbols\n"),
5698 (unsigned long) number);
dd24e3da 5699 goto exit_point;
252b5132
RH
5700 }
5701
dd24e3da 5702 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5703 {
5704 psym->st_name = BYTE_GET (esyms[j].st_name);
5705 psym->st_value = BYTE_GET (esyms[j].st_value);
5706 psym->st_size = BYTE_GET (esyms[j].st_size);
5707 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5708 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5709 psym->st_shndx
5710 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5711 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5712 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5713 psym->st_info = BYTE_GET (esyms[j].st_info);
5714 psym->st_other = BYTE_GET (esyms[j].st_other);
5715 }
5716
dd24e3da 5717 exit_point:
e3d39609
NC
5718 free (shndx);
5719 free (esyms);
252b5132 5720
ba5cdace
NC
5721 if (num_syms_return != NULL)
5722 * num_syms_return = isyms == NULL ? 0 : number;
5723
252b5132
RH
5724 return isyms;
5725}
5726
9ea033b2 5727static Elf_Internal_Sym *
dda8d76d
NC
5728get_64bit_elf_symbols (Filedata * filedata,
5729 Elf_Internal_Shdr * section,
5730 unsigned long * num_syms_return)
9ea033b2 5731{
ba5cdace
NC
5732 unsigned long number = 0;
5733 Elf64_External_Sym * esyms = NULL;
5734 Elf_External_Sym_Shndx * shndx = NULL;
5735 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5736 Elf_Internal_Sym * psym;
b34976b6 5737 unsigned int j;
e3d39609 5738 elf_section_list * entry;
9ea033b2 5739
c9c1d674
EG
5740 if (section->sh_size == 0)
5741 {
5742 if (num_syms_return != NULL)
5743 * num_syms_return = 0;
5744 return NULL;
5745 }
5746
dd24e3da 5747 /* Run some sanity checks first. */
c9c1d674 5748 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5749 {
c9c1d674 5750 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5751 printable_section_name (filedata, section),
8066deb1 5752 (unsigned long) section->sh_entsize);
ba5cdace 5753 goto exit_point;
dd24e3da
NC
5754 }
5755
dda8d76d 5756 if (section->sh_size > filedata->file_size)
f54498b4
NC
5757 {
5758 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5759 printable_section_name (filedata, section),
8066deb1 5760 (unsigned long) section->sh_size);
f54498b4
NC
5761 goto exit_point;
5762 }
5763
dd24e3da
NC
5764 number = section->sh_size / section->sh_entsize;
5765
5766 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5767 {
c9c1d674 5768 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5769 (unsigned long) section->sh_size,
dda8d76d 5770 printable_section_name (filedata, section),
8066deb1 5771 (unsigned long) section->sh_entsize);
ba5cdace 5772 goto exit_point;
dd24e3da
NC
5773 }
5774
dda8d76d 5775 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5776 section->sh_size, _("symbols"));
a6e9f9df 5777 if (!esyms)
ba5cdace 5778 goto exit_point;
9ea033b2 5779
e3d39609 5780 shndx = NULL;
978c4450 5781 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5782 {
5783 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5784 continue;
5785
5786 if (shndx != NULL)
5787 {
5788 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5789 free (shndx);
c9c1d674 5790 }
e3d39609
NC
5791
5792 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5793 entry->hdr->sh_offset,
5794 1, entry->hdr->sh_size,
5795 _("symbol table section indices"));
5796 if (shndx == NULL)
5797 goto exit_point;
5798
5799 /* PR17531: file: heap-buffer-overflow */
5800 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5801 {
5802 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5803 printable_section_name (filedata, entry->hdr),
5804 (unsigned long) entry->hdr->sh_size,
5805 (unsigned long) section->sh_size);
5806 goto exit_point;
5807 }
5808 }
9ad5cbcf 5809
3f5e193b 5810 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5811
5812 if (isyms == NULL)
5813 {
8b73c356
NC
5814 error (_("Out of memory reading %lu symbols\n"),
5815 (unsigned long) number);
ba5cdace 5816 goto exit_point;
9ea033b2
NC
5817 }
5818
ba5cdace 5819 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5820 {
5821 psym->st_name = BYTE_GET (esyms[j].st_name);
5822 psym->st_info = BYTE_GET (esyms[j].st_info);
5823 psym->st_other = BYTE_GET (esyms[j].st_other);
5824 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5825
4fbb74a6 5826 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5827 psym->st_shndx
5828 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5829 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5830 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5831
66543521
AM
5832 psym->st_value = BYTE_GET (esyms[j].st_value);
5833 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5834 }
5835
ba5cdace 5836 exit_point:
e3d39609
NC
5837 free (shndx);
5838 free (esyms);
ba5cdace
NC
5839
5840 if (num_syms_return != NULL)
5841 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5842
5843 return isyms;
5844}
5845
d1133906 5846static const char *
dda8d76d 5847get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 5848{
5477e8a0 5849 static char buff[1024];
2cf0635d 5850 char * p = buff;
32ec8896
NC
5851 unsigned int field_size = is_32bit_elf ? 8 : 16;
5852 signed int sindex;
5853 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5854 bfd_vma os_flags = 0;
5855 bfd_vma proc_flags = 0;
5856 bfd_vma unknown_flags = 0;
148b93f2 5857 static const struct
5477e8a0 5858 {
2cf0635d 5859 const char * str;
32ec8896 5860 unsigned int len;
5477e8a0
L
5861 }
5862 flags [] =
5863 {
cfcac11d
NC
5864 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5865 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5866 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5867 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5868 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5869 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5870 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5871 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5872 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5873 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5874 /* IA-64 specific. */
5875 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5876 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5877 /* IA-64 OpenVMS specific. */
5878 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5879 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5880 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5881 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5882 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5883 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5884 /* Generic. */
cfcac11d 5885 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5886 /* SPARC specific. */
77115a4a 5887 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
5888 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
5889 /* ARM specific. */
5890 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 5891 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
5892 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
5893 /* GNU specific. */
5894 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
5895 /* VLE specific. */
5896 /* 25 */ { STRING_COMMA_LEN ("VLE") },
5477e8a0
L
5897 };
5898
5899 if (do_section_details)
5900 {
8d5ff12c
L
5901 sprintf (buff, "[%*.*lx]: ",
5902 field_size, field_size, (unsigned long) sh_flags);
5903 p += field_size + 4;
5477e8a0 5904 }
76da6bbe 5905
d1133906
NC
5906 while (sh_flags)
5907 {
5908 bfd_vma flag;
5909
5910 flag = sh_flags & - sh_flags;
5911 sh_flags &= ~ flag;
76da6bbe 5912
5477e8a0 5913 if (do_section_details)
d1133906 5914 {
5477e8a0
L
5915 switch (flag)
5916 {
91d6fa6a
NC
5917 case SHF_WRITE: sindex = 0; break;
5918 case SHF_ALLOC: sindex = 1; break;
5919 case SHF_EXECINSTR: sindex = 2; break;
5920 case SHF_MERGE: sindex = 3; break;
5921 case SHF_STRINGS: sindex = 4; break;
5922 case SHF_INFO_LINK: sindex = 5; break;
5923 case SHF_LINK_ORDER: sindex = 6; break;
5924 case SHF_OS_NONCONFORMING: sindex = 7; break;
5925 case SHF_GROUP: sindex = 8; break;
5926 case SHF_TLS: sindex = 9; break;
18ae9cc1 5927 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 5928 case SHF_COMPRESSED: sindex = 20; break;
a91e1603 5929 case SHF_GNU_MBIND: sindex = 24; break;
76da6bbe 5930
5477e8a0 5931 default:
91d6fa6a 5932 sindex = -1;
dda8d76d 5933 switch (filedata->file_header.e_machine)
148b93f2 5934 {
cfcac11d 5935 case EM_IA_64:
148b93f2 5936 if (flag == SHF_IA_64_SHORT)
91d6fa6a 5937 sindex = 10;
148b93f2 5938 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 5939 sindex = 11;
148b93f2 5940#ifdef BFD64
dda8d76d 5941 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
5942 switch (flag)
5943 {
91d6fa6a
NC
5944 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
5945 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
5946 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
5947 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
5948 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
5949 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
5950 default: break;
5951 }
5952#endif
cfcac11d
NC
5953 break;
5954
caa83f8b 5955 case EM_386:
22abe556 5956 case EM_IAMCU:
caa83f8b 5957 case EM_X86_64:
7f502d6c 5958 case EM_L1OM:
7a9068fe 5959 case EM_K1OM:
cfcac11d
NC
5960 case EM_OLD_SPARCV9:
5961 case EM_SPARC32PLUS:
5962 case EM_SPARCV9:
5963 case EM_SPARC:
18ae9cc1 5964 if (flag == SHF_ORDERED)
91d6fa6a 5965 sindex = 19;
cfcac11d 5966 break;
ac4c9b04
MG
5967
5968 case EM_ARM:
5969 switch (flag)
5970 {
5971 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 5972 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
5973 case SHF_COMDEF: sindex = 23; break;
5974 default: break;
5975 }
5976 break;
83eef883
AFB
5977 case EM_PPC:
5978 if (flag == SHF_PPC_VLE)
5979 sindex = 25;
5980 break;
ac4c9b04 5981
cfcac11d
NC
5982 default:
5983 break;
148b93f2 5984 }
5477e8a0
L
5985 }
5986
91d6fa6a 5987 if (sindex != -1)
5477e8a0 5988 {
8d5ff12c
L
5989 if (p != buff + field_size + 4)
5990 {
5991 if (size < (10 + 2))
bee0ee85
NC
5992 {
5993 warn (_("Internal error: not enough buffer room for section flag info"));
5994 return _("<unknown>");
5995 }
8d5ff12c
L
5996 size -= 2;
5997 *p++ = ',';
5998 *p++ = ' ';
5999 }
6000
91d6fa6a
NC
6001 size -= flags [sindex].len;
6002 p = stpcpy (p, flags [sindex].str);
5477e8a0 6003 }
3b22753a 6004 else if (flag & SHF_MASKOS)
8d5ff12c 6005 os_flags |= flag;
d1133906 6006 else if (flag & SHF_MASKPROC)
8d5ff12c 6007 proc_flags |= flag;
d1133906 6008 else
8d5ff12c 6009 unknown_flags |= flag;
5477e8a0
L
6010 }
6011 else
6012 {
6013 switch (flag)
6014 {
6015 case SHF_WRITE: *p = 'W'; break;
6016 case SHF_ALLOC: *p = 'A'; break;
6017 case SHF_EXECINSTR: *p = 'X'; break;
6018 case SHF_MERGE: *p = 'M'; break;
6019 case SHF_STRINGS: *p = 'S'; break;
6020 case SHF_INFO_LINK: *p = 'I'; break;
6021 case SHF_LINK_ORDER: *p = 'L'; break;
6022 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6023 case SHF_GROUP: *p = 'G'; break;
6024 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6025 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6026 case SHF_COMPRESSED: *p = 'C'; break;
a91e1603 6027 case SHF_GNU_MBIND: *p = 'D'; break;
5477e8a0
L
6028
6029 default:
dda8d76d
NC
6030 if ((filedata->file_header.e_machine == EM_X86_64
6031 || filedata->file_header.e_machine == EM_L1OM
6032 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6033 && flag == SHF_X86_64_LARGE)
6034 *p = 'l';
dda8d76d 6035 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6036 && flag == SHF_ARM_PURECODE)
91f68a68 6037 *p = 'y';
dda8d76d 6038 else if (filedata->file_header.e_machine == EM_PPC
83eef883
AFB
6039 && flag == SHF_PPC_VLE)
6040 *p = 'v';
5477e8a0
L
6041 else if (flag & SHF_MASKOS)
6042 {
6043 *p = 'o';
6044 sh_flags &= ~ SHF_MASKOS;
6045 }
6046 else if (flag & SHF_MASKPROC)
6047 {
6048 *p = 'p';
6049 sh_flags &= ~ SHF_MASKPROC;
6050 }
6051 else
6052 *p = 'x';
6053 break;
6054 }
6055 p++;
d1133906
NC
6056 }
6057 }
76da6bbe 6058
8d5ff12c
L
6059 if (do_section_details)
6060 {
6061 if (os_flags)
6062 {
6063 size -= 5 + field_size;
6064 if (p != buff + field_size + 4)
6065 {
6066 if (size < (2 + 1))
bee0ee85
NC
6067 {
6068 warn (_("Internal error: not enough buffer room for section flag info"));
6069 return _("<unknown>");
6070 }
8d5ff12c
L
6071 size -= 2;
6072 *p++ = ',';
6073 *p++ = ' ';
6074 }
6075 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6076 (unsigned long) os_flags);
6077 p += 5 + field_size;
6078 }
6079 if (proc_flags)
6080 {
6081 size -= 7 + field_size;
6082 if (p != buff + field_size + 4)
6083 {
6084 if (size < (2 + 1))
bee0ee85
NC
6085 {
6086 warn (_("Internal error: not enough buffer room for section flag info"));
6087 return _("<unknown>");
6088 }
8d5ff12c
L
6089 size -= 2;
6090 *p++ = ',';
6091 *p++ = ' ';
6092 }
6093 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6094 (unsigned long) proc_flags);
6095 p += 7 + field_size;
6096 }
6097 if (unknown_flags)
6098 {
6099 size -= 10 + field_size;
6100 if (p != buff + field_size + 4)
6101 {
6102 if (size < (2 + 1))
bee0ee85
NC
6103 {
6104 warn (_("Internal error: not enough buffer room for section flag info"));
6105 return _("<unknown>");
6106 }
8d5ff12c
L
6107 size -= 2;
6108 *p++ = ',';
6109 *p++ = ' ';
6110 }
2b692964 6111 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6112 (unsigned long) unknown_flags);
6113 p += 10 + field_size;
6114 }
6115 }
6116
e9e44622 6117 *p = '\0';
d1133906
NC
6118 return buff;
6119}
6120
5844b465 6121static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6122get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6123{
6124 if (is_32bit_elf)
6125 {
6126 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6127
ebdf1ebf
NC
6128 if (size < sizeof (* echdr))
6129 {
6130 error (_("Compressed section is too small even for a compression header\n"));
6131 return 0;
6132 }
6133
77115a4a
L
6134 chdr->ch_type = BYTE_GET (echdr->ch_type);
6135 chdr->ch_size = BYTE_GET (echdr->ch_size);
6136 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6137 return sizeof (*echdr);
6138 }
6139 else
6140 {
6141 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6142
ebdf1ebf
NC
6143 if (size < sizeof (* echdr))
6144 {
6145 error (_("Compressed section is too small even for a compression header\n"));
6146 return 0;
6147 }
6148
77115a4a
L
6149 chdr->ch_type = BYTE_GET (echdr->ch_type);
6150 chdr->ch_size = BYTE_GET (echdr->ch_size);
6151 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6152 return sizeof (*echdr);
6153 }
6154}
6155
32ec8896 6156static bfd_boolean
dda8d76d 6157process_section_headers (Filedata * filedata)
252b5132 6158{
2cf0635d 6159 Elf_Internal_Shdr * section;
b34976b6 6160 unsigned int i;
252b5132 6161
8fb879cd 6162 free (filedata->section_headers);
dda8d76d 6163 filedata->section_headers = NULL;
978c4450
AM
6164 free (filedata->dynamic_symbols);
6165 filedata->dynamic_symbols = NULL;
6166 filedata->num_dynamic_syms = 0;
6167 free (filedata->dynamic_strings);
6168 filedata->dynamic_strings = NULL;
6169 filedata->dynamic_strings_length = 0;
6170 free (filedata->dynamic_syminfo);
6171 filedata->dynamic_syminfo = NULL;
6172 while (filedata->symtab_shndx_list != NULL)
8ff66993 6173 {
978c4450
AM
6174 elf_section_list *next = filedata->symtab_shndx_list->next;
6175 free (filedata->symtab_shndx_list);
6176 filedata->symtab_shndx_list = next;
8ff66993 6177 }
252b5132 6178
dda8d76d 6179 if (filedata->file_header.e_shnum == 0)
252b5132 6180 {
82f2dbf7 6181 /* PR binutils/12467. */
dda8d76d 6182 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6183 {
6184 warn (_("possibly corrupt ELF file header - it has a non-zero"
6185 " section header offset, but no section headers\n"));
6186 return FALSE;
6187 }
82f2dbf7 6188 else if (do_sections)
252b5132
RH
6189 printf (_("\nThere are no sections in this file.\n"));
6190
32ec8896 6191 return TRUE;
252b5132
RH
6192 }
6193
6194 if (do_sections && !do_header)
d3a49aa8
AM
6195 printf (ngettext ("There is %d section header, "
6196 "starting at offset 0x%lx:\n",
6197 "There are %d section headers, "
6198 "starting at offset 0x%lx:\n",
dda8d76d
NC
6199 filedata->file_header.e_shnum),
6200 filedata->file_header.e_shnum,
6201 (unsigned long) filedata->file_header.e_shoff);
252b5132 6202
9ea033b2
NC
6203 if (is_32bit_elf)
6204 {
dda8d76d 6205 if (! get_32bit_section_headers (filedata, FALSE))
32ec8896
NC
6206 return FALSE;
6207 }
6208 else
6209 {
dda8d76d 6210 if (! get_64bit_section_headers (filedata, FALSE))
32ec8896 6211 return FALSE;
9ea033b2 6212 }
252b5132
RH
6213
6214 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6215 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6216 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6217 {
dda8d76d 6218 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6219
c256ffe7
JJ
6220 if (section->sh_size != 0)
6221 {
dda8d76d
NC
6222 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6223 1, section->sh_size,
6224 _("string table"));
0de14b54 6225
dda8d76d 6226 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6227 }
252b5132
RH
6228 }
6229
6230 /* Scan the sections for the dynamic symbol table
e3c8793a 6231 and dynamic string table and debug sections. */
89fac5e3 6232 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6233 switch (filedata->file_header.e_machine)
89fac5e3
RS
6234 {
6235 case EM_MIPS:
6236 case EM_MIPS_RS3_LE:
6237 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6238 FDE addresses. However, the ABI also has a semi-official ILP32
6239 variant for which the normal FDE address size rules apply.
6240
6241 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6242 section, where XX is the size of longs in bits. Unfortunately,
6243 earlier compilers provided no way of distinguishing ILP32 objects
6244 from LP64 objects, so if there's any doubt, we should assume that
6245 the official LP64 form is being used. */
dda8d76d
NC
6246 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6247 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6248 eh_addr_size = 8;
6249 break;
0f56a26a
DD
6250
6251 case EM_H8_300:
6252 case EM_H8_300H:
dda8d76d 6253 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6254 {
6255 case E_H8_MACH_H8300:
6256 case E_H8_MACH_H8300HN:
6257 case E_H8_MACH_H8300SN:
6258 case E_H8_MACH_H8300SXN:
6259 eh_addr_size = 2;
6260 break;
6261 case E_H8_MACH_H8300H:
6262 case E_H8_MACH_H8300S:
6263 case E_H8_MACH_H8300SX:
6264 eh_addr_size = 4;
6265 break;
6266 }
f4236fe4
DD
6267 break;
6268
ff7eeb89 6269 case EM_M32C_OLD:
f4236fe4 6270 case EM_M32C:
dda8d76d 6271 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6272 {
6273 case EF_M32C_CPU_M16C:
6274 eh_addr_size = 2;
6275 break;
6276 }
6277 break;
89fac5e3
RS
6278 }
6279
76ca31c0
NC
6280#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6281 do \
6282 { \
6283 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6284 if (section->sh_entsize != expected_entsize) \
9dd3a467 6285 { \
76ca31c0
NC
6286 char buf[40]; \
6287 sprintf_vma (buf, section->sh_entsize); \
6288 /* Note: coded this way so that there is a single string for \
6289 translation. */ \
6290 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6291 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6292 (unsigned) expected_entsize); \
9dd3a467 6293 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6294 } \
6295 } \
08d8fa11 6296 while (0)
9dd3a467
NC
6297
6298#define CHECK_ENTSIZE(section, i, type) \
1b513401 6299 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
6300 sizeof (Elf64_External_##type))
6301
dda8d76d
NC
6302 for (i = 0, section = filedata->section_headers;
6303 i < filedata->file_header.e_shnum;
b34976b6 6304 i++, section++)
252b5132 6305 {
2cf0635d 6306 char * name = SECTION_NAME (section);
252b5132 6307
1b513401
NC
6308 /* Run some sanity checks on the headers and
6309 possibly fill in some file data as well. */
6310 switch (section->sh_type)
252b5132 6311 {
1b513401 6312 case SHT_DYNSYM:
978c4450 6313 if (filedata->dynamic_symbols != NULL)
252b5132
RH
6314 {
6315 error (_("File contains multiple dynamic symbol tables\n"));
6316 continue;
6317 }
6318
08d8fa11 6319 CHECK_ENTSIZE (section, i, Sym);
978c4450
AM
6320 filedata->dynamic_symbols
6321 = GET_ELF_SYMBOLS (filedata, section, &filedata->num_dynamic_syms);
1b513401
NC
6322 break;
6323
6324 case SHT_STRTAB:
6325 if (streq (name, ".dynstr"))
252b5132 6326 {
1b513401
NC
6327 if (filedata->dynamic_strings != NULL)
6328 {
6329 error (_("File contains multiple dynamic string tables\n"));
6330 continue;
6331 }
6332
6333 filedata->dynamic_strings
6334 = (char *) get_data (NULL, filedata, section->sh_offset,
6335 1, section->sh_size, _("dynamic strings"));
6336 filedata->dynamic_strings_length
6337 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 6338 }
1b513401
NC
6339 break;
6340
6341 case SHT_SYMTAB_SHNDX:
6342 {
6343 elf_section_list * entry = xmalloc (sizeof * entry);
6344
6345 entry->hdr = section;
6346 entry->next = filedata->symtab_shndx_list;
6347 filedata->symtab_shndx_list = entry;
6348 }
6349 break;
6350
6351 case SHT_SYMTAB:
6352 CHECK_ENTSIZE (section, i, Sym);
6353 break;
6354
6355 case SHT_GROUP:
6356 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6357 break;
252b5132 6358
1b513401
NC
6359 case SHT_REL:
6360 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 6361 if (do_checks && section->sh_size == 0)
1b513401
NC
6362 warn (_("Section '%s': zero-sized relocation section\n"), name);
6363 break;
6364
6365 case SHT_RELA:
6366 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 6367 if (do_checks && section->sh_size == 0)
1b513401
NC
6368 warn (_("Section '%s': zero-sized relocation section\n"), name);
6369 break;
6370
6371 case SHT_NOTE:
6372 case SHT_PROGBITS:
546cb2d8
NC
6373 /* Having a zero sized section is not illegal according to the
6374 ELF standard, but it might be an indication that something
6375 is wrong. So issue a warning if we are running in lint mode. */
6376 if (do_checks && section->sh_size == 0)
1b513401
NC
6377 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
6378 break;
6379
6380 default:
6381 break;
6382 }
6383
6384 if ((do_debugging || do_debug_info || do_debug_abbrevs
6385 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
6386 || do_debug_aranges || do_debug_frames || do_debug_macinfo
6387 || do_debug_str || do_debug_loc || do_debug_ranges
6388 || do_debug_addr || do_debug_cu_index || do_debug_links)
6389 && (const_strneq (name, ".debug_")
6390 || const_strneq (name, ".zdebug_")))
252b5132 6391 {
1b315056
CS
6392 if (name[1] == 'z')
6393 name += sizeof (".zdebug_") - 1;
6394 else
6395 name += sizeof (".debug_") - 1;
252b5132
RH
6396
6397 if (do_debugging
4723351a
CC
6398 || (do_debug_info && const_strneq (name, "info"))
6399 || (do_debug_info && const_strneq (name, "types"))
6400 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
6401 || (do_debug_lines && strcmp (name, "line") == 0)
6402 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
6403 || (do_debug_pubnames && const_strneq (name, "pubnames"))
6404 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
6405 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
6406 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
6407 || (do_debug_aranges && const_strneq (name, "aranges"))
6408 || (do_debug_ranges && const_strneq (name, "ranges"))
77145576 6409 || (do_debug_ranges && const_strneq (name, "rnglists"))
4723351a
CC
6410 || (do_debug_frames && const_strneq (name, "frame"))
6411 || (do_debug_macinfo && const_strneq (name, "macinfo"))
6412 || (do_debug_macinfo && const_strneq (name, "macro"))
6413 || (do_debug_str && const_strneq (name, "str"))
6414 || (do_debug_loc && const_strneq (name, "loc"))
77145576 6415 || (do_debug_loc && const_strneq (name, "loclists"))
657d0d47
CC
6416 || (do_debug_addr && const_strneq (name, "addr"))
6417 || (do_debug_cu_index && const_strneq (name, "cu_index"))
6418 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 6419 )
6431e409 6420 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6421 }
a262ae96 6422 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6423 else if ((do_debugging || do_debug_info)
0112cd26 6424 && const_strneq (name, ".gnu.linkonce.wi."))
6431e409 6425 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6426 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6427 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6428 else if (do_gdb_index && (streq (name, ".gdb_index")
6429 || streq (name, ".debug_names")))
6431e409 6430 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6431 /* Trace sections for Itanium VMS. */
6432 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6433 || do_trace_aranges)
6434 && const_strneq (name, ".trace_"))
6435 {
6436 name += sizeof (".trace_") - 1;
6437
6438 if (do_debugging
6439 || (do_trace_info && streq (name, "info"))
6440 || (do_trace_abbrevs && streq (name, "abbrev"))
6441 || (do_trace_aranges && streq (name, "aranges"))
6442 )
6431e409 6443 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6444 }
dda8d76d
NC
6445 else if ((do_debugging || do_debug_links)
6446 && (const_strneq (name, ".gnu_debuglink")
6447 || const_strneq (name, ".gnu_debugaltlink")))
6431e409 6448 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6449 }
6450
6451 if (! do_sections)
32ec8896 6452 return TRUE;
252b5132 6453
dda8d76d 6454 if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6455 printf (_("\nSection Headers:\n"));
6456 else
6457 printf (_("\nSection Header:\n"));
76da6bbe 6458
f7a99963 6459 if (is_32bit_elf)
595cf52e 6460 {
5477e8a0 6461 if (do_section_details)
595cf52e
L
6462 {
6463 printf (_(" [Nr] Name\n"));
5477e8a0 6464 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6465 }
6466 else
6467 printf
6468 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6469 }
d974e256 6470 else if (do_wide)
595cf52e 6471 {
5477e8a0 6472 if (do_section_details)
595cf52e
L
6473 {
6474 printf (_(" [Nr] Name\n"));
5477e8a0 6475 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6476 }
6477 else
6478 printf
6479 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6480 }
f7a99963
NC
6481 else
6482 {
5477e8a0 6483 if (do_section_details)
595cf52e
L
6484 {
6485 printf (_(" [Nr] Name\n"));
5477e8a0
L
6486 printf (_(" Type Address Offset Link\n"));
6487 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6488 }
6489 else
6490 {
6491 printf (_(" [Nr] Name Type Address Offset\n"));
6492 printf (_(" Size EntSize Flags Link Info Align\n"));
6493 }
f7a99963 6494 }
252b5132 6495
5477e8a0
L
6496 if (do_section_details)
6497 printf (_(" Flags\n"));
6498
dda8d76d
NC
6499 for (i = 0, section = filedata->section_headers;
6500 i < filedata->file_header.e_shnum;
b34976b6 6501 i++, section++)
252b5132 6502 {
dd905818
NC
6503 /* Run some sanity checks on the section header. */
6504
6505 /* Check the sh_link field. */
6506 switch (section->sh_type)
6507 {
285e3f99
AM
6508 case SHT_REL:
6509 case SHT_RELA:
6510 if (section->sh_link == 0
6511 && (filedata->file_header.e_type == ET_EXEC
6512 || filedata->file_header.e_type == ET_DYN))
6513 /* A dynamic relocation section where all entries use a
6514 zero symbol index need not specify a symtab section. */
6515 break;
6516 /* Fall through. */
dd905818
NC
6517 case SHT_SYMTAB_SHNDX:
6518 case SHT_GROUP:
6519 case SHT_HASH:
6520 case SHT_GNU_HASH:
6521 case SHT_GNU_versym:
285e3f99 6522 if (section->sh_link == 0
dda8d76d
NC
6523 || section->sh_link >= filedata->file_header.e_shnum
6524 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6525 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6526 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6527 i, section->sh_link);
6528 break;
6529
6530 case SHT_DYNAMIC:
6531 case SHT_SYMTAB:
6532 case SHT_DYNSYM:
6533 case SHT_GNU_verneed:
6534 case SHT_GNU_verdef:
6535 case SHT_GNU_LIBLIST:
285e3f99 6536 if (section->sh_link == 0
dda8d76d
NC
6537 || section->sh_link >= filedata->file_header.e_shnum
6538 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6539 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6540 i, section->sh_link);
6541 break;
6542
6543 case SHT_INIT_ARRAY:
6544 case SHT_FINI_ARRAY:
6545 case SHT_PREINIT_ARRAY:
6546 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6547 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6548 i, section->sh_link);
6549 break;
6550
6551 default:
6552 /* FIXME: Add support for target specific section types. */
6553#if 0 /* Currently we do not check other section types as there are too
6554 many special cases. Stab sections for example have a type
6555 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6556 section. */
6557 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6558 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6559 i, section->sh_link);
6560#endif
6561 break;
6562 }
6563
6564 /* Check the sh_info field. */
6565 switch (section->sh_type)
6566 {
6567 case SHT_REL:
6568 case SHT_RELA:
285e3f99
AM
6569 if (section->sh_info == 0
6570 && (filedata->file_header.e_type == ET_EXEC
6571 || filedata->file_header.e_type == ET_DYN))
6572 /* Dynamic relocations apply to segments, so they do not
6573 need to specify the section they relocate. */
6574 break;
6575 if (section->sh_info == 0
dda8d76d
NC
6576 || section->sh_info >= filedata->file_header.e_shnum
6577 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6578 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6579 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6580 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6581 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6582 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6583 /* FIXME: Are other section types valid ? */
dda8d76d 6584 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6585 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6586 i, section->sh_info);
dd905818
NC
6587 break;
6588
6589 case SHT_DYNAMIC:
6590 case SHT_HASH:
6591 case SHT_SYMTAB_SHNDX:
6592 case SHT_INIT_ARRAY:
6593 case SHT_FINI_ARRAY:
6594 case SHT_PREINIT_ARRAY:
6595 if (section->sh_info != 0)
6596 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6597 i, section->sh_info);
6598 break;
6599
6600 case SHT_GROUP:
6601 case SHT_SYMTAB:
6602 case SHT_DYNSYM:
6603 /* A symbol index - we assume that it is valid. */
6604 break;
6605
6606 default:
6607 /* FIXME: Add support for target specific section types. */
6608 if (section->sh_type == SHT_NOBITS)
6609 /* NOBITS section headers with non-zero sh_info fields can be
6610 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6611 information. The stripped sections have their headers
6612 preserved but their types set to SHT_NOBITS. So do not check
6613 this type of section. */
dd905818
NC
6614 ;
6615 else if (section->sh_flags & SHF_INFO_LINK)
6616 {
dda8d76d 6617 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6618 warn (_("[%2u]: Expected link to another section in info field"), i);
6619 }
a91e1603
L
6620 else if (section->sh_type < SHT_LOOS
6621 && (section->sh_flags & SHF_GNU_MBIND) == 0
6622 && section->sh_info != 0)
dd905818
NC
6623 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6624 i, section->sh_info);
6625 break;
6626 }
6627
3e6b6445 6628 /* Check the sh_size field. */
dda8d76d 6629 if (section->sh_size > filedata->file_size
3e6b6445
NC
6630 && section->sh_type != SHT_NOBITS
6631 && section->sh_type != SHT_NULL
6632 && section->sh_type < SHT_LOOS)
6633 warn (_("Size of section %u is larger than the entire file!\n"), i);
6634
7bfd842d 6635 printf (" [%2u] ", i);
5477e8a0 6636 if (do_section_details)
dda8d76d 6637 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6638 else
74e1a04b 6639 print_symbol (-17, SECTION_NAME (section));
0b4362b0 6640
ea52a088 6641 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6642 get_section_type_name (filedata, section->sh_type));
0b4362b0 6643
f7a99963
NC
6644 if (is_32bit_elf)
6645 {
cfcac11d
NC
6646 const char * link_too_big = NULL;
6647
f7a99963 6648 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6649
f7a99963
NC
6650 printf ( " %6.6lx %6.6lx %2.2lx",
6651 (unsigned long) section->sh_offset,
6652 (unsigned long) section->sh_size,
6653 (unsigned long) section->sh_entsize);
d1133906 6654
5477e8a0
L
6655 if (do_section_details)
6656 fputs (" ", stdout);
6657 else
dda8d76d 6658 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6659
dda8d76d 6660 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6661 {
6662 link_too_big = "";
6663 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6664 an error but it can have special values in Solaris binaries. */
dda8d76d 6665 switch (filedata->file_header.e_machine)
cfcac11d 6666 {
caa83f8b 6667 case EM_386:
22abe556 6668 case EM_IAMCU:
caa83f8b 6669 case EM_X86_64:
7f502d6c 6670 case EM_L1OM:
7a9068fe 6671 case EM_K1OM:
cfcac11d
NC
6672 case EM_OLD_SPARCV9:
6673 case EM_SPARC32PLUS:
6674 case EM_SPARCV9:
6675 case EM_SPARC:
6676 if (section->sh_link == (SHN_BEFORE & 0xffff))
6677 link_too_big = "BEFORE";
6678 else if (section->sh_link == (SHN_AFTER & 0xffff))
6679 link_too_big = "AFTER";
6680 break;
6681 default:
6682 break;
6683 }
6684 }
6685
6686 if (do_section_details)
6687 {
6688 if (link_too_big != NULL && * link_too_big)
6689 printf ("<%s> ", link_too_big);
6690 else
6691 printf ("%2u ", section->sh_link);
6692 printf ("%3u %2lu\n", section->sh_info,
6693 (unsigned long) section->sh_addralign);
6694 }
6695 else
6696 printf ("%2u %3u %2lu\n",
6697 section->sh_link,
6698 section->sh_info,
6699 (unsigned long) section->sh_addralign);
6700
6701 if (link_too_big && ! * link_too_big)
6702 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6703 i, section->sh_link);
f7a99963 6704 }
d974e256
JJ
6705 else if (do_wide)
6706 {
6707 print_vma (section->sh_addr, LONG_HEX);
6708
6709 if ((long) section->sh_offset == section->sh_offset)
6710 printf (" %6.6lx", (unsigned long) section->sh_offset);
6711 else
6712 {
6713 putchar (' ');
6714 print_vma (section->sh_offset, LONG_HEX);
6715 }
6716
6717 if ((unsigned long) section->sh_size == section->sh_size)
6718 printf (" %6.6lx", (unsigned long) section->sh_size);
6719 else
6720 {
6721 putchar (' ');
6722 print_vma (section->sh_size, LONG_HEX);
6723 }
6724
6725 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6726 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6727 else
6728 {
6729 putchar (' ');
6730 print_vma (section->sh_entsize, LONG_HEX);
6731 }
6732
5477e8a0
L
6733 if (do_section_details)
6734 fputs (" ", stdout);
6735 else
dda8d76d 6736 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6737
72de5009 6738 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6739
6740 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6741 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6742 else
6743 {
6744 print_vma (section->sh_addralign, DEC);
6745 putchar ('\n');
6746 }
6747 }
5477e8a0 6748 else if (do_section_details)
595cf52e 6749 {
55cc53e9 6750 putchar (' ');
595cf52e
L
6751 print_vma (section->sh_addr, LONG_HEX);
6752 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 6753 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
6754 else
6755 {
6756 printf (" ");
6757 print_vma (section->sh_offset, LONG_HEX);
6758 }
72de5009 6759 printf (" %u\n ", section->sh_link);
595cf52e 6760 print_vma (section->sh_size, LONG_HEX);
5477e8a0 6761 putchar (' ');
595cf52e
L
6762 print_vma (section->sh_entsize, LONG_HEX);
6763
72de5009
AM
6764 printf (" %-16u %lu\n",
6765 section->sh_info,
595cf52e
L
6766 (unsigned long) section->sh_addralign);
6767 }
f7a99963
NC
6768 else
6769 {
6770 putchar (' ');
6771 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
6772 if ((long) section->sh_offset == section->sh_offset)
6773 printf (" %8.8lx", (unsigned long) section->sh_offset);
6774 else
6775 {
6776 printf (" ");
6777 print_vma (section->sh_offset, LONG_HEX);
6778 }
f7a99963
NC
6779 printf ("\n ");
6780 print_vma (section->sh_size, LONG_HEX);
6781 printf (" ");
6782 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 6783
dda8d76d 6784 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6785
72de5009
AM
6786 printf (" %2u %3u %lu\n",
6787 section->sh_link,
6788 section->sh_info,
f7a99963
NC
6789 (unsigned long) section->sh_addralign);
6790 }
5477e8a0
L
6791
6792 if (do_section_details)
77115a4a 6793 {
dda8d76d 6794 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
6795 if ((section->sh_flags & SHF_COMPRESSED) != 0)
6796 {
6797 /* Minimum section size is 12 bytes for 32-bit compression
6798 header + 12 bytes for compressed data header. */
6799 unsigned char buf[24];
d8024a91 6800
77115a4a 6801 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 6802 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
6803 sizeof (buf), _("compression header")))
6804 {
6805 Elf_Internal_Chdr chdr;
d8024a91 6806
5844b465
NC
6807 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
6808 printf (_(" [<corrupt>]\n"));
77115a4a 6809 else
5844b465
NC
6810 {
6811 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
6812 printf (" ZLIB, ");
6813 else
6814 printf (_(" [<unknown>: 0x%x], "),
6815 chdr.ch_type);
6816 print_vma (chdr.ch_size, LONG_HEX);
6817 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
6818 }
77115a4a
L
6819 }
6820 }
6821 }
252b5132
RH
6822 }
6823
5477e8a0 6824 if (!do_section_details)
3dbcc61d 6825 {
9fb71ee4
NC
6826 /* The ordering of the letters shown here matches the ordering of the
6827 corresponding SHF_xxx values, and hence the order in which these
6828 letters will be displayed to the user. */
6829 printf (_("Key to Flags:\n\
6830 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
6831 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 6832 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
dda8d76d
NC
6833 if (filedata->file_header.e_machine == EM_X86_64
6834 || filedata->file_header.e_machine == EM_L1OM
6835 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 6836 printf (_("l (large), "));
dda8d76d 6837 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 6838 printf (_("y (purecode), "));
dda8d76d 6839 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 6840 printf (_("v (VLE), "));
9fb71ee4 6841 printf ("p (processor specific)\n");
0b4362b0 6842 }
d1133906 6843
32ec8896 6844 return TRUE;
252b5132
RH
6845}
6846
28d13567
AM
6847static bfd_boolean
6848get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
6849 Elf_Internal_Sym **symtab, unsigned long *nsyms,
6850 char **strtab, unsigned long *strtablen)
6851{
6852 *strtab = NULL;
6853 *strtablen = 0;
6854 *symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms);
6855
6856 if (*symtab == NULL)
6857 return FALSE;
6858
6859 if (symsec->sh_link != 0)
6860 {
6861 Elf_Internal_Shdr *strsec;
6862
6863 if (symsec->sh_link >= filedata->file_header.e_shnum)
6864 {
6865 error (_("Bad sh_link in symbol table section\n"));
6866 free (*symtab);
6867 *symtab = NULL;
6868 *nsyms = 0;
6869 return FALSE;
6870 }
6871
6872 strsec = filedata->section_headers + symsec->sh_link;
6873
6874 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
6875 1, strsec->sh_size, _("string table"));
6876 if (*strtab == NULL)
6877 {
6878 free (*symtab);
6879 *symtab = NULL;
6880 *nsyms = 0;
6881 return FALSE;
6882 }
6883 *strtablen = strsec->sh_size;
6884 }
6885 return TRUE;
6886}
6887
f5842774
L
6888static const char *
6889get_group_flags (unsigned int flags)
6890{
1449284b 6891 static char buff[128];
220453ec 6892
6d913794
NC
6893 if (flags == 0)
6894 return "";
6895 else if (flags == GRP_COMDAT)
6896 return "COMDAT ";
f5842774 6897
89246a0e
AM
6898 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
6899 flags,
6900 flags & GRP_MASKOS ? _("<OS specific>") : "",
6901 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
6902 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
6903 ? _("<unknown>") : ""));
6d913794 6904
f5842774
L
6905 return buff;
6906}
6907
32ec8896 6908static bfd_boolean
dda8d76d 6909process_section_groups (Filedata * filedata)
f5842774 6910{
2cf0635d 6911 Elf_Internal_Shdr * section;
f5842774 6912 unsigned int i;
2cf0635d
NC
6913 struct group * group;
6914 Elf_Internal_Shdr * symtab_sec;
6915 Elf_Internal_Shdr * strtab_sec;
6916 Elf_Internal_Sym * symtab;
ba5cdace 6917 unsigned long num_syms;
2cf0635d 6918 char * strtab;
c256ffe7 6919 size_t strtab_size;
d1f5c6e3
L
6920
6921 /* Don't process section groups unless needed. */
6922 if (!do_unwind && !do_section_groups)
32ec8896 6923 return TRUE;
f5842774 6924
dda8d76d 6925 if (filedata->file_header.e_shnum == 0)
f5842774
L
6926 {
6927 if (do_section_groups)
82f2dbf7 6928 printf (_("\nThere are no sections to group in this file.\n"));
f5842774 6929
32ec8896 6930 return TRUE;
f5842774
L
6931 }
6932
dda8d76d 6933 if (filedata->section_headers == NULL)
f5842774
L
6934 {
6935 error (_("Section headers are not available!\n"));
fa1908fd 6936 /* PR 13622: This can happen with a corrupt ELF header. */
32ec8896 6937 return FALSE;
f5842774
L
6938 }
6939
978c4450
AM
6940 filedata->section_headers_groups
6941 = (struct group **) calloc (filedata->file_header.e_shnum,
6942 sizeof (struct group *));
e4b17d5c 6943
978c4450 6944 if (filedata->section_headers_groups == NULL)
e4b17d5c 6945 {
8b73c356 6946 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 6947 filedata->file_header.e_shnum);
32ec8896 6948 return FALSE;
e4b17d5c
L
6949 }
6950
f5842774 6951 /* Scan the sections for the group section. */
978c4450 6952 filedata->group_count = 0;
dda8d76d
NC
6953 for (i = 0, section = filedata->section_headers;
6954 i < filedata->file_header.e_shnum;
f5842774 6955 i++, section++)
e4b17d5c 6956 if (section->sh_type == SHT_GROUP)
978c4450 6957 filedata->group_count++;
e4b17d5c 6958
978c4450 6959 if (filedata->group_count == 0)
d1f5c6e3
L
6960 {
6961 if (do_section_groups)
6962 printf (_("\nThere are no section groups in this file.\n"));
6963
32ec8896 6964 return TRUE;
d1f5c6e3
L
6965 }
6966
978c4450
AM
6967 filedata->section_groups = (struct group *) calloc (filedata->group_count,
6968 sizeof (struct group));
e4b17d5c 6969
978c4450 6970 if (filedata->section_groups == NULL)
e4b17d5c 6971 {
8b73c356 6972 error (_("Out of memory reading %lu groups\n"),
978c4450 6973 (unsigned long) filedata->group_count);
32ec8896 6974 return FALSE;
e4b17d5c
L
6975 }
6976
d1f5c6e3
L
6977 symtab_sec = NULL;
6978 strtab_sec = NULL;
6979 symtab = NULL;
ba5cdace 6980 num_syms = 0;
d1f5c6e3 6981 strtab = NULL;
c256ffe7 6982 strtab_size = 0;
978c4450 6983 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 6984 i < filedata->file_header.e_shnum;
e4b17d5c 6985 i++, section++)
f5842774
L
6986 {
6987 if (section->sh_type == SHT_GROUP)
6988 {
dda8d76d 6989 const char * name = printable_section_name (filedata, section);
74e1a04b 6990 const char * group_name;
2cf0635d
NC
6991 unsigned char * start;
6992 unsigned char * indices;
f5842774 6993 unsigned int entry, j, size;
2cf0635d
NC
6994 Elf_Internal_Shdr * sec;
6995 Elf_Internal_Sym * sym;
f5842774
L
6996
6997 /* Get the symbol table. */
dda8d76d
NC
6998 if (section->sh_link >= filedata->file_header.e_shnum
6999 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7000 != SHT_SYMTAB))
f5842774
L
7001 {
7002 error (_("Bad sh_link in group section `%s'\n"), name);
7003 continue;
7004 }
d1f5c6e3
L
7005
7006 if (symtab_sec != sec)
7007 {
7008 symtab_sec = sec;
7009 if (symtab)
7010 free (symtab);
dda8d76d 7011 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 7012 }
f5842774 7013
dd24e3da
NC
7014 if (symtab == NULL)
7015 {
7016 error (_("Corrupt header in group section `%s'\n"), name);
7017 continue;
7018 }
7019
ba5cdace
NC
7020 if (section->sh_info >= num_syms)
7021 {
7022 error (_("Bad sh_info in group section `%s'\n"), name);
7023 continue;
7024 }
7025
f5842774
L
7026 sym = symtab + section->sh_info;
7027
7028 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7029 {
4fbb74a6 7030 if (sym->st_shndx == 0
dda8d76d 7031 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7032 {
7033 error (_("Bad sh_info in group section `%s'\n"), name);
7034 continue;
7035 }
ba2685cc 7036
dda8d76d 7037 group_name = SECTION_NAME (filedata->section_headers + sym->st_shndx);
c256ffe7
JJ
7038 strtab_sec = NULL;
7039 if (strtab)
7040 free (strtab);
f5842774 7041 strtab = NULL;
c256ffe7 7042 strtab_size = 0;
f5842774
L
7043 }
7044 else
7045 {
7046 /* Get the string table. */
dda8d76d 7047 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7048 {
7049 strtab_sec = NULL;
7050 if (strtab)
7051 free (strtab);
7052 strtab = NULL;
7053 strtab_size = 0;
7054 }
7055 else if (strtab_sec
dda8d76d 7056 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7057 {
7058 strtab_sec = sec;
7059 if (strtab)
7060 free (strtab);
071436c6 7061
dda8d76d 7062 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7063 1, strtab_sec->sh_size,
7064 _("string table"));
c256ffe7 7065 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7066 }
c256ffe7 7067 group_name = sym->st_name < strtab_size
2b692964 7068 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7069 }
7070
c9c1d674
EG
7071 /* PR 17531: file: loop. */
7072 if (section->sh_entsize > section->sh_size)
7073 {
7074 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7075 printable_section_name (filedata, section),
8066deb1
AM
7076 (unsigned long) section->sh_entsize,
7077 (unsigned long) section->sh_size);
61dd8e19 7078 continue;
c9c1d674
EG
7079 }
7080
dda8d76d 7081 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7082 1, section->sh_size,
7083 _("section data"));
59245841
NC
7084 if (start == NULL)
7085 continue;
f5842774
L
7086
7087 indices = start;
7088 size = (section->sh_size / section->sh_entsize) - 1;
7089 entry = byte_get (indices, 4);
7090 indices += 4;
e4b17d5c
L
7091
7092 if (do_section_groups)
7093 {
2b692964 7094 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7095 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7096
e4b17d5c
L
7097 printf (_(" [Index] Name\n"));
7098 }
7099
7100 group->group_index = i;
7101
f5842774
L
7102 for (j = 0; j < size; j++)
7103 {
2cf0635d 7104 struct group_list * g;
e4b17d5c 7105
f5842774
L
7106 entry = byte_get (indices, 4);
7107 indices += 4;
7108
dda8d76d 7109 if (entry >= filedata->file_header.e_shnum)
391cb864 7110 {
57028622
NC
7111 static unsigned num_group_errors = 0;
7112
7113 if (num_group_errors ++ < 10)
7114 {
7115 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7116 entry, i, filedata->file_header.e_shnum - 1);
57028622 7117 if (num_group_errors == 10)
67ce483b 7118 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7119 }
391cb864
L
7120 continue;
7121 }
391cb864 7122
978c4450 7123 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7124 {
d1f5c6e3
L
7125 if (entry)
7126 {
57028622
NC
7127 static unsigned num_errs = 0;
7128
7129 if (num_errs ++ < 10)
7130 {
7131 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7132 entry, i,
978c4450 7133 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7134 if (num_errs == 10)
7135 warn (_("Further error messages about already contained group sections suppressed\n"));
7136 }
d1f5c6e3
L
7137 continue;
7138 }
7139 else
7140 {
7141 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7142 section group. We just warn it the first time
d1f5c6e3 7143 and ignore it afterwards. */
32ec8896 7144 static bfd_boolean warned = FALSE;
d1f5c6e3
L
7145 if (!warned)
7146 {
7147 error (_("section 0 in group section [%5u]\n"),
978c4450 7148 filedata->section_headers_groups [entry]->group_index);
32ec8896 7149 warned = TRUE;
d1f5c6e3
L
7150 }
7151 }
e4b17d5c
L
7152 }
7153
978c4450 7154 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7155
7156 if (do_section_groups)
7157 {
dda8d76d
NC
7158 sec = filedata->section_headers + entry;
7159 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7160 }
7161
3f5e193b 7162 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7163 g->section_index = entry;
7164 g->next = group->root;
7165 group->root = g;
f5842774
L
7166 }
7167
f5842774
L
7168 if (start)
7169 free (start);
e4b17d5c
L
7170
7171 group++;
f5842774
L
7172 }
7173 }
7174
d1f5c6e3
L
7175 if (symtab)
7176 free (symtab);
7177 if (strtab)
7178 free (strtab);
32ec8896 7179 return TRUE;
f5842774
L
7180}
7181
28f997cf
TG
7182/* Data used to display dynamic fixups. */
7183
7184struct ia64_vms_dynfixup
7185{
7186 bfd_vma needed_ident; /* Library ident number. */
7187 bfd_vma needed; /* Index in the dstrtab of the library name. */
7188 bfd_vma fixup_needed; /* Index of the library. */
7189 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7190 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7191};
7192
7193/* Data used to display dynamic relocations. */
7194
7195struct ia64_vms_dynimgrela
7196{
7197 bfd_vma img_rela_cnt; /* Number of relocations. */
7198 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7199};
7200
7201/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7202 library). */
7203
32ec8896 7204static bfd_boolean
dda8d76d
NC
7205dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7206 struct ia64_vms_dynfixup * fixup,
7207 const char * strtab,
7208 unsigned int strtab_sz)
28f997cf 7209{
32ec8896 7210 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7211 long i;
32ec8896 7212 const char * lib_name;
28f997cf 7213
978c4450
AM
7214 imfs = get_data (NULL, filedata,
7215 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7216 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7217 _("dynamic section image fixups"));
7218 if (!imfs)
32ec8896 7219 return FALSE;
28f997cf
TG
7220
7221 if (fixup->needed < strtab_sz)
7222 lib_name = strtab + fixup->needed;
7223 else
7224 {
32ec8896 7225 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7226 (unsigned long) fixup->needed);
28f997cf
TG
7227 lib_name = "???";
7228 }
736990c4 7229
28f997cf
TG
7230 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7231 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7232 printf
7233 (_("Seg Offset Type SymVec DataType\n"));
7234
7235 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7236 {
7237 unsigned int type;
7238 const char *rtype;
7239
7240 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7241 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7242 type = BYTE_GET (imfs [i].type);
7243 rtype = elf_ia64_reloc_type (type);
7244 if (rtype == NULL)
7245 printf (" 0x%08x ", type);
7246 else
7247 printf (" %-32s ", rtype);
7248 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7249 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7250 }
7251
7252 free (imfs);
32ec8896 7253 return TRUE;
28f997cf
TG
7254}
7255
7256/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7257
32ec8896 7258static bfd_boolean
dda8d76d 7259dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7260{
7261 Elf64_External_VMS_IMAGE_RELA *imrs;
7262 long i;
7263
978c4450
AM
7264 imrs = get_data (NULL, filedata,
7265 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 7266 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7267 _("dynamic section image relocations"));
28f997cf 7268 if (!imrs)
32ec8896 7269 return FALSE;
28f997cf
TG
7270
7271 printf (_("\nImage relocs\n"));
7272 printf
7273 (_("Seg Offset Type Addend Seg Sym Off\n"));
7274
7275 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7276 {
7277 unsigned int type;
7278 const char *rtype;
7279
7280 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7281 printf ("%08" BFD_VMA_FMT "x ",
7282 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7283 type = BYTE_GET (imrs [i].type);
7284 rtype = elf_ia64_reloc_type (type);
7285 if (rtype == NULL)
7286 printf ("0x%08x ", type);
7287 else
7288 printf ("%-31s ", rtype);
7289 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7290 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7291 printf ("%08" BFD_VMA_FMT "x\n",
7292 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7293 }
7294
7295 free (imrs);
32ec8896 7296 return TRUE;
28f997cf
TG
7297}
7298
7299/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7300
32ec8896 7301static bfd_boolean
dda8d76d 7302process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7303{
7304 struct ia64_vms_dynfixup fixup;
7305 struct ia64_vms_dynimgrela imgrela;
7306 Elf_Internal_Dyn *entry;
28f997cf
TG
7307 bfd_vma strtab_off = 0;
7308 bfd_vma strtab_sz = 0;
7309 char *strtab = NULL;
32ec8896 7310 bfd_boolean res = TRUE;
28f997cf
TG
7311
7312 memset (&fixup, 0, sizeof (fixup));
7313 memset (&imgrela, 0, sizeof (imgrela));
7314
7315 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
7316 for (entry = filedata->dynamic_section;
7317 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
7318 entry++)
7319 {
7320 switch (entry->d_tag)
7321 {
7322 case DT_IA_64_VMS_STRTAB_OFFSET:
7323 strtab_off = entry->d_un.d_val;
7324 break;
7325 case DT_STRSZ:
7326 strtab_sz = entry->d_un.d_val;
7327 if (strtab == NULL)
978c4450
AM
7328 strtab = get_data (NULL, filedata,
7329 filedata->dynamic_addr + strtab_off,
28f997cf 7330 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7331 if (strtab == NULL)
7332 strtab_sz = 0;
28f997cf
TG
7333 break;
7334
7335 case DT_IA_64_VMS_NEEDED_IDENT:
7336 fixup.needed_ident = entry->d_un.d_val;
7337 break;
7338 case DT_NEEDED:
7339 fixup.needed = entry->d_un.d_val;
7340 break;
7341 case DT_IA_64_VMS_FIXUP_NEEDED:
7342 fixup.fixup_needed = entry->d_un.d_val;
7343 break;
7344 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7345 fixup.fixup_rela_cnt = entry->d_un.d_val;
7346 break;
7347 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7348 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7349 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
32ec8896 7350 res = FALSE;
28f997cf 7351 break;
28f997cf
TG
7352 case DT_IA_64_VMS_IMG_RELA_CNT:
7353 imgrela.img_rela_cnt = entry->d_un.d_val;
7354 break;
7355 case DT_IA_64_VMS_IMG_RELA_OFF:
7356 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7357 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
32ec8896 7358 res = FALSE;
28f997cf
TG
7359 break;
7360
7361 default:
7362 break;
7363 }
7364 }
7365
7366 if (strtab != NULL)
7367 free (strtab);
7368
7369 return res;
7370}
7371
85b1c36d 7372static struct
566b0d53 7373{
2cf0635d 7374 const char * name;
566b0d53
L
7375 int reloc;
7376 int size;
7377 int rela;
32ec8896
NC
7378}
7379 dynamic_relocations [] =
566b0d53 7380{
32ec8896
NC
7381 { "REL", DT_REL, DT_RELSZ, FALSE },
7382 { "RELA", DT_RELA, DT_RELASZ, TRUE },
7383 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7384};
7385
252b5132 7386/* Process the reloc section. */
18bd398b 7387
32ec8896 7388static bfd_boolean
dda8d76d 7389process_relocs (Filedata * filedata)
252b5132 7390{
b34976b6
AM
7391 unsigned long rel_size;
7392 unsigned long rel_offset;
252b5132 7393
252b5132 7394 if (!do_reloc)
32ec8896 7395 return TRUE;
252b5132
RH
7396
7397 if (do_using_dynamic)
7398 {
32ec8896 7399 int is_rela;
2cf0635d 7400 const char * name;
32ec8896 7401 bfd_boolean has_dynamic_reloc;
566b0d53 7402 unsigned int i;
0de14b54 7403
32ec8896 7404 has_dynamic_reloc = FALSE;
252b5132 7405
566b0d53 7406 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7407 {
566b0d53
L
7408 is_rela = dynamic_relocations [i].rela;
7409 name = dynamic_relocations [i].name;
978c4450
AM
7410 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
7411 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 7412
32ec8896
NC
7413 if (rel_size)
7414 has_dynamic_reloc = TRUE;
566b0d53
L
7415
7416 if (is_rela == UNKNOWN)
aa903cfb 7417 {
566b0d53 7418 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 7419 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
7420 {
7421 case DT_REL:
7422 is_rela = FALSE;
7423 break;
7424 case DT_RELA:
7425 is_rela = TRUE;
7426 break;
7427 }
aa903cfb 7428 }
252b5132 7429
566b0d53
L
7430 if (rel_size)
7431 {
7432 printf
7433 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7434 name, rel_offset, rel_size);
252b5132 7435
dda8d76d
NC
7436 dump_relocations (filedata,
7437 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7438 rel_size,
978c4450
AM
7439 filedata->dynamic_symbols,
7440 filedata->num_dynamic_syms,
7441 filedata->dynamic_strings,
7442 filedata->dynamic_strings_length,
32ec8896 7443 is_rela, TRUE /* is_dynamic */);
566b0d53 7444 }
252b5132 7445 }
566b0d53 7446
dda8d76d
NC
7447 if (is_ia64_vms (filedata))
7448 if (process_ia64_vms_dynamic_relocs (filedata))
32ec8896 7449 has_dynamic_reloc = TRUE;
28f997cf 7450
566b0d53 7451 if (! has_dynamic_reloc)
252b5132
RH
7452 printf (_("\nThere are no dynamic relocations in this file.\n"));
7453 }
7454 else
7455 {
2cf0635d 7456 Elf_Internal_Shdr * section;
b34976b6 7457 unsigned long i;
32ec8896 7458 bfd_boolean found = FALSE;
252b5132 7459
dda8d76d
NC
7460 for (i = 0, section = filedata->section_headers;
7461 i < filedata->file_header.e_shnum;
b34976b6 7462 i++, section++)
252b5132
RH
7463 {
7464 if ( section->sh_type != SHT_RELA
7465 && section->sh_type != SHT_REL)
7466 continue;
7467
7468 rel_offset = section->sh_offset;
7469 rel_size = section->sh_size;
7470
7471 if (rel_size)
7472 {
b34976b6 7473 int is_rela;
d3a49aa8 7474 unsigned long num_rela;
103f02d3 7475
252b5132
RH
7476 printf (_("\nRelocation section "));
7477
dda8d76d 7478 if (filedata->string_table == NULL)
19936277 7479 printf ("%d", section->sh_name);
252b5132 7480 else
dda8d76d 7481 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7482
d3a49aa8
AM
7483 num_rela = rel_size / section->sh_entsize;
7484 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7485 " at offset 0x%lx contains %lu entries:\n",
7486 num_rela),
7487 rel_offset, num_rela);
252b5132 7488
d79b3d50
NC
7489 is_rela = section->sh_type == SHT_RELA;
7490
4fbb74a6 7491 if (section->sh_link != 0
dda8d76d 7492 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7493 {
2cf0635d
NC
7494 Elf_Internal_Shdr * symsec;
7495 Elf_Internal_Sym * symtab;
d79b3d50 7496 unsigned long nsyms;
c256ffe7 7497 unsigned long strtablen = 0;
2cf0635d 7498 char * strtab = NULL;
57346661 7499
dda8d76d 7500 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7501 if (symsec->sh_type != SHT_SYMTAB
7502 && symsec->sh_type != SHT_DYNSYM)
7503 continue;
7504
28d13567
AM
7505 if (!get_symtab (filedata, symsec,
7506 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7507 continue;
252b5132 7508
dda8d76d 7509 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7510 symtab, nsyms, strtab, strtablen,
7511 is_rela,
7512 symsec->sh_type == SHT_DYNSYM);
d79b3d50
NC
7513 if (strtab)
7514 free (strtab);
7515 free (symtab);
7516 }
7517 else
dda8d76d 7518 dump_relocations (filedata, rel_offset, rel_size,
32ec8896
NC
7519 NULL, 0, NULL, 0, is_rela,
7520 FALSE /* is_dynamic */);
252b5132 7521
32ec8896 7522 found = TRUE;
252b5132
RH
7523 }
7524 }
7525
7526 if (! found)
45ac8f4f
NC
7527 {
7528 /* Users sometimes forget the -D option, so try to be helpful. */
7529 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7530 {
978c4450 7531 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f
NC
7532 {
7533 printf (_("\nThere are no static relocations in this file."));
7534 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7535
7536 break;
7537 }
7538 }
7539 if (i == ARRAY_SIZE (dynamic_relocations))
7540 printf (_("\nThere are no relocations in this file.\n"));
7541 }
252b5132
RH
7542 }
7543
32ec8896 7544 return TRUE;
252b5132
RH
7545}
7546
4d6ed7c8
NC
7547/* An absolute address consists of a section and an offset. If the
7548 section is NULL, the offset itself is the address, otherwise, the
7549 address equals to LOAD_ADDRESS(section) + offset. */
7550
7551struct absaddr
948f632f
DA
7552{
7553 unsigned short section;
7554 bfd_vma offset;
7555};
4d6ed7c8 7556
948f632f
DA
7557/* Find the nearest symbol at or below ADDR. Returns the symbol
7558 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7559
4d6ed7c8 7560static void
dda8d76d
NC
7561find_symbol_for_address (Filedata * filedata,
7562 Elf_Internal_Sym * symtab,
7563 unsigned long nsyms,
7564 const char * strtab,
7565 unsigned long strtab_size,
7566 struct absaddr addr,
7567 const char ** symname,
7568 bfd_vma * offset)
4d6ed7c8 7569{
d3ba0551 7570 bfd_vma dist = 0x100000;
2cf0635d 7571 Elf_Internal_Sym * sym;
948f632f
DA
7572 Elf_Internal_Sym * beg;
7573 Elf_Internal_Sym * end;
2cf0635d 7574 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7575
0b6ae522 7576 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7577 beg = symtab;
7578 end = symtab + nsyms;
0b6ae522 7579
948f632f 7580 while (beg < end)
4d6ed7c8 7581 {
948f632f
DA
7582 bfd_vma value;
7583
7584 sym = beg + (end - beg) / 2;
0b6ae522 7585
948f632f 7586 value = sym->st_value;
0b6ae522
DJ
7587 REMOVE_ARCH_BITS (value);
7588
948f632f 7589 if (sym->st_name != 0
4d6ed7c8 7590 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7591 && addr.offset >= value
7592 && addr.offset - value < dist)
4d6ed7c8
NC
7593 {
7594 best = sym;
0b6ae522 7595 dist = addr.offset - value;
4d6ed7c8
NC
7596 if (!dist)
7597 break;
7598 }
948f632f
DA
7599
7600 if (addr.offset < value)
7601 end = sym;
7602 else
7603 beg = sym + 1;
4d6ed7c8 7604 }
1b31d05e 7605
4d6ed7c8
NC
7606 if (best)
7607 {
57346661 7608 *symname = (best->st_name >= strtab_size
2b692964 7609 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7610 *offset = dist;
7611 return;
7612 }
1b31d05e 7613
4d6ed7c8
NC
7614 *symname = NULL;
7615 *offset = addr.offset;
7616}
7617
32ec8896 7618static /* signed */ int
948f632f
DA
7619symcmp (const void *p, const void *q)
7620{
7621 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7622 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7623
7624 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7625}
7626
7627/* Process the unwind section. */
7628
7629#include "unwind-ia64.h"
7630
7631struct ia64_unw_table_entry
7632{
7633 struct absaddr start;
7634 struct absaddr end;
7635 struct absaddr info;
7636};
7637
7638struct ia64_unw_aux_info
7639{
32ec8896
NC
7640 struct ia64_unw_table_entry * table; /* Unwind table. */
7641 unsigned long table_len; /* Length of unwind table. */
7642 unsigned char * info; /* Unwind info. */
7643 unsigned long info_size; /* Size of unwind info. */
7644 bfd_vma info_addr; /* Starting address of unwind info. */
7645 bfd_vma seg_base; /* Starting address of segment. */
7646 Elf_Internal_Sym * symtab; /* The symbol table. */
7647 unsigned long nsyms; /* Number of symbols. */
7648 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7649 unsigned long nfuns; /* Number of entries in funtab. */
7650 char * strtab; /* The string table. */
7651 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7652};
7653
32ec8896 7654static bfd_boolean
dda8d76d 7655dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7656{
2cf0635d 7657 struct ia64_unw_table_entry * tp;
948f632f 7658 unsigned long j, nfuns;
4d6ed7c8 7659 int in_body;
32ec8896 7660 bfd_boolean res = TRUE;
7036c0e1 7661
948f632f
DA
7662 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7663 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7664 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7665 aux->funtab[nfuns++] = aux->symtab[j];
7666 aux->nfuns = nfuns;
7667 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7668
4d6ed7c8
NC
7669 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7670 {
7671 bfd_vma stamp;
7672 bfd_vma offset;
2cf0635d
NC
7673 const unsigned char * dp;
7674 const unsigned char * head;
53774b7e 7675 const unsigned char * end;
2cf0635d 7676 const char * procname;
4d6ed7c8 7677
dda8d76d 7678 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7679 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7680
7681 fputs ("\n<", stdout);
7682
7683 if (procname)
7684 {
7685 fputs (procname, stdout);
7686
7687 if (offset)
7688 printf ("+%lx", (unsigned long) offset);
7689 }
7690
7691 fputs (">: [", stdout);
7692 print_vma (tp->start.offset, PREFIX_HEX);
7693 fputc ('-', stdout);
7694 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7695 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7696 (unsigned long) (tp->info.offset - aux->seg_base));
7697
53774b7e
NC
7698 /* PR 17531: file: 86232b32. */
7699 if (aux->info == NULL)
7700 continue;
7701
97c0a079
AM
7702 offset = tp->info.offset;
7703 if (tp->info.section)
7704 {
7705 if (tp->info.section >= filedata->file_header.e_shnum)
7706 {
7707 warn (_("Invalid section %u in table entry %ld\n"),
7708 tp->info.section, (long) (tp - aux->table));
7709 res = FALSE;
7710 continue;
7711 }
7712 offset += filedata->section_headers[tp->info.section].sh_addr;
7713 }
7714 offset -= aux->info_addr;
53774b7e 7715 /* PR 17531: file: 0997b4d1. */
90679903
AM
7716 if (offset >= aux->info_size
7717 || aux->info_size - offset < 8)
53774b7e
NC
7718 {
7719 warn (_("Invalid offset %lx in table entry %ld\n"),
7720 (long) tp->info.offset, (long) (tp - aux->table));
32ec8896 7721 res = FALSE;
53774b7e
NC
7722 continue;
7723 }
7724
97c0a079 7725 head = aux->info + offset;
a4a00738 7726 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 7727
86f55779 7728 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
7729 (unsigned) UNW_VER (stamp),
7730 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
7731 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
7732 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 7733 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
7734
7735 if (UNW_VER (stamp) != 1)
7736 {
2b692964 7737 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
7738 continue;
7739 }
7740
7741 in_body = 0;
53774b7e
NC
7742 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
7743 /* PR 17531: file: 16ceda89. */
7744 if (end > aux->info + aux->info_size)
7745 end = aux->info + aux->info_size;
7746 for (dp = head + 8; dp < end;)
b4477bc8 7747 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 7748 }
948f632f
DA
7749
7750 free (aux->funtab);
32ec8896
NC
7751
7752 return res;
4d6ed7c8
NC
7753}
7754
53774b7e 7755static bfd_boolean
dda8d76d
NC
7756slurp_ia64_unwind_table (Filedata * filedata,
7757 struct ia64_unw_aux_info * aux,
7758 Elf_Internal_Shdr * sec)
4d6ed7c8 7759{
89fac5e3 7760 unsigned long size, nrelas, i;
2cf0635d
NC
7761 Elf_Internal_Phdr * seg;
7762 struct ia64_unw_table_entry * tep;
7763 Elf_Internal_Shdr * relsec;
7764 Elf_Internal_Rela * rela;
7765 Elf_Internal_Rela * rp;
7766 unsigned char * table;
7767 unsigned char * tp;
7768 Elf_Internal_Sym * sym;
7769 const char * relname;
4d6ed7c8 7770
53774b7e
NC
7771 aux->table_len = 0;
7772
4d6ed7c8
NC
7773 /* First, find the starting address of the segment that includes
7774 this section: */
7775
dda8d76d 7776 if (filedata->file_header.e_phnum)
4d6ed7c8 7777 {
dda8d76d 7778 if (! get_program_headers (filedata))
53774b7e 7779 return FALSE;
4d6ed7c8 7780
dda8d76d
NC
7781 for (seg = filedata->program_headers;
7782 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 7783 ++seg)
4d6ed7c8
NC
7784 {
7785 if (seg->p_type != PT_LOAD)
7786 continue;
7787
7788 if (sec->sh_addr >= seg->p_vaddr
7789 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7790 {
7791 aux->seg_base = seg->p_vaddr;
7792 break;
7793 }
7794 }
4d6ed7c8
NC
7795 }
7796
7797 /* Second, build the unwind table from the contents of the unwind section: */
7798 size = sec->sh_size;
dda8d76d 7799 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7800 _("unwind table"));
a6e9f9df 7801 if (!table)
53774b7e 7802 return FALSE;
4d6ed7c8 7803
53774b7e 7804 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 7805 aux->table = (struct ia64_unw_table_entry *)
53774b7e 7806 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 7807 tep = aux->table;
53774b7e
NC
7808
7809 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
7810 {
7811 tep->start.section = SHN_UNDEF;
7812 tep->end.section = SHN_UNDEF;
7813 tep->info.section = SHN_UNDEF;
c6a0c689
AM
7814 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7815 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7816 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
7817 tep->start.offset += aux->seg_base;
7818 tep->end.offset += aux->seg_base;
7819 tep->info.offset += aux->seg_base;
7820 }
7821 free (table);
7822
41e92641 7823 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
7824 for (relsec = filedata->section_headers;
7825 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
7826 ++relsec)
7827 {
7828 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
7829 || relsec->sh_info >= filedata->file_header.e_shnum
7830 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
7831 continue;
7832
dda8d76d 7833 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 7834 & rela, & nrelas))
53774b7e
NC
7835 {
7836 free (aux->table);
7837 aux->table = NULL;
7838 aux->table_len = 0;
7839 return FALSE;
7840 }
4d6ed7c8
NC
7841
7842 for (rp = rela; rp < rela + nrelas; ++rp)
7843 {
4770fb94 7844 unsigned int sym_ndx;
726bd37d
AM
7845 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
7846 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 7847
82b1b41b
NC
7848 /* PR 17531: file: 9fa67536. */
7849 if (relname == NULL)
7850 {
726bd37d 7851 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
7852 continue;
7853 }
948f632f 7854
0112cd26 7855 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 7856 {
82b1b41b 7857 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
7858 continue;
7859 }
7860
89fac5e3 7861 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 7862
53774b7e
NC
7863 /* PR 17531: file: 5bc8d9bf. */
7864 if (i >= aux->table_len)
7865 {
7866 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
7867 continue;
7868 }
7869
4770fb94
AM
7870 sym_ndx = get_reloc_symindex (rp->r_info);
7871 if (sym_ndx >= aux->nsyms)
7872 {
7873 warn (_("Skipping reloc with invalid symbol index: %u\n"),
7874 sym_ndx);
7875 continue;
7876 }
7877 sym = aux->symtab + sym_ndx;
7878
53774b7e 7879 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
7880 {
7881 case 0:
7882 aux->table[i].start.section = sym->st_shndx;
e466bc6e 7883 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7884 break;
7885 case 1:
7886 aux->table[i].end.section = sym->st_shndx;
e466bc6e 7887 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7888 break;
7889 case 2:
7890 aux->table[i].info.section = sym->st_shndx;
e466bc6e 7891 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7892 break;
7893 default:
7894 break;
7895 }
7896 }
7897
7898 free (rela);
7899 }
7900
53774b7e 7901 return TRUE;
4d6ed7c8
NC
7902}
7903
32ec8896 7904static bfd_boolean
dda8d76d 7905ia64_process_unwind (Filedata * filedata)
4d6ed7c8 7906{
2cf0635d
NC
7907 Elf_Internal_Shdr * sec;
7908 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 7909 unsigned long i, unwcount = 0, unwstart = 0;
57346661 7910 struct ia64_unw_aux_info aux;
32ec8896 7911 bfd_boolean res = TRUE;
f1467e33 7912
4d6ed7c8
NC
7913 memset (& aux, 0, sizeof (aux));
7914
dda8d76d 7915 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 7916 {
28d13567 7917 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 7918 {
28d13567 7919 if (aux.symtab)
4082ef84 7920 {
28d13567
AM
7921 error (_("Multiple symbol tables encountered\n"));
7922 free (aux.symtab);
7923 aux.symtab = NULL;
4082ef84 7924 free (aux.strtab);
28d13567 7925 aux.strtab = NULL;
4082ef84 7926 }
28d13567
AM
7927 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
7928 &aux.strtab, &aux.strtab_size))
7929 return FALSE;
4d6ed7c8
NC
7930 }
7931 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
7932 unwcount++;
7933 }
7934
7935 if (!unwcount)
7936 printf (_("\nThere are no unwind sections in this file.\n"));
7937
7938 while (unwcount-- > 0)
7939 {
2cf0635d 7940 char * suffix;
579f31ac
JJ
7941 size_t len, len2;
7942
dda8d76d
NC
7943 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
7944 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
7945 if (sec->sh_type == SHT_IA_64_UNWIND)
7946 {
7947 unwsec = sec;
7948 break;
7949 }
4082ef84
NC
7950 /* We have already counted the number of SHT_IA64_UNWIND
7951 sections so the loop above should never fail. */
7952 assert (unwsec != NULL);
579f31ac
JJ
7953
7954 unwstart = i + 1;
7955 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
7956
e4b17d5c
L
7957 if ((unwsec->sh_flags & SHF_GROUP) != 0)
7958 {
7959 /* We need to find which section group it is in. */
4082ef84 7960 struct group_list * g;
e4b17d5c 7961
978c4450
AM
7962 if (filedata->section_headers_groups == NULL
7963 || filedata->section_headers_groups[i] == NULL)
dda8d76d 7964 i = filedata->file_header.e_shnum;
4082ef84 7965 else
e4b17d5c 7966 {
978c4450 7967 g = filedata->section_headers_groups[i]->root;
18bd398b 7968
4082ef84
NC
7969 for (; g != NULL; g = g->next)
7970 {
dda8d76d 7971 sec = filedata->section_headers + g->section_index;
e4b17d5c 7972
4082ef84
NC
7973 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
7974 break;
7975 }
7976
7977 if (g == NULL)
dda8d76d 7978 i = filedata->file_header.e_shnum;
4082ef84 7979 }
e4b17d5c 7980 }
18bd398b 7981 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 7982 {
18bd398b 7983 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
7984 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
7985 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 7986 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 7987 ++i, ++sec)
18bd398b
NC
7988 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
7989 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7990 break;
7991 }
7992 else
7993 {
7994 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 7995 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
7996 len = sizeof (ELF_STRING_ia64_unwind) - 1;
7997 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
7998 suffix = "";
18bd398b 7999 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac 8000 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 8001 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 8002 ++i, ++sec)
18bd398b
NC
8003 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
8004 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8005 break;
8006 }
8007
dda8d76d 8008 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8009 {
8010 printf (_("\nCould not find unwind info section for "));
8011
dda8d76d 8012 if (filedata->string_table == NULL)
579f31ac
JJ
8013 printf ("%d", unwsec->sh_name);
8014 else
dda8d76d 8015 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8016 }
8017 else
4d6ed7c8 8018 {
4d6ed7c8 8019 aux.info_addr = sec->sh_addr;
dda8d76d 8020 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8021 sec->sh_size,
8022 _("unwind info"));
59245841 8023 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8024
579f31ac 8025 printf (_("\nUnwind section "));
4d6ed7c8 8026
dda8d76d 8027 if (filedata->string_table == NULL)
579f31ac
JJ
8028 printf ("%d", unwsec->sh_name);
8029 else
dda8d76d 8030 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8031
579f31ac 8032 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8033 (unsigned long) unwsec->sh_offset,
89fac5e3 8034 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8035
dda8d76d 8036 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8037 && aux.table_len > 0)
dda8d76d 8038 dump_ia64_unwind (filedata, & aux);
579f31ac
JJ
8039
8040 if (aux.table)
8041 free ((char *) aux.table);
8042 if (aux.info)
8043 free ((char *) aux.info);
8044 aux.table = NULL;
8045 aux.info = NULL;
8046 }
4d6ed7c8 8047 }
4d6ed7c8 8048
4d6ed7c8
NC
8049 if (aux.symtab)
8050 free (aux.symtab);
8051 if (aux.strtab)
8052 free ((char *) aux.strtab);
32ec8896
NC
8053
8054 return res;
4d6ed7c8
NC
8055}
8056
3f5e193b 8057struct hppa_unw_table_entry
32ec8896
NC
8058{
8059 struct absaddr start;
8060 struct absaddr end;
8061 unsigned int Cannot_unwind:1; /* 0 */
8062 unsigned int Millicode:1; /* 1 */
8063 unsigned int Millicode_save_sr0:1; /* 2 */
8064 unsigned int Region_description:2; /* 3..4 */
8065 unsigned int reserved1:1; /* 5 */
8066 unsigned int Entry_SR:1; /* 6 */
8067 unsigned int Entry_FR:4; /* Number saved 7..10 */
8068 unsigned int Entry_GR:5; /* Number saved 11..15 */
8069 unsigned int Args_stored:1; /* 16 */
8070 unsigned int Variable_Frame:1; /* 17 */
8071 unsigned int Separate_Package_Body:1; /* 18 */
8072 unsigned int Frame_Extension_Millicode:1; /* 19 */
8073 unsigned int Stack_Overflow_Check:1; /* 20 */
8074 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8075 unsigned int Ada_Region:1; /* 22 */
8076 unsigned int cxx_info:1; /* 23 */
8077 unsigned int cxx_try_catch:1; /* 24 */
8078 unsigned int sched_entry_seq:1; /* 25 */
8079 unsigned int reserved2:1; /* 26 */
8080 unsigned int Save_SP:1; /* 27 */
8081 unsigned int Save_RP:1; /* 28 */
8082 unsigned int Save_MRP_in_frame:1; /* 29 */
8083 unsigned int extn_ptr_defined:1; /* 30 */
8084 unsigned int Cleanup_defined:1; /* 31 */
8085
8086 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8087 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8088 unsigned int Large_frame:1; /* 2 */
8089 unsigned int Pseudo_SP_Set:1; /* 3 */
8090 unsigned int reserved4:1; /* 4 */
8091 unsigned int Total_frame_size:27; /* 5..31 */
8092};
3f5e193b 8093
57346661 8094struct hppa_unw_aux_info
948f632f 8095{
32ec8896
NC
8096 struct hppa_unw_table_entry * table; /* Unwind table. */
8097 unsigned long table_len; /* Length of unwind table. */
8098 bfd_vma seg_base; /* Starting address of segment. */
8099 Elf_Internal_Sym * symtab; /* The symbol table. */
8100 unsigned long nsyms; /* Number of symbols. */
8101 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8102 unsigned long nfuns; /* Number of entries in funtab. */
8103 char * strtab; /* The string table. */
8104 unsigned long strtab_size; /* Size of string table. */
948f632f 8105};
57346661 8106
32ec8896 8107static bfd_boolean
dda8d76d 8108dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8109{
2cf0635d 8110 struct hppa_unw_table_entry * tp;
948f632f 8111 unsigned long j, nfuns;
32ec8896 8112 bfd_boolean res = TRUE;
948f632f
DA
8113
8114 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8115 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8116 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8117 aux->funtab[nfuns++] = aux->symtab[j];
8118 aux->nfuns = nfuns;
8119 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8120
57346661
AM
8121 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8122 {
8123 bfd_vma offset;
2cf0635d 8124 const char * procname;
57346661 8125
dda8d76d 8126 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8127 aux->strtab_size, tp->start, &procname,
8128 &offset);
8129
8130 fputs ("\n<", stdout);
8131
8132 if (procname)
8133 {
8134 fputs (procname, stdout);
8135
8136 if (offset)
8137 printf ("+%lx", (unsigned long) offset);
8138 }
8139
8140 fputs (">: [", stdout);
8141 print_vma (tp->start.offset, PREFIX_HEX);
8142 fputc ('-', stdout);
8143 print_vma (tp->end.offset, PREFIX_HEX);
8144 printf ("]\n\t");
8145
18bd398b
NC
8146#define PF(_m) if (tp->_m) printf (#_m " ");
8147#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8148 PF(Cannot_unwind);
8149 PF(Millicode);
8150 PF(Millicode_save_sr0);
18bd398b 8151 /* PV(Region_description); */
57346661
AM
8152 PF(Entry_SR);
8153 PV(Entry_FR);
8154 PV(Entry_GR);
8155 PF(Args_stored);
8156 PF(Variable_Frame);
8157 PF(Separate_Package_Body);
8158 PF(Frame_Extension_Millicode);
8159 PF(Stack_Overflow_Check);
8160 PF(Two_Instruction_SP_Increment);
8161 PF(Ada_Region);
8162 PF(cxx_info);
8163 PF(cxx_try_catch);
8164 PF(sched_entry_seq);
8165 PF(Save_SP);
8166 PF(Save_RP);
8167 PF(Save_MRP_in_frame);
8168 PF(extn_ptr_defined);
8169 PF(Cleanup_defined);
8170 PF(MPE_XL_interrupt_marker);
8171 PF(HP_UX_interrupt_marker);
8172 PF(Large_frame);
8173 PF(Pseudo_SP_Set);
8174 PV(Total_frame_size);
8175#undef PF
8176#undef PV
8177 }
8178
18bd398b 8179 printf ("\n");
948f632f
DA
8180
8181 free (aux->funtab);
32ec8896
NC
8182
8183 return res;
57346661
AM
8184}
8185
32ec8896 8186static bfd_boolean
dda8d76d
NC
8187slurp_hppa_unwind_table (Filedata * filedata,
8188 struct hppa_unw_aux_info * aux,
8189 Elf_Internal_Shdr * sec)
57346661 8190{
1c0751b2 8191 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8192 Elf_Internal_Phdr * seg;
8193 struct hppa_unw_table_entry * tep;
8194 Elf_Internal_Shdr * relsec;
8195 Elf_Internal_Rela * rela;
8196 Elf_Internal_Rela * rp;
8197 unsigned char * table;
8198 unsigned char * tp;
8199 Elf_Internal_Sym * sym;
8200 const char * relname;
57346661 8201
57346661
AM
8202 /* First, find the starting address of the segment that includes
8203 this section. */
dda8d76d 8204 if (filedata->file_header.e_phnum)
57346661 8205 {
dda8d76d 8206 if (! get_program_headers (filedata))
32ec8896 8207 return FALSE;
57346661 8208
dda8d76d
NC
8209 for (seg = filedata->program_headers;
8210 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8211 ++seg)
8212 {
8213 if (seg->p_type != PT_LOAD)
8214 continue;
8215
8216 if (sec->sh_addr >= seg->p_vaddr
8217 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8218 {
8219 aux->seg_base = seg->p_vaddr;
8220 break;
8221 }
8222 }
8223 }
8224
8225 /* Second, build the unwind table from the contents of the unwind
8226 section. */
8227 size = sec->sh_size;
dda8d76d 8228 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8229 _("unwind table"));
57346661 8230 if (!table)
32ec8896 8231 return FALSE;
57346661 8232
1c0751b2
DA
8233 unw_ent_size = 16;
8234 nentries = size / unw_ent_size;
8235 size = unw_ent_size * nentries;
57346661 8236
3f5e193b
NC
8237 tep = aux->table = (struct hppa_unw_table_entry *)
8238 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8239
1c0751b2 8240 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8241 {
8242 unsigned int tmp1, tmp2;
8243
8244 tep->start.section = SHN_UNDEF;
8245 tep->end.section = SHN_UNDEF;
8246
1c0751b2
DA
8247 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8248 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8249 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8250 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8251
8252 tep->start.offset += aux->seg_base;
8253 tep->end.offset += aux->seg_base;
57346661
AM
8254
8255 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8256 tep->Millicode = (tmp1 >> 30) & 0x1;
8257 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8258 tep->Region_description = (tmp1 >> 27) & 0x3;
8259 tep->reserved1 = (tmp1 >> 26) & 0x1;
8260 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8261 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8262 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8263 tep->Args_stored = (tmp1 >> 15) & 0x1;
8264 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8265 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8266 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8267 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8268 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8269 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8270 tep->cxx_info = (tmp1 >> 8) & 0x1;
8271 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8272 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8273 tep->reserved2 = (tmp1 >> 5) & 0x1;
8274 tep->Save_SP = (tmp1 >> 4) & 0x1;
8275 tep->Save_RP = (tmp1 >> 3) & 0x1;
8276 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8277 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8278 tep->Cleanup_defined = tmp1 & 0x1;
8279
8280 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8281 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8282 tep->Large_frame = (tmp2 >> 29) & 0x1;
8283 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8284 tep->reserved4 = (tmp2 >> 27) & 0x1;
8285 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8286 }
8287 free (table);
8288
8289 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8290 for (relsec = filedata->section_headers;
8291 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8292 ++relsec)
8293 {
8294 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8295 || relsec->sh_info >= filedata->file_header.e_shnum
8296 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8297 continue;
8298
dda8d76d 8299 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8300 & rela, & nrelas))
32ec8896 8301 return FALSE;
57346661
AM
8302
8303 for (rp = rela; rp < rela + nrelas; ++rp)
8304 {
4770fb94 8305 unsigned int sym_ndx;
726bd37d
AM
8306 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8307 relname = elf_hppa_reloc_type (r_type);
57346661 8308
726bd37d
AM
8309 if (relname == NULL)
8310 {
8311 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8312 continue;
8313 }
8314
57346661 8315 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 8316 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661 8317 {
726bd37d 8318 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8319 continue;
8320 }
8321
8322 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8323 if (i >= aux->table_len)
8324 {
8325 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8326 continue;
8327 }
57346661 8328
4770fb94
AM
8329 sym_ndx = get_reloc_symindex (rp->r_info);
8330 if (sym_ndx >= aux->nsyms)
8331 {
8332 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8333 sym_ndx);
8334 continue;
8335 }
8336 sym = aux->symtab + sym_ndx;
8337
43f6cd05 8338 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8339 {
8340 case 0:
8341 aux->table[i].start.section = sym->st_shndx;
1e456d54 8342 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8343 break;
8344 case 1:
8345 aux->table[i].end.section = sym->st_shndx;
1e456d54 8346 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8347 break;
8348 default:
8349 break;
8350 }
8351 }
8352
8353 free (rela);
8354 }
8355
1c0751b2 8356 aux->table_len = nentries;
57346661 8357
32ec8896 8358 return TRUE;
57346661
AM
8359}
8360
32ec8896 8361static bfd_boolean
dda8d76d 8362hppa_process_unwind (Filedata * filedata)
57346661 8363{
57346661 8364 struct hppa_unw_aux_info aux;
2cf0635d 8365 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8366 Elf_Internal_Shdr * sec;
18bd398b 8367 unsigned long i;
32ec8896 8368 bfd_boolean res = TRUE;
57346661 8369
dda8d76d 8370 if (filedata->string_table == NULL)
32ec8896 8371 return FALSE;
1b31d05e
NC
8372
8373 memset (& aux, 0, sizeof (aux));
57346661 8374
dda8d76d 8375 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8376 {
28d13567 8377 if (sec->sh_type == SHT_SYMTAB)
57346661 8378 {
28d13567 8379 if (aux.symtab)
4082ef84 8380 {
28d13567
AM
8381 error (_("Multiple symbol tables encountered\n"));
8382 free (aux.symtab);
8383 aux.symtab = NULL;
4082ef84 8384 free (aux.strtab);
28d13567 8385 aux.strtab = NULL;
4082ef84 8386 }
28d13567
AM
8387 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8388 &aux.strtab, &aux.strtab_size))
8389 return FALSE;
57346661 8390 }
18bd398b 8391 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8392 unwsec = sec;
8393 }
8394
8395 if (!unwsec)
8396 printf (_("\nThere are no unwind sections in this file.\n"));
8397
dda8d76d 8398 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8399 {
18bd398b 8400 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8401 {
43f6cd05 8402 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8403
d3a49aa8
AM
8404 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8405 "contains %lu entry:\n",
8406 "\nUnwind section '%s' at offset 0x%lx "
8407 "contains %lu entries:\n",
8408 num_unwind),
dda8d76d 8409 printable_section_name (filedata, sec),
57346661 8410 (unsigned long) sec->sh_offset,
d3a49aa8 8411 num_unwind);
57346661 8412
dda8d76d 8413 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
32ec8896 8414 res = FALSE;
66b09c7e
S
8415
8416 if (res && aux.table_len > 0)
32ec8896 8417 {
dda8d76d 8418 if (! dump_hppa_unwind (filedata, &aux))
32ec8896
NC
8419 res = FALSE;
8420 }
57346661
AM
8421
8422 if (aux.table)
8423 free ((char *) aux.table);
8424 aux.table = NULL;
8425 }
8426 }
8427
8428 if (aux.symtab)
8429 free (aux.symtab);
8430 if (aux.strtab)
8431 free ((char *) aux.strtab);
32ec8896
NC
8432
8433 return res;
57346661
AM
8434}
8435
0b6ae522
DJ
8436struct arm_section
8437{
a734115a
NC
8438 unsigned char * data; /* The unwind data. */
8439 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8440 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8441 unsigned long nrelas; /* The number of relocations. */
8442 unsigned int rel_type; /* REL or RELA ? */
8443 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8444};
8445
8446struct arm_unw_aux_info
8447{
dda8d76d 8448 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8449 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8450 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8451 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8452 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8453 char * strtab; /* The file's string table. */
8454 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8455};
8456
8457static const char *
dda8d76d
NC
8458arm_print_vma_and_name (Filedata * filedata,
8459 struct arm_unw_aux_info * aux,
8460 bfd_vma fn,
8461 struct absaddr addr)
0b6ae522
DJ
8462{
8463 const char *procname;
8464 bfd_vma sym_offset;
8465
8466 if (addr.section == SHN_UNDEF)
8467 addr.offset = fn;
8468
dda8d76d 8469 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8470 aux->strtab_size, addr, &procname,
8471 &sym_offset);
8472
8473 print_vma (fn, PREFIX_HEX);
8474
8475 if (procname)
8476 {
8477 fputs (" <", stdout);
8478 fputs (procname, stdout);
8479
8480 if (sym_offset)
8481 printf ("+0x%lx", (unsigned long) sym_offset);
8482 fputc ('>', stdout);
8483 }
8484
8485 return procname;
8486}
8487
8488static void
8489arm_free_section (struct arm_section *arm_sec)
8490{
8491 if (arm_sec->data != NULL)
8492 free (arm_sec->data);
8493
8494 if (arm_sec->rela != NULL)
8495 free (arm_sec->rela);
8496}
8497
a734115a
NC
8498/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8499 cached section and install SEC instead.
8500 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8501 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8502 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8503 relocation's offset in ADDR.
1b31d05e
NC
8504 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8505 into the string table of the symbol associated with the reloc. If no
8506 reloc was applied store -1 there.
8507 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
8508
8509static bfd_boolean
dda8d76d
NC
8510get_unwind_section_word (Filedata * filedata,
8511 struct arm_unw_aux_info * aux,
1b31d05e
NC
8512 struct arm_section * arm_sec,
8513 Elf_Internal_Shdr * sec,
8514 bfd_vma word_offset,
8515 unsigned int * wordp,
8516 struct absaddr * addr,
8517 bfd_vma * sym_name)
0b6ae522
DJ
8518{
8519 Elf_Internal_Rela *rp;
8520 Elf_Internal_Sym *sym;
8521 const char * relname;
8522 unsigned int word;
8523 bfd_boolean wrapped;
8524
e0a31db1
NC
8525 if (sec == NULL || arm_sec == NULL)
8526 return FALSE;
8527
0b6ae522
DJ
8528 addr->section = SHN_UNDEF;
8529 addr->offset = 0;
8530
1b31d05e
NC
8531 if (sym_name != NULL)
8532 *sym_name = (bfd_vma) -1;
8533
a734115a 8534 /* If necessary, update the section cache. */
0b6ae522
DJ
8535 if (sec != arm_sec->sec)
8536 {
8537 Elf_Internal_Shdr *relsec;
8538
8539 arm_free_section (arm_sec);
8540
8541 arm_sec->sec = sec;
dda8d76d 8542 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8543 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8544 arm_sec->rela = NULL;
8545 arm_sec->nrelas = 0;
8546
dda8d76d
NC
8547 for (relsec = filedata->section_headers;
8548 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8549 ++relsec)
8550 {
dda8d76d
NC
8551 if (relsec->sh_info >= filedata->file_header.e_shnum
8552 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8553 /* PR 15745: Check the section type as well. */
8554 || (relsec->sh_type != SHT_REL
8555 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8556 continue;
8557
a734115a 8558 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8559 if (relsec->sh_type == SHT_REL)
8560 {
dda8d76d 8561 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8562 relsec->sh_size,
8563 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8564 return FALSE;
0b6ae522 8565 }
1ae40aa4 8566 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8567 {
dda8d76d 8568 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8569 relsec->sh_size,
8570 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8571 return FALSE;
0b6ae522 8572 }
1ae40aa4 8573 break;
0b6ae522
DJ
8574 }
8575
8576 arm_sec->next_rela = arm_sec->rela;
8577 }
8578
a734115a 8579 /* If there is no unwind data we can do nothing. */
0b6ae522 8580 if (arm_sec->data == NULL)
a734115a 8581 return FALSE;
0b6ae522 8582
e0a31db1 8583 /* If the offset is invalid then fail. */
f32ba729
NC
8584 if (/* PR 21343 *//* PR 18879 */
8585 sec->sh_size < 4
8586 || word_offset > (sec->sh_size - 4)
1a915552 8587 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
8588 return FALSE;
8589
a734115a 8590 /* Get the word at the required offset. */
0b6ae522
DJ
8591 word = byte_get (arm_sec->data + word_offset, 4);
8592
0eff7165
NC
8593 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8594 if (arm_sec->rela == NULL)
8595 {
8596 * wordp = word;
8597 return TRUE;
8598 }
8599
a734115a 8600 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
8601 wrapped = FALSE;
8602 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8603 {
8604 bfd_vma prelval, offset;
8605
8606 if (rp->r_offset > word_offset && !wrapped)
8607 {
8608 rp = arm_sec->rela;
8609 wrapped = TRUE;
8610 }
8611 if (rp->r_offset > word_offset)
8612 break;
8613
8614 if (rp->r_offset & 3)
8615 {
8616 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8617 (unsigned long) rp->r_offset);
8618 continue;
8619 }
8620
8621 if (rp->r_offset < word_offset)
8622 continue;
8623
74e1a04b
NC
8624 /* PR 17531: file: 027-161405-0.004 */
8625 if (aux->symtab == NULL)
8626 continue;
8627
0b6ae522
DJ
8628 if (arm_sec->rel_type == SHT_REL)
8629 {
8630 offset = word & 0x7fffffff;
8631 if (offset & 0x40000000)
8632 offset |= ~ (bfd_vma) 0x7fffffff;
8633 }
a734115a 8634 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8635 offset = rp->r_addend;
a734115a 8636 else
74e1a04b
NC
8637 {
8638 error (_("Unknown section relocation type %d encountered\n"),
8639 arm_sec->rel_type);
8640 break;
8641 }
0b6ae522 8642
071436c6
NC
8643 /* PR 17531 file: 027-1241568-0.004. */
8644 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8645 {
8646 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8647 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8648 break;
8649 }
8650
8651 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8652 offset += sym->st_value;
8653 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8654
a734115a 8655 /* Check that we are processing the expected reloc type. */
dda8d76d 8656 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8657 {
8658 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8659 if (relname == NULL)
8660 {
8661 warn (_("Skipping unknown ARM relocation type: %d\n"),
8662 (int) ELF32_R_TYPE (rp->r_info));
8663 continue;
8664 }
a734115a
NC
8665
8666 if (streq (relname, "R_ARM_NONE"))
8667 continue;
0b4362b0 8668
a734115a
NC
8669 if (! streq (relname, "R_ARM_PREL31"))
8670 {
071436c6 8671 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8672 continue;
8673 }
8674 }
dda8d76d 8675 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8676 {
8677 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8678 if (relname == NULL)
8679 {
8680 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8681 (int) ELF32_R_TYPE (rp->r_info));
8682 continue;
8683 }
0b4362b0 8684
a734115a
NC
8685 if (streq (relname, "R_C6000_NONE"))
8686 continue;
8687
8688 if (! streq (relname, "R_C6000_PREL31"))
8689 {
071436c6 8690 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8691 continue;
8692 }
8693
8694 prelval >>= 1;
8695 }
8696 else
74e1a04b
NC
8697 {
8698 /* This function currently only supports ARM and TI unwinders. */
8699 warn (_("Only TI and ARM unwinders are currently supported\n"));
8700 break;
8701 }
fa197c1c 8702
0b6ae522
DJ
8703 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
8704 addr->section = sym->st_shndx;
8705 addr->offset = offset;
74e1a04b 8706
1b31d05e
NC
8707 if (sym_name)
8708 * sym_name = sym->st_name;
0b6ae522
DJ
8709 break;
8710 }
8711
8712 *wordp = word;
8713 arm_sec->next_rela = rp;
8714
a734115a 8715 return TRUE;
0b6ae522
DJ
8716}
8717
a734115a
NC
8718static const char *tic6x_unwind_regnames[16] =
8719{
0b4362b0
RM
8720 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
8721 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
8722 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
8723};
fa197c1c 8724
0b6ae522 8725static void
fa197c1c 8726decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 8727{
fa197c1c
PB
8728 int i;
8729
8730 for (i = 12; mask; mask >>= 1, i--)
8731 {
8732 if (mask & 1)
8733 {
8734 fputs (tic6x_unwind_regnames[i], stdout);
8735 if (mask > 1)
8736 fputs (", ", stdout);
8737 }
8738 }
8739}
0b6ae522
DJ
8740
8741#define ADVANCE \
8742 if (remaining == 0 && more_words) \
8743 { \
8744 data_offset += 4; \
dda8d76d 8745 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 8746 data_offset, & word, & addr, NULL)) \
32ec8896 8747 return FALSE; \
0b6ae522
DJ
8748 remaining = 4; \
8749 more_words--; \
8750 } \
8751
8752#define GET_OP(OP) \
8753 ADVANCE; \
8754 if (remaining) \
8755 { \
8756 remaining--; \
8757 (OP) = word >> 24; \
8758 word <<= 8; \
8759 } \
8760 else \
8761 { \
2b692964 8762 printf (_("[Truncated opcode]\n")); \
32ec8896 8763 return FALSE; \
0b6ae522 8764 } \
cc5914eb 8765 printf ("0x%02x ", OP)
0b6ae522 8766
32ec8896 8767static bfd_boolean
dda8d76d
NC
8768decode_arm_unwind_bytecode (Filedata * filedata,
8769 struct arm_unw_aux_info * aux,
948f632f
DA
8770 unsigned int word,
8771 unsigned int remaining,
8772 unsigned int more_words,
8773 bfd_vma data_offset,
8774 Elf_Internal_Shdr * data_sec,
8775 struct arm_section * data_arm_sec)
fa197c1c
PB
8776{
8777 struct absaddr addr;
32ec8896 8778 bfd_boolean res = TRUE;
0b6ae522
DJ
8779
8780 /* Decode the unwinding instructions. */
8781 while (1)
8782 {
8783 unsigned int op, op2;
8784
8785 ADVANCE;
8786 if (remaining == 0)
8787 break;
8788 remaining--;
8789 op = word >> 24;
8790 word <<= 8;
8791
cc5914eb 8792 printf (" 0x%02x ", op);
0b6ae522
DJ
8793
8794 if ((op & 0xc0) == 0x00)
8795 {
8796 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8797
cc5914eb 8798 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
8799 }
8800 else if ((op & 0xc0) == 0x40)
8801 {
8802 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8803
cc5914eb 8804 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
8805 }
8806 else if ((op & 0xf0) == 0x80)
8807 {
8808 GET_OP (op2);
8809 if (op == 0x80 && op2 == 0)
8810 printf (_("Refuse to unwind"));
8811 else
8812 {
8813 unsigned int mask = ((op & 0x0f) << 8) | op2;
32ec8896 8814 bfd_boolean first = TRUE;
0b6ae522 8815 int i;
2b692964 8816
0b6ae522
DJ
8817 printf ("pop {");
8818 for (i = 0; i < 12; i++)
8819 if (mask & (1 << i))
8820 {
8821 if (first)
32ec8896 8822 first = FALSE;
0b6ae522
DJ
8823 else
8824 printf (", ");
8825 printf ("r%d", 4 + i);
8826 }
8827 printf ("}");
8828 }
8829 }
8830 else if ((op & 0xf0) == 0x90)
8831 {
8832 if (op == 0x9d || op == 0x9f)
8833 printf (_(" [Reserved]"));
8834 else
cc5914eb 8835 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
8836 }
8837 else if ((op & 0xf0) == 0xa0)
8838 {
8839 int end = 4 + (op & 0x07);
32ec8896 8840 bfd_boolean first = TRUE;
0b6ae522 8841 int i;
61865e30 8842
0b6ae522
DJ
8843 printf (" pop {");
8844 for (i = 4; i <= end; i++)
8845 {
8846 if (first)
32ec8896 8847 first = FALSE;
0b6ae522
DJ
8848 else
8849 printf (", ");
8850 printf ("r%d", i);
8851 }
8852 if (op & 0x08)
8853 {
1b31d05e 8854 if (!first)
0b6ae522
DJ
8855 printf (", ");
8856 printf ("r14");
8857 }
8858 printf ("}");
8859 }
8860 else if (op == 0xb0)
8861 printf (_(" finish"));
8862 else if (op == 0xb1)
8863 {
8864 GET_OP (op2);
8865 if (op2 == 0 || (op2 & 0xf0) != 0)
8866 printf (_("[Spare]"));
8867 else
8868 {
8869 unsigned int mask = op2 & 0x0f;
32ec8896 8870 bfd_boolean first = TRUE;
0b6ae522 8871 int i;
61865e30 8872
0b6ae522
DJ
8873 printf ("pop {");
8874 for (i = 0; i < 12; i++)
8875 if (mask & (1 << i))
8876 {
8877 if (first)
32ec8896 8878 first = FALSE;
0b6ae522
DJ
8879 else
8880 printf (", ");
8881 printf ("r%d", i);
8882 }
8883 printf ("}");
8884 }
8885 }
8886 else if (op == 0xb2)
8887 {
b115cf96 8888 unsigned char buf[9];
0b6ae522
DJ
8889 unsigned int i, len;
8890 unsigned long offset;
61865e30 8891
b115cf96 8892 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
8893 {
8894 GET_OP (buf[i]);
8895 if ((buf[i] & 0x80) == 0)
8896 break;
8897 }
4082ef84 8898 if (i == sizeof (buf))
32ec8896 8899 {
27a45f42 8900 error (_("corrupt change to vsp\n"));
32ec8896
NC
8901 res = FALSE;
8902 }
4082ef84
NC
8903 else
8904 {
cd30bcef 8905 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
4082ef84
NC
8906 assert (len == i + 1);
8907 offset = offset * 4 + 0x204;
8908 printf ("vsp = vsp + %ld", offset);
8909 }
0b6ae522 8910 }
61865e30 8911 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 8912 {
61865e30
NC
8913 unsigned int first, last;
8914
8915 GET_OP (op2);
8916 first = op2 >> 4;
8917 last = op2 & 0x0f;
8918 if (op == 0xc8)
8919 first = first + 16;
8920 printf ("pop {D%d", first);
8921 if (last)
8922 printf ("-D%d", first + last);
8923 printf ("}");
8924 }
8925 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
8926 {
8927 unsigned int count = op & 0x07;
8928
8929 printf ("pop {D8");
8930 if (count)
8931 printf ("-D%d", 8 + count);
8932 printf ("}");
8933 }
8934 else if (op >= 0xc0 && op <= 0xc5)
8935 {
8936 unsigned int count = op & 0x07;
8937
8938 printf (" pop {wR10");
8939 if (count)
8940 printf ("-wR%d", 10 + count);
8941 printf ("}");
8942 }
8943 else if (op == 0xc6)
8944 {
8945 unsigned int first, last;
8946
8947 GET_OP (op2);
8948 first = op2 >> 4;
8949 last = op2 & 0x0f;
8950 printf ("pop {wR%d", first);
8951 if (last)
8952 printf ("-wR%d", first + last);
8953 printf ("}");
8954 }
8955 else if (op == 0xc7)
8956 {
8957 GET_OP (op2);
8958 if (op2 == 0 || (op2 & 0xf0) != 0)
8959 printf (_("[Spare]"));
0b6ae522
DJ
8960 else
8961 {
61865e30 8962 unsigned int mask = op2 & 0x0f;
32ec8896 8963 bfd_boolean first = TRUE;
61865e30
NC
8964 int i;
8965
8966 printf ("pop {");
8967 for (i = 0; i < 4; i++)
8968 if (mask & (1 << i))
8969 {
8970 if (first)
32ec8896 8971 first = FALSE;
61865e30
NC
8972 else
8973 printf (", ");
8974 printf ("wCGR%d", i);
8975 }
8976 printf ("}");
0b6ae522
DJ
8977 }
8978 }
61865e30 8979 else
32ec8896
NC
8980 {
8981 printf (_(" [unsupported opcode]"));
8982 res = FALSE;
8983 }
8984
0b6ae522
DJ
8985 printf ("\n");
8986 }
32ec8896
NC
8987
8988 return res;
fa197c1c
PB
8989}
8990
32ec8896 8991static bfd_boolean
dda8d76d
NC
8992decode_tic6x_unwind_bytecode (Filedata * filedata,
8993 struct arm_unw_aux_info * aux,
948f632f
DA
8994 unsigned int word,
8995 unsigned int remaining,
8996 unsigned int more_words,
8997 bfd_vma data_offset,
8998 Elf_Internal_Shdr * data_sec,
8999 struct arm_section * data_arm_sec)
fa197c1c
PB
9000{
9001 struct absaddr addr;
9002
9003 /* Decode the unwinding instructions. */
9004 while (1)
9005 {
9006 unsigned int op, op2;
9007
9008 ADVANCE;
9009 if (remaining == 0)
9010 break;
9011 remaining--;
9012 op = word >> 24;
9013 word <<= 8;
9014
9cf03b7e 9015 printf (" 0x%02x ", op);
fa197c1c
PB
9016
9017 if ((op & 0xc0) == 0x00)
9018 {
9019 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9020 printf (" sp = sp + %d", offset);
fa197c1c
PB
9021 }
9022 else if ((op & 0xc0) == 0x80)
9023 {
9024 GET_OP (op2);
9025 if (op == 0x80 && op2 == 0)
9026 printf (_("Refuse to unwind"));
9027 else
9028 {
9029 unsigned int mask = ((op & 0x1f) << 8) | op2;
9030 if (op & 0x20)
9031 printf ("pop compact {");
9032 else
9033 printf ("pop {");
9034
9035 decode_tic6x_unwind_regmask (mask);
9036 printf("}");
9037 }
9038 }
9039 else if ((op & 0xf0) == 0xc0)
9040 {
9041 unsigned int reg;
9042 unsigned int nregs;
9043 unsigned int i;
9044 const char *name;
a734115a
NC
9045 struct
9046 {
32ec8896
NC
9047 unsigned int offset;
9048 unsigned int reg;
fa197c1c
PB
9049 } regpos[16];
9050
9051 /* Scan entire instruction first so that GET_OP output is not
9052 interleaved with disassembly. */
9053 nregs = 0;
9054 for (i = 0; nregs < (op & 0xf); i++)
9055 {
9056 GET_OP (op2);
9057 reg = op2 >> 4;
9058 if (reg != 0xf)
9059 {
9060 regpos[nregs].offset = i * 2;
9061 regpos[nregs].reg = reg;
9062 nregs++;
9063 }
9064
9065 reg = op2 & 0xf;
9066 if (reg != 0xf)
9067 {
9068 regpos[nregs].offset = i * 2 + 1;
9069 regpos[nregs].reg = reg;
9070 nregs++;
9071 }
9072 }
9073
9074 printf (_("pop frame {"));
18344509 9075 if (nregs == 0)
fa197c1c 9076 {
18344509
NC
9077 printf (_("*corrupt* - no registers specified"));
9078 }
9079 else
9080 {
9081 reg = nregs - 1;
9082 for (i = i * 2; i > 0; i--)
fa197c1c 9083 {
18344509
NC
9084 if (regpos[reg].offset == i - 1)
9085 {
9086 name = tic6x_unwind_regnames[regpos[reg].reg];
9087 if (reg > 0)
9088 reg--;
9089 }
9090 else
9091 name = _("[pad]");
fa197c1c 9092
18344509
NC
9093 fputs (name, stdout);
9094 if (i > 1)
9095 printf (", ");
9096 }
fa197c1c
PB
9097 }
9098
9099 printf ("}");
9100 }
9101 else if (op == 0xd0)
9102 printf (" MOV FP, SP");
9103 else if (op == 0xd1)
9104 printf (" __c6xabi_pop_rts");
9105 else if (op == 0xd2)
9106 {
9107 unsigned char buf[9];
9108 unsigned int i, len;
9109 unsigned long offset;
a734115a 9110
fa197c1c
PB
9111 for (i = 0; i < sizeof (buf); i++)
9112 {
9113 GET_OP (buf[i]);
9114 if ((buf[i] & 0x80) == 0)
9115 break;
9116 }
0eff7165
NC
9117 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9118 if (i == sizeof (buf))
9119 {
0eff7165 9120 warn (_("Corrupt stack pointer adjustment detected\n"));
32ec8896 9121 return FALSE;
0eff7165 9122 }
948f632f 9123
cd30bcef 9124 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
fa197c1c
PB
9125 assert (len == i + 1);
9126 offset = offset * 8 + 0x408;
9127 printf (_("sp = sp + %ld"), offset);
9128 }
9129 else if ((op & 0xf0) == 0xe0)
9130 {
9131 if ((op & 0x0f) == 7)
9132 printf (" RETURN");
9133 else
9134 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9135 }
9136 else
9137 {
9138 printf (_(" [unsupported opcode]"));
9139 }
9140 putchar ('\n');
9141 }
32ec8896
NC
9142
9143 return TRUE;
fa197c1c
PB
9144}
9145
9146static bfd_vma
dda8d76d 9147arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9148{
9149 bfd_vma offset;
9150
9151 offset = word & 0x7fffffff;
9152 if (offset & 0x40000000)
9153 offset |= ~ (bfd_vma) 0x7fffffff;
9154
dda8d76d 9155 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9156 offset <<= 1;
9157
9158 return offset + where;
9159}
9160
32ec8896 9161static bfd_boolean
dda8d76d
NC
9162decode_arm_unwind (Filedata * filedata,
9163 struct arm_unw_aux_info * aux,
1b31d05e
NC
9164 unsigned int word,
9165 unsigned int remaining,
9166 bfd_vma data_offset,
9167 Elf_Internal_Shdr * data_sec,
9168 struct arm_section * data_arm_sec)
fa197c1c
PB
9169{
9170 int per_index;
9171 unsigned int more_words = 0;
37e14bc3 9172 struct absaddr addr;
1b31d05e 9173 bfd_vma sym_name = (bfd_vma) -1;
97953bab 9174 bfd_boolean res = TRUE;
fa197c1c
PB
9175
9176 if (remaining == 0)
9177 {
1b31d05e
NC
9178 /* Fetch the first word.
9179 Note - when decoding an object file the address extracted
9180 here will always be 0. So we also pass in the sym_name
9181 parameter so that we can find the symbol associated with
9182 the personality routine. */
dda8d76d 9183 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9184 & word, & addr, & sym_name))
32ec8896 9185 return FALSE;
1b31d05e 9186
fa197c1c
PB
9187 remaining = 4;
9188 }
c93dbb25
CZ
9189 else
9190 {
9191 addr.section = SHN_UNDEF;
9192 addr.offset = 0;
9193 }
fa197c1c
PB
9194
9195 if ((word & 0x80000000) == 0)
9196 {
9197 /* Expand prel31 for personality routine. */
9198 bfd_vma fn;
9199 const char *procname;
9200
dda8d76d 9201 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9202 printf (_(" Personality routine: "));
1b31d05e
NC
9203 if (fn == 0
9204 && addr.section == SHN_UNDEF && addr.offset == 0
9205 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9206 {
9207 procname = aux->strtab + sym_name;
9208 print_vma (fn, PREFIX_HEX);
9209 if (procname)
9210 {
9211 fputs (" <", stdout);
9212 fputs (procname, stdout);
9213 fputc ('>', stdout);
9214 }
9215 }
9216 else
dda8d76d 9217 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9218 fputc ('\n', stdout);
9219
9220 /* The GCC personality routines use the standard compact
9221 encoding, starting with one byte giving the number of
9222 words. */
9223 if (procname != NULL
9224 && (const_strneq (procname, "__gcc_personality_v0")
9225 || const_strneq (procname, "__gxx_personality_v0")
9226 || const_strneq (procname, "__gcj_personality_v0")
9227 || const_strneq (procname, "__gnu_objc_personality_v0")))
9228 {
9229 remaining = 0;
9230 more_words = 1;
9231 ADVANCE;
9232 if (!remaining)
9233 {
9234 printf (_(" [Truncated data]\n"));
32ec8896 9235 return FALSE;
fa197c1c
PB
9236 }
9237 more_words = word >> 24;
9238 word <<= 8;
9239 remaining--;
9240 per_index = -1;
9241 }
9242 else
32ec8896 9243 return TRUE;
fa197c1c
PB
9244 }
9245 else
9246 {
1b31d05e 9247 /* ARM EHABI Section 6.3:
0b4362b0 9248
1b31d05e 9249 An exception-handling table entry for the compact model looks like:
0b4362b0 9250
1b31d05e
NC
9251 31 30-28 27-24 23-0
9252 -- ----- ----- ----
9253 1 0 index Data for personalityRoutine[index] */
9254
dda8d76d 9255 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9256 && (word & 0x70000000))
32ec8896
NC
9257 {
9258 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
9259 res = FALSE;
9260 }
1b31d05e 9261
fa197c1c 9262 per_index = (word >> 24) & 0x7f;
1b31d05e 9263 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9264 if (per_index == 0)
9265 {
9266 more_words = 0;
9267 word <<= 8;
9268 remaining--;
9269 }
9270 else if (per_index < 3)
9271 {
9272 more_words = (word >> 16) & 0xff;
9273 word <<= 16;
9274 remaining -= 2;
9275 }
9276 }
9277
dda8d76d 9278 switch (filedata->file_header.e_machine)
fa197c1c
PB
9279 {
9280 case EM_ARM:
9281 if (per_index < 3)
9282 {
dda8d76d 9283 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9284 data_offset, data_sec, data_arm_sec))
9285 res = FALSE;
fa197c1c
PB
9286 }
9287 else
1b31d05e
NC
9288 {
9289 warn (_("Unknown ARM compact model index encountered\n"));
9290 printf (_(" [reserved]\n"));
32ec8896 9291 res = FALSE;
1b31d05e 9292 }
fa197c1c
PB
9293 break;
9294
9295 case EM_TI_C6000:
9296 if (per_index < 3)
9297 {
dda8d76d 9298 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9299 data_offset, data_sec, data_arm_sec))
9300 res = FALSE;
fa197c1c
PB
9301 }
9302 else if (per_index < 5)
9303 {
9304 if (((word >> 17) & 0x7f) == 0x7f)
9305 printf (_(" Restore stack from frame pointer\n"));
9306 else
9307 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9308 printf (_(" Registers restored: "));
9309 if (per_index == 4)
9310 printf (" (compact) ");
9311 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9312 putchar ('\n');
9313 printf (_(" Return register: %s\n"),
9314 tic6x_unwind_regnames[word & 0xf]);
9315 }
9316 else
1b31d05e 9317 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9318 break;
9319
9320 default:
74e1a04b 9321 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9322 filedata->file_header.e_machine);
32ec8896 9323 res = FALSE;
fa197c1c 9324 }
0b6ae522
DJ
9325
9326 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9327
9328 return res;
0b6ae522
DJ
9329}
9330
32ec8896 9331static bfd_boolean
dda8d76d
NC
9332dump_arm_unwind (Filedata * filedata,
9333 struct arm_unw_aux_info * aux,
9334 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9335{
9336 struct arm_section exidx_arm_sec, extab_arm_sec;
9337 unsigned int i, exidx_len;
948f632f 9338 unsigned long j, nfuns;
32ec8896 9339 bfd_boolean res = TRUE;
0b6ae522
DJ
9340
9341 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9342 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9343 exidx_len = exidx_sec->sh_size / 8;
9344
948f632f
DA
9345 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9346 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9347 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9348 aux->funtab[nfuns++] = aux->symtab[j];
9349 aux->nfuns = nfuns;
9350 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9351
0b6ae522
DJ
9352 for (i = 0; i < exidx_len; i++)
9353 {
9354 unsigned int exidx_fn, exidx_entry;
9355 struct absaddr fn_addr, entry_addr;
9356 bfd_vma fn;
9357
9358 fputc ('\n', stdout);
9359
dda8d76d 9360 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9361 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9362 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9363 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9364 {
948f632f 9365 free (aux->funtab);
1b31d05e
NC
9366 arm_free_section (& exidx_arm_sec);
9367 arm_free_section (& extab_arm_sec);
32ec8896 9368 return FALSE;
0b6ae522
DJ
9369 }
9370
83c257ca
NC
9371 /* ARM EHABI, Section 5:
9372 An index table entry consists of 2 words.
9373 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9374 if (exidx_fn & 0x80000000)
32ec8896
NC
9375 {
9376 warn (_("corrupt index table entry: %x\n"), exidx_fn);
9377 res = FALSE;
9378 }
83c257ca 9379
dda8d76d 9380 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9381
dda8d76d 9382 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9383 fputs (": ", stdout);
9384
9385 if (exidx_entry == 1)
9386 {
9387 print_vma (exidx_entry, PREFIX_HEX);
9388 fputs (" [cantunwind]\n", stdout);
9389 }
9390 else if (exidx_entry & 0x80000000)
9391 {
9392 print_vma (exidx_entry, PREFIX_HEX);
9393 fputc ('\n', stdout);
dda8d76d 9394 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9395 }
9396 else
9397 {
8f73510c 9398 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9399 Elf_Internal_Shdr *table_sec;
9400
9401 fputs ("@", stdout);
dda8d76d 9402 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9403 print_vma (table, PREFIX_HEX);
9404 printf ("\n");
9405
9406 /* Locate the matching .ARM.extab. */
9407 if (entry_addr.section != SHN_UNDEF
dda8d76d 9408 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9409 {
dda8d76d 9410 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9411 table_offset = entry_addr.offset;
1a915552
NC
9412 /* PR 18879 */
9413 if (table_offset > table_sec->sh_size
9414 || ((bfd_signed_vma) table_offset) < 0)
9415 {
9416 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9417 (unsigned long) table_offset,
dda8d76d 9418 printable_section_name (filedata, table_sec));
32ec8896 9419 res = FALSE;
1a915552
NC
9420 continue;
9421 }
0b6ae522
DJ
9422 }
9423 else
9424 {
dda8d76d 9425 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9426 if (table_sec != NULL)
9427 table_offset = table - table_sec->sh_addr;
9428 }
32ec8896 9429
0b6ae522
DJ
9430 if (table_sec == NULL)
9431 {
9432 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9433 (unsigned long) table);
32ec8896 9434 res = FALSE;
0b6ae522
DJ
9435 continue;
9436 }
32ec8896 9437
dda8d76d 9438 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896
NC
9439 &extab_arm_sec))
9440 res = FALSE;
0b6ae522
DJ
9441 }
9442 }
9443
9444 printf ("\n");
9445
948f632f 9446 free (aux->funtab);
0b6ae522
DJ
9447 arm_free_section (&exidx_arm_sec);
9448 arm_free_section (&extab_arm_sec);
32ec8896
NC
9449
9450 return res;
0b6ae522
DJ
9451}
9452
fa197c1c 9453/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9454
32ec8896 9455static bfd_boolean
dda8d76d 9456arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9457{
9458 struct arm_unw_aux_info aux;
9459 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9460 Elf_Internal_Shdr *sec;
9461 unsigned long i;
fa197c1c 9462 unsigned int sec_type;
32ec8896 9463 bfd_boolean res = TRUE;
0b6ae522 9464
dda8d76d 9465 switch (filedata->file_header.e_machine)
fa197c1c
PB
9466 {
9467 case EM_ARM:
9468 sec_type = SHT_ARM_EXIDX;
9469 break;
9470
9471 case EM_TI_C6000:
9472 sec_type = SHT_C6000_UNWIND;
9473 break;
9474
0b4362b0 9475 default:
74e1a04b 9476 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9477 filedata->file_header.e_machine);
32ec8896 9478 return FALSE;
fa197c1c
PB
9479 }
9480
dda8d76d 9481 if (filedata->string_table == NULL)
32ec8896 9482 return FALSE;
1b31d05e
NC
9483
9484 memset (& aux, 0, sizeof (aux));
dda8d76d 9485 aux.filedata = filedata;
0b6ae522 9486
dda8d76d 9487 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9488 {
28d13567 9489 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9490 {
28d13567 9491 if (aux.symtab)
74e1a04b 9492 {
28d13567
AM
9493 error (_("Multiple symbol tables encountered\n"));
9494 free (aux.symtab);
9495 aux.symtab = NULL;
74e1a04b 9496 free (aux.strtab);
28d13567 9497 aux.strtab = NULL;
74e1a04b 9498 }
28d13567
AM
9499 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9500 &aux.strtab, &aux.strtab_size))
9501 return FALSE;
0b6ae522 9502 }
fa197c1c 9503 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9504 unwsec = sec;
9505 }
9506
1b31d05e 9507 if (unwsec == NULL)
0b6ae522 9508 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9509 else
dda8d76d 9510 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9511 {
9512 if (sec->sh_type == sec_type)
9513 {
d3a49aa8
AM
9514 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9515 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9516 "contains %lu entry:\n",
9517 "\nUnwind section '%s' at offset 0x%lx "
9518 "contains %lu entries:\n",
9519 num_unwind),
dda8d76d 9520 printable_section_name (filedata, sec),
1b31d05e 9521 (unsigned long) sec->sh_offset,
d3a49aa8 9522 num_unwind);
0b6ae522 9523
dda8d76d 9524 if (! dump_arm_unwind (filedata, &aux, sec))
32ec8896 9525 res = FALSE;
1b31d05e
NC
9526 }
9527 }
0b6ae522
DJ
9528
9529 if (aux.symtab)
9530 free (aux.symtab);
9531 if (aux.strtab)
9532 free ((char *) aux.strtab);
32ec8896
NC
9533
9534 return res;
0b6ae522
DJ
9535}
9536
32ec8896 9537static bfd_boolean
dda8d76d 9538process_unwind (Filedata * filedata)
57346661 9539{
2cf0635d
NC
9540 struct unwind_handler
9541 {
32ec8896 9542 unsigned int machtype;
dda8d76d 9543 bfd_boolean (* handler)(Filedata *);
2cf0635d
NC
9544 } handlers[] =
9545 {
0b6ae522 9546 { EM_ARM, arm_process_unwind },
57346661
AM
9547 { EM_IA_64, ia64_process_unwind },
9548 { EM_PARISC, hppa_process_unwind },
fa197c1c 9549 { EM_TI_C6000, arm_process_unwind },
32ec8896 9550 { 0, NULL }
57346661
AM
9551 };
9552 int i;
9553
9554 if (!do_unwind)
32ec8896 9555 return TRUE;
57346661
AM
9556
9557 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9558 if (filedata->file_header.e_machine == handlers[i].machtype)
9559 return handlers[i].handler (filedata);
57346661 9560
1b31d05e 9561 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9562 get_machine_name (filedata->file_header.e_machine));
32ec8896 9563 return TRUE;
57346661
AM
9564}
9565
37c18eed
SD
9566static void
9567dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
9568{
9569 switch (entry->d_tag)
9570 {
9571 case DT_AARCH64_BTI_PLT:
1dbade74 9572 case DT_AARCH64_PAC_PLT:
37c18eed
SD
9573 break;
9574 default:
9575 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9576 break;
9577 }
9578 putchar ('\n');
9579}
9580
252b5132 9581static void
978c4450 9582dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
9583{
9584 switch (entry->d_tag)
9585 {
9586 case DT_MIPS_FLAGS:
9587 if (entry->d_un.d_val == 0)
4b68bca3 9588 printf (_("NONE"));
252b5132
RH
9589 else
9590 {
9591 static const char * opts[] =
9592 {
9593 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9594 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9595 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9596 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9597 "RLD_ORDER_SAFE"
9598 };
9599 unsigned int cnt;
32ec8896 9600 bfd_boolean first = TRUE;
2b692964 9601
60bca95a 9602 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9603 if (entry->d_un.d_val & (1 << cnt))
9604 {
9605 printf ("%s%s", first ? "" : " ", opts[cnt]);
32ec8896 9606 first = FALSE;
252b5132 9607 }
252b5132
RH
9608 }
9609 break;
103f02d3 9610
252b5132 9611 case DT_MIPS_IVERSION:
978c4450
AM
9612 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
9613 printf (_("Interface Version: %s"),
9614 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 9615 else
76ca31c0
NC
9616 {
9617 char buf[40];
9618 sprintf_vma (buf, entry->d_un.d_ptr);
9619 /* Note: coded this way so that there is a single string for translation. */
9620 printf (_("<corrupt: %s>"), buf);
9621 }
252b5132 9622 break;
103f02d3 9623
252b5132
RH
9624 case DT_MIPS_TIME_STAMP:
9625 {
d5b07ef4 9626 char timebuf[128];
2cf0635d 9627 struct tm * tmp;
91d6fa6a 9628 time_t atime = entry->d_un.d_val;
82b1b41b 9629
91d6fa6a 9630 tmp = gmtime (&atime);
82b1b41b
NC
9631 /* PR 17531: file: 6accc532. */
9632 if (tmp == NULL)
9633 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9634 else
9635 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9636 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9637 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9638 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9639 }
9640 break;
103f02d3 9641
252b5132
RH
9642 case DT_MIPS_RLD_VERSION:
9643 case DT_MIPS_LOCAL_GOTNO:
9644 case DT_MIPS_CONFLICTNO:
9645 case DT_MIPS_LIBLISTNO:
9646 case DT_MIPS_SYMTABNO:
9647 case DT_MIPS_UNREFEXTNO:
9648 case DT_MIPS_HIPAGENO:
9649 case DT_MIPS_DELTA_CLASS_NO:
9650 case DT_MIPS_DELTA_INSTANCE_NO:
9651 case DT_MIPS_DELTA_RELOC_NO:
9652 case DT_MIPS_DELTA_SYM_NO:
9653 case DT_MIPS_DELTA_CLASSSYM_NO:
9654 case DT_MIPS_COMPACT_SIZE:
c69075ac 9655 print_vma (entry->d_un.d_val, DEC);
252b5132 9656 break;
103f02d3 9657
f16a9783 9658 case DT_MIPS_XHASH:
978c4450
AM
9659 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
9660 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
9661 /* Falls through. */
9662
103f02d3 9663 default:
4b68bca3 9664 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9665 }
4b68bca3 9666 putchar ('\n');
103f02d3
UD
9667}
9668
103f02d3 9669static void
2cf0635d 9670dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9671{
9672 switch (entry->d_tag)
9673 {
9674 case DT_HP_DLD_FLAGS:
9675 {
9676 static struct
9677 {
9678 long int bit;
2cf0635d 9679 const char * str;
5e220199
NC
9680 }
9681 flags[] =
9682 {
9683 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9684 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9685 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9686 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9687 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9688 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9689 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9690 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9691 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9692 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9693 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9694 { DT_HP_GST, "HP_GST" },
9695 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
9696 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
9697 { DT_HP_NODELETE, "HP_NODELETE" },
9698 { DT_HP_GROUP, "HP_GROUP" },
9699 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 9700 };
32ec8896 9701 bfd_boolean first = TRUE;
5e220199 9702 size_t cnt;
f7a99963 9703 bfd_vma val = entry->d_un.d_val;
103f02d3 9704
60bca95a 9705 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 9706 if (val & flags[cnt].bit)
30800947
NC
9707 {
9708 if (! first)
9709 putchar (' ');
9710 fputs (flags[cnt].str, stdout);
32ec8896 9711 first = FALSE;
30800947
NC
9712 val ^= flags[cnt].bit;
9713 }
76da6bbe 9714
103f02d3 9715 if (val != 0 || first)
f7a99963
NC
9716 {
9717 if (! first)
9718 putchar (' ');
9719 print_vma (val, HEX);
9720 }
103f02d3
UD
9721 }
9722 break;
76da6bbe 9723
252b5132 9724 default:
f7a99963
NC
9725 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9726 break;
252b5132 9727 }
35b1837e 9728 putchar ('\n');
252b5132
RH
9729}
9730
28f997cf
TG
9731#ifdef BFD64
9732
9733/* VMS vs Unix time offset and factor. */
9734
9735#define VMS_EPOCH_OFFSET 35067168000000000LL
9736#define VMS_GRANULARITY_FACTOR 10000000
9737
9738/* Display a VMS time in a human readable format. */
9739
9740static void
9741print_vms_time (bfd_int64_t vmstime)
9742{
9743 struct tm *tm;
9744 time_t unxtime;
9745
9746 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
9747 tm = gmtime (&unxtime);
9748 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
9749 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
9750 tm->tm_hour, tm->tm_min, tm->tm_sec);
9751}
9752#endif /* BFD64 */
9753
ecc51f48 9754static void
2cf0635d 9755dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
9756{
9757 switch (entry->d_tag)
9758 {
0de14b54 9759 case DT_IA_64_PLT_RESERVE:
bdf4d63a 9760 /* First 3 slots reserved. */
ecc51f48
NC
9761 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9762 printf (" -- ");
9763 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
9764 break;
9765
28f997cf
TG
9766 case DT_IA_64_VMS_LINKTIME:
9767#ifdef BFD64
9768 print_vms_time (entry->d_un.d_val);
9769#endif
9770 break;
9771
9772 case DT_IA_64_VMS_LNKFLAGS:
9773 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9774 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
9775 printf (" CALL_DEBUG");
9776 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
9777 printf (" NOP0BUFS");
9778 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
9779 printf (" P0IMAGE");
9780 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
9781 printf (" MKTHREADS");
9782 if (entry->d_un.d_val & VMS_LF_UPCALLS)
9783 printf (" UPCALLS");
9784 if (entry->d_un.d_val & VMS_LF_IMGSTA)
9785 printf (" IMGSTA");
9786 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
9787 printf (" INITIALIZE");
9788 if (entry->d_un.d_val & VMS_LF_MAIN)
9789 printf (" MAIN");
9790 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
9791 printf (" EXE_INIT");
9792 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
9793 printf (" TBK_IN_IMG");
9794 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
9795 printf (" DBG_IN_IMG");
9796 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
9797 printf (" TBK_IN_DSF");
9798 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
9799 printf (" DBG_IN_DSF");
9800 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
9801 printf (" SIGNATURES");
9802 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
9803 printf (" REL_SEG_OFF");
9804 break;
9805
bdf4d63a
JJ
9806 default:
9807 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9808 break;
ecc51f48 9809 }
bdf4d63a 9810 putchar ('\n');
ecc51f48
NC
9811}
9812
32ec8896 9813static bfd_boolean
dda8d76d 9814get_32bit_dynamic_section (Filedata * filedata)
252b5132 9815{
2cf0635d
NC
9816 Elf32_External_Dyn * edyn;
9817 Elf32_External_Dyn * ext;
9818 Elf_Internal_Dyn * entry;
103f02d3 9819
978c4450
AM
9820 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
9821 filedata->dynamic_addr, 1,
9822 filedata->dynamic_size,
9823 _("dynamic section"));
a6e9f9df 9824 if (!edyn)
32ec8896 9825 return FALSE;
103f02d3 9826
071436c6
NC
9827 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9828 might not have the luxury of section headers. Look for the DT_NULL
9829 terminator to determine the number of entries. */
978c4450
AM
9830 for (ext = edyn, filedata->dynamic_nent = 0;
9831 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
9832 ext++)
9833 {
978c4450 9834 filedata->dynamic_nent++;
ba2685cc
AM
9835 if (BYTE_GET (ext->d_tag) == DT_NULL)
9836 break;
9837 }
252b5132 9838
978c4450
AM
9839 filedata->dynamic_section
9840 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
9841 if (filedata->dynamic_section == NULL)
252b5132 9842 {
8b73c356 9843 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 9844 (unsigned long) filedata->dynamic_nent);
9ea033b2 9845 free (edyn);
32ec8896 9846 return FALSE;
9ea033b2 9847 }
252b5132 9848
978c4450
AM
9849 for (ext = edyn, entry = filedata->dynamic_section;
9850 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 9851 ext++, entry++)
9ea033b2 9852 {
fb514b26
AM
9853 entry->d_tag = BYTE_GET (ext->d_tag);
9854 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9855 }
9856
9ea033b2
NC
9857 free (edyn);
9858
32ec8896 9859 return TRUE;
9ea033b2
NC
9860}
9861
32ec8896 9862static bfd_boolean
dda8d76d 9863get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 9864{
2cf0635d
NC
9865 Elf64_External_Dyn * edyn;
9866 Elf64_External_Dyn * ext;
9867 Elf_Internal_Dyn * entry;
103f02d3 9868
071436c6 9869 /* Read in the data. */
978c4450
AM
9870 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
9871 filedata->dynamic_addr, 1,
9872 filedata->dynamic_size,
9873 _("dynamic section"));
a6e9f9df 9874 if (!edyn)
32ec8896 9875 return FALSE;
103f02d3 9876
071436c6
NC
9877 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9878 might not have the luxury of section headers. Look for the DT_NULL
9879 terminator to determine the number of entries. */
978c4450 9880 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 9881 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 9882 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
9883 ext++)
9884 {
978c4450 9885 filedata->dynamic_nent++;
66543521 9886 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
9887 break;
9888 }
252b5132 9889
978c4450
AM
9890 filedata->dynamic_section
9891 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
9892 if (filedata->dynamic_section == NULL)
252b5132 9893 {
8b73c356 9894 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 9895 (unsigned long) filedata->dynamic_nent);
252b5132 9896 free (edyn);
32ec8896 9897 return FALSE;
252b5132
RH
9898 }
9899
071436c6 9900 /* Convert from external to internal formats. */
978c4450
AM
9901 for (ext = edyn, entry = filedata->dynamic_section;
9902 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 9903 ext++, entry++)
252b5132 9904 {
66543521
AM
9905 entry->d_tag = BYTE_GET (ext->d_tag);
9906 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9907 }
9908
9909 free (edyn);
9910
32ec8896 9911 return TRUE;
9ea033b2
NC
9912}
9913
e9e44622
JJ
9914static void
9915print_dynamic_flags (bfd_vma flags)
d1133906 9916{
32ec8896 9917 bfd_boolean first = TRUE;
13ae64f3 9918
d1133906
NC
9919 while (flags)
9920 {
9921 bfd_vma flag;
9922
9923 flag = flags & - flags;
9924 flags &= ~ flag;
9925
e9e44622 9926 if (first)
32ec8896 9927 first = FALSE;
e9e44622
JJ
9928 else
9929 putc (' ', stdout);
13ae64f3 9930
d1133906
NC
9931 switch (flag)
9932 {
e9e44622
JJ
9933 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
9934 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
9935 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
9936 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
9937 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 9938 default: fputs (_("unknown"), stdout); break;
d1133906
NC
9939 }
9940 }
e9e44622 9941 puts ("");
d1133906
NC
9942}
9943
10ca4b04
L
9944static bfd_vma *
9945get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
9946{
9947 unsigned char * e_data;
9948 bfd_vma * i_data;
9949
9950 /* If the size_t type is smaller than the bfd_size_type, eg because
9951 you are building a 32-bit tool on a 64-bit host, then make sure
9952 that when (number) is cast to (size_t) no information is lost. */
9953 if (sizeof (size_t) < sizeof (bfd_size_type)
9954 && (bfd_size_type) ((size_t) number) != number)
9955 {
9956 error (_("Size truncation prevents reading %s elements of size %u\n"),
9957 bfd_vmatoa ("u", number), ent_size);
9958 return NULL;
9959 }
9960
9961 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
9962 attempting to allocate memory when the read is bound to fail. */
9963 if (ent_size * number > filedata->file_size)
9964 {
9965 error (_("Invalid number of dynamic entries: %s\n"),
9966 bfd_vmatoa ("u", number));
9967 return NULL;
9968 }
9969
9970 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
9971 if (e_data == NULL)
9972 {
9973 error (_("Out of memory reading %s dynamic entries\n"),
9974 bfd_vmatoa ("u", number));
9975 return NULL;
9976 }
9977
9978 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
9979 {
9980 error (_("Unable to read in %s bytes of dynamic data\n"),
9981 bfd_vmatoa ("u", number * ent_size));
9982 free (e_data);
9983 return NULL;
9984 }
9985
9986 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
9987 if (i_data == NULL)
9988 {
9989 error (_("Out of memory allocating space for %s dynamic entries\n"),
9990 bfd_vmatoa ("u", number));
9991 free (e_data);
9992 return NULL;
9993 }
9994
9995 while (number--)
9996 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
9997
9998 free (e_data);
9999
10000 return i_data;
10001}
10002
10003static unsigned long
10004get_num_dynamic_syms (Filedata * filedata)
10005{
10006 unsigned long num_of_syms = 0;
10007
10008 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10009 return num_of_syms;
10010
978c4450 10011 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10012 {
10013 unsigned char nb[8];
10014 unsigned char nc[8];
10015 unsigned int hash_ent_size = 4;
10016
10017 if ((filedata->file_header.e_machine == EM_ALPHA
10018 || filedata->file_header.e_machine == EM_S390
10019 || filedata->file_header.e_machine == EM_S390_OLD)
10020 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10021 hash_ent_size = 8;
10022
10023 if (fseek (filedata->handle,
978c4450
AM
10024 (filedata->archive_file_offset
10025 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10026 sizeof nb + sizeof nc)),
10027 SEEK_SET))
10028 {
10029 error (_("Unable to seek to start of dynamic information\n"));
10030 goto no_hash;
10031 }
10032
10033 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10034 {
10035 error (_("Failed to read in number of buckets\n"));
10036 goto no_hash;
10037 }
10038
10039 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10040 {
10041 error (_("Failed to read in number of chains\n"));
10042 goto no_hash;
10043 }
10044
978c4450
AM
10045 filedata->nbuckets = byte_get (nb, hash_ent_size);
10046 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10047
2482f306
AM
10048 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10049 {
10050 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10051 hash_ent_size);
10052 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10053 hash_ent_size);
001890e1 10054
2482f306
AM
10055 if (filedata->buckets != NULL && filedata->chains != NULL)
10056 num_of_syms = filedata->nchains;
10057 }
ceb9bf11 10058 no_hash:
10ca4b04
L
10059 if (num_of_syms == 0)
10060 {
978c4450 10061 if (filedata->buckets)
10ca4b04 10062 {
978c4450
AM
10063 free (filedata->buckets);
10064 filedata->buckets = NULL;
10ca4b04 10065 }
978c4450 10066 if (filedata->chains)
10ca4b04 10067 {
978c4450
AM
10068 free (filedata->chains);
10069 filedata->chains = NULL;
10ca4b04 10070 }
978c4450 10071 filedata->nbuckets = 0;
10ca4b04
L
10072 }
10073 }
10074
978c4450 10075 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10076 {
10077 unsigned char nb[16];
10078 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10079 bfd_vma buckets_vma;
10080 unsigned long hn;
10ca4b04
L
10081
10082 if (fseek (filedata->handle,
978c4450
AM
10083 (filedata->archive_file_offset
10084 + offset_from_vma (filedata,
10085 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10086 sizeof nb)),
10087 SEEK_SET))
10088 {
10089 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10090 goto no_gnu_hash;
10091 }
10092
10093 if (fread (nb, 16, 1, filedata->handle) != 1)
10094 {
10095 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10096 goto no_gnu_hash;
10097 }
10098
978c4450
AM
10099 filedata->ngnubuckets = byte_get (nb, 4);
10100 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10101 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10102 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10103 if (is_32bit_elf)
10104 buckets_vma += bitmaskwords * 4;
10105 else
10106 buckets_vma += bitmaskwords * 8;
10107
10108 if (fseek (filedata->handle,
978c4450 10109 (filedata->archive_file_offset
10ca4b04
L
10110 + offset_from_vma (filedata, buckets_vma, 4)),
10111 SEEK_SET))
10112 {
10113 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10114 goto no_gnu_hash;
10115 }
10116
978c4450
AM
10117 filedata->gnubuckets
10118 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10119
978c4450 10120 if (filedata->gnubuckets == NULL)
90837ea7 10121 goto no_gnu_hash;
10ca4b04 10122
978c4450
AM
10123 for (i = 0; i < filedata->ngnubuckets; i++)
10124 if (filedata->gnubuckets[i] != 0)
10ca4b04 10125 {
978c4450 10126 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10127 goto no_gnu_hash;
10ca4b04 10128
978c4450
AM
10129 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10130 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10131 }
10132
10133 if (maxchain == 0xffffffff)
90837ea7 10134 goto no_gnu_hash;
10ca4b04 10135
978c4450 10136 maxchain -= filedata->gnusymidx;
10ca4b04
L
10137
10138 if (fseek (filedata->handle,
978c4450
AM
10139 (filedata->archive_file_offset
10140 + offset_from_vma (filedata,
10141 buckets_vma + 4 * (filedata->ngnubuckets
10142 + maxchain),
10143 4)),
10ca4b04
L
10144 SEEK_SET))
10145 {
10146 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10147 goto no_gnu_hash;
10148 }
10149
10150 do
10151 {
10152 if (fread (nb, 4, 1, filedata->handle) != 1)
10153 {
10154 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10155 goto no_gnu_hash;
10156 }
10157
10158 if (maxchain + 1 == 0)
90837ea7 10159 goto no_gnu_hash;
10ca4b04
L
10160
10161 ++maxchain;
10162 }
10163 while ((byte_get (nb, 4) & 1) == 0);
10164
10165 if (fseek (filedata->handle,
978c4450
AM
10166 (filedata->archive_file_offset
10167 + offset_from_vma (filedata, (buckets_vma
10168 + 4 * filedata->ngnubuckets),
10169 4)),
10ca4b04
L
10170 SEEK_SET))
10171 {
10172 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10173 goto no_gnu_hash;
10174 }
10175
978c4450
AM
10176 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10177 filedata->ngnuchains = maxchain;
10ca4b04 10178
978c4450 10179 if (filedata->gnuchains == NULL)
90837ea7 10180 goto no_gnu_hash;
10ca4b04 10181
978c4450 10182 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10183 {
10184 if (fseek (filedata->handle,
978c4450 10185 (filedata->archive_file_offset
10ca4b04 10186 + offset_from_vma (filedata, (buckets_vma
978c4450 10187 + 4 * (filedata->ngnubuckets
10ca4b04
L
10188 + maxchain)), 4)),
10189 SEEK_SET))
10190 {
10191 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10192 goto no_gnu_hash;
10193 }
10194
978c4450 10195 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10196 if (filedata->mipsxlat == NULL)
10197 goto no_gnu_hash;
10ca4b04
L
10198 }
10199
978c4450
AM
10200 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10201 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10202 {
978c4450
AM
10203 bfd_vma si = filedata->gnubuckets[hn];
10204 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10205
10206 do
10207 {
978c4450 10208 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 10209 {
978c4450
AM
10210 if (filedata->mipsxlat[off] >= num_of_syms)
10211 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
10212 }
10213 else
10214 {
10215 if (si >= num_of_syms)
10216 num_of_syms = si + 1;
10217 }
10218 si++;
10219 }
978c4450
AM
10220 while (off < filedata->ngnuchains
10221 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
10222 }
10223
90837ea7 10224 if (num_of_syms == 0)
10ca4b04 10225 {
90837ea7 10226 no_gnu_hash:
978c4450 10227 if (filedata->mipsxlat)
10ca4b04 10228 {
978c4450
AM
10229 free (filedata->mipsxlat);
10230 filedata->mipsxlat = NULL;
10ca4b04 10231 }
978c4450 10232 if (filedata->gnuchains)
10ca4b04 10233 {
978c4450
AM
10234 free (filedata->gnuchains);
10235 filedata->gnuchains = NULL;
10ca4b04 10236 }
978c4450 10237 if (filedata->gnubuckets)
10ca4b04 10238 {
978c4450
AM
10239 free (filedata->gnubuckets);
10240 filedata->gnubuckets = NULL;
10ca4b04 10241 }
978c4450
AM
10242 filedata->ngnubuckets = 0;
10243 filedata->ngnuchains = 0;
10ca4b04
L
10244 }
10245 }
10246
10247 return num_of_syms;
10248}
10249
b2d38a17
NC
10250/* Parse and display the contents of the dynamic section. */
10251
32ec8896 10252static bfd_boolean
dda8d76d 10253process_dynamic_section (Filedata * filedata)
9ea033b2 10254{
2cf0635d 10255 Elf_Internal_Dyn * entry;
9ea033b2 10256
978c4450 10257 if (filedata->dynamic_size == 0)
9ea033b2
NC
10258 {
10259 if (do_dynamic)
b2d38a17 10260 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2 10261
32ec8896 10262 return TRUE;
9ea033b2
NC
10263 }
10264
10265 if (is_32bit_elf)
10266 {
dda8d76d 10267 if (! get_32bit_dynamic_section (filedata))
32ec8896
NC
10268 return FALSE;
10269 }
10270 else
10271 {
dda8d76d 10272 if (! get_64bit_dynamic_section (filedata))
32ec8896 10273 return FALSE;
9ea033b2 10274 }
9ea033b2 10275
252b5132 10276 /* Find the appropriate symbol table. */
978c4450 10277 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 10278 {
2482f306
AM
10279 unsigned long num_of_syms;
10280
978c4450
AM
10281 for (entry = filedata->dynamic_section;
10282 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10283 ++entry)
10ca4b04 10284 if (entry->d_tag == DT_SYMTAB)
978c4450 10285 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 10286 else if (entry->d_tag == DT_SYMENT)
978c4450 10287 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 10288 else if (entry->d_tag == DT_HASH)
978c4450 10289 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 10290 else if (entry->d_tag == DT_GNU_HASH)
978c4450 10291 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
10292 else if ((filedata->file_header.e_machine == EM_MIPS
10293 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10294 && entry->d_tag == DT_MIPS_XHASH)
10295 {
978c4450
AM
10296 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10297 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 10298 }
252b5132 10299
2482f306
AM
10300 num_of_syms = get_num_dynamic_syms (filedata);
10301
10302 if (num_of_syms != 0
10303 && filedata->dynamic_symbols == NULL
10304 && filedata->dynamic_info[DT_SYMTAB]
978c4450 10305 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
10306 {
10307 Elf_Internal_Phdr *seg;
2482f306 10308 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 10309
2482f306
AM
10310 if (! get_program_headers (filedata))
10311 {
10312 error (_("Cannot interpret virtual addresses "
10313 "without program headers.\n"));
10314 return FALSE;
10315 }
252b5132 10316
2482f306
AM
10317 for (seg = filedata->program_headers;
10318 seg < filedata->program_headers + filedata->file_header.e_phnum;
10319 ++seg)
10320 {
10321 if (seg->p_type != PT_LOAD)
10322 continue;
252b5132 10323
2482f306
AM
10324 if (seg->p_offset + seg->p_filesz > filedata->file_size)
10325 {
10326 /* See PR 21379 for a reproducer. */
10327 error (_("Invalid PT_LOAD entry\n"));
10328 return FALSE;
10329 }
252b5132 10330
2482f306
AM
10331 if (vma >= (seg->p_vaddr & -seg->p_align)
10332 && vma < seg->p_vaddr + seg->p_filesz)
10333 {
10334 /* Since we do not know how big the symbol table is,
10335 we default to reading in up to the end of PT_LOAD
10336 segment and processing that. This is overkill, I
10337 know, but it should work. */
10338 Elf_Internal_Shdr section;
10339 section.sh_offset = (vma - seg->p_vaddr
10340 + seg->p_offset);
10341 section.sh_size = (num_of_syms
10342 * filedata->dynamic_info[DT_SYMENT]);
10343 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
10344 section.sh_name = filedata->string_table_length;
10345 filedata->dynamic_symbols
10346 = GET_ELF_SYMBOLS (filedata, &section,
10347 &filedata->num_dynamic_syms);
10348 if (filedata->dynamic_symbols == NULL
10349 || filedata->num_dynamic_syms != num_of_syms)
10350 {
10351 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
10352 return FALSE;
10353 }
10354 break;
10355 }
10356 }
10357 }
10358 }
252b5132
RH
10359
10360 /* Similarly find a string table. */
978c4450
AM
10361 if (filedata->dynamic_strings == NULL)
10362 for (entry = filedata->dynamic_section;
10363 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
10364 ++entry)
10365 {
10366 if (entry->d_tag == DT_STRTAB)
978c4450 10367 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 10368
10ca4b04 10369 if (entry->d_tag == DT_STRSZ)
978c4450 10370 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10371
978c4450
AM
10372 if (filedata->dynamic_info[DT_STRTAB]
10373 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
10374 {
10375 unsigned long offset;
978c4450 10376 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
10377
10378 offset = offset_from_vma (filedata,
978c4450 10379 filedata->dynamic_info[DT_STRTAB],
10ca4b04 10380 str_tab_len);
978c4450
AM
10381 filedata->dynamic_strings
10382 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
10383 _("dynamic string table"));
10384 if (filedata->dynamic_strings == NULL)
10ca4b04
L
10385 {
10386 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10387 break;
10388 }
e3d39609 10389
978c4450 10390 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
10391 break;
10392 }
10393 }
252b5132
RH
10394
10395 /* And find the syminfo section if available. */
978c4450 10396 if (filedata->dynamic_syminfo == NULL)
252b5132 10397 {
3e8bba36 10398 unsigned long syminsz = 0;
252b5132 10399
978c4450
AM
10400 for (entry = filedata->dynamic_section;
10401 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10402 ++entry)
252b5132
RH
10403 {
10404 if (entry->d_tag == DT_SYMINENT)
10405 {
10406 /* Note: these braces are necessary to avoid a syntax
10407 error from the SunOS4 C compiler. */
049b0c3a
NC
10408 /* PR binutils/17531: A corrupt file can trigger this test.
10409 So do not use an assert, instead generate an error message. */
10410 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10411 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10412 (int) entry->d_un.d_val);
252b5132
RH
10413 }
10414 else if (entry->d_tag == DT_SYMINSZ)
10415 syminsz = entry->d_un.d_val;
10416 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
10417 filedata->dynamic_syminfo_offset
10418 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
10419 }
10420
978c4450 10421 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 10422 {
2cf0635d
NC
10423 Elf_External_Syminfo * extsyminfo;
10424 Elf_External_Syminfo * extsym;
10425 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10426
10427 /* There is a syminfo section. Read the data. */
3f5e193b 10428 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
10429 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
10430 1, syminsz, _("symbol information"));
a6e9f9df 10431 if (!extsyminfo)
32ec8896 10432 return FALSE;
252b5132 10433
978c4450 10434 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
10435 {
10436 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 10437 free (filedata->dynamic_syminfo);
e3d39609 10438 }
978c4450
AM
10439 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
10440 if (filedata->dynamic_syminfo == NULL)
252b5132 10441 {
2482f306
AM
10442 error (_("Out of memory allocating %lu bytes "
10443 "for dynamic symbol info\n"),
8b73c356 10444 (unsigned long) syminsz);
32ec8896 10445 return FALSE;
252b5132
RH
10446 }
10447
2482f306
AM
10448 filedata->dynamic_syminfo_nent
10449 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 10450 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
10451 syminfo < (filedata->dynamic_syminfo
10452 + filedata->dynamic_syminfo_nent);
86dba8ee 10453 ++syminfo, ++extsym)
252b5132 10454 {
86dba8ee
AM
10455 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10456 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10457 }
10458
10459 free (extsyminfo);
10460 }
10461 }
10462
978c4450 10463 if (do_dynamic && filedata->dynamic_addr)
d3a49aa8
AM
10464 printf (ngettext ("\nDynamic section at offset 0x%lx "
10465 "contains %lu entry:\n",
10466 "\nDynamic section at offset 0x%lx "
10467 "contains %lu entries:\n",
978c4450
AM
10468 filedata->dynamic_nent),
10469 filedata->dynamic_addr, (unsigned long) filedata->dynamic_nent);
252b5132
RH
10470 if (do_dynamic)
10471 printf (_(" Tag Type Name/Value\n"));
10472
978c4450
AM
10473 for (entry = filedata->dynamic_section;
10474 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10475 entry++)
252b5132
RH
10476 {
10477 if (do_dynamic)
f7a99963 10478 {
2cf0635d 10479 const char * dtype;
e699b9ff 10480
f7a99963
NC
10481 putchar (' ');
10482 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10483 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10484 printf (" (%s)%*s", dtype,
32ec8896 10485 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10486 }
252b5132
RH
10487
10488 switch (entry->d_tag)
10489 {
d1133906
NC
10490 case DT_FLAGS:
10491 if (do_dynamic)
e9e44622 10492 print_dynamic_flags (entry->d_un.d_val);
d1133906 10493 break;
76da6bbe 10494
252b5132
RH
10495 case DT_AUXILIARY:
10496 case DT_FILTER:
019148e4
L
10497 case DT_CONFIG:
10498 case DT_DEPAUDIT:
10499 case DT_AUDIT:
252b5132
RH
10500 if (do_dynamic)
10501 {
019148e4 10502 switch (entry->d_tag)
b34976b6 10503 {
019148e4
L
10504 case DT_AUXILIARY:
10505 printf (_("Auxiliary library"));
10506 break;
10507
10508 case DT_FILTER:
10509 printf (_("Filter library"));
10510 break;
10511
b34976b6 10512 case DT_CONFIG:
019148e4
L
10513 printf (_("Configuration file"));
10514 break;
10515
10516 case DT_DEPAUDIT:
10517 printf (_("Dependency audit library"));
10518 break;
10519
10520 case DT_AUDIT:
10521 printf (_("Audit library"));
10522 break;
10523 }
252b5132 10524
978c4450
AM
10525 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10526 printf (": [%s]\n",
10527 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 10528 else
f7a99963
NC
10529 {
10530 printf (": ");
10531 print_vma (entry->d_un.d_val, PREFIX_HEX);
10532 putchar ('\n');
10533 }
252b5132
RH
10534 }
10535 break;
10536
dcefbbbd 10537 case DT_FEATURE:
252b5132
RH
10538 if (do_dynamic)
10539 {
10540 printf (_("Flags:"));
86f55779 10541
252b5132
RH
10542 if (entry->d_un.d_val == 0)
10543 printf (_(" None\n"));
10544 else
10545 {
10546 unsigned long int val = entry->d_un.d_val;
86f55779 10547
252b5132
RH
10548 if (val & DTF_1_PARINIT)
10549 {
10550 printf (" PARINIT");
10551 val ^= DTF_1_PARINIT;
10552 }
dcefbbbd
L
10553 if (val & DTF_1_CONFEXP)
10554 {
10555 printf (" CONFEXP");
10556 val ^= DTF_1_CONFEXP;
10557 }
252b5132
RH
10558 if (val != 0)
10559 printf (" %lx", val);
10560 puts ("");
10561 }
10562 }
10563 break;
10564
10565 case DT_POSFLAG_1:
10566 if (do_dynamic)
10567 {
10568 printf (_("Flags:"));
86f55779 10569
252b5132
RH
10570 if (entry->d_un.d_val == 0)
10571 printf (_(" None\n"));
10572 else
10573 {
10574 unsigned long int val = entry->d_un.d_val;
86f55779 10575
252b5132
RH
10576 if (val & DF_P1_LAZYLOAD)
10577 {
10578 printf (" LAZYLOAD");
10579 val ^= DF_P1_LAZYLOAD;
10580 }
10581 if (val & DF_P1_GROUPPERM)
10582 {
10583 printf (" GROUPPERM");
10584 val ^= DF_P1_GROUPPERM;
10585 }
10586 if (val != 0)
10587 printf (" %lx", val);
10588 puts ("");
10589 }
10590 }
10591 break;
10592
10593 case DT_FLAGS_1:
10594 if (do_dynamic)
10595 {
10596 printf (_("Flags:"));
10597 if (entry->d_un.d_val == 0)
10598 printf (_(" None\n"));
10599 else
10600 {
10601 unsigned long int val = entry->d_un.d_val;
86f55779 10602
252b5132
RH
10603 if (val & DF_1_NOW)
10604 {
10605 printf (" NOW");
10606 val ^= DF_1_NOW;
10607 }
10608 if (val & DF_1_GLOBAL)
10609 {
10610 printf (" GLOBAL");
10611 val ^= DF_1_GLOBAL;
10612 }
10613 if (val & DF_1_GROUP)
10614 {
10615 printf (" GROUP");
10616 val ^= DF_1_GROUP;
10617 }
10618 if (val & DF_1_NODELETE)
10619 {
10620 printf (" NODELETE");
10621 val ^= DF_1_NODELETE;
10622 }
10623 if (val & DF_1_LOADFLTR)
10624 {
10625 printf (" LOADFLTR");
10626 val ^= DF_1_LOADFLTR;
10627 }
10628 if (val & DF_1_INITFIRST)
10629 {
10630 printf (" INITFIRST");
10631 val ^= DF_1_INITFIRST;
10632 }
10633 if (val & DF_1_NOOPEN)
10634 {
10635 printf (" NOOPEN");
10636 val ^= DF_1_NOOPEN;
10637 }
10638 if (val & DF_1_ORIGIN)
10639 {
10640 printf (" ORIGIN");
10641 val ^= DF_1_ORIGIN;
10642 }
10643 if (val & DF_1_DIRECT)
10644 {
10645 printf (" DIRECT");
10646 val ^= DF_1_DIRECT;
10647 }
10648 if (val & DF_1_TRANS)
10649 {
10650 printf (" TRANS");
10651 val ^= DF_1_TRANS;
10652 }
10653 if (val & DF_1_INTERPOSE)
10654 {
10655 printf (" INTERPOSE");
10656 val ^= DF_1_INTERPOSE;
10657 }
f7db6139 10658 if (val & DF_1_NODEFLIB)
dcefbbbd 10659 {
f7db6139
L
10660 printf (" NODEFLIB");
10661 val ^= DF_1_NODEFLIB;
dcefbbbd
L
10662 }
10663 if (val & DF_1_NODUMP)
10664 {
10665 printf (" NODUMP");
10666 val ^= DF_1_NODUMP;
10667 }
34b60028 10668 if (val & DF_1_CONFALT)
dcefbbbd 10669 {
34b60028
L
10670 printf (" CONFALT");
10671 val ^= DF_1_CONFALT;
10672 }
10673 if (val & DF_1_ENDFILTEE)
10674 {
10675 printf (" ENDFILTEE");
10676 val ^= DF_1_ENDFILTEE;
10677 }
10678 if (val & DF_1_DISPRELDNE)
10679 {
10680 printf (" DISPRELDNE");
10681 val ^= DF_1_DISPRELDNE;
10682 }
10683 if (val & DF_1_DISPRELPND)
10684 {
10685 printf (" DISPRELPND");
10686 val ^= DF_1_DISPRELPND;
10687 }
10688 if (val & DF_1_NODIRECT)
10689 {
10690 printf (" NODIRECT");
10691 val ^= DF_1_NODIRECT;
10692 }
10693 if (val & DF_1_IGNMULDEF)
10694 {
10695 printf (" IGNMULDEF");
10696 val ^= DF_1_IGNMULDEF;
10697 }
10698 if (val & DF_1_NOKSYMS)
10699 {
10700 printf (" NOKSYMS");
10701 val ^= DF_1_NOKSYMS;
10702 }
10703 if (val & DF_1_NOHDR)
10704 {
10705 printf (" NOHDR");
10706 val ^= DF_1_NOHDR;
10707 }
10708 if (val & DF_1_EDITED)
10709 {
10710 printf (" EDITED");
10711 val ^= DF_1_EDITED;
10712 }
10713 if (val & DF_1_NORELOC)
10714 {
10715 printf (" NORELOC");
10716 val ^= DF_1_NORELOC;
10717 }
10718 if (val & DF_1_SYMINTPOSE)
10719 {
10720 printf (" SYMINTPOSE");
10721 val ^= DF_1_SYMINTPOSE;
10722 }
10723 if (val & DF_1_GLOBAUDIT)
10724 {
10725 printf (" GLOBAUDIT");
10726 val ^= DF_1_GLOBAUDIT;
10727 }
10728 if (val & DF_1_SINGLETON)
10729 {
10730 printf (" SINGLETON");
10731 val ^= DF_1_SINGLETON;
dcefbbbd 10732 }
5c383f02
RO
10733 if (val & DF_1_STUB)
10734 {
10735 printf (" STUB");
10736 val ^= DF_1_STUB;
10737 }
10738 if (val & DF_1_PIE)
10739 {
10740 printf (" PIE");
10741 val ^= DF_1_PIE;
10742 }
b1202ffa
L
10743 if (val & DF_1_KMOD)
10744 {
10745 printf (" KMOD");
10746 val ^= DF_1_KMOD;
10747 }
10748 if (val & DF_1_WEAKFILTER)
10749 {
10750 printf (" WEAKFILTER");
10751 val ^= DF_1_WEAKFILTER;
10752 }
10753 if (val & DF_1_NOCOMMON)
10754 {
10755 printf (" NOCOMMON");
10756 val ^= DF_1_NOCOMMON;
10757 }
252b5132
RH
10758 if (val != 0)
10759 printf (" %lx", val);
10760 puts ("");
10761 }
10762 }
10763 break;
10764
10765 case DT_PLTREL:
978c4450 10766 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 10767 if (do_dynamic)
dda8d76d 10768 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
10769 break;
10770
10771 case DT_NULL :
10772 case DT_NEEDED :
10773 case DT_PLTGOT :
10774 case DT_HASH :
10775 case DT_STRTAB :
10776 case DT_SYMTAB :
10777 case DT_RELA :
10778 case DT_INIT :
10779 case DT_FINI :
10780 case DT_SONAME :
10781 case DT_RPATH :
10782 case DT_SYMBOLIC:
10783 case DT_REL :
10784 case DT_DEBUG :
10785 case DT_TEXTREL :
10786 case DT_JMPREL :
019148e4 10787 case DT_RUNPATH :
978c4450 10788 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
10789
10790 if (do_dynamic)
10791 {
2cf0635d 10792 char * name;
252b5132 10793
978c4450
AM
10794 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10795 name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 10796 else
d79b3d50 10797 name = NULL;
252b5132
RH
10798
10799 if (name)
10800 {
10801 switch (entry->d_tag)
10802 {
10803 case DT_NEEDED:
10804 printf (_("Shared library: [%s]"), name);
10805
978c4450 10806 if (streq (name, filedata->program_interpreter))
f7a99963 10807 printf (_(" program interpreter"));
252b5132
RH
10808 break;
10809
10810 case DT_SONAME:
f7a99963 10811 printf (_("Library soname: [%s]"), name);
252b5132
RH
10812 break;
10813
10814 case DT_RPATH:
f7a99963 10815 printf (_("Library rpath: [%s]"), name);
252b5132
RH
10816 break;
10817
019148e4
L
10818 case DT_RUNPATH:
10819 printf (_("Library runpath: [%s]"), name);
10820 break;
10821
252b5132 10822 default:
f7a99963
NC
10823 print_vma (entry->d_un.d_val, PREFIX_HEX);
10824 break;
252b5132
RH
10825 }
10826 }
10827 else
f7a99963
NC
10828 print_vma (entry->d_un.d_val, PREFIX_HEX);
10829
10830 putchar ('\n');
252b5132
RH
10831 }
10832 break;
10833
10834 case DT_PLTRELSZ:
10835 case DT_RELASZ :
10836 case DT_STRSZ :
10837 case DT_RELSZ :
10838 case DT_RELAENT :
10839 case DT_SYMENT :
10840 case DT_RELENT :
978c4450 10841 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 10842 /* Fall through. */
252b5132
RH
10843 case DT_PLTPADSZ:
10844 case DT_MOVEENT :
10845 case DT_MOVESZ :
10846 case DT_INIT_ARRAYSZ:
10847 case DT_FINI_ARRAYSZ:
047b2264
JJ
10848 case DT_GNU_CONFLICTSZ:
10849 case DT_GNU_LIBLISTSZ:
252b5132 10850 if (do_dynamic)
f7a99963
NC
10851 {
10852 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 10853 printf (_(" (bytes)\n"));
f7a99963 10854 }
252b5132
RH
10855 break;
10856
10857 case DT_VERDEFNUM:
10858 case DT_VERNEEDNUM:
10859 case DT_RELACOUNT:
10860 case DT_RELCOUNT:
10861 if (do_dynamic)
f7a99963
NC
10862 {
10863 print_vma (entry->d_un.d_val, UNSIGNED);
10864 putchar ('\n');
10865 }
252b5132
RH
10866 break;
10867
10868 case DT_SYMINSZ:
10869 case DT_SYMINENT:
10870 case DT_SYMINFO:
10871 case DT_USED:
10872 case DT_INIT_ARRAY:
10873 case DT_FINI_ARRAY:
10874 if (do_dynamic)
10875 {
d79b3d50 10876 if (entry->d_tag == DT_USED
978c4450 10877 && VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
252b5132 10878 {
978c4450 10879 char * name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 10880
b34976b6 10881 if (*name)
252b5132
RH
10882 {
10883 printf (_("Not needed object: [%s]\n"), name);
10884 break;
10885 }
10886 }
103f02d3 10887
f7a99963
NC
10888 print_vma (entry->d_un.d_val, PREFIX_HEX);
10889 putchar ('\n');
252b5132
RH
10890 }
10891 break;
10892
10893 case DT_BIND_NOW:
10894 /* The value of this entry is ignored. */
35b1837e
AM
10895 if (do_dynamic)
10896 putchar ('\n');
252b5132 10897 break;
103f02d3 10898
047b2264
JJ
10899 case DT_GNU_PRELINKED:
10900 if (do_dynamic)
10901 {
2cf0635d 10902 struct tm * tmp;
91d6fa6a 10903 time_t atime = entry->d_un.d_val;
047b2264 10904
91d6fa6a 10905 tmp = gmtime (&atime);
071436c6
NC
10906 /* PR 17533 file: 041-1244816-0.004. */
10907 if (tmp == NULL)
5a2cbcf4
L
10908 printf (_("<corrupt time val: %lx"),
10909 (unsigned long) atime);
071436c6
NC
10910 else
10911 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
10912 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10913 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
10914
10915 }
10916 break;
10917
fdc90cb4 10918 case DT_GNU_HASH:
978c4450 10919 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
10920 if (do_dynamic)
10921 {
10922 print_vma (entry->d_un.d_val, PREFIX_HEX);
10923 putchar ('\n');
10924 }
10925 break;
10926
252b5132
RH
10927 default:
10928 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
10929 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
10930 = entry->d_un.d_val;
252b5132
RH
10931
10932 if (do_dynamic)
10933 {
dda8d76d 10934 switch (filedata->file_header.e_machine)
252b5132 10935 {
37c18eed
SD
10936 case EM_AARCH64:
10937 dynamic_section_aarch64_val (entry);
10938 break;
252b5132 10939 case EM_MIPS:
4fe85591 10940 case EM_MIPS_RS3_LE:
978c4450 10941 dynamic_section_mips_val (filedata, entry);
252b5132 10942 break;
103f02d3 10943 case EM_PARISC:
b2d38a17 10944 dynamic_section_parisc_val (entry);
103f02d3 10945 break;
ecc51f48 10946 case EM_IA_64:
b2d38a17 10947 dynamic_section_ia64_val (entry);
ecc51f48 10948 break;
252b5132 10949 default:
f7a99963
NC
10950 print_vma (entry->d_un.d_val, PREFIX_HEX);
10951 putchar ('\n');
252b5132
RH
10952 }
10953 }
10954 break;
10955 }
10956 }
10957
32ec8896 10958 return TRUE;
252b5132
RH
10959}
10960
10961static char *
d3ba0551 10962get_ver_flags (unsigned int flags)
252b5132 10963{
6d4f21f6 10964 static char buff[128];
252b5132
RH
10965
10966 buff[0] = 0;
10967
10968 if (flags == 0)
10969 return _("none");
10970
10971 if (flags & VER_FLG_BASE)
7bb1ad17 10972 strcat (buff, "BASE");
252b5132
RH
10973
10974 if (flags & VER_FLG_WEAK)
10975 {
10976 if (flags & VER_FLG_BASE)
7bb1ad17 10977 strcat (buff, " | ");
252b5132 10978
7bb1ad17 10979 strcat (buff, "WEAK");
252b5132
RH
10980 }
10981
44ec90b9
RO
10982 if (flags & VER_FLG_INFO)
10983 {
10984 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 10985 strcat (buff, " | ");
44ec90b9 10986
7bb1ad17 10987 strcat (buff, "INFO");
44ec90b9
RO
10988 }
10989
10990 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
10991 {
10992 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
10993 strcat (buff, " | ");
10994
10995 strcat (buff, _("<unknown>"));
10996 }
252b5132
RH
10997
10998 return buff;
10999}
11000
11001/* Display the contents of the version sections. */
98fb390a 11002
32ec8896 11003static bfd_boolean
dda8d76d 11004process_version_sections (Filedata * filedata)
252b5132 11005{
2cf0635d 11006 Elf_Internal_Shdr * section;
b34976b6 11007 unsigned i;
32ec8896 11008 bfd_boolean found = FALSE;
252b5132
RH
11009
11010 if (! do_version)
32ec8896 11011 return TRUE;
252b5132 11012
dda8d76d
NC
11013 for (i = 0, section = filedata->section_headers;
11014 i < filedata->file_header.e_shnum;
b34976b6 11015 i++, section++)
252b5132
RH
11016 {
11017 switch (section->sh_type)
11018 {
11019 case SHT_GNU_verdef:
11020 {
2cf0635d 11021 Elf_External_Verdef * edefs;
452bf675
AM
11022 unsigned long idx;
11023 unsigned long cnt;
2cf0635d 11024 char * endbuf;
252b5132 11025
32ec8896 11026 found = TRUE;
252b5132 11027
d3a49aa8
AM
11028 printf (ngettext ("\nVersion definition section '%s' "
11029 "contains %u entry:\n",
11030 "\nVersion definition section '%s' "
11031 "contains %u entries:\n",
11032 section->sh_info),
dda8d76d 11033 printable_section_name (filedata, section),
74e1a04b 11034 section->sh_info);
252b5132 11035
ae9ac79e 11036 printf (_(" Addr: 0x"));
252b5132 11037 printf_vma (section->sh_addr);
233f82cf 11038 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11039 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11040 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11041
3f5e193b 11042 edefs = (Elf_External_Verdef *)
dda8d76d 11043 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11044 _("version definition section"));
a6e9f9df
AM
11045 if (!edefs)
11046 break;
59245841 11047 endbuf = (char *) edefs + section->sh_size;
252b5132 11048
1445030f 11049 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11050 {
2cf0635d
NC
11051 char * vstart;
11052 Elf_External_Verdef * edef;
b34976b6 11053 Elf_Internal_Verdef ent;
2cf0635d 11054 Elf_External_Verdaux * eaux;
b34976b6 11055 Elf_Internal_Verdaux aux;
452bf675 11056 unsigned long isum;
b34976b6 11057 int j;
103f02d3 11058
252b5132 11059 vstart = ((char *) edefs) + idx;
54806181
AM
11060 if (vstart + sizeof (*edef) > endbuf)
11061 break;
252b5132
RH
11062
11063 edef = (Elf_External_Verdef *) vstart;
11064
11065 ent.vd_version = BYTE_GET (edef->vd_version);
11066 ent.vd_flags = BYTE_GET (edef->vd_flags);
11067 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11068 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11069 ent.vd_hash = BYTE_GET (edef->vd_hash);
11070 ent.vd_aux = BYTE_GET (edef->vd_aux);
11071 ent.vd_next = BYTE_GET (edef->vd_next);
11072
452bf675 11073 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11074 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11075
11076 printf (_(" Index: %d Cnt: %d "),
11077 ent.vd_ndx, ent.vd_cnt);
11078
452bf675 11079 /* Check for overflow. */
1445030f 11080 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11081 break;
11082
252b5132
RH
11083 vstart += ent.vd_aux;
11084
1445030f
AM
11085 if (vstart + sizeof (*eaux) > endbuf)
11086 break;
252b5132
RH
11087 eaux = (Elf_External_Verdaux *) vstart;
11088
11089 aux.vda_name = BYTE_GET (eaux->vda_name);
11090 aux.vda_next = BYTE_GET (eaux->vda_next);
11091
978c4450
AM
11092 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
11093 printf (_("Name: %s\n"),
11094 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132
RH
11095 else
11096 printf (_("Name index: %ld\n"), aux.vda_name);
11097
11098 isum = idx + ent.vd_aux;
11099
b34976b6 11100 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11101 {
1445030f
AM
11102 if (aux.vda_next < sizeof (*eaux)
11103 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11104 {
11105 warn (_("Invalid vda_next field of %lx\n"),
11106 aux.vda_next);
11107 j = ent.vd_cnt;
11108 break;
11109 }
dd24e3da 11110 /* Check for overflow. */
7e26601c 11111 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11112 break;
11113
252b5132
RH
11114 isum += aux.vda_next;
11115 vstart += aux.vda_next;
11116
54806181
AM
11117 if (vstart + sizeof (*eaux) > endbuf)
11118 break;
1445030f 11119 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11120
11121 aux.vda_name = BYTE_GET (eaux->vda_name);
11122 aux.vda_next = BYTE_GET (eaux->vda_next);
11123
978c4450 11124 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
452bf675 11125 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450
AM
11126 isum, j,
11127 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132 11128 else
452bf675 11129 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11130 isum, j, aux.vda_name);
11131 }
dd24e3da 11132
54806181
AM
11133 if (j < ent.vd_cnt)
11134 printf (_(" Version def aux past end of section\n"));
252b5132 11135
c9f02c3e
MR
11136 /* PR 17531:
11137 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11138 if (ent.vd_next < sizeof (*edef)
11139 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11140 {
11141 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11142 cnt = section->sh_info;
11143 break;
11144 }
452bf675 11145 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11146 break;
11147
252b5132
RH
11148 idx += ent.vd_next;
11149 }
dd24e3da 11150
54806181
AM
11151 if (cnt < section->sh_info)
11152 printf (_(" Version definition past end of section\n"));
252b5132
RH
11153
11154 free (edefs);
11155 }
11156 break;
103f02d3 11157
252b5132
RH
11158 case SHT_GNU_verneed:
11159 {
2cf0635d 11160 Elf_External_Verneed * eneed;
452bf675
AM
11161 unsigned long idx;
11162 unsigned long cnt;
2cf0635d 11163 char * endbuf;
252b5132 11164
32ec8896 11165 found = TRUE;
252b5132 11166
d3a49aa8
AM
11167 printf (ngettext ("\nVersion needs section '%s' "
11168 "contains %u entry:\n",
11169 "\nVersion needs section '%s' "
11170 "contains %u entries:\n",
11171 section->sh_info),
dda8d76d 11172 printable_section_name (filedata, section), section->sh_info);
252b5132
RH
11173
11174 printf (_(" Addr: 0x"));
11175 printf_vma (section->sh_addr);
72de5009 11176 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11177 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11178 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11179
dda8d76d 11180 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11181 section->sh_offset, 1,
11182 section->sh_size,
9cf03b7e 11183 _("Version Needs section"));
a6e9f9df
AM
11184 if (!eneed)
11185 break;
59245841 11186 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11187
11188 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11189 {
2cf0635d 11190 Elf_External_Verneed * entry;
b34976b6 11191 Elf_Internal_Verneed ent;
452bf675 11192 unsigned long isum;
b34976b6 11193 int j;
2cf0635d 11194 char * vstart;
252b5132
RH
11195
11196 vstart = ((char *) eneed) + idx;
54806181
AM
11197 if (vstart + sizeof (*entry) > endbuf)
11198 break;
252b5132
RH
11199
11200 entry = (Elf_External_Verneed *) vstart;
11201
11202 ent.vn_version = BYTE_GET (entry->vn_version);
11203 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11204 ent.vn_file = BYTE_GET (entry->vn_file);
11205 ent.vn_aux = BYTE_GET (entry->vn_aux);
11206 ent.vn_next = BYTE_GET (entry->vn_next);
11207
452bf675 11208 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11209
978c4450
AM
11210 if (VALID_DYNAMIC_NAME (filedata, ent.vn_file))
11211 printf (_(" File: %s"),
11212 GET_DYNAMIC_NAME (filedata, ent.vn_file));
252b5132
RH
11213 else
11214 printf (_(" File: %lx"), ent.vn_file);
11215
11216 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11217
dd24e3da 11218 /* Check for overflow. */
7e26601c 11219 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11220 break;
252b5132
RH
11221 vstart += ent.vn_aux;
11222
11223 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11224 {
2cf0635d 11225 Elf_External_Vernaux * eaux;
b34976b6 11226 Elf_Internal_Vernaux aux;
252b5132 11227
54806181
AM
11228 if (vstart + sizeof (*eaux) > endbuf)
11229 break;
252b5132
RH
11230 eaux = (Elf_External_Vernaux *) vstart;
11231
11232 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11233 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11234 aux.vna_other = BYTE_GET (eaux->vna_other);
11235 aux.vna_name = BYTE_GET (eaux->vna_name);
11236 aux.vna_next = BYTE_GET (eaux->vna_next);
11237
978c4450 11238 if (VALID_DYNAMIC_NAME (filedata, aux.vna_name))
452bf675 11239 printf (_(" %#06lx: Name: %s"),
978c4450 11240 isum, GET_DYNAMIC_NAME (filedata, aux.vna_name));
252b5132 11241 else
452bf675 11242 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11243 isum, aux.vna_name);
11244
11245 printf (_(" Flags: %s Version: %d\n"),
11246 get_ver_flags (aux.vna_flags), aux.vna_other);
11247
1445030f
AM
11248 if (aux.vna_next < sizeof (*eaux)
11249 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11250 {
11251 warn (_("Invalid vna_next field of %lx\n"),
11252 aux.vna_next);
11253 j = ent.vn_cnt;
11254 break;
11255 }
1445030f
AM
11256 /* Check for overflow. */
11257 if (aux.vna_next > (size_t) (endbuf - vstart))
11258 break;
252b5132
RH
11259 isum += aux.vna_next;
11260 vstart += aux.vna_next;
11261 }
9cf03b7e 11262
54806181 11263 if (j < ent.vn_cnt)
9cf03b7e 11264 warn (_("Missing Version Needs auxillary information\n"));
252b5132 11265
1445030f
AM
11266 if (ent.vn_next < sizeof (*entry)
11267 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11268 {
452bf675 11269 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11270 cnt = section->sh_info;
11271 break;
11272 }
1445030f
AM
11273 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11274 break;
252b5132
RH
11275 idx += ent.vn_next;
11276 }
9cf03b7e 11277
54806181 11278 if (cnt < section->sh_info)
9cf03b7e 11279 warn (_("Missing Version Needs information\n"));
103f02d3 11280
252b5132
RH
11281 free (eneed);
11282 }
11283 break;
11284
11285 case SHT_GNU_versym:
11286 {
2cf0635d 11287 Elf_Internal_Shdr * link_section;
8b73c356
NC
11288 size_t total;
11289 unsigned int cnt;
2cf0635d
NC
11290 unsigned char * edata;
11291 unsigned short * data;
11292 char * strtab;
11293 Elf_Internal_Sym * symbols;
11294 Elf_Internal_Shdr * string_sec;
ba5cdace 11295 unsigned long num_syms;
d3ba0551 11296 long off;
252b5132 11297
dda8d76d 11298 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11299 break;
11300
dda8d76d 11301 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11302 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11303
dda8d76d 11304 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11305 break;
11306
32ec8896 11307 found = TRUE;
252b5132 11308
dda8d76d 11309 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
11310 if (symbols == NULL)
11311 break;
252b5132 11312
dda8d76d 11313 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11314
dda8d76d 11315 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11316 string_sec->sh_size,
11317 _("version string table"));
a6e9f9df 11318 if (!strtab)
0429c154
MS
11319 {
11320 free (symbols);
11321 break;
11322 }
252b5132 11323
d3a49aa8
AM
11324 printf (ngettext ("\nVersion symbols section '%s' "
11325 "contains %lu entry:\n",
11326 "\nVersion symbols section '%s' "
11327 "contains %lu entries:\n",
11328 total),
dda8d76d 11329 printable_section_name (filedata, section), (unsigned long) total);
252b5132 11330
ae9ac79e 11331 printf (_(" Addr: 0x"));
252b5132 11332 printf_vma (section->sh_addr);
72de5009 11333 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11334 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11335 printable_section_name (filedata, link_section));
252b5132 11336
dda8d76d 11337 off = offset_from_vma (filedata,
978c4450 11338 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11339 total * sizeof (short));
95099889
AM
11340 edata = (unsigned char *) get_data (NULL, filedata, off,
11341 sizeof (short), total,
11342 _("version symbol data"));
a6e9f9df
AM
11343 if (!edata)
11344 {
11345 free (strtab);
0429c154 11346 free (symbols);
a6e9f9df
AM
11347 break;
11348 }
252b5132 11349
3f5e193b 11350 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11351
11352 for (cnt = total; cnt --;)
b34976b6
AM
11353 data[cnt] = byte_get (edata + cnt * sizeof (short),
11354 sizeof (short));
252b5132
RH
11355
11356 free (edata);
11357
11358 for (cnt = 0; cnt < total; cnt += 4)
11359 {
11360 int j, nn;
ab273396
AM
11361 char *name;
11362 char *invalid = _("*invalid*");
252b5132
RH
11363
11364 printf (" %03x:", cnt);
11365
11366 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11367 switch (data[cnt + j])
252b5132
RH
11368 {
11369 case 0:
11370 fputs (_(" 0 (*local*) "), stdout);
11371 break;
11372
11373 case 1:
11374 fputs (_(" 1 (*global*) "), stdout);
11375 break;
11376
11377 default:
c244d050
NC
11378 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11379 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11380
dd24e3da 11381 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11382 array, break to avoid an out-of-bounds read. */
11383 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11384 {
11385 warn (_("invalid index into symbol array\n"));
11386 break;
11387 }
11388
ab273396 11389 name = NULL;
978c4450 11390 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11391 {
b34976b6
AM
11392 Elf_Internal_Verneed ivn;
11393 unsigned long offset;
252b5132 11394
d93f0186 11395 offset = offset_from_vma
978c4450
AM
11396 (filedata,
11397 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11398 sizeof (Elf_External_Verneed));
252b5132 11399
b34976b6 11400 do
252b5132 11401 {
b34976b6
AM
11402 Elf_Internal_Vernaux ivna;
11403 Elf_External_Verneed evn;
11404 Elf_External_Vernaux evna;
11405 unsigned long a_off;
252b5132 11406
dda8d76d 11407 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11408 _("version need")) == NULL)
11409 break;
0b4362b0 11410
252b5132
RH
11411 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11412 ivn.vn_next = BYTE_GET (evn.vn_next);
11413
11414 a_off = offset + ivn.vn_aux;
11415
11416 do
11417 {
dda8d76d 11418 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11419 1, _("version need aux (2)")) == NULL)
11420 {
11421 ivna.vna_next = 0;
11422 ivna.vna_other = 0;
11423 }
11424 else
11425 {
11426 ivna.vna_next = BYTE_GET (evna.vna_next);
11427 ivna.vna_other = BYTE_GET (evna.vna_other);
11428 }
252b5132
RH
11429
11430 a_off += ivna.vna_next;
11431 }
b34976b6 11432 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11433 && ivna.vna_next != 0);
11434
b34976b6 11435 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11436 {
11437 ivna.vna_name = BYTE_GET (evna.vna_name);
11438
54806181 11439 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11440 name = invalid;
54806181
AM
11441 else
11442 name = strtab + ivna.vna_name;
252b5132
RH
11443 break;
11444 }
11445
11446 offset += ivn.vn_next;
11447 }
11448 while (ivn.vn_next);
11449 }
00d93f34 11450
ab273396 11451 if (data[cnt + j] != 0x8001
978c4450 11452 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 11453 {
b34976b6
AM
11454 Elf_Internal_Verdef ivd;
11455 Elf_External_Verdef evd;
11456 unsigned long offset;
252b5132 11457
d93f0186 11458 offset = offset_from_vma
978c4450
AM
11459 (filedata,
11460 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 11461 sizeof evd);
252b5132
RH
11462
11463 do
11464 {
dda8d76d 11465 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
11466 _("version def")) == NULL)
11467 {
11468 ivd.vd_next = 0;
948f632f 11469 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
11470 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
11471 break;
59245841
NC
11472 }
11473 else
11474 {
11475 ivd.vd_next = BYTE_GET (evd.vd_next);
11476 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11477 }
252b5132
RH
11478
11479 offset += ivd.vd_next;
11480 }
c244d050 11481 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
11482 && ivd.vd_next != 0);
11483
c244d050 11484 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 11485 {
b34976b6
AM
11486 Elf_External_Verdaux evda;
11487 Elf_Internal_Verdaux ivda;
252b5132
RH
11488
11489 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11490
dda8d76d 11491 if (get_data (&evda, filedata,
59245841
NC
11492 offset - ivd.vd_next + ivd.vd_aux,
11493 sizeof (evda), 1,
11494 _("version def aux")) == NULL)
11495 break;
252b5132
RH
11496
11497 ivda.vda_name = BYTE_GET (evda.vda_name);
11498
54806181 11499 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
11500 name = invalid;
11501 else if (name != NULL && name != invalid)
11502 name = _("*both*");
54806181
AM
11503 else
11504 name = strtab + ivda.vda_name;
252b5132
RH
11505 }
11506 }
ab273396
AM
11507 if (name != NULL)
11508 nn += printf ("(%s%-*s",
11509 name,
11510 12 - (int) strlen (name),
11511 ")");
252b5132
RH
11512
11513 if (nn < 18)
11514 printf ("%*c", 18 - nn, ' ');
11515 }
11516
11517 putchar ('\n');
11518 }
11519
11520 free (data);
11521 free (strtab);
11522 free (symbols);
11523 }
11524 break;
103f02d3 11525
252b5132
RH
11526 default:
11527 break;
11528 }
11529 }
11530
11531 if (! found)
11532 printf (_("\nNo version information found in this file.\n"));
11533
32ec8896 11534 return TRUE;
252b5132
RH
11535}
11536
d1133906 11537static const char *
dda8d76d 11538get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 11539{
89246a0e 11540 static char buff[64];
252b5132
RH
11541
11542 switch (binding)
11543 {
b34976b6
AM
11544 case STB_LOCAL: return "LOCAL";
11545 case STB_GLOBAL: return "GLOBAL";
11546 case STB_WEAK: return "WEAK";
252b5132
RH
11547 default:
11548 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
11549 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
11550 binding);
252b5132 11551 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
11552 {
11553 if (binding == STB_GNU_UNIQUE
df3a023b 11554 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
11555 return "UNIQUE";
11556 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
11557 }
252b5132 11558 else
e9e44622 11559 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
11560 return buff;
11561 }
11562}
11563
d1133906 11564static const char *
dda8d76d 11565get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 11566{
89246a0e 11567 static char buff[64];
252b5132
RH
11568
11569 switch (type)
11570 {
b34976b6
AM
11571 case STT_NOTYPE: return "NOTYPE";
11572 case STT_OBJECT: return "OBJECT";
11573 case STT_FUNC: return "FUNC";
11574 case STT_SECTION: return "SECTION";
11575 case STT_FILE: return "FILE";
11576 case STT_COMMON: return "COMMON";
11577 case STT_TLS: return "TLS";
15ab5209
DB
11578 case STT_RELC: return "RELC";
11579 case STT_SRELC: return "SRELC";
252b5132
RH
11580 default:
11581 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 11582 {
dda8d76d 11583 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 11584 return "THUMB_FUNC";
103f02d3 11585
dda8d76d 11586 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
11587 return "REGISTER";
11588
dda8d76d 11589 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
11590 return "PARISC_MILLI";
11591
e9e44622 11592 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 11593 }
252b5132 11594 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 11595 {
dda8d76d 11596 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
11597 {
11598 if (type == STT_HP_OPAQUE)
11599 return "HP_OPAQUE";
11600 if (type == STT_HP_STUB)
11601 return "HP_STUB";
11602 }
11603
d8045f23 11604 if (type == STT_GNU_IFUNC
dda8d76d 11605 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 11606 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
11607 return "IFUNC";
11608
e9e44622 11609 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 11610 }
252b5132 11611 else
e9e44622 11612 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
11613 return buff;
11614 }
11615}
11616
d1133906 11617static const char *
d3ba0551 11618get_symbol_visibility (unsigned int visibility)
d1133906
NC
11619{
11620 switch (visibility)
11621 {
b34976b6
AM
11622 case STV_DEFAULT: return "DEFAULT";
11623 case STV_INTERNAL: return "INTERNAL";
11624 case STV_HIDDEN: return "HIDDEN";
d1133906 11625 case STV_PROTECTED: return "PROTECTED";
bee0ee85 11626 default:
27a45f42 11627 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 11628 return _("<unknown>");
d1133906
NC
11629 }
11630}
11631
2057d69d
CZ
11632static const char *
11633get_alpha_symbol_other (unsigned int other)
9abca702 11634{
2057d69d
CZ
11635 switch (other)
11636 {
11637 case STO_ALPHA_NOPV: return "NOPV";
11638 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
11639 default:
27a45f42 11640 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 11641 return _("<unknown>");
9abca702 11642 }
2057d69d
CZ
11643}
11644
fd85a6a1
NC
11645static const char *
11646get_solaris_symbol_visibility (unsigned int visibility)
11647{
11648 switch (visibility)
11649 {
11650 case 4: return "EXPORTED";
11651 case 5: return "SINGLETON";
11652 case 6: return "ELIMINATE";
11653 default: return get_symbol_visibility (visibility);
11654 }
11655}
11656
2301ed1c
SN
11657static const char *
11658get_aarch64_symbol_other (unsigned int other)
11659{
11660 static char buf[32];
11661
11662 if (other & STO_AARCH64_VARIANT_PCS)
11663 {
11664 other &= ~STO_AARCH64_VARIANT_PCS;
11665 if (other == 0)
11666 return "VARIANT_PCS";
11667 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
11668 return buf;
11669 }
11670 return NULL;
11671}
11672
5e2b0d47
NC
11673static const char *
11674get_mips_symbol_other (unsigned int other)
11675{
11676 switch (other)
11677 {
32ec8896
NC
11678 case STO_OPTIONAL: return "OPTIONAL";
11679 case STO_MIPS_PLT: return "MIPS PLT";
11680 case STO_MIPS_PIC: return "MIPS PIC";
11681 case STO_MICROMIPS: return "MICROMIPS";
11682 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
11683 case STO_MIPS16: return "MIPS16";
11684 default: return NULL;
5e2b0d47
NC
11685 }
11686}
11687
28f997cf 11688static const char *
dda8d76d 11689get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 11690{
dda8d76d 11691 if (is_ia64_vms (filedata))
28f997cf
TG
11692 {
11693 static char res[32];
11694
11695 res[0] = 0;
11696
11697 /* Function types is for images and .STB files only. */
dda8d76d 11698 switch (filedata->file_header.e_type)
28f997cf
TG
11699 {
11700 case ET_DYN:
11701 case ET_EXEC:
11702 switch (VMS_ST_FUNC_TYPE (other))
11703 {
11704 case VMS_SFT_CODE_ADDR:
11705 strcat (res, " CA");
11706 break;
11707 case VMS_SFT_SYMV_IDX:
11708 strcat (res, " VEC");
11709 break;
11710 case VMS_SFT_FD:
11711 strcat (res, " FD");
11712 break;
11713 case VMS_SFT_RESERVE:
11714 strcat (res, " RSV");
11715 break;
11716 default:
bee0ee85
NC
11717 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
11718 VMS_ST_FUNC_TYPE (other));
11719 strcat (res, " <unknown>");
11720 break;
28f997cf
TG
11721 }
11722 break;
11723 default:
11724 break;
11725 }
11726 switch (VMS_ST_LINKAGE (other))
11727 {
11728 case VMS_STL_IGNORE:
11729 strcat (res, " IGN");
11730 break;
11731 case VMS_STL_RESERVE:
11732 strcat (res, " RSV");
11733 break;
11734 case VMS_STL_STD:
11735 strcat (res, " STD");
11736 break;
11737 case VMS_STL_LNK:
11738 strcat (res, " LNK");
11739 break;
11740 default:
bee0ee85
NC
11741 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
11742 VMS_ST_LINKAGE (other));
11743 strcat (res, " <unknown>");
11744 break;
28f997cf
TG
11745 }
11746
11747 if (res[0] != 0)
11748 return res + 1;
11749 else
11750 return res;
11751 }
11752 return NULL;
11753}
11754
6911b7dc
AM
11755static const char *
11756get_ppc64_symbol_other (unsigned int other)
11757{
14732552
AM
11758 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
11759 return NULL;
11760
11761 other >>= STO_PPC64_LOCAL_BIT;
11762 if (other <= 6)
6911b7dc 11763 {
89246a0e 11764 static char buf[64];
14732552
AM
11765 if (other >= 2)
11766 other = ppc64_decode_local_entry (other);
11767 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
11768 return buf;
11769 }
11770 return NULL;
11771}
11772
5e2b0d47 11773static const char *
dda8d76d 11774get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
11775{
11776 const char * result = NULL;
89246a0e 11777 static char buff [64];
5e2b0d47
NC
11778
11779 if (other == 0)
11780 return "";
11781
dda8d76d 11782 switch (filedata->file_header.e_machine)
5e2b0d47 11783 {
2057d69d
CZ
11784 case EM_ALPHA:
11785 result = get_alpha_symbol_other (other);
11786 break;
2301ed1c
SN
11787 case EM_AARCH64:
11788 result = get_aarch64_symbol_other (other);
11789 break;
5e2b0d47
NC
11790 case EM_MIPS:
11791 result = get_mips_symbol_other (other);
28f997cf
TG
11792 break;
11793 case EM_IA_64:
dda8d76d 11794 result = get_ia64_symbol_other (filedata, other);
28f997cf 11795 break;
6911b7dc
AM
11796 case EM_PPC64:
11797 result = get_ppc64_symbol_other (other);
11798 break;
5e2b0d47 11799 default:
fd85a6a1 11800 result = NULL;
5e2b0d47
NC
11801 break;
11802 }
11803
11804 if (result)
11805 return result;
11806
11807 snprintf (buff, sizeof buff, _("<other>: %x"), other);
11808 return buff;
11809}
11810
d1133906 11811static const char *
dda8d76d 11812get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 11813{
b34976b6 11814 static char buff[32];
5cf1065c 11815
252b5132
RH
11816 switch (type)
11817 {
b34976b6
AM
11818 case SHN_UNDEF: return "UND";
11819 case SHN_ABS: return "ABS";
11820 case SHN_COMMON: return "COM";
252b5132 11821 default:
9ce701e2 11822 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
11823 && filedata->file_header.e_machine == EM_IA_64
11824 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
11825 return "ANSI_COM";
11826 else if ((filedata->file_header.e_machine == EM_X86_64
11827 || filedata->file_header.e_machine == EM_L1OM
11828 || filedata->file_header.e_machine == EM_K1OM)
11829 && type == SHN_X86_64_LCOMMON)
11830 return "LARGE_COM";
11831 else if ((type == SHN_MIPS_SCOMMON
11832 && filedata->file_header.e_machine == EM_MIPS)
11833 || (type == SHN_TIC6X_SCOMMON
11834 && filedata->file_header.e_machine == EM_TI_C6000))
11835 return "SCOM";
11836 else if (type == SHN_MIPS_SUNDEFINED
11837 && filedata->file_header.e_machine == EM_MIPS)
11838 return "SUND";
11839 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
11840 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
11841 else if (type >= SHN_LOOS && type <= SHN_HIOS)
11842 sprintf (buff, "OS [0x%04x]", type & 0xffff);
11843 else if (type >= SHN_LORESERVE)
11844 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
11845 else if (filedata->file_header.e_shnum != 0
11846 && type >= filedata->file_header.e_shnum)
11847 sprintf (buff, _("bad section index[%3d]"), type);
11848 else
11849 sprintf (buff, "%3d", type);
11850 break;
fd85a6a1
NC
11851 }
11852
10ca4b04 11853 return buff;
6bd1a22c
L
11854}
11855
bb4d2ac2 11856static const char *
dda8d76d 11857get_symbol_version_string (Filedata * filedata,
1449284b
NC
11858 bfd_boolean is_dynsym,
11859 const char * strtab,
11860 unsigned long int strtab_size,
11861 unsigned int si,
11862 Elf_Internal_Sym * psym,
11863 enum versioned_symbol_info * sym_info,
11864 unsigned short * vna_other)
bb4d2ac2 11865{
ab273396
AM
11866 unsigned char data[2];
11867 unsigned short vers_data;
11868 unsigned long offset;
7a815dd5 11869 unsigned short max_vd_ndx;
bb4d2ac2 11870
ab273396 11871 if (!is_dynsym
978c4450 11872 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 11873 return NULL;
bb4d2ac2 11874
978c4450
AM
11875 offset = offset_from_vma (filedata,
11876 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 11877 sizeof data + si * sizeof (vers_data));
bb4d2ac2 11878
dda8d76d 11879 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
11880 sizeof (data), 1, _("version data")) == NULL)
11881 return NULL;
11882
11883 vers_data = byte_get (data, 2);
bb4d2ac2 11884
1f6f5dba 11885 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 11886 return NULL;
bb4d2ac2 11887
0b8b7609 11888 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
11889 max_vd_ndx = 0;
11890
ab273396
AM
11891 /* Usually we'd only see verdef for defined symbols, and verneed for
11892 undefined symbols. However, symbols defined by the linker in
11893 .dynbss for variables copied from a shared library in order to
11894 avoid text relocations are defined yet have verneed. We could
11895 use a heuristic to detect the special case, for example, check
11896 for verneed first on symbols defined in SHT_NOBITS sections, but
11897 it is simpler and more reliable to just look for both verdef and
11898 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 11899
ab273396
AM
11900 if (psym->st_shndx != SHN_UNDEF
11901 && vers_data != 0x8001
978c4450 11902 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
11903 {
11904 Elf_Internal_Verdef ivd;
11905 Elf_Internal_Verdaux ivda;
11906 Elf_External_Verdaux evda;
11907 unsigned long off;
bb4d2ac2 11908
dda8d76d 11909 off = offset_from_vma (filedata,
978c4450 11910 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
11911 sizeof (Elf_External_Verdef));
11912
11913 do
bb4d2ac2 11914 {
ab273396
AM
11915 Elf_External_Verdef evd;
11916
dda8d76d 11917 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
11918 _("version def")) == NULL)
11919 {
11920 ivd.vd_ndx = 0;
11921 ivd.vd_aux = 0;
11922 ivd.vd_next = 0;
1f6f5dba 11923 ivd.vd_flags = 0;
ab273396
AM
11924 }
11925 else
bb4d2ac2 11926 {
ab273396
AM
11927 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11928 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11929 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 11930 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 11931 }
bb4d2ac2 11932
7a815dd5
L
11933 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
11934 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
11935
ab273396
AM
11936 off += ivd.vd_next;
11937 }
11938 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 11939
ab273396
AM
11940 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
11941 {
9abca702 11942 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
11943 return NULL;
11944
ab273396
AM
11945 off -= ivd.vd_next;
11946 off += ivd.vd_aux;
bb4d2ac2 11947
dda8d76d 11948 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
11949 _("version def aux")) != NULL)
11950 {
11951 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 11952
ab273396 11953 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
11954 return (ivda.vda_name < strtab_size
11955 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
11956 }
11957 }
11958 }
bb4d2ac2 11959
978c4450 11960 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
11961 {
11962 Elf_External_Verneed evn;
11963 Elf_Internal_Verneed ivn;
11964 Elf_Internal_Vernaux ivna;
bb4d2ac2 11965
dda8d76d 11966 offset = offset_from_vma (filedata,
978c4450 11967 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
11968 sizeof evn);
11969 do
11970 {
11971 unsigned long vna_off;
bb4d2ac2 11972
dda8d76d 11973 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
11974 _("version need")) == NULL)
11975 {
11976 ivna.vna_next = 0;
11977 ivna.vna_other = 0;
11978 ivna.vna_name = 0;
11979 break;
11980 }
bb4d2ac2 11981
ab273396
AM
11982 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11983 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 11984
ab273396 11985 vna_off = offset + ivn.vn_aux;
bb4d2ac2 11986
ab273396
AM
11987 do
11988 {
11989 Elf_External_Vernaux evna;
bb4d2ac2 11990
dda8d76d 11991 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 11992 _("version need aux (3)")) == NULL)
bb4d2ac2 11993 {
ab273396
AM
11994 ivna.vna_next = 0;
11995 ivna.vna_other = 0;
11996 ivna.vna_name = 0;
bb4d2ac2 11997 }
bb4d2ac2 11998 else
bb4d2ac2 11999 {
ab273396
AM
12000 ivna.vna_other = BYTE_GET (evna.vna_other);
12001 ivna.vna_next = BYTE_GET (evna.vna_next);
12002 ivna.vna_name = BYTE_GET (evna.vna_name);
12003 }
bb4d2ac2 12004
ab273396
AM
12005 vna_off += ivna.vna_next;
12006 }
12007 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12008
ab273396
AM
12009 if (ivna.vna_other == vers_data)
12010 break;
bb4d2ac2 12011
ab273396
AM
12012 offset += ivn.vn_next;
12013 }
12014 while (ivn.vn_next != 0);
bb4d2ac2 12015
ab273396
AM
12016 if (ivna.vna_other == vers_data)
12017 {
12018 *sym_info = symbol_undefined;
12019 *vna_other = ivna.vna_other;
12020 return (ivna.vna_name < strtab_size
12021 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12022 }
7a815dd5
L
12023 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12024 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12025 return _("<corrupt>");
bb4d2ac2 12026 }
ab273396 12027 return NULL;
bb4d2ac2
L
12028}
12029
10ca4b04
L
12030static void
12031print_dynamic_symbol (Filedata *filedata, unsigned long si,
12032 Elf_Internal_Sym *symtab,
12033 Elf_Internal_Shdr *section,
12034 char *strtab, size_t strtab_size)
252b5132 12035{
10ca4b04
L
12036 const char *version_string;
12037 enum versioned_symbol_info sym_info;
12038 unsigned short vna_other;
12039 Elf_Internal_Sym *psym = symtab + si;
252b5132 12040
10ca4b04
L
12041 printf ("%6ld: ", si);
12042 print_vma (psym->st_value, LONG_HEX);
12043 putchar (' ');
12044 print_vma (psym->st_size, DEC_5);
12045 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12046 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12047 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12048 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12049 else
252b5132 12050 {
10ca4b04 12051 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12052
10ca4b04
L
12053 printf (" %-7s", get_symbol_visibility (vis));
12054 /* Check to see if any other bits in the st_other field are set.
12055 Note - displaying this information disrupts the layout of the
12056 table being generated, but for the moment this case is very rare. */
12057 if (psym->st_other ^ vis)
12058 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12059 }
10ca4b04
L
12060 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
12061 print_symbol (25, VALID_SYMBOL_NAME (strtab, strtab_size,
12062 psym->st_name)
12063 ? strtab + psym->st_name : _("<corrupt>"));
12064
12065 version_string
12066 = get_symbol_version_string (filedata,
12067 (section == NULL
12068 || section->sh_type == SHT_DYNSYM),
12069 strtab, strtab_size, si,
12070 psym, &sym_info, &vna_other);
12071 if (version_string)
12072 {
12073 if (sym_info == symbol_undefined)
12074 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12075 else
10ca4b04
L
12076 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12077 version_string);
12078 }
6bd1a22c 12079
10ca4b04 12080 putchar ('\n');
6bd1a22c 12081
10ca4b04
L
12082 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12083 && section != NULL
12084 && si >= section->sh_info
12085 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12086 && filedata->file_header.e_machine != EM_MIPS
12087 /* Solaris binaries have been found to violate this requirement as
12088 well. Not sure if this is a bug or an ABI requirement. */
12089 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12090 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12091 si, printable_section_name (filedata, section), section->sh_info);
12092}
f16a9783 12093
10ca4b04
L
12094/* Dump the symbol table. */
12095static bfd_boolean
12096process_symbol_table (Filedata * filedata)
12097{
12098 Elf_Internal_Shdr * section;
f16a9783 12099
10ca4b04
L
12100 if (!do_syms && !do_dyn_syms && !do_histogram)
12101 return TRUE;
6bd1a22c 12102
978c4450 12103 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
12104 && do_syms
12105 && do_using_dynamic
978c4450
AM
12106 && filedata->dynamic_strings != NULL
12107 && filedata->dynamic_symbols != NULL)
6bd1a22c 12108 {
10ca4b04 12109 unsigned long si;
6bd1a22c 12110
10ca4b04
L
12111 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12112 "\nSymbol table for image contains %lu entries:\n",
978c4450
AM
12113 filedata->num_dynamic_syms),
12114 filedata->num_dynamic_syms);
10ca4b04
L
12115 if (is_32bit_elf)
12116 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12117 else
12118 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12119
978c4450
AM
12120 for (si = 0; si < filedata->num_dynamic_syms; si++)
12121 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
12122 filedata->dynamic_strings,
12123 filedata->dynamic_strings_length);
252b5132 12124 }
8b73c356 12125 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 12126 && filedata->section_headers != NULL)
252b5132 12127 {
b34976b6 12128 unsigned int i;
252b5132 12129
dda8d76d
NC
12130 for (i = 0, section = filedata->section_headers;
12131 i < filedata->file_header.e_shnum;
252b5132
RH
12132 i++, section++)
12133 {
2cf0635d 12134 char * strtab = NULL;
c256ffe7 12135 unsigned long int strtab_size = 0;
2cf0635d 12136 Elf_Internal_Sym * symtab;
ef3df110 12137 unsigned long si, num_syms;
252b5132 12138
2c610e4b
L
12139 if ((section->sh_type != SHT_SYMTAB
12140 && section->sh_type != SHT_DYNSYM)
12141 || (!do_syms
12142 && section->sh_type == SHT_SYMTAB))
252b5132
RH
12143 continue;
12144
dd24e3da
NC
12145 if (section->sh_entsize == 0)
12146 {
12147 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 12148 printable_section_name (filedata, section));
dd24e3da
NC
12149 continue;
12150 }
12151
d3a49aa8
AM
12152 num_syms = section->sh_size / section->sh_entsize;
12153 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
12154 "\nSymbol table '%s' contains %lu entries:\n",
12155 num_syms),
dda8d76d 12156 printable_section_name (filedata, section),
d3a49aa8 12157 num_syms);
dd24e3da 12158
f7a99963 12159 if (is_32bit_elf)
ca47b30c 12160 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 12161 else
ca47b30c 12162 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 12163
dda8d76d 12164 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
12165 if (symtab == NULL)
12166 continue;
12167
dda8d76d 12168 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 12169 {
dda8d76d
NC
12170 strtab = filedata->string_table;
12171 strtab_size = filedata->string_table_length;
c256ffe7 12172 }
dda8d76d 12173 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 12174 {
2cf0635d 12175 Elf_Internal_Shdr * string_sec;
252b5132 12176
dda8d76d 12177 string_sec = filedata->section_headers + section->sh_link;
252b5132 12178
dda8d76d 12179 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
12180 1, string_sec->sh_size,
12181 _("string table"));
c256ffe7 12182 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
12183 }
12184
10ca4b04
L
12185 for (si = 0; si < num_syms; si++)
12186 print_dynamic_symbol (filedata, si, symtab, section,
12187 strtab, strtab_size);
252b5132
RH
12188
12189 free (symtab);
dda8d76d 12190 if (strtab != filedata->string_table)
252b5132
RH
12191 free (strtab);
12192 }
12193 }
12194 else if (do_syms)
12195 printf
12196 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
12197
978c4450 12198 if (do_histogram && filedata->buckets != NULL)
252b5132 12199 {
2cf0635d
NC
12200 unsigned long * lengths;
12201 unsigned long * counts;
66543521
AM
12202 unsigned long hn;
12203 bfd_vma si;
12204 unsigned long maxlength = 0;
12205 unsigned long nzero_counts = 0;
12206 unsigned long nsyms = 0;
6bd6a03d 12207 char *visited;
252b5132 12208
d3a49aa8
AM
12209 printf (ngettext ("\nHistogram for bucket list length "
12210 "(total of %lu bucket):\n",
12211 "\nHistogram for bucket list length "
12212 "(total of %lu buckets):\n",
978c4450
AM
12213 (unsigned long) filedata->nbuckets),
12214 (unsigned long) filedata->nbuckets);
252b5132 12215
978c4450
AM
12216 lengths = (unsigned long *) calloc (filedata->nbuckets,
12217 sizeof (*lengths));
252b5132
RH
12218 if (lengths == NULL)
12219 {
8b73c356 12220 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 12221 goto err_out;
252b5132 12222 }
978c4450
AM
12223 visited = xcmalloc (filedata->nchains, 1);
12224 memset (visited, 0, filedata->nchains);
8b73c356
NC
12225
12226 printf (_(" Length Number %% of total Coverage\n"));
978c4450 12227 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 12228 {
978c4450 12229 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 12230 {
b34976b6 12231 ++nsyms;
252b5132 12232 if (maxlength < ++lengths[hn])
b34976b6 12233 ++maxlength;
978c4450 12234 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
12235 {
12236 error (_("histogram chain is corrupt\n"));
12237 break;
12238 }
12239 visited[si] = 1;
252b5132
RH
12240 }
12241 }
6bd6a03d 12242 free (visited);
252b5132 12243
3f5e193b 12244 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
12245 if (counts == NULL)
12246 {
b2e951ec 12247 free (lengths);
8b73c356 12248 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 12249 goto err_out;
252b5132
RH
12250 }
12251
978c4450 12252 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 12253 ++counts[lengths[hn]];
252b5132 12254
978c4450 12255 if (filedata->nbuckets > 0)
252b5132 12256 {
66543521
AM
12257 unsigned long i;
12258 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12259 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 12260 for (i = 1; i <= maxlength; ++i)
103f02d3 12261 {
66543521
AM
12262 nzero_counts += counts[i] * i;
12263 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12264 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
12265 (nzero_counts * 100.0) / nsyms);
12266 }
252b5132
RH
12267 }
12268
12269 free (counts);
12270 free (lengths);
12271 }
12272
978c4450
AM
12273 free (filedata->buckets);
12274 filedata->buckets = NULL;
12275 filedata->nbuckets = 0;
12276 free (filedata->chains);
12277 filedata->chains = NULL;
252b5132 12278
978c4450 12279 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 12280 {
2cf0635d
NC
12281 unsigned long * lengths;
12282 unsigned long * counts;
fdc90cb4
JJ
12283 unsigned long hn;
12284 unsigned long maxlength = 0;
12285 unsigned long nzero_counts = 0;
12286 unsigned long nsyms = 0;
fdc90cb4 12287
f16a9783 12288 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 12289 "(total of %lu bucket):\n",
f16a9783 12290 "\nHistogram for `%s' bucket list length "
d3a49aa8 12291 "(total of %lu buckets):\n",
978c4450
AM
12292 (unsigned long) filedata->ngnubuckets),
12293 GNU_HASH_SECTION_NAME (filedata),
12294 (unsigned long) filedata->ngnubuckets);
8b73c356 12295
978c4450
AM
12296 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
12297 sizeof (*lengths));
fdc90cb4
JJ
12298 if (lengths == NULL)
12299 {
8b73c356 12300 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 12301 goto err_out;
fdc90cb4
JJ
12302 }
12303
fdc90cb4
JJ
12304 printf (_(" Length Number %% of total Coverage\n"));
12305
978c4450
AM
12306 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
12307 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
12308 {
12309 bfd_vma off, length = 1;
12310
978c4450 12311 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 12312 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
12313 off < filedata->ngnuchains
12314 && (filedata->gnuchains[off] & 1) == 0;
071436c6 12315 ++off)
fdc90cb4
JJ
12316 ++length;
12317 lengths[hn] = length;
12318 if (length > maxlength)
12319 maxlength = length;
12320 nsyms += length;
12321 }
12322
3f5e193b 12323 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
12324 if (counts == NULL)
12325 {
b2e951ec 12326 free (lengths);
8b73c356 12327 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 12328 goto err_out;
fdc90cb4
JJ
12329 }
12330
978c4450 12331 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
12332 ++counts[lengths[hn]];
12333
978c4450 12334 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
12335 {
12336 unsigned long j;
12337 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12338 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
12339 for (j = 1; j <= maxlength; ++j)
12340 {
12341 nzero_counts += counts[j] * j;
12342 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12343 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
12344 (nzero_counts * 100.0) / nsyms);
12345 }
12346 }
12347
12348 free (counts);
12349 free (lengths);
fdc90cb4 12350 }
978c4450
AM
12351 free (filedata->gnubuckets);
12352 filedata->gnubuckets = NULL;
12353 filedata->ngnubuckets = 0;
12354 free (filedata->gnuchains);
12355 filedata->gnuchains = NULL;
12356 filedata->ngnuchains = 0;
12357 free (filedata->mipsxlat);
12358 filedata->mipsxlat = NULL;
32ec8896 12359 return TRUE;
fd486f32
AM
12360
12361 err_out:
978c4450
AM
12362 free (filedata->gnubuckets);
12363 filedata->gnubuckets = NULL;
12364 filedata->ngnubuckets = 0;
12365 free (filedata->gnuchains);
12366 filedata->gnuchains = NULL;
12367 filedata->ngnuchains = 0;
12368 free (filedata->mipsxlat);
12369 filedata->mipsxlat = NULL;
12370 free (filedata->buckets);
12371 filedata->buckets = NULL;
12372 filedata->nbuckets = 0;
12373 free (filedata->chains);
12374 filedata->chains = NULL;
fd486f32 12375 return FALSE;
252b5132
RH
12376}
12377
32ec8896 12378static bfd_boolean
dda8d76d 12379process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
252b5132 12380{
b4c96d0d 12381 unsigned int i;
252b5132 12382
978c4450 12383 if (filedata->dynamic_syminfo == NULL
252b5132
RH
12384 || !do_dynamic)
12385 /* No syminfo, this is ok. */
32ec8896 12386 return TRUE;
252b5132
RH
12387
12388 /* There better should be a dynamic symbol section. */
978c4450 12389 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
32ec8896 12390 return FALSE;
252b5132 12391
978c4450 12392 if (filedata->dynamic_addr)
d3a49aa8
AM
12393 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
12394 "contains %d entry:\n",
12395 "\nDynamic info segment at offset 0x%lx "
12396 "contains %d entries:\n",
978c4450
AM
12397 filedata->dynamic_syminfo_nent),
12398 filedata->dynamic_syminfo_offset, filedata->dynamic_syminfo_nent);
252b5132
RH
12399
12400 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 12401 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 12402 {
978c4450 12403 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 12404
31104126 12405 printf ("%4d: ", i);
978c4450 12406 if (i >= filedata->num_dynamic_syms)
4082ef84 12407 printf (_("<corrupt index>"));
978c4450
AM
12408 else if (VALID_DYNAMIC_NAME (filedata, filedata->dynamic_symbols[i].st_name))
12409 print_symbol (30, GET_DYNAMIC_NAME (filedata,
12410 filedata->dynamic_symbols[i].st_name));
d79b3d50 12411 else
978c4450 12412 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 12413 putchar (' ');
252b5132 12414
978c4450 12415 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
12416 {
12417 case SYMINFO_BT_SELF:
12418 fputs ("SELF ", stdout);
12419 break;
12420 case SYMINFO_BT_PARENT:
12421 fputs ("PARENT ", stdout);
12422 break;
12423 default:
978c4450
AM
12424 if (filedata->dynamic_syminfo[i].si_boundto > 0
12425 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
12426 && VALID_DYNAMIC_NAME (filedata,
12427 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 12428 {
978c4450
AM
12429 print_symbol (10, GET_DYNAMIC_NAME (filedata,
12430 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
12431 putchar (' ' );
12432 }
252b5132 12433 else
978c4450 12434 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
12435 break;
12436 }
12437
12438 if (flags & SYMINFO_FLG_DIRECT)
12439 printf (" DIRECT");
12440 if (flags & SYMINFO_FLG_PASSTHRU)
12441 printf (" PASSTHRU");
12442 if (flags & SYMINFO_FLG_COPY)
12443 printf (" COPY");
12444 if (flags & SYMINFO_FLG_LAZYLOAD)
12445 printf (" LAZYLOAD");
12446
12447 puts ("");
12448 }
12449
32ec8896 12450 return TRUE;
252b5132
RH
12451}
12452
75802ccb
CE
12453/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
12454 is contained by the region START .. END. The types of ADDR, START
12455 and END should all be the same. Note both ADDR + NELEM and END
12456 point to just beyond the end of the regions that are being tested. */
12457#define IN_RANGE(START,END,ADDR,NELEM) \
12458 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 12459
cf13d699
NC
12460/* Check to see if the given reloc needs to be handled in a target specific
12461 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
12462 FALSE.
12463
12464 If called with reloc == NULL, then this is a signal that reloc processing
12465 for the current section has finished, and any saved state should be
12466 discarded. */
09c11c86 12467
cf13d699 12468static bfd_boolean
dda8d76d
NC
12469target_specific_reloc_handling (Filedata * filedata,
12470 Elf_Internal_Rela * reloc,
12471 unsigned char * start,
12472 unsigned char * end,
12473 Elf_Internal_Sym * symtab,
12474 unsigned long num_syms)
252b5132 12475{
f84ce13b
NC
12476 unsigned int reloc_type = 0;
12477 unsigned long sym_index = 0;
12478
12479 if (reloc)
12480 {
dda8d76d 12481 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
12482 sym_index = get_reloc_symindex (reloc->r_info);
12483 }
252b5132 12484
dda8d76d 12485 switch (filedata->file_header.e_machine)
252b5132 12486 {
13761a11
NC
12487 case EM_MSP430:
12488 case EM_MSP430_OLD:
12489 {
12490 static Elf_Internal_Sym * saved_sym = NULL;
12491
f84ce13b
NC
12492 if (reloc == NULL)
12493 {
12494 saved_sym = NULL;
12495 return TRUE;
12496 }
12497
13761a11
NC
12498 switch (reloc_type)
12499 {
12500 case 10: /* R_MSP430_SYM_DIFF */
dda8d76d 12501 if (uses_msp430x_relocs (filedata))
13761a11 12502 break;
1a0670f3 12503 /* Fall through. */
13761a11 12504 case 21: /* R_MSP430X_SYM_DIFF */
f84ce13b
NC
12505 /* PR 21139. */
12506 if (sym_index >= num_syms)
12507 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
12508 sym_index);
12509 else
12510 saved_sym = symtab + sym_index;
13761a11
NC
12511 return TRUE;
12512
12513 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
12514 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
12515 goto handle_sym_diff;
0b4362b0 12516
13761a11
NC
12517 case 5: /* R_MSP430_16_BYTE */
12518 case 9: /* R_MSP430_8 */
dda8d76d 12519 if (uses_msp430x_relocs (filedata))
13761a11
NC
12520 break;
12521 goto handle_sym_diff;
12522
12523 case 2: /* R_MSP430_ABS16 */
12524 case 15: /* R_MSP430X_ABS16 */
dda8d76d 12525 if (! uses_msp430x_relocs (filedata))
13761a11
NC
12526 break;
12527 goto handle_sym_diff;
0b4362b0 12528
13761a11
NC
12529 handle_sym_diff:
12530 if (saved_sym != NULL)
12531 {
03f7786e 12532 int reloc_size = reloc_type == 1 ? 4 : 2;
13761a11
NC
12533 bfd_vma value;
12534
f84ce13b
NC
12535 if (sym_index >= num_syms)
12536 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
12537 sym_index);
03f7786e 12538 else
f84ce13b
NC
12539 {
12540 value = reloc->r_addend + (symtab[sym_index].st_value
12541 - saved_sym->st_value);
12542
b32e566b 12543 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12544 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12545 else
12546 /* PR 21137 */
12547 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
12548 (long) reloc->r_offset);
f84ce13b 12549 }
13761a11
NC
12550
12551 saved_sym = NULL;
12552 return TRUE;
12553 }
12554 break;
12555
12556 default:
12557 if (saved_sym != NULL)
071436c6 12558 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
12559 break;
12560 }
12561 break;
12562 }
12563
cf13d699
NC
12564 case EM_MN10300:
12565 case EM_CYGNUS_MN10300:
12566 {
12567 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 12568
f84ce13b
NC
12569 if (reloc == NULL)
12570 {
12571 saved_sym = NULL;
12572 return TRUE;
12573 }
12574
cf13d699
NC
12575 switch (reloc_type)
12576 {
12577 case 34: /* R_MN10300_ALIGN */
12578 return TRUE;
12579 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
12580 if (sym_index >= num_syms)
12581 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
12582 sym_index);
12583 else
12584 saved_sym = symtab + sym_index;
cf13d699 12585 return TRUE;
f84ce13b 12586
cf13d699
NC
12587 case 1: /* R_MN10300_32 */
12588 case 2: /* R_MN10300_16 */
12589 if (saved_sym != NULL)
12590 {
03f7786e 12591 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 12592 bfd_vma value;
252b5132 12593
f84ce13b
NC
12594 if (sym_index >= num_syms)
12595 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
12596 sym_index);
03f7786e 12597 else
f84ce13b
NC
12598 {
12599 value = reloc->r_addend + (symtab[sym_index].st_value
12600 - saved_sym->st_value);
12601
b32e566b 12602 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12603 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12604 else
12605 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
12606 (long) reloc->r_offset);
f84ce13b 12607 }
252b5132 12608
cf13d699
NC
12609 saved_sym = NULL;
12610 return TRUE;
12611 }
12612 break;
12613 default:
12614 if (saved_sym != NULL)
071436c6 12615 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
12616 break;
12617 }
12618 break;
12619 }
6ff71e76
NC
12620
12621 case EM_RL78:
12622 {
12623 static bfd_vma saved_sym1 = 0;
12624 static bfd_vma saved_sym2 = 0;
12625 static bfd_vma value;
12626
f84ce13b
NC
12627 if (reloc == NULL)
12628 {
12629 saved_sym1 = saved_sym2 = 0;
12630 return TRUE;
12631 }
12632
6ff71e76
NC
12633 switch (reloc_type)
12634 {
12635 case 0x80: /* R_RL78_SYM. */
12636 saved_sym1 = saved_sym2;
f84ce13b
NC
12637 if (sym_index >= num_syms)
12638 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
12639 sym_index);
12640 else
12641 {
12642 saved_sym2 = symtab[sym_index].st_value;
12643 saved_sym2 += reloc->r_addend;
12644 }
6ff71e76
NC
12645 return TRUE;
12646
12647 case 0x83: /* R_RL78_OPsub. */
12648 value = saved_sym1 - saved_sym2;
12649 saved_sym2 = saved_sym1 = 0;
12650 return TRUE;
12651 break;
12652
12653 case 0x41: /* R_RL78_ABS32. */
b32e566b 12654 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 12655 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
12656 else
12657 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12658 (long) reloc->r_offset);
6ff71e76
NC
12659 value = 0;
12660 return TRUE;
12661
12662 case 0x43: /* R_RL78_ABS16. */
b32e566b 12663 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 12664 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
12665 else
12666 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12667 (long) reloc->r_offset);
6ff71e76
NC
12668 value = 0;
12669 return TRUE;
12670
12671 default:
12672 break;
12673 }
12674 break;
12675 }
252b5132
RH
12676 }
12677
cf13d699 12678 return FALSE;
252b5132
RH
12679}
12680
aca88567
NC
12681/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
12682 DWARF debug sections. This is a target specific test. Note - we do not
12683 go through the whole including-target-headers-multiple-times route, (as
12684 we have already done with <elf/h8.h>) because this would become very
12685 messy and even then this function would have to contain target specific
12686 information (the names of the relocs instead of their numeric values).
12687 FIXME: This is not the correct way to solve this problem. The proper way
12688 is to have target specific reloc sizing and typing functions created by
12689 the reloc-macros.h header, in the same way that it already creates the
12690 reloc naming functions. */
12691
12692static bfd_boolean
dda8d76d 12693is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12694{
d347c9df 12695 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12696 switch (filedata->file_header.e_machine)
aca88567 12697 {
41e92641 12698 case EM_386:
22abe556 12699 case EM_IAMCU:
41e92641 12700 return reloc_type == 1; /* R_386_32. */
aca88567
NC
12701 case EM_68K:
12702 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
12703 case EM_860:
12704 return reloc_type == 1; /* R_860_32. */
12705 case EM_960:
12706 return reloc_type == 2; /* R_960_32. */
a06ea964 12707 case EM_AARCH64:
9282b95a
JW
12708 return (reloc_type == 258
12709 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
12710 case EM_BPF:
12711 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
12712 case EM_ADAPTEVA_EPIPHANY:
12713 return reloc_type == 3;
aca88567 12714 case EM_ALPHA:
137b6b5f 12715 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
12716 case EM_ARC:
12717 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
12718 case EM_ARC_COMPACT:
12719 case EM_ARC_COMPACT2:
12720 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
12721 case EM_ARM:
12722 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 12723 case EM_AVR_OLD:
aca88567
NC
12724 case EM_AVR:
12725 return reloc_type == 1;
12726 case EM_BLACKFIN:
12727 return reloc_type == 0x12; /* R_byte4_data. */
12728 case EM_CRIS:
12729 return reloc_type == 3; /* R_CRIS_32. */
12730 case EM_CR16:
12731 return reloc_type == 3; /* R_CR16_NUM32. */
12732 case EM_CRX:
12733 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
12734 case EM_CSKY:
12735 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
12736 case EM_CYGNUS_FRV:
12737 return reloc_type == 1;
41e92641
NC
12738 case EM_CYGNUS_D10V:
12739 case EM_D10V:
12740 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
12741 case EM_CYGNUS_D30V:
12742 case EM_D30V:
12743 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
12744 case EM_DLX:
12745 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
12746 case EM_CYGNUS_FR30:
12747 case EM_FR30:
12748 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
12749 case EM_FT32:
12750 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
12751 case EM_H8S:
12752 case EM_H8_300:
12753 case EM_H8_300H:
12754 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 12755 case EM_IA_64:
262cdac7
AM
12756 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
12757 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
12758 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
12759 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
12760 case EM_IP2K_OLD:
12761 case EM_IP2K:
12762 return reloc_type == 2; /* R_IP2K_32. */
12763 case EM_IQ2000:
12764 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
12765 case EM_LATTICEMICO32:
12766 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 12767 case EM_M32C_OLD:
aca88567
NC
12768 case EM_M32C:
12769 return reloc_type == 3; /* R_M32C_32. */
12770 case EM_M32R:
12771 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
12772 case EM_68HC11:
12773 case EM_68HC12:
12774 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 12775 case EM_S12Z:
2849d19f
JD
12776 return reloc_type == 7 || /* R_S12Z_EXT32 */
12777 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
12778 case EM_MCORE:
12779 return reloc_type == 1; /* R_MCORE_ADDR32. */
12780 case EM_CYGNUS_MEP:
12781 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
12782 case EM_METAG:
12783 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
12784 case EM_MICROBLAZE:
12785 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
12786 case EM_MIPS:
12787 return reloc_type == 2; /* R_MIPS_32. */
12788 case EM_MMIX:
12789 return reloc_type == 4; /* R_MMIX_32. */
12790 case EM_CYGNUS_MN10200:
12791 case EM_MN10200:
12792 return reloc_type == 1; /* R_MN10200_32. */
12793 case EM_CYGNUS_MN10300:
12794 case EM_MN10300:
12795 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
12796 case EM_MOXIE:
12797 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
12798 case EM_MSP430_OLD:
12799 case EM_MSP430:
13761a11 12800 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
12801 case EM_MT:
12802 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
12803 case EM_NDS32:
12804 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 12805 case EM_ALTERA_NIOS2:
36591ba1 12806 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
12807 case EM_NIOS32:
12808 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
12809 case EM_OR1K:
12810 return reloc_type == 1; /* R_OR1K_32. */
aca88567 12811 case EM_PARISC:
9abca702 12812 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 12813 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 12814 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
12815 case EM_PJ:
12816 case EM_PJ_OLD:
12817 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
12818 case EM_PPC64:
12819 return reloc_type == 1; /* R_PPC64_ADDR32. */
12820 case EM_PPC:
12821 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
12822 case EM_TI_PRU:
12823 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
12824 case EM_RISCV:
12825 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
12826 case EM_RL78:
12827 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
12828 case EM_RX:
12829 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
12830 case EM_S370:
12831 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
12832 case EM_S390_OLD:
12833 case EM_S390:
12834 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
12835 case EM_SCORE:
12836 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
12837 case EM_SH:
12838 return reloc_type == 1; /* R_SH_DIR32. */
12839 case EM_SPARC32PLUS:
12840 case EM_SPARCV9:
12841 case EM_SPARC:
12842 return reloc_type == 3 /* R_SPARC_32. */
12843 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
12844 case EM_SPU:
12845 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
12846 case EM_TI_C6000:
12847 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
12848 case EM_TILEGX:
12849 return reloc_type == 2; /* R_TILEGX_32. */
12850 case EM_TILEPRO:
12851 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
12852 case EM_CYGNUS_V850:
12853 case EM_V850:
12854 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
12855 case EM_V800:
12856 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
12857 case EM_VAX:
12858 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
12859 case EM_VISIUM:
12860 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
12861 case EM_WEBASSEMBLY:
12862 return reloc_type == 1; /* R_WASM32_32. */
aca88567 12863 case EM_X86_64:
8a9036a4 12864 case EM_L1OM:
7a9068fe 12865 case EM_K1OM:
aca88567 12866 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
12867 case EM_XC16X:
12868 case EM_C166:
12869 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
12870 case EM_XGATE:
12871 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
12872 case EM_XSTORMY16:
12873 return reloc_type == 1; /* R_XSTROMY16_32. */
12874 case EM_XTENSA_OLD:
12875 case EM_XTENSA:
12876 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
12877 case EM_Z80:
12878 return reloc_type == 6; /* R_Z80_32. */
aca88567 12879 default:
bee0ee85
NC
12880 {
12881 static unsigned int prev_warn = 0;
12882
12883 /* Avoid repeating the same warning multiple times. */
dda8d76d 12884 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 12885 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
12886 filedata->file_header.e_machine);
12887 prev_warn = filedata->file_header.e_machine;
bee0ee85
NC
12888 return FALSE;
12889 }
aca88567
NC
12890 }
12891}
12892
12893/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12894 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
12895
12896static bfd_boolean
dda8d76d 12897is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12898{
dda8d76d 12899 switch (filedata->file_header.e_machine)
d347c9df 12900 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 12901 {
41e92641 12902 case EM_386:
22abe556 12903 case EM_IAMCU:
3e0873ac 12904 return reloc_type == 2; /* R_386_PC32. */
aca88567 12905 case EM_68K:
3e0873ac 12906 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
12907 case EM_AARCH64:
12908 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
12909 case EM_ADAPTEVA_EPIPHANY:
12910 return reloc_type == 6;
aca88567
NC
12911 case EM_ALPHA:
12912 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
12913 case EM_ARC_COMPACT:
12914 case EM_ARC_COMPACT2:
12915 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 12916 case EM_ARM:
3e0873ac 12917 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
12918 case EM_AVR_OLD:
12919 case EM_AVR:
12920 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
12921 case EM_MICROBLAZE:
12922 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
12923 case EM_OR1K:
12924 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 12925 case EM_PARISC:
85acf597 12926 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
12927 case EM_PPC:
12928 return reloc_type == 26; /* R_PPC_REL32. */
12929 case EM_PPC64:
3e0873ac 12930 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
12931 case EM_RISCV:
12932 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
12933 case EM_S390_OLD:
12934 case EM_S390:
3e0873ac 12935 return reloc_type == 5; /* R_390_PC32. */
aca88567 12936 case EM_SH:
3e0873ac 12937 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
12938 case EM_SPARC32PLUS:
12939 case EM_SPARCV9:
12940 case EM_SPARC:
3e0873ac 12941 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
12942 case EM_SPU:
12943 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
12944 case EM_TILEGX:
12945 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
12946 case EM_TILEPRO:
12947 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
12948 case EM_VISIUM:
12949 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 12950 case EM_X86_64:
8a9036a4 12951 case EM_L1OM:
7a9068fe 12952 case EM_K1OM:
3e0873ac 12953 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
12954 case EM_VAX:
12955 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
12956 case EM_XTENSA_OLD:
12957 case EM_XTENSA:
12958 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
12959 default:
12960 /* Do not abort or issue an error message here. Not all targets use
12961 pc-relative 32-bit relocs in their DWARF debug information and we
12962 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
12963 more helpful warning message will be generated by apply_relocations
12964 anyway, so just return. */
aca88567
NC
12965 return FALSE;
12966 }
12967}
12968
12969/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12970 a 64-bit absolute RELA relocation used in DWARF debug sections. */
12971
12972static bfd_boolean
dda8d76d 12973is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12974{
dda8d76d 12975 switch (filedata->file_header.e_machine)
aca88567 12976 {
a06ea964
NC
12977 case EM_AARCH64:
12978 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
12979 case EM_ALPHA:
12980 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 12981 case EM_IA_64:
262cdac7
AM
12982 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
12983 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
12984 case EM_PARISC:
12985 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
12986 case EM_PPC64:
12987 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
12988 case EM_RISCV:
12989 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
12990 case EM_SPARC32PLUS:
12991 case EM_SPARCV9:
12992 case EM_SPARC:
714da62f
NC
12993 return reloc_type == 32 /* R_SPARC_64. */
12994 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 12995 case EM_X86_64:
8a9036a4 12996 case EM_L1OM:
7a9068fe 12997 case EM_K1OM:
aca88567 12998 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
12999 case EM_S390_OLD:
13000 case EM_S390:
aa137e4d
NC
13001 return reloc_type == 22; /* R_S390_64. */
13002 case EM_TILEGX:
13003 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 13004 case EM_MIPS:
aa137e4d 13005 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
13006 default:
13007 return FALSE;
13008 }
13009}
13010
85acf597
RH
13011/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
13012 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
13013
13014static bfd_boolean
dda8d76d 13015is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 13016{
dda8d76d 13017 switch (filedata->file_header.e_machine)
85acf597 13018 {
a06ea964
NC
13019 case EM_AARCH64:
13020 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 13021 case EM_ALPHA:
aa137e4d 13022 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 13023 case EM_IA_64:
262cdac7
AM
13024 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
13025 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 13026 case EM_PARISC:
aa137e4d 13027 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 13028 case EM_PPC64:
aa137e4d 13029 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
13030 case EM_SPARC32PLUS:
13031 case EM_SPARCV9:
13032 case EM_SPARC:
aa137e4d 13033 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 13034 case EM_X86_64:
8a9036a4 13035 case EM_L1OM:
7a9068fe 13036 case EM_K1OM:
aa137e4d 13037 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
13038 case EM_S390_OLD:
13039 case EM_S390:
aa137e4d
NC
13040 return reloc_type == 23; /* R_S390_PC64. */
13041 case EM_TILEGX:
13042 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
13043 default:
13044 return FALSE;
13045 }
13046}
13047
4dc3c23d
AM
13048/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13049 a 24-bit absolute RELA relocation used in DWARF debug sections. */
13050
13051static bfd_boolean
dda8d76d 13052is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 13053{
dda8d76d 13054 switch (filedata->file_header.e_machine)
4dc3c23d
AM
13055 {
13056 case EM_CYGNUS_MN10200:
13057 case EM_MN10200:
13058 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
13059 case EM_FT32:
13060 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
13061 case EM_Z80:
13062 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d
AM
13063 default:
13064 return FALSE;
13065 }
13066}
13067
aca88567
NC
13068/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13069 a 16-bit absolute RELA relocation used in DWARF debug sections. */
13070
13071static bfd_boolean
dda8d76d 13072is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 13073{
d347c9df 13074 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13075 switch (filedata->file_header.e_machine)
4b78141a 13076 {
886a2506
NC
13077 case EM_ARC:
13078 case EM_ARC_COMPACT:
13079 case EM_ARC_COMPACT2:
13080 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
13081 case EM_ADAPTEVA_EPIPHANY:
13082 return reloc_type == 5;
aca88567
NC
13083 case EM_AVR_OLD:
13084 case EM_AVR:
13085 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
13086 case EM_CYGNUS_D10V:
13087 case EM_D10V:
13088 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
13089 case EM_FT32:
13090 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
13091 case EM_H8S:
13092 case EM_H8_300:
13093 case EM_H8_300H:
aca88567
NC
13094 return reloc_type == R_H8_DIR16;
13095 case EM_IP2K_OLD:
13096 case EM_IP2K:
13097 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 13098 case EM_M32C_OLD:
f4236fe4
DD
13099 case EM_M32C:
13100 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
13101 case EM_CYGNUS_MN10200:
13102 case EM_MN10200:
13103 return reloc_type == 2; /* R_MN10200_16. */
13104 case EM_CYGNUS_MN10300:
13105 case EM_MN10300:
13106 return reloc_type == 2; /* R_MN10300_16. */
aca88567 13107 case EM_MSP430:
dda8d76d 13108 if (uses_msp430x_relocs (filedata))
13761a11 13109 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 13110 /* Fall through. */
78c8d46c 13111 case EM_MSP430_OLD:
aca88567 13112 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
13113 case EM_NDS32:
13114 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 13115 case EM_ALTERA_NIOS2:
36591ba1 13116 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
13117 case EM_NIOS32:
13118 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
13119 case EM_OR1K:
13120 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
13121 case EM_RISCV:
13122 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
13123 case EM_TI_PRU:
13124 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
13125 case EM_TI_C6000:
13126 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
13127 case EM_VISIUM:
13128 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
13129 case EM_XC16X:
13130 case EM_C166:
13131 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
13132 case EM_XGATE:
13133 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
13134 case EM_Z80:
13135 return reloc_type == 4; /* R_Z80_16. */
4b78141a 13136 default:
aca88567 13137 return FALSE;
4b78141a
NC
13138 }
13139}
13140
39e07931
AS
13141/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13142 a 8-bit absolute RELA relocation used in DWARF debug sections. */
13143
13144static bfd_boolean
13145is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13146{
13147 switch (filedata->file_header.e_machine)
13148 {
13149 case EM_RISCV:
13150 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
13151 case EM_Z80:
13152 return reloc_type == 1; /* R_Z80_8. */
39e07931
AS
13153 default:
13154 return FALSE;
13155 }
13156}
13157
13158/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13159 a 6-bit absolute RELA relocation used in DWARF debug sections. */
13160
13161static bfd_boolean
13162is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13163{
13164 switch (filedata->file_header.e_machine)
13165 {
13166 case EM_RISCV:
13167 return reloc_type == 53; /* R_RISCV_SET6. */
13168 default:
13169 return FALSE;
13170 }
13171}
13172
03336641
JW
13173/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13174 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
13175
13176static bfd_boolean
13177is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13178{
13179 /* Please keep this table alpha-sorted for ease of visual lookup. */
13180 switch (filedata->file_header.e_machine)
13181 {
13182 case EM_RISCV:
13183 return reloc_type == 35; /* R_RISCV_ADD32. */
13184 default:
13185 return FALSE;
13186 }
13187}
13188
13189/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13190 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
13191
13192static bfd_boolean
13193is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13194{
13195 /* Please keep this table alpha-sorted for ease of visual lookup. */
13196 switch (filedata->file_header.e_machine)
13197 {
13198 case EM_RISCV:
13199 return reloc_type == 39; /* R_RISCV_SUB32. */
13200 default:
13201 return FALSE;
13202 }
13203}
13204
13205/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13206 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
13207
13208static bfd_boolean
13209is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13210{
13211 /* Please keep this table alpha-sorted for ease of visual lookup. */
13212 switch (filedata->file_header.e_machine)
13213 {
13214 case EM_RISCV:
13215 return reloc_type == 36; /* R_RISCV_ADD64. */
13216 default:
13217 return FALSE;
13218 }
13219}
13220
13221/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13222 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
13223
13224static bfd_boolean
13225is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13226{
13227 /* Please keep this table alpha-sorted for ease of visual lookup. */
13228 switch (filedata->file_header.e_machine)
13229 {
13230 case EM_RISCV:
13231 return reloc_type == 40; /* R_RISCV_SUB64. */
13232 default:
13233 return FALSE;
13234 }
13235}
13236
13237/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13238 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
13239
13240static bfd_boolean
13241is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13242{
13243 /* Please keep this table alpha-sorted for ease of visual lookup. */
13244 switch (filedata->file_header.e_machine)
13245 {
13246 case EM_RISCV:
13247 return reloc_type == 34; /* R_RISCV_ADD16. */
13248 default:
13249 return FALSE;
13250 }
13251}
13252
13253/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13254 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
13255
13256static bfd_boolean
13257is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13258{
13259 /* Please keep this table alpha-sorted for ease of visual lookup. */
13260 switch (filedata->file_header.e_machine)
13261 {
13262 case EM_RISCV:
13263 return reloc_type == 38; /* R_RISCV_SUB16. */
13264 default:
13265 return FALSE;
13266 }
13267}
13268
13269/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13270 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
13271
13272static bfd_boolean
13273is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13274{
13275 /* Please keep this table alpha-sorted for ease of visual lookup. */
13276 switch (filedata->file_header.e_machine)
13277 {
13278 case EM_RISCV:
13279 return reloc_type == 33; /* R_RISCV_ADD8. */
13280 default:
13281 return FALSE;
13282 }
13283}
13284
13285/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13286 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
13287
13288static bfd_boolean
13289is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13290{
13291 /* Please keep this table alpha-sorted for ease of visual lookup. */
13292 switch (filedata->file_header.e_machine)
13293 {
13294 case EM_RISCV:
13295 return reloc_type == 37; /* R_RISCV_SUB8. */
13296 default:
13297 return FALSE;
13298 }
13299}
13300
39e07931
AS
13301/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13302 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
13303
13304static bfd_boolean
13305is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13306{
13307 switch (filedata->file_header.e_machine)
13308 {
13309 case EM_RISCV:
13310 return reloc_type == 52; /* R_RISCV_SUB6. */
13311 default:
13312 return FALSE;
13313 }
13314}
13315
2a7b2e88
JK
13316/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
13317 relocation entries (possibly formerly used for SHT_GROUP sections). */
13318
13319static bfd_boolean
dda8d76d 13320is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 13321{
dda8d76d 13322 switch (filedata->file_header.e_machine)
2a7b2e88 13323 {
cb8f3167 13324 case EM_386: /* R_386_NONE. */
d347c9df 13325 case EM_68K: /* R_68K_NONE. */
cfb8c092 13326 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
13327 case EM_ALPHA: /* R_ALPHA_NONE. */
13328 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 13329 case EM_ARC: /* R_ARC_NONE. */
886a2506 13330 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 13331 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 13332 case EM_ARM: /* R_ARM_NONE. */
d347c9df 13333 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 13334 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
13335 case EM_FT32: /* R_FT32_NONE. */
13336 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 13337 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
13338 case EM_L1OM: /* R_X86_64_NONE. */
13339 case EM_M32R: /* R_M32R_NONE. */
13340 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 13341 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 13342 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
13343 case EM_NIOS32: /* R_NIOS_NONE. */
13344 case EM_OR1K: /* R_OR1K_NONE. */
13345 case EM_PARISC: /* R_PARISC_NONE. */
13346 case EM_PPC64: /* R_PPC64_NONE. */
13347 case EM_PPC: /* R_PPC_NONE. */
e23eba97 13348 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
13349 case EM_S390: /* R_390_NONE. */
13350 case EM_S390_OLD:
13351 case EM_SH: /* R_SH_NONE. */
13352 case EM_SPARC32PLUS:
13353 case EM_SPARC: /* R_SPARC_NONE. */
13354 case EM_SPARCV9:
aa137e4d
NC
13355 case EM_TILEGX: /* R_TILEGX_NONE. */
13356 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
13357 case EM_TI_C6000:/* R_C6000_NONE. */
13358 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 13359 case EM_XC16X:
6655dba2 13360 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 13361 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 13362 return reloc_type == 0;
d347c9df 13363
a06ea964
NC
13364 case EM_AARCH64:
13365 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
13366 case EM_AVR_OLD:
13367 case EM_AVR:
13368 return (reloc_type == 0 /* R_AVR_NONE. */
13369 || reloc_type == 30 /* R_AVR_DIFF8. */
13370 || reloc_type == 31 /* R_AVR_DIFF16. */
13371 || reloc_type == 32 /* R_AVR_DIFF32. */);
13372 case EM_METAG:
13373 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
13374 case EM_NDS32:
13375 return (reloc_type == 0 /* R_XTENSA_NONE. */
13376 || reloc_type == 204 /* R_NDS32_DIFF8. */
13377 || reloc_type == 205 /* R_NDS32_DIFF16. */
13378 || reloc_type == 206 /* R_NDS32_DIFF32. */
13379 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
13380 case EM_TI_PRU:
13381 return (reloc_type == 0 /* R_PRU_NONE. */
13382 || reloc_type == 65 /* R_PRU_DIFF8. */
13383 || reloc_type == 66 /* R_PRU_DIFF16. */
13384 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
13385 case EM_XTENSA_OLD:
13386 case EM_XTENSA:
4dc3c23d
AM
13387 return (reloc_type == 0 /* R_XTENSA_NONE. */
13388 || reloc_type == 17 /* R_XTENSA_DIFF8. */
13389 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
13390 || reloc_type == 19 /* R_XTENSA_DIFF32. */
13391 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
13392 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
13393 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
13394 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
13395 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
13396 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88
JK
13397 }
13398 return FALSE;
13399}
13400
d1c4b12b
NC
13401/* Returns TRUE if there is a relocation against
13402 section NAME at OFFSET bytes. */
13403
13404bfd_boolean
13405reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
13406{
13407 Elf_Internal_Rela * relocs;
13408 Elf_Internal_Rela * rp;
13409
13410 if (dsec == NULL || dsec->reloc_info == NULL)
13411 return FALSE;
13412
13413 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
13414
13415 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
13416 if (rp->r_offset == offset)
13417 return TRUE;
13418
13419 return FALSE;
13420}
13421
cf13d699 13422/* Apply relocations to a section.
32ec8896
NC
13423 Returns TRUE upon success, FALSE otherwise.
13424 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
13425 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
13426 will be set to the number of relocs loaded.
13427
cf13d699 13428 Note: So far support has been added only for those relocations
32ec8896
NC
13429 which can be found in debug sections. FIXME: Add support for
13430 more relocations ? */
1b315056 13431
32ec8896 13432static bfd_boolean
dda8d76d 13433apply_relocations (Filedata * filedata,
d1c4b12b
NC
13434 const Elf_Internal_Shdr * section,
13435 unsigned char * start,
13436 bfd_size_type size,
1449284b 13437 void ** relocs_return,
d1c4b12b 13438 unsigned long * num_relocs_return)
1b315056 13439{
cf13d699 13440 Elf_Internal_Shdr * relsec;
0d2a7a93 13441 unsigned char * end = start + size;
cb8f3167 13442
d1c4b12b
NC
13443 if (relocs_return != NULL)
13444 {
13445 * (Elf_Internal_Rela **) relocs_return = NULL;
13446 * num_relocs_return = 0;
13447 }
13448
dda8d76d 13449 if (filedata->file_header.e_type != ET_REL)
32ec8896
NC
13450 /* No relocs to apply. */
13451 return TRUE;
1b315056 13452
cf13d699 13453 /* Find the reloc section associated with the section. */
dda8d76d
NC
13454 for (relsec = filedata->section_headers;
13455 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 13456 ++relsec)
252b5132 13457 {
41e92641
NC
13458 bfd_boolean is_rela;
13459 unsigned long num_relocs;
2cf0635d
NC
13460 Elf_Internal_Rela * relocs;
13461 Elf_Internal_Rela * rp;
13462 Elf_Internal_Shdr * symsec;
13463 Elf_Internal_Sym * symtab;
ba5cdace 13464 unsigned long num_syms;
2cf0635d 13465 Elf_Internal_Sym * sym;
252b5132 13466
41e92641 13467 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13468 || relsec->sh_info >= filedata->file_header.e_shnum
13469 || filedata->section_headers + relsec->sh_info != section
c256ffe7 13470 || relsec->sh_size == 0
dda8d76d 13471 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 13472 continue;
428409d5 13473
a788aedd
AM
13474 symsec = filedata->section_headers + relsec->sh_link;
13475 if (symsec->sh_type != SHT_SYMTAB
13476 && symsec->sh_type != SHT_DYNSYM)
13477 return FALSE;
13478
41e92641
NC
13479 is_rela = relsec->sh_type == SHT_RELA;
13480
13481 if (is_rela)
13482 {
dda8d76d 13483 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 13484 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13485 return FALSE;
41e92641
NC
13486 }
13487 else
13488 {
dda8d76d 13489 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 13490 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13491 return FALSE;
41e92641
NC
13492 }
13493
13494 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 13495 if (filedata->file_header.e_machine == EM_SH)
41e92641 13496 is_rela = FALSE;
428409d5 13497
dda8d76d 13498 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 13499
41e92641 13500 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 13501 {
41e92641
NC
13502 bfd_vma addend;
13503 unsigned int reloc_type;
13504 unsigned int reloc_size;
03336641
JW
13505 bfd_boolean reloc_inplace = FALSE;
13506 bfd_boolean reloc_subtract = FALSE;
91d6fa6a 13507 unsigned char * rloc;
ba5cdace 13508 unsigned long sym_index;
4b78141a 13509
dda8d76d 13510 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 13511
dda8d76d 13512 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 13513 continue;
dda8d76d 13514 else if (is_none_reloc (filedata, reloc_type))
98fb390a 13515 continue;
dda8d76d
NC
13516 else if (is_32bit_abs_reloc (filedata, reloc_type)
13517 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 13518 reloc_size = 4;
dda8d76d
NC
13519 else if (is_64bit_abs_reloc (filedata, reloc_type)
13520 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 13521 reloc_size = 8;
dda8d76d 13522 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 13523 reloc_size = 3;
dda8d76d 13524 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 13525 reloc_size = 2;
39e07931
AS
13526 else if (is_8bit_abs_reloc (filedata, reloc_type)
13527 || is_6bit_abs_reloc (filedata, reloc_type))
13528 reloc_size = 1;
03336641
JW
13529 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
13530 reloc_type))
13531 || is_32bit_inplace_add_reloc (filedata, reloc_type))
13532 {
13533 reloc_size = 4;
13534 reloc_inplace = TRUE;
13535 }
13536 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
13537 reloc_type))
13538 || is_64bit_inplace_add_reloc (filedata, reloc_type))
13539 {
13540 reloc_size = 8;
13541 reloc_inplace = TRUE;
13542 }
13543 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
13544 reloc_type))
13545 || is_16bit_inplace_add_reloc (filedata, reloc_type))
13546 {
13547 reloc_size = 2;
13548 reloc_inplace = TRUE;
13549 }
13550 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
13551 reloc_type))
13552 || is_8bit_inplace_add_reloc (filedata, reloc_type))
13553 {
13554 reloc_size = 1;
13555 reloc_inplace = TRUE;
13556 }
39e07931
AS
13557 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
13558 reloc_type)))
13559 {
13560 reloc_size = 1;
13561 reloc_inplace = TRUE;
13562 }
aca88567 13563 else
4b78141a 13564 {
bee0ee85 13565 static unsigned int prev_reloc = 0;
dda8d76d 13566
bee0ee85
NC
13567 if (reloc_type != prev_reloc)
13568 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 13569 reloc_type, printable_section_name (filedata, section));
bee0ee85 13570 prev_reloc = reloc_type;
4b78141a
NC
13571 continue;
13572 }
103f02d3 13573
91d6fa6a 13574 rloc = start + rp->r_offset;
75802ccb 13575 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
13576 {
13577 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
13578 (unsigned long) rp->r_offset,
dda8d76d 13579 printable_section_name (filedata, section));
700dd8b7
L
13580 continue;
13581 }
103f02d3 13582
ba5cdace
NC
13583 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
13584 if (sym_index >= num_syms)
13585 {
13586 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 13587 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
13588 continue;
13589 }
13590 sym = symtab + sym_index;
41e92641
NC
13591
13592 /* If the reloc has a symbol associated with it,
55f25fc3
L
13593 make sure that it is of an appropriate type.
13594
13595 Relocations against symbols without type can happen.
13596 Gcc -feliminate-dwarf2-dups may generate symbols
13597 without type for debug info.
13598
13599 Icc generates relocations against function symbols
13600 instead of local labels.
13601
13602 Relocations against object symbols can happen, eg when
13603 referencing a global array. For an example of this see
13604 the _clz.o binary in libgcc.a. */
aca88567 13605 if (sym != symtab
b8871f35 13606 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 13607 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 13608 {
d3a49aa8 13609 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
13610 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
13611 printable_section_name (filedata, relsec),
d3a49aa8 13612 (long int)(rp - relocs));
aca88567 13613 continue;
5b18a4bc 13614 }
252b5132 13615
4dc3c23d
AM
13616 addend = 0;
13617 if (is_rela)
13618 addend += rp->r_addend;
c47320c3
AM
13619 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
13620 partial_inplace. */
4dc3c23d 13621 if (!is_rela
dda8d76d 13622 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 13623 && reloc_type == 1)
dda8d76d
NC
13624 || ((filedata->file_header.e_machine == EM_PJ
13625 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 13626 && reloc_type == 1)
dda8d76d
NC
13627 || ((filedata->file_header.e_machine == EM_D30V
13628 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
13629 && reloc_type == 12)
13630 || reloc_inplace)
39e07931
AS
13631 {
13632 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
13633 addend += byte_get (rloc, reloc_size) & 0x3f;
13634 else
13635 addend += byte_get (rloc, reloc_size);
13636 }
cb8f3167 13637
dda8d76d
NC
13638 if (is_32bit_pcrel_reloc (filedata, reloc_type)
13639 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
13640 {
13641 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 13642 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 13643 addend -= 8;
91d6fa6a 13644 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
13645 reloc_size);
13646 }
39e07931
AS
13647 else if (is_6bit_abs_reloc (filedata, reloc_type)
13648 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
13649 {
13650 if (reloc_subtract)
13651 addend -= sym->st_value;
13652 else
13653 addend += sym->st_value;
13654 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
13655 byte_put (rloc, addend, reloc_size);
13656 }
03336641
JW
13657 else if (reloc_subtract)
13658 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 13659 else
91d6fa6a 13660 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 13661 }
252b5132 13662
5b18a4bc 13663 free (symtab);
f84ce13b
NC
13664 /* Let the target specific reloc processing code know that
13665 we have finished with these relocs. */
dda8d76d 13666 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
13667
13668 if (relocs_return)
13669 {
13670 * (Elf_Internal_Rela **) relocs_return = relocs;
13671 * num_relocs_return = num_relocs;
13672 }
13673 else
13674 free (relocs);
13675
5b18a4bc
NC
13676 break;
13677 }
32ec8896 13678
dfc616fa 13679 return TRUE;
5b18a4bc 13680}
103f02d3 13681
cf13d699 13682#ifdef SUPPORT_DISASSEMBLY
32ec8896 13683static bfd_boolean
dda8d76d 13684disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13685{
dda8d76d 13686 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 13687
74e1a04b 13688 /* FIXME: XXX -- to be done --- XXX */
cf13d699 13689
32ec8896 13690 return TRUE;
cf13d699
NC
13691}
13692#endif
13693
13694/* Reads in the contents of SECTION from FILE, returning a pointer
13695 to a malloc'ed buffer or NULL if something went wrong. */
13696
13697static char *
dda8d76d 13698get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13699{
dda8d76d 13700 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
13701
13702 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
13703 {
c6b78c96 13704 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 13705 printable_section_name (filedata, section));
cf13d699
NC
13706 return NULL;
13707 }
13708
dda8d76d 13709 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 13710 _("section contents"));
cf13d699
NC
13711}
13712
0e602686
NC
13713/* Uncompresses a section that was compressed using zlib, in place. */
13714
13715static bfd_boolean
dda8d76d
NC
13716uncompress_section_contents (unsigned char ** buffer,
13717 dwarf_size_type uncompressed_size,
13718 dwarf_size_type * size)
0e602686
NC
13719{
13720 dwarf_size_type compressed_size = *size;
13721 unsigned char * compressed_buffer = *buffer;
13722 unsigned char * uncompressed_buffer;
13723 z_stream strm;
13724 int rc;
13725
13726 /* It is possible the section consists of several compressed
13727 buffers concatenated together, so we uncompress in a loop. */
13728 /* PR 18313: The state field in the z_stream structure is supposed
13729 to be invisible to the user (ie us), but some compilers will
13730 still complain about it being used without initialisation. So
13731 we first zero the entire z_stream structure and then set the fields
13732 that we need. */
13733 memset (& strm, 0, sizeof strm);
13734 strm.avail_in = compressed_size;
13735 strm.next_in = (Bytef *) compressed_buffer;
13736 strm.avail_out = uncompressed_size;
13737 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
13738
13739 rc = inflateInit (& strm);
13740 while (strm.avail_in > 0)
13741 {
13742 if (rc != Z_OK)
13743 goto fail;
13744 strm.next_out = ((Bytef *) uncompressed_buffer
13745 + (uncompressed_size - strm.avail_out));
13746 rc = inflate (&strm, Z_FINISH);
13747 if (rc != Z_STREAM_END)
13748 goto fail;
13749 rc = inflateReset (& strm);
13750 }
13751 rc = inflateEnd (& strm);
13752 if (rc != Z_OK
13753 || strm.avail_out != 0)
13754 goto fail;
13755
13756 *buffer = uncompressed_buffer;
13757 *size = uncompressed_size;
13758 return TRUE;
13759
13760 fail:
13761 free (uncompressed_buffer);
13762 /* Indicate decompression failure. */
13763 *buffer = NULL;
13764 return FALSE;
13765}
dd24e3da 13766
32ec8896 13767static bfd_boolean
dda8d76d 13768dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13769{
0e602686
NC
13770 Elf_Internal_Shdr * relsec;
13771 bfd_size_type num_bytes;
fd8008d8
L
13772 unsigned char * data;
13773 unsigned char * end;
13774 unsigned char * real_start;
13775 unsigned char * start;
0e602686 13776 bfd_boolean some_strings_shown;
cf13d699 13777
dda8d76d 13778 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13779 if (start == NULL)
c6b78c96
NC
13780 /* PR 21820: Do not fail if the section was empty. */
13781 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
13782
0e602686 13783 num_bytes = section->sh_size;
cf13d699 13784
dda8d76d 13785 printf (_("\nString dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13786
0e602686
NC
13787 if (decompress_dumps)
13788 {
13789 dwarf_size_type new_size = num_bytes;
13790 dwarf_size_type uncompressed_size = 0;
13791
13792 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13793 {
13794 Elf_Internal_Chdr chdr;
13795 unsigned int compression_header_size
ebdf1ebf
NC
13796 = get_compression_header (& chdr, (unsigned char *) start,
13797 num_bytes);
5844b465
NC
13798 if (compression_header_size == 0)
13799 /* An error message will have already been generated
13800 by get_compression_header. */
13801 goto error_out;
0e602686 13802
813dabb9 13803 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13804 {
813dabb9 13805 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13806 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 13807 goto error_out;
813dabb9 13808 }
813dabb9
L
13809 uncompressed_size = chdr.ch_size;
13810 start += compression_header_size;
13811 new_size -= compression_header_size;
0e602686
NC
13812 }
13813 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13814 {
13815 /* Read the zlib header. In this case, it should be "ZLIB"
13816 followed by the uncompressed section size, 8 bytes in
13817 big-endian order. */
13818 uncompressed_size = start[4]; uncompressed_size <<= 8;
13819 uncompressed_size += start[5]; uncompressed_size <<= 8;
13820 uncompressed_size += start[6]; uncompressed_size <<= 8;
13821 uncompressed_size += start[7]; uncompressed_size <<= 8;
13822 uncompressed_size += start[8]; uncompressed_size <<= 8;
13823 uncompressed_size += start[9]; uncompressed_size <<= 8;
13824 uncompressed_size += start[10]; uncompressed_size <<= 8;
13825 uncompressed_size += start[11];
13826 start += 12;
13827 new_size -= 12;
13828 }
13829
1835f746
NC
13830 if (uncompressed_size)
13831 {
13832 if (uncompress_section_contents (& start,
13833 uncompressed_size, & new_size))
13834 num_bytes = new_size;
13835 else
13836 {
13837 error (_("Unable to decompress section %s\n"),
dda8d76d 13838 printable_section_name (filedata, section));
f761cb13 13839 goto error_out;
1835f746
NC
13840 }
13841 }
bc303e5d
NC
13842 else
13843 start = real_start;
0e602686 13844 }
fd8008d8 13845
cf13d699
NC
13846 /* If the section being dumped has relocations against it the user might
13847 be expecting these relocations to have been applied. Check for this
13848 case and issue a warning message in order to avoid confusion.
13849 FIXME: Maybe we ought to have an option that dumps a section with
13850 relocs applied ? */
dda8d76d
NC
13851 for (relsec = filedata->section_headers;
13852 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13853 ++relsec)
13854 {
13855 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13856 || relsec->sh_info >= filedata->file_header.e_shnum
13857 || filedata->section_headers + relsec->sh_info != section
cf13d699 13858 || relsec->sh_size == 0
dda8d76d 13859 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13860 continue;
13861
13862 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13863 break;
13864 }
13865
cf13d699
NC
13866 data = start;
13867 end = start + num_bytes;
13868 some_strings_shown = FALSE;
13869
ba3265d0
NC
13870#ifdef HAVE_MBSTATE_T
13871 mbstate_t state;
13872 /* Initialise the multibyte conversion state. */
13873 memset (& state, 0, sizeof (state));
13874#endif
13875
13876 bfd_boolean continuing = FALSE;
13877
cf13d699
NC
13878 while (data < end)
13879 {
13880 while (!ISPRINT (* data))
13881 if (++ data >= end)
13882 break;
13883
13884 if (data < end)
13885 {
071436c6
NC
13886 size_t maxlen = end - data;
13887
ba3265d0
NC
13888 if (continuing)
13889 {
13890 printf (" ");
13891 continuing = FALSE;
13892 }
13893 else
13894 {
cf13d699 13895#ifndef __MSVCRT__
ba3265d0
NC
13896 /* PR 11128: Use two separate invocations in order to work
13897 around bugs in the Solaris 8 implementation of printf. */
13898 printf (" [%6tx] ", data - start);
cf13d699 13899#else
ba3265d0 13900 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 13901#endif
ba3265d0
NC
13902 }
13903
4082ef84
NC
13904 if (maxlen > 0)
13905 {
ba3265d0
NC
13906 char c;
13907
13908 while (maxlen)
13909 {
13910 c = *data++;
13911
13912 if (c == 0)
13913 break;
13914
13915 /* PR 25543: Treat new-lines as string-ending characters. */
13916 if (c == '\n')
13917 {
13918 printf ("\\n\n");
13919 if (*data != 0)
13920 continuing = TRUE;
13921 break;
13922 }
13923
13924 /* Do not print control characters directly as they can affect terminal
13925 settings. Such characters usually appear in the names generated
13926 by the assembler for local labels. */
13927 if (ISCNTRL (c))
13928 {
13929 printf ("^%c", c + 0x40);
13930 }
13931 else if (ISPRINT (c))
13932 {
13933 putchar (c);
13934 }
13935 else
13936 {
13937 size_t n;
13938#ifdef HAVE_MBSTATE_T
13939 wchar_t w;
13940#endif
13941 /* Let printf do the hard work of displaying multibyte characters. */
13942 printf ("%.1s", data - 1);
13943#ifdef HAVE_MBSTATE_T
13944 /* Try to find out how many bytes made up the character that was
13945 just printed. Advance the symbol pointer past the bytes that
13946 were displayed. */
13947 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
13948#else
13949 n = 1;
13950#endif
13951 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
13952 data += (n - 1);
13953 }
13954 }
13955
13956 if (c != '\n')
13957 putchar ('\n');
4082ef84
NC
13958 }
13959 else
13960 {
13961 printf (_("<corrupt>\n"));
13962 data = end;
13963 }
cf13d699
NC
13964 some_strings_shown = TRUE;
13965 }
13966 }
13967
13968 if (! some_strings_shown)
13969 printf (_(" No strings found in this section."));
13970
0e602686 13971 free (real_start);
cf13d699
NC
13972
13973 putchar ('\n');
32ec8896 13974 return TRUE;
f761cb13
AM
13975
13976error_out:
13977 free (real_start);
13978 return FALSE;
cf13d699
NC
13979}
13980
32ec8896 13981static bfd_boolean
dda8d76d
NC
13982dump_section_as_bytes (Elf_Internal_Shdr * section,
13983 Filedata * filedata,
13984 bfd_boolean relocate)
cf13d699
NC
13985{
13986 Elf_Internal_Shdr * relsec;
0e602686
NC
13987 bfd_size_type bytes;
13988 bfd_size_type section_size;
13989 bfd_vma addr;
13990 unsigned char * data;
13991 unsigned char * real_start;
13992 unsigned char * start;
13993
dda8d76d 13994 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13995 if (start == NULL)
c6b78c96
NC
13996 /* PR 21820: Do not fail if the section was empty. */
13997 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
32ec8896 13998
0e602686 13999 section_size = section->sh_size;
cf13d699 14000
dda8d76d 14001 printf (_("\nHex dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 14002
0e602686
NC
14003 if (decompress_dumps)
14004 {
14005 dwarf_size_type new_size = section_size;
14006 dwarf_size_type uncompressed_size = 0;
14007
14008 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14009 {
14010 Elf_Internal_Chdr chdr;
14011 unsigned int compression_header_size
ebdf1ebf 14012 = get_compression_header (& chdr, start, section_size);
0e602686 14013
5844b465
NC
14014 if (compression_header_size == 0)
14015 /* An error message will have already been generated
14016 by get_compression_header. */
14017 goto error_out;
14018
813dabb9 14019 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14020 {
813dabb9 14021 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14022 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14023 goto error_out;
0e602686 14024 }
813dabb9
L
14025 uncompressed_size = chdr.ch_size;
14026 start += compression_header_size;
14027 new_size -= compression_header_size;
0e602686
NC
14028 }
14029 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14030 {
14031 /* Read the zlib header. In this case, it should be "ZLIB"
14032 followed by the uncompressed section size, 8 bytes in
14033 big-endian order. */
14034 uncompressed_size = start[4]; uncompressed_size <<= 8;
14035 uncompressed_size += start[5]; uncompressed_size <<= 8;
14036 uncompressed_size += start[6]; uncompressed_size <<= 8;
14037 uncompressed_size += start[7]; uncompressed_size <<= 8;
14038 uncompressed_size += start[8]; uncompressed_size <<= 8;
14039 uncompressed_size += start[9]; uncompressed_size <<= 8;
14040 uncompressed_size += start[10]; uncompressed_size <<= 8;
14041 uncompressed_size += start[11];
14042 start += 12;
14043 new_size -= 12;
14044 }
14045
f055032e
NC
14046 if (uncompressed_size)
14047 {
14048 if (uncompress_section_contents (& start, uncompressed_size,
14049 & new_size))
bc303e5d
NC
14050 {
14051 section_size = new_size;
14052 }
f055032e
NC
14053 else
14054 {
14055 error (_("Unable to decompress section %s\n"),
dda8d76d 14056 printable_section_name (filedata, section));
bc303e5d 14057 /* FIXME: Print the section anyway ? */
f761cb13 14058 goto error_out;
f055032e
NC
14059 }
14060 }
bc303e5d
NC
14061 else
14062 start = real_start;
0e602686 14063 }
14ae95f2 14064
cf13d699
NC
14065 if (relocate)
14066 {
dda8d76d 14067 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 14068 goto error_out;
cf13d699
NC
14069 }
14070 else
14071 {
14072 /* If the section being dumped has relocations against it the user might
14073 be expecting these relocations to have been applied. Check for this
14074 case and issue a warning message in order to avoid confusion.
14075 FIXME: Maybe we ought to have an option that dumps a section with
14076 relocs applied ? */
dda8d76d
NC
14077 for (relsec = filedata->section_headers;
14078 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14079 ++relsec)
14080 {
14081 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14082 || relsec->sh_info >= filedata->file_header.e_shnum
14083 || filedata->section_headers + relsec->sh_info != section
cf13d699 14084 || relsec->sh_size == 0
dda8d76d 14085 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14086 continue;
14087
14088 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14089 break;
14090 }
14091 }
14092
14093 addr = section->sh_addr;
0e602686 14094 bytes = section_size;
cf13d699
NC
14095 data = start;
14096
14097 while (bytes)
14098 {
14099 int j;
14100 int k;
14101 int lbytes;
14102
14103 lbytes = (bytes > 16 ? 16 : bytes);
14104
14105 printf (" 0x%8.8lx ", (unsigned long) addr);
14106
14107 for (j = 0; j < 16; j++)
14108 {
14109 if (j < lbytes)
14110 printf ("%2.2x", data[j]);
14111 else
14112 printf (" ");
14113
14114 if ((j & 3) == 3)
14115 printf (" ");
14116 }
14117
14118 for (j = 0; j < lbytes; j++)
14119 {
14120 k = data[j];
14121 if (k >= ' ' && k < 0x7f)
14122 printf ("%c", k);
14123 else
14124 printf (".");
14125 }
14126
14127 putchar ('\n');
14128
14129 data += lbytes;
14130 addr += lbytes;
14131 bytes -= lbytes;
14132 }
14133
0e602686 14134 free (real_start);
cf13d699
NC
14135
14136 putchar ('\n');
32ec8896 14137 return TRUE;
f761cb13
AM
14138
14139 error_out:
14140 free (real_start);
14141 return FALSE;
cf13d699
NC
14142}
14143
7d9813f1
NA
14144static ctf_sect_t *
14145shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
14146{
90bd5423 14147 buf->cts_name = SECTION_NAME (shdr);
7d9813f1
NA
14148 buf->cts_size = shdr->sh_size;
14149 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
14150
14151 return buf;
14152}
14153
14154/* Formatting callback function passed to ctf_dump. Returns either the pointer
14155 it is passed, or a pointer to newly-allocated storage, in which case
14156 dump_ctf() will free it when it no longer needs it. */
14157
14158static char *dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14159 char *s, void *arg)
14160{
3e50a591 14161 const char *blanks = arg;
7d9813f1
NA
14162 char *new_s;
14163
3e50a591 14164 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
14165 return s;
14166 return new_s;
14167}
14168
14169static bfd_boolean
14170dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
14171{
14172 Elf_Internal_Shdr * parent_sec = NULL;
14173 Elf_Internal_Shdr * symtab_sec = NULL;
14174 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
14175 void * data = NULL;
14176 void * symdata = NULL;
14177 void * strdata = NULL;
14178 void * parentdata = NULL;
14179 ctf_sect_t ctfsect, symsect, strsect, parentsect;
14180 ctf_sect_t * symsectp = NULL;
14181 ctf_sect_t * strsectp = NULL;
14182 ctf_file_t * ctf = NULL;
14183 ctf_file_t * parent = NULL;
7d9813f1 14184
9b32cba4
NA
14185 const char *things[] = {"Header", "Labels", "Data objects",
14186 "Function objects", "Variables", "Types", "Strings",
14187 ""};
7d9813f1
NA
14188 const char **thing;
14189 int err;
14190 bfd_boolean ret = FALSE;
14191 size_t i;
14192
14193 shdr_to_ctf_sect (&ctfsect, section, filedata);
14194 data = get_section_contents (section, filedata);
14195 ctfsect.cts_data = data;
14196
616febde
NA
14197 if (!dump_ctf_symtab_name)
14198 dump_ctf_symtab_name = strdup (".symtab");
14199
14200 if (!dump_ctf_strtab_name)
14201 dump_ctf_strtab_name = strdup (".strtab");
14202
14203 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
14204 {
14205 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
14206 {
14207 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
14208 goto fail;
14209 }
14210 if ((symdata = (void *) get_data (NULL, filedata,
14211 symtab_sec->sh_offset, 1,
14212 symtab_sec->sh_size,
14213 _("symbols"))) == NULL)
14214 goto fail;
14215 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
14216 symsect.cts_data = symdata;
14217 }
616febde 14218 if (dump_ctf_strtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
14219 {
14220 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
14221 {
14222 error (_("No string table section named %s\n"),
14223 dump_ctf_strtab_name);
14224 goto fail;
14225 }
14226 if ((strdata = (void *) get_data (NULL, filedata,
14227 strtab_sec->sh_offset, 1,
14228 strtab_sec->sh_size,
14229 _("strings"))) == NULL)
14230 goto fail;
14231 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
14232 strsect.cts_data = strdata;
14233 }
14234 if (dump_ctf_parent_name)
14235 {
14236 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
14237 {
14238 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
14239 goto fail;
14240 }
14241 if ((parentdata = (void *) get_data (NULL, filedata,
14242 parent_sec->sh_offset, 1,
14243 parent_sec->sh_size,
14244 _("CTF parent"))) == NULL)
14245 goto fail;
14246 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
14247 parentsect.cts_data = parentdata;
14248 }
14249
14250 /* Load the CTF file and dump it. */
14251
14252 if ((ctf = ctf_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
14253 {
14254 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14255 goto fail;
14256 }
14257
14258 if (parentdata)
14259 {
14260 if ((parent = ctf_bufopen (&parentsect, symsectp, strsectp, &err)) == NULL)
14261 {
14262 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14263 goto fail;
14264 }
14265
14266 ctf_import (ctf, parent);
14267 }
14268
14269 ret = TRUE;
14270
14271 printf (_("\nDump of CTF section '%s':\n"),
14272 printable_section_name (filedata, section));
14273
9b32cba4 14274 for (i = 0, thing = things; *thing[0]; thing++, i++)
7d9813f1
NA
14275 {
14276 ctf_dump_state_t *s = NULL;
14277 char *item;
14278
14279 printf ("\n %s:\n", *thing);
14280 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
14281 (void *) " ")) != NULL)
14282 {
14283 printf ("%s\n", item);
14284 free (item);
14285 }
14286
14287 if (ctf_errno (ctf))
14288 {
14289 error (_("Iteration failed: %s, %s\n"), *thing,
14290 ctf_errmsg (ctf_errno (ctf)));
14291 ret = FALSE;
14292 }
14293 }
14294
14295 fail:
14296 ctf_file_close (ctf);
14297 ctf_file_close (parent);
14298 free (parentdata);
14299 free (data);
14300 free (symdata);
14301 free (strdata);
14302 return ret;
14303}
14304
32ec8896 14305static bfd_boolean
dda8d76d
NC
14306load_specific_debug_section (enum dwarf_section_display_enum debug,
14307 const Elf_Internal_Shdr * sec,
14308 void * data)
1007acb3 14309{
2cf0635d 14310 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 14311 char buf [64];
dda8d76d 14312 Filedata * filedata = (Filedata *) data;
9abca702 14313
19e6b90e 14314 if (section->start != NULL)
dda8d76d
NC
14315 {
14316 /* If it is already loaded, do nothing. */
14317 if (streq (section->filename, filedata->file_name))
14318 return TRUE;
14319 free (section->start);
14320 }
1007acb3 14321
19e6b90e
L
14322 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
14323 section->address = sec->sh_addr;
06614111 14324 section->user_data = NULL;
dda8d76d
NC
14325 section->filename = filedata->file_name;
14326 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
14327 sec->sh_offset, 1,
14328 sec->sh_size, buf);
59245841
NC
14329 if (section->start == NULL)
14330 section->size = 0;
14331 else
14332 {
77115a4a
L
14333 unsigned char *start = section->start;
14334 dwarf_size_type size = sec->sh_size;
dab394de 14335 dwarf_size_type uncompressed_size = 0;
77115a4a
L
14336
14337 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
14338 {
14339 Elf_Internal_Chdr chdr;
d8024a91
NC
14340 unsigned int compression_header_size;
14341
f53be977
L
14342 if (size < (is_32bit_elf
14343 ? sizeof (Elf32_External_Chdr)
14344 : sizeof (Elf64_External_Chdr)))
d8024a91 14345 {
55be8fd0 14346 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 14347 section->name);
32ec8896 14348 return FALSE;
d8024a91
NC
14349 }
14350
ebdf1ebf 14351 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
14352 if (compression_header_size == 0)
14353 /* An error message will have already been generated
14354 by get_compression_header. */
14355 return FALSE;
d8024a91 14356
813dabb9
L
14357 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
14358 {
14359 warn (_("section '%s' has unsupported compress type: %d\n"),
14360 section->name, chdr.ch_type);
32ec8896 14361 return FALSE;
813dabb9 14362 }
dab394de 14363 uncompressed_size = chdr.ch_size;
77115a4a
L
14364 start += compression_header_size;
14365 size -= compression_header_size;
14366 }
dab394de
L
14367 else if (size > 12 && streq ((char *) start, "ZLIB"))
14368 {
14369 /* Read the zlib header. In this case, it should be "ZLIB"
14370 followed by the uncompressed section size, 8 bytes in
14371 big-endian order. */
14372 uncompressed_size = start[4]; uncompressed_size <<= 8;
14373 uncompressed_size += start[5]; uncompressed_size <<= 8;
14374 uncompressed_size += start[6]; uncompressed_size <<= 8;
14375 uncompressed_size += start[7]; uncompressed_size <<= 8;
14376 uncompressed_size += start[8]; uncompressed_size <<= 8;
14377 uncompressed_size += start[9]; uncompressed_size <<= 8;
14378 uncompressed_size += start[10]; uncompressed_size <<= 8;
14379 uncompressed_size += start[11];
14380 start += 12;
14381 size -= 12;
14382 }
14383
1835f746 14384 if (uncompressed_size)
77115a4a 14385 {
1835f746
NC
14386 if (uncompress_section_contents (&start, uncompressed_size,
14387 &size))
14388 {
14389 /* Free the compressed buffer, update the section buffer
14390 and the section size if uncompress is successful. */
14391 free (section->start);
14392 section->start = start;
14393 }
14394 else
14395 {
14396 error (_("Unable to decompress section %s\n"),
dda8d76d 14397 printable_section_name (filedata, sec));
32ec8896 14398 return FALSE;
1835f746 14399 }
77115a4a 14400 }
bc303e5d 14401
77115a4a 14402 section->size = size;
59245841 14403 }
4a114e3e 14404
1b315056 14405 if (section->start == NULL)
32ec8896 14406 return FALSE;
1b315056 14407
19e6b90e 14408 if (debug_displays [debug].relocate)
32ec8896 14409 {
dda8d76d 14410 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896
NC
14411 & section->reloc_info, & section->num_relocs))
14412 return FALSE;
14413 }
d1c4b12b
NC
14414 else
14415 {
14416 section->reloc_info = NULL;
14417 section->num_relocs = 0;
14418 }
1007acb3 14419
32ec8896 14420 return TRUE;
1007acb3
L
14421}
14422
301a9420
AM
14423#if HAVE_LIBDEBUGINFOD
14424/* Return a hex string representation of the build-id. */
14425unsigned char *
14426get_build_id (void * data)
14427{
14428 Filedata * filedata = (Filedata *)data;
14429 Elf_Internal_Shdr * shdr;
14430 unsigned long i;
14431
55be8fd0
NC
14432 /* Iterate through notes to find note.gnu.build-id.
14433 FIXME: Only the first note in any note section is examined. */
301a9420
AM
14434 for (i = 0, shdr = filedata->section_headers;
14435 i < filedata->file_header.e_shnum && shdr != NULL;
14436 i++, shdr++)
14437 {
14438 if (shdr->sh_type != SHT_NOTE)
14439 continue;
14440
14441 char * next;
14442 char * end;
14443 size_t data_remaining;
14444 size_t min_notesz;
14445 Elf_External_Note * enote;
14446 Elf_Internal_Note inote;
14447
14448 bfd_vma offset = shdr->sh_offset;
14449 bfd_vma align = shdr->sh_addralign;
14450 bfd_vma length = shdr->sh_size;
14451
14452 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
14453 if (enote == NULL)
14454 continue;
14455
14456 if (align < 4)
14457 align = 4;
14458 else if (align != 4 && align != 8)
f761cb13
AM
14459 {
14460 free (enote);
14461 continue;
14462 }
301a9420
AM
14463
14464 end = (char *) enote + length;
14465 data_remaining = end - (char *) enote;
14466
14467 if (!is_ia64_vms (filedata))
14468 {
14469 min_notesz = offsetof (Elf_External_Note, name);
14470 if (data_remaining < min_notesz)
14471 {
55be8fd0
NC
14472 warn (_("\
14473malformed note encountered in section %s whilst scanning for build-id note\n"),
14474 printable_section_name (filedata, shdr));
f761cb13 14475 free (enote);
55be8fd0 14476 continue;
301a9420
AM
14477 }
14478 data_remaining -= min_notesz;
14479
14480 inote.type = BYTE_GET (enote->type);
14481 inote.namesz = BYTE_GET (enote->namesz);
14482 inote.namedata = enote->name;
14483 inote.descsz = BYTE_GET (enote->descsz);
14484 inote.descdata = ((char *) enote
14485 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
14486 inote.descpos = offset + (inote.descdata - (char *) enote);
14487 next = ((char *) enote
14488 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
14489 }
14490 else
14491 {
14492 Elf64_External_VMS_Note *vms_enote;
14493
14494 /* PR binutils/15191
14495 Make sure that there is enough data to read. */
14496 min_notesz = offsetof (Elf64_External_VMS_Note, name);
14497 if (data_remaining < min_notesz)
14498 {
55be8fd0
NC
14499 warn (_("\
14500malformed note encountered in section %s whilst scanning for build-id note\n"),
14501 printable_section_name (filedata, shdr));
f761cb13 14502 free (enote);
55be8fd0 14503 continue;
301a9420
AM
14504 }
14505 data_remaining -= min_notesz;
14506
14507 vms_enote = (Elf64_External_VMS_Note *) enote;
14508 inote.type = BYTE_GET (vms_enote->type);
14509 inote.namesz = BYTE_GET (vms_enote->namesz);
14510 inote.namedata = vms_enote->name;
14511 inote.descsz = BYTE_GET (vms_enote->descsz);
14512 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
14513 inote.descpos = offset + (inote.descdata - (char *) enote);
14514 next = inote.descdata + align_power (inote.descsz, 3);
14515 }
14516
14517 /* Skip malformed notes. */
14518 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
14519 || (size_t) (inote.descdata - inote.namedata) > data_remaining
14520 || (size_t) (next - inote.descdata) < inote.descsz
14521 || ((size_t) (next - inote.descdata)
14522 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
14523 {
55be8fd0
NC
14524 warn (_("\
14525malformed note encountered in section %s whilst scanning for build-id note\n"),
14526 printable_section_name (filedata, shdr));
f761cb13 14527 free (enote);
301a9420
AM
14528 continue;
14529 }
14530
14531 /* Check if this is the build-id note. If so then convert the build-id
14532 bytes to a hex string. */
14533 if (inote.namesz > 0
14534 && const_strneq (inote.namedata, "GNU")
14535 && inote.type == NT_GNU_BUILD_ID)
14536 {
14537 unsigned long j;
14538 char * build_id;
14539
14540 build_id = malloc (inote.descsz * 2 + 1);
14541 if (build_id == NULL)
f761cb13
AM
14542 {
14543 free (enote);
14544 return NULL;
14545 }
301a9420
AM
14546
14547 for (j = 0; j < inote.descsz; ++j)
14548 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
14549 build_id[inote.descsz * 2] = '\0';
f761cb13 14550 free (enote);
301a9420 14551
55be8fd0 14552 return (unsigned char *) build_id;
301a9420 14553 }
f761cb13 14554 free (enote);
301a9420
AM
14555 }
14556
14557 return NULL;
14558}
14559#endif /* HAVE_LIBDEBUGINFOD */
14560
657d0d47
CC
14561/* If this is not NULL, load_debug_section will only look for sections
14562 within the list of sections given here. */
32ec8896 14563static unsigned int * section_subset = NULL;
657d0d47 14564
32ec8896 14565bfd_boolean
dda8d76d 14566load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 14567{
2cf0635d
NC
14568 struct dwarf_section * section = &debug_displays [debug].section;
14569 Elf_Internal_Shdr * sec;
dda8d76d
NC
14570 Filedata * filedata = (Filedata *) data;
14571
f425ec66
NC
14572 /* Without section headers we cannot find any sections. */
14573 if (filedata->section_headers == NULL)
14574 return FALSE;
14575
9c1ce108
AM
14576 if (filedata->string_table == NULL
14577 && filedata->file_header.e_shstrndx != SHN_UNDEF
14578 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
14579 {
14580 Elf_Internal_Shdr * strs;
14581
14582 /* Read in the string table, so that we have section names to scan. */
14583 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
14584
4dff97b2 14585 if (strs != NULL && strs->sh_size != 0)
dda8d76d 14586 {
9c1ce108
AM
14587 filedata->string_table
14588 = (char *) get_data (NULL, filedata, strs->sh_offset,
14589 1, strs->sh_size, _("string table"));
dda8d76d 14590
9c1ce108
AM
14591 filedata->string_table_length
14592 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
14593 }
14594 }
d966045b
DJ
14595
14596 /* Locate the debug section. */
dda8d76d 14597 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
14598 if (sec != NULL)
14599 section->name = section->uncompressed_name;
14600 else
14601 {
dda8d76d 14602 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
14603 if (sec != NULL)
14604 section->name = section->compressed_name;
14605 }
14606 if (sec == NULL)
32ec8896 14607 return FALSE;
d966045b 14608
657d0d47
CC
14609 /* If we're loading from a subset of sections, and we've loaded
14610 a section matching this name before, it's likely that it's a
14611 different one. */
14612 if (section_subset != NULL)
14613 free_debug_section (debug);
14614
dda8d76d 14615 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
14616}
14617
19e6b90e
L
14618void
14619free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 14620{
2cf0635d 14621 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 14622
19e6b90e
L
14623 if (section->start == NULL)
14624 return;
1007acb3 14625
19e6b90e
L
14626 free ((char *) section->start);
14627 section->start = NULL;
14628 section->address = 0;
14629 section->size = 0;
a788aedd
AM
14630
14631 if (section->reloc_info != NULL)
14632 {
14633 free (section->reloc_info);
14634 section->reloc_info = NULL;
14635 section->num_relocs = 0;
14636 }
1007acb3
L
14637}
14638
32ec8896 14639static bfd_boolean
dda8d76d 14640display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 14641{
2cf0635d 14642 char * name = SECTION_NAME (section);
dda8d76d 14643 const char * print_name = printable_section_name (filedata, section);
19e6b90e 14644 bfd_size_type length;
32ec8896 14645 bfd_boolean result = TRUE;
3f5e193b 14646 int i;
1007acb3 14647
19e6b90e
L
14648 length = section->sh_size;
14649 if (length == 0)
1007acb3 14650 {
74e1a04b 14651 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
32ec8896 14652 return TRUE;
1007acb3 14653 }
5dff79d8
NC
14654 if (section->sh_type == SHT_NOBITS)
14655 {
14656 /* There is no point in dumping the contents of a debugging section
14657 which has the NOBITS type - the bits in the file will be random.
14658 This can happen when a file containing a .eh_frame section is
14659 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
14660 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
14661 print_name);
32ec8896 14662 return FALSE;
5dff79d8 14663 }
1007acb3 14664
0112cd26 14665 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 14666 name = ".debug_info";
1007acb3 14667
19e6b90e
L
14668 /* See if we know how to display the contents of this section. */
14669 for (i = 0; i < max; i++)
d85bf2ba
NC
14670 {
14671 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
14672 struct dwarf_section_display * display = debug_displays + i;
14673 struct dwarf_section * sec = & display->section;
d966045b 14674
d85bf2ba
NC
14675 if (streq (sec->uncompressed_name, name)
14676 || (id == line && const_strneq (name, ".debug_line."))
14677 || streq (sec->compressed_name, name))
14678 {
14679 bfd_boolean secondary = (section != find_section (filedata, name));
1007acb3 14680
d85bf2ba
NC
14681 if (secondary)
14682 free_debug_section (id);
dda8d76d 14683
d85bf2ba
NC
14684 if (i == line && const_strneq (name, ".debug_line."))
14685 sec->name = name;
14686 else if (streq (sec->uncompressed_name, name))
14687 sec->name = sec->uncompressed_name;
14688 else
14689 sec->name = sec->compressed_name;
657d0d47 14690
d85bf2ba
NC
14691 if (load_specific_debug_section (id, section, filedata))
14692 {
14693 /* If this debug section is part of a CU/TU set in a .dwp file,
14694 restrict load_debug_section to the sections in that set. */
14695 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 14696
d85bf2ba 14697 result &= display->display (sec, filedata);
657d0d47 14698
d85bf2ba 14699 section_subset = NULL;
1007acb3 14700
d85bf2ba
NC
14701 if (secondary || (id != info && id != abbrev))
14702 free_debug_section (id);
14703 }
14704 break;
14705 }
14706 }
1007acb3 14707
19e6b90e 14708 if (i == max)
1007acb3 14709 {
74e1a04b 14710 printf (_("Unrecognized debug section: %s\n"), print_name);
32ec8896 14711 result = FALSE;
1007acb3
L
14712 }
14713
19e6b90e 14714 return result;
5b18a4bc 14715}
103f02d3 14716
aef1f6d0
DJ
14717/* Set DUMP_SECTS for all sections where dumps were requested
14718 based on section name. */
14719
14720static void
dda8d76d 14721initialise_dumps_byname (Filedata * filedata)
aef1f6d0 14722{
2cf0635d 14723 struct dump_list_entry * cur;
aef1f6d0
DJ
14724
14725 for (cur = dump_sects_byname; cur; cur = cur->next)
14726 {
14727 unsigned int i;
32ec8896 14728 bfd_boolean any = FALSE;
aef1f6d0 14729
dda8d76d
NC
14730 for (i = 0; i < filedata->file_header.e_shnum; i++)
14731 if (streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 14732 {
6431e409 14733 request_dump_bynumber (&filedata->dump, i, cur->type);
32ec8896 14734 any = TRUE;
aef1f6d0
DJ
14735 }
14736
14737 if (!any)
14738 warn (_("Section '%s' was not dumped because it does not exist!\n"),
14739 cur->name);
14740 }
14741}
14742
32ec8896 14743static bfd_boolean
dda8d76d 14744process_section_contents (Filedata * filedata)
5b18a4bc 14745{
2cf0635d 14746 Elf_Internal_Shdr * section;
19e6b90e 14747 unsigned int i;
32ec8896 14748 bfd_boolean res = TRUE;
103f02d3 14749
19e6b90e 14750 if (! do_dump)
32ec8896 14751 return TRUE;
103f02d3 14752
dda8d76d 14753 initialise_dumps_byname (filedata);
aef1f6d0 14754
dda8d76d 14755 for (i = 0, section = filedata->section_headers;
6431e409 14756 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
14757 i++, section++)
14758 {
6431e409 14759 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 14760
19e6b90e 14761#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
14762 if (dump & DISASS_DUMP)
14763 {
14764 if (! disassemble_section (section, filedata))
14765 res = FALSE;
14766 }
19e6b90e 14767#endif
dda8d76d 14768 if (dump & HEX_DUMP)
32ec8896 14769 {
dda8d76d 14770 if (! dump_section_as_bytes (section, filedata, FALSE))
32ec8896
NC
14771 res = FALSE;
14772 }
103f02d3 14773
dda8d76d 14774 if (dump & RELOC_DUMP)
32ec8896 14775 {
dda8d76d 14776 if (! dump_section_as_bytes (section, filedata, TRUE))
32ec8896
NC
14777 res = FALSE;
14778 }
09c11c86 14779
dda8d76d 14780 if (dump & STRING_DUMP)
32ec8896 14781 {
dda8d76d 14782 if (! dump_section_as_strings (section, filedata))
32ec8896
NC
14783 res = FALSE;
14784 }
cf13d699 14785
dda8d76d 14786 if (dump & DEBUG_DUMP)
32ec8896 14787 {
dda8d76d 14788 if (! display_debug_section (i, section, filedata))
32ec8896
NC
14789 res = FALSE;
14790 }
7d9813f1
NA
14791
14792 if (dump & CTF_DUMP)
14793 {
14794 if (! dump_section_as_ctf (section, filedata))
14795 res = FALSE;
14796 }
5b18a4bc 14797 }
103f02d3 14798
19e6b90e
L
14799 /* Check to see if the user requested a
14800 dump of a section that does not exist. */
6431e409 14801 while (i < filedata->dump.num_dump_sects)
0ee3043f 14802 {
6431e409 14803 if (filedata->dump.dump_sects[i])
32ec8896
NC
14804 {
14805 warn (_("Section %d was not dumped because it does not exist!\n"), i);
14806 res = FALSE;
14807 }
0ee3043f
NC
14808 i++;
14809 }
32ec8896
NC
14810
14811 return res;
5b18a4bc 14812}
103f02d3 14813
5b18a4bc 14814static void
19e6b90e 14815process_mips_fpe_exception (int mask)
5b18a4bc 14816{
19e6b90e
L
14817 if (mask)
14818 {
32ec8896
NC
14819 bfd_boolean first = TRUE;
14820
19e6b90e 14821 if (mask & OEX_FPU_INEX)
32ec8896 14822 fputs ("INEX", stdout), first = FALSE;
19e6b90e 14823 if (mask & OEX_FPU_UFLO)
32ec8896 14824 printf ("%sUFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14825 if (mask & OEX_FPU_OFLO)
32ec8896 14826 printf ("%sOFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14827 if (mask & OEX_FPU_DIV0)
32ec8896 14828 printf ("%sDIV0", first ? "" : "|"), first = FALSE;
19e6b90e
L
14829 if (mask & OEX_FPU_INVAL)
14830 printf ("%sINVAL", first ? "" : "|");
14831 }
5b18a4bc 14832 else
19e6b90e 14833 fputs ("0", stdout);
5b18a4bc 14834}
103f02d3 14835
f6f0e17b
NC
14836/* Display's the value of TAG at location P. If TAG is
14837 greater than 0 it is assumed to be an unknown tag, and
14838 a message is printed to this effect. Otherwise it is
14839 assumed that a message has already been printed.
14840
14841 If the bottom bit of TAG is set it assumed to have a
14842 string value, otherwise it is assumed to have an integer
14843 value.
14844
14845 Returns an updated P pointing to the first unread byte
14846 beyond the end of TAG's value.
14847
14848 Reads at or beyond END will not be made. */
14849
14850static unsigned char *
60abdbed 14851display_tag_value (signed int tag,
f6f0e17b
NC
14852 unsigned char * p,
14853 const unsigned char * const end)
14854{
14855 unsigned long val;
14856
14857 if (tag > 0)
14858 printf (" Tag_unknown_%d: ", tag);
14859
14860 if (p >= end)
14861 {
4082ef84 14862 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
14863 }
14864 else if (tag & 1)
14865 {
071436c6
NC
14866 /* PR 17531 file: 027-19978-0.004. */
14867 size_t maxlen = (end - p) - 1;
14868
14869 putchar ('"');
4082ef84
NC
14870 if (maxlen > 0)
14871 {
14872 print_symbol ((int) maxlen, (const char *) p);
14873 p += strnlen ((char *) p, maxlen) + 1;
14874 }
14875 else
14876 {
14877 printf (_("<corrupt string tag>"));
14878 p = (unsigned char *) end;
14879 }
071436c6 14880 printf ("\"\n");
f6f0e17b
NC
14881 }
14882 else
14883 {
cd30bcef 14884 READ_ULEB (val, p, end);
f6f0e17b
NC
14885 printf ("%ld (0x%lx)\n", val, val);
14886 }
14887
4082ef84 14888 assert (p <= end);
f6f0e17b
NC
14889 return p;
14890}
14891
53a346d8
CZ
14892/* ARC ABI attributes section. */
14893
14894static unsigned char *
14895display_arc_attribute (unsigned char * p,
14896 const unsigned char * const end)
14897{
14898 unsigned int tag;
53a346d8
CZ
14899 unsigned int val;
14900
cd30bcef 14901 READ_ULEB (tag, p, end);
53a346d8
CZ
14902
14903 switch (tag)
14904 {
14905 case Tag_ARC_PCS_config:
cd30bcef 14906 READ_ULEB (val, p, end);
53a346d8
CZ
14907 printf (" Tag_ARC_PCS_config: ");
14908 switch (val)
14909 {
14910 case 0:
14911 printf (_("Absent/Non standard\n"));
14912 break;
14913 case 1:
14914 printf (_("Bare metal/mwdt\n"));
14915 break;
14916 case 2:
14917 printf (_("Bare metal/newlib\n"));
14918 break;
14919 case 3:
14920 printf (_("Linux/uclibc\n"));
14921 break;
14922 case 4:
14923 printf (_("Linux/glibc\n"));
14924 break;
14925 default:
14926 printf (_("Unknown\n"));
14927 break;
14928 }
14929 break;
14930
14931 case Tag_ARC_CPU_base:
cd30bcef 14932 READ_ULEB (val, p, end);
53a346d8
CZ
14933 printf (" Tag_ARC_CPU_base: ");
14934 switch (val)
14935 {
14936 default:
14937 case TAG_CPU_NONE:
14938 printf (_("Absent\n"));
14939 break;
14940 case TAG_CPU_ARC6xx:
14941 printf ("ARC6xx\n");
14942 break;
14943 case TAG_CPU_ARC7xx:
14944 printf ("ARC7xx\n");
14945 break;
14946 case TAG_CPU_ARCEM:
14947 printf ("ARCEM\n");
14948 break;
14949 case TAG_CPU_ARCHS:
14950 printf ("ARCHS\n");
14951 break;
14952 }
14953 break;
14954
14955 case Tag_ARC_CPU_variation:
cd30bcef 14956 READ_ULEB (val, p, end);
53a346d8
CZ
14957 printf (" Tag_ARC_CPU_variation: ");
14958 switch (val)
14959 {
14960 default:
14961 if (val > 0 && val < 16)
53a346d8 14962 printf ("Core%d\n", val);
d8cbc93b
JL
14963 else
14964 printf ("Unknown\n");
14965 break;
14966
53a346d8
CZ
14967 case 0:
14968 printf (_("Absent\n"));
14969 break;
14970 }
14971 break;
14972
14973 case Tag_ARC_CPU_name:
14974 printf (" Tag_ARC_CPU_name: ");
14975 p = display_tag_value (-1, p, end);
14976 break;
14977
14978 case Tag_ARC_ABI_rf16:
cd30bcef 14979 READ_ULEB (val, p, end);
53a346d8
CZ
14980 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
14981 break;
14982
14983 case Tag_ARC_ABI_osver:
cd30bcef 14984 READ_ULEB (val, p, end);
53a346d8
CZ
14985 printf (" Tag_ARC_ABI_osver: v%d\n", val);
14986 break;
14987
14988 case Tag_ARC_ABI_pic:
14989 case Tag_ARC_ABI_sda:
cd30bcef 14990 READ_ULEB (val, p, end);
53a346d8
CZ
14991 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
14992 : " Tag_ARC_ABI_pic: ");
14993 switch (val)
14994 {
14995 case 0:
14996 printf (_("Absent\n"));
14997 break;
14998 case 1:
14999 printf ("MWDT\n");
15000 break;
15001 case 2:
15002 printf ("GNU\n");
15003 break;
15004 default:
15005 printf (_("Unknown\n"));
15006 break;
15007 }
15008 break;
15009
15010 case Tag_ARC_ABI_tls:
cd30bcef 15011 READ_ULEB (val, p, end);
53a346d8
CZ
15012 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
15013 break;
15014
15015 case Tag_ARC_ABI_enumsize:
cd30bcef 15016 READ_ULEB (val, p, end);
53a346d8
CZ
15017 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
15018 _("smallest"));
15019 break;
15020
15021 case Tag_ARC_ABI_exceptions:
cd30bcef 15022 READ_ULEB (val, p, end);
53a346d8
CZ
15023 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
15024 : _("default"));
15025 break;
15026
15027 case Tag_ARC_ABI_double_size:
cd30bcef 15028 READ_ULEB (val, p, end);
53a346d8
CZ
15029 printf (" Tag_ARC_ABI_double_size: %d\n", val);
15030 break;
15031
15032 case Tag_ARC_ISA_config:
15033 printf (" Tag_ARC_ISA_config: ");
15034 p = display_tag_value (-1, p, end);
15035 break;
15036
15037 case Tag_ARC_ISA_apex:
15038 printf (" Tag_ARC_ISA_apex: ");
15039 p = display_tag_value (-1, p, end);
15040 break;
15041
15042 case Tag_ARC_ISA_mpy_option:
cd30bcef 15043 READ_ULEB (val, p, end);
53a346d8
CZ
15044 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
15045 break;
15046
db1e1b45 15047 case Tag_ARC_ATR_version:
cd30bcef 15048 READ_ULEB (val, p, end);
db1e1b45 15049 printf (" Tag_ARC_ATR_version: %d\n", val);
15050 break;
15051
53a346d8
CZ
15052 default:
15053 return display_tag_value (tag & 1, p, end);
15054 }
15055
15056 return p;
15057}
15058
11c1ff18
PB
15059/* ARM EABI attributes section. */
15060typedef struct
15061{
70e99720 15062 unsigned int tag;
2cf0635d 15063 const char * name;
11c1ff18 15064 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 15065 unsigned int type;
2cf0635d 15066 const char ** table;
11c1ff18
PB
15067} arm_attr_public_tag;
15068
2cf0635d 15069static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 15070 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 15071 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 15072 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
2cf0635d
NC
15073static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
15074static const char * arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 15075 {"No", "Thumb-1", "Thumb-2", "Yes"};
75375b3e 15076static const char * arm_attr_tag_FP_arch[] =
bca38921 15077 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 15078 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 15079static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 15080static const char * arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
15081 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
15082 "NEON for ARMv8.1"};
2cf0635d 15083static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
15084 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
15085 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 15086static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 15087 {"V6", "SB", "TLS", "Unused"};
2cf0635d 15088static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 15089 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 15090static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 15091 {"Absolute", "PC-relative", "None"};
2cf0635d 15092static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 15093 {"None", "direct", "GOT-indirect"};
2cf0635d 15094static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 15095 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
15096static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
15097static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 15098 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
15099static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
15100static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
15101static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 15102 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 15103static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 15104 {"Unused", "small", "int", "forced to int"};
2cf0635d 15105static const char * arm_attr_tag_ABI_HardFP_use[] =
99654aaf 15106 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
2cf0635d 15107static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 15108 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 15109static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 15110 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 15111static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
15112 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15113 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 15114static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
15115 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15116 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 15117static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 15118static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 15119 {"Not Allowed", "Allowed"};
2cf0635d 15120static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 15121 {"None", "IEEE 754", "Alternative Format"};
15afaa63
TP
15122static const char * arm_attr_tag_DSP_extension[] =
15123 {"Follow architecture", "Allowed"};
dd24e3da 15124static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
15125 {"Not Allowed", "Allowed"};
15126static const char * arm_attr_tag_DIV_use[] =
dd24e3da 15127 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 15128 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
15129static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
15130static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 15131 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 15132 "TrustZone and Virtualization Extensions"};
dd24e3da 15133static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 15134 {"Not Allowed", "Allowed"};
11c1ff18 15135
a7ad558c
AV
15136static const char * arm_attr_tag_MVE_arch[] =
15137 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
15138
11c1ff18
PB
15139#define LOOKUP(id, name) \
15140 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 15141static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
15142{
15143 {4, "CPU_raw_name", 1, NULL},
15144 {5, "CPU_name", 1, NULL},
15145 LOOKUP(6, CPU_arch),
15146 {7, "CPU_arch_profile", 0, NULL},
15147 LOOKUP(8, ARM_ISA_use),
15148 LOOKUP(9, THUMB_ISA_use),
75375b3e 15149 LOOKUP(10, FP_arch),
11c1ff18 15150 LOOKUP(11, WMMX_arch),
f5f53991
AS
15151 LOOKUP(12, Advanced_SIMD_arch),
15152 LOOKUP(13, PCS_config),
11c1ff18
PB
15153 LOOKUP(14, ABI_PCS_R9_use),
15154 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 15155 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
15156 LOOKUP(17, ABI_PCS_GOT_use),
15157 LOOKUP(18, ABI_PCS_wchar_t),
15158 LOOKUP(19, ABI_FP_rounding),
15159 LOOKUP(20, ABI_FP_denormal),
15160 LOOKUP(21, ABI_FP_exceptions),
15161 LOOKUP(22, ABI_FP_user_exceptions),
15162 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
15163 {24, "ABI_align_needed", 0, NULL},
15164 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
15165 LOOKUP(26, ABI_enum_size),
15166 LOOKUP(27, ABI_HardFP_use),
15167 LOOKUP(28, ABI_VFP_args),
15168 LOOKUP(29, ABI_WMMX_args),
15169 LOOKUP(30, ABI_optimization_goals),
15170 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 15171 {32, "compatibility", 0, NULL},
f5f53991 15172 LOOKUP(34, CPU_unaligned_access),
75375b3e 15173 LOOKUP(36, FP_HP_extension),
8e79c3df 15174 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
15175 LOOKUP(42, MPextension_use),
15176 LOOKUP(44, DIV_use),
15afaa63 15177 LOOKUP(46, DSP_extension),
a7ad558c 15178 LOOKUP(48, MVE_arch),
f5f53991
AS
15179 {64, "nodefaults", 0, NULL},
15180 {65, "also_compatible_with", 0, NULL},
15181 LOOKUP(66, T2EE_use),
15182 {67, "conformance", 1, NULL},
15183 LOOKUP(68, Virtualization_use),
cd21e546 15184 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
15185};
15186#undef LOOKUP
15187
11c1ff18 15188static unsigned char *
f6f0e17b
NC
15189display_arm_attribute (unsigned char * p,
15190 const unsigned char * const end)
11c1ff18 15191{
70e99720 15192 unsigned int tag;
70e99720 15193 unsigned int val;
2cf0635d 15194 arm_attr_public_tag * attr;
11c1ff18 15195 unsigned i;
70e99720 15196 unsigned int type;
11c1ff18 15197
cd30bcef 15198 READ_ULEB (tag, p, end);
11c1ff18 15199 attr = NULL;
2cf0635d 15200 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
15201 {
15202 if (arm_attr_public_tags[i].tag == tag)
15203 {
15204 attr = &arm_attr_public_tags[i];
15205 break;
15206 }
15207 }
15208
15209 if (attr)
15210 {
15211 printf (" Tag_%s: ", attr->name);
15212 switch (attr->type)
15213 {
15214 case 0:
15215 switch (tag)
15216 {
15217 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 15218 READ_ULEB (val, p, end);
11c1ff18
PB
15219 switch (val)
15220 {
2b692964
NC
15221 case 0: printf (_("None\n")); break;
15222 case 'A': printf (_("Application\n")); break;
15223 case 'R': printf (_("Realtime\n")); break;
15224 case 'M': printf (_("Microcontroller\n")); break;
15225 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
15226 default: printf ("??? (%d)\n", val); break;
15227 }
15228 break;
15229
75375b3e 15230 case 24: /* Tag_align_needed. */
cd30bcef 15231 READ_ULEB (val, p, end);
75375b3e
MGD
15232 switch (val)
15233 {
2b692964
NC
15234 case 0: printf (_("None\n")); break;
15235 case 1: printf (_("8-byte\n")); break;
15236 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
15237 case 3: printf ("??? 3\n"); break;
15238 default:
15239 if (val <= 12)
dd24e3da 15240 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15241 1 << val);
15242 else
15243 printf ("??? (%d)\n", val);
15244 break;
15245 }
15246 break;
15247
15248 case 25: /* Tag_align_preserved. */
cd30bcef 15249 READ_ULEB (val, p, end);
75375b3e
MGD
15250 switch (val)
15251 {
2b692964
NC
15252 case 0: printf (_("None\n")); break;
15253 case 1: printf (_("8-byte, except leaf SP\n")); break;
15254 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
15255 case 3: printf ("??? 3\n"); break;
15256 default:
15257 if (val <= 12)
dd24e3da 15258 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15259 1 << val);
15260 else
15261 printf ("??? (%d)\n", val);
15262 break;
15263 }
15264 break;
15265
11c1ff18 15266 case 32: /* Tag_compatibility. */
071436c6 15267 {
cd30bcef 15268 READ_ULEB (val, p, end);
071436c6 15269 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
15270 if (p < end - 1)
15271 {
15272 size_t maxlen = (end - p) - 1;
15273
15274 print_symbol ((int) maxlen, (const char *) p);
15275 p += strnlen ((char *) p, maxlen) + 1;
15276 }
15277 else
15278 {
15279 printf (_("<corrupt>"));
15280 p = (unsigned char *) end;
15281 }
071436c6 15282 putchar ('\n');
071436c6 15283 }
11c1ff18
PB
15284 break;
15285
f5f53991 15286 case 64: /* Tag_nodefaults. */
541a3cbd
NC
15287 /* PR 17531: file: 001-505008-0.01. */
15288 if (p < end)
15289 p++;
2b692964 15290 printf (_("True\n"));
f5f53991
AS
15291 break;
15292
15293 case 65: /* Tag_also_compatible_with. */
cd30bcef 15294 READ_ULEB (val, p, end);
f5f53991
AS
15295 if (val == 6 /* Tag_CPU_arch. */)
15296 {
cd30bcef 15297 READ_ULEB (val, p, end);
071436c6 15298 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
15299 printf ("??? (%d)\n", val);
15300 else
15301 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
15302 }
15303 else
15304 printf ("???\n");
071436c6
NC
15305 while (p < end && *(p++) != '\0' /* NUL terminator. */)
15306 ;
f5f53991
AS
15307 break;
15308
11c1ff18 15309 default:
bee0ee85
NC
15310 printf (_("<unknown: %d>\n"), tag);
15311 break;
11c1ff18
PB
15312 }
15313 return p;
15314
15315 case 1:
f6f0e17b 15316 return display_tag_value (-1, p, end);
11c1ff18 15317 case 2:
f6f0e17b 15318 return display_tag_value (0, p, end);
11c1ff18
PB
15319
15320 default:
15321 assert (attr->type & 0x80);
cd30bcef 15322 READ_ULEB (val, p, end);
11c1ff18
PB
15323 type = attr->type & 0x7f;
15324 if (val >= type)
15325 printf ("??? (%d)\n", val);
15326 else
15327 printf ("%s\n", attr->table[val]);
15328 return p;
15329 }
15330 }
11c1ff18 15331
f6f0e17b 15332 return display_tag_value (tag, p, end);
11c1ff18
PB
15333}
15334
104d59d1 15335static unsigned char *
60bca95a 15336display_gnu_attribute (unsigned char * p,
60abdbed 15337 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 15338 const unsigned char * const end)
104d59d1 15339{
cd30bcef 15340 unsigned int tag;
60abdbed 15341 unsigned int val;
104d59d1 15342
cd30bcef 15343 READ_ULEB (tag, p, end);
104d59d1
JM
15344
15345 /* Tag_compatibility is the only generic GNU attribute defined at
15346 present. */
15347 if (tag == 32)
15348 {
cd30bcef 15349 READ_ULEB (val, p, end);
071436c6
NC
15350
15351 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
15352 if (p == end)
15353 {
071436c6 15354 printf (_("<corrupt>\n"));
f6f0e17b
NC
15355 warn (_("corrupt vendor attribute\n"));
15356 }
15357 else
15358 {
4082ef84
NC
15359 if (p < end - 1)
15360 {
15361 size_t maxlen = (end - p) - 1;
071436c6 15362
4082ef84
NC
15363 print_symbol ((int) maxlen, (const char *) p);
15364 p += strnlen ((char *) p, maxlen) + 1;
15365 }
15366 else
15367 {
15368 printf (_("<corrupt>"));
15369 p = (unsigned char *) end;
15370 }
071436c6 15371 putchar ('\n');
f6f0e17b 15372 }
104d59d1
JM
15373 return p;
15374 }
15375
15376 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 15377 return display_proc_gnu_attribute (p, tag, end);
104d59d1 15378
f6f0e17b 15379 return display_tag_value (tag, p, end);
104d59d1
JM
15380}
15381
34c8bcba 15382static unsigned char *
f6f0e17b 15383display_power_gnu_attribute (unsigned char * p,
60abdbed 15384 unsigned int tag,
f6f0e17b 15385 const unsigned char * const end)
34c8bcba 15386{
005d79fd 15387 unsigned int val;
34c8bcba
JM
15388
15389 if (tag == Tag_GNU_Power_ABI_FP)
15390 {
34c8bcba 15391 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 15392 if (p == end)
005d79fd
AM
15393 {
15394 printf (_("<corrupt>\n"));
15395 return p;
15396 }
cd30bcef 15397 READ_ULEB (val, p, end);
60bca95a 15398
005d79fd
AM
15399 if (val > 15)
15400 printf ("(%#x), ", val);
15401
15402 switch (val & 3)
34c8bcba
JM
15403 {
15404 case 0:
005d79fd 15405 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
15406 break;
15407 case 1:
005d79fd 15408 printf (_("hard float, "));
34c8bcba
JM
15409 break;
15410 case 2:
005d79fd 15411 printf (_("soft float, "));
34c8bcba 15412 break;
3c7b9897 15413 case 3:
005d79fd 15414 printf (_("single-precision hard float, "));
3c7b9897 15415 break;
005d79fd
AM
15416 }
15417
15418 switch (val & 0xC)
15419 {
15420 case 0:
15421 printf (_("unspecified long double\n"));
15422 break;
15423 case 4:
15424 printf (_("128-bit IBM long double\n"));
15425 break;
15426 case 8:
15427 printf (_("64-bit long double\n"));
15428 break;
15429 case 12:
15430 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
15431 break;
15432 }
15433 return p;
005d79fd 15434 }
34c8bcba 15435
c6e65352
DJ
15436 if (tag == Tag_GNU_Power_ABI_Vector)
15437 {
c6e65352 15438 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 15439 if (p == end)
005d79fd
AM
15440 {
15441 printf (_("<corrupt>\n"));
15442 return p;
15443 }
cd30bcef 15444 READ_ULEB (val, p, end);
005d79fd
AM
15445
15446 if (val > 3)
15447 printf ("(%#x), ", val);
15448
15449 switch (val & 3)
c6e65352
DJ
15450 {
15451 case 0:
005d79fd 15452 printf (_("unspecified\n"));
c6e65352
DJ
15453 break;
15454 case 1:
005d79fd 15455 printf (_("generic\n"));
c6e65352
DJ
15456 break;
15457 case 2:
15458 printf ("AltiVec\n");
15459 break;
15460 case 3:
15461 printf ("SPE\n");
15462 break;
c6e65352
DJ
15463 }
15464 return p;
005d79fd 15465 }
c6e65352 15466
f82e0623
NF
15467 if (tag == Tag_GNU_Power_ABI_Struct_Return)
15468 {
005d79fd 15469 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 15470 if (p == end)
f6f0e17b 15471 {
005d79fd 15472 printf (_("<corrupt>\n"));
f6f0e17b
NC
15473 return p;
15474 }
cd30bcef 15475 READ_ULEB (val, p, end);
0b4362b0 15476
005d79fd
AM
15477 if (val > 2)
15478 printf ("(%#x), ", val);
15479
15480 switch (val & 3)
15481 {
15482 case 0:
15483 printf (_("unspecified\n"));
15484 break;
15485 case 1:
15486 printf ("r3/r4\n");
15487 break;
15488 case 2:
15489 printf (_("memory\n"));
15490 break;
15491 case 3:
15492 printf ("???\n");
15493 break;
15494 }
f82e0623
NF
15495 return p;
15496 }
15497
f6f0e17b 15498 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
15499}
15500
643f7afb
AK
15501static unsigned char *
15502display_s390_gnu_attribute (unsigned char * p,
60abdbed 15503 unsigned int tag,
643f7afb
AK
15504 const unsigned char * const end)
15505{
cd30bcef 15506 unsigned int val;
643f7afb
AK
15507
15508 if (tag == Tag_GNU_S390_ABI_Vector)
15509 {
643f7afb 15510 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 15511 READ_ULEB (val, p, end);
643f7afb
AK
15512
15513 switch (val)
15514 {
15515 case 0:
15516 printf (_("any\n"));
15517 break;
15518 case 1:
15519 printf (_("software\n"));
15520 break;
15521 case 2:
15522 printf (_("hardware\n"));
15523 break;
15524 default:
15525 printf ("??? (%d)\n", val);
15526 break;
15527 }
15528 return p;
15529 }
15530
15531 return display_tag_value (tag & 1, p, end);
15532}
15533
9e8c70f9 15534static void
60abdbed 15535display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
15536{
15537 if (mask)
15538 {
32ec8896 15539 bfd_boolean first = TRUE;
071436c6 15540
9e8c70f9 15541 if (mask & ELF_SPARC_HWCAP_MUL32)
32ec8896 15542 fputs ("mul32", stdout), first = FALSE;
9e8c70f9 15543 if (mask & ELF_SPARC_HWCAP_DIV32)
32ec8896 15544 printf ("%sdiv32", first ? "" : "|"), first = FALSE;
9e8c70f9 15545 if (mask & ELF_SPARC_HWCAP_FSMULD)
32ec8896 15546 printf ("%sfsmuld", first ? "" : "|"), first = FALSE;
9e8c70f9 15547 if (mask & ELF_SPARC_HWCAP_V8PLUS)
32ec8896 15548 printf ("%sv8plus", first ? "" : "|"), first = FALSE;
9e8c70f9 15549 if (mask & ELF_SPARC_HWCAP_POPC)
32ec8896 15550 printf ("%spopc", first ? "" : "|"), first = FALSE;
9e8c70f9 15551 if (mask & ELF_SPARC_HWCAP_VIS)
32ec8896 15552 printf ("%svis", first ? "" : "|"), first = FALSE;
9e8c70f9 15553 if (mask & ELF_SPARC_HWCAP_VIS2)
32ec8896 15554 printf ("%svis2", first ? "" : "|"), first = FALSE;
9e8c70f9 15555 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
32ec8896 15556 printf ("%sASIBlkInit", first ? "" : "|"), first = FALSE;
9e8c70f9 15557 if (mask & ELF_SPARC_HWCAP_FMAF)
32ec8896 15558 printf ("%sfmaf", first ? "" : "|"), first = FALSE;
9e8c70f9 15559 if (mask & ELF_SPARC_HWCAP_VIS3)
32ec8896 15560 printf ("%svis3", first ? "" : "|"), first = FALSE;
9e8c70f9 15561 if (mask & ELF_SPARC_HWCAP_HPC)
32ec8896 15562 printf ("%shpc", first ? "" : "|"), first = FALSE;
9e8c70f9 15563 if (mask & ELF_SPARC_HWCAP_RANDOM)
32ec8896 15564 printf ("%srandom", first ? "" : "|"), first = FALSE;
9e8c70f9 15565 if (mask & ELF_SPARC_HWCAP_TRANS)
32ec8896 15566 printf ("%strans", first ? "" : "|"), first = FALSE;
9e8c70f9 15567 if (mask & ELF_SPARC_HWCAP_FJFMAU)
32ec8896 15568 printf ("%sfjfmau", first ? "" : "|"), first = FALSE;
9e8c70f9 15569 if (mask & ELF_SPARC_HWCAP_IMA)
32ec8896 15570 printf ("%sima", first ? "" : "|"), first = FALSE;
9e8c70f9 15571 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
32ec8896 15572 printf ("%scspare", first ? "" : "|"), first = FALSE;
9e8c70f9
DM
15573 }
15574 else
071436c6
NC
15575 fputc ('0', stdout);
15576 fputc ('\n', stdout);
9e8c70f9
DM
15577}
15578
3d68f91c 15579static void
60abdbed 15580display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
15581{
15582 if (mask)
15583 {
32ec8896 15584 bfd_boolean first = TRUE;
071436c6 15585
3d68f91c 15586 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
32ec8896 15587 fputs ("fjathplus", stdout), first = FALSE;
3d68f91c 15588 if (mask & ELF_SPARC_HWCAP2_VIS3B)
32ec8896 15589 printf ("%svis3b", first ? "" : "|"), first = FALSE;
3d68f91c 15590 if (mask & ELF_SPARC_HWCAP2_ADP)
32ec8896 15591 printf ("%sadp", first ? "" : "|"), first = FALSE;
3d68f91c 15592 if (mask & ELF_SPARC_HWCAP2_SPARC5)
32ec8896 15593 printf ("%ssparc5", first ? "" : "|"), first = FALSE;
3d68f91c 15594 if (mask & ELF_SPARC_HWCAP2_MWAIT)
32ec8896 15595 printf ("%smwait", first ? "" : "|"), first = FALSE;
3d68f91c 15596 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
32ec8896 15597 printf ("%sxmpmul", first ? "" : "|"), first = FALSE;
3d68f91c 15598 if (mask & ELF_SPARC_HWCAP2_XMONT)
32ec8896 15599 printf ("%sxmont2", first ? "" : "|"), first = FALSE;
3d68f91c 15600 if (mask & ELF_SPARC_HWCAP2_NSEC)
32ec8896 15601 printf ("%snsec", first ? "" : "|"), first = FALSE;
3d68f91c 15602 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
32ec8896 15603 printf ("%sfjathhpc", first ? "" : "|"), first = FALSE;
3d68f91c 15604 if (mask & ELF_SPARC_HWCAP2_FJDES)
32ec8896 15605 printf ("%sfjdes", first ? "" : "|"), first = FALSE;
3d68f91c 15606 if (mask & ELF_SPARC_HWCAP2_FJAES)
32ec8896 15607 printf ("%sfjaes", first ? "" : "|"), first = FALSE;
3d68f91c
JM
15608 }
15609 else
071436c6
NC
15610 fputc ('0', stdout);
15611 fputc ('\n', stdout);
3d68f91c
JM
15612}
15613
9e8c70f9 15614static unsigned char *
f6f0e17b 15615display_sparc_gnu_attribute (unsigned char * p,
60abdbed 15616 unsigned int tag,
f6f0e17b 15617 const unsigned char * const end)
9e8c70f9 15618{
cd30bcef 15619 unsigned int val;
3d68f91c 15620
9e8c70f9
DM
15621 if (tag == Tag_GNU_Sparc_HWCAPS)
15622 {
cd30bcef 15623 READ_ULEB (val, p, end);
9e8c70f9 15624 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
15625 display_sparc_hwcaps (val);
15626 return p;
3d68f91c
JM
15627 }
15628 if (tag == Tag_GNU_Sparc_HWCAPS2)
15629 {
cd30bcef 15630 READ_ULEB (val, p, end);
3d68f91c
JM
15631 printf (" Tag_GNU_Sparc_HWCAPS2: ");
15632 display_sparc_hwcaps2 (val);
15633 return p;
15634 }
9e8c70f9 15635
f6f0e17b 15636 return display_tag_value (tag, p, end);
9e8c70f9
DM
15637}
15638
351cdf24 15639static void
32ec8896 15640print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
15641{
15642 switch (val)
15643 {
15644 case Val_GNU_MIPS_ABI_FP_ANY:
15645 printf (_("Hard or soft float\n"));
15646 break;
15647 case Val_GNU_MIPS_ABI_FP_DOUBLE:
15648 printf (_("Hard float (double precision)\n"));
15649 break;
15650 case Val_GNU_MIPS_ABI_FP_SINGLE:
15651 printf (_("Hard float (single precision)\n"));
15652 break;
15653 case Val_GNU_MIPS_ABI_FP_SOFT:
15654 printf (_("Soft float\n"));
15655 break;
15656 case Val_GNU_MIPS_ABI_FP_OLD_64:
15657 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
15658 break;
15659 case Val_GNU_MIPS_ABI_FP_XX:
15660 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
15661 break;
15662 case Val_GNU_MIPS_ABI_FP_64:
15663 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
15664 break;
15665 case Val_GNU_MIPS_ABI_FP_64A:
15666 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
15667 break;
3350cc01
CM
15668 case Val_GNU_MIPS_ABI_FP_NAN2008:
15669 printf (_("NaN 2008 compatibility\n"));
15670 break;
351cdf24
MF
15671 default:
15672 printf ("??? (%d)\n", val);
15673 break;
15674 }
15675}
15676
2cf19d5c 15677static unsigned char *
f6f0e17b 15678display_mips_gnu_attribute (unsigned char * p,
60abdbed 15679 unsigned int tag,
f6f0e17b 15680 const unsigned char * const end)
2cf19d5c 15681{
2cf19d5c
JM
15682 if (tag == Tag_GNU_MIPS_ABI_FP)
15683 {
32ec8896 15684 unsigned int val;
f6f0e17b 15685
2cf19d5c 15686 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 15687 READ_ULEB (val, p, end);
351cdf24 15688 print_mips_fp_abi_value (val);
2cf19d5c
JM
15689 return p;
15690 }
15691
a9f58168
CF
15692 if (tag == Tag_GNU_MIPS_ABI_MSA)
15693 {
32ec8896 15694 unsigned int val;
a9f58168 15695
a9f58168 15696 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 15697 READ_ULEB (val, p, end);
a9f58168
CF
15698
15699 switch (val)
15700 {
15701 case Val_GNU_MIPS_ABI_MSA_ANY:
15702 printf (_("Any MSA or not\n"));
15703 break;
15704 case Val_GNU_MIPS_ABI_MSA_128:
15705 printf (_("128-bit MSA\n"));
15706 break;
15707 default:
15708 printf ("??? (%d)\n", val);
15709 break;
15710 }
15711 return p;
15712 }
15713
f6f0e17b 15714 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
15715}
15716
59e6276b 15717static unsigned char *
f6f0e17b
NC
15718display_tic6x_attribute (unsigned char * p,
15719 const unsigned char * const end)
59e6276b 15720{
60abdbed 15721 unsigned int tag;
cd30bcef 15722 unsigned int val;
59e6276b 15723
cd30bcef 15724 READ_ULEB (tag, p, end);
59e6276b
JM
15725
15726 switch (tag)
15727 {
75fa6dc1 15728 case Tag_ISA:
75fa6dc1 15729 printf (" Tag_ISA: ");
cd30bcef 15730 READ_ULEB (val, p, end);
59e6276b
JM
15731
15732 switch (val)
15733 {
75fa6dc1 15734 case C6XABI_Tag_ISA_none:
59e6276b
JM
15735 printf (_("None\n"));
15736 break;
75fa6dc1 15737 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
15738 printf ("C62x\n");
15739 break;
75fa6dc1 15740 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
15741 printf ("C67x\n");
15742 break;
75fa6dc1 15743 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
15744 printf ("C67x+\n");
15745 break;
75fa6dc1 15746 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
15747 printf ("C64x\n");
15748 break;
75fa6dc1 15749 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
15750 printf ("C64x+\n");
15751 break;
75fa6dc1 15752 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
15753 printf ("C674x\n");
15754 break;
15755 default:
15756 printf ("??? (%d)\n", val);
15757 break;
15758 }
15759 return p;
15760
87779176 15761 case Tag_ABI_wchar_t:
87779176 15762 printf (" Tag_ABI_wchar_t: ");
cd30bcef 15763 READ_ULEB (val, p, end);
87779176
JM
15764 switch (val)
15765 {
15766 case 0:
15767 printf (_("Not used\n"));
15768 break;
15769 case 1:
15770 printf (_("2 bytes\n"));
15771 break;
15772 case 2:
15773 printf (_("4 bytes\n"));
15774 break;
15775 default:
15776 printf ("??? (%d)\n", val);
15777 break;
15778 }
15779 return p;
15780
15781 case Tag_ABI_stack_align_needed:
87779176 15782 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 15783 READ_ULEB (val, p, end);
87779176
JM
15784 switch (val)
15785 {
15786 case 0:
15787 printf (_("8-byte\n"));
15788 break;
15789 case 1:
15790 printf (_("16-byte\n"));
15791 break;
15792 default:
15793 printf ("??? (%d)\n", val);
15794 break;
15795 }
15796 return p;
15797
15798 case Tag_ABI_stack_align_preserved:
cd30bcef 15799 READ_ULEB (val, p, end);
87779176
JM
15800 printf (" Tag_ABI_stack_align_preserved: ");
15801 switch (val)
15802 {
15803 case 0:
15804 printf (_("8-byte\n"));
15805 break;
15806 case 1:
15807 printf (_("16-byte\n"));
15808 break;
15809 default:
15810 printf ("??? (%d)\n", val);
15811 break;
15812 }
15813 return p;
15814
b5593623 15815 case Tag_ABI_DSBT:
cd30bcef 15816 READ_ULEB (val, p, end);
b5593623
JM
15817 printf (" Tag_ABI_DSBT: ");
15818 switch (val)
15819 {
15820 case 0:
15821 printf (_("DSBT addressing not used\n"));
15822 break;
15823 case 1:
15824 printf (_("DSBT addressing used\n"));
15825 break;
15826 default:
15827 printf ("??? (%d)\n", val);
15828 break;
15829 }
15830 return p;
15831
87779176 15832 case Tag_ABI_PID:
cd30bcef 15833 READ_ULEB (val, p, end);
87779176
JM
15834 printf (" Tag_ABI_PID: ");
15835 switch (val)
15836 {
15837 case 0:
15838 printf (_("Data addressing position-dependent\n"));
15839 break;
15840 case 1:
15841 printf (_("Data addressing position-independent, GOT near DP\n"));
15842 break;
15843 case 2:
15844 printf (_("Data addressing position-independent, GOT far from DP\n"));
15845 break;
15846 default:
15847 printf ("??? (%d)\n", val);
15848 break;
15849 }
15850 return p;
15851
15852 case Tag_ABI_PIC:
cd30bcef 15853 READ_ULEB (val, p, end);
87779176
JM
15854 printf (" Tag_ABI_PIC: ");
15855 switch (val)
15856 {
15857 case 0:
15858 printf (_("Code addressing position-dependent\n"));
15859 break;
15860 case 1:
15861 printf (_("Code addressing position-independent\n"));
15862 break;
15863 default:
15864 printf ("??? (%d)\n", val);
15865 break;
15866 }
15867 return p;
15868
15869 case Tag_ABI_array_object_alignment:
cd30bcef 15870 READ_ULEB (val, p, end);
87779176
JM
15871 printf (" Tag_ABI_array_object_alignment: ");
15872 switch (val)
15873 {
15874 case 0:
15875 printf (_("8-byte\n"));
15876 break;
15877 case 1:
15878 printf (_("4-byte\n"));
15879 break;
15880 case 2:
15881 printf (_("16-byte\n"));
15882 break;
15883 default:
15884 printf ("??? (%d)\n", val);
15885 break;
15886 }
15887 return p;
15888
15889 case Tag_ABI_array_object_align_expected:
cd30bcef 15890 READ_ULEB (val, p, end);
87779176
JM
15891 printf (" Tag_ABI_array_object_align_expected: ");
15892 switch (val)
15893 {
15894 case 0:
15895 printf (_("8-byte\n"));
15896 break;
15897 case 1:
15898 printf (_("4-byte\n"));
15899 break;
15900 case 2:
15901 printf (_("16-byte\n"));
15902 break;
15903 default:
15904 printf ("??? (%d)\n", val);
15905 break;
15906 }
15907 return p;
15908
3cbd1c06 15909 case Tag_ABI_compatibility:
071436c6 15910 {
cd30bcef 15911 READ_ULEB (val, p, end);
071436c6 15912 printf (" Tag_ABI_compatibility: ");
071436c6 15913 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
15914 if (p < end - 1)
15915 {
15916 size_t maxlen = (end - p) - 1;
15917
15918 print_symbol ((int) maxlen, (const char *) p);
15919 p += strnlen ((char *) p, maxlen) + 1;
15920 }
15921 else
15922 {
15923 printf (_("<corrupt>"));
15924 p = (unsigned char *) end;
15925 }
071436c6 15926 putchar ('\n');
071436c6
NC
15927 return p;
15928 }
87779176
JM
15929
15930 case Tag_ABI_conformance:
071436c6 15931 {
4082ef84
NC
15932 printf (" Tag_ABI_conformance: \"");
15933 if (p < end - 1)
15934 {
15935 size_t maxlen = (end - p) - 1;
071436c6 15936
4082ef84
NC
15937 print_symbol ((int) maxlen, (const char *) p);
15938 p += strnlen ((char *) p, maxlen) + 1;
15939 }
15940 else
15941 {
15942 printf (_("<corrupt>"));
15943 p = (unsigned char *) end;
15944 }
071436c6 15945 printf ("\"\n");
071436c6
NC
15946 return p;
15947 }
59e6276b
JM
15948 }
15949
f6f0e17b
NC
15950 return display_tag_value (tag, p, end);
15951}
59e6276b 15952
f6f0e17b 15953static void
60abdbed 15954display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
15955{
15956 unsigned long addr = 0;
15957 size_t bytes = end - p;
15958
feceaa59 15959 assert (end >= p);
f6f0e17b 15960 while (bytes)
87779176 15961 {
f6f0e17b
NC
15962 int j;
15963 int k;
15964 int lbytes = (bytes > 16 ? 16 : bytes);
15965
15966 printf (" 0x%8.8lx ", addr);
15967
15968 for (j = 0; j < 16; j++)
15969 {
15970 if (j < lbytes)
15971 printf ("%2.2x", p[j]);
15972 else
15973 printf (" ");
15974
15975 if ((j & 3) == 3)
15976 printf (" ");
15977 }
15978
15979 for (j = 0; j < lbytes; j++)
15980 {
15981 k = p[j];
15982 if (k >= ' ' && k < 0x7f)
15983 printf ("%c", k);
15984 else
15985 printf (".");
15986 }
15987
15988 putchar ('\n');
15989
15990 p += lbytes;
15991 bytes -= lbytes;
15992 addr += lbytes;
87779176 15993 }
59e6276b 15994
f6f0e17b 15995 putchar ('\n');
59e6276b
JM
15996}
15997
13761a11
NC
15998static unsigned char *
15999display_msp430x_attribute (unsigned char * p,
16000 const unsigned char * const end)
16001{
60abdbed
NC
16002 unsigned int val;
16003 unsigned int tag;
13761a11 16004
cd30bcef 16005 READ_ULEB (tag, p, end);
0b4362b0 16006
13761a11
NC
16007 switch (tag)
16008 {
16009 case OFBA_MSPABI_Tag_ISA:
13761a11 16010 printf (" Tag_ISA: ");
cd30bcef 16011 READ_ULEB (val, p, end);
13761a11
NC
16012 switch (val)
16013 {
16014 case 0: printf (_("None\n")); break;
16015 case 1: printf (_("MSP430\n")); break;
16016 case 2: printf (_("MSP430X\n")); break;
16017 default: printf ("??? (%d)\n", val); break;
16018 }
16019 break;
16020
16021 case OFBA_MSPABI_Tag_Code_Model:
13761a11 16022 printf (" Tag_Code_Model: ");
cd30bcef 16023 READ_ULEB (val, p, end);
13761a11
NC
16024 switch (val)
16025 {
16026 case 0: printf (_("None\n")); break;
16027 case 1: printf (_("Small\n")); break;
16028 case 2: printf (_("Large\n")); break;
16029 default: printf ("??? (%d)\n", val); break;
16030 }
16031 break;
16032
16033 case OFBA_MSPABI_Tag_Data_Model:
13761a11 16034 printf (" Tag_Data_Model: ");
cd30bcef 16035 READ_ULEB (val, p, end);
13761a11
NC
16036 switch (val)
16037 {
16038 case 0: printf (_("None\n")); break;
16039 case 1: printf (_("Small\n")); break;
16040 case 2: printf (_("Large\n")); break;
16041 case 3: printf (_("Restricted Large\n")); break;
16042 default: printf ("??? (%d)\n", val); break;
16043 }
16044 break;
16045
16046 default:
16047 printf (_(" <unknown tag %d>: "), tag);
16048
16049 if (tag & 1)
16050 {
071436c6 16051 putchar ('"');
4082ef84
NC
16052 if (p < end - 1)
16053 {
16054 size_t maxlen = (end - p) - 1;
16055
16056 print_symbol ((int) maxlen, (const char *) p);
16057 p += strnlen ((char *) p, maxlen) + 1;
16058 }
16059 else
16060 {
16061 printf (_("<corrupt>"));
16062 p = (unsigned char *) end;
16063 }
071436c6 16064 printf ("\"\n");
13761a11
NC
16065 }
16066 else
16067 {
cd30bcef 16068 READ_ULEB (val, p, end);
13761a11
NC
16069 printf ("%d (0x%x)\n", val, val);
16070 }
16071 break;
16072 }
16073
4082ef84 16074 assert (p <= end);
13761a11
NC
16075 return p;
16076}
16077
c0ea7c52
JL
16078static unsigned char *
16079display_msp430_gnu_attribute (unsigned char * p,
16080 unsigned int tag,
16081 const unsigned char * const end)
16082{
16083 if (tag == Tag_GNU_MSP430_Data_Region)
16084 {
cd30bcef 16085 unsigned int val;
c0ea7c52 16086
c0ea7c52 16087 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 16088 READ_ULEB (val, p, end);
c0ea7c52
JL
16089
16090 switch (val)
16091 {
16092 case Val_GNU_MSP430_Data_Region_Any:
16093 printf (_("Any Region\n"));
16094 break;
16095 case Val_GNU_MSP430_Data_Region_Lower:
16096 printf (_("Lower Region Only\n"));
16097 break;
16098 default:
cd30bcef 16099 printf ("??? (%u)\n", val);
c0ea7c52
JL
16100 }
16101 return p;
16102 }
16103 return display_tag_value (tag & 1, p, end);
16104}
16105
2dc8dd17
JW
16106struct riscv_attr_tag_t {
16107 const char *name;
cd30bcef 16108 unsigned int tag;
2dc8dd17
JW
16109};
16110
16111static struct riscv_attr_tag_t riscv_attr_tag[] =
16112{
16113#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
16114 T(arch),
16115 T(priv_spec),
16116 T(priv_spec_minor),
16117 T(priv_spec_revision),
16118 T(unaligned_access),
16119 T(stack_align),
16120#undef T
16121};
16122
16123static unsigned char *
16124display_riscv_attribute (unsigned char *p,
16125 const unsigned char * const end)
16126{
cd30bcef
AM
16127 unsigned int val;
16128 unsigned int tag;
2dc8dd17
JW
16129 struct riscv_attr_tag_t *attr = NULL;
16130 unsigned i;
16131
cd30bcef 16132 READ_ULEB (tag, p, end);
2dc8dd17
JW
16133
16134 /* Find the name of attribute. */
16135 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
16136 {
16137 if (riscv_attr_tag[i].tag == tag)
16138 {
16139 attr = &riscv_attr_tag[i];
16140 break;
16141 }
16142 }
16143
16144 if (attr)
16145 printf (" %s: ", attr->name);
16146 else
16147 return display_tag_value (tag, p, end);
16148
16149 switch (tag)
16150 {
16151 case Tag_RISCV_priv_spec:
16152 case Tag_RISCV_priv_spec_minor:
16153 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
16154 READ_ULEB (val, p, end);
16155 printf (_("%u\n"), val);
2dc8dd17
JW
16156 break;
16157 case Tag_RISCV_unaligned_access:
cd30bcef 16158 READ_ULEB (val, p, end);
2dc8dd17
JW
16159 switch (val)
16160 {
16161 case 0:
16162 printf (_("No unaligned access\n"));
16163 break;
16164 case 1:
16165 printf (_("Unaligned access\n"));
16166 break;
16167 }
16168 break;
16169 case Tag_RISCV_stack_align:
cd30bcef
AM
16170 READ_ULEB (val, p, end);
16171 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
16172 break;
16173 case Tag_RISCV_arch:
16174 p = display_tag_value (-1, p, end);
16175 break;
16176 default:
16177 return display_tag_value (tag, p, end);
16178 }
16179
16180 return p;
16181}
16182
32ec8896 16183static bfd_boolean
dda8d76d 16184process_attributes (Filedata * filedata,
60bca95a 16185 const char * public_name,
104d59d1 16186 unsigned int proc_type,
f6f0e17b 16187 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 16188 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 16189{
2cf0635d 16190 Elf_Internal_Shdr * sect;
11c1ff18 16191 unsigned i;
32ec8896 16192 bfd_boolean res = TRUE;
11c1ff18
PB
16193
16194 /* Find the section header so that we get the size. */
dda8d76d
NC
16195 for (i = 0, sect = filedata->section_headers;
16196 i < filedata->file_header.e_shnum;
11c1ff18
PB
16197 i++, sect++)
16198 {
071436c6
NC
16199 unsigned char * contents;
16200 unsigned char * p;
16201
104d59d1 16202 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
16203 continue;
16204
dda8d76d 16205 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 16206 sect->sh_size, _("attributes"));
60bca95a 16207 if (contents == NULL)
32ec8896
NC
16208 {
16209 res = FALSE;
16210 continue;
16211 }
60bca95a 16212
11c1ff18 16213 p = contents;
60abdbed
NC
16214 /* The first character is the version of the attributes.
16215 Currently only version 1, (aka 'A') is recognised here. */
16216 if (*p != 'A')
32ec8896
NC
16217 {
16218 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
16219 res = FALSE;
16220 }
60abdbed 16221 else
11c1ff18 16222 {
071436c6
NC
16223 bfd_vma section_len;
16224
16225 section_len = sect->sh_size - 1;
11c1ff18 16226 p++;
60bca95a 16227
071436c6 16228 while (section_len > 0)
11c1ff18 16229 {
071436c6 16230 bfd_vma attr_len;
e9847026 16231 unsigned int namelen;
11c1ff18 16232 bfd_boolean public_section;
104d59d1 16233 bfd_boolean gnu_section;
11c1ff18 16234
071436c6 16235 if (section_len <= 4)
e0a31db1
NC
16236 {
16237 error (_("Tag section ends prematurely\n"));
32ec8896 16238 res = FALSE;
e0a31db1
NC
16239 break;
16240 }
071436c6 16241 attr_len = byte_get (p, 4);
11c1ff18 16242 p += 4;
60bca95a 16243
071436c6 16244 if (attr_len > section_len)
11c1ff18 16245 {
071436c6
NC
16246 error (_("Bad attribute length (%u > %u)\n"),
16247 (unsigned) attr_len, (unsigned) section_len);
16248 attr_len = section_len;
32ec8896 16249 res = FALSE;
11c1ff18 16250 }
74e1a04b 16251 /* PR 17531: file: 001-101425-0.004 */
071436c6 16252 else if (attr_len < 5)
74e1a04b 16253 {
071436c6 16254 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
32ec8896 16255 res = FALSE;
74e1a04b
NC
16256 break;
16257 }
e9847026 16258
071436c6
NC
16259 section_len -= attr_len;
16260 attr_len -= 4;
16261
16262 namelen = strnlen ((char *) p, attr_len) + 1;
16263 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
16264 {
16265 error (_("Corrupt attribute section name\n"));
32ec8896 16266 res = FALSE;
e9847026
NC
16267 break;
16268 }
16269
071436c6
NC
16270 printf (_("Attribute Section: "));
16271 print_symbol (INT_MAX, (const char *) p);
16272 putchar ('\n');
60bca95a
NC
16273
16274 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
16275 public_section = TRUE;
16276 else
16277 public_section = FALSE;
60bca95a
NC
16278
16279 if (streq ((char *) p, "gnu"))
104d59d1
JM
16280 gnu_section = TRUE;
16281 else
16282 gnu_section = FALSE;
60bca95a 16283
11c1ff18 16284 p += namelen;
071436c6 16285 attr_len -= namelen;
e0a31db1 16286
071436c6 16287 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 16288 {
e0a31db1 16289 int tag;
cd30bcef 16290 unsigned int val;
11c1ff18 16291 bfd_vma size;
071436c6 16292 unsigned char * end;
60bca95a 16293
e0a31db1 16294 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 16295 if (attr_len < 6)
e0a31db1
NC
16296 {
16297 error (_("Unused bytes at end of section\n"));
32ec8896 16298 res = FALSE;
e0a31db1
NC
16299 section_len = 0;
16300 break;
16301 }
16302
16303 tag = *(p++);
11c1ff18 16304 size = byte_get (p, 4);
071436c6 16305 if (size > attr_len)
11c1ff18 16306 {
e9847026 16307 error (_("Bad subsection length (%u > %u)\n"),
071436c6 16308 (unsigned) size, (unsigned) attr_len);
32ec8896 16309 res = FALSE;
071436c6 16310 size = attr_len;
11c1ff18 16311 }
e0a31db1
NC
16312 /* PR binutils/17531: Safe handling of corrupt files. */
16313 if (size < 6)
16314 {
16315 error (_("Bad subsection length (%u < 6)\n"),
16316 (unsigned) size);
32ec8896 16317 res = FALSE;
e0a31db1
NC
16318 section_len = 0;
16319 break;
16320 }
60bca95a 16321
071436c6 16322 attr_len -= size;
11c1ff18 16323 end = p + size - 1;
071436c6 16324 assert (end <= contents + sect->sh_size);
11c1ff18 16325 p += 4;
60bca95a 16326
11c1ff18
PB
16327 switch (tag)
16328 {
16329 case 1:
2b692964 16330 printf (_("File Attributes\n"));
11c1ff18
PB
16331 break;
16332 case 2:
2b692964 16333 printf (_("Section Attributes:"));
11c1ff18
PB
16334 goto do_numlist;
16335 case 3:
2b692964 16336 printf (_("Symbol Attributes:"));
1a0670f3 16337 /* Fall through. */
11c1ff18
PB
16338 do_numlist:
16339 for (;;)
16340 {
cd30bcef 16341 READ_ULEB (val, p, end);
11c1ff18
PB
16342 if (val == 0)
16343 break;
16344 printf (" %d", val);
16345 }
16346 printf ("\n");
16347 break;
16348 default:
2b692964 16349 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
16350 public_section = FALSE;
16351 break;
16352 }
60bca95a 16353
071436c6 16354 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
16355 {
16356 while (p < end)
f6f0e17b 16357 p = display_pub_attribute (p, end);
60abdbed 16358 assert (p == end);
104d59d1 16359 }
071436c6 16360 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
16361 {
16362 while (p < end)
16363 p = display_gnu_attribute (p,
f6f0e17b
NC
16364 display_proc_gnu_attribute,
16365 end);
60abdbed 16366 assert (p == end);
11c1ff18 16367 }
071436c6 16368 else if (p < end)
11c1ff18 16369 {
071436c6 16370 printf (_(" Unknown attribute:\n"));
f6f0e17b 16371 display_raw_attribute (p, end);
11c1ff18
PB
16372 p = end;
16373 }
071436c6
NC
16374 else
16375 attr_len = 0;
11c1ff18
PB
16376 }
16377 }
16378 }
d70c5fc7 16379
60bca95a 16380 free (contents);
11c1ff18 16381 }
32ec8896
NC
16382
16383 return res;
11c1ff18
PB
16384}
16385
ccb4c951
RS
16386/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
16387 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
16388 and return the VMA of the next entry, or -1 if there was a problem.
16389 Does not read from DATA_END or beyond. */
ccb4c951
RS
16390
16391static bfd_vma
82b1b41b
NC
16392print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
16393 unsigned char * data_end)
ccb4c951
RS
16394{
16395 printf (" ");
16396 print_vma (addr, LONG_HEX);
16397 printf (" ");
16398 if (addr < pltgot + 0xfff0)
16399 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
16400 else
16401 printf ("%10s", "");
16402 printf (" ");
16403 if (data == NULL)
2b692964 16404 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
16405 else
16406 {
16407 bfd_vma entry;
82b1b41b 16408 unsigned char * from = data + addr - pltgot;
ccb4c951 16409
82b1b41b
NC
16410 if (from + (is_32bit_elf ? 4 : 8) > data_end)
16411 {
16412 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
16413 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
16414 return (bfd_vma) -1;
16415 }
16416 else
16417 {
16418 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
16419 print_vma (entry, LONG_HEX);
16420 }
ccb4c951
RS
16421 }
16422 return addr + (is_32bit_elf ? 4 : 8);
16423}
16424
861fb55a
DJ
16425/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
16426 PLTGOT. Print the Address and Initial fields of an entry at VMA
16427 ADDR and return the VMA of the next entry. */
16428
16429static bfd_vma
2cf0635d 16430print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
16431{
16432 printf (" ");
16433 print_vma (addr, LONG_HEX);
16434 printf (" ");
16435 if (data == NULL)
2b692964 16436 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
16437 else
16438 {
16439 bfd_vma entry;
16440
16441 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
16442 print_vma (entry, LONG_HEX);
16443 }
16444 return addr + (is_32bit_elf ? 4 : 8);
16445}
16446
351cdf24
MF
16447static void
16448print_mips_ases (unsigned int mask)
16449{
16450 if (mask & AFL_ASE_DSP)
16451 fputs ("\n\tDSP ASE", stdout);
16452 if (mask & AFL_ASE_DSPR2)
16453 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
16454 if (mask & AFL_ASE_DSPR3)
16455 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
16456 if (mask & AFL_ASE_EVA)
16457 fputs ("\n\tEnhanced VA Scheme", stdout);
16458 if (mask & AFL_ASE_MCU)
16459 fputs ("\n\tMCU (MicroController) ASE", stdout);
16460 if (mask & AFL_ASE_MDMX)
16461 fputs ("\n\tMDMX ASE", stdout);
16462 if (mask & AFL_ASE_MIPS3D)
16463 fputs ("\n\tMIPS-3D ASE", stdout);
16464 if (mask & AFL_ASE_MT)
16465 fputs ("\n\tMT ASE", stdout);
16466 if (mask & AFL_ASE_SMARTMIPS)
16467 fputs ("\n\tSmartMIPS ASE", stdout);
16468 if (mask & AFL_ASE_VIRT)
16469 fputs ("\n\tVZ ASE", stdout);
16470 if (mask & AFL_ASE_MSA)
16471 fputs ("\n\tMSA ASE", stdout);
16472 if (mask & AFL_ASE_MIPS16)
16473 fputs ("\n\tMIPS16 ASE", stdout);
16474 if (mask & AFL_ASE_MICROMIPS)
16475 fputs ("\n\tMICROMIPS ASE", stdout);
16476 if (mask & AFL_ASE_XPA)
16477 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
16478 if (mask & AFL_ASE_MIPS16E2)
16479 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
16480 if (mask & AFL_ASE_CRC)
16481 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
16482 if (mask & AFL_ASE_GINV)
16483 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
16484 if (mask & AFL_ASE_LOONGSON_MMI)
16485 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
16486 if (mask & AFL_ASE_LOONGSON_CAM)
16487 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
16488 if (mask & AFL_ASE_LOONGSON_EXT)
16489 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
16490 if (mask & AFL_ASE_LOONGSON_EXT2)
16491 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
16492 if (mask == 0)
16493 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
16494 else if ((mask & ~AFL_ASE_MASK) != 0)
16495 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
16496}
16497
16498static void
16499print_mips_isa_ext (unsigned int isa_ext)
16500{
16501 switch (isa_ext)
16502 {
16503 case 0:
16504 fputs (_("None"), stdout);
16505 break;
16506 case AFL_EXT_XLR:
16507 fputs ("RMI XLR", stdout);
16508 break;
2c629856
N
16509 case AFL_EXT_OCTEON3:
16510 fputs ("Cavium Networks Octeon3", stdout);
16511 break;
351cdf24
MF
16512 case AFL_EXT_OCTEON2:
16513 fputs ("Cavium Networks Octeon2", stdout);
16514 break;
16515 case AFL_EXT_OCTEONP:
16516 fputs ("Cavium Networks OcteonP", stdout);
16517 break;
351cdf24
MF
16518 case AFL_EXT_OCTEON:
16519 fputs ("Cavium Networks Octeon", stdout);
16520 break;
16521 case AFL_EXT_5900:
16522 fputs ("Toshiba R5900", stdout);
16523 break;
16524 case AFL_EXT_4650:
16525 fputs ("MIPS R4650", stdout);
16526 break;
16527 case AFL_EXT_4010:
16528 fputs ("LSI R4010", stdout);
16529 break;
16530 case AFL_EXT_4100:
16531 fputs ("NEC VR4100", stdout);
16532 break;
16533 case AFL_EXT_3900:
16534 fputs ("Toshiba R3900", stdout);
16535 break;
16536 case AFL_EXT_10000:
16537 fputs ("MIPS R10000", stdout);
16538 break;
16539 case AFL_EXT_SB1:
16540 fputs ("Broadcom SB-1", stdout);
16541 break;
16542 case AFL_EXT_4111:
16543 fputs ("NEC VR4111/VR4181", stdout);
16544 break;
16545 case AFL_EXT_4120:
16546 fputs ("NEC VR4120", stdout);
16547 break;
16548 case AFL_EXT_5400:
16549 fputs ("NEC VR5400", stdout);
16550 break;
16551 case AFL_EXT_5500:
16552 fputs ("NEC VR5500", stdout);
16553 break;
16554 case AFL_EXT_LOONGSON_2E:
16555 fputs ("ST Microelectronics Loongson 2E", stdout);
16556 break;
16557 case AFL_EXT_LOONGSON_2F:
16558 fputs ("ST Microelectronics Loongson 2F", stdout);
16559 break;
38bf472a
MR
16560 case AFL_EXT_INTERAPTIV_MR2:
16561 fputs ("Imagination interAptiv MR2", stdout);
16562 break;
351cdf24 16563 default:
00ac7aa0 16564 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
16565 }
16566}
16567
32ec8896 16568static signed int
351cdf24
MF
16569get_mips_reg_size (int reg_size)
16570{
16571 return (reg_size == AFL_REG_NONE) ? 0
16572 : (reg_size == AFL_REG_32) ? 32
16573 : (reg_size == AFL_REG_64) ? 64
16574 : (reg_size == AFL_REG_128) ? 128
16575 : -1;
16576}
16577
32ec8896 16578static bfd_boolean
dda8d76d 16579process_mips_specific (Filedata * filedata)
5b18a4bc 16580{
2cf0635d 16581 Elf_Internal_Dyn * entry;
351cdf24 16582 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
16583 size_t liblist_offset = 0;
16584 size_t liblistno = 0;
16585 size_t conflictsno = 0;
16586 size_t options_offset = 0;
16587 size_t conflicts_offset = 0;
861fb55a
DJ
16588 size_t pltrelsz = 0;
16589 size_t pltrel = 0;
ccb4c951 16590 bfd_vma pltgot = 0;
861fb55a
DJ
16591 bfd_vma mips_pltgot = 0;
16592 bfd_vma jmprel = 0;
ccb4c951
RS
16593 bfd_vma local_gotno = 0;
16594 bfd_vma gotsym = 0;
16595 bfd_vma symtabno = 0;
32ec8896 16596 bfd_boolean res = TRUE;
103f02d3 16597
dda8d76d 16598 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896
NC
16599 display_mips_gnu_attribute))
16600 res = FALSE;
2cf19d5c 16601
dda8d76d 16602 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
16603
16604 if (sect != NULL)
16605 {
16606 Elf_External_ABIFlags_v0 *abiflags_ext;
16607 Elf_Internal_ABIFlags_v0 abiflags_in;
16608
16609 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
16610 {
16611 error (_("Corrupt MIPS ABI Flags section.\n"));
16612 res = FALSE;
16613 }
351cdf24
MF
16614 else
16615 {
dda8d76d 16616 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
16617 sect->sh_size, _("MIPS ABI Flags section"));
16618 if (abiflags_ext)
16619 {
16620 abiflags_in.version = BYTE_GET (abiflags_ext->version);
16621 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
16622 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
16623 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
16624 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
16625 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
16626 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
16627 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
16628 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
16629 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
16630 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
16631
16632 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
16633 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
16634 if (abiflags_in.isa_rev > 1)
16635 printf ("r%d", abiflags_in.isa_rev);
16636 printf ("\nGPR size: %d",
16637 get_mips_reg_size (abiflags_in.gpr_size));
16638 printf ("\nCPR1 size: %d",
16639 get_mips_reg_size (abiflags_in.cpr1_size));
16640 printf ("\nCPR2 size: %d",
16641 get_mips_reg_size (abiflags_in.cpr2_size));
16642 fputs ("\nFP ABI: ", stdout);
16643 print_mips_fp_abi_value (abiflags_in.fp_abi);
16644 fputs ("ISA Extension: ", stdout);
16645 print_mips_isa_ext (abiflags_in.isa_ext);
16646 fputs ("\nASEs:", stdout);
16647 print_mips_ases (abiflags_in.ases);
16648 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
16649 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
16650 fputc ('\n', stdout);
16651 free (abiflags_ext);
16652 }
16653 }
16654 }
16655
19e6b90e 16656 /* We have a lot of special sections. Thanks SGI! */
978c4450 16657 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
16658 {
16659 /* No dynamic information available. See if there is static GOT. */
dda8d76d 16660 sect = find_section (filedata, ".got");
bbdd9a68
MR
16661 if (sect != NULL)
16662 {
16663 unsigned char *data_end;
16664 unsigned char *data;
16665 bfd_vma ent, end;
16666 int addr_size;
16667
16668 pltgot = sect->sh_addr;
16669
16670 ent = pltgot;
16671 addr_size = (is_32bit_elf ? 4 : 8);
16672 end = pltgot + sect->sh_size;
16673
dda8d76d 16674 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
16675 end - pltgot, 1,
16676 _("Global Offset Table data"));
16677 /* PR 12855: Null data is handled gracefully throughout. */
16678 data_end = data + (end - pltgot);
16679
16680 printf (_("\nStatic GOT:\n"));
16681 printf (_(" Canonical gp value: "));
16682 print_vma (ent + 0x7ff0, LONG_HEX);
16683 printf ("\n\n");
16684
16685 /* In a dynamic binary GOT[0] is reserved for the dynamic
16686 loader to store the lazy resolver pointer, however in
16687 a static binary it may well have been omitted and GOT
16688 reduced to a table of addresses.
16689 PR 21344: Check for the entry being fully available
16690 before fetching it. */
16691 if (data
16692 && data + ent - pltgot + addr_size <= data_end
16693 && byte_get (data + ent - pltgot, addr_size) == 0)
16694 {
16695 printf (_(" Reserved entries:\n"));
16696 printf (_(" %*s %10s %*s\n"),
16697 addr_size * 2, _("Address"), _("Access"),
16698 addr_size * 2, _("Value"));
16699 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16700 printf ("\n");
16701 if (ent == (bfd_vma) -1)
16702 goto sgot_print_fail;
16703
16704 /* Check for the MSB of GOT[1] being set, identifying a
16705 GNU object. This entry will be used by some runtime
16706 loaders, to store the module pointer. Otherwise this
16707 is an ordinary local entry.
16708 PR 21344: Check for the entry being fully available
16709 before fetching it. */
16710 if (data
16711 && data + ent - pltgot + addr_size <= data_end
16712 && (byte_get (data + ent - pltgot, addr_size)
16713 >> (addr_size * 8 - 1)) != 0)
16714 {
16715 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16716 printf ("\n");
16717 if (ent == (bfd_vma) -1)
16718 goto sgot_print_fail;
16719 }
16720 printf ("\n");
16721 }
16722
f17e9d8a 16723 if (data != NULL && ent < end)
bbdd9a68
MR
16724 {
16725 printf (_(" Local entries:\n"));
16726 printf (" %*s %10s %*s\n",
16727 addr_size * 2, _("Address"), _("Access"),
16728 addr_size * 2, _("Value"));
16729 while (ent < end)
16730 {
16731 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16732 printf ("\n");
16733 if (ent == (bfd_vma) -1)
16734 goto sgot_print_fail;
16735 }
16736 printf ("\n");
16737 }
16738
16739 sgot_print_fail:
16740 if (data)
16741 free (data);
16742 }
16743 return res;
16744 }
252b5132 16745
978c4450 16746 for (entry = filedata->dynamic_section;
071436c6 16747 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
16748 (entry < filedata->dynamic_section + filedata->dynamic_nent
16749 && entry->d_tag != DT_NULL);
071436c6 16750 ++entry)
252b5132
RH
16751 switch (entry->d_tag)
16752 {
16753 case DT_MIPS_LIBLIST:
d93f0186 16754 liblist_offset
dda8d76d 16755 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 16756 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
16757 break;
16758 case DT_MIPS_LIBLISTNO:
16759 liblistno = entry->d_un.d_val;
16760 break;
16761 case DT_MIPS_OPTIONS:
dda8d76d 16762 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
16763 break;
16764 case DT_MIPS_CONFLICT:
d93f0186 16765 conflicts_offset
dda8d76d 16766 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 16767 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
16768 break;
16769 case DT_MIPS_CONFLICTNO:
16770 conflictsno = entry->d_un.d_val;
16771 break;
ccb4c951 16772 case DT_PLTGOT:
861fb55a
DJ
16773 pltgot = entry->d_un.d_ptr;
16774 break;
ccb4c951
RS
16775 case DT_MIPS_LOCAL_GOTNO:
16776 local_gotno = entry->d_un.d_val;
16777 break;
16778 case DT_MIPS_GOTSYM:
16779 gotsym = entry->d_un.d_val;
16780 break;
16781 case DT_MIPS_SYMTABNO:
16782 symtabno = entry->d_un.d_val;
16783 break;
861fb55a
DJ
16784 case DT_MIPS_PLTGOT:
16785 mips_pltgot = entry->d_un.d_ptr;
16786 break;
16787 case DT_PLTREL:
16788 pltrel = entry->d_un.d_val;
16789 break;
16790 case DT_PLTRELSZ:
16791 pltrelsz = entry->d_un.d_val;
16792 break;
16793 case DT_JMPREL:
16794 jmprel = entry->d_un.d_ptr;
16795 break;
252b5132
RH
16796 default:
16797 break;
16798 }
16799
16800 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
16801 {
2cf0635d 16802 Elf32_External_Lib * elib;
252b5132
RH
16803 size_t cnt;
16804
dda8d76d 16805 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
16806 sizeof (Elf32_External_Lib),
16807 liblistno,
16808 _("liblist section data"));
a6e9f9df 16809 if (elib)
252b5132 16810 {
d3a49aa8
AM
16811 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
16812 "\nSection '.liblist' contains %lu entries:\n",
16813 (unsigned long) liblistno),
a6e9f9df 16814 (unsigned long) liblistno);
2b692964 16815 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
16816 stdout);
16817
16818 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 16819 {
a6e9f9df 16820 Elf32_Lib liblist;
91d6fa6a 16821 time_t atime;
d5b07ef4 16822 char timebuf[128];
2cf0635d 16823 struct tm * tmp;
a6e9f9df
AM
16824
16825 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 16826 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
16827 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
16828 liblist.l_version = BYTE_GET (elib[cnt].l_version);
16829 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
16830
91d6fa6a 16831 tmp = gmtime (&atime);
e9e44622
JJ
16832 snprintf (timebuf, sizeof (timebuf),
16833 "%04u-%02u-%02uT%02u:%02u:%02u",
16834 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
16835 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 16836
31104126 16837 printf ("%3lu: ", (unsigned long) cnt);
978c4450
AM
16838 if (VALID_DYNAMIC_NAME (filedata, liblist.l_name))
16839 print_symbol (20, GET_DYNAMIC_NAME (filedata, liblist.l_name));
d79b3d50 16840 else
2b692964 16841 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
16842 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
16843 liblist.l_version);
a6e9f9df
AM
16844
16845 if (liblist.l_flags == 0)
2b692964 16846 puts (_(" NONE"));
a6e9f9df
AM
16847 else
16848 {
16849 static const struct
252b5132 16850 {
2cf0635d 16851 const char * name;
a6e9f9df 16852 int bit;
252b5132 16853 }
a6e9f9df
AM
16854 l_flags_vals[] =
16855 {
16856 { " EXACT_MATCH", LL_EXACT_MATCH },
16857 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
16858 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
16859 { " EXPORTS", LL_EXPORTS },
16860 { " DELAY_LOAD", LL_DELAY_LOAD },
16861 { " DELTA", LL_DELTA }
16862 };
16863 int flags = liblist.l_flags;
16864 size_t fcnt;
16865
60bca95a 16866 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
16867 if ((flags & l_flags_vals[fcnt].bit) != 0)
16868 {
16869 fputs (l_flags_vals[fcnt].name, stdout);
16870 flags ^= l_flags_vals[fcnt].bit;
16871 }
16872 if (flags != 0)
16873 printf (" %#x", (unsigned int) flags);
252b5132 16874
a6e9f9df
AM
16875 puts ("");
16876 }
252b5132 16877 }
252b5132 16878
a6e9f9df
AM
16879 free (elib);
16880 }
32ec8896
NC
16881 else
16882 res = FALSE;
252b5132
RH
16883 }
16884
16885 if (options_offset != 0)
16886 {
2cf0635d 16887 Elf_External_Options * eopt;
252b5132
RH
16888 size_t offset;
16889 int cnt;
dda8d76d 16890 sect = filedata->section_headers;
252b5132
RH
16891
16892 /* Find the section header so that we get the size. */
dda8d76d 16893 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 16894 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
16895 if (sect == NULL)
16896 {
16897 error (_("No MIPS_OPTIONS header found\n"));
32ec8896 16898 return FALSE;
071436c6 16899 }
7fc0c668
NC
16900 /* PR 24243 */
16901 if (sect->sh_size < sizeof (* eopt))
16902 {
16903 error (_("The MIPS options section is too small.\n"));
16904 return FALSE;
16905 }
252b5132 16906
dda8d76d 16907 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 16908 sect->sh_size, _("options"));
a6e9f9df 16909 if (eopt)
252b5132 16910 {
2e6be59c
NC
16911 Elf_Internal_Options * iopt;
16912 Elf_Internal_Options * option;
16913 Elf_Internal_Options * iopt_end;
16914
3f5e193b
NC
16915 iopt = (Elf_Internal_Options *)
16916 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
16917 if (iopt == NULL)
16918 {
fb324ee9 16919 error (_("Out of memory allocating space for MIPS options\n"));
645f43a8 16920 free (eopt);
32ec8896 16921 return FALSE;
a6e9f9df 16922 }
76da6bbe 16923
a6e9f9df
AM
16924 offset = cnt = 0;
16925 option = iopt;
2e6be59c
NC
16926 iopt_end = iopt + (sect->sh_size / sizeof (eopt));
16927
82b1b41b 16928 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 16929 {
2cf0635d 16930 Elf_External_Options * eoption;
252b5132 16931
a6e9f9df 16932 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 16933
a6e9f9df
AM
16934 option->kind = BYTE_GET (eoption->kind);
16935 option->size = BYTE_GET (eoption->size);
16936 option->section = BYTE_GET (eoption->section);
16937 option->info = BYTE_GET (eoption->info);
76da6bbe 16938
82b1b41b
NC
16939 /* PR 17531: file: ffa0fa3b. */
16940 if (option->size < sizeof (* eopt)
16941 || offset + option->size > sect->sh_size)
16942 {
645f43a8
AM
16943 error (_("Invalid size (%u) for MIPS option\n"),
16944 option->size);
16945 free (iopt);
16946 free (eopt);
32ec8896 16947 return FALSE;
82b1b41b 16948 }
a6e9f9df 16949 offset += option->size;
14ae95f2 16950
a6e9f9df
AM
16951 ++option;
16952 ++cnt;
16953 }
252b5132 16954
d3a49aa8
AM
16955 printf (ngettext ("\nSection '%s' contains %d entry:\n",
16956 "\nSection '%s' contains %d entries:\n",
16957 cnt),
dda8d76d 16958 printable_section_name (filedata, sect), cnt);
76da6bbe 16959
a6e9f9df 16960 option = iopt;
82b1b41b 16961 offset = 0;
252b5132 16962
a6e9f9df 16963 while (cnt-- > 0)
252b5132 16964 {
a6e9f9df
AM
16965 size_t len;
16966
16967 switch (option->kind)
252b5132 16968 {
a6e9f9df
AM
16969 case ODK_NULL:
16970 /* This shouldn't happen. */
16971 printf (" NULL %d %lx", option->section, option->info);
16972 break;
2e6be59c 16973
a6e9f9df
AM
16974 case ODK_REGINFO:
16975 printf (" REGINFO ");
dda8d76d 16976 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 16977 {
2cf0635d 16978 Elf32_External_RegInfo * ereg;
b34976b6 16979 Elf32_RegInfo reginfo;
a6e9f9df 16980
2e6be59c
NC
16981 /* 32bit form. */
16982 if (option + 2 > iopt_end)
16983 {
16984 printf (_("<corrupt>\n"));
16985 error (_("Truncated MIPS REGINFO option\n"));
16986 cnt = 0;
16987 break;
16988 }
16989
a6e9f9df 16990 ereg = (Elf32_External_RegInfo *) (option + 1);
2e6be59c 16991
a6e9f9df
AM
16992 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
16993 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
16994 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
16995 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
16996 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
16997 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
16998
16999 printf ("GPR %08lx GP 0x%lx\n",
17000 reginfo.ri_gprmask,
17001 (unsigned long) reginfo.ri_gp_value);
17002 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
17003 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17004 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17005 }
17006 else
17007 {
17008 /* 64 bit form. */
2cf0635d 17009 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
17010 Elf64_Internal_RegInfo reginfo;
17011
2e6be59c
NC
17012 if (option + 2 > iopt_end)
17013 {
17014 printf (_("<corrupt>\n"));
17015 error (_("Truncated MIPS REGINFO option\n"));
17016 cnt = 0;
17017 break;
17018 }
17019
a6e9f9df
AM
17020 ereg = (Elf64_External_RegInfo *) (option + 1);
17021 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17022 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17023 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17024 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17025 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 17026 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
17027
17028 printf ("GPR %08lx GP 0x",
17029 reginfo.ri_gprmask);
17030 printf_vma (reginfo.ri_gp_value);
17031 printf ("\n");
17032
17033 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
17034 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17035 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17036 }
17037 ++option;
17038 continue;
2e6be59c 17039
a6e9f9df
AM
17040 case ODK_EXCEPTIONS:
17041 fputs (" EXCEPTIONS fpe_min(", stdout);
17042 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
17043 fputs (") fpe_max(", stdout);
17044 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
17045 fputs (")", stdout);
17046
17047 if (option->info & OEX_PAGE0)
17048 fputs (" PAGE0", stdout);
17049 if (option->info & OEX_SMM)
17050 fputs (" SMM", stdout);
17051 if (option->info & OEX_FPDBUG)
17052 fputs (" FPDBUG", stdout);
17053 if (option->info & OEX_DISMISS)
17054 fputs (" DISMISS", stdout);
17055 break;
2e6be59c 17056
a6e9f9df
AM
17057 case ODK_PAD:
17058 fputs (" PAD ", stdout);
17059 if (option->info & OPAD_PREFIX)
17060 fputs (" PREFIX", stdout);
17061 if (option->info & OPAD_POSTFIX)
17062 fputs (" POSTFIX", stdout);
17063 if (option->info & OPAD_SYMBOL)
17064 fputs (" SYMBOL", stdout);
17065 break;
2e6be59c 17066
a6e9f9df
AM
17067 case ODK_HWPATCH:
17068 fputs (" HWPATCH ", stdout);
17069 if (option->info & OHW_R4KEOP)
17070 fputs (" R4KEOP", stdout);
17071 if (option->info & OHW_R8KPFETCH)
17072 fputs (" R8KPFETCH", stdout);
17073 if (option->info & OHW_R5KEOP)
17074 fputs (" R5KEOP", stdout);
17075 if (option->info & OHW_R5KCVTL)
17076 fputs (" R5KCVTL", stdout);
17077 break;
2e6be59c 17078
a6e9f9df
AM
17079 case ODK_FILL:
17080 fputs (" FILL ", stdout);
17081 /* XXX Print content of info word? */
17082 break;
2e6be59c 17083
a6e9f9df
AM
17084 case ODK_TAGS:
17085 fputs (" TAGS ", stdout);
17086 /* XXX Print content of info word? */
17087 break;
2e6be59c 17088
a6e9f9df
AM
17089 case ODK_HWAND:
17090 fputs (" HWAND ", stdout);
17091 if (option->info & OHWA0_R4KEOP_CHECKED)
17092 fputs (" R4KEOP_CHECKED", stdout);
17093 if (option->info & OHWA0_R4KEOP_CLEAN)
17094 fputs (" R4KEOP_CLEAN", stdout);
17095 break;
2e6be59c 17096
a6e9f9df
AM
17097 case ODK_HWOR:
17098 fputs (" HWOR ", stdout);
17099 if (option->info & OHWA0_R4KEOP_CHECKED)
17100 fputs (" R4KEOP_CHECKED", stdout);
17101 if (option->info & OHWA0_R4KEOP_CLEAN)
17102 fputs (" R4KEOP_CLEAN", stdout);
17103 break;
2e6be59c 17104
a6e9f9df
AM
17105 case ODK_GP_GROUP:
17106 printf (" GP_GROUP %#06lx self-contained %#06lx",
17107 option->info & OGP_GROUP,
17108 (option->info & OGP_SELF) >> 16);
17109 break;
2e6be59c 17110
a6e9f9df
AM
17111 case ODK_IDENT:
17112 printf (" IDENT %#06lx self-contained %#06lx",
17113 option->info & OGP_GROUP,
17114 (option->info & OGP_SELF) >> 16);
17115 break;
2e6be59c 17116
a6e9f9df
AM
17117 default:
17118 /* This shouldn't happen. */
17119 printf (" %3d ??? %d %lx",
17120 option->kind, option->section, option->info);
17121 break;
252b5132 17122 }
a6e9f9df 17123
2cf0635d 17124 len = sizeof (* eopt);
a6e9f9df 17125 while (len < option->size)
82b1b41b 17126 {
7e27a9d5 17127 unsigned char datum = * ((unsigned char *) eopt + offset + len);
a6e9f9df 17128
82b1b41b
NC
17129 if (ISPRINT (datum))
17130 printf ("%c", datum);
17131 else
17132 printf ("\\%03o", datum);
17133 len ++;
17134 }
a6e9f9df 17135 fputs ("\n", stdout);
82b1b41b
NC
17136
17137 offset += option->size;
252b5132 17138 ++option;
252b5132 17139 }
645f43a8 17140 free (iopt);
a6e9f9df 17141 free (eopt);
252b5132 17142 }
32ec8896
NC
17143 else
17144 res = FALSE;
252b5132
RH
17145 }
17146
17147 if (conflicts_offset != 0 && conflictsno != 0)
17148 {
2cf0635d 17149 Elf32_Conflict * iconf;
252b5132
RH
17150 size_t cnt;
17151
978c4450 17152 if (filedata->dynamic_symbols == NULL)
252b5132 17153 {
591a748a 17154 error (_("conflict list found without a dynamic symbol table\n"));
32ec8896 17155 return FALSE;
252b5132
RH
17156 }
17157
7296a62a
NC
17158 /* PR 21345 - print a slightly more helpful error message
17159 if we are sure that the cmalloc will fail. */
645f43a8 17160 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
17161 {
17162 error (_("Overlarge number of conflicts detected: %lx\n"),
17163 (long) conflictsno);
17164 return FALSE;
17165 }
17166
3f5e193b 17167 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
17168 if (iconf == NULL)
17169 {
8b73c356 17170 error (_("Out of memory allocating space for dynamic conflicts\n"));
32ec8896 17171 return FALSE;
252b5132
RH
17172 }
17173
9ea033b2 17174 if (is_32bit_elf)
252b5132 17175 {
2cf0635d 17176 Elf32_External_Conflict * econf32;
a6e9f9df 17177
3f5e193b 17178 econf32 = (Elf32_External_Conflict *)
95099889
AM
17179 get_data (NULL, filedata, conflicts_offset,
17180 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 17181 if (!econf32)
5a814d6d
AM
17182 {
17183 free (iconf);
17184 return FALSE;
17185 }
252b5132
RH
17186
17187 for (cnt = 0; cnt < conflictsno; ++cnt)
17188 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
17189
17190 free (econf32);
252b5132
RH
17191 }
17192 else
17193 {
2cf0635d 17194 Elf64_External_Conflict * econf64;
a6e9f9df 17195
3f5e193b 17196 econf64 = (Elf64_External_Conflict *)
95099889
AM
17197 get_data (NULL, filedata, conflicts_offset,
17198 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 17199 if (!econf64)
5a814d6d
AM
17200 {
17201 free (iconf);
17202 return FALSE;
17203 }
252b5132
RH
17204
17205 for (cnt = 0; cnt < conflictsno; ++cnt)
17206 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
17207
17208 free (econf64);
252b5132
RH
17209 }
17210
d3a49aa8
AM
17211 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
17212 "\nSection '.conflict' contains %lu entries:\n",
17213 (unsigned long) conflictsno),
c7e7ca54 17214 (unsigned long) conflictsno);
252b5132
RH
17215 puts (_(" Num: Index Value Name"));
17216
17217 for (cnt = 0; cnt < conflictsno; ++cnt)
17218 {
b34976b6 17219 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 17220
978c4450 17221 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 17222 printf (_("<corrupt symbol index>"));
d79b3d50 17223 else
e0a31db1
NC
17224 {
17225 Elf_Internal_Sym * psym;
17226
978c4450 17227 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
17228 print_vma (psym->st_value, FULL_HEX);
17229 putchar (' ');
978c4450
AM
17230 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17231 print_symbol (25, GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17232 else
17233 printf (_("<corrupt: %14ld>"), psym->st_name);
17234 }
31104126 17235 putchar ('\n');
252b5132
RH
17236 }
17237
252b5132
RH
17238 free (iconf);
17239 }
17240
ccb4c951
RS
17241 if (pltgot != 0 && local_gotno != 0)
17242 {
91d6fa6a 17243 bfd_vma ent, local_end, global_end;
bbeee7ea 17244 size_t i, offset;
2cf0635d 17245 unsigned char * data;
82b1b41b 17246 unsigned char * data_end;
bbeee7ea 17247 int addr_size;
ccb4c951 17248
91d6fa6a 17249 ent = pltgot;
ccb4c951
RS
17250 addr_size = (is_32bit_elf ? 4 : 8);
17251 local_end = pltgot + local_gotno * addr_size;
ccb4c951 17252
74e1a04b
NC
17253 /* PR binutils/17533 file: 012-111227-0.004 */
17254 if (symtabno < gotsym)
17255 {
17256 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 17257 (unsigned long) gotsym, (unsigned long) symtabno);
32ec8896 17258 return FALSE;
74e1a04b 17259 }
82b1b41b 17260
74e1a04b 17261 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
17262 /* PR 17531: file: 54c91a34. */
17263 if (global_end < local_end)
17264 {
17265 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
32ec8896 17266 return FALSE;
82b1b41b 17267 }
948f632f 17268
dda8d76d
NC
17269 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
17270 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
17271 global_end - pltgot, 1,
17272 _("Global Offset Table data"));
919383ac 17273 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 17274 data_end = data + (global_end - pltgot);
59245841 17275
ccb4c951
RS
17276 printf (_("\nPrimary GOT:\n"));
17277 printf (_(" Canonical gp value: "));
17278 print_vma (pltgot + 0x7ff0, LONG_HEX);
17279 printf ("\n\n");
17280
17281 printf (_(" Reserved entries:\n"));
17282 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
17283 addr_size * 2, _("Address"), _("Access"),
17284 addr_size * 2, _("Initial"));
82b1b41b 17285 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 17286 printf (_(" Lazy resolver\n"));
82b1b41b
NC
17287 if (ent == (bfd_vma) -1)
17288 goto got_print_fail;
75ec1fdb 17289
c4ab9505
MR
17290 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
17291 This entry will be used by some runtime loaders, to store the
17292 module pointer. Otherwise this is an ordinary local entry.
17293 PR 21344: Check for the entry being fully available before
17294 fetching it. */
17295 if (data
17296 && data + ent - pltgot + addr_size <= data_end
17297 && (byte_get (data + ent - pltgot, addr_size)
17298 >> (addr_size * 8 - 1)) != 0)
17299 {
17300 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17301 printf (_(" Module pointer (GNU extension)\n"));
17302 if (ent == (bfd_vma) -1)
17303 goto got_print_fail;
ccb4c951
RS
17304 }
17305 printf ("\n");
17306
f17e9d8a 17307 if (data != NULL && ent < local_end)
ccb4c951
RS
17308 {
17309 printf (_(" Local entries:\n"));
cc5914eb 17310 printf (" %*s %10s %*s\n",
2b692964
NC
17311 addr_size * 2, _("Address"), _("Access"),
17312 addr_size * 2, _("Initial"));
91d6fa6a 17313 while (ent < local_end)
ccb4c951 17314 {
82b1b41b 17315 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 17316 printf ("\n");
82b1b41b
NC
17317 if (ent == (bfd_vma) -1)
17318 goto got_print_fail;
ccb4c951
RS
17319 }
17320 printf ("\n");
17321 }
17322
f17e9d8a 17323 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
17324 {
17325 int sym_width;
17326
17327 printf (_(" Global entries:\n"));
cc5914eb 17328 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
17329 addr_size * 2, _("Address"),
17330 _("Access"),
2b692964 17331 addr_size * 2, _("Initial"),
9cf03b7e
NC
17332 addr_size * 2, _("Sym.Val."),
17333 _("Type"),
17334 /* Note for translators: "Ndx" = abbreviated form of "Index". */
17335 _("Ndx"), _("Name"));
0b4362b0 17336
ccb4c951 17337 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 17338
ccb4c951
RS
17339 for (i = gotsym; i < symtabno; i++)
17340 {
82b1b41b 17341 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 17342 printf (" ");
e0a31db1 17343
978c4450 17344 if (filedata->dynamic_symbols == NULL)
e0a31db1 17345 printf (_("<no dynamic symbols>"));
978c4450 17346 else if (i < filedata->num_dynamic_syms)
e0a31db1 17347 {
978c4450 17348 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
17349
17350 print_vma (psym->st_value, LONG_HEX);
17351 printf (" %-7s %3s ",
dda8d76d
NC
17352 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
17353 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 17354
978c4450
AM
17355 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17356 print_symbol (sym_width,
17357 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17358 else
17359 printf (_("<corrupt: %14ld>"), psym->st_name);
17360 }
ccb4c951 17361 else
7fc5ac57
JBG
17362 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
17363 (unsigned long) i);
e0a31db1 17364
ccb4c951 17365 printf ("\n");
82b1b41b
NC
17366 if (ent == (bfd_vma) -1)
17367 break;
ccb4c951
RS
17368 }
17369 printf ("\n");
17370 }
17371
82b1b41b 17372 got_print_fail:
ccb4c951
RS
17373 if (data)
17374 free (data);
17375 }
17376
861fb55a
DJ
17377 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
17378 {
91d6fa6a 17379 bfd_vma ent, end;
861fb55a
DJ
17380 size_t offset, rel_offset;
17381 unsigned long count, i;
2cf0635d 17382 unsigned char * data;
861fb55a 17383 int addr_size, sym_width;
2cf0635d 17384 Elf_Internal_Rela * rels;
861fb55a 17385
dda8d76d 17386 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
17387 if (pltrel == DT_RELA)
17388 {
dda8d76d 17389 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 17390 return FALSE;
861fb55a
DJ
17391 }
17392 else
17393 {
dda8d76d 17394 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 17395 return FALSE;
861fb55a
DJ
17396 }
17397
91d6fa6a 17398 ent = mips_pltgot;
861fb55a
DJ
17399 addr_size = (is_32bit_elf ? 4 : 8);
17400 end = mips_pltgot + (2 + count) * addr_size;
17401
dda8d76d
NC
17402 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
17403 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 17404 1, _("Procedure Linkage Table data"));
59245841 17405 if (data == NULL)
32ec8896 17406 return FALSE;
59245841 17407
9cf03b7e 17408 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
17409 printf (_(" Reserved entries:\n"));
17410 printf (_(" %*s %*s Purpose\n"),
2b692964 17411 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 17412 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 17413 printf (_(" PLT lazy resolver\n"));
91d6fa6a 17414 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 17415 printf (_(" Module pointer\n"));
861fb55a
DJ
17416 printf ("\n");
17417
17418 printf (_(" Entries:\n"));
cc5914eb 17419 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
17420 addr_size * 2, _("Address"),
17421 addr_size * 2, _("Initial"),
17422 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
17423 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
17424 for (i = 0; i < count; i++)
17425 {
df97ab2a 17426 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 17427
91d6fa6a 17428 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 17429 printf (" ");
e0a31db1 17430
978c4450 17431 if (idx >= filedata->num_dynamic_syms)
df97ab2a 17432 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 17433 else
e0a31db1 17434 {
978c4450 17435 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
17436
17437 print_vma (psym->st_value, LONG_HEX);
17438 printf (" %-7s %3s ",
dda8d76d
NC
17439 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
17440 get_symbol_index_type (filedata, psym->st_shndx));
978c4450
AM
17441 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17442 print_symbol (sym_width,
17443 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17444 else
17445 printf (_("<corrupt: %14ld>"), psym->st_name);
17446 }
861fb55a
DJ
17447 printf ("\n");
17448 }
17449 printf ("\n");
17450
17451 if (data)
17452 free (data);
17453 free (rels);
17454 }
17455
32ec8896 17456 return res;
252b5132
RH
17457}
17458
32ec8896 17459static bfd_boolean
dda8d76d 17460process_nds32_specific (Filedata * filedata)
35c08157
KLC
17461{
17462 Elf_Internal_Shdr *sect = NULL;
17463
dda8d76d 17464 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 17465 if (sect != NULL && sect->sh_size >= 4)
35c08157 17466 {
9c7b8e9b
AM
17467 unsigned char *buf;
17468 unsigned int flag;
35c08157
KLC
17469
17470 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
17471 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
17472 _("NDS32 elf flags section"));
35c08157 17473
9c7b8e9b 17474 if (buf == NULL)
32ec8896
NC
17475 return FALSE;
17476
9c7b8e9b
AM
17477 flag = byte_get (buf, 4);
17478 free (buf);
17479 switch (flag & 0x3)
35c08157
KLC
17480 {
17481 case 0:
17482 printf ("(VEC_SIZE):\tNo entry.\n");
17483 break;
17484 case 1:
17485 printf ("(VEC_SIZE):\t4 bytes\n");
17486 break;
17487 case 2:
17488 printf ("(VEC_SIZE):\t16 bytes\n");
17489 break;
17490 case 3:
17491 printf ("(VEC_SIZE):\treserved\n");
17492 break;
17493 }
17494 }
17495
17496 return TRUE;
17497}
17498
32ec8896 17499static bfd_boolean
dda8d76d 17500process_gnu_liblist (Filedata * filedata)
047b2264 17501{
2cf0635d
NC
17502 Elf_Internal_Shdr * section;
17503 Elf_Internal_Shdr * string_sec;
17504 Elf32_External_Lib * elib;
17505 char * strtab;
c256ffe7 17506 size_t strtab_size;
047b2264 17507 size_t cnt;
d3a49aa8 17508 unsigned long num_liblist;
047b2264 17509 unsigned i;
32ec8896 17510 bfd_boolean res = TRUE;
047b2264
JJ
17511
17512 if (! do_arch)
32ec8896 17513 return TRUE;
047b2264 17514
dda8d76d
NC
17515 for (i = 0, section = filedata->section_headers;
17516 i < filedata->file_header.e_shnum;
b34976b6 17517 i++, section++)
047b2264
JJ
17518 {
17519 switch (section->sh_type)
17520 {
17521 case SHT_GNU_LIBLIST:
dda8d76d 17522 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
17523 break;
17524
3f5e193b 17525 elib = (Elf32_External_Lib *)
dda8d76d 17526 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 17527 _("liblist section data"));
047b2264
JJ
17528
17529 if (elib == NULL)
32ec8896
NC
17530 {
17531 res = FALSE;
17532 break;
17533 }
047b2264 17534
dda8d76d
NC
17535 string_sec = filedata->section_headers + section->sh_link;
17536 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
17537 string_sec->sh_size,
17538 _("liblist string table"));
047b2264
JJ
17539 if (strtab == NULL
17540 || section->sh_entsize != sizeof (Elf32_External_Lib))
17541 {
17542 free (elib);
2842702f 17543 free (strtab);
32ec8896 17544 res = FALSE;
047b2264
JJ
17545 break;
17546 }
59245841 17547 strtab_size = string_sec->sh_size;
047b2264 17548
d3a49aa8
AM
17549 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
17550 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
17551 "\nLibrary list section '%s' contains %lu entries:\n",
17552 num_liblist),
dda8d76d 17553 printable_section_name (filedata, section),
d3a49aa8 17554 num_liblist);
047b2264 17555
2b692964 17556 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
17557
17558 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
17559 ++cnt)
17560 {
17561 Elf32_Lib liblist;
91d6fa6a 17562 time_t atime;
d5b07ef4 17563 char timebuf[128];
2cf0635d 17564 struct tm * tmp;
047b2264
JJ
17565
17566 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17567 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
17568 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17569 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17570 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17571
91d6fa6a 17572 tmp = gmtime (&atime);
e9e44622
JJ
17573 snprintf (timebuf, sizeof (timebuf),
17574 "%04u-%02u-%02uT%02u:%02u:%02u",
17575 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17576 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
17577
17578 printf ("%3lu: ", (unsigned long) cnt);
17579 if (do_wide)
c256ffe7 17580 printf ("%-20s", liblist.l_name < strtab_size
2b692964 17581 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 17582 else
c256ffe7 17583 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 17584 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
17585 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
17586 liblist.l_version, liblist.l_flags);
17587 }
17588
17589 free (elib);
2842702f 17590 free (strtab);
047b2264
JJ
17591 }
17592 }
17593
32ec8896 17594 return res;
047b2264
JJ
17595}
17596
9437c45b 17597static const char *
dda8d76d 17598get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
17599{
17600 static char buff[64];
103f02d3 17601
dda8d76d 17602 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
17603 switch (e_type)
17604 {
57346661 17605 case NT_AUXV:
1ec5cd37 17606 return _("NT_AUXV (auxiliary vector)");
57346661 17607 case NT_PRSTATUS:
1ec5cd37 17608 return _("NT_PRSTATUS (prstatus structure)");
57346661 17609 case NT_FPREGSET:
1ec5cd37 17610 return _("NT_FPREGSET (floating point registers)");
57346661 17611 case NT_PRPSINFO:
1ec5cd37 17612 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 17613 case NT_TASKSTRUCT:
1ec5cd37 17614 return _("NT_TASKSTRUCT (task structure)");
57346661 17615 case NT_PRXFPREG:
1ec5cd37 17616 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
17617 case NT_PPC_VMX:
17618 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
17619 case NT_PPC_VSX:
17620 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
17621 case NT_PPC_TAR:
17622 return _("NT_PPC_TAR (ppc TAR register)");
17623 case NT_PPC_PPR:
17624 return _("NT_PPC_PPR (ppc PPR register)");
17625 case NT_PPC_DSCR:
17626 return _("NT_PPC_DSCR (ppc DSCR register)");
17627 case NT_PPC_EBB:
17628 return _("NT_PPC_EBB (ppc EBB registers)");
17629 case NT_PPC_PMU:
17630 return _("NT_PPC_PMU (ppc PMU registers)");
17631 case NT_PPC_TM_CGPR:
17632 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
17633 case NT_PPC_TM_CFPR:
17634 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
17635 case NT_PPC_TM_CVMX:
17636 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
17637 case NT_PPC_TM_CVSX:
3fd21718 17638 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
17639 case NT_PPC_TM_SPR:
17640 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
17641 case NT_PPC_TM_CTAR:
17642 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
17643 case NT_PPC_TM_CPPR:
17644 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
17645 case NT_PPC_TM_CDSCR:
17646 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
17647 case NT_386_TLS:
17648 return _("NT_386_TLS (x86 TLS information)");
17649 case NT_386_IOPERM:
17650 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
17651 case NT_X86_XSTATE:
17652 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
17653 case NT_S390_HIGH_GPRS:
17654 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
17655 case NT_S390_TIMER:
17656 return _("NT_S390_TIMER (s390 timer register)");
17657 case NT_S390_TODCMP:
17658 return _("NT_S390_TODCMP (s390 TOD comparator register)");
17659 case NT_S390_TODPREG:
17660 return _("NT_S390_TODPREG (s390 TOD programmable register)");
17661 case NT_S390_CTRS:
17662 return _("NT_S390_CTRS (s390 control registers)");
17663 case NT_S390_PREFIX:
17664 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
17665 case NT_S390_LAST_BREAK:
17666 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
17667 case NT_S390_SYSTEM_CALL:
17668 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
17669 case NT_S390_TDB:
17670 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
17671 case NT_S390_VXRS_LOW:
17672 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
17673 case NT_S390_VXRS_HIGH:
17674 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
17675 case NT_S390_GS_CB:
17676 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
17677 case NT_S390_GS_BC:
17678 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
17679 case NT_ARM_VFP:
17680 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
17681 case NT_ARM_TLS:
17682 return _("NT_ARM_TLS (AArch TLS registers)");
17683 case NT_ARM_HW_BREAK:
17684 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
17685 case NT_ARM_HW_WATCH:
17686 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
27456742
AK
17687 case NT_ARC_V2:
17688 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
57346661 17689 case NT_PSTATUS:
1ec5cd37 17690 return _("NT_PSTATUS (pstatus structure)");
57346661 17691 case NT_FPREGS:
1ec5cd37 17692 return _("NT_FPREGS (floating point registers)");
57346661 17693 case NT_PSINFO:
1ec5cd37 17694 return _("NT_PSINFO (psinfo structure)");
57346661 17695 case NT_LWPSTATUS:
1ec5cd37 17696 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 17697 case NT_LWPSINFO:
1ec5cd37 17698 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 17699 case NT_WIN32PSTATUS:
1ec5cd37 17700 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
17701 case NT_SIGINFO:
17702 return _("NT_SIGINFO (siginfo_t data)");
17703 case NT_FILE:
17704 return _("NT_FILE (mapped files)");
1ec5cd37
NC
17705 default:
17706 break;
17707 }
17708 else
17709 switch (e_type)
17710 {
17711 case NT_VERSION:
17712 return _("NT_VERSION (version)");
17713 case NT_ARCH:
17714 return _("NT_ARCH (architecture)");
9ef920e9 17715 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 17716 return _("OPEN");
9ef920e9 17717 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 17718 return _("func");
1ec5cd37
NC
17719 default:
17720 break;
17721 }
17722
e9e44622 17723 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 17724 return buff;
779fe533
NC
17725}
17726
32ec8896 17727static bfd_boolean
9ece1fa9
TT
17728print_core_note (Elf_Internal_Note *pnote)
17729{
17730 unsigned int addr_size = is_32bit_elf ? 4 : 8;
17731 bfd_vma count, page_size;
17732 unsigned char *descdata, *filenames, *descend;
17733
17734 if (pnote->type != NT_FILE)
04ac15ab
AS
17735 {
17736 if (do_wide)
17737 printf ("\n");
17738 return TRUE;
17739 }
9ece1fa9
TT
17740
17741#ifndef BFD64
17742 if (!is_32bit_elf)
17743 {
17744 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
17745 /* Still "successful". */
32ec8896 17746 return TRUE;
9ece1fa9
TT
17747 }
17748#endif
17749
17750 if (pnote->descsz < 2 * addr_size)
17751 {
32ec8896
NC
17752 error (_(" Malformed note - too short for header\n"));
17753 return FALSE;
9ece1fa9
TT
17754 }
17755
17756 descdata = (unsigned char *) pnote->descdata;
17757 descend = descdata + pnote->descsz;
17758
17759 if (descdata[pnote->descsz - 1] != '\0')
17760 {
32ec8896
NC
17761 error (_(" Malformed note - does not end with \\0\n"));
17762 return FALSE;
9ece1fa9
TT
17763 }
17764
17765 count = byte_get (descdata, addr_size);
17766 descdata += addr_size;
17767
17768 page_size = byte_get (descdata, addr_size);
17769 descdata += addr_size;
17770
5396a86e
AM
17771 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
17772 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 17773 {
32ec8896
NC
17774 error (_(" Malformed note - too short for supplied file count\n"));
17775 return FALSE;
9ece1fa9
TT
17776 }
17777
17778 printf (_(" Page size: "));
17779 print_vma (page_size, DEC);
17780 printf ("\n");
17781
17782 printf (_(" %*s%*s%*s\n"),
17783 (int) (2 + 2 * addr_size), _("Start"),
17784 (int) (4 + 2 * addr_size), _("End"),
17785 (int) (4 + 2 * addr_size), _("Page Offset"));
17786 filenames = descdata + count * 3 * addr_size;
595712bb 17787 while (count-- > 0)
9ece1fa9
TT
17788 {
17789 bfd_vma start, end, file_ofs;
17790
17791 if (filenames == descend)
17792 {
32ec8896
NC
17793 error (_(" Malformed note - filenames end too early\n"));
17794 return FALSE;
9ece1fa9
TT
17795 }
17796
17797 start = byte_get (descdata, addr_size);
17798 descdata += addr_size;
17799 end = byte_get (descdata, addr_size);
17800 descdata += addr_size;
17801 file_ofs = byte_get (descdata, addr_size);
17802 descdata += addr_size;
17803
17804 printf (" ");
17805 print_vma (start, FULL_HEX);
17806 printf (" ");
17807 print_vma (end, FULL_HEX);
17808 printf (" ");
17809 print_vma (file_ofs, FULL_HEX);
17810 printf ("\n %s\n", filenames);
17811
17812 filenames += 1 + strlen ((char *) filenames);
17813 }
17814
32ec8896 17815 return TRUE;
9ece1fa9
TT
17816}
17817
1118d252
RM
17818static const char *
17819get_gnu_elf_note_type (unsigned e_type)
17820{
1449284b 17821 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
17822 switch (e_type)
17823 {
17824 case NT_GNU_ABI_TAG:
17825 return _("NT_GNU_ABI_TAG (ABI version tag)");
17826 case NT_GNU_HWCAP:
17827 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
17828 case NT_GNU_BUILD_ID:
17829 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
17830 case NT_GNU_GOLD_VERSION:
17831 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
17832 case NT_GNU_PROPERTY_TYPE_0:
17833 return _("NT_GNU_PROPERTY_TYPE_0");
17834 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
17835 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
17836 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
17837 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 17838 default:
1449284b
NC
17839 {
17840 static char buff[64];
1118d252 17841
1449284b
NC
17842 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
17843 return buff;
17844 }
17845 }
1118d252
RM
17846}
17847
a9eafb08
L
17848static void
17849decode_x86_compat_isa (unsigned int bitmask)
17850{
17851 while (bitmask)
17852 {
17853 unsigned int bit = bitmask & (- bitmask);
17854
17855 bitmask &= ~ bit;
17856 switch (bit)
17857 {
17858 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
17859 printf ("i486");
17860 break;
17861 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
17862 printf ("586");
17863 break;
17864 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
17865 printf ("686");
17866 break;
17867 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
17868 printf ("SSE");
17869 break;
17870 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
17871 printf ("SSE2");
17872 break;
17873 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
17874 printf ("SSE3");
17875 break;
17876 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
17877 printf ("SSSE3");
17878 break;
17879 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
17880 printf ("SSE4_1");
17881 break;
17882 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
17883 printf ("SSE4_2");
17884 break;
17885 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
17886 printf ("AVX");
17887 break;
17888 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
17889 printf ("AVX2");
17890 break;
17891 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
17892 printf ("AVX512F");
17893 break;
17894 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
17895 printf ("AVX512CD");
17896 break;
17897 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
17898 printf ("AVX512ER");
17899 break;
17900 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
17901 printf ("AVX512PF");
17902 break;
17903 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
17904 printf ("AVX512VL");
17905 break;
17906 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
17907 printf ("AVX512DQ");
17908 break;
17909 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
17910 printf ("AVX512BW");
17911 break;
65b3d26e
L
17912 default:
17913 printf (_("<unknown: %x>"), bit);
17914 break;
a9eafb08
L
17915 }
17916 if (bitmask)
17917 printf (", ");
17918 }
17919}
17920
9ef920e9 17921static void
1fc87489 17922decode_x86_isa (unsigned int bitmask)
9ef920e9 17923{
0a59decb 17924 if (!bitmask)
90c745dc
L
17925 {
17926 printf (_("<None>"));
17927 return;
17928 }
90c745dc 17929
9ef920e9
NC
17930 while (bitmask)
17931 {
1fc87489 17932 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
17933
17934 bitmask &= ~ bit;
17935 switch (bit)
17936 {
a9eafb08
L
17937 case GNU_PROPERTY_X86_ISA_1_CMOV:
17938 printf ("CMOV");
17939 break;
17940 case GNU_PROPERTY_X86_ISA_1_SSE:
17941 printf ("SSE");
17942 break;
17943 case GNU_PROPERTY_X86_ISA_1_SSE2:
17944 printf ("SSE2");
17945 break;
17946 case GNU_PROPERTY_X86_ISA_1_SSE3:
17947 printf ("SSE3");
17948 break;
17949 case GNU_PROPERTY_X86_ISA_1_SSSE3:
17950 printf ("SSSE3");
17951 break;
17952 case GNU_PROPERTY_X86_ISA_1_SSE4_1:
17953 printf ("SSE4_1");
17954 break;
17955 case GNU_PROPERTY_X86_ISA_1_SSE4_2:
17956 printf ("SSE4_2");
17957 break;
17958 case GNU_PROPERTY_X86_ISA_1_AVX:
17959 printf ("AVX");
17960 break;
17961 case GNU_PROPERTY_X86_ISA_1_AVX2:
17962 printf ("AVX2");
17963 break;
17964 case GNU_PROPERTY_X86_ISA_1_FMA:
17965 printf ("FMA");
17966 break;
17967 case GNU_PROPERTY_X86_ISA_1_AVX512F:
17968 printf ("AVX512F");
17969 break;
17970 case GNU_PROPERTY_X86_ISA_1_AVX512CD:
17971 printf ("AVX512CD");
17972 break;
17973 case GNU_PROPERTY_X86_ISA_1_AVX512ER:
17974 printf ("AVX512ER");
17975 break;
17976 case GNU_PROPERTY_X86_ISA_1_AVX512PF:
17977 printf ("AVX512PF");
17978 break;
17979 case GNU_PROPERTY_X86_ISA_1_AVX512VL:
17980 printf ("AVX512VL");
17981 break;
17982 case GNU_PROPERTY_X86_ISA_1_AVX512DQ:
17983 printf ("AVX512DQ");
17984 break;
17985 case GNU_PROPERTY_X86_ISA_1_AVX512BW:
17986 printf ("AVX512BW");
17987 break;
17988 case GNU_PROPERTY_X86_ISA_1_AVX512_4FMAPS:
17989 printf ("AVX512_4FMAPS");
17990 break;
17991 case GNU_PROPERTY_X86_ISA_1_AVX512_4VNNIW:
17992 printf ("AVX512_4VNNIW");
17993 break;
17994 case GNU_PROPERTY_X86_ISA_1_AVX512_BITALG:
17995 printf ("AVX512_BITALG");
17996 break;
17997 case GNU_PROPERTY_X86_ISA_1_AVX512_IFMA:
17998 printf ("AVX512_IFMA");
17999 break;
18000 case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI:
18001 printf ("AVX512_VBMI");
18002 break;
18003 case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI2:
18004 printf ("AVX512_VBMI2");
18005 break;
18006 case GNU_PROPERTY_X86_ISA_1_AVX512_VNNI:
18007 printf ("AVX512_VNNI");
18008 break;
462cac58
L
18009 case GNU_PROPERTY_X86_ISA_1_AVX512_BF16:
18010 printf ("AVX512_BF16");
18011 break;
65b3d26e
L
18012 default:
18013 printf (_("<unknown: %x>"), bit);
18014 break;
9ef920e9
NC
18015 }
18016 if (bitmask)
18017 printf (", ");
18018 }
18019}
18020
ee2fdd6f 18021static void
a9eafb08 18022decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 18023{
0a59decb 18024 if (!bitmask)
90c745dc
L
18025 {
18026 printf (_("<None>"));
18027 return;
18028 }
90c745dc 18029
ee2fdd6f
L
18030 while (bitmask)
18031 {
18032 unsigned int bit = bitmask & (- bitmask);
18033
18034 bitmask &= ~ bit;
18035 switch (bit)
18036 {
18037 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 18038 printf ("IBT");
ee2fdd6f 18039 break;
48580982 18040 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 18041 printf ("SHSTK");
48580982 18042 break;
ee2fdd6f
L
18043 default:
18044 printf (_("<unknown: %x>"), bit);
18045 break;
18046 }
18047 if (bitmask)
18048 printf (", ");
18049 }
18050}
18051
a9eafb08
L
18052static void
18053decode_x86_feature_2 (unsigned int bitmask)
18054{
0a59decb 18055 if (!bitmask)
90c745dc
L
18056 {
18057 printf (_("<None>"));
18058 return;
18059 }
90c745dc 18060
a9eafb08
L
18061 while (bitmask)
18062 {
18063 unsigned int bit = bitmask & (- bitmask);
18064
18065 bitmask &= ~ bit;
18066 switch (bit)
18067 {
18068 case GNU_PROPERTY_X86_FEATURE_2_X86:
18069 printf ("x86");
18070 break;
18071 case GNU_PROPERTY_X86_FEATURE_2_X87:
18072 printf ("x87");
18073 break;
18074 case GNU_PROPERTY_X86_FEATURE_2_MMX:
18075 printf ("MMX");
18076 break;
18077 case GNU_PROPERTY_X86_FEATURE_2_XMM:
18078 printf ("XMM");
18079 break;
18080 case GNU_PROPERTY_X86_FEATURE_2_YMM:
18081 printf ("YMM");
18082 break;
18083 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
18084 printf ("ZMM");
18085 break;
18086 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
18087 printf ("FXSR");
18088 break;
18089 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
18090 printf ("XSAVE");
18091 break;
18092 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
18093 printf ("XSAVEOPT");
18094 break;
18095 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
18096 printf ("XSAVEC");
18097 break;
65b3d26e
L
18098 default:
18099 printf (_("<unknown: %x>"), bit);
18100 break;
a9eafb08
L
18101 }
18102 if (bitmask)
18103 printf (", ");
18104 }
18105}
18106
cd702818
SD
18107static void
18108decode_aarch64_feature_1_and (unsigned int bitmask)
18109{
18110 while (bitmask)
18111 {
18112 unsigned int bit = bitmask & (- bitmask);
18113
18114 bitmask &= ~ bit;
18115 switch (bit)
18116 {
18117 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
18118 printf ("BTI");
18119 break;
18120
18121 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
18122 printf ("PAC");
18123 break;
18124
18125 default:
18126 printf (_("<unknown: %x>"), bit);
18127 break;
18128 }
18129 if (bitmask)
18130 printf (", ");
18131 }
18132}
18133
9ef920e9 18134static void
dda8d76d 18135print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
18136{
18137 unsigned char * ptr = (unsigned char *) pnote->descdata;
18138 unsigned char * ptr_end = ptr + pnote->descsz;
18139 unsigned int size = is_32bit_elf ? 4 : 8;
18140
18141 printf (_(" Properties: "));
18142
1fc87489 18143 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
18144 {
18145 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
18146 return;
18147 }
18148
6ab2c4ed 18149 while (ptr < ptr_end)
9ef920e9 18150 {
1fc87489 18151 unsigned int j;
6ab2c4ed
MC
18152 unsigned int type;
18153 unsigned int datasz;
18154
18155 if ((size_t) (ptr_end - ptr) < 8)
18156 {
18157 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
18158 break;
18159 }
18160
18161 type = byte_get (ptr, 4);
18162 datasz = byte_get (ptr + 4, 4);
9ef920e9 18163
1fc87489 18164 ptr += 8;
9ef920e9 18165
6ab2c4ed 18166 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 18167 {
1fc87489
L
18168 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
18169 type, datasz);
9ef920e9 18170 break;
1fc87489 18171 }
9ef920e9 18172
1fc87489
L
18173 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
18174 {
dda8d76d
NC
18175 if (filedata->file_header.e_machine == EM_X86_64
18176 || filedata->file_header.e_machine == EM_IAMCU
18177 || filedata->file_header.e_machine == EM_386)
1fc87489 18178 {
aa7bca9b
L
18179 unsigned int bitmask;
18180
18181 if (datasz == 4)
0a59decb 18182 bitmask = byte_get (ptr, 4);
aa7bca9b
L
18183 else
18184 bitmask = 0;
18185
1fc87489
L
18186 switch (type)
18187 {
18188 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 18189 if (datasz != 4)
aa7bca9b
L
18190 printf (_("x86 ISA used: <corrupt length: %#x> "),
18191 datasz);
1fc87489 18192 else
aa7bca9b
L
18193 {
18194 printf ("x86 ISA used: ");
18195 decode_x86_isa (bitmask);
18196 }
1fc87489 18197 goto next;
9ef920e9 18198
1fc87489 18199 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 18200 if (datasz != 4)
aa7bca9b
L
18201 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18202 datasz);
1fc87489 18203 else
aa7bca9b
L
18204 {
18205 printf ("x86 ISA needed: ");
18206 decode_x86_isa (bitmask);
18207 }
1fc87489 18208 goto next;
9ef920e9 18209
ee2fdd6f 18210 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 18211 if (datasz != 4)
aa7bca9b
L
18212 printf (_("x86 feature: <corrupt length: %#x> "),
18213 datasz);
ee2fdd6f 18214 else
aa7bca9b
L
18215 {
18216 printf ("x86 feature: ");
a9eafb08
L
18217 decode_x86_feature_1 (bitmask);
18218 }
18219 goto next;
18220
18221 case GNU_PROPERTY_X86_FEATURE_2_USED:
18222 if (datasz != 4)
18223 printf (_("x86 feature used: <corrupt length: %#x> "),
18224 datasz);
18225 else
18226 {
18227 printf ("x86 feature used: ");
18228 decode_x86_feature_2 (bitmask);
18229 }
18230 goto next;
18231
18232 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
18233 if (datasz != 4)
18234 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
18235 else
18236 {
18237 printf ("x86 feature needed: ");
18238 decode_x86_feature_2 (bitmask);
18239 }
18240 goto next;
18241
18242 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
18243 if (datasz != 4)
18244 printf (_("x86 ISA used: <corrupt length: %#x> "),
18245 datasz);
18246 else
18247 {
18248 printf ("x86 ISA used: ");
18249 decode_x86_compat_isa (bitmask);
18250 }
18251 goto next;
18252
18253 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
18254 if (datasz != 4)
18255 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18256 datasz);
18257 else
18258 {
18259 printf ("x86 ISA needed: ");
18260 decode_x86_compat_isa (bitmask);
aa7bca9b 18261 }
ee2fdd6f
L
18262 goto next;
18263
1fc87489
L
18264 default:
18265 break;
18266 }
18267 }
cd702818
SD
18268 else if (filedata->file_header.e_machine == EM_AARCH64)
18269 {
18270 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
18271 {
18272 printf ("AArch64 feature: ");
18273 if (datasz != 4)
18274 printf (_("<corrupt length: %#x> "), datasz);
18275 else
18276 decode_aarch64_feature_1_and (byte_get (ptr, 4));
18277 goto next;
18278 }
18279 }
1fc87489
L
18280 }
18281 else
18282 {
18283 switch (type)
9ef920e9 18284 {
1fc87489
L
18285 case GNU_PROPERTY_STACK_SIZE:
18286 printf (_("stack size: "));
18287 if (datasz != size)
18288 printf (_("<corrupt length: %#x> "), datasz);
18289 else
18290 printf ("%#lx", (unsigned long) byte_get (ptr, size));
18291 goto next;
18292
18293 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
18294 printf ("no copy on protected ");
18295 if (datasz)
18296 printf (_("<corrupt length: %#x> "), datasz);
18297 goto next;
18298
18299 default:
9ef920e9
NC
18300 break;
18301 }
9ef920e9
NC
18302 }
18303
1fc87489
L
18304 if (type < GNU_PROPERTY_LOPROC)
18305 printf (_("<unknown type %#x data: "), type);
18306 else if (type < GNU_PROPERTY_LOUSER)
18307 printf (_("<procesor-specific type %#x data: "), type);
18308 else
18309 printf (_("<application-specific type %#x data: "), type);
18310 for (j = 0; j < datasz; ++j)
18311 printf ("%02x ", ptr[j] & 0xff);
18312 printf (">");
18313
dc1e8a47 18314 next:
9ef920e9 18315 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
18316 if (ptr == ptr_end)
18317 break;
1fc87489 18318
6ab2c4ed
MC
18319 if (do_wide)
18320 printf (", ");
18321 else
18322 printf ("\n\t");
9ef920e9
NC
18323 }
18324
18325 printf ("\n");
18326}
18327
32ec8896 18328static bfd_boolean
dda8d76d 18329print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 18330{
1449284b 18331 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
18332 switch (pnote->type)
18333 {
18334 case NT_GNU_BUILD_ID:
18335 {
18336 unsigned long i;
18337
18338 printf (_(" Build ID: "));
18339 for (i = 0; i < pnote->descsz; ++i)
18340 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 18341 printf ("\n");
664f90a3
TT
18342 }
18343 break;
18344
18345 case NT_GNU_ABI_TAG:
18346 {
18347 unsigned long os, major, minor, subminor;
18348 const char *osname;
18349
3102e897
NC
18350 /* PR 17531: file: 030-599401-0.004. */
18351 if (pnote->descsz < 16)
18352 {
18353 printf (_(" <corrupt GNU_ABI_TAG>\n"));
18354 break;
18355 }
18356
664f90a3
TT
18357 os = byte_get ((unsigned char *) pnote->descdata, 4);
18358 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
18359 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
18360 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
18361
18362 switch (os)
18363 {
18364 case GNU_ABI_TAG_LINUX:
18365 osname = "Linux";
18366 break;
18367 case GNU_ABI_TAG_HURD:
18368 osname = "Hurd";
18369 break;
18370 case GNU_ABI_TAG_SOLARIS:
18371 osname = "Solaris";
18372 break;
18373 case GNU_ABI_TAG_FREEBSD:
18374 osname = "FreeBSD";
18375 break;
18376 case GNU_ABI_TAG_NETBSD:
18377 osname = "NetBSD";
18378 break;
14ae95f2
RM
18379 case GNU_ABI_TAG_SYLLABLE:
18380 osname = "Syllable";
18381 break;
18382 case GNU_ABI_TAG_NACL:
18383 osname = "NaCl";
18384 break;
664f90a3
TT
18385 default:
18386 osname = "Unknown";
18387 break;
18388 }
18389
18390 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
18391 major, minor, subminor);
18392 }
18393 break;
926c5385
CC
18394
18395 case NT_GNU_GOLD_VERSION:
18396 {
18397 unsigned long i;
18398
18399 printf (_(" Version: "));
18400 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
18401 printf ("%c", pnote->descdata[i]);
18402 printf ("\n");
18403 }
18404 break;
1449284b
NC
18405
18406 case NT_GNU_HWCAP:
18407 {
18408 unsigned long num_entries, mask;
18409
18410 /* Hardware capabilities information. Word 0 is the number of entries.
18411 Word 1 is a bitmask of enabled entries. The rest of the descriptor
18412 is a series of entries, where each entry is a single byte followed
18413 by a nul terminated string. The byte gives the bit number to test
18414 if enabled in the bitmask. */
18415 printf (_(" Hardware Capabilities: "));
18416 if (pnote->descsz < 8)
18417 {
32ec8896
NC
18418 error (_("<corrupt GNU_HWCAP>\n"));
18419 return FALSE;
1449284b
NC
18420 }
18421 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
18422 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
18423 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
18424 /* FIXME: Add code to display the entries... */
18425 }
18426 break;
18427
9ef920e9 18428 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 18429 print_gnu_property_note (filedata, pnote);
9ef920e9 18430 break;
9abca702 18431
1449284b
NC
18432 default:
18433 /* Handle unrecognised types. An error message should have already been
18434 created by get_gnu_elf_note_type(), so all that we need to do is to
18435 display the data. */
18436 {
18437 unsigned long i;
18438
18439 printf (_(" Description data: "));
18440 for (i = 0; i < pnote->descsz; ++i)
18441 printf ("%02x ", pnote->descdata[i] & 0xff);
18442 printf ("\n");
18443 }
18444 break;
664f90a3
TT
18445 }
18446
32ec8896 18447 return TRUE;
664f90a3
TT
18448}
18449
685080f2
NC
18450static const char *
18451get_v850_elf_note_type (enum v850_notes n_type)
18452{
18453 static char buff[64];
18454
18455 switch (n_type)
18456 {
18457 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
18458 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
18459 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
18460 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
18461 case V850_NOTE_CACHE_INFO: return _("Use of cache");
18462 case V850_NOTE_MMU_INFO: return _("Use of MMU");
18463 default:
18464 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
18465 return buff;
18466 }
18467}
18468
32ec8896 18469static bfd_boolean
685080f2
NC
18470print_v850_note (Elf_Internal_Note * pnote)
18471{
18472 unsigned int val;
18473
18474 if (pnote->descsz != 4)
32ec8896
NC
18475 return FALSE;
18476
685080f2
NC
18477 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
18478
18479 if (val == 0)
18480 {
18481 printf (_("not set\n"));
32ec8896 18482 return TRUE;
685080f2
NC
18483 }
18484
18485 switch (pnote->type)
18486 {
18487 case V850_NOTE_ALIGNMENT:
18488 switch (val)
18489 {
32ec8896
NC
18490 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return TRUE;
18491 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return TRUE;
685080f2
NC
18492 }
18493 break;
14ae95f2 18494
685080f2
NC
18495 case V850_NOTE_DATA_SIZE:
18496 switch (val)
18497 {
32ec8896
NC
18498 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return TRUE;
18499 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return TRUE;
685080f2
NC
18500 }
18501 break;
14ae95f2 18502
685080f2
NC
18503 case V850_NOTE_FPU_INFO:
18504 switch (val)
18505 {
32ec8896
NC
18506 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return TRUE;
18507 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return TRUE;
685080f2
NC
18508 }
18509 break;
14ae95f2 18510
685080f2
NC
18511 case V850_NOTE_MMU_INFO:
18512 case V850_NOTE_CACHE_INFO:
18513 case V850_NOTE_SIMD_INFO:
18514 if (val == EF_RH850_SIMD)
18515 {
18516 printf (_("yes\n"));
32ec8896 18517 return TRUE;
685080f2
NC
18518 }
18519 break;
18520
18521 default:
18522 /* An 'unknown note type' message will already have been displayed. */
18523 break;
18524 }
18525
18526 printf (_("unknown value: %x\n"), val);
32ec8896 18527 return FALSE;
685080f2
NC
18528}
18529
32ec8896 18530static bfd_boolean
c6056a74
SF
18531process_netbsd_elf_note (Elf_Internal_Note * pnote)
18532{
18533 unsigned int version;
18534
18535 switch (pnote->type)
18536 {
18537 case NT_NETBSD_IDENT:
b966f55f
AM
18538 if (pnote->descsz < 1)
18539 break;
c6056a74
SF
18540 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
18541 if ((version / 10000) % 100)
b966f55f 18542 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
18543 version, version / 100000000, (version / 1000000) % 100,
18544 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 18545 'A' + (version / 10000) % 26);
c6056a74
SF
18546 else
18547 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 18548 version, version / 100000000, (version / 1000000) % 100,
15f205b1 18549 (version / 100) % 100);
32ec8896 18550 return TRUE;
c6056a74
SF
18551
18552 case NT_NETBSD_MARCH:
9abca702 18553 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 18554 pnote->descdata);
32ec8896 18555 return TRUE;
c6056a74 18556
9abca702
CZ
18557#ifdef NT_NETBSD_PAX
18558 case NT_NETBSD_PAX:
b966f55f
AM
18559 if (pnote->descsz < 1)
18560 break;
9abca702
CZ
18561 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
18562 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
18563 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
18564 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
18565 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
18566 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
18567 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
18568 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
18569 return TRUE;
18570#endif
c6056a74 18571 }
b966f55f
AM
18572
18573 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
18574 pnote->descsz, pnote->type);
18575 return FALSE;
c6056a74
SF
18576}
18577
f4ddf30f 18578static const char *
dda8d76d 18579get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 18580{
f4ddf30f
JB
18581 switch (e_type)
18582 {
18583 case NT_FREEBSD_THRMISC:
18584 return _("NT_THRMISC (thrmisc structure)");
18585 case NT_FREEBSD_PROCSTAT_PROC:
18586 return _("NT_PROCSTAT_PROC (proc data)");
18587 case NT_FREEBSD_PROCSTAT_FILES:
18588 return _("NT_PROCSTAT_FILES (files data)");
18589 case NT_FREEBSD_PROCSTAT_VMMAP:
18590 return _("NT_PROCSTAT_VMMAP (vmmap data)");
18591 case NT_FREEBSD_PROCSTAT_GROUPS:
18592 return _("NT_PROCSTAT_GROUPS (groups data)");
18593 case NT_FREEBSD_PROCSTAT_UMASK:
18594 return _("NT_PROCSTAT_UMASK (umask data)");
18595 case NT_FREEBSD_PROCSTAT_RLIMIT:
18596 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
18597 case NT_FREEBSD_PROCSTAT_OSREL:
18598 return _("NT_PROCSTAT_OSREL (osreldate data)");
18599 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
18600 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
18601 case NT_FREEBSD_PROCSTAT_AUXV:
18602 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
18603 case NT_FREEBSD_PTLWPINFO:
18604 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 18605 }
dda8d76d 18606 return get_note_type (filedata, e_type);
f4ddf30f
JB
18607}
18608
9437c45b 18609static const char *
dda8d76d 18610get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
18611{
18612 static char buff[64];
18613
540e6170
CZ
18614 switch (e_type)
18615 {
18616 case NT_NETBSDCORE_PROCINFO:
18617 /* NetBSD core "procinfo" structure. */
18618 return _("NetBSD procinfo structure");
9437c45b 18619
540e6170
CZ
18620#ifdef NT_NETBSDCORE_AUXV
18621 case NT_NETBSDCORE_AUXV:
18622 return _("NetBSD ELF auxiliary vector data");
18623#endif
9437c45b 18624
06d949ec
KR
18625#ifdef NT_NETBSDCORE_LWPSTATUS
18626 case NT_NETBSDCORE_LWPSTATUS:
18627 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
18628#endif
18629
540e6170 18630 default:
06d949ec 18631 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
18632 defined for NetBSD core files. If the note type is less
18633 than the start of the machine-dependent note types, we don't
18634 understand it. */
18635
18636 if (e_type < NT_NETBSDCORE_FIRSTMACH)
18637 {
18638 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18639 return buff;
18640 }
18641 break;
9437c45b
JT
18642 }
18643
dda8d76d 18644 switch (filedata->file_header.e_machine)
9437c45b
JT
18645 {
18646 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
18647 and PT_GETFPREGS == mach+2. */
18648
18649 case EM_OLD_ALPHA:
18650 case EM_ALPHA:
18651 case EM_SPARC:
18652 case EM_SPARC32PLUS:
18653 case EM_SPARCV9:
18654 switch (e_type)
18655 {
2b692964 18656 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 18657 return _("PT_GETREGS (reg structure)");
2b692964 18658 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 18659 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
18660 default:
18661 break;
18662 }
18663 break;
18664
c0d38b0e
CZ
18665 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
18666 There's also old PT___GETREGS40 == mach + 1 for old reg
18667 structure which lacks GBR. */
18668 case EM_SH:
18669 switch (e_type)
18670 {
18671 case NT_NETBSDCORE_FIRSTMACH + 1:
18672 return _("PT___GETREGS40 (old reg structure)");
18673 case NT_NETBSDCORE_FIRSTMACH + 3:
18674 return _("PT_GETREGS (reg structure)");
18675 case NT_NETBSDCORE_FIRSTMACH + 5:
18676 return _("PT_GETFPREGS (fpreg structure)");
18677 default:
18678 break;
18679 }
18680 break;
18681
9437c45b
JT
18682 /* On all other arch's, PT_GETREGS == mach+1 and
18683 PT_GETFPREGS == mach+3. */
18684 default:
18685 switch (e_type)
18686 {
2b692964 18687 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 18688 return _("PT_GETREGS (reg structure)");
2b692964 18689 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 18690 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
18691 default:
18692 break;
18693 }
18694 }
18695
9cf03b7e 18696 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 18697 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
18698 return buff;
18699}
18700
70616151
TT
18701static const char *
18702get_stapsdt_note_type (unsigned e_type)
18703{
18704 static char buff[64];
18705
18706 switch (e_type)
18707 {
18708 case NT_STAPSDT:
18709 return _("NT_STAPSDT (SystemTap probe descriptors)");
18710
18711 default:
18712 break;
18713 }
18714
18715 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18716 return buff;
18717}
18718
32ec8896 18719static bfd_boolean
c6a9fc58
TT
18720print_stapsdt_note (Elf_Internal_Note *pnote)
18721{
3ca60c57
NC
18722 size_t len, maxlen;
18723 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
18724 char *data = pnote->descdata;
18725 char *data_end = pnote->descdata + pnote->descsz;
18726 bfd_vma pc, base_addr, semaphore;
18727 char *provider, *probe, *arg_fmt;
18728
3ca60c57
NC
18729 if (pnote->descsz < (addr_size * 3))
18730 goto stapdt_note_too_small;
18731
c6a9fc58
TT
18732 pc = byte_get ((unsigned char *) data, addr_size);
18733 data += addr_size;
3ca60c57 18734
c6a9fc58
TT
18735 base_addr = byte_get ((unsigned char *) data, addr_size);
18736 data += addr_size;
3ca60c57 18737
c6a9fc58
TT
18738 semaphore = byte_get ((unsigned char *) data, addr_size);
18739 data += addr_size;
18740
3ca60c57
NC
18741 if (data >= data_end)
18742 goto stapdt_note_too_small;
18743 maxlen = data_end - data;
18744 len = strnlen (data, maxlen);
18745 if (len < maxlen)
18746 {
18747 provider = data;
18748 data += len + 1;
18749 }
18750 else
18751 goto stapdt_note_too_small;
18752
18753 if (data >= data_end)
18754 goto stapdt_note_too_small;
18755 maxlen = data_end - data;
18756 len = strnlen (data, maxlen);
18757 if (len < maxlen)
18758 {
18759 probe = data;
18760 data += len + 1;
18761 }
18762 else
18763 goto stapdt_note_too_small;
9abca702 18764
3ca60c57
NC
18765 if (data >= data_end)
18766 goto stapdt_note_too_small;
18767 maxlen = data_end - data;
18768 len = strnlen (data, maxlen);
18769 if (len < maxlen)
18770 {
18771 arg_fmt = data;
18772 data += len + 1;
18773 }
18774 else
18775 goto stapdt_note_too_small;
c6a9fc58
TT
18776
18777 printf (_(" Provider: %s\n"), provider);
18778 printf (_(" Name: %s\n"), probe);
18779 printf (_(" Location: "));
18780 print_vma (pc, FULL_HEX);
18781 printf (_(", Base: "));
18782 print_vma (base_addr, FULL_HEX);
18783 printf (_(", Semaphore: "));
18784 print_vma (semaphore, FULL_HEX);
9cf03b7e 18785 printf ("\n");
c6a9fc58
TT
18786 printf (_(" Arguments: %s\n"), arg_fmt);
18787
18788 return data == data_end;
3ca60c57
NC
18789
18790 stapdt_note_too_small:
18791 printf (_(" <corrupt - note is too small>\n"));
18792 error (_("corrupt stapdt note - the data size is too small\n"));
18793 return FALSE;
c6a9fc58
TT
18794}
18795
00e98fc7
TG
18796static const char *
18797get_ia64_vms_note_type (unsigned e_type)
18798{
18799 static char buff[64];
18800
18801 switch (e_type)
18802 {
18803 case NT_VMS_MHD:
18804 return _("NT_VMS_MHD (module header)");
18805 case NT_VMS_LNM:
18806 return _("NT_VMS_LNM (language name)");
18807 case NT_VMS_SRC:
18808 return _("NT_VMS_SRC (source files)");
18809 case NT_VMS_TITLE:
9cf03b7e 18810 return "NT_VMS_TITLE";
00e98fc7
TG
18811 case NT_VMS_EIDC:
18812 return _("NT_VMS_EIDC (consistency check)");
18813 case NT_VMS_FPMODE:
18814 return _("NT_VMS_FPMODE (FP mode)");
18815 case NT_VMS_LINKTIME:
9cf03b7e 18816 return "NT_VMS_LINKTIME";
00e98fc7
TG
18817 case NT_VMS_IMGNAM:
18818 return _("NT_VMS_IMGNAM (image name)");
18819 case NT_VMS_IMGID:
18820 return _("NT_VMS_IMGID (image id)");
18821 case NT_VMS_LINKID:
18822 return _("NT_VMS_LINKID (link id)");
18823 case NT_VMS_IMGBID:
18824 return _("NT_VMS_IMGBID (build id)");
18825 case NT_VMS_GSTNAM:
18826 return _("NT_VMS_GSTNAM (sym table name)");
18827 case NT_VMS_ORIG_DYN:
9cf03b7e 18828 return "NT_VMS_ORIG_DYN";
00e98fc7 18829 case NT_VMS_PATCHTIME:
9cf03b7e 18830 return "NT_VMS_PATCHTIME";
00e98fc7
TG
18831 default:
18832 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18833 return buff;
18834 }
18835}
18836
32ec8896 18837static bfd_boolean
00e98fc7
TG
18838print_ia64_vms_note (Elf_Internal_Note * pnote)
18839{
8d18bf79
NC
18840 int maxlen = pnote->descsz;
18841
18842 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
18843 goto desc_size_fail;
18844
00e98fc7
TG
18845 switch (pnote->type)
18846 {
18847 case NT_VMS_MHD:
8d18bf79
NC
18848 if (maxlen <= 36)
18849 goto desc_size_fail;
18850
18851 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
18852
18853 printf (_(" Creation date : %.17s\n"), pnote->descdata);
18854 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
18855 if (l + 34 < maxlen)
18856 {
18857 printf (_(" Module name : %s\n"), pnote->descdata + 34);
18858 if (l + 35 < maxlen)
18859 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
18860 else
18861 printf (_(" Module version : <missing>\n"));
18862 }
00e98fc7 18863 else
8d18bf79
NC
18864 {
18865 printf (_(" Module name : <missing>\n"));
18866 printf (_(" Module version : <missing>\n"));
18867 }
00e98fc7 18868 break;
8d18bf79 18869
00e98fc7 18870 case NT_VMS_LNM:
8d18bf79 18871 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18872 break;
8d18bf79 18873
00e98fc7
TG
18874#ifdef BFD64
18875 case NT_VMS_FPMODE:
9cf03b7e 18876 printf (_(" Floating Point mode: "));
8d18bf79
NC
18877 if (maxlen < 8)
18878 goto desc_size_fail;
18879 /* FIXME: Generate an error if descsz > 8 ? */
18880
4a5cb34f 18881 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 18882 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 18883 break;
8d18bf79 18884
00e98fc7
TG
18885 case NT_VMS_LINKTIME:
18886 printf (_(" Link time: "));
8d18bf79
NC
18887 if (maxlen < 8)
18888 goto desc_size_fail;
18889 /* FIXME: Generate an error if descsz > 8 ? */
18890
00e98fc7 18891 print_vms_time
8d18bf79 18892 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
18893 printf ("\n");
18894 break;
8d18bf79 18895
00e98fc7
TG
18896 case NT_VMS_PATCHTIME:
18897 printf (_(" Patch time: "));
8d18bf79
NC
18898 if (maxlen < 8)
18899 goto desc_size_fail;
18900 /* FIXME: Generate an error if descsz > 8 ? */
18901
00e98fc7 18902 print_vms_time
8d18bf79 18903 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
18904 printf ("\n");
18905 break;
8d18bf79 18906
00e98fc7 18907 case NT_VMS_ORIG_DYN:
8d18bf79
NC
18908 if (maxlen < 34)
18909 goto desc_size_fail;
18910
00e98fc7
TG
18911 printf (_(" Major id: %u, minor id: %u\n"),
18912 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
18913 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 18914 printf (_(" Last modified : "));
00e98fc7
TG
18915 print_vms_time
18916 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 18917 printf (_("\n Link flags : "));
4a5cb34f 18918 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 18919 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 18920 printf (_(" Header flags: 0x%08x\n"),
948f632f 18921 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 18922 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
18923 break;
18924#endif
8d18bf79 18925
00e98fc7 18926 case NT_VMS_IMGNAM:
8d18bf79 18927 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18928 break;
8d18bf79 18929
00e98fc7 18930 case NT_VMS_GSTNAM:
8d18bf79 18931 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18932 break;
8d18bf79 18933
00e98fc7 18934 case NT_VMS_IMGID:
8d18bf79 18935 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18936 break;
8d18bf79 18937
00e98fc7 18938 case NT_VMS_LINKID:
8d18bf79 18939 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18940 break;
8d18bf79 18941
00e98fc7 18942 default:
32ec8896 18943 return FALSE;
00e98fc7 18944 }
8d18bf79 18945
32ec8896 18946 return TRUE;
8d18bf79
NC
18947
18948 desc_size_fail:
18949 printf (_(" <corrupt - data size is too small>\n"));
18950 error (_("corrupt IA64 note: data size is too small\n"));
18951 return FALSE;
00e98fc7
TG
18952}
18953
fd486f32
AM
18954struct build_attr_cache {
18955 Filedata *filedata;
18956 char *strtab;
18957 unsigned long strtablen;
18958 Elf_Internal_Sym *symtab;
18959 unsigned long nsyms;
18960} ba_cache;
18961
6f156d7a
NC
18962/* Find the symbol associated with a build attribute that is attached
18963 to address OFFSET. If PNAME is non-NULL then store the name of
18964 the symbol (if found) in the provided pointer, Returns NULL if a
18965 symbol could not be found. */
c799a79d 18966
6f156d7a
NC
18967static Elf_Internal_Sym *
18968get_symbol_for_build_attribute (Filedata * filedata,
18969 unsigned long offset,
18970 bfd_boolean is_open_attr,
18971 const char ** pname)
9ef920e9 18972{
fd486f32
AM
18973 Elf_Internal_Sym *saved_sym = NULL;
18974 Elf_Internal_Sym *sym;
9ef920e9 18975
dda8d76d 18976 if (filedata->section_headers != NULL
fd486f32 18977 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 18978 {
c799a79d 18979 Elf_Internal_Shdr * symsec;
9ef920e9 18980
fd486f32
AM
18981 free (ba_cache.strtab);
18982 ba_cache.strtab = NULL;
18983 free (ba_cache.symtab);
18984 ba_cache.symtab = NULL;
18985
c799a79d 18986 /* Load the symbol and string sections. */
dda8d76d
NC
18987 for (symsec = filedata->section_headers;
18988 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 18989 symsec ++)
9ef920e9 18990 {
28d13567
AM
18991 if (symsec->sh_type == SHT_SYMTAB
18992 && get_symtab (filedata, symsec,
18993 &ba_cache.symtab, &ba_cache.nsyms,
18994 &ba_cache.strtab, &ba_cache.strtablen))
18995 break;
9ef920e9 18996 }
fd486f32 18997 ba_cache.filedata = filedata;
9ef920e9
NC
18998 }
18999
fd486f32 19000 if (ba_cache.symtab == NULL)
6f156d7a 19001 return NULL;
9ef920e9 19002
c799a79d 19003 /* Find a symbol whose value matches offset. */
fd486f32 19004 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
19005 if (sym->st_value == offset)
19006 {
fd486f32 19007 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
19008 /* Huh ? This should not happen. */
19009 continue;
9ef920e9 19010
fd486f32 19011 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 19012 continue;
9ef920e9 19013
8fd75781
NC
19014 /* The AArch64 and ARM architectures define mapping symbols
19015 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
19016 if (ba_cache.strtab[sym->st_name] == '$'
19017 && ba_cache.strtab[sym->st_name + 1] != 0
19018 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
19019 continue;
19020
c799a79d
NC
19021 if (is_open_attr)
19022 {
19023 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
19024 and FILE or OBJECT symbols over NOTYPE symbols. We skip
19025 FUNC symbols entirely. */
19026 switch (ELF_ST_TYPE (sym->st_info))
19027 {
c799a79d 19028 case STT_OBJECT:
6f156d7a 19029 case STT_FILE:
c799a79d 19030 saved_sym = sym;
6f156d7a
NC
19031 if (sym->st_size)
19032 {
19033 /* If the symbol has a size associated
19034 with it then we can stop searching. */
fd486f32 19035 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 19036 }
c799a79d 19037 continue;
9ef920e9 19038
c799a79d
NC
19039 case STT_FUNC:
19040 /* Ignore function symbols. */
19041 continue;
19042
19043 default:
19044 break;
19045 }
19046
19047 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 19048 {
c799a79d
NC
19049 case STB_GLOBAL:
19050 if (saved_sym == NULL
19051 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
19052 saved_sym = sym;
19053 break;
c871dade 19054
c799a79d
NC
19055 case STB_LOCAL:
19056 if (saved_sym == NULL)
19057 saved_sym = sym;
19058 break;
19059
19060 default:
9ef920e9
NC
19061 break;
19062 }
19063 }
c799a79d
NC
19064 else
19065 {
19066 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
19067 continue;
19068
19069 saved_sym = sym;
19070 break;
19071 }
19072 }
19073
6f156d7a 19074 if (saved_sym && pname)
fd486f32 19075 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
19076
19077 return saved_sym;
c799a79d
NC
19078}
19079
d20e98ab
NC
19080/* Returns true iff addr1 and addr2 are in the same section. */
19081
19082static bfd_boolean
19083same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
19084{
19085 Elf_Internal_Shdr * a1;
19086 Elf_Internal_Shdr * a2;
19087
19088 a1 = find_section_by_address (filedata, addr1);
19089 a2 = find_section_by_address (filedata, addr2);
9abca702 19090
d20e98ab
NC
19091 return a1 == a2 && a1 != NULL;
19092}
19093
c799a79d 19094static bfd_boolean
dda8d76d
NC
19095print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
19096 Filedata * filedata)
c799a79d 19097{
6f156d7a
NC
19098 static unsigned long global_offset = 0;
19099 static unsigned long global_end = 0;
19100 static unsigned long func_offset = 0;
19101 static unsigned long func_end = 0;
c871dade 19102
6f156d7a
NC
19103 Elf_Internal_Sym * sym;
19104 const char * name;
19105 unsigned long start;
19106 unsigned long end;
19107 bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
19108
19109 switch (pnote->descsz)
c799a79d 19110 {
6f156d7a
NC
19111 case 0:
19112 /* A zero-length description means that the range of
19113 the previous note of the same type should be used. */
c799a79d 19114 if (is_open_attr)
c871dade 19115 {
6f156d7a
NC
19116 if (global_end > global_offset)
19117 printf (_(" Applies to region from %#lx to %#lx\n"),
19118 global_offset, global_end);
19119 else
19120 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
19121 }
19122 else
19123 {
6f156d7a
NC
19124 if (func_end > func_offset)
19125 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
19126 else
19127 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 19128 }
6f156d7a 19129 return TRUE;
9ef920e9 19130
6f156d7a
NC
19131 case 4:
19132 start = byte_get ((unsigned char *) pnote->descdata, 4);
19133 end = 0;
19134 break;
19135
19136 case 8:
19137 if (is_32bit_elf)
19138 {
19139 /* FIXME: We should check that version 3+ notes are being used here... */
19140 start = byte_get ((unsigned char *) pnote->descdata, 4);
19141 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19142 }
19143 else
19144 {
19145 start = byte_get ((unsigned char *) pnote->descdata, 8);
19146 end = 0;
19147 }
19148 break;
19149
19150 case 16:
19151 start = byte_get ((unsigned char *) pnote->descdata, 8);
19152 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
19153 break;
9abca702 19154
6f156d7a 19155 default:
c799a79d
NC
19156 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
19157 printf (_(" <invalid descsz>"));
19158 return FALSE;
19159 }
19160
6f156d7a
NC
19161 name = NULL;
19162 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
19163 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
19164 in order to avoid them being confused with the start address of the
19165 first function in the file... */
19166 if (sym == NULL && is_open_attr)
19167 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
19168 & name);
6f156d7a
NC
19169
19170 if (end == 0 && sym != NULL && sym->st_size > 0)
19171 end = start + sym->st_size;
c799a79d
NC
19172
19173 if (is_open_attr)
19174 {
d20e98ab
NC
19175 /* FIXME: Need to properly allow for section alignment.
19176 16 is just the alignment used on x86_64. */
19177 if (global_end > 0
19178 && start > BFD_ALIGN (global_end, 16)
19179 /* Build notes are not guaranteed to be organised in order of
19180 increasing address, but we should find the all of the notes
19181 for one section in the same place. */
19182 && same_section (filedata, start, global_end))
6f156d7a
NC
19183 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
19184 global_end + 1, start - 1);
19185
19186 printf (_(" Applies to region from %#lx"), start);
19187 global_offset = start;
19188
19189 if (end)
19190 {
19191 printf (_(" to %#lx"), end);
19192 global_end = end;
19193 }
c799a79d
NC
19194 }
19195 else
19196 {
6f156d7a
NC
19197 printf (_(" Applies to region from %#lx"), start);
19198 func_offset = start;
19199
19200 if (end)
19201 {
19202 printf (_(" to %#lx"), end);
19203 func_end = end;
19204 }
c799a79d
NC
19205 }
19206
6f156d7a
NC
19207 if (sym && name)
19208 printf (_(" (%s)"), name);
19209
19210 printf ("\n");
19211 return TRUE;
9ef920e9
NC
19212}
19213
19214static bfd_boolean
19215print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
19216{
1d15e434
NC
19217 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
19218 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
19219 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
19220 char name_type;
19221 char name_attribute;
1d15e434 19222 const char * expected_types;
9ef920e9
NC
19223 const char * name = pnote->namedata;
19224 const char * text;
88305e1b 19225 signed int left;
9ef920e9
NC
19226
19227 if (name == NULL || pnote->namesz < 2)
19228 {
19229 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 19230 print_symbol (-20, _(" <corrupt name>"));
9ef920e9
NC
19231 return FALSE;
19232 }
19233
6f156d7a
NC
19234 if (do_wide)
19235 left = 28;
19236 else
19237 left = 20;
88305e1b
NC
19238
19239 /* Version 2 of the spec adds a "GA" prefix to the name field. */
19240 if (name[0] == 'G' && name[1] == 'A')
19241 {
6f156d7a
NC
19242 if (pnote->namesz < 4)
19243 {
19244 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
19245 print_symbol (-20, _(" <corrupt name>"));
19246 return FALSE;
19247 }
19248
88305e1b
NC
19249 printf ("GA");
19250 name += 2;
19251 left -= 2;
19252 }
19253
9ef920e9
NC
19254 switch ((name_type = * name))
19255 {
19256 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
19257 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
19258 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
19259 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
19260 printf ("%c", * name);
88305e1b 19261 left --;
9ef920e9
NC
19262 break;
19263 default:
19264 error (_("unrecognised attribute type in name field: %d\n"), name_type);
19265 print_symbol (-20, _("<unknown name type>"));
19266 return FALSE;
19267 }
19268
9ef920e9
NC
19269 ++ name;
19270 text = NULL;
19271
19272 switch ((name_attribute = * name))
19273 {
19274 case GNU_BUILD_ATTRIBUTE_VERSION:
19275 text = _("<version>");
1d15e434 19276 expected_types = string_expected;
9ef920e9
NC
19277 ++ name;
19278 break;
19279 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
19280 text = _("<stack prot>");
75d7d298 19281 expected_types = "!+*";
9ef920e9
NC
19282 ++ name;
19283 break;
19284 case GNU_BUILD_ATTRIBUTE_RELRO:
19285 text = _("<relro>");
1d15e434 19286 expected_types = bool_expected;
9ef920e9
NC
19287 ++ name;
19288 break;
19289 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
19290 text = _("<stack size>");
1d15e434 19291 expected_types = number_expected;
9ef920e9
NC
19292 ++ name;
19293 break;
19294 case GNU_BUILD_ATTRIBUTE_TOOL:
19295 text = _("<tool>");
1d15e434 19296 expected_types = string_expected;
9ef920e9
NC
19297 ++ name;
19298 break;
19299 case GNU_BUILD_ATTRIBUTE_ABI:
19300 text = _("<ABI>");
19301 expected_types = "$*";
19302 ++ name;
19303 break;
19304 case GNU_BUILD_ATTRIBUTE_PIC:
19305 text = _("<PIC>");
1d15e434 19306 expected_types = number_expected;
9ef920e9
NC
19307 ++ name;
19308 break;
a8be5506
NC
19309 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
19310 text = _("<short enum>");
1d15e434 19311 expected_types = bool_expected;
a8be5506
NC
19312 ++ name;
19313 break;
9ef920e9
NC
19314 default:
19315 if (ISPRINT (* name))
19316 {
19317 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
19318
19319 if (len > left && ! do_wide)
19320 len = left;
75d7d298 19321 printf ("%.*s:", len, name);
9ef920e9 19322 left -= len;
0dd6ae21 19323 name += len;
9ef920e9
NC
19324 }
19325 else
19326 {
3e6b6445 19327 static char tmpbuf [128];
88305e1b 19328
3e6b6445
NC
19329 error (_("unrecognised byte in name field: %d\n"), * name);
19330 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
19331 text = tmpbuf;
19332 name ++;
9ef920e9
NC
19333 }
19334 expected_types = "*$!+";
19335 break;
19336 }
19337
19338 if (text)
88305e1b 19339 left -= printf ("%s", text);
9ef920e9
NC
19340
19341 if (strchr (expected_types, name_type) == NULL)
75d7d298 19342 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
19343
19344 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
19345 {
19346 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
19347 (unsigned long) pnote->namesz,
19348 (long) (name - pnote->namedata));
19349 return FALSE;
19350 }
19351
19352 if (left < 1 && ! do_wide)
19353 return TRUE;
19354
19355 switch (name_type)
19356 {
19357 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
19358 {
b06b2c92 19359 unsigned int bytes;
ddef72cd
NC
19360 unsigned long long val = 0;
19361 unsigned int shift = 0;
19362 char * decoded = NULL;
19363
b06b2c92
NC
19364 bytes = pnote->namesz - (name - pnote->namedata);
19365 if (bytes > 0)
19366 /* The -1 is because the name field is always 0 terminated, and we
19367 want to be able to ensure that the shift in the while loop below
19368 will not overflow. */
19369 -- bytes;
19370
ddef72cd
NC
19371 if (bytes > sizeof (val))
19372 {
3e6b6445
NC
19373 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
19374 bytes);
19375 bytes = sizeof (val);
ddef72cd 19376 }
3e6b6445
NC
19377 /* We do not bother to warn if bytes == 0 as this can
19378 happen with some early versions of the gcc plugin. */
9ef920e9
NC
19379
19380 while (bytes --)
19381 {
79a964dc
NC
19382 unsigned long byte = (* name ++) & 0xff;
19383
19384 val |= byte << shift;
9ef920e9
NC
19385 shift += 8;
19386 }
19387
75d7d298 19388 switch (name_attribute)
9ef920e9 19389 {
75d7d298 19390 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
19391 switch (val)
19392 {
75d7d298
NC
19393 case 0: decoded = "static"; break;
19394 case 1: decoded = "pic"; break;
19395 case 2: decoded = "PIC"; break;
19396 case 3: decoded = "pie"; break;
19397 case 4: decoded = "PIE"; break;
19398 default: break;
9ef920e9 19399 }
75d7d298
NC
19400 break;
19401 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
19402 switch (val)
9ef920e9 19403 {
75d7d298
NC
19404 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
19405 case 0: decoded = "off"; break;
19406 case 1: decoded = "on"; break;
19407 case 2: decoded = "all"; break;
19408 case 3: decoded = "strong"; break;
19409 case 4: decoded = "explicit"; break;
19410 default: break;
9ef920e9 19411 }
75d7d298
NC
19412 break;
19413 default:
19414 break;
9ef920e9
NC
19415 }
19416
75d7d298 19417 if (decoded != NULL)
3e6b6445
NC
19418 {
19419 print_symbol (-left, decoded);
19420 left = 0;
19421 }
19422 else if (val == 0)
19423 {
19424 printf ("0x0");
19425 left -= 3;
19426 }
9ef920e9 19427 else
75d7d298
NC
19428 {
19429 if (do_wide)
ddef72cd 19430 left -= printf ("0x%llx", val);
75d7d298 19431 else
ddef72cd 19432 left -= printf ("0x%-.*llx", left, val);
75d7d298 19433 }
9ef920e9
NC
19434 }
19435 break;
19436 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
19437 left -= print_symbol (- left, name);
19438 break;
19439 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
19440 left -= print_symbol (- left, "true");
19441 break;
19442 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
19443 left -= print_symbol (- left, "false");
19444 break;
19445 }
19446
19447 if (do_wide && left > 0)
19448 printf ("%-*s", left, " ");
9abca702 19449
9ef920e9
NC
19450 return TRUE;
19451}
19452
6d118b09
NC
19453/* Note that by the ELF standard, the name field is already null byte
19454 terminated, and namesz includes the terminating null byte.
19455 I.E. the value of namesz for the name "FSF" is 4.
19456
e3c8793a 19457 If the value of namesz is zero, there is no name present. */
9ef920e9 19458
32ec8896 19459static bfd_boolean
9ef920e9 19460process_note (Elf_Internal_Note * pnote,
dda8d76d 19461 Filedata * filedata)
779fe533 19462{
2cf0635d
NC
19463 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
19464 const char * nt;
9437c45b
JT
19465
19466 if (pnote->namesz == 0)
1ec5cd37
NC
19467 /* If there is no note name, then use the default set of
19468 note type strings. */
dda8d76d 19469 nt = get_note_type (filedata, pnote->type);
1ec5cd37 19470
1118d252
RM
19471 else if (const_strneq (pnote->namedata, "GNU"))
19472 /* GNU-specific object file notes. */
19473 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
19474
19475 else if (const_strneq (pnote->namedata, "FreeBSD"))
19476 /* FreeBSD-specific core file notes. */
dda8d76d 19477 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 19478
0112cd26 19479 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 19480 /* NetBSD-specific core file notes. */
dda8d76d 19481 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 19482
c6056a74
SF
19483 else if (const_strneq (pnote->namedata, "NetBSD"))
19484 /* NetBSD-specific core file notes. */
19485 return process_netbsd_elf_note (pnote);
19486
9abca702
CZ
19487 else if (const_strneq (pnote->namedata, "PaX"))
19488 /* NetBSD-specific core file notes. */
19489 return process_netbsd_elf_note (pnote);
19490
b15fa79e
AM
19491 else if (strneq (pnote->namedata, "SPU/", 4))
19492 {
19493 /* SPU-specific core file notes. */
19494 nt = pnote->namedata + 4;
19495 name = "SPU";
19496 }
19497
00e98fc7
TG
19498 else if (const_strneq (pnote->namedata, "IPF/VMS"))
19499 /* VMS/ia64-specific file notes. */
19500 nt = get_ia64_vms_note_type (pnote->type);
19501
70616151
TT
19502 else if (const_strneq (pnote->namedata, "stapsdt"))
19503 nt = get_stapsdt_note_type (pnote->type);
19504
9437c45b 19505 else
1ec5cd37
NC
19506 /* Don't recognize this note name; just use the default set of
19507 note type strings. */
dda8d76d 19508 nt = get_note_type (filedata, pnote->type);
9437c45b 19509
1449284b 19510 printf (" ");
9ef920e9 19511
483767a3
AM
19512 if (((const_strneq (pnote->namedata, "GA")
19513 && strchr ("*$!+", pnote->namedata[2]) != NULL)
19514 || strchr ("*$!+", pnote->namedata[0]) != NULL)
19515 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
19516 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
19517 print_gnu_build_attribute_name (pnote);
19518 else
19519 print_symbol (-20, name);
19520
19521 if (do_wide)
19522 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
19523 else
19524 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7
TG
19525
19526 if (const_strneq (pnote->namedata, "IPF/VMS"))
19527 return print_ia64_vms_note (pnote);
664f90a3 19528 else if (const_strneq (pnote->namedata, "GNU"))
dda8d76d 19529 return print_gnu_note (filedata, pnote);
c6a9fc58
TT
19530 else if (const_strneq (pnote->namedata, "stapsdt"))
19531 return print_stapsdt_note (pnote);
9ece1fa9
TT
19532 else if (const_strneq (pnote->namedata, "CORE"))
19533 return print_core_note (pnote);
483767a3
AM
19534 else if (((const_strneq (pnote->namedata, "GA")
19535 && strchr ("*$!+", pnote->namedata[2]) != NULL)
19536 || strchr ("*$!+", pnote->namedata[0]) != NULL)
19537 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
19538 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 19539 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 19540
9ef920e9 19541 if (pnote->descsz)
1449284b
NC
19542 {
19543 unsigned long i;
19544
19545 printf (_(" description data: "));
19546 for (i = 0; i < pnote->descsz; i++)
178d8719 19547 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
19548 if (!do_wide)
19549 printf ("\n");
1449284b
NC
19550 }
19551
9ef920e9
NC
19552 if (do_wide)
19553 printf ("\n");
19554
32ec8896 19555 return TRUE;
1449284b 19556}
6d118b09 19557
32ec8896 19558static bfd_boolean
dda8d76d
NC
19559process_notes_at (Filedata * filedata,
19560 Elf_Internal_Shdr * section,
19561 bfd_vma offset,
82ed9683
L
19562 bfd_vma length,
19563 bfd_vma align)
779fe533 19564{
2cf0635d
NC
19565 Elf_External_Note * pnotes;
19566 Elf_External_Note * external;
4dff97b2
NC
19567 char * end;
19568 bfd_boolean res = TRUE;
103f02d3 19569
779fe533 19570 if (length <= 0)
32ec8896 19571 return FALSE;
103f02d3 19572
1449284b
NC
19573 if (section)
19574 {
dda8d76d 19575 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 19576 if (pnotes)
32ec8896 19577 {
dda8d76d 19578 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
19579 {
19580 free (pnotes);
19581 return FALSE;
19582 }
32ec8896 19583 }
1449284b
NC
19584 }
19585 else
82ed9683 19586 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 19587 _("notes"));
4dff97b2 19588
dd24e3da 19589 if (pnotes == NULL)
32ec8896 19590 return FALSE;
779fe533 19591
103f02d3 19592 external = pnotes;
103f02d3 19593
1449284b 19594 if (section)
dda8d76d 19595 printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b
NC
19596 else
19597 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
19598 (unsigned long) offset, (unsigned long) length);
19599
82ed9683
L
19600 /* NB: Some note sections may have alignment value of 0 or 1. gABI
19601 specifies that notes should be aligned to 4 bytes in 32-bit
19602 objects and to 8 bytes in 64-bit objects. As a Linux extension,
19603 we also support 4 byte alignment in 64-bit objects. If section
19604 alignment is less than 4, we treate alignment as 4 bytes. */
19605 if (align < 4)
19606 align = 4;
19607 else if (align != 4 && align != 8)
19608 {
19609 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
19610 (long) align);
a788aedd 19611 free (pnotes);
82ed9683
L
19612 return FALSE;
19613 }
19614
dbe15e4e 19615 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 19616
c8071705
NC
19617 end = (char *) pnotes + length;
19618 while ((char *) external < end)
779fe533 19619 {
b34976b6 19620 Elf_Internal_Note inote;
15b42fb0 19621 size_t min_notesz;
4dff97b2 19622 char * next;
2cf0635d 19623 char * temp = NULL;
c8071705 19624 size_t data_remaining = end - (char *) external;
6d118b09 19625
dda8d76d 19626 if (!is_ia64_vms (filedata))
15b42fb0 19627 {
9dd3a467
NC
19628 /* PR binutils/15191
19629 Make sure that there is enough data to read. */
15b42fb0
AM
19630 min_notesz = offsetof (Elf_External_Note, name);
19631 if (data_remaining < min_notesz)
9dd3a467 19632 {
d3a49aa8
AM
19633 warn (ngettext ("Corrupt note: only %ld byte remains, "
19634 "not enough for a full note\n",
19635 "Corrupt note: only %ld bytes remain, "
19636 "not enough for a full note\n",
19637 data_remaining),
19638 (long) data_remaining);
9dd3a467
NC
19639 break;
19640 }
5396a86e
AM
19641 data_remaining -= min_notesz;
19642
15b42fb0
AM
19643 inote.type = BYTE_GET (external->type);
19644 inote.namesz = BYTE_GET (external->namesz);
19645 inote.namedata = external->name;
19646 inote.descsz = BYTE_GET (external->descsz);
276da9b3 19647 inote.descdata = ((char *) external
4dff97b2 19648 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 19649 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 19650 next = ((char *) external
4dff97b2 19651 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 19652 }
00e98fc7 19653 else
15b42fb0
AM
19654 {
19655 Elf64_External_VMS_Note *vms_external;
00e98fc7 19656
9dd3a467
NC
19657 /* PR binutils/15191
19658 Make sure that there is enough data to read. */
15b42fb0
AM
19659 min_notesz = offsetof (Elf64_External_VMS_Note, name);
19660 if (data_remaining < min_notesz)
9dd3a467 19661 {
d3a49aa8
AM
19662 warn (ngettext ("Corrupt note: only %ld byte remains, "
19663 "not enough for a full note\n",
19664 "Corrupt note: only %ld bytes remain, "
19665 "not enough for a full note\n",
19666 data_remaining),
19667 (long) data_remaining);
9dd3a467
NC
19668 break;
19669 }
5396a86e 19670 data_remaining -= min_notesz;
3e55a963 19671
15b42fb0
AM
19672 vms_external = (Elf64_External_VMS_Note *) external;
19673 inote.type = BYTE_GET (vms_external->type);
19674 inote.namesz = BYTE_GET (vms_external->namesz);
19675 inote.namedata = vms_external->name;
19676 inote.descsz = BYTE_GET (vms_external->descsz);
19677 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
19678 inote.descpos = offset + (inote.descdata - (char *) pnotes);
19679 next = inote.descdata + align_power (inote.descsz, 3);
19680 }
19681
5396a86e
AM
19682 /* PR 17531: file: 3443835e. */
19683 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
19684 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
19685 || (size_t) (inote.descdata - inote.namedata) > data_remaining
19686 || (size_t) (next - inote.descdata) < inote.descsz
19687 || ((size_t) (next - inote.descdata)
19688 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 19689 {
15b42fb0 19690 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 19691 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
19692 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
19693 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
19694 break;
19695 }
19696
15b42fb0 19697 external = (Elf_External_Note *) next;
dd24e3da 19698
6d118b09
NC
19699 /* Verify that name is null terminated. It appears that at least
19700 one version of Linux (RedHat 6.0) generates corefiles that don't
19701 comply with the ELF spec by failing to include the null byte in
19702 namesz. */
18344509 19703 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 19704 {
5396a86e 19705 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 19706 {
5396a86e
AM
19707 temp = (char *) malloc (inote.namesz + 1);
19708 if (temp == NULL)
19709 {
19710 error (_("Out of memory allocating space for inote name\n"));
19711 res = FALSE;
19712 break;
19713 }
76da6bbe 19714
5396a86e
AM
19715 memcpy (temp, inote.namedata, inote.namesz);
19716 inote.namedata = temp;
19717 }
19718 inote.namedata[inote.namesz] = 0;
6d118b09
NC
19719 }
19720
dda8d76d 19721 if (! process_note (& inote, filedata))
6b4bf3bc 19722 res = FALSE;
103f02d3 19723
6d118b09
NC
19724 if (temp != NULL)
19725 {
19726 free (temp);
19727 temp = NULL;
19728 }
779fe533
NC
19729 }
19730
19731 free (pnotes);
103f02d3 19732
779fe533
NC
19733 return res;
19734}
19735
32ec8896 19736static bfd_boolean
dda8d76d 19737process_corefile_note_segments (Filedata * filedata)
779fe533 19738{
2cf0635d 19739 Elf_Internal_Phdr * segment;
b34976b6 19740 unsigned int i;
32ec8896 19741 bfd_boolean res = TRUE;
103f02d3 19742
dda8d76d 19743 if (! get_program_headers (filedata))
6b4bf3bc 19744 return TRUE;
103f02d3 19745
dda8d76d
NC
19746 for (i = 0, segment = filedata->program_headers;
19747 i < filedata->file_header.e_phnum;
b34976b6 19748 i++, segment++)
779fe533
NC
19749 {
19750 if (segment->p_type == PT_NOTE)
dda8d76d 19751 if (! process_notes_at (filedata, NULL,
32ec8896 19752 (bfd_vma) segment->p_offset,
82ed9683
L
19753 (bfd_vma) segment->p_filesz,
19754 (bfd_vma) segment->p_align))
32ec8896 19755 res = FALSE;
779fe533 19756 }
103f02d3 19757
779fe533
NC
19758 return res;
19759}
19760
32ec8896 19761static bfd_boolean
dda8d76d 19762process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
19763{
19764 Elf_External_Note * pnotes;
19765 Elf_External_Note * external;
c8071705 19766 char * end;
32ec8896 19767 bfd_boolean res = TRUE;
685080f2
NC
19768
19769 if (length <= 0)
32ec8896 19770 return FALSE;
685080f2 19771
dda8d76d 19772 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
19773 _("v850 notes"));
19774 if (pnotes == NULL)
32ec8896 19775 return FALSE;
685080f2
NC
19776
19777 external = pnotes;
c8071705 19778 end = (char*) pnotes + length;
685080f2
NC
19779
19780 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
19781 (unsigned long) offset, (unsigned long) length);
19782
c8071705 19783 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
19784 {
19785 Elf_External_Note * next;
19786 Elf_Internal_Note inote;
19787
19788 inote.type = BYTE_GET (external->type);
19789 inote.namesz = BYTE_GET (external->namesz);
19790 inote.namedata = external->name;
19791 inote.descsz = BYTE_GET (external->descsz);
19792 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
19793 inote.descpos = offset + (inote.descdata - (char *) pnotes);
19794
c8071705
NC
19795 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
19796 {
19797 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
19798 inote.descdata = inote.namedata;
19799 inote.namesz = 0;
19800 }
19801
685080f2
NC
19802 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
19803
c8071705 19804 if ( ((char *) next > end)
685080f2
NC
19805 || ((char *) next < (char *) pnotes))
19806 {
19807 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
19808 (unsigned long) ((char *) external - (char *) pnotes));
19809 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
19810 inote.type, inote.namesz, inote.descsz);
19811 break;
19812 }
19813
19814 external = next;
19815
19816 /* Prevent out-of-bounds indexing. */
c8071705 19817 if ( inote.namedata + inote.namesz > end
685080f2
NC
19818 || inote.namedata + inote.namesz < inote.namedata)
19819 {
19820 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
19821 (unsigned long) ((char *) external - (char *) pnotes));
19822 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
19823 inote.type, inote.namesz, inote.descsz);
19824 break;
19825 }
19826
19827 printf (" %s: ", get_v850_elf_note_type (inote.type));
19828
19829 if (! print_v850_note (& inote))
19830 {
32ec8896 19831 res = FALSE;
685080f2
NC
19832 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
19833 inote.namesz, inote.descsz);
19834 }
19835 }
19836
19837 free (pnotes);
19838
19839 return res;
19840}
19841
32ec8896 19842static bfd_boolean
dda8d76d 19843process_note_sections (Filedata * filedata)
1ec5cd37 19844{
2cf0635d 19845 Elf_Internal_Shdr * section;
1ec5cd37 19846 unsigned long i;
32ec8896
NC
19847 unsigned int n = 0;
19848 bfd_boolean res = TRUE;
1ec5cd37 19849
dda8d76d
NC
19850 for (i = 0, section = filedata->section_headers;
19851 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 19852 i++, section++)
685080f2
NC
19853 {
19854 if (section->sh_type == SHT_NOTE)
19855 {
dda8d76d 19856 if (! process_notes_at (filedata, section,
32ec8896 19857 (bfd_vma) section->sh_offset,
82ed9683
L
19858 (bfd_vma) section->sh_size,
19859 (bfd_vma) section->sh_addralign))
32ec8896 19860 res = FALSE;
685080f2
NC
19861 n++;
19862 }
19863
dda8d76d
NC
19864 if (( filedata->file_header.e_machine == EM_V800
19865 || filedata->file_header.e_machine == EM_V850
19866 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
19867 && section->sh_type == SHT_RENESAS_INFO)
19868 {
dda8d76d 19869 if (! process_v850_notes (filedata,
32ec8896
NC
19870 (bfd_vma) section->sh_offset,
19871 (bfd_vma) section->sh_size))
19872 res = FALSE;
685080f2
NC
19873 n++;
19874 }
19875 }
df565f32
NC
19876
19877 if (n == 0)
19878 /* Try processing NOTE segments instead. */
dda8d76d 19879 return process_corefile_note_segments (filedata);
1ec5cd37
NC
19880
19881 return res;
19882}
19883
32ec8896 19884static bfd_boolean
dda8d76d 19885process_notes (Filedata * filedata)
779fe533
NC
19886{
19887 /* If we have not been asked to display the notes then do nothing. */
19888 if (! do_notes)
32ec8896 19889 return TRUE;
103f02d3 19890
dda8d76d
NC
19891 if (filedata->file_header.e_type != ET_CORE)
19892 return process_note_sections (filedata);
103f02d3 19893
779fe533 19894 /* No program headers means no NOTE segment. */
dda8d76d
NC
19895 if (filedata->file_header.e_phnum > 0)
19896 return process_corefile_note_segments (filedata);
779fe533 19897
1ec5cd37 19898 printf (_("No note segments present in the core file.\n"));
32ec8896 19899 return TRUE;
779fe533
NC
19900}
19901
60abdbed
NC
19902static unsigned char *
19903display_public_gnu_attributes (unsigned char * start,
19904 const unsigned char * const end)
19905{
19906 printf (_(" Unknown GNU attribute: %s\n"), start);
19907
19908 start += strnlen ((char *) start, end - start);
19909 display_raw_attribute (start, end);
19910
19911 return (unsigned char *) end;
19912}
19913
19914static unsigned char *
19915display_generic_attribute (unsigned char * start,
19916 unsigned int tag,
19917 const unsigned char * const end)
19918{
19919 if (tag == 0)
19920 return (unsigned char *) end;
19921
19922 return display_tag_value (tag, start, end);
19923}
19924
32ec8896 19925static bfd_boolean
dda8d76d 19926process_arch_specific (Filedata * filedata)
252b5132 19927{
a952a375 19928 if (! do_arch)
32ec8896 19929 return TRUE;
a952a375 19930
dda8d76d 19931 switch (filedata->file_header.e_machine)
252b5132 19932 {
53a346d8
CZ
19933 case EM_ARC:
19934 case EM_ARC_COMPACT:
19935 case EM_ARC_COMPACT2:
dda8d76d 19936 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
19937 display_arc_attribute,
19938 display_generic_attribute);
11c1ff18 19939 case EM_ARM:
dda8d76d 19940 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
19941 display_arm_attribute,
19942 display_generic_attribute);
19943
252b5132 19944 case EM_MIPS:
4fe85591 19945 case EM_MIPS_RS3_LE:
dda8d76d 19946 return process_mips_specific (filedata);
60abdbed
NC
19947
19948 case EM_MSP430:
dda8d76d
NC
19949 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
19950 display_msp430x_attribute,
c0ea7c52 19951 display_msp430_gnu_attribute);
60abdbed 19952
2dc8dd17
JW
19953 case EM_RISCV:
19954 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
19955 display_riscv_attribute,
19956 display_generic_attribute);
19957
35c08157 19958 case EM_NDS32:
dda8d76d 19959 return process_nds32_specific (filedata);
60abdbed 19960
34c8bcba 19961 case EM_PPC:
b82317dd 19962 case EM_PPC64:
dda8d76d 19963 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
19964 display_power_gnu_attribute);
19965
643f7afb
AK
19966 case EM_S390:
19967 case EM_S390_OLD:
dda8d76d 19968 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
19969 display_s390_gnu_attribute);
19970
9e8c70f9
DM
19971 case EM_SPARC:
19972 case EM_SPARC32PLUS:
19973 case EM_SPARCV9:
dda8d76d 19974 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
19975 display_sparc_gnu_attribute);
19976
59e6276b 19977 case EM_TI_C6000:
dda8d76d 19978 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
19979 display_tic6x_attribute,
19980 display_generic_attribute);
19981
252b5132 19982 default:
dda8d76d 19983 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
19984 display_public_gnu_attributes,
19985 display_generic_attribute);
252b5132 19986 }
252b5132
RH
19987}
19988
32ec8896 19989static bfd_boolean
dda8d76d 19990get_file_header (Filedata * filedata)
252b5132 19991{
9ea033b2 19992 /* Read in the identity array. */
dda8d76d 19993 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 19994 return FALSE;
252b5132 19995
9ea033b2 19996 /* Determine how to read the rest of the header. */
dda8d76d 19997 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 19998 {
1a0670f3
AM
19999 default:
20000 case ELFDATANONE:
adab8cdc
AO
20001 case ELFDATA2LSB:
20002 byte_get = byte_get_little_endian;
20003 byte_put = byte_put_little_endian;
20004 break;
20005 case ELFDATA2MSB:
20006 byte_get = byte_get_big_endian;
20007 byte_put = byte_put_big_endian;
20008 break;
9ea033b2
NC
20009 }
20010
20011 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 20012 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
20013
20014 /* Read in the rest of the header. */
20015 if (is_32bit_elf)
20016 {
20017 Elf32_External_Ehdr ehdr32;
252b5132 20018
dda8d76d 20019 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20020 return FALSE;
103f02d3 20021
dda8d76d
NC
20022 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
20023 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
20024 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
20025 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
20026 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
20027 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
20028 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
20029 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
20030 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
20031 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
20032 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
20033 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
20034 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 20035 }
252b5132 20036 else
9ea033b2
NC
20037 {
20038 Elf64_External_Ehdr ehdr64;
a952a375
NC
20039
20040 /* If we have been compiled with sizeof (bfd_vma) == 4, then
20041 we will not be able to cope with the 64bit data found in
20042 64 ELF files. Detect this now and abort before we start
50c2245b 20043 overwriting things. */
a952a375
NC
20044 if (sizeof (bfd_vma) < 8)
20045 {
e3c8793a
NC
20046 error (_("This instance of readelf has been built without support for a\n\
2004764 bit data type and so it cannot read 64 bit ELF files.\n"));
32ec8896 20048 return FALSE;
a952a375 20049 }
103f02d3 20050
dda8d76d 20051 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20052 return FALSE;
103f02d3 20053
dda8d76d
NC
20054 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
20055 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
20056 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
20057 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
20058 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
20059 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
20060 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
20061 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
20062 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
20063 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
20064 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
20065 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
20066 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 20067 }
252b5132 20068
dda8d76d 20069 if (filedata->file_header.e_shoff)
7ece0d85
JJ
20070 {
20071 /* There may be some extensions in the first section header. Don't
20072 bomb if we can't read it. */
20073 if (is_32bit_elf)
dda8d76d 20074 get_32bit_section_headers (filedata, TRUE);
7ece0d85 20075 else
dda8d76d 20076 get_64bit_section_headers (filedata, TRUE);
7ece0d85 20077 }
560f3c1c 20078
32ec8896 20079 return TRUE;
252b5132
RH
20080}
20081
dda8d76d
NC
20082static void
20083close_file (Filedata * filedata)
20084{
20085 if (filedata)
20086 {
20087 if (filedata->handle)
20088 fclose (filedata->handle);
20089 free (filedata);
20090 }
20091}
20092
20093void
20094close_debug_file (void * data)
20095{
20096 close_file ((Filedata *) data);
20097}
20098
20099static Filedata *
20100open_file (const char * pathname)
20101{
20102 struct stat statbuf;
20103 Filedata * filedata = NULL;
20104
20105 if (stat (pathname, & statbuf) < 0
20106 || ! S_ISREG (statbuf.st_mode))
20107 goto fail;
20108
20109 filedata = calloc (1, sizeof * filedata);
20110 if (filedata == NULL)
20111 goto fail;
20112
20113 filedata->handle = fopen (pathname, "rb");
20114 if (filedata->handle == NULL)
20115 goto fail;
20116
20117 filedata->file_size = (bfd_size_type) statbuf.st_size;
20118 filedata->file_name = pathname;
20119
20120 if (! get_file_header (filedata))
20121 goto fail;
20122
20123 if (filedata->file_header.e_shoff)
20124 {
20125 bfd_boolean res;
20126
20127 /* Read the section headers again, this time for real. */
20128 if (is_32bit_elf)
20129 res = get_32bit_section_headers (filedata, FALSE);
20130 else
20131 res = get_64bit_section_headers (filedata, FALSE);
20132
20133 if (!res)
20134 goto fail;
20135 }
20136
20137 return filedata;
20138
20139 fail:
20140 if (filedata)
20141 {
20142 if (filedata->handle)
20143 fclose (filedata->handle);
20144 free (filedata);
20145 }
20146 return NULL;
20147}
20148
20149void *
20150open_debug_file (const char * pathname)
20151{
20152 return open_file (pathname);
20153}
20154
fb52b2f4
NC
20155/* Process one ELF object file according to the command line options.
20156 This file may actually be stored in an archive. The file is
32ec8896
NC
20157 positioned at the start of the ELF object. Returns TRUE if no
20158 problems were encountered, FALSE otherwise. */
fb52b2f4 20159
32ec8896 20160static bfd_boolean
dda8d76d 20161process_object (Filedata * filedata)
252b5132 20162{
24841daa 20163 bfd_boolean have_separate_files;
252b5132 20164 unsigned int i;
2482f306 20165 bfd_boolean res;
252b5132 20166
dda8d76d 20167 if (! get_file_header (filedata))
252b5132 20168 {
dda8d76d 20169 error (_("%s: Failed to read file header\n"), filedata->file_name);
32ec8896 20170 return FALSE;
252b5132
RH
20171 }
20172
20173 /* Initialise per file variables. */
978c4450
AM
20174 for (i = ARRAY_SIZE (filedata->version_info); i--;)
20175 filedata->version_info[i] = 0;
252b5132 20176
978c4450
AM
20177 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
20178 filedata->dynamic_info[i] = 0;
20179 filedata->dynamic_info_DT_GNU_HASH = 0;
20180 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
20181
20182 /* Process the file. */
20183 if (show_name)
dda8d76d 20184 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 20185
18bd398b
NC
20186 /* Initialise the dump_sects array from the cmdline_dump_sects array.
20187 Note we do this even if cmdline_dump_sects is empty because we
20188 must make sure that the dump_sets array is zeroed out before each
20189 object file is processed. */
6431e409
AM
20190 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
20191 memset (filedata->dump.dump_sects, 0,
20192 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20193
dda8d76d 20194 if (cmdline.num_dump_sects > 0)
18bd398b 20195 {
6431e409 20196 if (filedata->dump.num_dump_sects == 0)
18bd398b 20197 /* A sneaky way of allocating the dump_sects array. */
6431e409 20198 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
18bd398b 20199
6431e409
AM
20200 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
20201 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
20202 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20203 }
d70c5fc7 20204
dda8d76d 20205 if (! process_file_header (filedata))
32ec8896 20206 return FALSE;
252b5132 20207
dda8d76d 20208 if (! process_section_headers (filedata))
2f62977e 20209 {
32ec8896
NC
20210 /* Without loaded section headers we cannot process lots of things. */
20211 do_unwind = do_version = do_dump = do_arch = FALSE;
252b5132 20212
2f62977e 20213 if (! do_using_dynamic)
32ec8896 20214 do_syms = do_dyn_syms = do_reloc = FALSE;
2f62977e 20215 }
252b5132 20216
dda8d76d 20217 if (! process_section_groups (filedata))
32ec8896
NC
20218 /* Without loaded section groups we cannot process unwind. */
20219 do_unwind = FALSE;
d1f5c6e3 20220
2482f306
AM
20221 res = process_program_headers (filedata);
20222 if (res)
20223 res = process_dynamic_section (filedata);
252b5132 20224
dda8d76d 20225 if (! process_relocs (filedata))
32ec8896 20226 res = FALSE;
252b5132 20227
dda8d76d 20228 if (! process_unwind (filedata))
32ec8896 20229 res = FALSE;
4d6ed7c8 20230
dda8d76d 20231 if (! process_symbol_table (filedata))
32ec8896 20232 res = FALSE;
252b5132 20233
dda8d76d 20234 if (! process_syminfo (filedata))
32ec8896 20235 res = FALSE;
252b5132 20236
dda8d76d 20237 if (! process_version_sections (filedata))
32ec8896 20238 res = FALSE;
252b5132 20239
82ed9683 20240 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 20241 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 20242 else
24841daa 20243 have_separate_files = FALSE;
dda8d76d
NC
20244
20245 if (! process_section_contents (filedata))
32ec8896 20246 res = FALSE;
f5842774 20247
24841daa 20248 if (have_separate_files)
dda8d76d 20249 {
24841daa
NC
20250 separate_info * d;
20251
20252 for (d = first_separate_info; d != NULL; d = d->next)
20253 {
20254 if (! process_section_headers (d->handle))
20255 res = FALSE;
20256 else if (! process_section_contents (d->handle))
20257 res = FALSE;
20258 }
20259
20260 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
20261 }
20262
20263 if (! process_notes (filedata))
32ec8896 20264 res = FALSE;
103f02d3 20265
dda8d76d 20266 if (! process_gnu_liblist (filedata))
32ec8896 20267 res = FALSE;
047b2264 20268
dda8d76d 20269 if (! process_arch_specific (filedata))
32ec8896 20270 res = FALSE;
252b5132 20271
dda8d76d
NC
20272 free (filedata->program_headers);
20273 filedata->program_headers = NULL;
d93f0186 20274
dda8d76d
NC
20275 free (filedata->section_headers);
20276 filedata->section_headers = NULL;
252b5132 20277
dda8d76d
NC
20278 free (filedata->string_table);
20279 filedata->string_table = NULL;
20280 filedata->string_table_length = 0;
252b5132 20281
6431e409 20282 if (filedata->dump.dump_sects != NULL)
a788aedd 20283 {
6431e409
AM
20284 free (filedata->dump.dump_sects);
20285 filedata->dump.dump_sects = NULL;
20286 filedata->dump.num_dump_sects = 0;
a788aedd
AM
20287 }
20288
978c4450 20289 if (filedata->dynamic_strings)
252b5132 20290 {
978c4450
AM
20291 free (filedata->dynamic_strings);
20292 filedata->dynamic_strings = NULL;
20293 filedata->dynamic_strings_length = 0;
252b5132
RH
20294 }
20295
978c4450 20296 if (filedata->dynamic_symbols)
252b5132 20297 {
978c4450
AM
20298 free (filedata->dynamic_symbols);
20299 filedata->dynamic_symbols = NULL;
20300 filedata->num_dynamic_syms = 0;
252b5132
RH
20301 }
20302
978c4450 20303 if (filedata->dynamic_syminfo)
252b5132 20304 {
978c4450
AM
20305 free (filedata->dynamic_syminfo);
20306 filedata->dynamic_syminfo = NULL;
252b5132 20307 }
ff78d6d6 20308
978c4450 20309 if (filedata->dynamic_section)
293c573e 20310 {
978c4450
AM
20311 free (filedata->dynamic_section);
20312 filedata->dynamic_section = NULL;
293c573e
MR
20313 }
20314
978c4450 20315 while (filedata->symtab_shndx_list != NULL)
8fb879cd 20316 {
978c4450
AM
20317 elf_section_list *next = filedata->symtab_shndx_list->next;
20318 free (filedata->symtab_shndx_list);
20319 filedata->symtab_shndx_list = next;
8fb879cd
AM
20320 }
20321
978c4450 20322 if (filedata->section_headers_groups)
e4b17d5c 20323 {
978c4450
AM
20324 free (filedata->section_headers_groups);
20325 filedata->section_headers_groups = NULL;
e4b17d5c
L
20326 }
20327
978c4450 20328 if (filedata->section_groups)
e4b17d5c 20329 {
2cf0635d
NC
20330 struct group_list * g;
20331 struct group_list * next;
e4b17d5c 20332
978c4450 20333 for (i = 0; i < filedata->group_count; i++)
e4b17d5c 20334 {
978c4450 20335 for (g = filedata->section_groups [i].root; g != NULL; g = next)
e4b17d5c
L
20336 {
20337 next = g->next;
20338 free (g);
20339 }
20340 }
20341
978c4450
AM
20342 free (filedata->section_groups);
20343 filedata->section_groups = NULL;
e4b17d5c
L
20344 }
20345
19e6b90e 20346 free_debug_memory ();
18bd398b 20347
32ec8896 20348 return res;
252b5132
RH
20349}
20350
2cf0635d 20351/* Process an ELF archive.
32ec8896
NC
20352 On entry the file is positioned just after the ARMAG string.
20353 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 20354
32ec8896 20355static bfd_boolean
dda8d76d 20356process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
2cf0635d
NC
20357{
20358 struct archive_info arch;
20359 struct archive_info nested_arch;
20360 size_t got;
32ec8896 20361 bfd_boolean ret = TRUE;
2cf0635d 20362
32ec8896 20363 show_name = TRUE;
2cf0635d
NC
20364
20365 /* The ARCH structure is used to hold information about this archive. */
20366 arch.file_name = NULL;
20367 arch.file = NULL;
20368 arch.index_array = NULL;
20369 arch.sym_table = NULL;
20370 arch.longnames = NULL;
20371
20372 /* The NESTED_ARCH structure is used as a single-item cache of information
20373 about a nested archive (when members of a thin archive reside within
20374 another regular archive file). */
20375 nested_arch.file_name = NULL;
20376 nested_arch.file = NULL;
20377 nested_arch.index_array = NULL;
20378 nested_arch.sym_table = NULL;
20379 nested_arch.longnames = NULL;
20380
dda8d76d 20381 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
20382 filedata->file_size, is_thin_archive,
20383 do_archive_index) != 0)
2cf0635d 20384 {
32ec8896 20385 ret = FALSE;
2cf0635d 20386 goto out;
4145f1d5 20387 }
fb52b2f4 20388
4145f1d5
NC
20389 if (do_archive_index)
20390 {
2cf0635d 20391 if (arch.sym_table == NULL)
1cb7d8b1
AM
20392 error (_("%s: unable to dump the index as none was found\n"),
20393 filedata->file_name);
4145f1d5
NC
20394 else
20395 {
591f7597 20396 unsigned long i, l;
4145f1d5
NC
20397 unsigned long current_pos;
20398
1cb7d8b1
AM
20399 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
20400 "in the symbol table)\n"),
20401 filedata->file_name, (unsigned long) arch.index_num,
20402 arch.sym_size);
dda8d76d
NC
20403
20404 current_pos = ftell (filedata->handle);
4145f1d5 20405
2cf0635d 20406 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 20407 {
1cb7d8b1
AM
20408 if (i == 0
20409 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
20410 {
20411 char * member_name
20412 = get_archive_member_name_at (&arch, arch.index_array[i],
20413 &nested_arch);
2cf0635d 20414
1cb7d8b1
AM
20415 if (member_name != NULL)
20416 {
20417 char * qualified_name
20418 = make_qualified_name (&arch, &nested_arch,
20419 member_name);
2cf0635d 20420
1cb7d8b1
AM
20421 if (qualified_name != NULL)
20422 {
20423 printf (_("Contents of binary %s at offset "),
20424 qualified_name);
c2a7d3f5
NC
20425 (void) print_vma (arch.index_array[i], PREFIX_HEX);
20426 putchar ('\n');
1cb7d8b1
AM
20427 free (qualified_name);
20428 }
fd486f32 20429 free (member_name);
4145f1d5
NC
20430 }
20431 }
2cf0635d
NC
20432
20433 if (l >= arch.sym_size)
4145f1d5 20434 {
1cb7d8b1
AM
20435 error (_("%s: end of the symbol table reached "
20436 "before the end of the index\n"),
dda8d76d 20437 filedata->file_name);
32ec8896 20438 ret = FALSE;
cb8f3167 20439 break;
4145f1d5 20440 }
591f7597 20441 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
20442 printf ("\t%.*s\n",
20443 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 20444 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
20445 }
20446
67ce483b 20447 if (arch.uses_64bit_indices)
c2a7d3f5
NC
20448 l = (l + 7) & ~ 7;
20449 else
20450 l += l & 1;
20451
2cf0635d 20452 if (l < arch.sym_size)
32ec8896 20453 {
d3a49aa8
AM
20454 error (ngettext ("%s: %ld byte remains in the symbol table, "
20455 "but without corresponding entries in "
20456 "the index table\n",
20457 "%s: %ld bytes remain in the symbol table, "
20458 "but without corresponding entries in "
20459 "the index table\n",
20460 arch.sym_size - l),
dda8d76d 20461 filedata->file_name, arch.sym_size - l);
32ec8896
NC
20462 ret = FALSE;
20463 }
4145f1d5 20464
dda8d76d 20465 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 20466 {
1cb7d8b1
AM
20467 error (_("%s: failed to seek back to start of object files "
20468 "in the archive\n"),
dda8d76d 20469 filedata->file_name);
32ec8896 20470 ret = FALSE;
2cf0635d 20471 goto out;
4145f1d5 20472 }
fb52b2f4 20473 }
4145f1d5
NC
20474
20475 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
20476 && !do_segments && !do_header && !do_dump && !do_version
20477 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 20478 && !do_section_groups && !do_dyn_syms)
2cf0635d 20479 {
32ec8896 20480 ret = TRUE; /* Archive index only. */
2cf0635d
NC
20481 goto out;
20482 }
fb52b2f4
NC
20483 }
20484
fb52b2f4
NC
20485 while (1)
20486 {
2cf0635d
NC
20487 char * name;
20488 size_t namelen;
20489 char * qualified_name;
20490
20491 /* Read the next archive header. */
dda8d76d 20492 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
20493 {
20494 error (_("%s: failed to seek to next archive header\n"),
20495 arch.file_name);
20496 ret = FALSE;
20497 break;
20498 }
dda8d76d 20499 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 20500 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
20501 {
20502 if (got == 0)
2cf0635d 20503 break;
28e817cc
NC
20504 /* PR 24049 - we cannot use filedata->file_name as this will
20505 have already been freed. */
20506 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 20507
1cb7d8b1
AM
20508 ret = FALSE;
20509 break;
20510 }
2cf0635d 20511 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
20512 {
20513 error (_("%s: did not find a valid archive header\n"),
20514 arch.file_name);
20515 ret = FALSE;
20516 break;
20517 }
2cf0635d
NC
20518
20519 arch.next_arhdr_offset += sizeof arch.arhdr;
20520
978c4450
AM
20521 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
20522 if (filedata->archive_file_size & 01)
20523 ++filedata->archive_file_size;
2cf0635d
NC
20524
20525 name = get_archive_member_name (&arch, &nested_arch);
20526 if (name == NULL)
fb52b2f4 20527 {
28e817cc 20528 error (_("%s: bad archive file name\n"), arch.file_name);
32ec8896 20529 ret = FALSE;
d989285c 20530 break;
fb52b2f4 20531 }
2cf0635d 20532 namelen = strlen (name);
fb52b2f4 20533
2cf0635d
NC
20534 qualified_name = make_qualified_name (&arch, &nested_arch, name);
20535 if (qualified_name == NULL)
fb52b2f4 20536 {
28e817cc 20537 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 20538 free (name);
32ec8896 20539 ret = FALSE;
d989285c 20540 break;
fb52b2f4
NC
20541 }
20542
2cf0635d 20543 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
20544 {
20545 /* This is a proxy for an external member of a thin archive. */
20546 Filedata * member_filedata;
20547 char * member_file_name = adjust_relative_path
dda8d76d 20548 (filedata->file_name, name, namelen);
32ec8896 20549
fd486f32 20550 free (name);
1cb7d8b1
AM
20551 if (member_file_name == NULL)
20552 {
fd486f32 20553 free (qualified_name);
1cb7d8b1
AM
20554 ret = FALSE;
20555 break;
20556 }
2cf0635d 20557
1cb7d8b1
AM
20558 member_filedata = open_file (member_file_name);
20559 if (member_filedata == NULL)
20560 {
20561 error (_("Input file '%s' is not readable.\n"), member_file_name);
20562 free (member_file_name);
fd486f32 20563 free (qualified_name);
1cb7d8b1
AM
20564 ret = FALSE;
20565 break;
20566 }
2cf0635d 20567
978c4450 20568 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 20569 member_filedata->file_name = qualified_name;
2cf0635d 20570
1cb7d8b1 20571 if (! process_object (member_filedata))
32ec8896 20572 ret = FALSE;
2cf0635d 20573
1cb7d8b1
AM
20574 close_file (member_filedata);
20575 free (member_file_name);
1cb7d8b1 20576 }
2cf0635d 20577 else if (is_thin_archive)
1cb7d8b1
AM
20578 {
20579 Filedata thin_filedata;
eb02c04d 20580
1cb7d8b1 20581 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 20582
a043396b
NC
20583 /* PR 15140: Allow for corrupt thin archives. */
20584 if (nested_arch.file == NULL)
20585 {
20586 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 20587 qualified_name, name);
fd486f32
AM
20588 free (qualified_name);
20589 free (name);
32ec8896 20590 ret = FALSE;
a043396b
NC
20591 break;
20592 }
fd486f32 20593 free (name);
a043396b 20594
1cb7d8b1 20595 /* This is a proxy for a member of a nested archive. */
978c4450
AM
20596 filedata->archive_file_offset
20597 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 20598
1cb7d8b1
AM
20599 /* The nested archive file will have been opened and setup by
20600 get_archive_member_name. */
978c4450
AM
20601 if (fseek (nested_arch.file, filedata->archive_file_offset,
20602 SEEK_SET) != 0)
1cb7d8b1
AM
20603 {
20604 error (_("%s: failed to seek to archive member.\n"),
20605 nested_arch.file_name);
fd486f32 20606 free (qualified_name);
1cb7d8b1
AM
20607 ret = FALSE;
20608 break;
20609 }
2cf0635d 20610
dda8d76d
NC
20611 thin_filedata.handle = nested_arch.file;
20612 thin_filedata.file_name = qualified_name;
9abca702 20613
1cb7d8b1 20614 if (! process_object (& thin_filedata))
32ec8896 20615 ret = FALSE;
1cb7d8b1 20616 }
2cf0635d 20617 else
1cb7d8b1 20618 {
fd486f32 20619 free (name);
978c4450 20620 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 20621 filedata->file_name = qualified_name;
1cb7d8b1 20622 if (! process_object (filedata))
32ec8896 20623 ret = FALSE;
978c4450 20624 arch.next_arhdr_offset += filedata->archive_file_size;
4c836627 20625 /* Stop looping with "negative" archive_file_size. */
978c4450 20626 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 20627 arch.next_arhdr_offset = -1ul;
1cb7d8b1 20628 }
fb52b2f4 20629
2cf0635d 20630 free (qualified_name);
fb52b2f4
NC
20631 }
20632
4145f1d5 20633 out:
2cf0635d
NC
20634 if (nested_arch.file != NULL)
20635 fclose (nested_arch.file);
20636 release_archive (&nested_arch);
20637 release_archive (&arch);
fb52b2f4 20638
d989285c 20639 return ret;
fb52b2f4
NC
20640}
20641
32ec8896 20642static bfd_boolean
2cf0635d 20643process_file (char * file_name)
fb52b2f4 20644{
dda8d76d 20645 Filedata * filedata = NULL;
fb52b2f4
NC
20646 struct stat statbuf;
20647 char armag[SARMAG];
32ec8896 20648 bfd_boolean ret = TRUE;
fb52b2f4
NC
20649
20650 if (stat (file_name, &statbuf) < 0)
20651 {
f24ddbdd
NC
20652 if (errno == ENOENT)
20653 error (_("'%s': No such file\n"), file_name);
20654 else
20655 error (_("Could not locate '%s'. System error message: %s\n"),
20656 file_name, strerror (errno));
32ec8896 20657 return FALSE;
f24ddbdd
NC
20658 }
20659
20660 if (! S_ISREG (statbuf.st_mode))
20661 {
20662 error (_("'%s' is not an ordinary file\n"), file_name);
32ec8896 20663 return FALSE;
fb52b2f4
NC
20664 }
20665
dda8d76d
NC
20666 filedata = calloc (1, sizeof * filedata);
20667 if (filedata == NULL)
20668 {
20669 error (_("Out of memory allocating file data structure\n"));
20670 return FALSE;
20671 }
20672
20673 filedata->file_name = file_name;
20674 filedata->handle = fopen (file_name, "rb");
20675 if (filedata->handle == NULL)
fb52b2f4 20676 {
f24ddbdd 20677 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 20678 free (filedata);
32ec8896 20679 return FALSE;
fb52b2f4
NC
20680 }
20681
dda8d76d 20682 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 20683 {
4145f1d5 20684 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
20685 fclose (filedata->handle);
20686 free (filedata);
32ec8896 20687 return FALSE;
fb52b2f4
NC
20688 }
20689
dda8d76d 20690 filedata->file_size = (bfd_size_type) statbuf.st_size;
f54498b4 20691
fb52b2f4 20692 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 20693 {
dda8d76d 20694 if (! process_archive (filedata, FALSE))
32ec8896
NC
20695 ret = FALSE;
20696 }
2cf0635d 20697 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 20698 {
dda8d76d 20699 if ( ! process_archive (filedata, TRUE))
32ec8896
NC
20700 ret = FALSE;
20701 }
fb52b2f4
NC
20702 else
20703 {
1b513401 20704 if (do_archive_index && !check_all)
4145f1d5
NC
20705 error (_("File %s is not an archive so its index cannot be displayed.\n"),
20706 file_name);
20707
dda8d76d 20708 rewind (filedata->handle);
978c4450 20709 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 20710
dda8d76d 20711 if (! process_object (filedata))
32ec8896 20712 ret = FALSE;
fb52b2f4
NC
20713 }
20714
dda8d76d 20715 fclose (filedata->handle);
8fb879cd
AM
20716 free (filedata->section_headers);
20717 free (filedata->program_headers);
20718 free (filedata->string_table);
6431e409 20719 free (filedata->dump.dump_sects);
dda8d76d 20720 free (filedata);
32ec8896 20721
fd486f32 20722 free (ba_cache.strtab);
1bd6175a 20723 ba_cache.strtab = NULL;
fd486f32 20724 free (ba_cache.symtab);
1bd6175a 20725 ba_cache.symtab = NULL;
fd486f32
AM
20726 ba_cache.filedata = NULL;
20727
fb52b2f4
NC
20728 return ret;
20729}
20730
252b5132
RH
20731#ifdef SUPPORT_DISASSEMBLY
20732/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 20733 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 20734 symbols. */
252b5132
RH
20735
20736void
2cf0635d 20737print_address (unsigned int addr, FILE * outfile)
252b5132
RH
20738{
20739 fprintf (outfile,"0x%8.8x", addr);
20740}
20741
e3c8793a 20742/* Needed by the i386 disassembler. */
dda8d76d 20743
252b5132
RH
20744void
20745db_task_printsym (unsigned int addr)
20746{
20747 print_address (addr, stderr);
20748}
20749#endif
20750
20751int
2cf0635d 20752main (int argc, char ** argv)
252b5132 20753{
ff78d6d6
L
20754 int err;
20755
252b5132
RH
20756#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
20757 setlocale (LC_MESSAGES, "");
3882b010
L
20758#endif
20759#if defined (HAVE_SETLOCALE)
20760 setlocale (LC_CTYPE, "");
252b5132
RH
20761#endif
20762 bindtextdomain (PACKAGE, LOCALEDIR);
20763 textdomain (PACKAGE);
20764
869b9d07
MM
20765 expandargv (&argc, &argv);
20766
dda8d76d 20767 parse_args (& cmdline, argc, argv);
59f14fc0 20768
18bd398b 20769 if (optind < (argc - 1))
1b513401
NC
20770 /* When displaying information for more than one file,
20771 prefix the information with the file name. */
32ec8896 20772 show_name = TRUE;
5656ba2c
L
20773 else if (optind >= argc)
20774 {
1b513401
NC
20775 /* Ensure that the warning is always displayed. */
20776 do_checks = TRUE;
20777
5656ba2c
L
20778 warn (_("Nothing to do.\n"));
20779 usage (stderr);
20780 }
18bd398b 20781
32ec8896 20782 err = FALSE;
252b5132 20783 while (optind < argc)
32ec8896
NC
20784 if (! process_file (argv[optind++]))
20785 err = TRUE;
252b5132 20786
dda8d76d
NC
20787 if (cmdline.dump_sects != NULL)
20788 free (cmdline.dump_sects);
252b5132 20789
7d9813f1
NA
20790 free (dump_ctf_symtab_name);
20791 free (dump_ctf_strtab_name);
20792 free (dump_ctf_parent_name);
20793
32ec8896 20794 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 20795}