]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Replace "if (x) free (x)" with "free (x)", bfd
[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;
8ac10c5b 270 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450
AM
271 char * dynamic_strings;
272 unsigned long dynamic_strings_length;
8ac10c5b 273 Elf_Internal_Shdr * dynamic_symtab_section;
978c4450
AM
274 unsigned long num_dynamic_syms;
275 Elf_Internal_Sym * dynamic_symbols;
276 bfd_vma version_info[16];
277 unsigned int dynamic_syminfo_nent;
278 Elf_Internal_Syminfo * dynamic_syminfo;
279 unsigned long dynamic_syminfo_offset;
280 bfd_size_type nbuckets;
281 bfd_size_type nchains;
282 bfd_vma * buckets;
283 bfd_vma * chains;
284 bfd_size_type ngnubuckets;
285 bfd_size_type ngnuchains;
286 bfd_vma * gnubuckets;
287 bfd_vma * gnuchains;
288 bfd_vma * mipsxlat;
289 bfd_vma gnusymidx;
290 char program_interpreter[PATH_MAX];
291 bfd_vma dynamic_info[DT_ENCODING];
292 bfd_vma dynamic_info_DT_GNU_HASH;
293 bfd_vma dynamic_info_DT_MIPS_XHASH;
294 elf_section_list * symtab_shndx_list;
295 size_t group_count;
296 struct group * section_groups;
297 struct group ** section_headers_groups;
298 /* A dynamic array of flags indicating for which sections a dump of
299 some kind has been requested. It is reset on a per-object file
300 basis and then initialised from the cmdline_dump_sects array,
301 the results of interpreting the -w switch, and the
302 dump_sects_byname list. */
303 struct dump_data dump;
304} Filedata;
aef1f6d0 305
c256ffe7 306/* How to print a vma value. */
843dd992
NC
307typedef enum print_mode
308{
309 HEX,
310 DEC,
311 DEC_5,
312 UNSIGNED,
313 PREFIX_HEX,
314 FULL_HEX,
315 LONG_HEX
316}
317print_mode;
318
bb4d2ac2
L
319/* Versioned symbol info. */
320enum versioned_symbol_info
321{
322 symbol_undefined,
323 symbol_hidden,
324 symbol_public
325};
326
32ec8896 327static const char * get_symbol_version_string
dda8d76d 328 (Filedata *, bfd_boolean, const char *, unsigned long, unsigned,
32ec8896 329 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 330
9c19a809
NC
331#define UNKNOWN -1
332
2b692964
NC
333#define SECTION_NAME(X) \
334 ((X) == NULL ? _("<none>") \
dda8d76d
NC
335 : filedata->string_table == NULL ? _("<no-strings>") \
336 : ((X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
337 : filedata->string_table + (X)->sh_name))
252b5132 338
ee42cf8c 339#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 340
ba5cdace
NC
341#define GET_ELF_SYMBOLS(file, section, sym_count) \
342 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
343 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 344
10ca4b04
L
345#define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
346 (strtab != NULL && offset < strtab_size)
978c4450
AM
347#define VALID_DYNAMIC_NAME(filedata, offset) \
348 VALID_SYMBOL_NAME (filedata->dynamic_strings, \
349 filedata->dynamic_strings_length, offset)
d79b3d50
NC
350/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
351 already been called and verified that the string exists. */
978c4450
AM
352#define GET_DYNAMIC_NAME(filedata, offset) \
353 (filedata->dynamic_strings + offset)
18bd398b 354
61865e30
NC
355#define REMOVE_ARCH_BITS(ADDR) \
356 do \
357 { \
dda8d76d 358 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
359 (ADDR) &= ~1; \
360 } \
361 while (0)
f16a9783
MS
362
363/* Get the correct GNU hash section name. */
978c4450
AM
364#define GNU_HASH_SECTION_NAME(filedata) \
365 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 366\f
66cfc0fd
AM
367/* Print a BFD_VMA to an internal buffer, for use in error messages.
368 BFD_FMA_FMT can't be used in translated strings. */
369
370static const char *
371bfd_vmatoa (char *fmtch, bfd_vma value)
372{
373 /* bfd_vmatoa is used more then once in a printf call for output.
374 Cycle through an array of buffers. */
375 static int buf_pos = 0;
376 static struct bfd_vmatoa_buf
377 {
378 char place[64];
379 } buf[4];
380 char *ret;
381 char fmt[32];
382
383 ret = buf[buf_pos++].place;
384 buf_pos %= ARRAY_SIZE (buf);
385
386 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
387 snprintf (ret, sizeof (buf[0].place), fmt, value);
388 return ret;
389}
390
dda8d76d
NC
391/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
392 OFFSET + the offset of the current archive member, if we are examining an
393 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
394 allocate a buffer using malloc and fill that. In either case return the
395 pointer to the start of the retrieved data or NULL if something went wrong.
396 If something does go wrong and REASON is not NULL then emit an error
397 message using REASON as part of the context. */
59245841 398
c256ffe7 399static void *
dda8d76d
NC
400get_data (void * var,
401 Filedata * filedata,
402 unsigned long offset,
403 bfd_size_type size,
404 bfd_size_type nmemb,
405 const char * reason)
a6e9f9df 406{
2cf0635d 407 void * mvar;
57028622 408 bfd_size_type amt = size * nmemb;
a6e9f9df 409
c256ffe7 410 if (size == 0 || nmemb == 0)
a6e9f9df
AM
411 return NULL;
412
57028622
NC
413 /* If the size_t type is smaller than the bfd_size_type, eg because
414 you are building a 32-bit tool on a 64-bit host, then make sure
415 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
416 if ((size_t) size != size
417 || (size_t) nmemb != nmemb
418 || (size_t) amt != amt)
57028622
NC
419 {
420 if (reason)
66cfc0fd
AM
421 error (_("Size truncation prevents reading %s"
422 " elements of size %s for %s\n"),
423 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
424 return NULL;
425 }
426
427 /* Check for size overflow. */
7c1c1904 428 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
429 {
430 if (reason)
66cfc0fd
AM
431 error (_("Size overflow prevents reading %s"
432 " elements of size %s for %s\n"),
433 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
434 return NULL;
435 }
436
c22b42ce 437 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 438 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
439 if (filedata->archive_file_offset > filedata->file_size
440 || offset > filedata->file_size - filedata->archive_file_offset
441 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 442 {
049b0c3a 443 if (reason)
66cfc0fd
AM
444 error (_("Reading %s bytes extends past end of file for %s\n"),
445 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
446 return NULL;
447 }
448
978c4450
AM
449 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
450 SEEK_SET))
071436c6
NC
451 {
452 if (reason)
c9c1d674 453 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 454 filedata->archive_file_offset + offset, reason);
071436c6
NC
455 return NULL;
456 }
457
a6e9f9df
AM
458 mvar = var;
459 if (mvar == NULL)
460 {
7c1c1904
AM
461 /* + 1 so that we can '\0' terminate invalid string table sections. */
462 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
463
464 if (mvar == NULL)
465 {
049b0c3a 466 if (reason)
66cfc0fd
AM
467 error (_("Out of memory allocating %s bytes for %s\n"),
468 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
469 return NULL;
470 }
c256ffe7 471
c9c1d674 472 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
473 }
474
dda8d76d 475 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 476 {
049b0c3a 477 if (reason)
66cfc0fd
AM
478 error (_("Unable to read in %s bytes of %s\n"),
479 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
480 if (mvar != var)
481 free (mvar);
482 return NULL;
483 }
484
485 return mvar;
486}
487
32ec8896
NC
488/* Print a VMA value in the MODE specified.
489 Returns the number of characters displayed. */
cb8f3167 490
32ec8896 491static unsigned int
14a91970 492print_vma (bfd_vma vma, print_mode mode)
66543521 493{
32ec8896 494 unsigned int nc = 0;
66543521 495
14a91970 496 switch (mode)
66543521 497 {
14a91970
AM
498 case FULL_HEX:
499 nc = printf ("0x");
1a0670f3 500 /* Fall through. */
14a91970 501 case LONG_HEX:
f7a99963 502#ifdef BFD64
14a91970 503 if (is_32bit_elf)
437c2fb7 504 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 505#endif
14a91970
AM
506 printf_vma (vma);
507 return nc + 16;
b19aac67 508
14a91970
AM
509 case DEC_5:
510 if (vma <= 99999)
511 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 512 /* Fall through. */
14a91970
AM
513 case PREFIX_HEX:
514 nc = printf ("0x");
1a0670f3 515 /* Fall through. */
14a91970
AM
516 case HEX:
517 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 518
14a91970
AM
519 case DEC:
520 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 521
14a91970
AM
522 case UNSIGNED:
523 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896
NC
524
525 default:
526 /* FIXME: Report unrecognised mode ? */
527 return 0;
f7a99963 528 }
f7a99963
NC
529}
530
7bfd842d 531/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 532 multibye characters (assuming the host environment supports them).
31104126 533
7bfd842d
NC
534 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
535
536 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
537 padding as necessary.
171191ba
NC
538
539 Returns the number of emitted characters. */
540
541static unsigned int
32ec8896 542print_symbol (signed int width, const char *symbol)
31104126 543{
171191ba 544 bfd_boolean extra_padding = FALSE;
32ec8896 545 signed int num_printed = 0;
3bfcb652 546#ifdef HAVE_MBSTATE_T
7bfd842d 547 mbstate_t state;
3bfcb652 548#endif
32ec8896 549 unsigned int width_remaining;
961c521f 550
7bfd842d 551 if (width < 0)
961c521f 552 {
88305e1b 553 /* Keep the width positive. This helps the code below. */
961c521f 554 width = - width;
171191ba 555 extra_padding = TRUE;
0b4362b0 556 }
56d8f8a9
NC
557 else if (width == 0)
558 return 0;
961c521f 559
7bfd842d
NC
560 if (do_wide)
561 /* Set the remaining width to a very large value.
562 This simplifies the code below. */
563 width_remaining = INT_MAX;
564 else
565 width_remaining = width;
cb8f3167 566
3bfcb652 567#ifdef HAVE_MBSTATE_T
7bfd842d
NC
568 /* Initialise the multibyte conversion state. */
569 memset (& state, 0, sizeof (state));
3bfcb652 570#endif
961c521f 571
7bfd842d
NC
572 while (width_remaining)
573 {
574 size_t n;
7bfd842d 575 const char c = *symbol++;
961c521f 576
7bfd842d 577 if (c == 0)
961c521f
NC
578 break;
579
7bfd842d
NC
580 /* Do not print control characters directly as they can affect terminal
581 settings. Such characters usually appear in the names generated
582 by the assembler for local labels. */
583 if (ISCNTRL (c))
961c521f 584 {
7bfd842d 585 if (width_remaining < 2)
961c521f
NC
586 break;
587
7bfd842d
NC
588 printf ("^%c", c + 0x40);
589 width_remaining -= 2;
171191ba 590 num_printed += 2;
961c521f 591 }
7bfd842d
NC
592 else if (ISPRINT (c))
593 {
594 putchar (c);
595 width_remaining --;
596 num_printed ++;
597 }
961c521f
NC
598 else
599 {
3bfcb652
NC
600#ifdef HAVE_MBSTATE_T
601 wchar_t w;
602#endif
7bfd842d
NC
603 /* Let printf do the hard work of displaying multibyte characters. */
604 printf ("%.1s", symbol - 1);
605 width_remaining --;
606 num_printed ++;
607
3bfcb652 608#ifdef HAVE_MBSTATE_T
7bfd842d
NC
609 /* Try to find out how many bytes made up the character that was
610 just printed. Advance the symbol pointer past the bytes that
611 were displayed. */
612 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
613#else
614 n = 1;
615#endif
7bfd842d
NC
616 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
617 symbol += (n - 1);
961c521f 618 }
961c521f 619 }
171191ba 620
7bfd842d 621 if (extra_padding && num_printed < width)
171191ba
NC
622 {
623 /* Fill in the remaining spaces. */
7bfd842d
NC
624 printf ("%-*s", width - num_printed, " ");
625 num_printed = width;
171191ba
NC
626 }
627
628 return num_printed;
31104126
NC
629}
630
1449284b 631/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
632 the given section's name. Like print_symbol, except that it does not try
633 to print multibyte characters, it just interprets them as hex values. */
634
635static const char *
dda8d76d 636printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b
NC
637{
638#define MAX_PRINT_SEC_NAME_LEN 128
639 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
640 const char * name = SECTION_NAME (sec);
641 char * buf = sec_name_buf;
642 char c;
643 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
644
645 while ((c = * name ++) != 0)
646 {
647 if (ISCNTRL (c))
648 {
649 if (remaining < 2)
650 break;
948f632f 651
74e1a04b
NC
652 * buf ++ = '^';
653 * buf ++ = c + 0x40;
654 remaining -= 2;
655 }
656 else if (ISPRINT (c))
657 {
658 * buf ++ = c;
659 remaining -= 1;
660 }
661 else
662 {
663 static char hex[17] = "0123456789ABCDEF";
664
665 if (remaining < 4)
666 break;
667 * buf ++ = '<';
668 * buf ++ = hex[(c & 0xf0) >> 4];
669 * buf ++ = hex[c & 0x0f];
670 * buf ++ = '>';
671 remaining -= 4;
672 }
673
674 if (remaining == 0)
675 break;
676 }
677
678 * buf = 0;
679 return sec_name_buf;
680}
681
682static const char *
dda8d76d 683printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 684{
dda8d76d 685 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
686 return _("<corrupt>");
687
dda8d76d 688 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
689}
690
89fac5e3
RS
691/* Return a pointer to section NAME, or NULL if no such section exists. */
692
693static Elf_Internal_Shdr *
dda8d76d 694find_section (Filedata * filedata, const char * name)
89fac5e3
RS
695{
696 unsigned int i;
697
68807c3c
NC
698 if (filedata->section_headers == NULL)
699 return NULL;
dda8d76d
NC
700
701 for (i = 0; i < filedata->file_header.e_shnum; i++)
702 if (streq (SECTION_NAME (filedata->section_headers + i), name))
703 return filedata->section_headers + i;
89fac5e3
RS
704
705 return NULL;
706}
707
0b6ae522
DJ
708/* Return a pointer to a section containing ADDR, or NULL if no such
709 section exists. */
710
711static Elf_Internal_Shdr *
dda8d76d 712find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
713{
714 unsigned int i;
715
68807c3c
NC
716 if (filedata->section_headers == NULL)
717 return NULL;
718
dda8d76d 719 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 720 {
dda8d76d
NC
721 Elf_Internal_Shdr *sec = filedata->section_headers + i;
722
0b6ae522
DJ
723 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
724 return sec;
725 }
726
727 return NULL;
728}
729
071436c6 730static Elf_Internal_Shdr *
dda8d76d 731find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
732{
733 unsigned int i;
734
68807c3c
NC
735 if (filedata->section_headers == NULL)
736 return NULL;
737
dda8d76d 738 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 739 {
dda8d76d
NC
740 Elf_Internal_Shdr *sec = filedata->section_headers + i;
741
071436c6
NC
742 if (sec->sh_type == type)
743 return sec;
744 }
745
746 return NULL;
747}
748
657d0d47
CC
749/* Return a pointer to section NAME, or NULL if no such section exists,
750 restricted to the list of sections given in SET. */
751
752static Elf_Internal_Shdr *
dda8d76d 753find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
754{
755 unsigned int i;
756
68807c3c
NC
757 if (filedata->section_headers == NULL)
758 return NULL;
759
657d0d47
CC
760 if (set != NULL)
761 {
762 while ((i = *set++) > 0)
b814a36d
NC
763 {
764 /* See PR 21156 for a reproducer. */
dda8d76d 765 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
766 continue; /* FIXME: Should we issue an error message ? */
767
dda8d76d
NC
768 if (streq (SECTION_NAME (filedata->section_headers + i), name))
769 return filedata->section_headers + i;
b814a36d 770 }
657d0d47
CC
771 }
772
dda8d76d 773 return find_section (filedata, name);
657d0d47
CC
774}
775
32ec8896 776/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
777 This OS has so many departures from the ELF standard that we test it at
778 many places. */
779
32ec8896 780static inline bfd_boolean
dda8d76d 781is_ia64_vms (Filedata * filedata)
28f997cf 782{
dda8d76d
NC
783 return filedata->file_header.e_machine == EM_IA_64
784 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
785}
786
bcedfee6 787/* Guess the relocation size commonly used by the specific machines. */
252b5132 788
32ec8896 789static bfd_boolean
2dc4cec1 790guess_is_rela (unsigned int e_machine)
252b5132 791{
9c19a809 792 switch (e_machine)
252b5132
RH
793 {
794 /* Targets that use REL relocations. */
252b5132 795 case EM_386:
22abe556 796 case EM_IAMCU:
f954747f 797 case EM_960:
e9f53129 798 case EM_ARM:
2b0337b0 799 case EM_D10V:
252b5132 800 case EM_CYGNUS_D10V:
e9f53129 801 case EM_DLX:
252b5132 802 case EM_MIPS:
4fe85591 803 case EM_MIPS_RS3_LE:
e9f53129 804 case EM_CYGNUS_M32R:
1c0d3aa6 805 case EM_SCORE:
f6c1a2d5 806 case EM_XGATE:
fe944acf 807 case EM_NFP:
aca4efc7 808 case EM_BPF:
9c19a809 809 return FALSE;
103f02d3 810
252b5132
RH
811 /* Targets that use RELA relocations. */
812 case EM_68K:
f954747f 813 case EM_860:
a06ea964 814 case EM_AARCH64:
cfb8c092 815 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
816 case EM_ALPHA:
817 case EM_ALTERA_NIOS2:
886a2506
NC
818 case EM_ARC:
819 case EM_ARC_COMPACT:
820 case EM_ARC_COMPACT2:
e9f53129
AM
821 case EM_AVR:
822 case EM_AVR_OLD:
823 case EM_BLACKFIN:
60bca95a 824 case EM_CR16:
e9f53129
AM
825 case EM_CRIS:
826 case EM_CRX:
b8891f8d 827 case EM_CSKY:
2b0337b0 828 case EM_D30V:
252b5132 829 case EM_CYGNUS_D30V:
2b0337b0 830 case EM_FR30:
3f8107ab 831 case EM_FT32:
252b5132 832 case EM_CYGNUS_FR30:
5c70f934 833 case EM_CYGNUS_FRV:
e9f53129
AM
834 case EM_H8S:
835 case EM_H8_300:
836 case EM_H8_300H:
800eeca4 837 case EM_IA_64:
1e4cf259
NC
838 case EM_IP2K:
839 case EM_IP2K_OLD:
3b36097d 840 case EM_IQ2000:
84e94c90 841 case EM_LATTICEMICO32:
ff7eeb89 842 case EM_M32C_OLD:
49f58d10 843 case EM_M32C:
e9f53129
AM
844 case EM_M32R:
845 case EM_MCORE:
15ab5209 846 case EM_CYGNUS_MEP:
a3c62988 847 case EM_METAG:
e9f53129
AM
848 case EM_MMIX:
849 case EM_MN10200:
850 case EM_CYGNUS_MN10200:
851 case EM_MN10300:
852 case EM_CYGNUS_MN10300:
5506d11a 853 case EM_MOXIE:
e9f53129
AM
854 case EM_MSP430:
855 case EM_MSP430_OLD:
d031aafb 856 case EM_MT:
35c08157 857 case EM_NDS32:
64fd6348 858 case EM_NIOS32:
73589c9d 859 case EM_OR1K:
e9f53129
AM
860 case EM_PPC64:
861 case EM_PPC:
2b100bb5 862 case EM_TI_PRU:
e23eba97 863 case EM_RISCV:
99c513f6 864 case EM_RL78:
c7927a3c 865 case EM_RX:
e9f53129
AM
866 case EM_S390:
867 case EM_S390_OLD:
868 case EM_SH:
869 case EM_SPARC:
870 case EM_SPARC32PLUS:
871 case EM_SPARCV9:
872 case EM_SPU:
40b36596 873 case EM_TI_C6000:
aa137e4d
NC
874 case EM_TILEGX:
875 case EM_TILEPRO:
708e2187 876 case EM_V800:
e9f53129
AM
877 case EM_V850:
878 case EM_CYGNUS_V850:
879 case EM_VAX:
619ed720 880 case EM_VISIUM:
e9f53129 881 case EM_X86_64:
8a9036a4 882 case EM_L1OM:
7a9068fe 883 case EM_K1OM:
e9f53129
AM
884 case EM_XSTORMY16:
885 case EM_XTENSA:
886 case EM_XTENSA_OLD:
7ba29e2a
NC
887 case EM_MICROBLAZE:
888 case EM_MICROBLAZE_OLD:
f96bd6c2 889 case EM_WEBASSEMBLY:
9c19a809 890 return TRUE;
103f02d3 891
e9f53129
AM
892 case EM_68HC05:
893 case EM_68HC08:
894 case EM_68HC11:
895 case EM_68HC16:
896 case EM_FX66:
897 case EM_ME16:
d1133906 898 case EM_MMA:
d1133906
NC
899 case EM_NCPU:
900 case EM_NDR1:
e9f53129 901 case EM_PCP:
d1133906 902 case EM_ST100:
e9f53129 903 case EM_ST19:
d1133906 904 case EM_ST7:
e9f53129
AM
905 case EM_ST9PLUS:
906 case EM_STARCORE:
d1133906 907 case EM_SVX:
e9f53129 908 case EM_TINYJ:
9c19a809
NC
909 default:
910 warn (_("Don't know about relocations on this machine architecture\n"));
911 return FALSE;
912 }
913}
252b5132 914
dda8d76d 915/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
916 Returns TRUE upon success, FALSE otherwise. If successful then a
917 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
918 and the number of relocs loaded is placed in *NRELASP. It is the caller's
919 responsibility to free the allocated buffer. */
920
921static bfd_boolean
dda8d76d
NC
922slurp_rela_relocs (Filedata * filedata,
923 unsigned long rel_offset,
924 unsigned long rel_size,
925 Elf_Internal_Rela ** relasp,
926 unsigned long * nrelasp)
9c19a809 927{
2cf0635d 928 Elf_Internal_Rela * relas;
8b73c356 929 size_t nrelas;
4d6ed7c8 930 unsigned int i;
252b5132 931
4d6ed7c8
NC
932 if (is_32bit_elf)
933 {
2cf0635d 934 Elf32_External_Rela * erelas;
103f02d3 935
dda8d76d 936 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 937 rel_size, _("32-bit relocation data"));
a6e9f9df 938 if (!erelas)
32ec8896 939 return FALSE;
252b5132 940
4d6ed7c8 941 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 942
3f5e193b
NC
943 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
944 sizeof (Elf_Internal_Rela));
103f02d3 945
4d6ed7c8
NC
946 if (relas == NULL)
947 {
c256ffe7 948 free (erelas);
591a748a 949 error (_("out of memory parsing relocs\n"));
32ec8896 950 return FALSE;
4d6ed7c8 951 }
103f02d3 952
4d6ed7c8
NC
953 for (i = 0; i < nrelas; i++)
954 {
955 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
956 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 957 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 958 }
103f02d3 959
4d6ed7c8
NC
960 free (erelas);
961 }
962 else
963 {
2cf0635d 964 Elf64_External_Rela * erelas;
103f02d3 965
dda8d76d 966 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 967 rel_size, _("64-bit relocation data"));
a6e9f9df 968 if (!erelas)
32ec8896 969 return FALSE;
4d6ed7c8
NC
970
971 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 972
3f5e193b
NC
973 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
974 sizeof (Elf_Internal_Rela));
103f02d3 975
4d6ed7c8
NC
976 if (relas == NULL)
977 {
c256ffe7 978 free (erelas);
591a748a 979 error (_("out of memory parsing relocs\n"));
32ec8896 980 return FALSE;
9c19a809 981 }
4d6ed7c8
NC
982
983 for (i = 0; i < nrelas; i++)
9c19a809 984 {
66543521
AM
985 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
986 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 987 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
988
989 /* The #ifdef BFD64 below is to prevent a compile time
990 warning. We know that if we do not have a 64 bit data
991 type that we will never execute this code anyway. */
992#ifdef BFD64
dda8d76d
NC
993 if (filedata->file_header.e_machine == EM_MIPS
994 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
995 {
996 /* In little-endian objects, r_info isn't really a
997 64-bit little-endian value: it has a 32-bit
998 little-endian symbol index followed by four
999 individual byte fields. Reorder INFO
1000 accordingly. */
91d6fa6a
NC
1001 bfd_vma inf = relas[i].r_info;
1002 inf = (((inf & 0xffffffff) << 32)
1003 | ((inf >> 56) & 0xff)
1004 | ((inf >> 40) & 0xff00)
1005 | ((inf >> 24) & 0xff0000)
1006 | ((inf >> 8) & 0xff000000));
1007 relas[i].r_info = inf;
861fb55a
DJ
1008 }
1009#endif /* BFD64 */
4d6ed7c8 1010 }
103f02d3 1011
4d6ed7c8
NC
1012 free (erelas);
1013 }
32ec8896 1014
4d6ed7c8
NC
1015 *relasp = relas;
1016 *nrelasp = nrelas;
32ec8896 1017 return TRUE;
4d6ed7c8 1018}
103f02d3 1019
dda8d76d 1020/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1021 Returns TRUE upon success, FALSE otherwise. If successful then a
1022 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1023 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1024 responsibility to free the allocated buffer. */
1025
1026static bfd_boolean
dda8d76d
NC
1027slurp_rel_relocs (Filedata * filedata,
1028 unsigned long rel_offset,
1029 unsigned long rel_size,
1030 Elf_Internal_Rela ** relsp,
1031 unsigned long * nrelsp)
4d6ed7c8 1032{
2cf0635d 1033 Elf_Internal_Rela * rels;
8b73c356 1034 size_t nrels;
4d6ed7c8 1035 unsigned int i;
103f02d3 1036
4d6ed7c8
NC
1037 if (is_32bit_elf)
1038 {
2cf0635d 1039 Elf32_External_Rel * erels;
103f02d3 1040
dda8d76d 1041 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1042 rel_size, _("32-bit relocation data"));
a6e9f9df 1043 if (!erels)
32ec8896 1044 return FALSE;
103f02d3 1045
4d6ed7c8 1046 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1047
3f5e193b 1048 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1049
4d6ed7c8
NC
1050 if (rels == NULL)
1051 {
c256ffe7 1052 free (erels);
591a748a 1053 error (_("out of memory parsing relocs\n"));
32ec8896 1054 return FALSE;
4d6ed7c8
NC
1055 }
1056
1057 for (i = 0; i < nrels; i++)
1058 {
1059 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1060 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1061 rels[i].r_addend = 0;
9ea033b2 1062 }
4d6ed7c8
NC
1063
1064 free (erels);
9c19a809
NC
1065 }
1066 else
1067 {
2cf0635d 1068 Elf64_External_Rel * erels;
9ea033b2 1069
dda8d76d 1070 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1071 rel_size, _("64-bit relocation data"));
a6e9f9df 1072 if (!erels)
32ec8896 1073 return FALSE;
103f02d3 1074
4d6ed7c8 1075 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1076
3f5e193b 1077 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1078
4d6ed7c8 1079 if (rels == NULL)
9c19a809 1080 {
c256ffe7 1081 free (erels);
591a748a 1082 error (_("out of memory parsing relocs\n"));
32ec8896 1083 return FALSE;
4d6ed7c8 1084 }
103f02d3 1085
4d6ed7c8
NC
1086 for (i = 0; i < nrels; i++)
1087 {
66543521
AM
1088 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1089 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1090 rels[i].r_addend = 0;
861fb55a
DJ
1091
1092 /* The #ifdef BFD64 below is to prevent a compile time
1093 warning. We know that if we do not have a 64 bit data
1094 type that we will never execute this code anyway. */
1095#ifdef BFD64
dda8d76d
NC
1096 if (filedata->file_header.e_machine == EM_MIPS
1097 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1098 {
1099 /* In little-endian objects, r_info isn't really a
1100 64-bit little-endian value: it has a 32-bit
1101 little-endian symbol index followed by four
1102 individual byte fields. Reorder INFO
1103 accordingly. */
91d6fa6a
NC
1104 bfd_vma inf = rels[i].r_info;
1105 inf = (((inf & 0xffffffff) << 32)
1106 | ((inf >> 56) & 0xff)
1107 | ((inf >> 40) & 0xff00)
1108 | ((inf >> 24) & 0xff0000)
1109 | ((inf >> 8) & 0xff000000));
1110 rels[i].r_info = inf;
861fb55a
DJ
1111 }
1112#endif /* BFD64 */
4d6ed7c8 1113 }
103f02d3 1114
4d6ed7c8
NC
1115 free (erels);
1116 }
32ec8896 1117
4d6ed7c8
NC
1118 *relsp = rels;
1119 *nrelsp = nrels;
32ec8896 1120 return TRUE;
4d6ed7c8 1121}
103f02d3 1122
aca88567
NC
1123/* Returns the reloc type extracted from the reloc info field. */
1124
1125static unsigned int
dda8d76d 1126get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1127{
1128 if (is_32bit_elf)
1129 return ELF32_R_TYPE (reloc_info);
1130
dda8d76d 1131 switch (filedata->file_header.e_machine)
aca88567
NC
1132 {
1133 case EM_MIPS:
1134 /* Note: We assume that reloc_info has already been adjusted for us. */
1135 return ELF64_MIPS_R_TYPE (reloc_info);
1136
1137 case EM_SPARCV9:
1138 return ELF64_R_TYPE_ID (reloc_info);
1139
1140 default:
1141 return ELF64_R_TYPE (reloc_info);
1142 }
1143}
1144
1145/* Return the symbol index extracted from the reloc info field. */
1146
1147static bfd_vma
1148get_reloc_symindex (bfd_vma reloc_info)
1149{
1150 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1151}
1152
13761a11 1153static inline bfd_boolean
dda8d76d 1154uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1155{
1156 return
dda8d76d 1157 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1158 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1159 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1160 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1161 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1162}
1163
d3ba0551
AM
1164/* Display the contents of the relocation data found at the specified
1165 offset. */
ee42cf8c 1166
32ec8896 1167static bfd_boolean
dda8d76d
NC
1168dump_relocations (Filedata * filedata,
1169 unsigned long rel_offset,
1170 unsigned long rel_size,
1171 Elf_Internal_Sym * symtab,
1172 unsigned long nsyms,
1173 char * strtab,
1174 unsigned long strtablen,
1175 int is_rela,
1176 bfd_boolean is_dynsym)
4d6ed7c8 1177{
32ec8896 1178 unsigned long i;
2cf0635d 1179 Elf_Internal_Rela * rels;
32ec8896 1180 bfd_boolean res = TRUE;
103f02d3 1181
4d6ed7c8 1182 if (is_rela == UNKNOWN)
dda8d76d 1183 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1184
4d6ed7c8
NC
1185 if (is_rela)
1186 {
dda8d76d 1187 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1188 return FALSE;
4d6ed7c8
NC
1189 }
1190 else
1191 {
dda8d76d 1192 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1193 return FALSE;
252b5132
RH
1194 }
1195
410f7a12
L
1196 if (is_32bit_elf)
1197 {
1198 if (is_rela)
2c71103e
NC
1199 {
1200 if (do_wide)
1201 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1202 else
1203 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1204 }
410f7a12 1205 else
2c71103e
NC
1206 {
1207 if (do_wide)
1208 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1209 else
1210 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1211 }
410f7a12 1212 }
252b5132 1213 else
410f7a12
L
1214 {
1215 if (is_rela)
2c71103e
NC
1216 {
1217 if (do_wide)
8beeaeb7 1218 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1219 else
1220 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1221 }
410f7a12 1222 else
2c71103e
NC
1223 {
1224 if (do_wide)
8beeaeb7 1225 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1226 else
1227 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1228 }
410f7a12 1229 }
252b5132
RH
1230
1231 for (i = 0; i < rel_size; i++)
1232 {
2cf0635d 1233 const char * rtype;
b34976b6 1234 bfd_vma offset;
91d6fa6a 1235 bfd_vma inf;
b34976b6
AM
1236 bfd_vma symtab_index;
1237 bfd_vma type;
103f02d3 1238
b34976b6 1239 offset = rels[i].r_offset;
91d6fa6a 1240 inf = rels[i].r_info;
103f02d3 1241
dda8d76d 1242 type = get_reloc_type (filedata, inf);
91d6fa6a 1243 symtab_index = get_reloc_symindex (inf);
252b5132 1244
410f7a12
L
1245 if (is_32bit_elf)
1246 {
39dbeff8
AM
1247 printf ("%8.8lx %8.8lx ",
1248 (unsigned long) offset & 0xffffffff,
91d6fa6a 1249 (unsigned long) inf & 0xffffffff);
410f7a12
L
1250 }
1251 else
1252 {
39dbeff8
AM
1253#if BFD_HOST_64BIT_LONG
1254 printf (do_wide
1255 ? "%16.16lx %16.16lx "
1256 : "%12.12lx %12.12lx ",
91d6fa6a 1257 offset, inf);
39dbeff8 1258#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1259#ifndef __MSVCRT__
39dbeff8
AM
1260 printf (do_wide
1261 ? "%16.16llx %16.16llx "
1262 : "%12.12llx %12.12llx ",
91d6fa6a 1263 offset, inf);
6e3d6dc1
NC
1264#else
1265 printf (do_wide
1266 ? "%16.16I64x %16.16I64x "
1267 : "%12.12I64x %12.12I64x ",
91d6fa6a 1268 offset, inf);
6e3d6dc1 1269#endif
39dbeff8 1270#else
2c71103e
NC
1271 printf (do_wide
1272 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1273 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1274 _bfd_int64_high (offset),
1275 _bfd_int64_low (offset),
91d6fa6a
NC
1276 _bfd_int64_high (inf),
1277 _bfd_int64_low (inf));
9ea033b2 1278#endif
410f7a12 1279 }
103f02d3 1280
dda8d76d 1281 switch (filedata->file_header.e_machine)
252b5132
RH
1282 {
1283 default:
1284 rtype = NULL;
1285 break;
1286
a06ea964
NC
1287 case EM_AARCH64:
1288 rtype = elf_aarch64_reloc_type (type);
1289 break;
1290
2b0337b0 1291 case EM_M32R:
252b5132 1292 case EM_CYGNUS_M32R:
9ea033b2 1293 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1294 break;
1295
1296 case EM_386:
22abe556 1297 case EM_IAMCU:
9ea033b2 1298 rtype = elf_i386_reloc_type (type);
252b5132
RH
1299 break;
1300
ba2685cc
AM
1301 case EM_68HC11:
1302 case EM_68HC12:
1303 rtype = elf_m68hc11_reloc_type (type);
1304 break;
75751cd9 1305
7b4ae824
JD
1306 case EM_S12Z:
1307 rtype = elf_s12z_reloc_type (type);
1308 break;
1309
252b5132 1310 case EM_68K:
9ea033b2 1311 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1312 break;
1313
f954747f
AM
1314 case EM_960:
1315 rtype = elf_i960_reloc_type (type);
1316 break;
1317
adde6300 1318 case EM_AVR:
2b0337b0 1319 case EM_AVR_OLD:
adde6300
AM
1320 rtype = elf_avr_reloc_type (type);
1321 break;
1322
9ea033b2
NC
1323 case EM_OLD_SPARCV9:
1324 case EM_SPARC32PLUS:
1325 case EM_SPARCV9:
252b5132 1326 case EM_SPARC:
9ea033b2 1327 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1328 break;
1329
e9f53129
AM
1330 case EM_SPU:
1331 rtype = elf_spu_reloc_type (type);
1332 break;
1333
708e2187
NC
1334 case EM_V800:
1335 rtype = v800_reloc_type (type);
1336 break;
2b0337b0 1337 case EM_V850:
252b5132 1338 case EM_CYGNUS_V850:
9ea033b2 1339 rtype = v850_reloc_type (type);
252b5132
RH
1340 break;
1341
2b0337b0 1342 case EM_D10V:
252b5132 1343 case EM_CYGNUS_D10V:
9ea033b2 1344 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1345 break;
1346
2b0337b0 1347 case EM_D30V:
252b5132 1348 case EM_CYGNUS_D30V:
9ea033b2 1349 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1350 break;
1351
d172d4ba
NC
1352 case EM_DLX:
1353 rtype = elf_dlx_reloc_type (type);
1354 break;
1355
252b5132 1356 case EM_SH:
9ea033b2 1357 rtype = elf_sh_reloc_type (type);
252b5132
RH
1358 break;
1359
2b0337b0 1360 case EM_MN10300:
252b5132 1361 case EM_CYGNUS_MN10300:
9ea033b2 1362 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1363 break;
1364
2b0337b0 1365 case EM_MN10200:
252b5132 1366 case EM_CYGNUS_MN10200:
9ea033b2 1367 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1368 break;
1369
2b0337b0 1370 case EM_FR30:
252b5132 1371 case EM_CYGNUS_FR30:
9ea033b2 1372 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1373 break;
1374
ba2685cc
AM
1375 case EM_CYGNUS_FRV:
1376 rtype = elf_frv_reloc_type (type);
1377 break;
5c70f934 1378
b8891f8d
AJ
1379 case EM_CSKY:
1380 rtype = elf_csky_reloc_type (type);
1381 break;
1382
3f8107ab
AM
1383 case EM_FT32:
1384 rtype = elf_ft32_reloc_type (type);
1385 break;
1386
252b5132 1387 case EM_MCORE:
9ea033b2 1388 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1389 break;
1390
3c3bdf30
NC
1391 case EM_MMIX:
1392 rtype = elf_mmix_reloc_type (type);
1393 break;
1394
5506d11a
AM
1395 case EM_MOXIE:
1396 rtype = elf_moxie_reloc_type (type);
1397 break;
1398
2469cfa2 1399 case EM_MSP430:
dda8d76d 1400 if (uses_msp430x_relocs (filedata))
13761a11
NC
1401 {
1402 rtype = elf_msp430x_reloc_type (type);
1403 break;
1404 }
1a0670f3 1405 /* Fall through. */
2469cfa2
NC
1406 case EM_MSP430_OLD:
1407 rtype = elf_msp430_reloc_type (type);
1408 break;
1409
35c08157
KLC
1410 case EM_NDS32:
1411 rtype = elf_nds32_reloc_type (type);
1412 break;
1413
252b5132 1414 case EM_PPC:
9ea033b2 1415 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1416 break;
1417
c833c019
AM
1418 case EM_PPC64:
1419 rtype = elf_ppc64_reloc_type (type);
1420 break;
1421
252b5132 1422 case EM_MIPS:
4fe85591 1423 case EM_MIPS_RS3_LE:
9ea033b2 1424 rtype = elf_mips_reloc_type (type);
252b5132
RH
1425 break;
1426
e23eba97
NC
1427 case EM_RISCV:
1428 rtype = elf_riscv_reloc_type (type);
1429 break;
1430
252b5132 1431 case EM_ALPHA:
9ea033b2 1432 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1433 break;
1434
1435 case EM_ARM:
9ea033b2 1436 rtype = elf_arm_reloc_type (type);
252b5132
RH
1437 break;
1438
584da044 1439 case EM_ARC:
886a2506
NC
1440 case EM_ARC_COMPACT:
1441 case EM_ARC_COMPACT2:
9ea033b2 1442 rtype = elf_arc_reloc_type (type);
252b5132
RH
1443 break;
1444
1445 case EM_PARISC:
69e617ca 1446 rtype = elf_hppa_reloc_type (type);
252b5132 1447 break;
7d466069 1448
b8720f9d
JL
1449 case EM_H8_300:
1450 case EM_H8_300H:
1451 case EM_H8S:
1452 rtype = elf_h8_reloc_type (type);
1453 break;
1454
73589c9d
CS
1455 case EM_OR1K:
1456 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1457 break;
1458
7d466069 1459 case EM_PJ:
2b0337b0 1460 case EM_PJ_OLD:
7d466069
ILT
1461 rtype = elf_pj_reloc_type (type);
1462 break;
800eeca4
JW
1463 case EM_IA_64:
1464 rtype = elf_ia64_reloc_type (type);
1465 break;
1b61cf92
HPN
1466
1467 case EM_CRIS:
1468 rtype = elf_cris_reloc_type (type);
1469 break;
535c37ff 1470
f954747f
AM
1471 case EM_860:
1472 rtype = elf_i860_reloc_type (type);
1473 break;
1474
bcedfee6 1475 case EM_X86_64:
8a9036a4 1476 case EM_L1OM:
7a9068fe 1477 case EM_K1OM:
bcedfee6
NC
1478 rtype = elf_x86_64_reloc_type (type);
1479 break;
a85d7ed0 1480
f954747f
AM
1481 case EM_S370:
1482 rtype = i370_reloc_type (type);
1483 break;
1484
53c7db4b
KH
1485 case EM_S390_OLD:
1486 case EM_S390:
1487 rtype = elf_s390_reloc_type (type);
1488 break;
93fbbb04 1489
1c0d3aa6
NC
1490 case EM_SCORE:
1491 rtype = elf_score_reloc_type (type);
1492 break;
1493
93fbbb04
GK
1494 case EM_XSTORMY16:
1495 rtype = elf_xstormy16_reloc_type (type);
1496 break;
179d3252 1497
1fe1f39c
NC
1498 case EM_CRX:
1499 rtype = elf_crx_reloc_type (type);
1500 break;
1501
179d3252
JT
1502 case EM_VAX:
1503 rtype = elf_vax_reloc_type (type);
1504 break;
1e4cf259 1505
619ed720
EB
1506 case EM_VISIUM:
1507 rtype = elf_visium_reloc_type (type);
1508 break;
1509
aca4efc7
JM
1510 case EM_BPF:
1511 rtype = elf_bpf_reloc_type (type);
1512 break;
1513
cfb8c092
NC
1514 case EM_ADAPTEVA_EPIPHANY:
1515 rtype = elf_epiphany_reloc_type (type);
1516 break;
1517
1e4cf259
NC
1518 case EM_IP2K:
1519 case EM_IP2K_OLD:
1520 rtype = elf_ip2k_reloc_type (type);
1521 break;
3b36097d
SC
1522
1523 case EM_IQ2000:
1524 rtype = elf_iq2000_reloc_type (type);
1525 break;
88da6820
NC
1526
1527 case EM_XTENSA_OLD:
1528 case EM_XTENSA:
1529 rtype = elf_xtensa_reloc_type (type);
1530 break;
a34e3ecb 1531
84e94c90
NC
1532 case EM_LATTICEMICO32:
1533 rtype = elf_lm32_reloc_type (type);
1534 break;
1535
ff7eeb89 1536 case EM_M32C_OLD:
49f58d10
JB
1537 case EM_M32C:
1538 rtype = elf_m32c_reloc_type (type);
1539 break;
1540
d031aafb
NS
1541 case EM_MT:
1542 rtype = elf_mt_reloc_type (type);
a34e3ecb 1543 break;
1d65ded4
CM
1544
1545 case EM_BLACKFIN:
1546 rtype = elf_bfin_reloc_type (type);
1547 break;
15ab5209
DB
1548
1549 case EM_CYGNUS_MEP:
1550 rtype = elf_mep_reloc_type (type);
1551 break;
60bca95a
NC
1552
1553 case EM_CR16:
1554 rtype = elf_cr16_reloc_type (type);
1555 break;
dd24e3da 1556
7ba29e2a
NC
1557 case EM_MICROBLAZE:
1558 case EM_MICROBLAZE_OLD:
1559 rtype = elf_microblaze_reloc_type (type);
1560 break;
c7927a3c 1561
99c513f6
DD
1562 case EM_RL78:
1563 rtype = elf_rl78_reloc_type (type);
1564 break;
1565
c7927a3c
NC
1566 case EM_RX:
1567 rtype = elf_rx_reloc_type (type);
1568 break;
c29aca4a 1569
a3c62988
NC
1570 case EM_METAG:
1571 rtype = elf_metag_reloc_type (type);
1572 break;
1573
c29aca4a
NC
1574 case EM_XC16X:
1575 case EM_C166:
1576 rtype = elf_xc16x_reloc_type (type);
1577 break;
40b36596
JM
1578
1579 case EM_TI_C6000:
1580 rtype = elf_tic6x_reloc_type (type);
1581 break;
aa137e4d
NC
1582
1583 case EM_TILEGX:
1584 rtype = elf_tilegx_reloc_type (type);
1585 break;
1586
1587 case EM_TILEPRO:
1588 rtype = elf_tilepro_reloc_type (type);
1589 break;
f6c1a2d5 1590
f96bd6c2
PC
1591 case EM_WEBASSEMBLY:
1592 rtype = elf_wasm32_reloc_type (type);
1593 break;
1594
f6c1a2d5
NC
1595 case EM_XGATE:
1596 rtype = elf_xgate_reloc_type (type);
1597 break;
36591ba1
SL
1598
1599 case EM_ALTERA_NIOS2:
1600 rtype = elf_nios2_reloc_type (type);
1601 break;
2b100bb5
DD
1602
1603 case EM_TI_PRU:
1604 rtype = elf_pru_reloc_type (type);
1605 break;
fe944acf
FT
1606
1607 case EM_NFP:
1608 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1609 rtype = elf_nfp3200_reloc_type (type);
1610 else
1611 rtype = elf_nfp_reloc_type (type);
1612 break;
6655dba2
SB
1613
1614 case EM_Z80:
1615 rtype = elf_z80_reloc_type (type);
1616 break;
252b5132
RH
1617 }
1618
1619 if (rtype == NULL)
39dbeff8 1620 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1621 else
5c144731 1622 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1623
dda8d76d 1624 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1625 && rtype != NULL
7ace3541
RH
1626 && streq (rtype, "R_ALPHA_LITUSE")
1627 && is_rela)
1628 {
1629 switch (rels[i].r_addend)
1630 {
1631 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1632 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1633 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1634 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1635 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1636 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1637 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1638 default: rtype = NULL;
1639 }
32ec8896 1640
7ace3541
RH
1641 if (rtype)
1642 printf (" (%s)", rtype);
1643 else
1644 {
1645 putchar (' ');
1646 printf (_("<unknown addend: %lx>"),
1647 (unsigned long) rels[i].r_addend);
32ec8896 1648 res = FALSE;
7ace3541
RH
1649 }
1650 }
1651 else if (symtab_index)
252b5132 1652 {
af3fc3bc 1653 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1654 {
27a45f42
AS
1655 error (_(" bad symbol index: %08lx in reloc\n"),
1656 (unsigned long) symtab_index);
32ec8896
NC
1657 res = FALSE;
1658 }
af3fc3bc 1659 else
19936277 1660 {
2cf0635d 1661 Elf_Internal_Sym * psym;
bb4d2ac2
L
1662 const char * version_string;
1663 enum versioned_symbol_info sym_info;
1664 unsigned short vna_other;
19936277 1665
af3fc3bc 1666 psym = symtab + symtab_index;
103f02d3 1667
bb4d2ac2 1668 version_string
dda8d76d 1669 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1670 strtab, strtablen,
1671 symtab_index,
1672 psym,
1673 &sym_info,
1674 &vna_other);
1675
af3fc3bc 1676 printf (" ");
171191ba 1677
d8045f23
NC
1678 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1679 {
1680 const char * name;
1681 unsigned int len;
1682 unsigned int width = is_32bit_elf ? 8 : 14;
1683
1684 /* Relocations against GNU_IFUNC symbols do not use the value
1685 of the symbol as the address to relocate against. Instead
1686 they invoke the function named by the symbol and use its
1687 result as the address for relocation.
1688
1689 To indicate this to the user, do not display the value of
1690 the symbol in the "Symbols's Value" field. Instead show
1691 its name followed by () as a hint that the symbol is
1692 invoked. */
1693
1694 if (strtab == NULL
1695 || psym->st_name == 0
1696 || psym->st_name >= strtablen)
1697 name = "??";
1698 else
1699 name = strtab + psym->st_name;
1700
1701 len = print_symbol (width, name);
bb4d2ac2
L
1702 if (version_string)
1703 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1704 version_string);
d8045f23
NC
1705 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1706 }
1707 else
1708 {
1709 print_vma (psym->st_value, LONG_HEX);
171191ba 1710
d8045f23
NC
1711 printf (is_32bit_elf ? " " : " ");
1712 }
103f02d3 1713
af3fc3bc 1714 if (psym->st_name == 0)
f1ef08cb 1715 {
2cf0635d 1716 const char * sec_name = "<null>";
f1ef08cb
AM
1717 char name_buf[40];
1718
1719 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1720 {
dda8d76d
NC
1721 if (psym->st_shndx < filedata->file_header.e_shnum)
1722 sec_name = SECTION_NAME (filedata->section_headers + psym->st_shndx);
f1ef08cb
AM
1723 else if (psym->st_shndx == SHN_ABS)
1724 sec_name = "ABS";
1725 else if (psym->st_shndx == SHN_COMMON)
1726 sec_name = "COMMON";
dda8d76d 1727 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1728 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1729 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1730 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1731 sec_name = "SCOMMON";
dda8d76d 1732 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1733 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1734 sec_name = "SUNDEF";
dda8d76d
NC
1735 else if ((filedata->file_header.e_machine == EM_X86_64
1736 || filedata->file_header.e_machine == EM_L1OM
1737 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1738 && psym->st_shndx == SHN_X86_64_LCOMMON)
1739 sec_name = "LARGE_COMMON";
dda8d76d
NC
1740 else if (filedata->file_header.e_machine == EM_IA_64
1741 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1742 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1743 sec_name = "ANSI_COM";
dda8d76d 1744 else if (is_ia64_vms (filedata)
148b93f2
NC
1745 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1746 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1747 else
1748 {
1749 sprintf (name_buf, "<section 0x%x>",
1750 (unsigned int) psym->st_shndx);
1751 sec_name = name_buf;
1752 }
1753 }
1754 print_symbol (22, sec_name);
1755 }
af3fc3bc 1756 else if (strtab == NULL)
d79b3d50 1757 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1758 else if (psym->st_name >= strtablen)
32ec8896 1759 {
27a45f42
AS
1760 error (_("<corrupt string table index: %3ld>\n"),
1761 psym->st_name);
32ec8896
NC
1762 res = FALSE;
1763 }
af3fc3bc 1764 else
bb4d2ac2
L
1765 {
1766 print_symbol (22, strtab + psym->st_name);
1767 if (version_string)
1768 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1769 version_string);
1770 }
103f02d3 1771
af3fc3bc 1772 if (is_rela)
171191ba 1773 {
7360e63f 1774 bfd_vma off = rels[i].r_addend;
171191ba 1775
7360e63f 1776 if ((bfd_signed_vma) off < 0)
598aaa76 1777 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1778 else
598aaa76 1779 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1780 }
19936277 1781 }
252b5132 1782 }
1b228002 1783 else if (is_rela)
f7a99963 1784 {
7360e63f 1785 bfd_vma off = rels[i].r_addend;
e04d7088
L
1786
1787 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1788 if ((bfd_signed_vma) off < 0)
e04d7088
L
1789 printf ("-%" BFD_VMA_FMT "x", - off);
1790 else
1791 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1792 }
252b5132 1793
dda8d76d 1794 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1795 && rtype != NULL
1796 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1797 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1798
252b5132 1799 putchar ('\n');
2c71103e 1800
aca88567 1801#ifdef BFD64
dda8d76d 1802 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1803 {
91d6fa6a
NC
1804 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1805 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1806 const char * rtype2 = elf_mips_reloc_type (type2);
1807 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1808
2c71103e
NC
1809 printf (" Type2: ");
1810
1811 if (rtype2 == NULL)
39dbeff8
AM
1812 printf (_("unrecognized: %-7lx"),
1813 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1814 else
1815 printf ("%-17.17s", rtype2);
1816
18bd398b 1817 printf ("\n Type3: ");
2c71103e
NC
1818
1819 if (rtype3 == NULL)
39dbeff8
AM
1820 printf (_("unrecognized: %-7lx"),
1821 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1822 else
1823 printf ("%-17.17s", rtype3);
1824
53c7db4b 1825 putchar ('\n');
2c71103e 1826 }
aca88567 1827#endif /* BFD64 */
252b5132
RH
1828 }
1829
c8286bd1 1830 free (rels);
32ec8896
NC
1831
1832 return res;
252b5132
RH
1833}
1834
37c18eed
SD
1835static const char *
1836get_aarch64_dynamic_type (unsigned long type)
1837{
1838 switch (type)
1839 {
1840 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 1841 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 1842 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
1843 default:
1844 return NULL;
1845 }
1846}
1847
252b5132 1848static const char *
d3ba0551 1849get_mips_dynamic_type (unsigned long type)
252b5132
RH
1850{
1851 switch (type)
1852 {
1853 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1854 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1855 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1856 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1857 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1858 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1859 case DT_MIPS_MSYM: return "MIPS_MSYM";
1860 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1861 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1862 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1863 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1864 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1865 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1866 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1867 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1868 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1869 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1870 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1871 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1872 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1873 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1874 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1875 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1876 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1877 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1878 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1879 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1880 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1881 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1882 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1883 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1884 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1885 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1886 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1887 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1888 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1889 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1890 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1891 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1892 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1893 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1894 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1895 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1896 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1897 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1898 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 1899 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
1900 default:
1901 return NULL;
1902 }
1903}
1904
9a097730 1905static const char *
d3ba0551 1906get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1907{
1908 switch (type)
1909 {
1910 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1911 default:
1912 return NULL;
1913 }
103f02d3
UD
1914}
1915
7490d522
AM
1916static const char *
1917get_ppc_dynamic_type (unsigned long type)
1918{
1919 switch (type)
1920 {
a7f2871e 1921 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1922 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1923 default:
1924 return NULL;
1925 }
1926}
1927
f1cb7e17 1928static const char *
d3ba0551 1929get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1930{
1931 switch (type)
1932 {
a7f2871e
AM
1933 case DT_PPC64_GLINK: return "PPC64_GLINK";
1934 case DT_PPC64_OPD: return "PPC64_OPD";
1935 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1936 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1937 default:
1938 return NULL;
1939 }
1940}
1941
103f02d3 1942static const char *
d3ba0551 1943get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1944{
1945 switch (type)
1946 {
1947 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1948 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1949 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1950 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1951 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1952 case DT_HP_PREINIT: return "HP_PREINIT";
1953 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1954 case DT_HP_NEEDED: return "HP_NEEDED";
1955 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1956 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1957 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1958 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1959 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1960 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1961 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1962 case DT_HP_FILTERED: return "HP_FILTERED";
1963 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1964 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1965 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1966 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1967 case DT_PLT: return "PLT";
1968 case DT_PLT_SIZE: return "PLT_SIZE";
1969 case DT_DLT: return "DLT";
1970 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1971 default:
1972 return NULL;
1973 }
1974}
9a097730 1975
ecc51f48 1976static const char *
d3ba0551 1977get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1978{
1979 switch (type)
1980 {
148b93f2
NC
1981 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1982 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1983 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1984 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1985 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1986 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1987 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1988 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1989 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1990 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1991 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1992 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1993 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1994 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1995 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1996 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1997 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1998 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1999 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2000 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2001 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2002 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2003 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2004 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2005 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2006 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2007 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2008 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2009 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2010 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2011 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2012 default:
2013 return NULL;
2014 }
2015}
2016
fd85a6a1
NC
2017static const char *
2018get_solaris_section_type (unsigned long type)
2019{
2020 switch (type)
2021 {
2022 case 0x6fffffee: return "SUNW_ancillary";
2023 case 0x6fffffef: return "SUNW_capchain";
2024 case 0x6ffffff0: return "SUNW_capinfo";
2025 case 0x6ffffff1: return "SUNW_symsort";
2026 case 0x6ffffff2: return "SUNW_tlssort";
2027 case 0x6ffffff3: return "SUNW_LDYNSYM";
2028 case 0x6ffffff4: return "SUNW_dof";
2029 case 0x6ffffff5: return "SUNW_cap";
2030 case 0x6ffffff6: return "SUNW_SIGNATURE";
2031 case 0x6ffffff7: return "SUNW_ANNOTATE";
2032 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2033 case 0x6ffffff9: return "SUNW_DEBUG";
2034 case 0x6ffffffa: return "SUNW_move";
2035 case 0x6ffffffb: return "SUNW_COMDAT";
2036 case 0x6ffffffc: return "SUNW_syminfo";
2037 case 0x6ffffffd: return "SUNW_verdef";
2038 case 0x6ffffffe: return "SUNW_verneed";
2039 case 0x6fffffff: return "SUNW_versym";
2040 case 0x70000000: return "SPARC_GOTDATA";
2041 default: return NULL;
2042 }
2043}
2044
fabcb361
RH
2045static const char *
2046get_alpha_dynamic_type (unsigned long type)
2047{
2048 switch (type)
2049 {
2050 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2051 default: return NULL;
fabcb361
RH
2052 }
2053}
2054
1c0d3aa6
NC
2055static const char *
2056get_score_dynamic_type (unsigned long type)
2057{
2058 switch (type)
2059 {
2060 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2061 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2062 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2063 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2064 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2065 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2066 default: return NULL;
1c0d3aa6
NC
2067 }
2068}
2069
40b36596
JM
2070static const char *
2071get_tic6x_dynamic_type (unsigned long type)
2072{
2073 switch (type)
2074 {
2075 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2076 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2077 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2078 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2079 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2080 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2081 default: return NULL;
40b36596
JM
2082 }
2083}
1c0d3aa6 2084
36591ba1
SL
2085static const char *
2086get_nios2_dynamic_type (unsigned long type)
2087{
2088 switch (type)
2089 {
2090 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2091 default: return NULL;
36591ba1
SL
2092 }
2093}
2094
fd85a6a1
NC
2095static const char *
2096get_solaris_dynamic_type (unsigned long type)
2097{
2098 switch (type)
2099 {
2100 case 0x6000000d: return "SUNW_AUXILIARY";
2101 case 0x6000000e: return "SUNW_RTLDINF";
2102 case 0x6000000f: return "SUNW_FILTER";
2103 case 0x60000010: return "SUNW_CAP";
2104 case 0x60000011: return "SUNW_SYMTAB";
2105 case 0x60000012: return "SUNW_SYMSZ";
2106 case 0x60000013: return "SUNW_SORTENT";
2107 case 0x60000014: return "SUNW_SYMSORT";
2108 case 0x60000015: return "SUNW_SYMSORTSZ";
2109 case 0x60000016: return "SUNW_TLSSORT";
2110 case 0x60000017: return "SUNW_TLSSORTSZ";
2111 case 0x60000018: return "SUNW_CAPINFO";
2112 case 0x60000019: return "SUNW_STRPAD";
2113 case 0x6000001a: return "SUNW_CAPCHAIN";
2114 case 0x6000001b: return "SUNW_LDMACH";
2115 case 0x6000001d: return "SUNW_CAPCHAINENT";
2116 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2117 case 0x60000021: return "SUNW_PARENT";
2118 case 0x60000023: return "SUNW_ASLR";
2119 case 0x60000025: return "SUNW_RELAX";
2120 case 0x60000029: return "SUNW_NXHEAP";
2121 case 0x6000002b: return "SUNW_NXSTACK";
2122
2123 case 0x70000001: return "SPARC_REGISTER";
2124 case 0x7ffffffd: return "AUXILIARY";
2125 case 0x7ffffffe: return "USED";
2126 case 0x7fffffff: return "FILTER";
2127
15f205b1 2128 default: return NULL;
fd85a6a1
NC
2129 }
2130}
2131
252b5132 2132static const char *
dda8d76d 2133get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2134{
e9e44622 2135 static char buff[64];
252b5132
RH
2136
2137 switch (type)
2138 {
2139 case DT_NULL: return "NULL";
2140 case DT_NEEDED: return "NEEDED";
2141 case DT_PLTRELSZ: return "PLTRELSZ";
2142 case DT_PLTGOT: return "PLTGOT";
2143 case DT_HASH: return "HASH";
2144 case DT_STRTAB: return "STRTAB";
2145 case DT_SYMTAB: return "SYMTAB";
2146 case DT_RELA: return "RELA";
2147 case DT_RELASZ: return "RELASZ";
2148 case DT_RELAENT: return "RELAENT";
2149 case DT_STRSZ: return "STRSZ";
2150 case DT_SYMENT: return "SYMENT";
2151 case DT_INIT: return "INIT";
2152 case DT_FINI: return "FINI";
2153 case DT_SONAME: return "SONAME";
2154 case DT_RPATH: return "RPATH";
2155 case DT_SYMBOLIC: return "SYMBOLIC";
2156 case DT_REL: return "REL";
2157 case DT_RELSZ: return "RELSZ";
2158 case DT_RELENT: return "RELENT";
2159 case DT_PLTREL: return "PLTREL";
2160 case DT_DEBUG: return "DEBUG";
2161 case DT_TEXTREL: return "TEXTREL";
2162 case DT_JMPREL: return "JMPREL";
2163 case DT_BIND_NOW: return "BIND_NOW";
2164 case DT_INIT_ARRAY: return "INIT_ARRAY";
2165 case DT_FINI_ARRAY: return "FINI_ARRAY";
2166 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2167 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2168 case DT_RUNPATH: return "RUNPATH";
2169 case DT_FLAGS: return "FLAGS";
2d0e6f43 2170
d1133906
NC
2171 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2172 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2173 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2174
05107a46 2175 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2176 case DT_PLTPADSZ: return "PLTPADSZ";
2177 case DT_MOVEENT: return "MOVEENT";
2178 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2179 case DT_FEATURE: return "FEATURE";
252b5132
RH
2180 case DT_POSFLAG_1: return "POSFLAG_1";
2181 case DT_SYMINSZ: return "SYMINSZ";
2182 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2183
252b5132 2184 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2185 case DT_CONFIG: return "CONFIG";
2186 case DT_DEPAUDIT: return "DEPAUDIT";
2187 case DT_AUDIT: return "AUDIT";
2188 case DT_PLTPAD: return "PLTPAD";
2189 case DT_MOVETAB: return "MOVETAB";
252b5132 2190 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2191
252b5132 2192 case DT_VERSYM: return "VERSYM";
103f02d3 2193
67a4f2b7
AO
2194 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2195 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2196 case DT_RELACOUNT: return "RELACOUNT";
2197 case DT_RELCOUNT: return "RELCOUNT";
2198 case DT_FLAGS_1: return "FLAGS_1";
2199 case DT_VERDEF: return "VERDEF";
2200 case DT_VERDEFNUM: return "VERDEFNUM";
2201 case DT_VERNEED: return "VERNEED";
2202 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2203
019148e4 2204 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2205 case DT_USED: return "USED";
2206 case DT_FILTER: return "FILTER";
103f02d3 2207
047b2264
JJ
2208 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2209 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2210 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2211 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2212 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2213 case DT_GNU_HASH: return "GNU_HASH";
047b2264 2214
252b5132
RH
2215 default:
2216 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2217 {
2cf0635d 2218 const char * result;
103f02d3 2219
dda8d76d 2220 switch (filedata->file_header.e_machine)
252b5132 2221 {
37c18eed
SD
2222 case EM_AARCH64:
2223 result = get_aarch64_dynamic_type (type);
2224 break;
252b5132 2225 case EM_MIPS:
4fe85591 2226 case EM_MIPS_RS3_LE:
252b5132
RH
2227 result = get_mips_dynamic_type (type);
2228 break;
9a097730
RH
2229 case EM_SPARCV9:
2230 result = get_sparc64_dynamic_type (type);
2231 break;
7490d522
AM
2232 case EM_PPC:
2233 result = get_ppc_dynamic_type (type);
2234 break;
f1cb7e17
AM
2235 case EM_PPC64:
2236 result = get_ppc64_dynamic_type (type);
2237 break;
ecc51f48
NC
2238 case EM_IA_64:
2239 result = get_ia64_dynamic_type (type);
2240 break;
fabcb361
RH
2241 case EM_ALPHA:
2242 result = get_alpha_dynamic_type (type);
2243 break;
1c0d3aa6
NC
2244 case EM_SCORE:
2245 result = get_score_dynamic_type (type);
2246 break;
40b36596
JM
2247 case EM_TI_C6000:
2248 result = get_tic6x_dynamic_type (type);
2249 break;
36591ba1
SL
2250 case EM_ALTERA_NIOS2:
2251 result = get_nios2_dynamic_type (type);
2252 break;
252b5132 2253 default:
dda8d76d 2254 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2255 result = get_solaris_dynamic_type (type);
2256 else
2257 result = NULL;
252b5132
RH
2258 break;
2259 }
2260
2261 if (result != NULL)
2262 return result;
2263
e9e44622 2264 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2265 }
eec8f817 2266 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2267 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2268 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2269 {
2cf0635d 2270 const char * result;
103f02d3 2271
dda8d76d 2272 switch (filedata->file_header.e_machine)
103f02d3
UD
2273 {
2274 case EM_PARISC:
2275 result = get_parisc_dynamic_type (type);
2276 break;
148b93f2
NC
2277 case EM_IA_64:
2278 result = get_ia64_dynamic_type (type);
2279 break;
103f02d3 2280 default:
dda8d76d 2281 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2282 result = get_solaris_dynamic_type (type);
2283 else
2284 result = NULL;
103f02d3
UD
2285 break;
2286 }
2287
2288 if (result != NULL)
2289 return result;
2290
e9e44622
JJ
2291 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2292 type);
103f02d3 2293 }
252b5132 2294 else
e9e44622 2295 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2296
252b5132
RH
2297 return buff;
2298 }
2299}
2300
2301static char *
d3ba0551 2302get_file_type (unsigned e_type)
252b5132 2303{
89246a0e 2304 static char buff[64];
252b5132
RH
2305
2306 switch (e_type)
2307 {
32ec8896
NC
2308 case ET_NONE: return _("NONE (None)");
2309 case ET_REL: return _("REL (Relocatable file)");
2310 case ET_EXEC: return _("EXEC (Executable file)");
2311 case ET_DYN: return _("DYN (Shared object file)");
2312 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2313
2314 default:
2315 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2316 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2317 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2318 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2319 else
e9e44622 2320 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2321 return buff;
2322 }
2323}
2324
2325static char *
d3ba0551 2326get_machine_name (unsigned e_machine)
252b5132 2327{
b34976b6 2328 static char buff[64]; /* XXX */
252b5132
RH
2329
2330 switch (e_machine)
2331 {
55e22ca8
NC
2332 /* Please keep this switch table sorted by increasing EM_ value. */
2333 /* 0 */
c45021f2
NC
2334 case EM_NONE: return _("None");
2335 case EM_M32: return "WE32100";
2336 case EM_SPARC: return "Sparc";
2337 case EM_386: return "Intel 80386";
2338 case EM_68K: return "MC68000";
2339 case EM_88K: return "MC88000";
22abe556 2340 case EM_IAMCU: return "Intel MCU";
fb70ec17 2341 case EM_860: return "Intel 80860";
c45021f2
NC
2342 case EM_MIPS: return "MIPS R3000";
2343 case EM_S370: return "IBM System/370";
55e22ca8 2344 /* 10 */
7036c0e1 2345 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2346 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2347 case EM_PARISC: return "HPPA";
55e22ca8 2348 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2349 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2350 case EM_960: return "Intel 80960";
c45021f2 2351 case EM_PPC: return "PowerPC";
55e22ca8 2352 /* 20 */
285d1771 2353 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2354 case EM_S390_OLD:
2355 case EM_S390: return "IBM S/390";
2356 case EM_SPU: return "SPU";
2357 /* 30 */
2358 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2359 case EM_FR20: return "Fujitsu FR20";
2360 case EM_RH32: return "TRW RH32";
b34976b6 2361 case EM_MCORE: return "MCORE";
55e22ca8 2362 /* 40 */
7036c0e1
AJ
2363 case EM_ARM: return "ARM";
2364 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2365 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2366 case EM_SPARCV9: return "Sparc v9";
2367 case EM_TRICORE: return "Siemens Tricore";
584da044 2368 case EM_ARC: return "ARC";
c2dcd04e
NC
2369 case EM_H8_300: return "Renesas H8/300";
2370 case EM_H8_300H: return "Renesas H8/300H";
2371 case EM_H8S: return "Renesas H8S";
2372 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2373 /* 50 */
30800947 2374 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2375 case EM_MIPS_X: return "Stanford MIPS-X";
2376 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2377 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2378 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2379 case EM_PCP: return "Siemens PCP";
2380 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2381 case EM_NDR1: return "Denso NDR1 microprocesspr";
2382 case EM_STARCORE: return "Motorola Star*Core processor";
2383 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2384 /* 60 */
7036c0e1
AJ
2385 case EM_ST100: return "STMicroelectronics ST100 processor";
2386 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2387 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2388 case EM_PDSP: return "Sony DSP processor";
2389 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2390 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2391 case EM_FX66: return "Siemens FX66 microcontroller";
2392 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2393 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2394 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2395 /* 70 */
7036c0e1
AJ
2396 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2397 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2398 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2399 case EM_SVX: return "Silicon Graphics SVx";
2400 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2401 case EM_VAX: return "Digital VAX";
1b61cf92 2402 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2403 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2404 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2405 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2406 /* 80 */
b34976b6 2407 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2408 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2409 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2410 case EM_AVR_OLD:
2411 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2412 case EM_CYGNUS_FR30:
2413 case EM_FR30: return "Fujitsu FR30";
2414 case EM_CYGNUS_D10V:
2415 case EM_D10V: return "d10v";
2416 case EM_CYGNUS_D30V:
2417 case EM_D30V: return "d30v";
2418 case EM_CYGNUS_V850:
2419 case EM_V850: return "Renesas V850";
2420 case EM_CYGNUS_M32R:
2421 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2422 case EM_CYGNUS_MN10300:
2423 case EM_MN10300: return "mn10300";
2424 /* 90 */
2425 case EM_CYGNUS_MN10200:
2426 case EM_MN10200: return "mn10200";
2427 case EM_PJ: return "picoJava";
73589c9d 2428 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2429 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2430 case EM_XTENSA_OLD:
2431 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2432 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2433 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2434 case EM_NS32K: return "National Semiconductor 32000 series";
2435 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2436 case EM_SNP1K: return "Trebia SNP 1000 processor";
2437 /* 100 */
9abca702 2438 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2439 case EM_IP2K_OLD:
2440 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2441 case EM_MAX: return "MAX Processor";
2442 case EM_CR: return "National Semiconductor CompactRISC";
2443 case EM_F2MC16: return "Fujitsu F2MC16";
2444 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2445 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2446 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2447 case EM_SEP: return "Sharp embedded microprocessor";
2448 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2449 /* 110 */
11636f9e
JM
2450 case EM_UNICORE: return "Unicore";
2451 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2452 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2453 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2454 case EM_CRX: return "National Semiconductor CRX microprocessor";
2455 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2456 case EM_C166:
d70c5fc7 2457 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2458 case EM_M16C: return "Renesas M16C series microprocessors";
2459 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2460 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2461 /* 120 */
2462 case EM_M32C: return "Renesas M32c";
2463 /* 130 */
11636f9e
JM
2464 case EM_TSK3000: return "Altium TSK3000 core";
2465 case EM_RS08: return "Freescale RS08 embedded processor";
2466 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2467 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2468 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2469 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2470 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2471 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2472 /* 140 */
11636f9e
JM
2473 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2474 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2475 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2476 case EM_TI_PRU: return "TI PRU I/O processor";
2477 /* 160 */
11636f9e
JM
2478 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2479 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2480 case EM_R32C: return "Renesas R32C series microprocessors";
2481 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2482 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2483 case EM_8051: return "Intel 8051 and variants";
2484 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2485 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2486 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2487 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2488 /* 170 */
11636f9e
JM
2489 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2490 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2491 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2492 case EM_RX: return "Renesas RX";
a3c62988 2493 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2494 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2495 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2496 case EM_CR16:
2497 case EM_MICROBLAZE:
2498 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2499 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2500 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2501 /* 180 */
2502 case EM_L1OM: return "Intel L1OM";
2503 case EM_K1OM: return "Intel K1OM";
2504 case EM_INTEL182: return "Intel (reserved)";
2505 case EM_AARCH64: return "AArch64";
2506 case EM_ARM184: return "ARM (reserved)";
2507 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2508 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2509 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2510 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2511 /* 190 */
11636f9e 2512 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2513 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2514 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2515 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2516 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2517 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2518 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2519 case EM_RL78: return "Renesas RL78";
6d913794 2520 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2521 case EM_78K0R: return "Renesas 78K0R";
2522 /* 200 */
6d913794 2523 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2524 case EM_BA1: return "Beyond BA1 CPU architecture";
2525 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2526 case EM_XCORE: return "XMOS xCORE processor family";
2527 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
55e22ca8 2528 /* 210 */
6d913794
NC
2529 case EM_KM32: return "KM211 KM32 32-bit processor";
2530 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2531 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2532 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2533 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2534 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2535 case EM_COGE: return "Cognitive Smart Memory Processor";
2536 case EM_COOL: return "Bluechip Systems CoolEngine";
2537 case EM_NORC: return "Nanoradio Optimized RISC";
2538 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2539 /* 220 */
15f205b1 2540 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2541 case EM_VISIUM: return "CDS VISIUMcore processor";
2542 case EM_FT32: return "FTDI Chip FT32";
2543 case EM_MOXIE: return "Moxie";
2544 case EM_AMDGPU: return "AMD GPU";
2545 case EM_RISCV: return "RISC-V";
2546 case EM_LANAI: return "Lanai 32-bit processor";
2547 case EM_BPF: return "Linux BPF";
fe944acf 2548 case EM_NFP: return "Netronome Flow Processor";
55e22ca8
NC
2549
2550 /* Large numbers... */
2551 case EM_MT: return "Morpho Techologies MT processor";
2552 case EM_ALPHA: return "Alpha";
2553 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2554 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2555 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2556 case EM_IQ2000: return "Vitesse IQ2000";
2557 case EM_M32C_OLD:
2558 case EM_NIOS32: return "Altera Nios";
2559 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2560 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2561 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2562 case EM_S12Z: return "Freescale S12Z";
b8891f8d 2563 case EM_CSKY: return "C-SKY";
55e22ca8 2564
252b5132 2565 default:
35d9dd2f 2566 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2567 return buff;
2568 }
2569}
2570
a9522a21
AB
2571static void
2572decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2573{
2574 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
2575 other compilers don't a specific architecture type in the e_flags, and
2576 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2577 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2578 architectures.
2579
2580 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2581 but also sets a specific architecture type in the e_flags field.
2582
2583 However, when decoding the flags we don't worry if we see an
2584 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2585 ARCEM architecture type. */
2586
2587 switch (e_flags & EF_ARC_MACH_MSK)
2588 {
2589 /* We only expect these to occur for EM_ARC_COMPACT2. */
2590 case EF_ARC_CPU_ARCV2EM:
2591 strcat (buf, ", ARC EM");
2592 break;
2593 case EF_ARC_CPU_ARCV2HS:
2594 strcat (buf, ", ARC HS");
2595 break;
2596
2597 /* We only expect these to occur for EM_ARC_COMPACT. */
2598 case E_ARC_MACH_ARC600:
2599 strcat (buf, ", ARC600");
2600 break;
2601 case E_ARC_MACH_ARC601:
2602 strcat (buf, ", ARC601");
2603 break;
2604 case E_ARC_MACH_ARC700:
2605 strcat (buf, ", ARC700");
2606 break;
2607
2608 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2609 new ELF with new architecture being read by an old version of
2610 readelf, or (c) An ELF built with non-GNU compiler that does not
2611 set the architecture in the e_flags. */
2612 default:
2613 if (e_machine == EM_ARC_COMPACT)
2614 strcat (buf, ", Unknown ARCompact");
2615 else
2616 strcat (buf, ", Unknown ARC");
2617 break;
2618 }
2619
2620 switch (e_flags & EF_ARC_OSABI_MSK)
2621 {
2622 case E_ARC_OSABI_ORIG:
2623 strcat (buf, ", (ABI:legacy)");
2624 break;
2625 case E_ARC_OSABI_V2:
2626 strcat (buf, ", (ABI:v2)");
2627 break;
2628 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2629 case E_ARC_OSABI_V3:
2630 strcat (buf, ", v3 no-legacy-syscalls ABI");
2631 break;
53a346d8
CZ
2632 case E_ARC_OSABI_V4:
2633 strcat (buf, ", v4 ABI");
2634 break;
a9522a21
AB
2635 default:
2636 strcat (buf, ", unrecognised ARC OSABI flag");
2637 break;
2638 }
2639}
2640
f3485b74 2641static void
d3ba0551 2642decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2643{
2644 unsigned eabi;
32ec8896 2645 bfd_boolean unknown = FALSE;
f3485b74
NC
2646
2647 eabi = EF_ARM_EABI_VERSION (e_flags);
2648 e_flags &= ~ EF_ARM_EABIMASK;
2649
2650 /* Handle "generic" ARM flags. */
2651 if (e_flags & EF_ARM_RELEXEC)
2652 {
2653 strcat (buf, ", relocatable executable");
2654 e_flags &= ~ EF_ARM_RELEXEC;
2655 }
76da6bbe 2656
18a20338
CL
2657 if (e_flags & EF_ARM_PIC)
2658 {
2659 strcat (buf, ", position independent");
2660 e_flags &= ~ EF_ARM_PIC;
2661 }
2662
f3485b74
NC
2663 /* Now handle EABI specific flags. */
2664 switch (eabi)
2665 {
2666 default:
2c71103e 2667 strcat (buf, ", <unrecognized EABI>");
f3485b74 2668 if (e_flags)
32ec8896 2669 unknown = TRUE;
f3485b74
NC
2670 break;
2671
2672 case EF_ARM_EABI_VER1:
a5bcd848 2673 strcat (buf, ", Version1 EABI");
f3485b74
NC
2674 while (e_flags)
2675 {
2676 unsigned flag;
76da6bbe 2677
f3485b74
NC
2678 /* Process flags one bit at a time. */
2679 flag = e_flags & - e_flags;
2680 e_flags &= ~ flag;
76da6bbe 2681
f3485b74
NC
2682 switch (flag)
2683 {
a5bcd848 2684 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2685 strcat (buf, ", sorted symbol tables");
2686 break;
76da6bbe 2687
f3485b74 2688 default:
32ec8896 2689 unknown = TRUE;
f3485b74
NC
2690 break;
2691 }
2692 }
2693 break;
76da6bbe 2694
a5bcd848
PB
2695 case EF_ARM_EABI_VER2:
2696 strcat (buf, ", Version2 EABI");
2697 while (e_flags)
2698 {
2699 unsigned flag;
2700
2701 /* Process flags one bit at a time. */
2702 flag = e_flags & - e_flags;
2703 e_flags &= ~ flag;
2704
2705 switch (flag)
2706 {
2707 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2708 strcat (buf, ", sorted symbol tables");
2709 break;
2710
2711 case EF_ARM_DYNSYMSUSESEGIDX:
2712 strcat (buf, ", dynamic symbols use segment index");
2713 break;
2714
2715 case EF_ARM_MAPSYMSFIRST:
2716 strcat (buf, ", mapping symbols precede others");
2717 break;
2718
2719 default:
32ec8896 2720 unknown = TRUE;
a5bcd848
PB
2721 break;
2722 }
2723 }
2724 break;
2725
d507cf36
PB
2726 case EF_ARM_EABI_VER3:
2727 strcat (buf, ", Version3 EABI");
8cb51566
PB
2728 break;
2729
2730 case EF_ARM_EABI_VER4:
2731 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2732 while (e_flags)
2733 {
2734 unsigned flag;
2735
2736 /* Process flags one bit at a time. */
2737 flag = e_flags & - e_flags;
2738 e_flags &= ~ flag;
2739
2740 switch (flag)
2741 {
2742 case EF_ARM_BE8:
2743 strcat (buf, ", BE8");
2744 break;
2745
2746 case EF_ARM_LE8:
2747 strcat (buf, ", LE8");
2748 break;
2749
2750 default:
32ec8896 2751 unknown = TRUE;
3bfcb652
NC
2752 break;
2753 }
3bfcb652
NC
2754 }
2755 break;
3a4a14e9
PB
2756
2757 case EF_ARM_EABI_VER5:
2758 strcat (buf, ", Version5 EABI");
d507cf36
PB
2759 while (e_flags)
2760 {
2761 unsigned flag;
2762
2763 /* Process flags one bit at a time. */
2764 flag = e_flags & - e_flags;
2765 e_flags &= ~ flag;
2766
2767 switch (flag)
2768 {
2769 case EF_ARM_BE8:
2770 strcat (buf, ", BE8");
2771 break;
2772
2773 case EF_ARM_LE8:
2774 strcat (buf, ", LE8");
2775 break;
2776
3bfcb652
NC
2777 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2778 strcat (buf, ", soft-float ABI");
2779 break;
2780
2781 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2782 strcat (buf, ", hard-float ABI");
2783 break;
2784
d507cf36 2785 default:
32ec8896 2786 unknown = TRUE;
d507cf36
PB
2787 break;
2788 }
2789 }
2790 break;
2791
f3485b74 2792 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2793 strcat (buf, ", GNU EABI");
f3485b74
NC
2794 while (e_flags)
2795 {
2796 unsigned flag;
76da6bbe 2797
f3485b74
NC
2798 /* Process flags one bit at a time. */
2799 flag = e_flags & - e_flags;
2800 e_flags &= ~ flag;
76da6bbe 2801
f3485b74
NC
2802 switch (flag)
2803 {
a5bcd848 2804 case EF_ARM_INTERWORK:
f3485b74
NC
2805 strcat (buf, ", interworking enabled");
2806 break;
76da6bbe 2807
a5bcd848 2808 case EF_ARM_APCS_26:
f3485b74
NC
2809 strcat (buf, ", uses APCS/26");
2810 break;
76da6bbe 2811
a5bcd848 2812 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2813 strcat (buf, ", uses APCS/float");
2814 break;
76da6bbe 2815
a5bcd848 2816 case EF_ARM_PIC:
f3485b74
NC
2817 strcat (buf, ", position independent");
2818 break;
76da6bbe 2819
a5bcd848 2820 case EF_ARM_ALIGN8:
f3485b74
NC
2821 strcat (buf, ", 8 bit structure alignment");
2822 break;
76da6bbe 2823
a5bcd848 2824 case EF_ARM_NEW_ABI:
f3485b74
NC
2825 strcat (buf, ", uses new ABI");
2826 break;
76da6bbe 2827
a5bcd848 2828 case EF_ARM_OLD_ABI:
f3485b74
NC
2829 strcat (buf, ", uses old ABI");
2830 break;
76da6bbe 2831
a5bcd848 2832 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2833 strcat (buf, ", software FP");
2834 break;
76da6bbe 2835
90e01f86
ILT
2836 case EF_ARM_VFP_FLOAT:
2837 strcat (buf, ", VFP");
2838 break;
2839
fde78edd
NC
2840 case EF_ARM_MAVERICK_FLOAT:
2841 strcat (buf, ", Maverick FP");
2842 break;
2843
f3485b74 2844 default:
32ec8896 2845 unknown = TRUE;
f3485b74
NC
2846 break;
2847 }
2848 }
2849 }
f3485b74
NC
2850
2851 if (unknown)
2b692964 2852 strcat (buf,_(", <unknown>"));
f3485b74
NC
2853}
2854
343433df
AB
2855static void
2856decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2857{
2858 --size; /* Leave space for null terminator. */
2859
2860 switch (e_flags & EF_AVR_MACH)
2861 {
2862 case E_AVR_MACH_AVR1:
2863 strncat (buf, ", avr:1", size);
2864 break;
2865 case E_AVR_MACH_AVR2:
2866 strncat (buf, ", avr:2", size);
2867 break;
2868 case E_AVR_MACH_AVR25:
2869 strncat (buf, ", avr:25", size);
2870 break;
2871 case E_AVR_MACH_AVR3:
2872 strncat (buf, ", avr:3", size);
2873 break;
2874 case E_AVR_MACH_AVR31:
2875 strncat (buf, ", avr:31", size);
2876 break;
2877 case E_AVR_MACH_AVR35:
2878 strncat (buf, ", avr:35", size);
2879 break;
2880 case E_AVR_MACH_AVR4:
2881 strncat (buf, ", avr:4", size);
2882 break;
2883 case E_AVR_MACH_AVR5:
2884 strncat (buf, ", avr:5", size);
2885 break;
2886 case E_AVR_MACH_AVR51:
2887 strncat (buf, ", avr:51", size);
2888 break;
2889 case E_AVR_MACH_AVR6:
2890 strncat (buf, ", avr:6", size);
2891 break;
2892 case E_AVR_MACH_AVRTINY:
2893 strncat (buf, ", avr:100", size);
2894 break;
2895 case E_AVR_MACH_XMEGA1:
2896 strncat (buf, ", avr:101", size);
2897 break;
2898 case E_AVR_MACH_XMEGA2:
2899 strncat (buf, ", avr:102", size);
2900 break;
2901 case E_AVR_MACH_XMEGA3:
2902 strncat (buf, ", avr:103", size);
2903 break;
2904 case E_AVR_MACH_XMEGA4:
2905 strncat (buf, ", avr:104", size);
2906 break;
2907 case E_AVR_MACH_XMEGA5:
2908 strncat (buf, ", avr:105", size);
2909 break;
2910 case E_AVR_MACH_XMEGA6:
2911 strncat (buf, ", avr:106", size);
2912 break;
2913 case E_AVR_MACH_XMEGA7:
2914 strncat (buf, ", avr:107", size);
2915 break;
2916 default:
2917 strncat (buf, ", avr:<unknown>", size);
2918 break;
2919 }
2920
2921 size -= strlen (buf);
2922 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2923 strncat (buf, ", link-relax", size);
2924}
2925
35c08157
KLC
2926static void
2927decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2928{
2929 unsigned abi;
2930 unsigned arch;
2931 unsigned config;
2932 unsigned version;
32ec8896
NC
2933 bfd_boolean has_fpu = FALSE;
2934 unsigned int r = 0;
35c08157
KLC
2935
2936 static const char *ABI_STRINGS[] =
2937 {
2938 "ABI v0", /* use r5 as return register; only used in N1213HC */
2939 "ABI v1", /* use r0 as return register */
2940 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2941 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2942 "AABI",
2943 "ABI2 FP+"
35c08157
KLC
2944 };
2945 static const char *VER_STRINGS[] =
2946 {
2947 "Andes ELF V1.3 or older",
2948 "Andes ELF V1.3.1",
2949 "Andes ELF V1.4"
2950 };
2951 static const char *ARCH_STRINGS[] =
2952 {
2953 "",
2954 "Andes Star v1.0",
2955 "Andes Star v2.0",
2956 "Andes Star v3.0",
2957 "Andes Star v3.0m"
2958 };
2959
2960 abi = EF_NDS_ABI & e_flags;
2961 arch = EF_NDS_ARCH & e_flags;
2962 config = EF_NDS_INST & e_flags;
2963 version = EF_NDS32_ELF_VERSION & e_flags;
2964
2965 memset (buf, 0, size);
2966
2967 switch (abi)
2968 {
2969 case E_NDS_ABI_V0:
2970 case E_NDS_ABI_V1:
2971 case E_NDS_ABI_V2:
2972 case E_NDS_ABI_V2FP:
2973 case E_NDS_ABI_AABI:
40c7a7cb 2974 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2975 /* In case there are holes in the array. */
2976 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2977 break;
2978
2979 default:
2980 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2981 break;
2982 }
2983
2984 switch (version)
2985 {
2986 case E_NDS32_ELF_VER_1_2:
2987 case E_NDS32_ELF_VER_1_3:
2988 case E_NDS32_ELF_VER_1_4:
2989 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2990 break;
2991
2992 default:
2993 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
2994 break;
2995 }
2996
2997 if (E_NDS_ABI_V0 == abi)
2998 {
2999 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3000 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3001 if (arch == E_NDS_ARCH_STAR_V1_0)
3002 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3003 return;
3004 }
3005
3006 switch (arch)
3007 {
3008 case E_NDS_ARCH_STAR_V1_0:
3009 case E_NDS_ARCH_STAR_V2_0:
3010 case E_NDS_ARCH_STAR_V3_0:
3011 case E_NDS_ARCH_STAR_V3_M:
3012 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3013 break;
3014
3015 default:
3016 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3017 /* ARCH version determines how the e_flags are interpreted.
3018 If it is unknown, we cannot proceed. */
3019 return;
3020 }
3021
3022 /* Newer ABI; Now handle architecture specific flags. */
3023 if (arch == E_NDS_ARCH_STAR_V1_0)
3024 {
3025 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3026 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3027
3028 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3029 r += snprintf (buf + r, size -r, ", MAC");
3030
3031 if (config & E_NDS32_HAS_DIV_INST)
3032 r += snprintf (buf + r, size -r, ", DIV");
3033
3034 if (config & E_NDS32_HAS_16BIT_INST)
3035 r += snprintf (buf + r, size -r, ", 16b");
3036 }
3037 else
3038 {
3039 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3040 {
3041 if (version <= E_NDS32_ELF_VER_1_3)
3042 r += snprintf (buf + r, size -r, ", [B8]");
3043 else
3044 r += snprintf (buf + r, size -r, ", EX9");
3045 }
3046
3047 if (config & E_NDS32_HAS_MAC_DX_INST)
3048 r += snprintf (buf + r, size -r, ", MAC_DX");
3049
3050 if (config & E_NDS32_HAS_DIV_DX_INST)
3051 r += snprintf (buf + r, size -r, ", DIV_DX");
3052
3053 if (config & E_NDS32_HAS_16BIT_INST)
3054 {
3055 if (version <= E_NDS32_ELF_VER_1_3)
3056 r += snprintf (buf + r, size -r, ", 16b");
3057 else
3058 r += snprintf (buf + r, size -r, ", IFC");
3059 }
3060 }
3061
3062 if (config & E_NDS32_HAS_EXT_INST)
3063 r += snprintf (buf + r, size -r, ", PERF1");
3064
3065 if (config & E_NDS32_HAS_EXT2_INST)
3066 r += snprintf (buf + r, size -r, ", PERF2");
3067
3068 if (config & E_NDS32_HAS_FPU_INST)
3069 {
32ec8896 3070 has_fpu = TRUE;
35c08157
KLC
3071 r += snprintf (buf + r, size -r, ", FPU_SP");
3072 }
3073
3074 if (config & E_NDS32_HAS_FPU_DP_INST)
3075 {
32ec8896 3076 has_fpu = TRUE;
35c08157
KLC
3077 r += snprintf (buf + r, size -r, ", FPU_DP");
3078 }
3079
3080 if (config & E_NDS32_HAS_FPU_MAC_INST)
3081 {
32ec8896 3082 has_fpu = TRUE;
35c08157
KLC
3083 r += snprintf (buf + r, size -r, ", FPU_MAC");
3084 }
3085
3086 if (has_fpu)
3087 {
3088 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3089 {
3090 case E_NDS32_FPU_REG_8SP_4DP:
3091 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3092 break;
3093 case E_NDS32_FPU_REG_16SP_8DP:
3094 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3095 break;
3096 case E_NDS32_FPU_REG_32SP_16DP:
3097 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3098 break;
3099 case E_NDS32_FPU_REG_32SP_32DP:
3100 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3101 break;
3102 }
3103 }
3104
3105 if (config & E_NDS32_HAS_AUDIO_INST)
3106 r += snprintf (buf + r, size -r, ", AUDIO");
3107
3108 if (config & E_NDS32_HAS_STRING_INST)
3109 r += snprintf (buf + r, size -r, ", STR");
3110
3111 if (config & E_NDS32_HAS_REDUCED_REGS)
3112 r += snprintf (buf + r, size -r, ", 16REG");
3113
3114 if (config & E_NDS32_HAS_VIDEO_INST)
3115 {
3116 if (version <= E_NDS32_ELF_VER_1_3)
3117 r += snprintf (buf + r, size -r, ", VIDEO");
3118 else
3119 r += snprintf (buf + r, size -r, ", SATURATION");
3120 }
3121
3122 if (config & E_NDS32_HAS_ENCRIPT_INST)
3123 r += snprintf (buf + r, size -r, ", ENCRP");
3124
3125 if (config & E_NDS32_HAS_L2C_INST)
3126 r += snprintf (buf + r, size -r, ", L2C");
3127}
3128
252b5132 3129static char *
dda8d76d 3130get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3131{
b34976b6 3132 static char buf[1024];
252b5132
RH
3133
3134 buf[0] = '\0';
76da6bbe 3135
252b5132
RH
3136 if (e_flags)
3137 {
3138 switch (e_machine)
3139 {
3140 default:
3141 break;
3142
886a2506 3143 case EM_ARC_COMPACT2:
886a2506 3144 case EM_ARC_COMPACT:
a9522a21
AB
3145 decode_ARC_machine_flags (e_flags, e_machine, buf);
3146 break;
886a2506 3147
f3485b74
NC
3148 case EM_ARM:
3149 decode_ARM_machine_flags (e_flags, buf);
3150 break;
76da6bbe 3151
343433df
AB
3152 case EM_AVR:
3153 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3154 break;
3155
781303ce
MF
3156 case EM_BLACKFIN:
3157 if (e_flags & EF_BFIN_PIC)
3158 strcat (buf, ", PIC");
3159
3160 if (e_flags & EF_BFIN_FDPIC)
3161 strcat (buf, ", FDPIC");
3162
3163 if (e_flags & EF_BFIN_CODE_IN_L1)
3164 strcat (buf, ", code in L1");
3165
3166 if (e_flags & EF_BFIN_DATA_IN_L1)
3167 strcat (buf, ", data in L1");
3168
3169 break;
3170
ec2dfb42
AO
3171 case EM_CYGNUS_FRV:
3172 switch (e_flags & EF_FRV_CPU_MASK)
3173 {
3174 case EF_FRV_CPU_GENERIC:
3175 break;
3176
3177 default:
3178 strcat (buf, ", fr???");
3179 break;
57346661 3180
ec2dfb42
AO
3181 case EF_FRV_CPU_FR300:
3182 strcat (buf, ", fr300");
3183 break;
3184
3185 case EF_FRV_CPU_FR400:
3186 strcat (buf, ", fr400");
3187 break;
3188 case EF_FRV_CPU_FR405:
3189 strcat (buf, ", fr405");
3190 break;
3191
3192 case EF_FRV_CPU_FR450:
3193 strcat (buf, ", fr450");
3194 break;
3195
3196 case EF_FRV_CPU_FR500:
3197 strcat (buf, ", fr500");
3198 break;
3199 case EF_FRV_CPU_FR550:
3200 strcat (buf, ", fr550");
3201 break;
3202
3203 case EF_FRV_CPU_SIMPLE:
3204 strcat (buf, ", simple");
3205 break;
3206 case EF_FRV_CPU_TOMCAT:
3207 strcat (buf, ", tomcat");
3208 break;
3209 }
1c877e87 3210 break;
ec2dfb42 3211
53c7db4b 3212 case EM_68K:
425c6cb0 3213 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3214 strcat (buf, ", m68000");
425c6cb0 3215 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3216 strcat (buf, ", cpu32");
3217 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3218 strcat (buf, ", fido_a");
425c6cb0 3219 else
266abb8f 3220 {
2cf0635d
NC
3221 char const * isa = _("unknown");
3222 char const * mac = _("unknown mac");
3223 char const * additional = NULL;
0112cd26 3224
c694fd50 3225 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3226 {
c694fd50 3227 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3228 isa = "A";
3229 additional = ", nodiv";
3230 break;
c694fd50 3231 case EF_M68K_CF_ISA_A:
266abb8f
NS
3232 isa = "A";
3233 break;
c694fd50 3234 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3235 isa = "A+";
3236 break;
c694fd50 3237 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3238 isa = "B";
3239 additional = ", nousp";
3240 break;
c694fd50 3241 case EF_M68K_CF_ISA_B:
266abb8f
NS
3242 isa = "B";
3243 break;
f608cd77
NS
3244 case EF_M68K_CF_ISA_C:
3245 isa = "C";
3246 break;
3247 case EF_M68K_CF_ISA_C_NODIV:
3248 isa = "C";
3249 additional = ", nodiv";
3250 break;
266abb8f
NS
3251 }
3252 strcat (buf, ", cf, isa ");
3253 strcat (buf, isa);
0b2e31dc
NS
3254 if (additional)
3255 strcat (buf, additional);
c694fd50 3256 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3257 strcat (buf, ", float");
c694fd50 3258 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3259 {
3260 case 0:
3261 mac = NULL;
3262 break;
c694fd50 3263 case EF_M68K_CF_MAC:
266abb8f
NS
3264 mac = "mac";
3265 break;
c694fd50 3266 case EF_M68K_CF_EMAC:
266abb8f
NS
3267 mac = "emac";
3268 break;
f608cd77
NS
3269 case EF_M68K_CF_EMAC_B:
3270 mac = "emac_b";
3271 break;
266abb8f
NS
3272 }
3273 if (mac)
3274 {
3275 strcat (buf, ", ");
3276 strcat (buf, mac);
3277 }
266abb8f 3278 }
53c7db4b 3279 break;
33c63f9d 3280
153a2776
NC
3281 case EM_CYGNUS_MEP:
3282 switch (e_flags & EF_MEP_CPU_MASK)
3283 {
3284 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3285 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3286 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3287 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3288 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3289 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3290 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3291 }
3292
3293 switch (e_flags & EF_MEP_COP_MASK)
3294 {
3295 case EF_MEP_COP_NONE: break;
3296 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3297 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3298 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3299 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3300 default: strcat (buf, _("<unknown MeP copro type>")); break;
3301 }
3302
3303 if (e_flags & EF_MEP_LIBRARY)
3304 strcat (buf, ", Built for Library");
3305
3306 if (e_flags & EF_MEP_INDEX_MASK)
3307 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3308 e_flags & EF_MEP_INDEX_MASK);
3309
3310 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3311 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3312 e_flags & ~ EF_MEP_ALL_FLAGS);
3313 break;
3314
252b5132
RH
3315 case EM_PPC:
3316 if (e_flags & EF_PPC_EMB)
3317 strcat (buf, ", emb");
3318
3319 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3320 strcat (buf, _(", relocatable"));
252b5132
RH
3321
3322 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3323 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3324 break;
3325
ee67d69a
AM
3326 case EM_PPC64:
3327 if (e_flags & EF_PPC64_ABI)
3328 {
3329 char abi[] = ", abiv0";
3330
3331 abi[6] += e_flags & EF_PPC64_ABI;
3332 strcat (buf, abi);
3333 }
3334 break;
3335
708e2187
NC
3336 case EM_V800:
3337 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3338 strcat (buf, ", RH850 ABI");
0b4362b0 3339
708e2187
NC
3340 if (e_flags & EF_V800_850E3)
3341 strcat (buf, ", V3 architecture");
3342
3343 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3344 strcat (buf, ", FPU not used");
3345
3346 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3347 strcat (buf, ", regmode: COMMON");
3348
3349 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3350 strcat (buf, ", r4 not used");
3351
3352 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3353 strcat (buf, ", r30 not used");
3354
3355 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3356 strcat (buf, ", r5 not used");
3357
3358 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3359 strcat (buf, ", r2 not used");
3360
3361 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3362 {
3363 switch (e_flags & - e_flags)
3364 {
3365 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3366 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3367 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3368 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3369 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3370 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3371 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3372 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3373 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3374 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3375 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3376 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3377 default: break;
3378 }
3379 }
3380 break;
3381
2b0337b0 3382 case EM_V850:
252b5132
RH
3383 case EM_CYGNUS_V850:
3384 switch (e_flags & EF_V850_ARCH)
3385 {
78c8d46c
NC
3386 case E_V850E3V5_ARCH:
3387 strcat (buf, ", v850e3v5");
3388 break;
1cd986c5
NC
3389 case E_V850E2V3_ARCH:
3390 strcat (buf, ", v850e2v3");
3391 break;
3392 case E_V850E2_ARCH:
3393 strcat (buf, ", v850e2");
3394 break;
3395 case E_V850E1_ARCH:
3396 strcat (buf, ", v850e1");
8ad30312 3397 break;
252b5132
RH
3398 case E_V850E_ARCH:
3399 strcat (buf, ", v850e");
3400 break;
252b5132
RH
3401 case E_V850_ARCH:
3402 strcat (buf, ", v850");
3403 break;
3404 default:
2b692964 3405 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3406 break;
3407 }
3408 break;
3409
2b0337b0 3410 case EM_M32R:
252b5132
RH
3411 case EM_CYGNUS_M32R:
3412 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3413 strcat (buf, ", m32r");
252b5132
RH
3414 break;
3415
3416 case EM_MIPS:
4fe85591 3417 case EM_MIPS_RS3_LE:
252b5132
RH
3418 if (e_flags & EF_MIPS_NOREORDER)
3419 strcat (buf, ", noreorder");
3420
3421 if (e_flags & EF_MIPS_PIC)
3422 strcat (buf, ", pic");
3423
3424 if (e_flags & EF_MIPS_CPIC)
3425 strcat (buf, ", cpic");
3426
d1bdd336
TS
3427 if (e_flags & EF_MIPS_UCODE)
3428 strcat (buf, ", ugen_reserved");
3429
252b5132
RH
3430 if (e_flags & EF_MIPS_ABI2)
3431 strcat (buf, ", abi2");
3432
43521d43
TS
3433 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3434 strcat (buf, ", odk first");
3435
a5d22d2a
TS
3436 if (e_flags & EF_MIPS_32BITMODE)
3437 strcat (buf, ", 32bitmode");
3438
ba92f887
MR
3439 if (e_flags & EF_MIPS_NAN2008)
3440 strcat (buf, ", nan2008");
3441
fef1b0b3
SE
3442 if (e_flags & EF_MIPS_FP64)
3443 strcat (buf, ", fp64");
3444
156c2f8b
NC
3445 switch ((e_flags & EF_MIPS_MACH))
3446 {
3447 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3448 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3449 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3450 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3451 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3452 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3453 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3454 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3455 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3456 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3457 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3458 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3459 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3460 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3461 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3462 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3463 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3464 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3465 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3466 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3467 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3468 case 0:
3469 /* We simply ignore the field in this case to avoid confusion:
3470 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3471 extension. */
3472 break;
2b692964 3473 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3474 }
43521d43
TS
3475
3476 switch ((e_flags & EF_MIPS_ABI))
3477 {
3478 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3479 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3480 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3481 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3482 case 0:
3483 /* We simply ignore the field in this case to avoid confusion:
3484 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3485 This means it is likely to be an o32 file, but not for
3486 sure. */
3487 break;
2b692964 3488 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3489 }
3490
3491 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3492 strcat (buf, ", mdmx");
3493
3494 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3495 strcat (buf, ", mips16");
3496
df58fc94
RS
3497 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3498 strcat (buf, ", micromips");
3499
43521d43
TS
3500 switch ((e_flags & EF_MIPS_ARCH))
3501 {
3502 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3503 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3504 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3505 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3506 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3507 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3508 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3509 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3510 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3511 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3512 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3513 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3514 }
252b5132 3515 break;
351b4b40 3516
35c08157
KLC
3517 case EM_NDS32:
3518 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3519 break;
3520
fe944acf
FT
3521 case EM_NFP:
3522 switch (EF_NFP_MACH (e_flags))
3523 {
3524 case E_NFP_MACH_3200:
3525 strcat (buf, ", NFP-32xx");
3526 break;
3527 case E_NFP_MACH_6000:
3528 strcat (buf, ", NFP-6xxx");
3529 break;
3530 }
3531 break;
3532
e23eba97
NC
3533 case EM_RISCV:
3534 if (e_flags & EF_RISCV_RVC)
3535 strcat (buf, ", RVC");
2922d21d 3536
7f999549
JW
3537 if (e_flags & EF_RISCV_RVE)
3538 strcat (buf, ", RVE");
3539
2922d21d
AW
3540 switch (e_flags & EF_RISCV_FLOAT_ABI)
3541 {
3542 case EF_RISCV_FLOAT_ABI_SOFT:
3543 strcat (buf, ", soft-float ABI");
3544 break;
3545
3546 case EF_RISCV_FLOAT_ABI_SINGLE:
3547 strcat (buf, ", single-float ABI");
3548 break;
3549
3550 case EF_RISCV_FLOAT_ABI_DOUBLE:
3551 strcat (buf, ", double-float ABI");
3552 break;
3553
3554 case EF_RISCV_FLOAT_ABI_QUAD:
3555 strcat (buf, ", quad-float ABI");
3556 break;
3557 }
e23eba97
NC
3558 break;
3559
ccde1100
AO
3560 case EM_SH:
3561 switch ((e_flags & EF_SH_MACH_MASK))
3562 {
3563 case EF_SH1: strcat (buf, ", sh1"); break;
3564 case EF_SH2: strcat (buf, ", sh2"); break;
3565 case EF_SH3: strcat (buf, ", sh3"); break;
3566 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3567 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3568 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3569 case EF_SH3E: strcat (buf, ", sh3e"); break;
3570 case EF_SH4: strcat (buf, ", sh4"); break;
3571 case EF_SH5: strcat (buf, ", sh5"); break;
3572 case EF_SH2E: strcat (buf, ", sh2e"); break;
3573 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3574 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3575 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3576 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3577 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3578 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3579 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3580 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3581 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3582 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3583 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3584 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3585 }
3586
cec6a5b8
MR
3587 if (e_flags & EF_SH_PIC)
3588 strcat (buf, ", pic");
3589
3590 if (e_flags & EF_SH_FDPIC)
3591 strcat (buf, ", fdpic");
ccde1100 3592 break;
948f632f 3593
73589c9d
CS
3594 case EM_OR1K:
3595 if (e_flags & EF_OR1K_NODELAY)
3596 strcat (buf, ", no delay");
3597 break;
57346661 3598
351b4b40
RH
3599 case EM_SPARCV9:
3600 if (e_flags & EF_SPARC_32PLUS)
3601 strcat (buf, ", v8+");
3602
3603 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3604 strcat (buf, ", ultrasparcI");
3605
3606 if (e_flags & EF_SPARC_SUN_US3)
3607 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3608
3609 if (e_flags & EF_SPARC_HAL_R1)
3610 strcat (buf, ", halr1");
3611
3612 if (e_flags & EF_SPARC_LEDATA)
3613 strcat (buf, ", ledata");
3614
3615 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3616 strcat (buf, ", tso");
3617
3618 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3619 strcat (buf, ", pso");
3620
3621 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3622 strcat (buf, ", rmo");
3623 break;
7d466069 3624
103f02d3
UD
3625 case EM_PARISC:
3626 switch (e_flags & EF_PARISC_ARCH)
3627 {
3628 case EFA_PARISC_1_0:
3629 strcpy (buf, ", PA-RISC 1.0");
3630 break;
3631 case EFA_PARISC_1_1:
3632 strcpy (buf, ", PA-RISC 1.1");
3633 break;
3634 case EFA_PARISC_2_0:
3635 strcpy (buf, ", PA-RISC 2.0");
3636 break;
3637 default:
3638 break;
3639 }
3640 if (e_flags & EF_PARISC_TRAPNIL)
3641 strcat (buf, ", trapnil");
3642 if (e_flags & EF_PARISC_EXT)
3643 strcat (buf, ", ext");
3644 if (e_flags & EF_PARISC_LSB)
3645 strcat (buf, ", lsb");
3646 if (e_flags & EF_PARISC_WIDE)
3647 strcat (buf, ", wide");
3648 if (e_flags & EF_PARISC_NO_KABP)
3649 strcat (buf, ", no kabp");
3650 if (e_flags & EF_PARISC_LAZYSWAP)
3651 strcat (buf, ", lazyswap");
30800947 3652 break;
76da6bbe 3653
7d466069 3654 case EM_PJ:
2b0337b0 3655 case EM_PJ_OLD:
7d466069
ILT
3656 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3657 strcat (buf, ", new calling convention");
3658
3659 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3660 strcat (buf, ", gnu calling convention");
3661 break;
4d6ed7c8
NC
3662
3663 case EM_IA_64:
3664 if ((e_flags & EF_IA_64_ABI64))
3665 strcat (buf, ", 64-bit");
3666 else
3667 strcat (buf, ", 32-bit");
3668 if ((e_flags & EF_IA_64_REDUCEDFP))
3669 strcat (buf, ", reduced fp model");
3670 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3671 strcat (buf, ", no function descriptors, constant gp");
3672 else if ((e_flags & EF_IA_64_CONS_GP))
3673 strcat (buf, ", constant gp");
3674 if ((e_flags & EF_IA_64_ABSOLUTE))
3675 strcat (buf, ", absolute");
dda8d76d 3676 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3677 {
3678 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3679 strcat (buf, ", vms_linkages");
3680 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3681 {
3682 case EF_IA_64_VMS_COMCOD_SUCCESS:
3683 break;
3684 case EF_IA_64_VMS_COMCOD_WARNING:
3685 strcat (buf, ", warning");
3686 break;
3687 case EF_IA_64_VMS_COMCOD_ERROR:
3688 strcat (buf, ", error");
3689 break;
3690 case EF_IA_64_VMS_COMCOD_ABORT:
3691 strcat (buf, ", abort");
3692 break;
3693 default:
bee0ee85
NC
3694 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3695 e_flags & EF_IA_64_VMS_COMCOD);
3696 strcat (buf, ", <unknown>");
28f997cf
TG
3697 }
3698 }
4d6ed7c8 3699 break;
179d3252
JT
3700
3701 case EM_VAX:
3702 if ((e_flags & EF_VAX_NONPIC))
3703 strcat (buf, ", non-PIC");
3704 if ((e_flags & EF_VAX_DFLOAT))
3705 strcat (buf, ", D-Float");
3706 if ((e_flags & EF_VAX_GFLOAT))
3707 strcat (buf, ", G-Float");
3708 break;
c7927a3c 3709
619ed720
EB
3710 case EM_VISIUM:
3711 if (e_flags & EF_VISIUM_ARCH_MCM)
3712 strcat (buf, ", mcm");
3713 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3714 strcat (buf, ", mcm24");
3715 if (e_flags & EF_VISIUM_ARCH_GR6)
3716 strcat (buf, ", gr6");
3717 break;
3718
4046d87a 3719 case EM_RL78:
1740ba0c
NC
3720 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3721 {
3722 case E_FLAG_RL78_ANY_CPU: break;
3723 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3724 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3725 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3726 }
856ea05c
KP
3727 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3728 strcat (buf, ", 64-bit doubles");
4046d87a 3729 break;
0b4362b0 3730
c7927a3c
NC
3731 case EM_RX:
3732 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3733 strcat (buf, ", 64-bit doubles");
3734 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3735 strcat (buf, ", dsp");
d4cb0ea0 3736 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3737 strcat (buf, ", pid");
708e2187
NC
3738 if (e_flags & E_FLAG_RX_ABI)
3739 strcat (buf, ", RX ABI");
3525236c
NC
3740 if (e_flags & E_FLAG_RX_SINSNS_SET)
3741 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3742 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3743 if (e_flags & E_FLAG_RX_V2)
3744 strcat (buf, ", V2");
f87673e0
YS
3745 if (e_flags & E_FLAG_RX_V3)
3746 strcat (buf, ", V3");
d4cb0ea0 3747 break;
55786da2
AK
3748
3749 case EM_S390:
3750 if (e_flags & EF_S390_HIGH_GPRS)
3751 strcat (buf, ", highgprs");
d4cb0ea0 3752 break;
40b36596
JM
3753
3754 case EM_TI_C6000:
3755 if ((e_flags & EF_C6000_REL))
3756 strcat (buf, ", relocatable module");
d4cb0ea0 3757 break;
13761a11
NC
3758
3759 case EM_MSP430:
3760 strcat (buf, _(": architecture variant: "));
3761 switch (e_flags & EF_MSP430_MACH)
3762 {
3763 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3764 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3765 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3766 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3767 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3768 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3769 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3770 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3771 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3772 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3773 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3774 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3775 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3776 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3777 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3778 default:
3779 strcat (buf, _(": unknown")); break;
3780 }
3781
3782 if (e_flags & ~ EF_MSP430_MACH)
3783 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
3784 break;
3785
3786 case EM_Z80:
3787 switch (e_flags & EF_Z80_MACH_MSK)
3788 {
3789 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
3790 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
3791 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
3792 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
3793 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
3794 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 3795 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
3796 default:
3797 strcat (buf, _(", unknown")); break;
3798 }
3799 break;
252b5132
RH
3800 }
3801 }
3802
3803 return buf;
3804}
3805
252b5132 3806static const char *
dda8d76d 3807get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3808{
3809 static char buff[32];
3810
3811 switch (osabi)
3812 {
3813 case ELFOSABI_NONE: return "UNIX - System V";
3814 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3815 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3816 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3817 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3818 case ELFOSABI_AIX: return "UNIX - AIX";
3819 case ELFOSABI_IRIX: return "UNIX - IRIX";
3820 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3821 case ELFOSABI_TRU64: return "UNIX - TRU64";
3822 case ELFOSABI_MODESTO: return "Novell - Modesto";
3823 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3824 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3825 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3826 case ELFOSABI_AROS: return "AROS";
11636f9e 3827 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3828 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3829 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3830 default:
40b36596 3831 if (osabi >= 64)
dda8d76d 3832 switch (filedata->file_header.e_machine)
40b36596
JM
3833 {
3834 case EM_ARM:
3835 switch (osabi)
3836 {
3837 case ELFOSABI_ARM: return "ARM";
18a20338 3838 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3839 default:
3840 break;
3841 }
3842 break;
3843
3844 case EM_MSP430:
3845 case EM_MSP430_OLD:
619ed720 3846 case EM_VISIUM:
40b36596
JM
3847 switch (osabi)
3848 {
3849 case ELFOSABI_STANDALONE: return _("Standalone App");
3850 default:
3851 break;
3852 }
3853 break;
3854
3855 case EM_TI_C6000:
3856 switch (osabi)
3857 {
3858 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3859 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3860 default:
3861 break;
3862 }
3863 break;
3864
3865 default:
3866 break;
3867 }
e9e44622 3868 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3869 return buff;
3870 }
3871}
3872
a06ea964
NC
3873static const char *
3874get_aarch64_segment_type (unsigned long type)
3875{
3876 switch (type)
3877 {
32ec8896
NC
3878 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3879 default: return NULL;
a06ea964 3880 }
a06ea964
NC
3881}
3882
b294bdf8
MM
3883static const char *
3884get_arm_segment_type (unsigned long type)
3885{
3886 switch (type)
3887 {
32ec8896
NC
3888 case PT_ARM_EXIDX: return "EXIDX";
3889 default: return NULL;
b294bdf8 3890 }
b294bdf8
MM
3891}
3892
b4cbbe8f
AK
3893static const char *
3894get_s390_segment_type (unsigned long type)
3895{
3896 switch (type)
3897 {
3898 case PT_S390_PGSTE: return "S390_PGSTE";
3899 default: return NULL;
3900 }
3901}
3902
d3ba0551
AM
3903static const char *
3904get_mips_segment_type (unsigned long type)
252b5132
RH
3905{
3906 switch (type)
3907 {
32ec8896
NC
3908 case PT_MIPS_REGINFO: return "REGINFO";
3909 case PT_MIPS_RTPROC: return "RTPROC";
3910 case PT_MIPS_OPTIONS: return "OPTIONS";
3911 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3912 default: return NULL;
252b5132 3913 }
252b5132
RH
3914}
3915
103f02d3 3916static const char *
d3ba0551 3917get_parisc_segment_type (unsigned long type)
103f02d3
UD
3918{
3919 switch (type)
3920 {
103f02d3
UD
3921 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3922 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3923 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3924 default: return NULL;
103f02d3 3925 }
103f02d3
UD
3926}
3927
4d6ed7c8 3928static const char *
d3ba0551 3929get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3930{
3931 switch (type)
3932 {
3933 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3934 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 3935 default: return NULL;
4d6ed7c8 3936 }
4d6ed7c8
NC
3937}
3938
40b36596
JM
3939static const char *
3940get_tic6x_segment_type (unsigned long type)
3941{
3942 switch (type)
3943 {
32ec8896
NC
3944 case PT_C6000_PHATTR: return "C6000_PHATTR";
3945 default: return NULL;
40b36596 3946 }
40b36596
JM
3947}
3948
df3a023b
AM
3949static const char *
3950get_hpux_segment_type (unsigned long type, unsigned e_machine)
3951{
3952 if (e_machine == EM_PARISC)
3953 switch (type)
3954 {
3955 case PT_HP_TLS: return "HP_TLS";
3956 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3957 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3958 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3959 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3960 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3961 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3962 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3963 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3964 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3965 case PT_HP_PARALLEL: return "HP_PARALLEL";
3966 case PT_HP_FASTBIND: return "HP_FASTBIND";
3967 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3968 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3969 case PT_HP_STACK: return "HP_STACK";
3970 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
3971 default: return NULL;
3972 }
3973
3974 if (e_machine == EM_IA_64)
3975 switch (type)
3976 {
3977 case PT_HP_TLS: return "HP_TLS";
3978 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3979 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3980 case PT_IA_64_HP_STACK: return "HP_STACK";
3981 default: return NULL;
3982 }
3983
3984 return NULL;
3985}
3986
5522f910
NC
3987static const char *
3988get_solaris_segment_type (unsigned long type)
3989{
3990 switch (type)
3991 {
3992 case 0x6464e550: return "PT_SUNW_UNWIND";
3993 case 0x6474e550: return "PT_SUNW_EH_FRAME";
3994 case 0x6ffffff7: return "PT_LOSUNW";
3995 case 0x6ffffffa: return "PT_SUNWBSS";
3996 case 0x6ffffffb: return "PT_SUNWSTACK";
3997 case 0x6ffffffc: return "PT_SUNWDTRACE";
3998 case 0x6ffffffd: return "PT_SUNWCAP";
3999 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4000 default: return NULL;
5522f910
NC
4001 }
4002}
4003
252b5132 4004static const char *
dda8d76d 4005get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4006{
b34976b6 4007 static char buff[32];
252b5132
RH
4008
4009 switch (p_type)
4010 {
b34976b6
AM
4011 case PT_NULL: return "NULL";
4012 case PT_LOAD: return "LOAD";
252b5132 4013 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4014 case PT_INTERP: return "INTERP";
4015 case PT_NOTE: return "NOTE";
4016 case PT_SHLIB: return "SHLIB";
4017 case PT_PHDR: return "PHDR";
13ae64f3 4018 case PT_TLS: return "TLS";
32ec8896 4019 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4020 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4021 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4022 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4023
252b5132 4024 default:
df3a023b 4025 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4026 {
2cf0635d 4027 const char * result;
103f02d3 4028
dda8d76d 4029 switch (filedata->file_header.e_machine)
252b5132 4030 {
a06ea964
NC
4031 case EM_AARCH64:
4032 result = get_aarch64_segment_type (p_type);
4033 break;
b294bdf8
MM
4034 case EM_ARM:
4035 result = get_arm_segment_type (p_type);
4036 break;
252b5132 4037 case EM_MIPS:
4fe85591 4038 case EM_MIPS_RS3_LE:
252b5132
RH
4039 result = get_mips_segment_type (p_type);
4040 break;
103f02d3
UD
4041 case EM_PARISC:
4042 result = get_parisc_segment_type (p_type);
4043 break;
4d6ed7c8
NC
4044 case EM_IA_64:
4045 result = get_ia64_segment_type (p_type);
4046 break;
40b36596
JM
4047 case EM_TI_C6000:
4048 result = get_tic6x_segment_type (p_type);
4049 break;
b4cbbe8f
AK
4050 case EM_S390:
4051 case EM_S390_OLD:
4052 result = get_s390_segment_type (p_type);
4053 break;
252b5132
RH
4054 default:
4055 result = NULL;
4056 break;
4057 }
103f02d3 4058
252b5132
RH
4059 if (result != NULL)
4060 return result;
103f02d3 4061
1a9ccd70 4062 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4063 }
4064 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4065 {
df3a023b 4066 const char * result = NULL;
103f02d3 4067
df3a023b 4068 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4069 {
df3a023b
AM
4070 case ELFOSABI_GNU:
4071 case ELFOSABI_FREEBSD:
4072 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4073 {
4074 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4075 result = buff;
4076 }
103f02d3 4077 break;
df3a023b
AM
4078 case ELFOSABI_HPUX:
4079 result = get_hpux_segment_type (p_type,
4080 filedata->file_header.e_machine);
4081 break;
4082 case ELFOSABI_SOLARIS:
4083 result = get_solaris_segment_type (p_type);
00428cca 4084 break;
103f02d3 4085 default:
103f02d3
UD
4086 break;
4087 }
103f02d3
UD
4088 if (result != NULL)
4089 return result;
4090
1a9ccd70 4091 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4092 }
252b5132 4093 else
e9e44622 4094 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4095
4096 return buff;
4097 }
4098}
4099
53a346d8
CZ
4100static const char *
4101get_arc_section_type_name (unsigned int sh_type)
4102{
4103 switch (sh_type)
4104 {
4105 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4106 default:
4107 break;
4108 }
4109 return NULL;
4110}
4111
252b5132 4112static const char *
d3ba0551 4113get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4114{
4115 switch (sh_type)
4116 {
b34976b6
AM
4117 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4118 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4119 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4120 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4121 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4122 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4123 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4124 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4125 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4126 case SHT_MIPS_RELD: return "MIPS_RELD";
4127 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4128 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4129 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4130 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4131 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4132 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4133 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4134 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4135 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4136 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4137 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4138 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4139 case SHT_MIPS_LINE: return "MIPS_LINE";
4140 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4141 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4142 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4143 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4144 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4145 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4146 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4147 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4148 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4149 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4150 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4151 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4152 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4153 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4154 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4155 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4156 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4157 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4158 default:
4159 break;
4160 }
4161 return NULL;
4162}
4163
103f02d3 4164static const char *
d3ba0551 4165get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4166{
4167 switch (sh_type)
4168 {
4169 case SHT_PARISC_EXT: return "PARISC_EXT";
4170 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4171 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4172 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4173 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4174 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4175 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4176 default: return NULL;
103f02d3 4177 }
103f02d3
UD
4178}
4179
4d6ed7c8 4180static const char *
dda8d76d 4181get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4182{
18bd398b 4183 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4184 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4185 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4186
4d6ed7c8
NC
4187 switch (sh_type)
4188 {
148b93f2
NC
4189 case SHT_IA_64_EXT: return "IA_64_EXT";
4190 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4191 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4192 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4193 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4194 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4195 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4196 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4197 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4198 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4199 default:
4200 break;
4201 }
4202 return NULL;
4203}
4204
d2b2c203
DJ
4205static const char *
4206get_x86_64_section_type_name (unsigned int sh_type)
4207{
4208 switch (sh_type)
4209 {
4210 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4211 default: return NULL;
d2b2c203 4212 }
d2b2c203
DJ
4213}
4214
a06ea964
NC
4215static const char *
4216get_aarch64_section_type_name (unsigned int sh_type)
4217{
4218 switch (sh_type)
4219 {
32ec8896
NC
4220 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4221 default: return NULL;
a06ea964 4222 }
a06ea964
NC
4223}
4224
40a18ebd
NC
4225static const char *
4226get_arm_section_type_name (unsigned int sh_type)
4227{
4228 switch (sh_type)
4229 {
7f6fed87
NC
4230 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4231 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4232 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4233 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4234 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4235 default: return NULL;
40a18ebd 4236 }
40a18ebd
NC
4237}
4238
40b36596
JM
4239static const char *
4240get_tic6x_section_type_name (unsigned int sh_type)
4241{
4242 switch (sh_type)
4243 {
32ec8896
NC
4244 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4245 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4246 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4247 case SHT_TI_ICODE: return "TI_ICODE";
4248 case SHT_TI_XREF: return "TI_XREF";
4249 case SHT_TI_HANDLER: return "TI_HANDLER";
4250 case SHT_TI_INITINFO: return "TI_INITINFO";
4251 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4252 default: return NULL;
40b36596 4253 }
40b36596
JM
4254}
4255
13761a11
NC
4256static const char *
4257get_msp430x_section_type_name (unsigned int sh_type)
4258{
4259 switch (sh_type)
4260 {
32ec8896
NC
4261 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4262 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4263 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4264 default: return NULL;
13761a11
NC
4265 }
4266}
4267
fe944acf
FT
4268static const char *
4269get_nfp_section_type_name (unsigned int sh_type)
4270{
4271 switch (sh_type)
4272 {
4273 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4274 case SHT_NFP_INITREG: return "NFP_INITREG";
4275 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4276 default: return NULL;
4277 }
4278}
4279
685080f2
NC
4280static const char *
4281get_v850_section_type_name (unsigned int sh_type)
4282{
4283 switch (sh_type)
4284 {
32ec8896
NC
4285 case SHT_V850_SCOMMON: return "V850 Small Common";
4286 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4287 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4288 case SHT_RENESAS_IOP: return "RENESAS IOP";
4289 case SHT_RENESAS_INFO: return "RENESAS INFO";
4290 default: return NULL;
685080f2
NC
4291 }
4292}
4293
2dc8dd17
JW
4294static const char *
4295get_riscv_section_type_name (unsigned int sh_type)
4296{
4297 switch (sh_type)
4298 {
4299 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4300 default: return NULL;
4301 }
4302}
4303
252b5132 4304static const char *
dda8d76d 4305get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4306{
b34976b6 4307 static char buff[32];
9fb71ee4 4308 const char * result;
252b5132
RH
4309
4310 switch (sh_type)
4311 {
4312 case SHT_NULL: return "NULL";
4313 case SHT_PROGBITS: return "PROGBITS";
4314 case SHT_SYMTAB: return "SYMTAB";
4315 case SHT_STRTAB: return "STRTAB";
4316 case SHT_RELA: return "RELA";
4317 case SHT_HASH: return "HASH";
4318 case SHT_DYNAMIC: return "DYNAMIC";
4319 case SHT_NOTE: return "NOTE";
4320 case SHT_NOBITS: return "NOBITS";
4321 case SHT_REL: return "REL";
4322 case SHT_SHLIB: return "SHLIB";
4323 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4324 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4325 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4326 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4327 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4328 case SHT_GROUP: return "GROUP";
67ce483b 4329 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4330 case SHT_GNU_verdef: return "VERDEF";
4331 case SHT_GNU_verneed: return "VERNEED";
4332 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4333 case 0x6ffffff0: return "VERSYM";
4334 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4335 case 0x7ffffffd: return "AUXILIARY";
4336 case 0x7fffffff: return "FILTER";
047b2264 4337 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4338
4339 default:
4340 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4341 {
dda8d76d 4342 switch (filedata->file_header.e_machine)
252b5132 4343 {
53a346d8
CZ
4344 case EM_ARC:
4345 case EM_ARC_COMPACT:
4346 case EM_ARC_COMPACT2:
4347 result = get_arc_section_type_name (sh_type);
4348 break;
252b5132 4349 case EM_MIPS:
4fe85591 4350 case EM_MIPS_RS3_LE:
252b5132
RH
4351 result = get_mips_section_type_name (sh_type);
4352 break;
103f02d3
UD
4353 case EM_PARISC:
4354 result = get_parisc_section_type_name (sh_type);
4355 break;
4d6ed7c8 4356 case EM_IA_64:
dda8d76d 4357 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4358 break;
d2b2c203 4359 case EM_X86_64:
8a9036a4 4360 case EM_L1OM:
7a9068fe 4361 case EM_K1OM:
d2b2c203
DJ
4362 result = get_x86_64_section_type_name (sh_type);
4363 break;
a06ea964
NC
4364 case EM_AARCH64:
4365 result = get_aarch64_section_type_name (sh_type);
4366 break;
40a18ebd
NC
4367 case EM_ARM:
4368 result = get_arm_section_type_name (sh_type);
4369 break;
40b36596
JM
4370 case EM_TI_C6000:
4371 result = get_tic6x_section_type_name (sh_type);
4372 break;
13761a11
NC
4373 case EM_MSP430:
4374 result = get_msp430x_section_type_name (sh_type);
4375 break;
fe944acf
FT
4376 case EM_NFP:
4377 result = get_nfp_section_type_name (sh_type);
4378 break;
685080f2
NC
4379 case EM_V800:
4380 case EM_V850:
4381 case EM_CYGNUS_V850:
4382 result = get_v850_section_type_name (sh_type);
4383 break;
2dc8dd17
JW
4384 case EM_RISCV:
4385 result = get_riscv_section_type_name (sh_type);
4386 break;
252b5132
RH
4387 default:
4388 result = NULL;
4389 break;
4390 }
4391
4392 if (result != NULL)
4393 return result;
4394
9fb71ee4 4395 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4396 }
4397 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4398 {
dda8d76d 4399 switch (filedata->file_header.e_machine)
148b93f2
NC
4400 {
4401 case EM_IA_64:
dda8d76d 4402 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4403 break;
4404 default:
dda8d76d 4405 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4406 result = get_solaris_section_type (sh_type);
4407 else
1b4b80bf
NC
4408 {
4409 switch (sh_type)
4410 {
4411 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4412 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4413 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4414 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4415 default:
4416 result = NULL;
4417 break;
4418 }
4419 }
148b93f2
NC
4420 break;
4421 }
4422
4423 if (result != NULL)
4424 return result;
4425
9fb71ee4 4426 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4427 }
252b5132 4428 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4429 {
dda8d76d 4430 switch (filedata->file_header.e_machine)
685080f2
NC
4431 {
4432 case EM_V800:
4433 case EM_V850:
4434 case EM_CYGNUS_V850:
9fb71ee4 4435 result = get_v850_section_type_name (sh_type);
a9fb83be 4436 break;
685080f2 4437 default:
9fb71ee4 4438 result = NULL;
685080f2
NC
4439 break;
4440 }
4441
9fb71ee4
NC
4442 if (result != NULL)
4443 return result;
4444
4445 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4446 }
252b5132 4447 else
a7dbfd1c
NC
4448 /* This message is probably going to be displayed in a 15
4449 character wide field, so put the hex value first. */
4450 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4451
252b5132
RH
4452 return buff;
4453 }
4454}
4455
2979dc34 4456#define OPTION_DEBUG_DUMP 512
2c610e4b 4457#define OPTION_DYN_SYMS 513
fd2f0033
TT
4458#define OPTION_DWARF_DEPTH 514
4459#define OPTION_DWARF_START 515
4723351a 4460#define OPTION_DWARF_CHECK 516
7d9813f1
NA
4461#define OPTION_CTF_DUMP 517
4462#define OPTION_CTF_PARENT 518
4463#define OPTION_CTF_SYMBOLS 519
4464#define OPTION_CTF_STRINGS 520
2979dc34 4465
85b1c36d 4466static struct option options[] =
252b5132 4467{
b34976b6 4468 {"all", no_argument, 0, 'a'},
252b5132
RH
4469 {"file-header", no_argument, 0, 'h'},
4470 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
4471 {"headers", no_argument, 0, 'e'},
4472 {"histogram", no_argument, 0, 'I'},
4473 {"segments", no_argument, 0, 'l'},
4474 {"sections", no_argument, 0, 'S'},
252b5132 4475 {"section-headers", no_argument, 0, 'S'},
f5842774 4476 {"section-groups", no_argument, 0, 'g'},
5477e8a0 4477 {"section-details", no_argument, 0, 't'},
595cf52e 4478 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
4479 {"symbols", no_argument, 0, 's'},
4480 {"syms", no_argument, 0, 's'},
2c610e4b 4481 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
4482 {"relocs", no_argument, 0, 'r'},
4483 {"notes", no_argument, 0, 'n'},
4484 {"dynamic", no_argument, 0, 'd'},
1b513401
NC
4485 {"lint", no_argument, 0, 'L'},
4486 {"enable-checks", no_argument, 0, 'L'},
a952a375 4487 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
4488 {"version-info", no_argument, 0, 'V'},
4489 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 4490 {"unwind", no_argument, 0, 'u'},
4145f1d5 4491 {"archive-index", no_argument, 0, 'c'},
b34976b6 4492 {"hex-dump", required_argument, 0, 'x'},
cf13d699 4493 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 4494 {"string-dump", required_argument, 0, 'p'},
0e602686 4495 {"decompress", no_argument, 0, 'z'},
252b5132
RH
4496#ifdef SUPPORT_DISASSEMBLY
4497 {"instruction-dump", required_argument, 0, 'i'},
4498#endif
cf13d699 4499 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 4500
fd2f0033
TT
4501 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4502 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4503 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 4504
d344b407 4505 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
4506
4507 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
4508 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
4509 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
4510
b34976b6
AM
4511 {"version", no_argument, 0, 'v'},
4512 {"wide", no_argument, 0, 'W'},
4513 {"help", no_argument, 0, 'H'},
4514 {0, no_argument, 0, 0}
252b5132
RH
4515};
4516
4517static void
2cf0635d 4518usage (FILE * stream)
252b5132 4519{
92f01d61
JM
4520 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4521 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4522 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4523 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4524 -h --file-header Display the ELF file header\n\
4525 -l --program-headers Display the program headers\n\
4526 --segments An alias for --program-headers\n\
4527 -S --section-headers Display the sections' header\n\
4528 --sections An alias for --section-headers\n\
f5842774 4529 -g --section-groups Display the section groups\n\
5477e8a0 4530 -t --section-details Display the section details\n\
8b53311e
NC
4531 -e --headers Equivalent to: -h -l -S\n\
4532 -s --syms Display the symbol table\n\
3f08eb35 4533 --symbols An alias for --syms\n\
1b513401 4534 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
4535 -n --notes Display the core notes (if present)\n\
4536 -r --relocs Display the relocations (if present)\n\
4537 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4538 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4539 -V --version-info Display the version sections (if present)\n\
1b31d05e 4540 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4541 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4542 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
1b513401 4543 -L --lint|--enable-checks Display warning messages for possible problems\n\
09c11c86
NC
4544 -x --hex-dump=<number|name>\n\
4545 Dump the contents of section <number|name> as bytes\n\
4546 -p --string-dump=<number|name>\n\
4547 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4548 -R --relocated-dump=<number|name>\n\
4549 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4550 -z --decompress Decompress section before dumping it\n\
dda8d76d 4551 -w[lLiaprmfFsoRtUuTgAckK] or\n\
1ed06042 4552 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 4553 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47 4554 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
dda8d76d
NC
4555 =addr,=cu_index,=links,=follow-links]\n\
4556 Display the contents of DWARF debug sections\n"));
fd2f0033
TT
4557 fprintf (stream, _("\
4558 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4559 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4560 or deeper\n"));
7d9813f1
NA
4561 fprintf (stream, _("\
4562 --ctf=<number|name> Display CTF info from section <number|name>\n\
4563 --ctf-parent=<number|name>\n\
4564 Use section <number|name> as the CTF parent\n\n\
4565 --ctf-symbols=<number|name>\n\
4566 Use section <number|name> as the CTF external symtab\n\n\
4567 --ctf-strings=<number|name>\n\
4568 Use section <number|name> as the CTF external strtab\n\n"));
4569
252b5132 4570#ifdef SUPPORT_DISASSEMBLY
92f01d61 4571 fprintf (stream, _("\
09c11c86
NC
4572 -i --instruction-dump=<number|name>\n\
4573 Disassemble the contents of section <number|name>\n"));
252b5132 4574#endif
92f01d61 4575 fprintf (stream, _("\
8b53311e
NC
4576 -I --histogram Display histogram of bucket list lengths\n\
4577 -W --wide Allow output width to exceed 80 characters\n\
07012eee 4578 @<file> Read options from <file>\n\
8b53311e
NC
4579 -H --help Display this information\n\
4580 -v --version Display the version number of readelf\n"));
1118d252 4581
92f01d61
JM
4582 if (REPORT_BUGS_TO[0] && stream == stdout)
4583 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4584
92f01d61 4585 exit (stream == stdout ? 0 : 1);
252b5132
RH
4586}
4587
18bd398b
NC
4588/* Record the fact that the user wants the contents of section number
4589 SECTION to be displayed using the method(s) encoded as flags bits
4590 in TYPE. Note, TYPE can be zero if we are creating the array for
4591 the first time. */
4592
252b5132 4593static void
6431e409
AM
4594request_dump_bynumber (struct dump_data *dumpdata,
4595 unsigned int section, dump_type type)
252b5132 4596{
6431e409 4597 if (section >= dumpdata->num_dump_sects)
252b5132 4598 {
2cf0635d 4599 dump_type * new_dump_sects;
252b5132 4600
3f5e193b 4601 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4602 sizeof (* new_dump_sects));
252b5132
RH
4603
4604 if (new_dump_sects == NULL)
591a748a 4605 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4606 else
4607 {
6431e409 4608 if (dumpdata->dump_sects)
21b65bac
NC
4609 {
4610 /* Copy current flag settings. */
6431e409
AM
4611 memcpy (new_dump_sects, dumpdata->dump_sects,
4612 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4613
6431e409 4614 free (dumpdata->dump_sects);
21b65bac 4615 }
252b5132 4616
6431e409
AM
4617 dumpdata->dump_sects = new_dump_sects;
4618 dumpdata->num_dump_sects = section + 1;
252b5132
RH
4619 }
4620 }
4621
6431e409
AM
4622 if (dumpdata->dump_sects)
4623 dumpdata->dump_sects[section] |= type;
252b5132
RH
4624}
4625
aef1f6d0
DJ
4626/* Request a dump by section name. */
4627
4628static void
2cf0635d 4629request_dump_byname (const char * section, dump_type type)
aef1f6d0 4630{
2cf0635d 4631 struct dump_list_entry * new_request;
aef1f6d0 4632
3f5e193b
NC
4633 new_request = (struct dump_list_entry *)
4634 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4635 if (!new_request)
591a748a 4636 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4637
4638 new_request->name = strdup (section);
4639 if (!new_request->name)
591a748a 4640 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4641
4642 new_request->type = type;
4643
4644 new_request->next = dump_sects_byname;
4645 dump_sects_byname = new_request;
4646}
4647
cf13d699 4648static inline void
6431e409 4649request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
4650{
4651 int section;
4652 char * cp;
4653
4654 do_dump++;
4655 section = strtoul (optarg, & cp, 0);
4656
4657 if (! *cp && section >= 0)
6431e409 4658 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
4659 else
4660 request_dump_byname (optarg, type);
4661}
4662
252b5132 4663static void
6431e409 4664parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
4665{
4666 int c;
4667
4668 if (argc < 2)
92f01d61 4669 usage (stderr);
252b5132
RH
4670
4671 while ((c = getopt_long
1b513401 4672 (argc, argv, "ADHILNR:SVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4673 {
252b5132
RH
4674 switch (c)
4675 {
4676 case 0:
4677 /* Long options. */
4678 break;
4679 case 'H':
92f01d61 4680 usage (stdout);
252b5132
RH
4681 break;
4682
4683 case 'a':
32ec8896
NC
4684 do_syms = TRUE;
4685 do_reloc = TRUE;
4686 do_unwind = TRUE;
4687 do_dynamic = TRUE;
4688 do_header = TRUE;
4689 do_sections = TRUE;
4690 do_section_groups = TRUE;
4691 do_segments = TRUE;
4692 do_version = TRUE;
4693 do_histogram = TRUE;
4694 do_arch = TRUE;
4695 do_notes = TRUE;
252b5132 4696 break;
f5842774 4697 case 'g':
32ec8896 4698 do_section_groups = TRUE;
f5842774 4699 break;
5477e8a0 4700 case 't':
595cf52e 4701 case 'N':
32ec8896
NC
4702 do_sections = TRUE;
4703 do_section_details = TRUE;
595cf52e 4704 break;
252b5132 4705 case 'e':
32ec8896
NC
4706 do_header = TRUE;
4707 do_sections = TRUE;
4708 do_segments = TRUE;
252b5132 4709 break;
a952a375 4710 case 'A':
32ec8896 4711 do_arch = TRUE;
a952a375 4712 break;
252b5132 4713 case 'D':
32ec8896 4714 do_using_dynamic = TRUE;
252b5132
RH
4715 break;
4716 case 'r':
32ec8896 4717 do_reloc = TRUE;
252b5132 4718 break;
4d6ed7c8 4719 case 'u':
32ec8896 4720 do_unwind = TRUE;
4d6ed7c8 4721 break;
252b5132 4722 case 'h':
32ec8896 4723 do_header = TRUE;
252b5132
RH
4724 break;
4725 case 'l':
32ec8896 4726 do_segments = TRUE;
252b5132
RH
4727 break;
4728 case 's':
32ec8896 4729 do_syms = TRUE;
252b5132
RH
4730 break;
4731 case 'S':
32ec8896 4732 do_sections = TRUE;
252b5132
RH
4733 break;
4734 case 'd':
32ec8896 4735 do_dynamic = TRUE;
252b5132 4736 break;
a952a375 4737 case 'I':
32ec8896 4738 do_histogram = TRUE;
a952a375 4739 break;
779fe533 4740 case 'n':
32ec8896 4741 do_notes = TRUE;
779fe533 4742 break;
4145f1d5 4743 case 'c':
32ec8896 4744 do_archive_index = TRUE;
4145f1d5 4745 break;
1b513401
NC
4746 case 'L':
4747 do_checks = TRUE;
4748 break;
252b5132 4749 case 'x':
6431e409 4750 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 4751 break;
09c11c86 4752 case 'p':
6431e409 4753 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
4754 break;
4755 case 'R':
6431e409 4756 request_dump (dumpdata, RELOC_DUMP);
09c11c86 4757 break;
0e602686 4758 case 'z':
32ec8896 4759 decompress_dumps = TRUE;
0e602686 4760 break;
252b5132 4761 case 'w':
32ec8896 4762 do_dump = TRUE;
252b5132 4763 if (optarg == 0)
613ff48b 4764 {
32ec8896 4765 do_debugging = TRUE;
613ff48b
CC
4766 dwarf_select_sections_all ();
4767 }
252b5132
RH
4768 else
4769 {
32ec8896 4770 do_debugging = FALSE;
4cb93e3b 4771 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4772 }
4773 break;
2979dc34 4774 case OPTION_DEBUG_DUMP:
32ec8896 4775 do_dump = TRUE;
2979dc34 4776 if (optarg == 0)
32ec8896 4777 do_debugging = TRUE;
2979dc34
JJ
4778 else
4779 {
32ec8896 4780 do_debugging = FALSE;
4cb93e3b 4781 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4782 }
4783 break;
fd2f0033
TT
4784 case OPTION_DWARF_DEPTH:
4785 {
4786 char *cp;
4787
4788 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4789 }
4790 break;
4791 case OPTION_DWARF_START:
4792 {
4793 char *cp;
4794
4795 dwarf_start_die = strtoul (optarg, & cp, 0);
4796 }
4797 break;
4723351a 4798 case OPTION_DWARF_CHECK:
32ec8896 4799 dwarf_check = TRUE;
4723351a 4800 break;
7d9813f1
NA
4801 case OPTION_CTF_DUMP:
4802 do_ctf = TRUE;
6431e409 4803 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
4804 break;
4805 case OPTION_CTF_SYMBOLS:
4806 dump_ctf_symtab_name = strdup (optarg);
4807 break;
4808 case OPTION_CTF_STRINGS:
4809 dump_ctf_strtab_name = strdup (optarg);
4810 break;
4811 case OPTION_CTF_PARENT:
4812 dump_ctf_parent_name = strdup (optarg);
4813 break;
2c610e4b 4814 case OPTION_DYN_SYMS:
32ec8896 4815 do_dyn_syms = TRUE;
2c610e4b 4816 break;
252b5132
RH
4817#ifdef SUPPORT_DISASSEMBLY
4818 case 'i':
6431e409 4819 request_dump (dumpdata, DISASS_DUMP);
cf13d699 4820 break;
252b5132
RH
4821#endif
4822 case 'v':
4823 print_version (program_name);
4824 break;
4825 case 'V':
32ec8896 4826 do_version = TRUE;
252b5132 4827 break;
d974e256 4828 case 'W':
32ec8896 4829 do_wide = TRUE;
d974e256 4830 break;
252b5132 4831 default:
252b5132
RH
4832 /* xgettext:c-format */
4833 error (_("Invalid option '-%c'\n"), c);
1a0670f3 4834 /* Fall through. */
252b5132 4835 case '?':
92f01d61 4836 usage (stderr);
252b5132
RH
4837 }
4838 }
4839
4d6ed7c8 4840 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4841 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4842 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4843 && !do_section_groups && !do_archive_index
4844 && !do_dyn_syms)
1b513401
NC
4845 {
4846 if (do_checks)
4847 {
4848 check_all = TRUE;
4849 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = TRUE;
4850 do_segments = do_header = do_dump = do_version = TRUE;
4851 do_histogram = do_debugging = do_arch = do_notes = TRUE;
4852 do_section_groups = do_archive_index = do_dyn_syms = TRUE;
4853 }
4854 else
4855 usage (stderr);
4856 }
252b5132
RH
4857}
4858
4859static const char *
d3ba0551 4860get_elf_class (unsigned int elf_class)
252b5132 4861{
b34976b6 4862 static char buff[32];
103f02d3 4863
252b5132
RH
4864 switch (elf_class)
4865 {
4866 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4867 case ELFCLASS32: return "ELF32";
4868 case ELFCLASS64: return "ELF64";
ab5e7794 4869 default:
e9e44622 4870 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4871 return buff;
252b5132
RH
4872 }
4873}
4874
4875static const char *
d3ba0551 4876get_data_encoding (unsigned int encoding)
252b5132 4877{
b34976b6 4878 static char buff[32];
103f02d3 4879
252b5132
RH
4880 switch (encoding)
4881 {
4882 case ELFDATANONE: return _("none");
33c63f9d
CM
4883 case ELFDATA2LSB: return _("2's complement, little endian");
4884 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4885 default:
e9e44622 4886 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4887 return buff;
252b5132
RH
4888 }
4889}
4890
dda8d76d 4891/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 4892
32ec8896 4893static bfd_boolean
dda8d76d 4894process_file_header (Filedata * filedata)
252b5132 4895{
dda8d76d
NC
4896 Elf_Internal_Ehdr * header = & filedata->file_header;
4897
4898 if ( header->e_ident[EI_MAG0] != ELFMAG0
4899 || header->e_ident[EI_MAG1] != ELFMAG1
4900 || header->e_ident[EI_MAG2] != ELFMAG2
4901 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4902 {
4903 error
4904 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
32ec8896 4905 return FALSE;
252b5132
RH
4906 }
4907
955ff7fc 4908 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 4909
252b5132
RH
4910 if (do_header)
4911 {
32ec8896 4912 unsigned i;
252b5132
RH
4913
4914 printf (_("ELF Header:\n"));
4915 printf (_(" Magic: "));
b34976b6 4916 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 4917 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
4918 printf ("\n");
4919 printf (_(" Class: %s\n"),
dda8d76d 4920 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 4921 printf (_(" Data: %s\n"),
dda8d76d 4922 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 4923 printf (_(" Version: %d%s\n"),
dda8d76d
NC
4924 header->e_ident[EI_VERSION],
4925 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 4926 ? _(" (current)")
dda8d76d 4927 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 4928 ? _(" <unknown>")
789be9f7 4929 : "")));
252b5132 4930 printf (_(" OS/ABI: %s\n"),
dda8d76d 4931 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 4932 printf (_(" ABI Version: %d\n"),
dda8d76d 4933 header->e_ident[EI_ABIVERSION]);
252b5132 4934 printf (_(" Type: %s\n"),
dda8d76d 4935 get_file_type (header->e_type));
252b5132 4936 printf (_(" Machine: %s\n"),
dda8d76d 4937 get_machine_name (header->e_machine));
252b5132 4938 printf (_(" Version: 0x%lx\n"),
e8a64888 4939 header->e_version);
76da6bbe 4940
f7a99963 4941 printf (_(" Entry point address: "));
e8a64888 4942 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 4943 printf (_("\n Start of program headers: "));
e8a64888 4944 print_vma (header->e_phoff, DEC);
f7a99963 4945 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 4946 print_vma (header->e_shoff, DEC);
f7a99963 4947 printf (_(" (bytes into file)\n"));
76da6bbe 4948
252b5132 4949 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 4950 header->e_flags,
dda8d76d 4951 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
4952 printf (_(" Size of this header: %u (bytes)\n"),
4953 header->e_ehsize);
4954 printf (_(" Size of program headers: %u (bytes)\n"),
4955 header->e_phentsize);
4956 printf (_(" Number of program headers: %u"),
4957 header->e_phnum);
dda8d76d
NC
4958 if (filedata->section_headers != NULL
4959 && header->e_phnum == PN_XNUM
4960 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
4961 {
4962 header->e_phnum = filedata->section_headers[0].sh_info;
4963 printf (" (%u)", header->e_phnum);
4964 }
2046a35d 4965 putc ('\n', stdout);
e8a64888
AM
4966 printf (_(" Size of section headers: %u (bytes)\n"),
4967 header->e_shentsize);
4968 printf (_(" Number of section headers: %u"),
4969 header->e_shnum);
dda8d76d 4970 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
4971 {
4972 header->e_shnum = filedata->section_headers[0].sh_size;
4973 printf (" (%u)", header->e_shnum);
4974 }
560f3c1c 4975 putc ('\n', stdout);
e8a64888
AM
4976 printf (_(" Section header string table index: %u"),
4977 header->e_shstrndx);
dda8d76d
NC
4978 if (filedata->section_headers != NULL
4979 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
4980 {
4981 header->e_shstrndx = filedata->section_headers[0].sh_link;
4982 printf (" (%u)", header->e_shstrndx);
4983 }
4984 if (header->e_shstrndx != SHN_UNDEF
4985 && header->e_shstrndx >= header->e_shnum)
4986 {
4987 header->e_shstrndx = SHN_UNDEF;
4988 printf (_(" <corrupt: out of range>"));
4989 }
560f3c1c
AM
4990 putc ('\n', stdout);
4991 }
4992
dda8d76d 4993 if (filedata->section_headers != NULL)
560f3c1c 4994 {
dda8d76d
NC
4995 if (header->e_phnum == PN_XNUM
4996 && filedata->section_headers[0].sh_info != 0)
4997 header->e_phnum = filedata->section_headers[0].sh_info;
4998 if (header->e_shnum == SHN_UNDEF)
4999 header->e_shnum = filedata->section_headers[0].sh_size;
5000 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5001 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5002 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
5003 header->e_shstrndx = SHN_UNDEF;
5004 free (filedata->section_headers);
5005 filedata->section_headers = NULL;
252b5132 5006 }
103f02d3 5007
32ec8896 5008 return TRUE;
9ea033b2
NC
5009}
5010
dda8d76d
NC
5011/* Read in the program headers from FILEDATA and store them in PHEADERS.
5012 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5013
e0a31db1 5014static bfd_boolean
dda8d76d 5015get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5016{
2cf0635d
NC
5017 Elf32_External_Phdr * phdrs;
5018 Elf32_External_Phdr * external;
5019 Elf_Internal_Phdr * internal;
b34976b6 5020 unsigned int i;
dda8d76d
NC
5021 unsigned int size = filedata->file_header.e_phentsize;
5022 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5023
5024 /* PR binutils/17531: Cope with unexpected section header sizes. */
5025 if (size == 0 || num == 0)
5026 return FALSE;
5027 if (size < sizeof * phdrs)
5028 {
5029 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5030 return FALSE;
5031 }
5032 if (size > sizeof * phdrs)
5033 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5034
dda8d76d 5035 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5036 size, num, _("program headers"));
5037 if (phdrs == NULL)
5038 return FALSE;
9ea033b2 5039
91d6fa6a 5040 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5041 i < filedata->file_header.e_phnum;
b34976b6 5042 i++, internal++, external++)
252b5132 5043 {
9ea033b2
NC
5044 internal->p_type = BYTE_GET (external->p_type);
5045 internal->p_offset = BYTE_GET (external->p_offset);
5046 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5047 internal->p_paddr = BYTE_GET (external->p_paddr);
5048 internal->p_filesz = BYTE_GET (external->p_filesz);
5049 internal->p_memsz = BYTE_GET (external->p_memsz);
5050 internal->p_flags = BYTE_GET (external->p_flags);
5051 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5052 }
5053
9ea033b2 5054 free (phdrs);
e0a31db1 5055 return TRUE;
252b5132
RH
5056}
5057
dda8d76d
NC
5058/* Read in the program headers from FILEDATA and store them in PHEADERS.
5059 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5060
e0a31db1 5061static bfd_boolean
dda8d76d 5062get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5063{
2cf0635d
NC
5064 Elf64_External_Phdr * phdrs;
5065 Elf64_External_Phdr * external;
5066 Elf_Internal_Phdr * internal;
b34976b6 5067 unsigned int i;
dda8d76d
NC
5068 unsigned int size = filedata->file_header.e_phentsize;
5069 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5070
5071 /* PR binutils/17531: Cope with unexpected section header sizes. */
5072 if (size == 0 || num == 0)
5073 return FALSE;
5074 if (size < sizeof * phdrs)
5075 {
5076 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5077 return FALSE;
5078 }
5079 if (size > sizeof * phdrs)
5080 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5081
dda8d76d 5082 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5083 size, num, _("program headers"));
a6e9f9df 5084 if (!phdrs)
e0a31db1 5085 return FALSE;
9ea033b2 5086
91d6fa6a 5087 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5088 i < filedata->file_header.e_phnum;
b34976b6 5089 i++, internal++, external++)
9ea033b2
NC
5090 {
5091 internal->p_type = BYTE_GET (external->p_type);
5092 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5093 internal->p_offset = BYTE_GET (external->p_offset);
5094 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5095 internal->p_paddr = BYTE_GET (external->p_paddr);
5096 internal->p_filesz = BYTE_GET (external->p_filesz);
5097 internal->p_memsz = BYTE_GET (external->p_memsz);
5098 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5099 }
5100
5101 free (phdrs);
e0a31db1 5102 return TRUE;
9ea033b2 5103}
252b5132 5104
32ec8896 5105/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5106
32ec8896 5107static bfd_boolean
dda8d76d 5108get_program_headers (Filedata * filedata)
d93f0186 5109{
2cf0635d 5110 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5111
5112 /* Check cache of prior read. */
dda8d76d 5113 if (filedata->program_headers != NULL)
32ec8896 5114 return TRUE;
d93f0186 5115
82156ab7
NC
5116 /* Be kind to memory checkers by looking for
5117 e_phnum values which we know must be invalid. */
dda8d76d 5118 if (filedata->file_header.e_phnum
82156ab7 5119 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5120 >= filedata->file_size)
82156ab7
NC
5121 {
5122 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5123 filedata->file_header.e_phnum);
82156ab7
NC
5124 return FALSE;
5125 }
d93f0186 5126
dda8d76d 5127 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5128 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5129 if (phdrs == NULL)
5130 {
8b73c356 5131 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5132 filedata->file_header.e_phnum);
32ec8896 5133 return FALSE;
d93f0186
NC
5134 }
5135
5136 if (is_32bit_elf
dda8d76d
NC
5137 ? get_32bit_program_headers (filedata, phdrs)
5138 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5139 {
dda8d76d 5140 filedata->program_headers = phdrs;
32ec8896 5141 return TRUE;
d93f0186
NC
5142 }
5143
5144 free (phdrs);
32ec8896 5145 return FALSE;
d93f0186
NC
5146}
5147
32ec8896 5148/* Returns TRUE if the program headers were loaded. */
2f62977e 5149
32ec8896 5150static bfd_boolean
dda8d76d 5151process_program_headers (Filedata * filedata)
252b5132 5152{
2cf0635d 5153 Elf_Internal_Phdr * segment;
b34976b6 5154 unsigned int i;
1a9ccd70 5155 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5156
978c4450
AM
5157 filedata->dynamic_addr = 0;
5158 filedata->dynamic_size = 0;
663f67df 5159
dda8d76d 5160 if (filedata->file_header.e_phnum == 0)
252b5132 5161 {
82f2dbf7 5162 /* PR binutils/12467. */
dda8d76d 5163 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5164 {
5165 warn (_("possibly corrupt ELF header - it has a non-zero program"
5166 " header offset, but no program headers\n"));
5167 return FALSE;
5168 }
82f2dbf7 5169 else if (do_segments)
252b5132 5170 printf (_("\nThere are no program headers in this file.\n"));
32ec8896 5171 return TRUE;
252b5132
RH
5172 }
5173
5174 if (do_segments && !do_header)
5175 {
dda8d76d
NC
5176 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
5177 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5178 printf (ngettext ("There is %d program header, starting at offset %s\n",
5179 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5180 filedata->file_header.e_phnum),
5181 filedata->file_header.e_phnum,
5182 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5183 }
5184
dda8d76d 5185 if (! get_program_headers (filedata))
6b4bf3bc 5186 return TRUE;
103f02d3 5187
252b5132
RH
5188 if (do_segments)
5189 {
dda8d76d 5190 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5191 printf (_("\nProgram Headers:\n"));
5192 else
5193 printf (_("\nProgram Headers:\n"));
76da6bbe 5194
f7a99963
NC
5195 if (is_32bit_elf)
5196 printf
5197 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5198 else if (do_wide)
5199 printf
5200 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5201 else
5202 {
5203 printf
5204 (_(" Type Offset VirtAddr PhysAddr\n"));
5205 printf
5206 (_(" FileSiz MemSiz Flags Align\n"));
5207 }
252b5132
RH
5208 }
5209
dda8d76d
NC
5210 for (i = 0, segment = filedata->program_headers;
5211 i < filedata->file_header.e_phnum;
b34976b6 5212 i++, segment++)
252b5132
RH
5213 {
5214 if (do_segments)
5215 {
dda8d76d 5216 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5217
5218 if (is_32bit_elf)
5219 {
5220 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5221 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5222 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5223 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5224 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5225 printf ("%c%c%c ",
5226 (segment->p_flags & PF_R ? 'R' : ' '),
5227 (segment->p_flags & PF_W ? 'W' : ' '),
5228 (segment->p_flags & PF_X ? 'E' : ' '));
5229 printf ("%#lx", (unsigned long) segment->p_align);
5230 }
d974e256
JJ
5231 else if (do_wide)
5232 {
5233 if ((unsigned long) segment->p_offset == segment->p_offset)
5234 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5235 else
5236 {
5237 print_vma (segment->p_offset, FULL_HEX);
5238 putchar (' ');
5239 }
5240
5241 print_vma (segment->p_vaddr, FULL_HEX);
5242 putchar (' ');
5243 print_vma (segment->p_paddr, FULL_HEX);
5244 putchar (' ');
5245
5246 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5247 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5248 else
5249 {
5250 print_vma (segment->p_filesz, FULL_HEX);
5251 putchar (' ');
5252 }
5253
5254 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5255 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5256 else
5257 {
f48e6c45 5258 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5259 }
5260
5261 printf (" %c%c%c ",
5262 (segment->p_flags & PF_R ? 'R' : ' '),
5263 (segment->p_flags & PF_W ? 'W' : ' '),
5264 (segment->p_flags & PF_X ? 'E' : ' '));
5265
5266 if ((unsigned long) segment->p_align == segment->p_align)
5267 printf ("%#lx", (unsigned long) segment->p_align);
5268 else
5269 {
5270 print_vma (segment->p_align, PREFIX_HEX);
5271 }
5272 }
f7a99963
NC
5273 else
5274 {
5275 print_vma (segment->p_offset, FULL_HEX);
5276 putchar (' ');
5277 print_vma (segment->p_vaddr, FULL_HEX);
5278 putchar (' ');
5279 print_vma (segment->p_paddr, FULL_HEX);
5280 printf ("\n ");
5281 print_vma (segment->p_filesz, FULL_HEX);
5282 putchar (' ');
5283 print_vma (segment->p_memsz, FULL_HEX);
5284 printf (" %c%c%c ",
5285 (segment->p_flags & PF_R ? 'R' : ' '),
5286 (segment->p_flags & PF_W ? 'W' : ' '),
5287 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5288 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5289 }
252b5132 5290
1a9ccd70
NC
5291 putc ('\n', stdout);
5292 }
f54498b4 5293
252b5132
RH
5294 switch (segment->p_type)
5295 {
1a9ccd70 5296 case PT_LOAD:
502d895c
NC
5297#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5298 required by the ELF standard, several programs, including the Linux
5299 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5300 if (previous_load
5301 && previous_load->p_vaddr > segment->p_vaddr)
5302 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5303#endif
1a9ccd70
NC
5304 if (segment->p_memsz < segment->p_filesz)
5305 error (_("the segment's file size is larger than its memory size\n"));
5306 previous_load = segment;
5307 break;
5308
5309 case PT_PHDR:
5310 /* PR 20815 - Verify that the program header is loaded into memory. */
5311 if (i > 0 && previous_load != NULL)
5312 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5313 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5314 {
5315 unsigned int j;
5316
dda8d76d 5317 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5318 {
5319 Elf_Internal_Phdr *load = filedata->program_headers + j;
5320 if (load->p_type == PT_LOAD
5321 && load->p_offset <= segment->p_offset
5322 && (load->p_offset + load->p_filesz
5323 >= segment->p_offset + segment->p_filesz)
5324 && load->p_vaddr <= segment->p_vaddr
5325 && (load->p_vaddr + load->p_filesz
5326 >= segment->p_vaddr + segment->p_filesz))
5327 break;
5328 }
dda8d76d 5329 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5330 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5331 }
5332 break;
5333
252b5132 5334 case PT_DYNAMIC:
978c4450 5335 if (filedata->dynamic_addr)
252b5132
RH
5336 error (_("more than one dynamic segment\n"));
5337
20737c13
AM
5338 /* By default, assume that the .dynamic section is the first
5339 section in the DYNAMIC segment. */
978c4450
AM
5340 filedata->dynamic_addr = segment->p_offset;
5341 filedata->dynamic_size = segment->p_filesz;
20737c13 5342
b2d38a17
NC
5343 /* Try to locate the .dynamic section. If there is
5344 a section header table, we can easily locate it. */
dda8d76d 5345 if (filedata->section_headers != NULL)
b2d38a17 5346 {
2cf0635d 5347 Elf_Internal_Shdr * sec;
b2d38a17 5348
dda8d76d 5349 sec = find_section (filedata, ".dynamic");
89fac5e3 5350 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5351 {
28f997cf
TG
5352 /* A corresponding .dynamic section is expected, but on
5353 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5354 if (!is_ia64_vms (filedata))
28f997cf 5355 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5356 break;
5357 }
5358
42bb2e33 5359 if (sec->sh_type == SHT_NOBITS)
20737c13 5360 {
978c4450 5361 filedata->dynamic_size = 0;
20737c13
AM
5362 break;
5363 }
42bb2e33 5364
978c4450
AM
5365 filedata->dynamic_addr = sec->sh_offset;
5366 filedata->dynamic_size = sec->sh_size;
b2d38a17 5367
8ac10c5b
L
5368 /* The PT_DYNAMIC segment, which is used by the run-time
5369 loader, should exactly match the .dynamic section. */
5370 if (do_checks
5371 && (filedata->dynamic_addr != segment->p_offset
5372 || filedata->dynamic_size != segment->p_filesz))
5373 warn (_("\
5374the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 5375 }
39e224f6
MW
5376
5377 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5378 segment. Check this after matching against the section headers
5379 so we don't warn on debuginfo file (which have NOBITS .dynamic
5380 sections). */
978c4450
AM
5381 if (filedata->dynamic_addr > filedata->file_size
5382 || (filedata->dynamic_size
5383 > filedata->file_size - filedata->dynamic_addr))
39e224f6
MW
5384 {
5385 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
978c4450 5386 filedata->dynamic_addr = filedata->dynamic_size = 0;
39e224f6 5387 }
252b5132
RH
5388 break;
5389
5390 case PT_INTERP:
978c4450
AM
5391 if (fseek (filedata->handle,
5392 filedata->archive_file_offset + (long) segment->p_offset,
fb52b2f4 5393 SEEK_SET))
252b5132
RH
5394 error (_("Unable to find program interpreter name\n"));
5395 else
5396 {
f8eae8b2 5397 char fmt [32];
9495b2e6 5398 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
5399
5400 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 5401 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 5402
978c4450
AM
5403 filedata->program_interpreter[0] = 0;
5404 if (fscanf (filedata->handle, fmt,
5405 filedata->program_interpreter) <= 0)
7bd7b3ef 5406 error (_("Unable to read program interpreter name\n"));
252b5132
RH
5407
5408 if (do_segments)
f54498b4 5409 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 5410 filedata->program_interpreter);
252b5132
RH
5411 }
5412 break;
5413 }
252b5132
RH
5414 }
5415
dda8d76d
NC
5416 if (do_segments
5417 && filedata->section_headers != NULL
5418 && filedata->string_table != NULL)
252b5132
RH
5419 {
5420 printf (_("\n Section to Segment mapping:\n"));
5421 printf (_(" Segment Sections...\n"));
5422
dda8d76d 5423 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5424 {
9ad5cbcf 5425 unsigned int j;
2cf0635d 5426 Elf_Internal_Shdr * section;
252b5132 5427
dda8d76d
NC
5428 segment = filedata->program_headers + i;
5429 section = filedata->section_headers + 1;
252b5132
RH
5430
5431 printf (" %2.2d ", i);
5432
dda8d76d 5433 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5434 {
f4638467
AM
5435 if (!ELF_TBSS_SPECIAL (section, segment)
5436 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5437 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5438 }
5439
5440 putc ('\n',stdout);
5441 }
5442 }
5443
32ec8896 5444 return TRUE;
252b5132
RH
5445}
5446
5447
d93f0186
NC
5448/* Find the file offset corresponding to VMA by using the program headers. */
5449
5450static long
dda8d76d 5451offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5452{
2cf0635d 5453 Elf_Internal_Phdr * seg;
d93f0186 5454
dda8d76d 5455 if (! get_program_headers (filedata))
d93f0186
NC
5456 {
5457 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5458 return (long) vma;
5459 }
5460
dda8d76d
NC
5461 for (seg = filedata->program_headers;
5462 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5463 ++seg)
5464 {
5465 if (seg->p_type != PT_LOAD)
5466 continue;
5467
5468 if (vma >= (seg->p_vaddr & -seg->p_align)
5469 && vma + size <= seg->p_vaddr + seg->p_filesz)
5470 return vma - seg->p_vaddr + seg->p_offset;
5471 }
5472
5473 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5474 (unsigned long) vma);
d93f0186
NC
5475 return (long) vma;
5476}
5477
5478
dda8d76d
NC
5479/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5480 If PROBE is true, this is just a probe and we do not generate any error
5481 messages if the load fails. */
049b0c3a
NC
5482
5483static bfd_boolean
dda8d76d 5484get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
252b5132 5485{
2cf0635d
NC
5486 Elf32_External_Shdr * shdrs;
5487 Elf_Internal_Shdr * internal;
dda8d76d
NC
5488 unsigned int i;
5489 unsigned int size = filedata->file_header.e_shentsize;
5490 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5491
5492 /* PR binutils/17531: Cope with unexpected section header sizes. */
5493 if (size == 0 || num == 0)
5494 return FALSE;
5495 if (size < sizeof * shdrs)
5496 {
5497 if (! probe)
5498 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5499 return FALSE;
5500 }
5501 if (!probe && size > sizeof * shdrs)
5502 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5503
dda8d76d 5504 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5505 size, num,
5506 probe ? NULL : _("section headers"));
5507 if (shdrs == NULL)
5508 return FALSE;
252b5132 5509
dda8d76d
NC
5510 free (filedata->section_headers);
5511 filedata->section_headers = (Elf_Internal_Shdr *)
5512 cmalloc (num, sizeof (Elf_Internal_Shdr));
5513 if (filedata->section_headers == NULL)
252b5132 5514 {
049b0c3a 5515 if (!probe)
8b73c356 5516 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5517 free (shdrs);
049b0c3a 5518 return FALSE;
252b5132
RH
5519 }
5520
dda8d76d 5521 for (i = 0, internal = filedata->section_headers;
560f3c1c 5522 i < num;
b34976b6 5523 i++, internal++)
252b5132
RH
5524 {
5525 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5526 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5527 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5528 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5529 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5530 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5531 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5532 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5533 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5534 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5535 if (!probe && internal->sh_link > num)
5536 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5537 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5538 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5539 }
5540
5541 free (shdrs);
049b0c3a 5542 return TRUE;
252b5132
RH
5543}
5544
dda8d76d
NC
5545/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5546
049b0c3a 5547static bfd_boolean
dda8d76d 5548get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
9ea033b2 5549{
dda8d76d
NC
5550 Elf64_External_Shdr * shdrs;
5551 Elf_Internal_Shdr * internal;
5552 unsigned int i;
5553 unsigned int size = filedata->file_header.e_shentsize;
5554 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5555
5556 /* PR binutils/17531: Cope with unexpected section header sizes. */
5557 if (size == 0 || num == 0)
5558 return FALSE;
dda8d76d 5559
049b0c3a
NC
5560 if (size < sizeof * shdrs)
5561 {
5562 if (! probe)
5563 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5564 return FALSE;
5565 }
dda8d76d 5566
049b0c3a
NC
5567 if (! probe && size > sizeof * shdrs)
5568 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5569
dda8d76d
NC
5570 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5571 filedata->file_header.e_shoff,
049b0c3a
NC
5572 size, num,
5573 probe ? NULL : _("section headers"));
5574 if (shdrs == NULL)
5575 return FALSE;
9ea033b2 5576
dda8d76d
NC
5577 free (filedata->section_headers);
5578 filedata->section_headers = (Elf_Internal_Shdr *)
5579 cmalloc (num, sizeof (Elf_Internal_Shdr));
5580 if (filedata->section_headers == NULL)
9ea033b2 5581 {
049b0c3a 5582 if (! probe)
8b73c356 5583 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5584 free (shdrs);
049b0c3a 5585 return FALSE;
9ea033b2
NC
5586 }
5587
dda8d76d 5588 for (i = 0, internal = filedata->section_headers;
560f3c1c 5589 i < num;
b34976b6 5590 i++, internal++)
9ea033b2
NC
5591 {
5592 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5593 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5594 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5595 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5596 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5597 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5598 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5599 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5600 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5601 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5602 if (!probe && internal->sh_link > num)
5603 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5604 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5605 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5606 }
5607
5608 free (shdrs);
049b0c3a 5609 return TRUE;
9ea033b2
NC
5610}
5611
252b5132 5612static Elf_Internal_Sym *
dda8d76d
NC
5613get_32bit_elf_symbols (Filedata * filedata,
5614 Elf_Internal_Shdr * section,
5615 unsigned long * num_syms_return)
252b5132 5616{
ba5cdace 5617 unsigned long number = 0;
dd24e3da 5618 Elf32_External_Sym * esyms = NULL;
ba5cdace 5619 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5620 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5621 Elf_Internal_Sym * psym;
b34976b6 5622 unsigned int j;
e3d39609 5623 elf_section_list * entry;
252b5132 5624
c9c1d674
EG
5625 if (section->sh_size == 0)
5626 {
5627 if (num_syms_return != NULL)
5628 * num_syms_return = 0;
5629 return NULL;
5630 }
5631
dd24e3da 5632 /* Run some sanity checks first. */
c9c1d674 5633 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5634 {
c9c1d674 5635 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5636 printable_section_name (filedata, section),
5637 (unsigned long) section->sh_entsize);
ba5cdace 5638 goto exit_point;
dd24e3da
NC
5639 }
5640
dda8d76d 5641 if (section->sh_size > filedata->file_size)
f54498b4
NC
5642 {
5643 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5644 printable_section_name (filedata, section),
5645 (unsigned long) section->sh_size);
f54498b4
NC
5646 goto exit_point;
5647 }
5648
dd24e3da
NC
5649 number = section->sh_size / section->sh_entsize;
5650
5651 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5652 {
c9c1d674 5653 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5654 (unsigned long) section->sh_size,
dda8d76d 5655 printable_section_name (filedata, section),
8066deb1 5656 (unsigned long) section->sh_entsize);
ba5cdace 5657 goto exit_point;
dd24e3da
NC
5658 }
5659
dda8d76d 5660 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5661 section->sh_size, _("symbols"));
dd24e3da 5662 if (esyms == NULL)
ba5cdace 5663 goto exit_point;
252b5132 5664
e3d39609 5665 shndx = NULL;
978c4450 5666 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5667 {
5668 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5669 continue;
5670
5671 if (shndx != NULL)
5672 {
5673 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5674 free (shndx);
5675 }
5676
5677 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5678 entry->hdr->sh_offset,
5679 1, entry->hdr->sh_size,
5680 _("symbol table section indices"));
5681 if (shndx == NULL)
5682 goto exit_point;
5683
5684 /* PR17531: file: heap-buffer-overflow */
5685 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5686 {
5687 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5688 printable_section_name (filedata, entry->hdr),
5689 (unsigned long) entry->hdr->sh_size,
5690 (unsigned long) section->sh_size);
5691 goto exit_point;
c9c1d674 5692 }
e3d39609 5693 }
9ad5cbcf 5694
3f5e193b 5695 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5696
5697 if (isyms == NULL)
5698 {
8b73c356
NC
5699 error (_("Out of memory reading %lu symbols\n"),
5700 (unsigned long) number);
dd24e3da 5701 goto exit_point;
252b5132
RH
5702 }
5703
dd24e3da 5704 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5705 {
5706 psym->st_name = BYTE_GET (esyms[j].st_name);
5707 psym->st_value = BYTE_GET (esyms[j].st_value);
5708 psym->st_size = BYTE_GET (esyms[j].st_size);
5709 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5710 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5711 psym->st_shndx
5712 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5713 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5714 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5715 psym->st_info = BYTE_GET (esyms[j].st_info);
5716 psym->st_other = BYTE_GET (esyms[j].st_other);
5717 }
5718
dd24e3da 5719 exit_point:
e3d39609
NC
5720 free (shndx);
5721 free (esyms);
252b5132 5722
ba5cdace
NC
5723 if (num_syms_return != NULL)
5724 * num_syms_return = isyms == NULL ? 0 : number;
5725
252b5132
RH
5726 return isyms;
5727}
5728
9ea033b2 5729static Elf_Internal_Sym *
dda8d76d
NC
5730get_64bit_elf_symbols (Filedata * filedata,
5731 Elf_Internal_Shdr * section,
5732 unsigned long * num_syms_return)
9ea033b2 5733{
ba5cdace
NC
5734 unsigned long number = 0;
5735 Elf64_External_Sym * esyms = NULL;
5736 Elf_External_Sym_Shndx * shndx = NULL;
5737 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5738 Elf_Internal_Sym * psym;
b34976b6 5739 unsigned int j;
e3d39609 5740 elf_section_list * entry;
9ea033b2 5741
c9c1d674
EG
5742 if (section->sh_size == 0)
5743 {
5744 if (num_syms_return != NULL)
5745 * num_syms_return = 0;
5746 return NULL;
5747 }
5748
dd24e3da 5749 /* Run some sanity checks first. */
c9c1d674 5750 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5751 {
c9c1d674 5752 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5753 printable_section_name (filedata, section),
8066deb1 5754 (unsigned long) section->sh_entsize);
ba5cdace 5755 goto exit_point;
dd24e3da
NC
5756 }
5757
dda8d76d 5758 if (section->sh_size > filedata->file_size)
f54498b4
NC
5759 {
5760 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5761 printable_section_name (filedata, section),
8066deb1 5762 (unsigned long) section->sh_size);
f54498b4
NC
5763 goto exit_point;
5764 }
5765
dd24e3da
NC
5766 number = section->sh_size / section->sh_entsize;
5767
5768 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5769 {
c9c1d674 5770 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5771 (unsigned long) section->sh_size,
dda8d76d 5772 printable_section_name (filedata, section),
8066deb1 5773 (unsigned long) section->sh_entsize);
ba5cdace 5774 goto exit_point;
dd24e3da
NC
5775 }
5776
dda8d76d 5777 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5778 section->sh_size, _("symbols"));
a6e9f9df 5779 if (!esyms)
ba5cdace 5780 goto exit_point;
9ea033b2 5781
e3d39609 5782 shndx = NULL;
978c4450 5783 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5784 {
5785 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5786 continue;
5787
5788 if (shndx != NULL)
5789 {
5790 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5791 free (shndx);
c9c1d674 5792 }
e3d39609
NC
5793
5794 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5795 entry->hdr->sh_offset,
5796 1, entry->hdr->sh_size,
5797 _("symbol table section indices"));
5798 if (shndx == NULL)
5799 goto exit_point;
5800
5801 /* PR17531: file: heap-buffer-overflow */
5802 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5803 {
5804 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5805 printable_section_name (filedata, entry->hdr),
5806 (unsigned long) entry->hdr->sh_size,
5807 (unsigned long) section->sh_size);
5808 goto exit_point;
5809 }
5810 }
9ad5cbcf 5811
3f5e193b 5812 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5813
5814 if (isyms == NULL)
5815 {
8b73c356
NC
5816 error (_("Out of memory reading %lu symbols\n"),
5817 (unsigned long) number);
ba5cdace 5818 goto exit_point;
9ea033b2
NC
5819 }
5820
ba5cdace 5821 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5822 {
5823 psym->st_name = BYTE_GET (esyms[j].st_name);
5824 psym->st_info = BYTE_GET (esyms[j].st_info);
5825 psym->st_other = BYTE_GET (esyms[j].st_other);
5826 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5827
4fbb74a6 5828 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5829 psym->st_shndx
5830 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5831 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5832 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5833
66543521
AM
5834 psym->st_value = BYTE_GET (esyms[j].st_value);
5835 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5836 }
5837
ba5cdace 5838 exit_point:
e3d39609
NC
5839 free (shndx);
5840 free (esyms);
ba5cdace
NC
5841
5842 if (num_syms_return != NULL)
5843 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5844
5845 return isyms;
5846}
5847
d1133906 5848static const char *
dda8d76d 5849get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 5850{
5477e8a0 5851 static char buff[1024];
2cf0635d 5852 char * p = buff;
32ec8896
NC
5853 unsigned int field_size = is_32bit_elf ? 8 : 16;
5854 signed int sindex;
5855 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5856 bfd_vma os_flags = 0;
5857 bfd_vma proc_flags = 0;
5858 bfd_vma unknown_flags = 0;
148b93f2 5859 static const struct
5477e8a0 5860 {
2cf0635d 5861 const char * str;
32ec8896 5862 unsigned int len;
5477e8a0
L
5863 }
5864 flags [] =
5865 {
cfcac11d
NC
5866 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5867 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5868 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5869 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5870 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5871 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5872 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5873 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5874 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5875 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5876 /* IA-64 specific. */
5877 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5878 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5879 /* IA-64 OpenVMS specific. */
5880 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5881 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5882 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5883 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5884 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5885 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5886 /* Generic. */
cfcac11d 5887 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5888 /* SPARC specific. */
77115a4a 5889 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
5890 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
5891 /* ARM specific. */
5892 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 5893 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
5894 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
5895 /* GNU specific. */
5896 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
5897 /* VLE specific. */
5898 /* 25 */ { STRING_COMMA_LEN ("VLE") },
5477e8a0
L
5899 };
5900
5901 if (do_section_details)
5902 {
8d5ff12c
L
5903 sprintf (buff, "[%*.*lx]: ",
5904 field_size, field_size, (unsigned long) sh_flags);
5905 p += field_size + 4;
5477e8a0 5906 }
76da6bbe 5907
d1133906
NC
5908 while (sh_flags)
5909 {
5910 bfd_vma flag;
5911
5912 flag = sh_flags & - sh_flags;
5913 sh_flags &= ~ flag;
76da6bbe 5914
5477e8a0 5915 if (do_section_details)
d1133906 5916 {
5477e8a0
L
5917 switch (flag)
5918 {
91d6fa6a
NC
5919 case SHF_WRITE: sindex = 0; break;
5920 case SHF_ALLOC: sindex = 1; break;
5921 case SHF_EXECINSTR: sindex = 2; break;
5922 case SHF_MERGE: sindex = 3; break;
5923 case SHF_STRINGS: sindex = 4; break;
5924 case SHF_INFO_LINK: sindex = 5; break;
5925 case SHF_LINK_ORDER: sindex = 6; break;
5926 case SHF_OS_NONCONFORMING: sindex = 7; break;
5927 case SHF_GROUP: sindex = 8; break;
5928 case SHF_TLS: sindex = 9; break;
18ae9cc1 5929 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 5930 case SHF_COMPRESSED: sindex = 20; break;
a91e1603 5931 case SHF_GNU_MBIND: sindex = 24; break;
76da6bbe 5932
5477e8a0 5933 default:
91d6fa6a 5934 sindex = -1;
dda8d76d 5935 switch (filedata->file_header.e_machine)
148b93f2 5936 {
cfcac11d 5937 case EM_IA_64:
148b93f2 5938 if (flag == SHF_IA_64_SHORT)
91d6fa6a 5939 sindex = 10;
148b93f2 5940 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 5941 sindex = 11;
148b93f2 5942#ifdef BFD64
dda8d76d 5943 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
5944 switch (flag)
5945 {
91d6fa6a
NC
5946 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
5947 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
5948 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
5949 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
5950 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
5951 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
5952 default: break;
5953 }
5954#endif
cfcac11d
NC
5955 break;
5956
caa83f8b 5957 case EM_386:
22abe556 5958 case EM_IAMCU:
caa83f8b 5959 case EM_X86_64:
7f502d6c 5960 case EM_L1OM:
7a9068fe 5961 case EM_K1OM:
cfcac11d
NC
5962 case EM_OLD_SPARCV9:
5963 case EM_SPARC32PLUS:
5964 case EM_SPARCV9:
5965 case EM_SPARC:
18ae9cc1 5966 if (flag == SHF_ORDERED)
91d6fa6a 5967 sindex = 19;
cfcac11d 5968 break;
ac4c9b04
MG
5969
5970 case EM_ARM:
5971 switch (flag)
5972 {
5973 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 5974 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
5975 case SHF_COMDEF: sindex = 23; break;
5976 default: break;
5977 }
5978 break;
83eef883
AFB
5979 case EM_PPC:
5980 if (flag == SHF_PPC_VLE)
5981 sindex = 25;
5982 break;
ac4c9b04 5983
cfcac11d
NC
5984 default:
5985 break;
148b93f2 5986 }
5477e8a0
L
5987 }
5988
91d6fa6a 5989 if (sindex != -1)
5477e8a0 5990 {
8d5ff12c
L
5991 if (p != buff + field_size + 4)
5992 {
5993 if (size < (10 + 2))
bee0ee85
NC
5994 {
5995 warn (_("Internal error: not enough buffer room for section flag info"));
5996 return _("<unknown>");
5997 }
8d5ff12c
L
5998 size -= 2;
5999 *p++ = ',';
6000 *p++ = ' ';
6001 }
6002
91d6fa6a
NC
6003 size -= flags [sindex].len;
6004 p = stpcpy (p, flags [sindex].str);
5477e8a0 6005 }
3b22753a 6006 else if (flag & SHF_MASKOS)
8d5ff12c 6007 os_flags |= flag;
d1133906 6008 else if (flag & SHF_MASKPROC)
8d5ff12c 6009 proc_flags |= flag;
d1133906 6010 else
8d5ff12c 6011 unknown_flags |= flag;
5477e8a0
L
6012 }
6013 else
6014 {
6015 switch (flag)
6016 {
6017 case SHF_WRITE: *p = 'W'; break;
6018 case SHF_ALLOC: *p = 'A'; break;
6019 case SHF_EXECINSTR: *p = 'X'; break;
6020 case SHF_MERGE: *p = 'M'; break;
6021 case SHF_STRINGS: *p = 'S'; break;
6022 case SHF_INFO_LINK: *p = 'I'; break;
6023 case SHF_LINK_ORDER: *p = 'L'; break;
6024 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6025 case SHF_GROUP: *p = 'G'; break;
6026 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6027 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6028 case SHF_COMPRESSED: *p = 'C'; break;
a91e1603 6029 case SHF_GNU_MBIND: *p = 'D'; break;
5477e8a0
L
6030
6031 default:
dda8d76d
NC
6032 if ((filedata->file_header.e_machine == EM_X86_64
6033 || filedata->file_header.e_machine == EM_L1OM
6034 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6035 && flag == SHF_X86_64_LARGE)
6036 *p = 'l';
dda8d76d 6037 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6038 && flag == SHF_ARM_PURECODE)
91f68a68 6039 *p = 'y';
dda8d76d 6040 else if (filedata->file_header.e_machine == EM_PPC
83eef883
AFB
6041 && flag == SHF_PPC_VLE)
6042 *p = 'v';
5477e8a0
L
6043 else if (flag & SHF_MASKOS)
6044 {
6045 *p = 'o';
6046 sh_flags &= ~ SHF_MASKOS;
6047 }
6048 else if (flag & SHF_MASKPROC)
6049 {
6050 *p = 'p';
6051 sh_flags &= ~ SHF_MASKPROC;
6052 }
6053 else
6054 *p = 'x';
6055 break;
6056 }
6057 p++;
d1133906
NC
6058 }
6059 }
76da6bbe 6060
8d5ff12c
L
6061 if (do_section_details)
6062 {
6063 if (os_flags)
6064 {
6065 size -= 5 + field_size;
6066 if (p != buff + field_size + 4)
6067 {
6068 if (size < (2 + 1))
bee0ee85
NC
6069 {
6070 warn (_("Internal error: not enough buffer room for section flag info"));
6071 return _("<unknown>");
6072 }
8d5ff12c
L
6073 size -= 2;
6074 *p++ = ',';
6075 *p++ = ' ';
6076 }
6077 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6078 (unsigned long) os_flags);
6079 p += 5 + field_size;
6080 }
6081 if (proc_flags)
6082 {
6083 size -= 7 + field_size;
6084 if (p != buff + field_size + 4)
6085 {
6086 if (size < (2 + 1))
bee0ee85
NC
6087 {
6088 warn (_("Internal error: not enough buffer room for section flag info"));
6089 return _("<unknown>");
6090 }
8d5ff12c
L
6091 size -= 2;
6092 *p++ = ',';
6093 *p++ = ' ';
6094 }
6095 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6096 (unsigned long) proc_flags);
6097 p += 7 + field_size;
6098 }
6099 if (unknown_flags)
6100 {
6101 size -= 10 + field_size;
6102 if (p != buff + field_size + 4)
6103 {
6104 if (size < (2 + 1))
bee0ee85
NC
6105 {
6106 warn (_("Internal error: not enough buffer room for section flag info"));
6107 return _("<unknown>");
6108 }
8d5ff12c
L
6109 size -= 2;
6110 *p++ = ',';
6111 *p++ = ' ';
6112 }
2b692964 6113 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6114 (unsigned long) unknown_flags);
6115 p += 10 + field_size;
6116 }
6117 }
6118
e9e44622 6119 *p = '\0';
d1133906
NC
6120 return buff;
6121}
6122
5844b465 6123static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6124get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6125{
6126 if (is_32bit_elf)
6127 {
6128 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6129
ebdf1ebf
NC
6130 if (size < sizeof (* echdr))
6131 {
6132 error (_("Compressed section is too small even for a compression header\n"));
6133 return 0;
6134 }
6135
77115a4a
L
6136 chdr->ch_type = BYTE_GET (echdr->ch_type);
6137 chdr->ch_size = BYTE_GET (echdr->ch_size);
6138 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6139 return sizeof (*echdr);
6140 }
6141 else
6142 {
6143 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6144
ebdf1ebf
NC
6145 if (size < sizeof (* echdr))
6146 {
6147 error (_("Compressed section is too small even for a compression header\n"));
6148 return 0;
6149 }
6150
77115a4a
L
6151 chdr->ch_type = BYTE_GET (echdr->ch_type);
6152 chdr->ch_size = BYTE_GET (echdr->ch_size);
6153 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6154 return sizeof (*echdr);
6155 }
6156}
6157
32ec8896 6158static bfd_boolean
dda8d76d 6159process_section_headers (Filedata * filedata)
252b5132 6160{
2cf0635d 6161 Elf_Internal_Shdr * section;
b34976b6 6162 unsigned int i;
252b5132 6163
8fb879cd 6164 free (filedata->section_headers);
dda8d76d 6165 filedata->section_headers = NULL;
978c4450
AM
6166 free (filedata->dynamic_symbols);
6167 filedata->dynamic_symbols = NULL;
6168 filedata->num_dynamic_syms = 0;
6169 free (filedata->dynamic_strings);
6170 filedata->dynamic_strings = NULL;
6171 filedata->dynamic_strings_length = 0;
6172 free (filedata->dynamic_syminfo);
6173 filedata->dynamic_syminfo = NULL;
6174 while (filedata->symtab_shndx_list != NULL)
8ff66993 6175 {
978c4450
AM
6176 elf_section_list *next = filedata->symtab_shndx_list->next;
6177 free (filedata->symtab_shndx_list);
6178 filedata->symtab_shndx_list = next;
8ff66993 6179 }
252b5132 6180
dda8d76d 6181 if (filedata->file_header.e_shnum == 0)
252b5132 6182 {
82f2dbf7 6183 /* PR binutils/12467. */
dda8d76d 6184 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6185 {
6186 warn (_("possibly corrupt ELF file header - it has a non-zero"
6187 " section header offset, but no section headers\n"));
6188 return FALSE;
6189 }
82f2dbf7 6190 else if (do_sections)
252b5132
RH
6191 printf (_("\nThere are no sections in this file.\n"));
6192
32ec8896 6193 return TRUE;
252b5132
RH
6194 }
6195
6196 if (do_sections && !do_header)
d3a49aa8
AM
6197 printf (ngettext ("There is %d section header, "
6198 "starting at offset 0x%lx:\n",
6199 "There are %d section headers, "
6200 "starting at offset 0x%lx:\n",
dda8d76d
NC
6201 filedata->file_header.e_shnum),
6202 filedata->file_header.e_shnum,
6203 (unsigned long) filedata->file_header.e_shoff);
252b5132 6204
9ea033b2
NC
6205 if (is_32bit_elf)
6206 {
dda8d76d 6207 if (! get_32bit_section_headers (filedata, FALSE))
32ec8896
NC
6208 return FALSE;
6209 }
6210 else
6211 {
dda8d76d 6212 if (! get_64bit_section_headers (filedata, FALSE))
32ec8896 6213 return FALSE;
9ea033b2 6214 }
252b5132
RH
6215
6216 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6217 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6218 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6219 {
dda8d76d 6220 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6221
c256ffe7
JJ
6222 if (section->sh_size != 0)
6223 {
dda8d76d
NC
6224 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6225 1, section->sh_size,
6226 _("string table"));
0de14b54 6227
dda8d76d 6228 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6229 }
252b5132
RH
6230 }
6231
6232 /* Scan the sections for the dynamic symbol table
e3c8793a 6233 and dynamic string table and debug sections. */
89fac5e3 6234 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6235 switch (filedata->file_header.e_machine)
89fac5e3
RS
6236 {
6237 case EM_MIPS:
6238 case EM_MIPS_RS3_LE:
6239 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6240 FDE addresses. However, the ABI also has a semi-official ILP32
6241 variant for which the normal FDE address size rules apply.
6242
6243 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6244 section, where XX is the size of longs in bits. Unfortunately,
6245 earlier compilers provided no way of distinguishing ILP32 objects
6246 from LP64 objects, so if there's any doubt, we should assume that
6247 the official LP64 form is being used. */
dda8d76d
NC
6248 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6249 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6250 eh_addr_size = 8;
6251 break;
0f56a26a
DD
6252
6253 case EM_H8_300:
6254 case EM_H8_300H:
dda8d76d 6255 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6256 {
6257 case E_H8_MACH_H8300:
6258 case E_H8_MACH_H8300HN:
6259 case E_H8_MACH_H8300SN:
6260 case E_H8_MACH_H8300SXN:
6261 eh_addr_size = 2;
6262 break;
6263 case E_H8_MACH_H8300H:
6264 case E_H8_MACH_H8300S:
6265 case E_H8_MACH_H8300SX:
6266 eh_addr_size = 4;
6267 break;
6268 }
f4236fe4
DD
6269 break;
6270
ff7eeb89 6271 case EM_M32C_OLD:
f4236fe4 6272 case EM_M32C:
dda8d76d 6273 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6274 {
6275 case EF_M32C_CPU_M16C:
6276 eh_addr_size = 2;
6277 break;
6278 }
6279 break;
89fac5e3
RS
6280 }
6281
76ca31c0
NC
6282#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6283 do \
6284 { \
6285 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6286 if (section->sh_entsize != expected_entsize) \
9dd3a467 6287 { \
76ca31c0
NC
6288 char buf[40]; \
6289 sprintf_vma (buf, section->sh_entsize); \
6290 /* Note: coded this way so that there is a single string for \
6291 translation. */ \
6292 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6293 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6294 (unsigned) expected_entsize); \
9dd3a467 6295 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6296 } \
6297 } \
08d8fa11 6298 while (0)
9dd3a467
NC
6299
6300#define CHECK_ENTSIZE(section, i, type) \
1b513401 6301 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
6302 sizeof (Elf64_External_##type))
6303
dda8d76d
NC
6304 for (i = 0, section = filedata->section_headers;
6305 i < filedata->file_header.e_shnum;
b34976b6 6306 i++, section++)
252b5132 6307 {
2cf0635d 6308 char * name = SECTION_NAME (section);
252b5132 6309
1b513401
NC
6310 /* Run some sanity checks on the headers and
6311 possibly fill in some file data as well. */
6312 switch (section->sh_type)
252b5132 6313 {
1b513401 6314 case SHT_DYNSYM:
978c4450 6315 if (filedata->dynamic_symbols != NULL)
252b5132
RH
6316 {
6317 error (_("File contains multiple dynamic symbol tables\n"));
6318 continue;
6319 }
6320
08d8fa11 6321 CHECK_ENTSIZE (section, i, Sym);
978c4450
AM
6322 filedata->dynamic_symbols
6323 = GET_ELF_SYMBOLS (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 6324 filedata->dynamic_symtab_section = section;
1b513401
NC
6325 break;
6326
6327 case SHT_STRTAB:
6328 if (streq (name, ".dynstr"))
252b5132 6329 {
1b513401
NC
6330 if (filedata->dynamic_strings != NULL)
6331 {
6332 error (_("File contains multiple dynamic string tables\n"));
6333 continue;
6334 }
6335
6336 filedata->dynamic_strings
6337 = (char *) get_data (NULL, filedata, section->sh_offset,
6338 1, section->sh_size, _("dynamic strings"));
6339 filedata->dynamic_strings_length
6340 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 6341 filedata->dynamic_strtab_section = section;
252b5132 6342 }
1b513401
NC
6343 break;
6344
6345 case SHT_SYMTAB_SHNDX:
6346 {
6347 elf_section_list * entry = xmalloc (sizeof * entry);
6348
6349 entry->hdr = section;
6350 entry->next = filedata->symtab_shndx_list;
6351 filedata->symtab_shndx_list = entry;
6352 }
6353 break;
6354
6355 case SHT_SYMTAB:
6356 CHECK_ENTSIZE (section, i, Sym);
6357 break;
6358
6359 case SHT_GROUP:
6360 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6361 break;
252b5132 6362
1b513401
NC
6363 case SHT_REL:
6364 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 6365 if (do_checks && section->sh_size == 0)
1b513401
NC
6366 warn (_("Section '%s': zero-sized relocation section\n"), name);
6367 break;
6368
6369 case SHT_RELA:
6370 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 6371 if (do_checks && section->sh_size == 0)
1b513401
NC
6372 warn (_("Section '%s': zero-sized relocation section\n"), name);
6373 break;
6374
6375 case SHT_NOTE:
6376 case SHT_PROGBITS:
546cb2d8
NC
6377 /* Having a zero sized section is not illegal according to the
6378 ELF standard, but it might be an indication that something
6379 is wrong. So issue a warning if we are running in lint mode. */
6380 if (do_checks && section->sh_size == 0)
1b513401
NC
6381 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
6382 break;
6383
6384 default:
6385 break;
6386 }
6387
6388 if ((do_debugging || do_debug_info || do_debug_abbrevs
6389 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
6390 || do_debug_aranges || do_debug_frames || do_debug_macinfo
6391 || do_debug_str || do_debug_loc || do_debug_ranges
6392 || do_debug_addr || do_debug_cu_index || do_debug_links)
6393 && (const_strneq (name, ".debug_")
6394 || const_strneq (name, ".zdebug_")))
252b5132 6395 {
1b315056
CS
6396 if (name[1] == 'z')
6397 name += sizeof (".zdebug_") - 1;
6398 else
6399 name += sizeof (".debug_") - 1;
252b5132
RH
6400
6401 if (do_debugging
4723351a
CC
6402 || (do_debug_info && const_strneq (name, "info"))
6403 || (do_debug_info && const_strneq (name, "types"))
6404 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
6405 || (do_debug_lines && strcmp (name, "line") == 0)
6406 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
6407 || (do_debug_pubnames && const_strneq (name, "pubnames"))
6408 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
6409 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
6410 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
6411 || (do_debug_aranges && const_strneq (name, "aranges"))
6412 || (do_debug_ranges && const_strneq (name, "ranges"))
77145576 6413 || (do_debug_ranges && const_strneq (name, "rnglists"))
4723351a
CC
6414 || (do_debug_frames && const_strneq (name, "frame"))
6415 || (do_debug_macinfo && const_strneq (name, "macinfo"))
6416 || (do_debug_macinfo && const_strneq (name, "macro"))
6417 || (do_debug_str && const_strneq (name, "str"))
6418 || (do_debug_loc && const_strneq (name, "loc"))
77145576 6419 || (do_debug_loc && const_strneq (name, "loclists"))
657d0d47
CC
6420 || (do_debug_addr && const_strneq (name, "addr"))
6421 || (do_debug_cu_index && const_strneq (name, "cu_index"))
6422 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 6423 )
6431e409 6424 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6425 }
a262ae96 6426 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6427 else if ((do_debugging || do_debug_info)
0112cd26 6428 && const_strneq (name, ".gnu.linkonce.wi."))
6431e409 6429 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6430 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6431 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6432 else if (do_gdb_index && (streq (name, ".gdb_index")
6433 || streq (name, ".debug_names")))
6431e409 6434 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6435 /* Trace sections for Itanium VMS. */
6436 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6437 || do_trace_aranges)
6438 && const_strneq (name, ".trace_"))
6439 {
6440 name += sizeof (".trace_") - 1;
6441
6442 if (do_debugging
6443 || (do_trace_info && streq (name, "info"))
6444 || (do_trace_abbrevs && streq (name, "abbrev"))
6445 || (do_trace_aranges && streq (name, "aranges"))
6446 )
6431e409 6447 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6448 }
dda8d76d
NC
6449 else if ((do_debugging || do_debug_links)
6450 && (const_strneq (name, ".gnu_debuglink")
6451 || const_strneq (name, ".gnu_debugaltlink")))
6431e409 6452 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6453 }
6454
6455 if (! do_sections)
32ec8896 6456 return TRUE;
252b5132 6457
dda8d76d 6458 if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6459 printf (_("\nSection Headers:\n"));
6460 else
6461 printf (_("\nSection Header:\n"));
76da6bbe 6462
f7a99963 6463 if (is_32bit_elf)
595cf52e 6464 {
5477e8a0 6465 if (do_section_details)
595cf52e
L
6466 {
6467 printf (_(" [Nr] Name\n"));
5477e8a0 6468 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6469 }
6470 else
6471 printf
6472 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6473 }
d974e256 6474 else if (do_wide)
595cf52e 6475 {
5477e8a0 6476 if (do_section_details)
595cf52e
L
6477 {
6478 printf (_(" [Nr] Name\n"));
5477e8a0 6479 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6480 }
6481 else
6482 printf
6483 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6484 }
f7a99963
NC
6485 else
6486 {
5477e8a0 6487 if (do_section_details)
595cf52e
L
6488 {
6489 printf (_(" [Nr] Name\n"));
5477e8a0
L
6490 printf (_(" Type Address Offset Link\n"));
6491 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6492 }
6493 else
6494 {
6495 printf (_(" [Nr] Name Type Address Offset\n"));
6496 printf (_(" Size EntSize Flags Link Info Align\n"));
6497 }
f7a99963 6498 }
252b5132 6499
5477e8a0
L
6500 if (do_section_details)
6501 printf (_(" Flags\n"));
6502
dda8d76d
NC
6503 for (i = 0, section = filedata->section_headers;
6504 i < filedata->file_header.e_shnum;
b34976b6 6505 i++, section++)
252b5132 6506 {
dd905818
NC
6507 /* Run some sanity checks on the section header. */
6508
6509 /* Check the sh_link field. */
6510 switch (section->sh_type)
6511 {
285e3f99
AM
6512 case SHT_REL:
6513 case SHT_RELA:
6514 if (section->sh_link == 0
6515 && (filedata->file_header.e_type == ET_EXEC
6516 || filedata->file_header.e_type == ET_DYN))
6517 /* A dynamic relocation section where all entries use a
6518 zero symbol index need not specify a symtab section. */
6519 break;
6520 /* Fall through. */
dd905818
NC
6521 case SHT_SYMTAB_SHNDX:
6522 case SHT_GROUP:
6523 case SHT_HASH:
6524 case SHT_GNU_HASH:
6525 case SHT_GNU_versym:
285e3f99 6526 if (section->sh_link == 0
dda8d76d
NC
6527 || section->sh_link >= filedata->file_header.e_shnum
6528 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6529 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6530 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6531 i, section->sh_link);
6532 break;
6533
6534 case SHT_DYNAMIC:
6535 case SHT_SYMTAB:
6536 case SHT_DYNSYM:
6537 case SHT_GNU_verneed:
6538 case SHT_GNU_verdef:
6539 case SHT_GNU_LIBLIST:
285e3f99 6540 if (section->sh_link == 0
dda8d76d
NC
6541 || section->sh_link >= filedata->file_header.e_shnum
6542 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6543 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6544 i, section->sh_link);
6545 break;
6546
6547 case SHT_INIT_ARRAY:
6548 case SHT_FINI_ARRAY:
6549 case SHT_PREINIT_ARRAY:
6550 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6551 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6552 i, section->sh_link);
6553 break;
6554
6555 default:
6556 /* FIXME: Add support for target specific section types. */
6557#if 0 /* Currently we do not check other section types as there are too
6558 many special cases. Stab sections for example have a type
6559 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6560 section. */
6561 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6562 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6563 i, section->sh_link);
6564#endif
6565 break;
6566 }
6567
6568 /* Check the sh_info field. */
6569 switch (section->sh_type)
6570 {
6571 case SHT_REL:
6572 case SHT_RELA:
285e3f99
AM
6573 if (section->sh_info == 0
6574 && (filedata->file_header.e_type == ET_EXEC
6575 || filedata->file_header.e_type == ET_DYN))
6576 /* Dynamic relocations apply to segments, so they do not
6577 need to specify the section they relocate. */
6578 break;
6579 if (section->sh_info == 0
dda8d76d
NC
6580 || section->sh_info >= filedata->file_header.e_shnum
6581 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6582 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6583 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6584 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6585 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6586 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6587 /* FIXME: Are other section types valid ? */
dda8d76d 6588 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6589 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6590 i, section->sh_info);
dd905818
NC
6591 break;
6592
6593 case SHT_DYNAMIC:
6594 case SHT_HASH:
6595 case SHT_SYMTAB_SHNDX:
6596 case SHT_INIT_ARRAY:
6597 case SHT_FINI_ARRAY:
6598 case SHT_PREINIT_ARRAY:
6599 if (section->sh_info != 0)
6600 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6601 i, section->sh_info);
6602 break;
6603
6604 case SHT_GROUP:
6605 case SHT_SYMTAB:
6606 case SHT_DYNSYM:
6607 /* A symbol index - we assume that it is valid. */
6608 break;
6609
6610 default:
6611 /* FIXME: Add support for target specific section types. */
6612 if (section->sh_type == SHT_NOBITS)
6613 /* NOBITS section headers with non-zero sh_info fields can be
6614 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6615 information. The stripped sections have their headers
6616 preserved but their types set to SHT_NOBITS. So do not check
6617 this type of section. */
dd905818
NC
6618 ;
6619 else if (section->sh_flags & SHF_INFO_LINK)
6620 {
dda8d76d 6621 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6622 warn (_("[%2u]: Expected link to another section in info field"), i);
6623 }
a91e1603
L
6624 else if (section->sh_type < SHT_LOOS
6625 && (section->sh_flags & SHF_GNU_MBIND) == 0
6626 && section->sh_info != 0)
dd905818
NC
6627 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6628 i, section->sh_info);
6629 break;
6630 }
6631
3e6b6445 6632 /* Check the sh_size field. */
dda8d76d 6633 if (section->sh_size > filedata->file_size
3e6b6445
NC
6634 && section->sh_type != SHT_NOBITS
6635 && section->sh_type != SHT_NULL
6636 && section->sh_type < SHT_LOOS)
6637 warn (_("Size of section %u is larger than the entire file!\n"), i);
6638
7bfd842d 6639 printf (" [%2u] ", i);
5477e8a0 6640 if (do_section_details)
dda8d76d 6641 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6642 else
74e1a04b 6643 print_symbol (-17, SECTION_NAME (section));
0b4362b0 6644
ea52a088 6645 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6646 get_section_type_name (filedata, section->sh_type));
0b4362b0 6647
f7a99963
NC
6648 if (is_32bit_elf)
6649 {
cfcac11d
NC
6650 const char * link_too_big = NULL;
6651
f7a99963 6652 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6653
f7a99963
NC
6654 printf ( " %6.6lx %6.6lx %2.2lx",
6655 (unsigned long) section->sh_offset,
6656 (unsigned long) section->sh_size,
6657 (unsigned long) section->sh_entsize);
d1133906 6658
5477e8a0
L
6659 if (do_section_details)
6660 fputs (" ", stdout);
6661 else
dda8d76d 6662 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6663
dda8d76d 6664 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6665 {
6666 link_too_big = "";
6667 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6668 an error but it can have special values in Solaris binaries. */
dda8d76d 6669 switch (filedata->file_header.e_machine)
cfcac11d 6670 {
caa83f8b 6671 case EM_386:
22abe556 6672 case EM_IAMCU:
caa83f8b 6673 case EM_X86_64:
7f502d6c 6674 case EM_L1OM:
7a9068fe 6675 case EM_K1OM:
cfcac11d
NC
6676 case EM_OLD_SPARCV9:
6677 case EM_SPARC32PLUS:
6678 case EM_SPARCV9:
6679 case EM_SPARC:
6680 if (section->sh_link == (SHN_BEFORE & 0xffff))
6681 link_too_big = "BEFORE";
6682 else if (section->sh_link == (SHN_AFTER & 0xffff))
6683 link_too_big = "AFTER";
6684 break;
6685 default:
6686 break;
6687 }
6688 }
6689
6690 if (do_section_details)
6691 {
6692 if (link_too_big != NULL && * link_too_big)
6693 printf ("<%s> ", link_too_big);
6694 else
6695 printf ("%2u ", section->sh_link);
6696 printf ("%3u %2lu\n", section->sh_info,
6697 (unsigned long) section->sh_addralign);
6698 }
6699 else
6700 printf ("%2u %3u %2lu\n",
6701 section->sh_link,
6702 section->sh_info,
6703 (unsigned long) section->sh_addralign);
6704
6705 if (link_too_big && ! * link_too_big)
6706 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6707 i, section->sh_link);
f7a99963 6708 }
d974e256
JJ
6709 else if (do_wide)
6710 {
6711 print_vma (section->sh_addr, LONG_HEX);
6712
6713 if ((long) section->sh_offset == section->sh_offset)
6714 printf (" %6.6lx", (unsigned long) section->sh_offset);
6715 else
6716 {
6717 putchar (' ');
6718 print_vma (section->sh_offset, LONG_HEX);
6719 }
6720
6721 if ((unsigned long) section->sh_size == section->sh_size)
6722 printf (" %6.6lx", (unsigned long) section->sh_size);
6723 else
6724 {
6725 putchar (' ');
6726 print_vma (section->sh_size, LONG_HEX);
6727 }
6728
6729 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6730 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6731 else
6732 {
6733 putchar (' ');
6734 print_vma (section->sh_entsize, LONG_HEX);
6735 }
6736
5477e8a0
L
6737 if (do_section_details)
6738 fputs (" ", stdout);
6739 else
dda8d76d 6740 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6741
72de5009 6742 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6743
6744 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6745 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6746 else
6747 {
6748 print_vma (section->sh_addralign, DEC);
6749 putchar ('\n');
6750 }
6751 }
5477e8a0 6752 else if (do_section_details)
595cf52e 6753 {
55cc53e9 6754 putchar (' ');
595cf52e
L
6755 print_vma (section->sh_addr, LONG_HEX);
6756 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 6757 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
6758 else
6759 {
6760 printf (" ");
6761 print_vma (section->sh_offset, LONG_HEX);
6762 }
72de5009 6763 printf (" %u\n ", section->sh_link);
595cf52e 6764 print_vma (section->sh_size, LONG_HEX);
5477e8a0 6765 putchar (' ');
595cf52e
L
6766 print_vma (section->sh_entsize, LONG_HEX);
6767
72de5009
AM
6768 printf (" %-16u %lu\n",
6769 section->sh_info,
595cf52e
L
6770 (unsigned long) section->sh_addralign);
6771 }
f7a99963
NC
6772 else
6773 {
6774 putchar (' ');
6775 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
6776 if ((long) section->sh_offset == section->sh_offset)
6777 printf (" %8.8lx", (unsigned long) section->sh_offset);
6778 else
6779 {
6780 printf (" ");
6781 print_vma (section->sh_offset, LONG_HEX);
6782 }
f7a99963
NC
6783 printf ("\n ");
6784 print_vma (section->sh_size, LONG_HEX);
6785 printf (" ");
6786 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 6787
dda8d76d 6788 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6789
72de5009
AM
6790 printf (" %2u %3u %lu\n",
6791 section->sh_link,
6792 section->sh_info,
f7a99963
NC
6793 (unsigned long) section->sh_addralign);
6794 }
5477e8a0
L
6795
6796 if (do_section_details)
77115a4a 6797 {
dda8d76d 6798 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
6799 if ((section->sh_flags & SHF_COMPRESSED) != 0)
6800 {
6801 /* Minimum section size is 12 bytes for 32-bit compression
6802 header + 12 bytes for compressed data header. */
6803 unsigned char buf[24];
d8024a91 6804
77115a4a 6805 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 6806 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
6807 sizeof (buf), _("compression header")))
6808 {
6809 Elf_Internal_Chdr chdr;
d8024a91 6810
5844b465
NC
6811 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
6812 printf (_(" [<corrupt>]\n"));
77115a4a 6813 else
5844b465
NC
6814 {
6815 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
6816 printf (" ZLIB, ");
6817 else
6818 printf (_(" [<unknown>: 0x%x], "),
6819 chdr.ch_type);
6820 print_vma (chdr.ch_size, LONG_HEX);
6821 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
6822 }
77115a4a
L
6823 }
6824 }
6825 }
252b5132
RH
6826 }
6827
5477e8a0 6828 if (!do_section_details)
3dbcc61d 6829 {
9fb71ee4
NC
6830 /* The ordering of the letters shown here matches the ordering of the
6831 corresponding SHF_xxx values, and hence the order in which these
6832 letters will be displayed to the user. */
6833 printf (_("Key to Flags:\n\
6834 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
6835 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 6836 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
dda8d76d
NC
6837 if (filedata->file_header.e_machine == EM_X86_64
6838 || filedata->file_header.e_machine == EM_L1OM
6839 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 6840 printf (_("l (large), "));
dda8d76d 6841 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 6842 printf (_("y (purecode), "));
dda8d76d 6843 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 6844 printf (_("v (VLE), "));
9fb71ee4 6845 printf ("p (processor specific)\n");
0b4362b0 6846 }
d1133906 6847
32ec8896 6848 return TRUE;
252b5132
RH
6849}
6850
28d13567
AM
6851static bfd_boolean
6852get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
6853 Elf_Internal_Sym **symtab, unsigned long *nsyms,
6854 char **strtab, unsigned long *strtablen)
6855{
6856 *strtab = NULL;
6857 *strtablen = 0;
6858 *symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms);
6859
6860 if (*symtab == NULL)
6861 return FALSE;
6862
6863 if (symsec->sh_link != 0)
6864 {
6865 Elf_Internal_Shdr *strsec;
6866
6867 if (symsec->sh_link >= filedata->file_header.e_shnum)
6868 {
6869 error (_("Bad sh_link in symbol table section\n"));
6870 free (*symtab);
6871 *symtab = NULL;
6872 *nsyms = 0;
6873 return FALSE;
6874 }
6875
6876 strsec = filedata->section_headers + symsec->sh_link;
6877
6878 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
6879 1, strsec->sh_size, _("string table"));
6880 if (*strtab == NULL)
6881 {
6882 free (*symtab);
6883 *symtab = NULL;
6884 *nsyms = 0;
6885 return FALSE;
6886 }
6887 *strtablen = strsec->sh_size;
6888 }
6889 return TRUE;
6890}
6891
f5842774
L
6892static const char *
6893get_group_flags (unsigned int flags)
6894{
1449284b 6895 static char buff[128];
220453ec 6896
6d913794
NC
6897 if (flags == 0)
6898 return "";
6899 else if (flags == GRP_COMDAT)
6900 return "COMDAT ";
f5842774 6901
89246a0e
AM
6902 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
6903 flags,
6904 flags & GRP_MASKOS ? _("<OS specific>") : "",
6905 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
6906 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
6907 ? _("<unknown>") : ""));
6d913794 6908
f5842774
L
6909 return buff;
6910}
6911
32ec8896 6912static bfd_boolean
dda8d76d 6913process_section_groups (Filedata * filedata)
f5842774 6914{
2cf0635d 6915 Elf_Internal_Shdr * section;
f5842774 6916 unsigned int i;
2cf0635d
NC
6917 struct group * group;
6918 Elf_Internal_Shdr * symtab_sec;
6919 Elf_Internal_Shdr * strtab_sec;
6920 Elf_Internal_Sym * symtab;
ba5cdace 6921 unsigned long num_syms;
2cf0635d 6922 char * strtab;
c256ffe7 6923 size_t strtab_size;
d1f5c6e3
L
6924
6925 /* Don't process section groups unless needed. */
6926 if (!do_unwind && !do_section_groups)
32ec8896 6927 return TRUE;
f5842774 6928
dda8d76d 6929 if (filedata->file_header.e_shnum == 0)
f5842774
L
6930 {
6931 if (do_section_groups)
82f2dbf7 6932 printf (_("\nThere are no sections to group in this file.\n"));
f5842774 6933
32ec8896 6934 return TRUE;
f5842774
L
6935 }
6936
dda8d76d 6937 if (filedata->section_headers == NULL)
f5842774
L
6938 {
6939 error (_("Section headers are not available!\n"));
fa1908fd 6940 /* PR 13622: This can happen with a corrupt ELF header. */
32ec8896 6941 return FALSE;
f5842774
L
6942 }
6943
978c4450
AM
6944 filedata->section_headers_groups
6945 = (struct group **) calloc (filedata->file_header.e_shnum,
6946 sizeof (struct group *));
e4b17d5c 6947
978c4450 6948 if (filedata->section_headers_groups == NULL)
e4b17d5c 6949 {
8b73c356 6950 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 6951 filedata->file_header.e_shnum);
32ec8896 6952 return FALSE;
e4b17d5c
L
6953 }
6954
f5842774 6955 /* Scan the sections for the group section. */
978c4450 6956 filedata->group_count = 0;
dda8d76d
NC
6957 for (i = 0, section = filedata->section_headers;
6958 i < filedata->file_header.e_shnum;
f5842774 6959 i++, section++)
e4b17d5c 6960 if (section->sh_type == SHT_GROUP)
978c4450 6961 filedata->group_count++;
e4b17d5c 6962
978c4450 6963 if (filedata->group_count == 0)
d1f5c6e3
L
6964 {
6965 if (do_section_groups)
6966 printf (_("\nThere are no section groups in this file.\n"));
6967
32ec8896 6968 return TRUE;
d1f5c6e3
L
6969 }
6970
978c4450
AM
6971 filedata->section_groups = (struct group *) calloc (filedata->group_count,
6972 sizeof (struct group));
e4b17d5c 6973
978c4450 6974 if (filedata->section_groups == NULL)
e4b17d5c 6975 {
8b73c356 6976 error (_("Out of memory reading %lu groups\n"),
978c4450 6977 (unsigned long) filedata->group_count);
32ec8896 6978 return FALSE;
e4b17d5c
L
6979 }
6980
d1f5c6e3
L
6981 symtab_sec = NULL;
6982 strtab_sec = NULL;
6983 symtab = NULL;
ba5cdace 6984 num_syms = 0;
d1f5c6e3 6985 strtab = NULL;
c256ffe7 6986 strtab_size = 0;
978c4450 6987 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 6988 i < filedata->file_header.e_shnum;
e4b17d5c 6989 i++, section++)
f5842774
L
6990 {
6991 if (section->sh_type == SHT_GROUP)
6992 {
dda8d76d 6993 const char * name = printable_section_name (filedata, section);
74e1a04b 6994 const char * group_name;
2cf0635d
NC
6995 unsigned char * start;
6996 unsigned char * indices;
f5842774 6997 unsigned int entry, j, size;
2cf0635d
NC
6998 Elf_Internal_Shdr * sec;
6999 Elf_Internal_Sym * sym;
f5842774
L
7000
7001 /* Get the symbol table. */
dda8d76d
NC
7002 if (section->sh_link >= filedata->file_header.e_shnum
7003 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7004 != SHT_SYMTAB))
f5842774
L
7005 {
7006 error (_("Bad sh_link in group section `%s'\n"), name);
7007 continue;
7008 }
d1f5c6e3
L
7009
7010 if (symtab_sec != sec)
7011 {
7012 symtab_sec = sec;
7013 if (symtab)
7014 free (symtab);
dda8d76d 7015 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 7016 }
f5842774 7017
dd24e3da
NC
7018 if (symtab == NULL)
7019 {
7020 error (_("Corrupt header in group section `%s'\n"), name);
7021 continue;
7022 }
7023
ba5cdace
NC
7024 if (section->sh_info >= num_syms)
7025 {
7026 error (_("Bad sh_info in group section `%s'\n"), name);
7027 continue;
7028 }
7029
f5842774
L
7030 sym = symtab + section->sh_info;
7031
7032 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7033 {
4fbb74a6 7034 if (sym->st_shndx == 0
dda8d76d 7035 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7036 {
7037 error (_("Bad sh_info in group section `%s'\n"), name);
7038 continue;
7039 }
ba2685cc 7040
dda8d76d 7041 group_name = SECTION_NAME (filedata->section_headers + sym->st_shndx);
c256ffe7
JJ
7042 strtab_sec = NULL;
7043 if (strtab)
7044 free (strtab);
f5842774 7045 strtab = NULL;
c256ffe7 7046 strtab_size = 0;
f5842774
L
7047 }
7048 else
7049 {
7050 /* Get the string table. */
dda8d76d 7051 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7052 {
7053 strtab_sec = NULL;
7054 if (strtab)
7055 free (strtab);
7056 strtab = NULL;
7057 strtab_size = 0;
7058 }
7059 else if (strtab_sec
dda8d76d 7060 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7061 {
7062 strtab_sec = sec;
7063 if (strtab)
7064 free (strtab);
071436c6 7065
dda8d76d 7066 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7067 1, strtab_sec->sh_size,
7068 _("string table"));
c256ffe7 7069 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7070 }
c256ffe7 7071 group_name = sym->st_name < strtab_size
2b692964 7072 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7073 }
7074
c9c1d674
EG
7075 /* PR 17531: file: loop. */
7076 if (section->sh_entsize > section->sh_size)
7077 {
7078 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7079 printable_section_name (filedata, section),
8066deb1
AM
7080 (unsigned long) section->sh_entsize,
7081 (unsigned long) section->sh_size);
61dd8e19 7082 continue;
c9c1d674
EG
7083 }
7084
dda8d76d 7085 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7086 1, section->sh_size,
7087 _("section data"));
59245841
NC
7088 if (start == NULL)
7089 continue;
f5842774
L
7090
7091 indices = start;
7092 size = (section->sh_size / section->sh_entsize) - 1;
7093 entry = byte_get (indices, 4);
7094 indices += 4;
e4b17d5c
L
7095
7096 if (do_section_groups)
7097 {
2b692964 7098 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7099 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7100
e4b17d5c
L
7101 printf (_(" [Index] Name\n"));
7102 }
7103
7104 group->group_index = i;
7105
f5842774
L
7106 for (j = 0; j < size; j++)
7107 {
2cf0635d 7108 struct group_list * g;
e4b17d5c 7109
f5842774
L
7110 entry = byte_get (indices, 4);
7111 indices += 4;
7112
dda8d76d 7113 if (entry >= filedata->file_header.e_shnum)
391cb864 7114 {
57028622
NC
7115 static unsigned num_group_errors = 0;
7116
7117 if (num_group_errors ++ < 10)
7118 {
7119 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7120 entry, i, filedata->file_header.e_shnum - 1);
57028622 7121 if (num_group_errors == 10)
67ce483b 7122 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7123 }
391cb864
L
7124 continue;
7125 }
391cb864 7126
978c4450 7127 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7128 {
d1f5c6e3
L
7129 if (entry)
7130 {
57028622
NC
7131 static unsigned num_errs = 0;
7132
7133 if (num_errs ++ < 10)
7134 {
7135 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7136 entry, i,
978c4450 7137 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7138 if (num_errs == 10)
7139 warn (_("Further error messages about already contained group sections suppressed\n"));
7140 }
d1f5c6e3
L
7141 continue;
7142 }
7143 else
7144 {
7145 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7146 section group. We just warn it the first time
d1f5c6e3 7147 and ignore it afterwards. */
32ec8896 7148 static bfd_boolean warned = FALSE;
d1f5c6e3
L
7149 if (!warned)
7150 {
7151 error (_("section 0 in group section [%5u]\n"),
978c4450 7152 filedata->section_headers_groups [entry]->group_index);
32ec8896 7153 warned = TRUE;
d1f5c6e3
L
7154 }
7155 }
e4b17d5c
L
7156 }
7157
978c4450 7158 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7159
7160 if (do_section_groups)
7161 {
dda8d76d
NC
7162 sec = filedata->section_headers + entry;
7163 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7164 }
7165
3f5e193b 7166 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7167 g->section_index = entry;
7168 g->next = group->root;
7169 group->root = g;
f5842774
L
7170 }
7171
f5842774
L
7172 if (start)
7173 free (start);
e4b17d5c
L
7174
7175 group++;
f5842774
L
7176 }
7177 }
7178
d1f5c6e3
L
7179 if (symtab)
7180 free (symtab);
7181 if (strtab)
7182 free (strtab);
32ec8896 7183 return TRUE;
f5842774
L
7184}
7185
28f997cf
TG
7186/* Data used to display dynamic fixups. */
7187
7188struct ia64_vms_dynfixup
7189{
7190 bfd_vma needed_ident; /* Library ident number. */
7191 bfd_vma needed; /* Index in the dstrtab of the library name. */
7192 bfd_vma fixup_needed; /* Index of the library. */
7193 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7194 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7195};
7196
7197/* Data used to display dynamic relocations. */
7198
7199struct ia64_vms_dynimgrela
7200{
7201 bfd_vma img_rela_cnt; /* Number of relocations. */
7202 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7203};
7204
7205/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7206 library). */
7207
32ec8896 7208static bfd_boolean
dda8d76d
NC
7209dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7210 struct ia64_vms_dynfixup * fixup,
7211 const char * strtab,
7212 unsigned int strtab_sz)
28f997cf 7213{
32ec8896 7214 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7215 long i;
32ec8896 7216 const char * lib_name;
28f997cf 7217
978c4450
AM
7218 imfs = get_data (NULL, filedata,
7219 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7220 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7221 _("dynamic section image fixups"));
7222 if (!imfs)
32ec8896 7223 return FALSE;
28f997cf
TG
7224
7225 if (fixup->needed < strtab_sz)
7226 lib_name = strtab + fixup->needed;
7227 else
7228 {
32ec8896 7229 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7230 (unsigned long) fixup->needed);
28f997cf
TG
7231 lib_name = "???";
7232 }
736990c4 7233
28f997cf
TG
7234 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7235 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7236 printf
7237 (_("Seg Offset Type SymVec DataType\n"));
7238
7239 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7240 {
7241 unsigned int type;
7242 const char *rtype;
7243
7244 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7245 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7246 type = BYTE_GET (imfs [i].type);
7247 rtype = elf_ia64_reloc_type (type);
7248 if (rtype == NULL)
7249 printf (" 0x%08x ", type);
7250 else
7251 printf (" %-32s ", rtype);
7252 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7253 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7254 }
7255
7256 free (imfs);
32ec8896 7257 return TRUE;
28f997cf
TG
7258}
7259
7260/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7261
32ec8896 7262static bfd_boolean
dda8d76d 7263dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7264{
7265 Elf64_External_VMS_IMAGE_RELA *imrs;
7266 long i;
7267
978c4450
AM
7268 imrs = get_data (NULL, filedata,
7269 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 7270 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7271 _("dynamic section image relocations"));
28f997cf 7272 if (!imrs)
32ec8896 7273 return FALSE;
28f997cf
TG
7274
7275 printf (_("\nImage relocs\n"));
7276 printf
7277 (_("Seg Offset Type Addend Seg Sym Off\n"));
7278
7279 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7280 {
7281 unsigned int type;
7282 const char *rtype;
7283
7284 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7285 printf ("%08" BFD_VMA_FMT "x ",
7286 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7287 type = BYTE_GET (imrs [i].type);
7288 rtype = elf_ia64_reloc_type (type);
7289 if (rtype == NULL)
7290 printf ("0x%08x ", type);
7291 else
7292 printf ("%-31s ", rtype);
7293 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7294 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7295 printf ("%08" BFD_VMA_FMT "x\n",
7296 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7297 }
7298
7299 free (imrs);
32ec8896 7300 return TRUE;
28f997cf
TG
7301}
7302
7303/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7304
32ec8896 7305static bfd_boolean
dda8d76d 7306process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7307{
7308 struct ia64_vms_dynfixup fixup;
7309 struct ia64_vms_dynimgrela imgrela;
7310 Elf_Internal_Dyn *entry;
28f997cf
TG
7311 bfd_vma strtab_off = 0;
7312 bfd_vma strtab_sz = 0;
7313 char *strtab = NULL;
32ec8896 7314 bfd_boolean res = TRUE;
28f997cf
TG
7315
7316 memset (&fixup, 0, sizeof (fixup));
7317 memset (&imgrela, 0, sizeof (imgrela));
7318
7319 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
7320 for (entry = filedata->dynamic_section;
7321 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
7322 entry++)
7323 {
7324 switch (entry->d_tag)
7325 {
7326 case DT_IA_64_VMS_STRTAB_OFFSET:
7327 strtab_off = entry->d_un.d_val;
7328 break;
7329 case DT_STRSZ:
7330 strtab_sz = entry->d_un.d_val;
7331 if (strtab == NULL)
978c4450
AM
7332 strtab = get_data (NULL, filedata,
7333 filedata->dynamic_addr + strtab_off,
28f997cf 7334 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7335 if (strtab == NULL)
7336 strtab_sz = 0;
28f997cf
TG
7337 break;
7338
7339 case DT_IA_64_VMS_NEEDED_IDENT:
7340 fixup.needed_ident = entry->d_un.d_val;
7341 break;
7342 case DT_NEEDED:
7343 fixup.needed = entry->d_un.d_val;
7344 break;
7345 case DT_IA_64_VMS_FIXUP_NEEDED:
7346 fixup.fixup_needed = entry->d_un.d_val;
7347 break;
7348 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7349 fixup.fixup_rela_cnt = entry->d_un.d_val;
7350 break;
7351 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7352 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7353 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
32ec8896 7354 res = FALSE;
28f997cf 7355 break;
28f997cf
TG
7356 case DT_IA_64_VMS_IMG_RELA_CNT:
7357 imgrela.img_rela_cnt = entry->d_un.d_val;
7358 break;
7359 case DT_IA_64_VMS_IMG_RELA_OFF:
7360 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7361 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
32ec8896 7362 res = FALSE;
28f997cf
TG
7363 break;
7364
7365 default:
7366 break;
7367 }
7368 }
7369
7370 if (strtab != NULL)
7371 free (strtab);
7372
7373 return res;
7374}
7375
85b1c36d 7376static struct
566b0d53 7377{
2cf0635d 7378 const char * name;
566b0d53
L
7379 int reloc;
7380 int size;
7381 int rela;
32ec8896
NC
7382}
7383 dynamic_relocations [] =
566b0d53 7384{
32ec8896
NC
7385 { "REL", DT_REL, DT_RELSZ, FALSE },
7386 { "RELA", DT_RELA, DT_RELASZ, TRUE },
7387 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7388};
7389
252b5132 7390/* Process the reloc section. */
18bd398b 7391
32ec8896 7392static bfd_boolean
dda8d76d 7393process_relocs (Filedata * filedata)
252b5132 7394{
b34976b6
AM
7395 unsigned long rel_size;
7396 unsigned long rel_offset;
252b5132 7397
252b5132 7398 if (!do_reloc)
32ec8896 7399 return TRUE;
252b5132
RH
7400
7401 if (do_using_dynamic)
7402 {
32ec8896 7403 int is_rela;
2cf0635d 7404 const char * name;
32ec8896 7405 bfd_boolean has_dynamic_reloc;
566b0d53 7406 unsigned int i;
0de14b54 7407
32ec8896 7408 has_dynamic_reloc = FALSE;
252b5132 7409
566b0d53 7410 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7411 {
566b0d53
L
7412 is_rela = dynamic_relocations [i].rela;
7413 name = dynamic_relocations [i].name;
978c4450
AM
7414 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
7415 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 7416
32ec8896
NC
7417 if (rel_size)
7418 has_dynamic_reloc = TRUE;
566b0d53
L
7419
7420 if (is_rela == UNKNOWN)
aa903cfb 7421 {
566b0d53 7422 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 7423 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
7424 {
7425 case DT_REL:
7426 is_rela = FALSE;
7427 break;
7428 case DT_RELA:
7429 is_rela = TRUE;
7430 break;
7431 }
aa903cfb 7432 }
252b5132 7433
566b0d53
L
7434 if (rel_size)
7435 {
7436 printf
7437 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7438 name, rel_offset, rel_size);
252b5132 7439
dda8d76d
NC
7440 dump_relocations (filedata,
7441 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7442 rel_size,
978c4450
AM
7443 filedata->dynamic_symbols,
7444 filedata->num_dynamic_syms,
7445 filedata->dynamic_strings,
7446 filedata->dynamic_strings_length,
32ec8896 7447 is_rela, TRUE /* is_dynamic */);
566b0d53 7448 }
252b5132 7449 }
566b0d53 7450
dda8d76d
NC
7451 if (is_ia64_vms (filedata))
7452 if (process_ia64_vms_dynamic_relocs (filedata))
32ec8896 7453 has_dynamic_reloc = TRUE;
28f997cf 7454
566b0d53 7455 if (! has_dynamic_reloc)
252b5132
RH
7456 printf (_("\nThere are no dynamic relocations in this file.\n"));
7457 }
7458 else
7459 {
2cf0635d 7460 Elf_Internal_Shdr * section;
b34976b6 7461 unsigned long i;
32ec8896 7462 bfd_boolean found = FALSE;
252b5132 7463
dda8d76d
NC
7464 for (i = 0, section = filedata->section_headers;
7465 i < filedata->file_header.e_shnum;
b34976b6 7466 i++, section++)
252b5132
RH
7467 {
7468 if ( section->sh_type != SHT_RELA
7469 && section->sh_type != SHT_REL)
7470 continue;
7471
7472 rel_offset = section->sh_offset;
7473 rel_size = section->sh_size;
7474
7475 if (rel_size)
7476 {
b34976b6 7477 int is_rela;
d3a49aa8 7478 unsigned long num_rela;
103f02d3 7479
252b5132
RH
7480 printf (_("\nRelocation section "));
7481
dda8d76d 7482 if (filedata->string_table == NULL)
19936277 7483 printf ("%d", section->sh_name);
252b5132 7484 else
dda8d76d 7485 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7486
d3a49aa8
AM
7487 num_rela = rel_size / section->sh_entsize;
7488 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7489 " at offset 0x%lx contains %lu entries:\n",
7490 num_rela),
7491 rel_offset, num_rela);
252b5132 7492
d79b3d50
NC
7493 is_rela = section->sh_type == SHT_RELA;
7494
4fbb74a6 7495 if (section->sh_link != 0
dda8d76d 7496 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7497 {
2cf0635d
NC
7498 Elf_Internal_Shdr * symsec;
7499 Elf_Internal_Sym * symtab;
d79b3d50 7500 unsigned long nsyms;
c256ffe7 7501 unsigned long strtablen = 0;
2cf0635d 7502 char * strtab = NULL;
57346661 7503
dda8d76d 7504 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7505 if (symsec->sh_type != SHT_SYMTAB
7506 && symsec->sh_type != SHT_DYNSYM)
7507 continue;
7508
28d13567
AM
7509 if (!get_symtab (filedata, symsec,
7510 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7511 continue;
252b5132 7512
dda8d76d 7513 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7514 symtab, nsyms, strtab, strtablen,
7515 is_rela,
7516 symsec->sh_type == SHT_DYNSYM);
d79b3d50
NC
7517 if (strtab)
7518 free (strtab);
7519 free (symtab);
7520 }
7521 else
dda8d76d 7522 dump_relocations (filedata, rel_offset, rel_size,
32ec8896
NC
7523 NULL, 0, NULL, 0, is_rela,
7524 FALSE /* is_dynamic */);
252b5132 7525
32ec8896 7526 found = TRUE;
252b5132
RH
7527 }
7528 }
7529
7530 if (! found)
45ac8f4f
NC
7531 {
7532 /* Users sometimes forget the -D option, so try to be helpful. */
7533 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7534 {
978c4450 7535 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f
NC
7536 {
7537 printf (_("\nThere are no static relocations in this file."));
7538 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7539
7540 break;
7541 }
7542 }
7543 if (i == ARRAY_SIZE (dynamic_relocations))
7544 printf (_("\nThere are no relocations in this file.\n"));
7545 }
252b5132
RH
7546 }
7547
32ec8896 7548 return TRUE;
252b5132
RH
7549}
7550
4d6ed7c8
NC
7551/* An absolute address consists of a section and an offset. If the
7552 section is NULL, the offset itself is the address, otherwise, the
7553 address equals to LOAD_ADDRESS(section) + offset. */
7554
7555struct absaddr
948f632f
DA
7556{
7557 unsigned short section;
7558 bfd_vma offset;
7559};
4d6ed7c8 7560
948f632f
DA
7561/* Find the nearest symbol at or below ADDR. Returns the symbol
7562 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7563
4d6ed7c8 7564static void
dda8d76d
NC
7565find_symbol_for_address (Filedata * filedata,
7566 Elf_Internal_Sym * symtab,
7567 unsigned long nsyms,
7568 const char * strtab,
7569 unsigned long strtab_size,
7570 struct absaddr addr,
7571 const char ** symname,
7572 bfd_vma * offset)
4d6ed7c8 7573{
d3ba0551 7574 bfd_vma dist = 0x100000;
2cf0635d 7575 Elf_Internal_Sym * sym;
948f632f
DA
7576 Elf_Internal_Sym * beg;
7577 Elf_Internal_Sym * end;
2cf0635d 7578 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7579
0b6ae522 7580 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7581 beg = symtab;
7582 end = symtab + nsyms;
0b6ae522 7583
948f632f 7584 while (beg < end)
4d6ed7c8 7585 {
948f632f
DA
7586 bfd_vma value;
7587
7588 sym = beg + (end - beg) / 2;
0b6ae522 7589
948f632f 7590 value = sym->st_value;
0b6ae522
DJ
7591 REMOVE_ARCH_BITS (value);
7592
948f632f 7593 if (sym->st_name != 0
4d6ed7c8 7594 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7595 && addr.offset >= value
7596 && addr.offset - value < dist)
4d6ed7c8
NC
7597 {
7598 best = sym;
0b6ae522 7599 dist = addr.offset - value;
4d6ed7c8
NC
7600 if (!dist)
7601 break;
7602 }
948f632f
DA
7603
7604 if (addr.offset < value)
7605 end = sym;
7606 else
7607 beg = sym + 1;
4d6ed7c8 7608 }
1b31d05e 7609
4d6ed7c8
NC
7610 if (best)
7611 {
57346661 7612 *symname = (best->st_name >= strtab_size
2b692964 7613 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7614 *offset = dist;
7615 return;
7616 }
1b31d05e 7617
4d6ed7c8
NC
7618 *symname = NULL;
7619 *offset = addr.offset;
7620}
7621
32ec8896 7622static /* signed */ int
948f632f
DA
7623symcmp (const void *p, const void *q)
7624{
7625 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7626 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7627
7628 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7629}
7630
7631/* Process the unwind section. */
7632
7633#include "unwind-ia64.h"
7634
7635struct ia64_unw_table_entry
7636{
7637 struct absaddr start;
7638 struct absaddr end;
7639 struct absaddr info;
7640};
7641
7642struct ia64_unw_aux_info
7643{
32ec8896
NC
7644 struct ia64_unw_table_entry * table; /* Unwind table. */
7645 unsigned long table_len; /* Length of unwind table. */
7646 unsigned char * info; /* Unwind info. */
7647 unsigned long info_size; /* Size of unwind info. */
7648 bfd_vma info_addr; /* Starting address of unwind info. */
7649 bfd_vma seg_base; /* Starting address of segment. */
7650 Elf_Internal_Sym * symtab; /* The symbol table. */
7651 unsigned long nsyms; /* Number of symbols. */
7652 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7653 unsigned long nfuns; /* Number of entries in funtab. */
7654 char * strtab; /* The string table. */
7655 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7656};
7657
32ec8896 7658static bfd_boolean
dda8d76d 7659dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7660{
2cf0635d 7661 struct ia64_unw_table_entry * tp;
948f632f 7662 unsigned long j, nfuns;
4d6ed7c8 7663 int in_body;
32ec8896 7664 bfd_boolean res = TRUE;
7036c0e1 7665
948f632f
DA
7666 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7667 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7668 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7669 aux->funtab[nfuns++] = aux->symtab[j];
7670 aux->nfuns = nfuns;
7671 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7672
4d6ed7c8
NC
7673 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7674 {
7675 bfd_vma stamp;
7676 bfd_vma offset;
2cf0635d
NC
7677 const unsigned char * dp;
7678 const unsigned char * head;
53774b7e 7679 const unsigned char * end;
2cf0635d 7680 const char * procname;
4d6ed7c8 7681
dda8d76d 7682 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7683 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7684
7685 fputs ("\n<", stdout);
7686
7687 if (procname)
7688 {
7689 fputs (procname, stdout);
7690
7691 if (offset)
7692 printf ("+%lx", (unsigned long) offset);
7693 }
7694
7695 fputs (">: [", stdout);
7696 print_vma (tp->start.offset, PREFIX_HEX);
7697 fputc ('-', stdout);
7698 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7699 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7700 (unsigned long) (tp->info.offset - aux->seg_base));
7701
53774b7e
NC
7702 /* PR 17531: file: 86232b32. */
7703 if (aux->info == NULL)
7704 continue;
7705
97c0a079
AM
7706 offset = tp->info.offset;
7707 if (tp->info.section)
7708 {
7709 if (tp->info.section >= filedata->file_header.e_shnum)
7710 {
7711 warn (_("Invalid section %u in table entry %ld\n"),
7712 tp->info.section, (long) (tp - aux->table));
7713 res = FALSE;
7714 continue;
7715 }
7716 offset += filedata->section_headers[tp->info.section].sh_addr;
7717 }
7718 offset -= aux->info_addr;
53774b7e 7719 /* PR 17531: file: 0997b4d1. */
90679903
AM
7720 if (offset >= aux->info_size
7721 || aux->info_size - offset < 8)
53774b7e
NC
7722 {
7723 warn (_("Invalid offset %lx in table entry %ld\n"),
7724 (long) tp->info.offset, (long) (tp - aux->table));
32ec8896 7725 res = FALSE;
53774b7e
NC
7726 continue;
7727 }
7728
97c0a079 7729 head = aux->info + offset;
a4a00738 7730 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 7731
86f55779 7732 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
7733 (unsigned) UNW_VER (stamp),
7734 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
7735 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
7736 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 7737 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
7738
7739 if (UNW_VER (stamp) != 1)
7740 {
2b692964 7741 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
7742 continue;
7743 }
7744
7745 in_body = 0;
53774b7e
NC
7746 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
7747 /* PR 17531: file: 16ceda89. */
7748 if (end > aux->info + aux->info_size)
7749 end = aux->info + aux->info_size;
7750 for (dp = head + 8; dp < end;)
b4477bc8 7751 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 7752 }
948f632f
DA
7753
7754 free (aux->funtab);
32ec8896
NC
7755
7756 return res;
4d6ed7c8
NC
7757}
7758
53774b7e 7759static bfd_boolean
dda8d76d
NC
7760slurp_ia64_unwind_table (Filedata * filedata,
7761 struct ia64_unw_aux_info * aux,
7762 Elf_Internal_Shdr * sec)
4d6ed7c8 7763{
89fac5e3 7764 unsigned long size, nrelas, i;
2cf0635d
NC
7765 Elf_Internal_Phdr * seg;
7766 struct ia64_unw_table_entry * tep;
7767 Elf_Internal_Shdr * relsec;
7768 Elf_Internal_Rela * rela;
7769 Elf_Internal_Rela * rp;
7770 unsigned char * table;
7771 unsigned char * tp;
7772 Elf_Internal_Sym * sym;
7773 const char * relname;
4d6ed7c8 7774
53774b7e
NC
7775 aux->table_len = 0;
7776
4d6ed7c8
NC
7777 /* First, find the starting address of the segment that includes
7778 this section: */
7779
dda8d76d 7780 if (filedata->file_header.e_phnum)
4d6ed7c8 7781 {
dda8d76d 7782 if (! get_program_headers (filedata))
53774b7e 7783 return FALSE;
4d6ed7c8 7784
dda8d76d
NC
7785 for (seg = filedata->program_headers;
7786 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 7787 ++seg)
4d6ed7c8
NC
7788 {
7789 if (seg->p_type != PT_LOAD)
7790 continue;
7791
7792 if (sec->sh_addr >= seg->p_vaddr
7793 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7794 {
7795 aux->seg_base = seg->p_vaddr;
7796 break;
7797 }
7798 }
4d6ed7c8
NC
7799 }
7800
7801 /* Second, build the unwind table from the contents of the unwind section: */
7802 size = sec->sh_size;
dda8d76d 7803 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7804 _("unwind table"));
a6e9f9df 7805 if (!table)
53774b7e 7806 return FALSE;
4d6ed7c8 7807
53774b7e 7808 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 7809 aux->table = (struct ia64_unw_table_entry *)
53774b7e 7810 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 7811 tep = aux->table;
53774b7e
NC
7812
7813 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
7814 {
7815 tep->start.section = SHN_UNDEF;
7816 tep->end.section = SHN_UNDEF;
7817 tep->info.section = SHN_UNDEF;
c6a0c689
AM
7818 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7819 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7820 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
7821 tep->start.offset += aux->seg_base;
7822 tep->end.offset += aux->seg_base;
7823 tep->info.offset += aux->seg_base;
7824 }
7825 free (table);
7826
41e92641 7827 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
7828 for (relsec = filedata->section_headers;
7829 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
7830 ++relsec)
7831 {
7832 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
7833 || relsec->sh_info >= filedata->file_header.e_shnum
7834 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
7835 continue;
7836
dda8d76d 7837 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 7838 & rela, & nrelas))
53774b7e
NC
7839 {
7840 free (aux->table);
7841 aux->table = NULL;
7842 aux->table_len = 0;
7843 return FALSE;
7844 }
4d6ed7c8
NC
7845
7846 for (rp = rela; rp < rela + nrelas; ++rp)
7847 {
4770fb94 7848 unsigned int sym_ndx;
726bd37d
AM
7849 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
7850 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 7851
82b1b41b
NC
7852 /* PR 17531: file: 9fa67536. */
7853 if (relname == NULL)
7854 {
726bd37d 7855 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
7856 continue;
7857 }
948f632f 7858
0112cd26 7859 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 7860 {
82b1b41b 7861 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
7862 continue;
7863 }
7864
89fac5e3 7865 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 7866
53774b7e
NC
7867 /* PR 17531: file: 5bc8d9bf. */
7868 if (i >= aux->table_len)
7869 {
7870 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
7871 continue;
7872 }
7873
4770fb94
AM
7874 sym_ndx = get_reloc_symindex (rp->r_info);
7875 if (sym_ndx >= aux->nsyms)
7876 {
7877 warn (_("Skipping reloc with invalid symbol index: %u\n"),
7878 sym_ndx);
7879 continue;
7880 }
7881 sym = aux->symtab + sym_ndx;
7882
53774b7e 7883 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
7884 {
7885 case 0:
7886 aux->table[i].start.section = sym->st_shndx;
e466bc6e 7887 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7888 break;
7889 case 1:
7890 aux->table[i].end.section = sym->st_shndx;
e466bc6e 7891 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7892 break;
7893 case 2:
7894 aux->table[i].info.section = sym->st_shndx;
e466bc6e 7895 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7896 break;
7897 default:
7898 break;
7899 }
7900 }
7901
7902 free (rela);
7903 }
7904
53774b7e 7905 return TRUE;
4d6ed7c8
NC
7906}
7907
32ec8896 7908static bfd_boolean
dda8d76d 7909ia64_process_unwind (Filedata * filedata)
4d6ed7c8 7910{
2cf0635d
NC
7911 Elf_Internal_Shdr * sec;
7912 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 7913 unsigned long i, unwcount = 0, unwstart = 0;
57346661 7914 struct ia64_unw_aux_info aux;
32ec8896 7915 bfd_boolean res = TRUE;
f1467e33 7916
4d6ed7c8
NC
7917 memset (& aux, 0, sizeof (aux));
7918
dda8d76d 7919 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 7920 {
28d13567 7921 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 7922 {
28d13567 7923 if (aux.symtab)
4082ef84 7924 {
28d13567
AM
7925 error (_("Multiple symbol tables encountered\n"));
7926 free (aux.symtab);
7927 aux.symtab = NULL;
4082ef84 7928 free (aux.strtab);
28d13567 7929 aux.strtab = NULL;
4082ef84 7930 }
28d13567
AM
7931 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
7932 &aux.strtab, &aux.strtab_size))
7933 return FALSE;
4d6ed7c8
NC
7934 }
7935 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
7936 unwcount++;
7937 }
7938
7939 if (!unwcount)
7940 printf (_("\nThere are no unwind sections in this file.\n"));
7941
7942 while (unwcount-- > 0)
7943 {
2cf0635d 7944 char * suffix;
579f31ac
JJ
7945 size_t len, len2;
7946
dda8d76d
NC
7947 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
7948 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
7949 if (sec->sh_type == SHT_IA_64_UNWIND)
7950 {
7951 unwsec = sec;
7952 break;
7953 }
4082ef84
NC
7954 /* We have already counted the number of SHT_IA64_UNWIND
7955 sections so the loop above should never fail. */
7956 assert (unwsec != NULL);
579f31ac
JJ
7957
7958 unwstart = i + 1;
7959 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
7960
e4b17d5c
L
7961 if ((unwsec->sh_flags & SHF_GROUP) != 0)
7962 {
7963 /* We need to find which section group it is in. */
4082ef84 7964 struct group_list * g;
e4b17d5c 7965
978c4450
AM
7966 if (filedata->section_headers_groups == NULL
7967 || filedata->section_headers_groups[i] == NULL)
dda8d76d 7968 i = filedata->file_header.e_shnum;
4082ef84 7969 else
e4b17d5c 7970 {
978c4450 7971 g = filedata->section_headers_groups[i]->root;
18bd398b 7972
4082ef84
NC
7973 for (; g != NULL; g = g->next)
7974 {
dda8d76d 7975 sec = filedata->section_headers + g->section_index;
e4b17d5c 7976
4082ef84
NC
7977 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
7978 break;
7979 }
7980
7981 if (g == NULL)
dda8d76d 7982 i = filedata->file_header.e_shnum;
4082ef84 7983 }
e4b17d5c 7984 }
18bd398b 7985 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 7986 {
18bd398b 7987 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
7988 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
7989 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 7990 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 7991 ++i, ++sec)
18bd398b
NC
7992 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
7993 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7994 break;
7995 }
7996 else
7997 {
7998 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 7999 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8000 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8001 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8002 suffix = "";
18bd398b 8003 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac 8004 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 8005 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 8006 ++i, ++sec)
18bd398b
NC
8007 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
8008 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8009 break;
8010 }
8011
dda8d76d 8012 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8013 {
8014 printf (_("\nCould not find unwind info section for "));
8015
dda8d76d 8016 if (filedata->string_table == NULL)
579f31ac
JJ
8017 printf ("%d", unwsec->sh_name);
8018 else
dda8d76d 8019 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8020 }
8021 else
4d6ed7c8 8022 {
4d6ed7c8 8023 aux.info_addr = sec->sh_addr;
dda8d76d 8024 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8025 sec->sh_size,
8026 _("unwind info"));
59245841 8027 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8028
579f31ac 8029 printf (_("\nUnwind section "));
4d6ed7c8 8030
dda8d76d 8031 if (filedata->string_table == NULL)
579f31ac
JJ
8032 printf ("%d", unwsec->sh_name);
8033 else
dda8d76d 8034 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8035
579f31ac 8036 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8037 (unsigned long) unwsec->sh_offset,
89fac5e3 8038 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8039
dda8d76d 8040 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8041 && aux.table_len > 0)
dda8d76d 8042 dump_ia64_unwind (filedata, & aux);
579f31ac
JJ
8043
8044 if (aux.table)
8045 free ((char *) aux.table);
8046 if (aux.info)
8047 free ((char *) aux.info);
8048 aux.table = NULL;
8049 aux.info = NULL;
8050 }
4d6ed7c8 8051 }
4d6ed7c8 8052
4d6ed7c8
NC
8053 if (aux.symtab)
8054 free (aux.symtab);
8055 if (aux.strtab)
8056 free ((char *) aux.strtab);
32ec8896
NC
8057
8058 return res;
4d6ed7c8
NC
8059}
8060
3f5e193b 8061struct hppa_unw_table_entry
32ec8896
NC
8062{
8063 struct absaddr start;
8064 struct absaddr end;
8065 unsigned int Cannot_unwind:1; /* 0 */
8066 unsigned int Millicode:1; /* 1 */
8067 unsigned int Millicode_save_sr0:1; /* 2 */
8068 unsigned int Region_description:2; /* 3..4 */
8069 unsigned int reserved1:1; /* 5 */
8070 unsigned int Entry_SR:1; /* 6 */
8071 unsigned int Entry_FR:4; /* Number saved 7..10 */
8072 unsigned int Entry_GR:5; /* Number saved 11..15 */
8073 unsigned int Args_stored:1; /* 16 */
8074 unsigned int Variable_Frame:1; /* 17 */
8075 unsigned int Separate_Package_Body:1; /* 18 */
8076 unsigned int Frame_Extension_Millicode:1; /* 19 */
8077 unsigned int Stack_Overflow_Check:1; /* 20 */
8078 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8079 unsigned int Ada_Region:1; /* 22 */
8080 unsigned int cxx_info:1; /* 23 */
8081 unsigned int cxx_try_catch:1; /* 24 */
8082 unsigned int sched_entry_seq:1; /* 25 */
8083 unsigned int reserved2:1; /* 26 */
8084 unsigned int Save_SP:1; /* 27 */
8085 unsigned int Save_RP:1; /* 28 */
8086 unsigned int Save_MRP_in_frame:1; /* 29 */
8087 unsigned int extn_ptr_defined:1; /* 30 */
8088 unsigned int Cleanup_defined:1; /* 31 */
8089
8090 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8091 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8092 unsigned int Large_frame:1; /* 2 */
8093 unsigned int Pseudo_SP_Set:1; /* 3 */
8094 unsigned int reserved4:1; /* 4 */
8095 unsigned int Total_frame_size:27; /* 5..31 */
8096};
3f5e193b 8097
57346661 8098struct hppa_unw_aux_info
948f632f 8099{
32ec8896
NC
8100 struct hppa_unw_table_entry * table; /* Unwind table. */
8101 unsigned long table_len; /* Length of unwind table. */
8102 bfd_vma seg_base; /* Starting address of segment. */
8103 Elf_Internal_Sym * symtab; /* The symbol table. */
8104 unsigned long nsyms; /* Number of symbols. */
8105 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8106 unsigned long nfuns; /* Number of entries in funtab. */
8107 char * strtab; /* The string table. */
8108 unsigned long strtab_size; /* Size of string table. */
948f632f 8109};
57346661 8110
32ec8896 8111static bfd_boolean
dda8d76d 8112dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8113{
2cf0635d 8114 struct hppa_unw_table_entry * tp;
948f632f 8115 unsigned long j, nfuns;
32ec8896 8116 bfd_boolean res = TRUE;
948f632f
DA
8117
8118 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8119 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8120 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8121 aux->funtab[nfuns++] = aux->symtab[j];
8122 aux->nfuns = nfuns;
8123 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8124
57346661
AM
8125 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8126 {
8127 bfd_vma offset;
2cf0635d 8128 const char * procname;
57346661 8129
dda8d76d 8130 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8131 aux->strtab_size, tp->start, &procname,
8132 &offset);
8133
8134 fputs ("\n<", stdout);
8135
8136 if (procname)
8137 {
8138 fputs (procname, stdout);
8139
8140 if (offset)
8141 printf ("+%lx", (unsigned long) offset);
8142 }
8143
8144 fputs (">: [", stdout);
8145 print_vma (tp->start.offset, PREFIX_HEX);
8146 fputc ('-', stdout);
8147 print_vma (tp->end.offset, PREFIX_HEX);
8148 printf ("]\n\t");
8149
18bd398b
NC
8150#define PF(_m) if (tp->_m) printf (#_m " ");
8151#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8152 PF(Cannot_unwind);
8153 PF(Millicode);
8154 PF(Millicode_save_sr0);
18bd398b 8155 /* PV(Region_description); */
57346661
AM
8156 PF(Entry_SR);
8157 PV(Entry_FR);
8158 PV(Entry_GR);
8159 PF(Args_stored);
8160 PF(Variable_Frame);
8161 PF(Separate_Package_Body);
8162 PF(Frame_Extension_Millicode);
8163 PF(Stack_Overflow_Check);
8164 PF(Two_Instruction_SP_Increment);
8165 PF(Ada_Region);
8166 PF(cxx_info);
8167 PF(cxx_try_catch);
8168 PF(sched_entry_seq);
8169 PF(Save_SP);
8170 PF(Save_RP);
8171 PF(Save_MRP_in_frame);
8172 PF(extn_ptr_defined);
8173 PF(Cleanup_defined);
8174 PF(MPE_XL_interrupt_marker);
8175 PF(HP_UX_interrupt_marker);
8176 PF(Large_frame);
8177 PF(Pseudo_SP_Set);
8178 PV(Total_frame_size);
8179#undef PF
8180#undef PV
8181 }
8182
18bd398b 8183 printf ("\n");
948f632f
DA
8184
8185 free (aux->funtab);
32ec8896
NC
8186
8187 return res;
57346661
AM
8188}
8189
32ec8896 8190static bfd_boolean
dda8d76d
NC
8191slurp_hppa_unwind_table (Filedata * filedata,
8192 struct hppa_unw_aux_info * aux,
8193 Elf_Internal_Shdr * sec)
57346661 8194{
1c0751b2 8195 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8196 Elf_Internal_Phdr * seg;
8197 struct hppa_unw_table_entry * tep;
8198 Elf_Internal_Shdr * relsec;
8199 Elf_Internal_Rela * rela;
8200 Elf_Internal_Rela * rp;
8201 unsigned char * table;
8202 unsigned char * tp;
8203 Elf_Internal_Sym * sym;
8204 const char * relname;
57346661 8205
57346661
AM
8206 /* First, find the starting address of the segment that includes
8207 this section. */
dda8d76d 8208 if (filedata->file_header.e_phnum)
57346661 8209 {
dda8d76d 8210 if (! get_program_headers (filedata))
32ec8896 8211 return FALSE;
57346661 8212
dda8d76d
NC
8213 for (seg = filedata->program_headers;
8214 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8215 ++seg)
8216 {
8217 if (seg->p_type != PT_LOAD)
8218 continue;
8219
8220 if (sec->sh_addr >= seg->p_vaddr
8221 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8222 {
8223 aux->seg_base = seg->p_vaddr;
8224 break;
8225 }
8226 }
8227 }
8228
8229 /* Second, build the unwind table from the contents of the unwind
8230 section. */
8231 size = sec->sh_size;
dda8d76d 8232 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8233 _("unwind table"));
57346661 8234 if (!table)
32ec8896 8235 return FALSE;
57346661 8236
1c0751b2
DA
8237 unw_ent_size = 16;
8238 nentries = size / unw_ent_size;
8239 size = unw_ent_size * nentries;
57346661 8240
3f5e193b
NC
8241 tep = aux->table = (struct hppa_unw_table_entry *)
8242 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8243
1c0751b2 8244 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8245 {
8246 unsigned int tmp1, tmp2;
8247
8248 tep->start.section = SHN_UNDEF;
8249 tep->end.section = SHN_UNDEF;
8250
1c0751b2
DA
8251 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8252 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8253 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8254 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8255
8256 tep->start.offset += aux->seg_base;
8257 tep->end.offset += aux->seg_base;
57346661
AM
8258
8259 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8260 tep->Millicode = (tmp1 >> 30) & 0x1;
8261 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8262 tep->Region_description = (tmp1 >> 27) & 0x3;
8263 tep->reserved1 = (tmp1 >> 26) & 0x1;
8264 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8265 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8266 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8267 tep->Args_stored = (tmp1 >> 15) & 0x1;
8268 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8269 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8270 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8271 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8272 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8273 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8274 tep->cxx_info = (tmp1 >> 8) & 0x1;
8275 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8276 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8277 tep->reserved2 = (tmp1 >> 5) & 0x1;
8278 tep->Save_SP = (tmp1 >> 4) & 0x1;
8279 tep->Save_RP = (tmp1 >> 3) & 0x1;
8280 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8281 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8282 tep->Cleanup_defined = tmp1 & 0x1;
8283
8284 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8285 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8286 tep->Large_frame = (tmp2 >> 29) & 0x1;
8287 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8288 tep->reserved4 = (tmp2 >> 27) & 0x1;
8289 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8290 }
8291 free (table);
8292
8293 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8294 for (relsec = filedata->section_headers;
8295 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8296 ++relsec)
8297 {
8298 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8299 || relsec->sh_info >= filedata->file_header.e_shnum
8300 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8301 continue;
8302
dda8d76d 8303 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8304 & rela, & nrelas))
32ec8896 8305 return FALSE;
57346661
AM
8306
8307 for (rp = rela; rp < rela + nrelas; ++rp)
8308 {
4770fb94 8309 unsigned int sym_ndx;
726bd37d
AM
8310 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8311 relname = elf_hppa_reloc_type (r_type);
57346661 8312
726bd37d
AM
8313 if (relname == NULL)
8314 {
8315 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8316 continue;
8317 }
8318
57346661 8319 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 8320 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661 8321 {
726bd37d 8322 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8323 continue;
8324 }
8325
8326 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8327 if (i >= aux->table_len)
8328 {
8329 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8330 continue;
8331 }
57346661 8332
4770fb94
AM
8333 sym_ndx = get_reloc_symindex (rp->r_info);
8334 if (sym_ndx >= aux->nsyms)
8335 {
8336 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8337 sym_ndx);
8338 continue;
8339 }
8340 sym = aux->symtab + sym_ndx;
8341
43f6cd05 8342 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8343 {
8344 case 0:
8345 aux->table[i].start.section = sym->st_shndx;
1e456d54 8346 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8347 break;
8348 case 1:
8349 aux->table[i].end.section = sym->st_shndx;
1e456d54 8350 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8351 break;
8352 default:
8353 break;
8354 }
8355 }
8356
8357 free (rela);
8358 }
8359
1c0751b2 8360 aux->table_len = nentries;
57346661 8361
32ec8896 8362 return TRUE;
57346661
AM
8363}
8364
32ec8896 8365static bfd_boolean
dda8d76d 8366hppa_process_unwind (Filedata * filedata)
57346661 8367{
57346661 8368 struct hppa_unw_aux_info aux;
2cf0635d 8369 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8370 Elf_Internal_Shdr * sec;
18bd398b 8371 unsigned long i;
32ec8896 8372 bfd_boolean res = TRUE;
57346661 8373
dda8d76d 8374 if (filedata->string_table == NULL)
32ec8896 8375 return FALSE;
1b31d05e
NC
8376
8377 memset (& aux, 0, sizeof (aux));
57346661 8378
dda8d76d 8379 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8380 {
28d13567 8381 if (sec->sh_type == SHT_SYMTAB)
57346661 8382 {
28d13567 8383 if (aux.symtab)
4082ef84 8384 {
28d13567
AM
8385 error (_("Multiple symbol tables encountered\n"));
8386 free (aux.symtab);
8387 aux.symtab = NULL;
4082ef84 8388 free (aux.strtab);
28d13567 8389 aux.strtab = NULL;
4082ef84 8390 }
28d13567
AM
8391 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8392 &aux.strtab, &aux.strtab_size))
8393 return FALSE;
57346661 8394 }
18bd398b 8395 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8396 unwsec = sec;
8397 }
8398
8399 if (!unwsec)
8400 printf (_("\nThere are no unwind sections in this file.\n"));
8401
dda8d76d 8402 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8403 {
18bd398b 8404 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8405 {
43f6cd05 8406 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8407
d3a49aa8
AM
8408 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8409 "contains %lu entry:\n",
8410 "\nUnwind section '%s' at offset 0x%lx "
8411 "contains %lu entries:\n",
8412 num_unwind),
dda8d76d 8413 printable_section_name (filedata, sec),
57346661 8414 (unsigned long) sec->sh_offset,
d3a49aa8 8415 num_unwind);
57346661 8416
dda8d76d 8417 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
32ec8896 8418 res = FALSE;
66b09c7e
S
8419
8420 if (res && aux.table_len > 0)
32ec8896 8421 {
dda8d76d 8422 if (! dump_hppa_unwind (filedata, &aux))
32ec8896
NC
8423 res = FALSE;
8424 }
57346661
AM
8425
8426 if (aux.table)
8427 free ((char *) aux.table);
8428 aux.table = NULL;
8429 }
8430 }
8431
8432 if (aux.symtab)
8433 free (aux.symtab);
8434 if (aux.strtab)
8435 free ((char *) aux.strtab);
32ec8896
NC
8436
8437 return res;
57346661
AM
8438}
8439
0b6ae522
DJ
8440struct arm_section
8441{
a734115a
NC
8442 unsigned char * data; /* The unwind data. */
8443 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8444 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8445 unsigned long nrelas; /* The number of relocations. */
8446 unsigned int rel_type; /* REL or RELA ? */
8447 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8448};
8449
8450struct arm_unw_aux_info
8451{
dda8d76d 8452 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8453 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8454 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8455 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8456 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8457 char * strtab; /* The file's string table. */
8458 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8459};
8460
8461static const char *
dda8d76d
NC
8462arm_print_vma_and_name (Filedata * filedata,
8463 struct arm_unw_aux_info * aux,
8464 bfd_vma fn,
8465 struct absaddr addr)
0b6ae522
DJ
8466{
8467 const char *procname;
8468 bfd_vma sym_offset;
8469
8470 if (addr.section == SHN_UNDEF)
8471 addr.offset = fn;
8472
dda8d76d 8473 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8474 aux->strtab_size, addr, &procname,
8475 &sym_offset);
8476
8477 print_vma (fn, PREFIX_HEX);
8478
8479 if (procname)
8480 {
8481 fputs (" <", stdout);
8482 fputs (procname, stdout);
8483
8484 if (sym_offset)
8485 printf ("+0x%lx", (unsigned long) sym_offset);
8486 fputc ('>', stdout);
8487 }
8488
8489 return procname;
8490}
8491
8492static void
8493arm_free_section (struct arm_section *arm_sec)
8494{
8495 if (arm_sec->data != NULL)
8496 free (arm_sec->data);
8497
8498 if (arm_sec->rela != NULL)
8499 free (arm_sec->rela);
8500}
8501
a734115a
NC
8502/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8503 cached section and install SEC instead.
8504 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8505 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8506 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8507 relocation's offset in ADDR.
1b31d05e
NC
8508 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8509 into the string table of the symbol associated with the reloc. If no
8510 reloc was applied store -1 there.
8511 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
8512
8513static bfd_boolean
dda8d76d
NC
8514get_unwind_section_word (Filedata * filedata,
8515 struct arm_unw_aux_info * aux,
1b31d05e
NC
8516 struct arm_section * arm_sec,
8517 Elf_Internal_Shdr * sec,
8518 bfd_vma word_offset,
8519 unsigned int * wordp,
8520 struct absaddr * addr,
8521 bfd_vma * sym_name)
0b6ae522
DJ
8522{
8523 Elf_Internal_Rela *rp;
8524 Elf_Internal_Sym *sym;
8525 const char * relname;
8526 unsigned int word;
8527 bfd_boolean wrapped;
8528
e0a31db1
NC
8529 if (sec == NULL || arm_sec == NULL)
8530 return FALSE;
8531
0b6ae522
DJ
8532 addr->section = SHN_UNDEF;
8533 addr->offset = 0;
8534
1b31d05e
NC
8535 if (sym_name != NULL)
8536 *sym_name = (bfd_vma) -1;
8537
a734115a 8538 /* If necessary, update the section cache. */
0b6ae522
DJ
8539 if (sec != arm_sec->sec)
8540 {
8541 Elf_Internal_Shdr *relsec;
8542
8543 arm_free_section (arm_sec);
8544
8545 arm_sec->sec = sec;
dda8d76d 8546 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8547 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8548 arm_sec->rela = NULL;
8549 arm_sec->nrelas = 0;
8550
dda8d76d
NC
8551 for (relsec = filedata->section_headers;
8552 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8553 ++relsec)
8554 {
dda8d76d
NC
8555 if (relsec->sh_info >= filedata->file_header.e_shnum
8556 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8557 /* PR 15745: Check the section type as well. */
8558 || (relsec->sh_type != SHT_REL
8559 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8560 continue;
8561
a734115a 8562 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8563 if (relsec->sh_type == SHT_REL)
8564 {
dda8d76d 8565 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8566 relsec->sh_size,
8567 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8568 return FALSE;
0b6ae522 8569 }
1ae40aa4 8570 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8571 {
dda8d76d 8572 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8573 relsec->sh_size,
8574 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8575 return FALSE;
0b6ae522 8576 }
1ae40aa4 8577 break;
0b6ae522
DJ
8578 }
8579
8580 arm_sec->next_rela = arm_sec->rela;
8581 }
8582
a734115a 8583 /* If there is no unwind data we can do nothing. */
0b6ae522 8584 if (arm_sec->data == NULL)
a734115a 8585 return FALSE;
0b6ae522 8586
e0a31db1 8587 /* If the offset is invalid then fail. */
f32ba729
NC
8588 if (/* PR 21343 *//* PR 18879 */
8589 sec->sh_size < 4
8590 || word_offset > (sec->sh_size - 4)
1a915552 8591 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
8592 return FALSE;
8593
a734115a 8594 /* Get the word at the required offset. */
0b6ae522
DJ
8595 word = byte_get (arm_sec->data + word_offset, 4);
8596
0eff7165
NC
8597 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8598 if (arm_sec->rela == NULL)
8599 {
8600 * wordp = word;
8601 return TRUE;
8602 }
8603
a734115a 8604 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
8605 wrapped = FALSE;
8606 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8607 {
8608 bfd_vma prelval, offset;
8609
8610 if (rp->r_offset > word_offset && !wrapped)
8611 {
8612 rp = arm_sec->rela;
8613 wrapped = TRUE;
8614 }
8615 if (rp->r_offset > word_offset)
8616 break;
8617
8618 if (rp->r_offset & 3)
8619 {
8620 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8621 (unsigned long) rp->r_offset);
8622 continue;
8623 }
8624
8625 if (rp->r_offset < word_offset)
8626 continue;
8627
74e1a04b
NC
8628 /* PR 17531: file: 027-161405-0.004 */
8629 if (aux->symtab == NULL)
8630 continue;
8631
0b6ae522
DJ
8632 if (arm_sec->rel_type == SHT_REL)
8633 {
8634 offset = word & 0x7fffffff;
8635 if (offset & 0x40000000)
8636 offset |= ~ (bfd_vma) 0x7fffffff;
8637 }
a734115a 8638 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8639 offset = rp->r_addend;
a734115a 8640 else
74e1a04b
NC
8641 {
8642 error (_("Unknown section relocation type %d encountered\n"),
8643 arm_sec->rel_type);
8644 break;
8645 }
0b6ae522 8646
071436c6
NC
8647 /* PR 17531 file: 027-1241568-0.004. */
8648 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8649 {
8650 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8651 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8652 break;
8653 }
8654
8655 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8656 offset += sym->st_value;
8657 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8658
a734115a 8659 /* Check that we are processing the expected reloc type. */
dda8d76d 8660 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8661 {
8662 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8663 if (relname == NULL)
8664 {
8665 warn (_("Skipping unknown ARM relocation type: %d\n"),
8666 (int) ELF32_R_TYPE (rp->r_info));
8667 continue;
8668 }
a734115a
NC
8669
8670 if (streq (relname, "R_ARM_NONE"))
8671 continue;
0b4362b0 8672
a734115a
NC
8673 if (! streq (relname, "R_ARM_PREL31"))
8674 {
071436c6 8675 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8676 continue;
8677 }
8678 }
dda8d76d 8679 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8680 {
8681 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8682 if (relname == NULL)
8683 {
8684 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8685 (int) ELF32_R_TYPE (rp->r_info));
8686 continue;
8687 }
0b4362b0 8688
a734115a
NC
8689 if (streq (relname, "R_C6000_NONE"))
8690 continue;
8691
8692 if (! streq (relname, "R_C6000_PREL31"))
8693 {
071436c6 8694 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8695 continue;
8696 }
8697
8698 prelval >>= 1;
8699 }
8700 else
74e1a04b
NC
8701 {
8702 /* This function currently only supports ARM and TI unwinders. */
8703 warn (_("Only TI and ARM unwinders are currently supported\n"));
8704 break;
8705 }
fa197c1c 8706
0b6ae522
DJ
8707 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
8708 addr->section = sym->st_shndx;
8709 addr->offset = offset;
74e1a04b 8710
1b31d05e
NC
8711 if (sym_name)
8712 * sym_name = sym->st_name;
0b6ae522
DJ
8713 break;
8714 }
8715
8716 *wordp = word;
8717 arm_sec->next_rela = rp;
8718
a734115a 8719 return TRUE;
0b6ae522
DJ
8720}
8721
a734115a
NC
8722static const char *tic6x_unwind_regnames[16] =
8723{
0b4362b0
RM
8724 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
8725 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
8726 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
8727};
fa197c1c 8728
0b6ae522 8729static void
fa197c1c 8730decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 8731{
fa197c1c
PB
8732 int i;
8733
8734 for (i = 12; mask; mask >>= 1, i--)
8735 {
8736 if (mask & 1)
8737 {
8738 fputs (tic6x_unwind_regnames[i], stdout);
8739 if (mask > 1)
8740 fputs (", ", stdout);
8741 }
8742 }
8743}
0b6ae522
DJ
8744
8745#define ADVANCE \
8746 if (remaining == 0 && more_words) \
8747 { \
8748 data_offset += 4; \
dda8d76d 8749 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 8750 data_offset, & word, & addr, NULL)) \
32ec8896 8751 return FALSE; \
0b6ae522
DJ
8752 remaining = 4; \
8753 more_words--; \
8754 } \
8755
8756#define GET_OP(OP) \
8757 ADVANCE; \
8758 if (remaining) \
8759 { \
8760 remaining--; \
8761 (OP) = word >> 24; \
8762 word <<= 8; \
8763 } \
8764 else \
8765 { \
2b692964 8766 printf (_("[Truncated opcode]\n")); \
32ec8896 8767 return FALSE; \
0b6ae522 8768 } \
cc5914eb 8769 printf ("0x%02x ", OP)
0b6ae522 8770
32ec8896 8771static bfd_boolean
dda8d76d
NC
8772decode_arm_unwind_bytecode (Filedata * filedata,
8773 struct arm_unw_aux_info * aux,
948f632f
DA
8774 unsigned int word,
8775 unsigned int remaining,
8776 unsigned int more_words,
8777 bfd_vma data_offset,
8778 Elf_Internal_Shdr * data_sec,
8779 struct arm_section * data_arm_sec)
fa197c1c
PB
8780{
8781 struct absaddr addr;
32ec8896 8782 bfd_boolean res = TRUE;
0b6ae522
DJ
8783
8784 /* Decode the unwinding instructions. */
8785 while (1)
8786 {
8787 unsigned int op, op2;
8788
8789 ADVANCE;
8790 if (remaining == 0)
8791 break;
8792 remaining--;
8793 op = word >> 24;
8794 word <<= 8;
8795
cc5914eb 8796 printf (" 0x%02x ", op);
0b6ae522
DJ
8797
8798 if ((op & 0xc0) == 0x00)
8799 {
8800 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8801
cc5914eb 8802 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
8803 }
8804 else if ((op & 0xc0) == 0x40)
8805 {
8806 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8807
cc5914eb 8808 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
8809 }
8810 else if ((op & 0xf0) == 0x80)
8811 {
8812 GET_OP (op2);
8813 if (op == 0x80 && op2 == 0)
8814 printf (_("Refuse to unwind"));
8815 else
8816 {
8817 unsigned int mask = ((op & 0x0f) << 8) | op2;
32ec8896 8818 bfd_boolean first = TRUE;
0b6ae522 8819 int i;
2b692964 8820
0b6ae522
DJ
8821 printf ("pop {");
8822 for (i = 0; i < 12; i++)
8823 if (mask & (1 << i))
8824 {
8825 if (first)
32ec8896 8826 first = FALSE;
0b6ae522
DJ
8827 else
8828 printf (", ");
8829 printf ("r%d", 4 + i);
8830 }
8831 printf ("}");
8832 }
8833 }
8834 else if ((op & 0xf0) == 0x90)
8835 {
8836 if (op == 0x9d || op == 0x9f)
8837 printf (_(" [Reserved]"));
8838 else
cc5914eb 8839 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
8840 }
8841 else if ((op & 0xf0) == 0xa0)
8842 {
8843 int end = 4 + (op & 0x07);
32ec8896 8844 bfd_boolean first = TRUE;
0b6ae522 8845 int i;
61865e30 8846
0b6ae522
DJ
8847 printf (" pop {");
8848 for (i = 4; i <= end; i++)
8849 {
8850 if (first)
32ec8896 8851 first = FALSE;
0b6ae522
DJ
8852 else
8853 printf (", ");
8854 printf ("r%d", i);
8855 }
8856 if (op & 0x08)
8857 {
1b31d05e 8858 if (!first)
0b6ae522
DJ
8859 printf (", ");
8860 printf ("r14");
8861 }
8862 printf ("}");
8863 }
8864 else if (op == 0xb0)
8865 printf (_(" finish"));
8866 else if (op == 0xb1)
8867 {
8868 GET_OP (op2);
8869 if (op2 == 0 || (op2 & 0xf0) != 0)
8870 printf (_("[Spare]"));
8871 else
8872 {
8873 unsigned int mask = op2 & 0x0f;
32ec8896 8874 bfd_boolean first = TRUE;
0b6ae522 8875 int i;
61865e30 8876
0b6ae522
DJ
8877 printf ("pop {");
8878 for (i = 0; i < 12; i++)
8879 if (mask & (1 << i))
8880 {
8881 if (first)
32ec8896 8882 first = FALSE;
0b6ae522
DJ
8883 else
8884 printf (", ");
8885 printf ("r%d", i);
8886 }
8887 printf ("}");
8888 }
8889 }
8890 else if (op == 0xb2)
8891 {
b115cf96 8892 unsigned char buf[9];
0b6ae522
DJ
8893 unsigned int i, len;
8894 unsigned long offset;
61865e30 8895
b115cf96 8896 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
8897 {
8898 GET_OP (buf[i]);
8899 if ((buf[i] & 0x80) == 0)
8900 break;
8901 }
4082ef84 8902 if (i == sizeof (buf))
32ec8896 8903 {
27a45f42 8904 error (_("corrupt change to vsp\n"));
32ec8896
NC
8905 res = FALSE;
8906 }
4082ef84
NC
8907 else
8908 {
cd30bcef 8909 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
4082ef84
NC
8910 assert (len == i + 1);
8911 offset = offset * 4 + 0x204;
8912 printf ("vsp = vsp + %ld", offset);
8913 }
0b6ae522 8914 }
61865e30 8915 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 8916 {
61865e30
NC
8917 unsigned int first, last;
8918
8919 GET_OP (op2);
8920 first = op2 >> 4;
8921 last = op2 & 0x0f;
8922 if (op == 0xc8)
8923 first = first + 16;
8924 printf ("pop {D%d", first);
8925 if (last)
8926 printf ("-D%d", first + last);
8927 printf ("}");
8928 }
8929 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
8930 {
8931 unsigned int count = op & 0x07;
8932
8933 printf ("pop {D8");
8934 if (count)
8935 printf ("-D%d", 8 + count);
8936 printf ("}");
8937 }
8938 else if (op >= 0xc0 && op <= 0xc5)
8939 {
8940 unsigned int count = op & 0x07;
8941
8942 printf (" pop {wR10");
8943 if (count)
8944 printf ("-wR%d", 10 + count);
8945 printf ("}");
8946 }
8947 else if (op == 0xc6)
8948 {
8949 unsigned int first, last;
8950
8951 GET_OP (op2);
8952 first = op2 >> 4;
8953 last = op2 & 0x0f;
8954 printf ("pop {wR%d", first);
8955 if (last)
8956 printf ("-wR%d", first + last);
8957 printf ("}");
8958 }
8959 else if (op == 0xc7)
8960 {
8961 GET_OP (op2);
8962 if (op2 == 0 || (op2 & 0xf0) != 0)
8963 printf (_("[Spare]"));
0b6ae522
DJ
8964 else
8965 {
61865e30 8966 unsigned int mask = op2 & 0x0f;
32ec8896 8967 bfd_boolean first = TRUE;
61865e30
NC
8968 int i;
8969
8970 printf ("pop {");
8971 for (i = 0; i < 4; i++)
8972 if (mask & (1 << i))
8973 {
8974 if (first)
32ec8896 8975 first = FALSE;
61865e30
NC
8976 else
8977 printf (", ");
8978 printf ("wCGR%d", i);
8979 }
8980 printf ("}");
0b6ae522
DJ
8981 }
8982 }
61865e30 8983 else
32ec8896
NC
8984 {
8985 printf (_(" [unsupported opcode]"));
8986 res = FALSE;
8987 }
8988
0b6ae522
DJ
8989 printf ("\n");
8990 }
32ec8896
NC
8991
8992 return res;
fa197c1c
PB
8993}
8994
32ec8896 8995static bfd_boolean
dda8d76d
NC
8996decode_tic6x_unwind_bytecode (Filedata * filedata,
8997 struct arm_unw_aux_info * aux,
948f632f
DA
8998 unsigned int word,
8999 unsigned int remaining,
9000 unsigned int more_words,
9001 bfd_vma data_offset,
9002 Elf_Internal_Shdr * data_sec,
9003 struct arm_section * data_arm_sec)
fa197c1c
PB
9004{
9005 struct absaddr addr;
9006
9007 /* Decode the unwinding instructions. */
9008 while (1)
9009 {
9010 unsigned int op, op2;
9011
9012 ADVANCE;
9013 if (remaining == 0)
9014 break;
9015 remaining--;
9016 op = word >> 24;
9017 word <<= 8;
9018
9cf03b7e 9019 printf (" 0x%02x ", op);
fa197c1c
PB
9020
9021 if ((op & 0xc0) == 0x00)
9022 {
9023 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9024 printf (" sp = sp + %d", offset);
fa197c1c
PB
9025 }
9026 else if ((op & 0xc0) == 0x80)
9027 {
9028 GET_OP (op2);
9029 if (op == 0x80 && op2 == 0)
9030 printf (_("Refuse to unwind"));
9031 else
9032 {
9033 unsigned int mask = ((op & 0x1f) << 8) | op2;
9034 if (op & 0x20)
9035 printf ("pop compact {");
9036 else
9037 printf ("pop {");
9038
9039 decode_tic6x_unwind_regmask (mask);
9040 printf("}");
9041 }
9042 }
9043 else if ((op & 0xf0) == 0xc0)
9044 {
9045 unsigned int reg;
9046 unsigned int nregs;
9047 unsigned int i;
9048 const char *name;
a734115a
NC
9049 struct
9050 {
32ec8896
NC
9051 unsigned int offset;
9052 unsigned int reg;
fa197c1c
PB
9053 } regpos[16];
9054
9055 /* Scan entire instruction first so that GET_OP output is not
9056 interleaved with disassembly. */
9057 nregs = 0;
9058 for (i = 0; nregs < (op & 0xf); i++)
9059 {
9060 GET_OP (op2);
9061 reg = op2 >> 4;
9062 if (reg != 0xf)
9063 {
9064 regpos[nregs].offset = i * 2;
9065 regpos[nregs].reg = reg;
9066 nregs++;
9067 }
9068
9069 reg = op2 & 0xf;
9070 if (reg != 0xf)
9071 {
9072 regpos[nregs].offset = i * 2 + 1;
9073 regpos[nregs].reg = reg;
9074 nregs++;
9075 }
9076 }
9077
9078 printf (_("pop frame {"));
18344509 9079 if (nregs == 0)
fa197c1c 9080 {
18344509
NC
9081 printf (_("*corrupt* - no registers specified"));
9082 }
9083 else
9084 {
9085 reg = nregs - 1;
9086 for (i = i * 2; i > 0; i--)
fa197c1c 9087 {
18344509
NC
9088 if (regpos[reg].offset == i - 1)
9089 {
9090 name = tic6x_unwind_regnames[regpos[reg].reg];
9091 if (reg > 0)
9092 reg--;
9093 }
9094 else
9095 name = _("[pad]");
fa197c1c 9096
18344509
NC
9097 fputs (name, stdout);
9098 if (i > 1)
9099 printf (", ");
9100 }
fa197c1c
PB
9101 }
9102
9103 printf ("}");
9104 }
9105 else if (op == 0xd0)
9106 printf (" MOV FP, SP");
9107 else if (op == 0xd1)
9108 printf (" __c6xabi_pop_rts");
9109 else if (op == 0xd2)
9110 {
9111 unsigned char buf[9];
9112 unsigned int i, len;
9113 unsigned long offset;
a734115a 9114
fa197c1c
PB
9115 for (i = 0; i < sizeof (buf); i++)
9116 {
9117 GET_OP (buf[i]);
9118 if ((buf[i] & 0x80) == 0)
9119 break;
9120 }
0eff7165
NC
9121 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9122 if (i == sizeof (buf))
9123 {
0eff7165 9124 warn (_("Corrupt stack pointer adjustment detected\n"));
32ec8896 9125 return FALSE;
0eff7165 9126 }
948f632f 9127
cd30bcef 9128 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
fa197c1c
PB
9129 assert (len == i + 1);
9130 offset = offset * 8 + 0x408;
9131 printf (_("sp = sp + %ld"), offset);
9132 }
9133 else if ((op & 0xf0) == 0xe0)
9134 {
9135 if ((op & 0x0f) == 7)
9136 printf (" RETURN");
9137 else
9138 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9139 }
9140 else
9141 {
9142 printf (_(" [unsupported opcode]"));
9143 }
9144 putchar ('\n');
9145 }
32ec8896
NC
9146
9147 return TRUE;
fa197c1c
PB
9148}
9149
9150static bfd_vma
dda8d76d 9151arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9152{
9153 bfd_vma offset;
9154
9155 offset = word & 0x7fffffff;
9156 if (offset & 0x40000000)
9157 offset |= ~ (bfd_vma) 0x7fffffff;
9158
dda8d76d 9159 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9160 offset <<= 1;
9161
9162 return offset + where;
9163}
9164
32ec8896 9165static bfd_boolean
dda8d76d
NC
9166decode_arm_unwind (Filedata * filedata,
9167 struct arm_unw_aux_info * aux,
1b31d05e
NC
9168 unsigned int word,
9169 unsigned int remaining,
9170 bfd_vma data_offset,
9171 Elf_Internal_Shdr * data_sec,
9172 struct arm_section * data_arm_sec)
fa197c1c
PB
9173{
9174 int per_index;
9175 unsigned int more_words = 0;
37e14bc3 9176 struct absaddr addr;
1b31d05e 9177 bfd_vma sym_name = (bfd_vma) -1;
97953bab 9178 bfd_boolean res = TRUE;
fa197c1c
PB
9179
9180 if (remaining == 0)
9181 {
1b31d05e
NC
9182 /* Fetch the first word.
9183 Note - when decoding an object file the address extracted
9184 here will always be 0. So we also pass in the sym_name
9185 parameter so that we can find the symbol associated with
9186 the personality routine. */
dda8d76d 9187 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9188 & word, & addr, & sym_name))
32ec8896 9189 return FALSE;
1b31d05e 9190
fa197c1c
PB
9191 remaining = 4;
9192 }
c93dbb25
CZ
9193 else
9194 {
9195 addr.section = SHN_UNDEF;
9196 addr.offset = 0;
9197 }
fa197c1c
PB
9198
9199 if ((word & 0x80000000) == 0)
9200 {
9201 /* Expand prel31 for personality routine. */
9202 bfd_vma fn;
9203 const char *procname;
9204
dda8d76d 9205 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9206 printf (_(" Personality routine: "));
1b31d05e
NC
9207 if (fn == 0
9208 && addr.section == SHN_UNDEF && addr.offset == 0
9209 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9210 {
9211 procname = aux->strtab + sym_name;
9212 print_vma (fn, PREFIX_HEX);
9213 if (procname)
9214 {
9215 fputs (" <", stdout);
9216 fputs (procname, stdout);
9217 fputc ('>', stdout);
9218 }
9219 }
9220 else
dda8d76d 9221 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9222 fputc ('\n', stdout);
9223
9224 /* The GCC personality routines use the standard compact
9225 encoding, starting with one byte giving the number of
9226 words. */
9227 if (procname != NULL
9228 && (const_strneq (procname, "__gcc_personality_v0")
9229 || const_strneq (procname, "__gxx_personality_v0")
9230 || const_strneq (procname, "__gcj_personality_v0")
9231 || const_strneq (procname, "__gnu_objc_personality_v0")))
9232 {
9233 remaining = 0;
9234 more_words = 1;
9235 ADVANCE;
9236 if (!remaining)
9237 {
9238 printf (_(" [Truncated data]\n"));
32ec8896 9239 return FALSE;
fa197c1c
PB
9240 }
9241 more_words = word >> 24;
9242 word <<= 8;
9243 remaining--;
9244 per_index = -1;
9245 }
9246 else
32ec8896 9247 return TRUE;
fa197c1c
PB
9248 }
9249 else
9250 {
1b31d05e 9251 /* ARM EHABI Section 6.3:
0b4362b0 9252
1b31d05e 9253 An exception-handling table entry for the compact model looks like:
0b4362b0 9254
1b31d05e
NC
9255 31 30-28 27-24 23-0
9256 -- ----- ----- ----
9257 1 0 index Data for personalityRoutine[index] */
9258
dda8d76d 9259 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9260 && (word & 0x70000000))
32ec8896
NC
9261 {
9262 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
9263 res = FALSE;
9264 }
1b31d05e 9265
fa197c1c 9266 per_index = (word >> 24) & 0x7f;
1b31d05e 9267 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9268 if (per_index == 0)
9269 {
9270 more_words = 0;
9271 word <<= 8;
9272 remaining--;
9273 }
9274 else if (per_index < 3)
9275 {
9276 more_words = (word >> 16) & 0xff;
9277 word <<= 16;
9278 remaining -= 2;
9279 }
9280 }
9281
dda8d76d 9282 switch (filedata->file_header.e_machine)
fa197c1c
PB
9283 {
9284 case EM_ARM:
9285 if (per_index < 3)
9286 {
dda8d76d 9287 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9288 data_offset, data_sec, data_arm_sec))
9289 res = FALSE;
fa197c1c
PB
9290 }
9291 else
1b31d05e
NC
9292 {
9293 warn (_("Unknown ARM compact model index encountered\n"));
9294 printf (_(" [reserved]\n"));
32ec8896 9295 res = FALSE;
1b31d05e 9296 }
fa197c1c
PB
9297 break;
9298
9299 case EM_TI_C6000:
9300 if (per_index < 3)
9301 {
dda8d76d 9302 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9303 data_offset, data_sec, data_arm_sec))
9304 res = FALSE;
fa197c1c
PB
9305 }
9306 else if (per_index < 5)
9307 {
9308 if (((word >> 17) & 0x7f) == 0x7f)
9309 printf (_(" Restore stack from frame pointer\n"));
9310 else
9311 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9312 printf (_(" Registers restored: "));
9313 if (per_index == 4)
9314 printf (" (compact) ");
9315 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9316 putchar ('\n');
9317 printf (_(" Return register: %s\n"),
9318 tic6x_unwind_regnames[word & 0xf]);
9319 }
9320 else
1b31d05e 9321 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9322 break;
9323
9324 default:
74e1a04b 9325 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9326 filedata->file_header.e_machine);
32ec8896 9327 res = FALSE;
fa197c1c 9328 }
0b6ae522
DJ
9329
9330 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9331
9332 return res;
0b6ae522
DJ
9333}
9334
32ec8896 9335static bfd_boolean
dda8d76d
NC
9336dump_arm_unwind (Filedata * filedata,
9337 struct arm_unw_aux_info * aux,
9338 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9339{
9340 struct arm_section exidx_arm_sec, extab_arm_sec;
9341 unsigned int i, exidx_len;
948f632f 9342 unsigned long j, nfuns;
32ec8896 9343 bfd_boolean res = TRUE;
0b6ae522
DJ
9344
9345 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9346 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9347 exidx_len = exidx_sec->sh_size / 8;
9348
948f632f
DA
9349 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9350 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9351 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9352 aux->funtab[nfuns++] = aux->symtab[j];
9353 aux->nfuns = nfuns;
9354 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9355
0b6ae522
DJ
9356 for (i = 0; i < exidx_len; i++)
9357 {
9358 unsigned int exidx_fn, exidx_entry;
9359 struct absaddr fn_addr, entry_addr;
9360 bfd_vma fn;
9361
9362 fputc ('\n', stdout);
9363
dda8d76d 9364 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9365 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9366 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9367 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9368 {
948f632f 9369 free (aux->funtab);
1b31d05e
NC
9370 arm_free_section (& exidx_arm_sec);
9371 arm_free_section (& extab_arm_sec);
32ec8896 9372 return FALSE;
0b6ae522
DJ
9373 }
9374
83c257ca
NC
9375 /* ARM EHABI, Section 5:
9376 An index table entry consists of 2 words.
9377 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9378 if (exidx_fn & 0x80000000)
32ec8896
NC
9379 {
9380 warn (_("corrupt index table entry: %x\n"), exidx_fn);
9381 res = FALSE;
9382 }
83c257ca 9383
dda8d76d 9384 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9385
dda8d76d 9386 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9387 fputs (": ", stdout);
9388
9389 if (exidx_entry == 1)
9390 {
9391 print_vma (exidx_entry, PREFIX_HEX);
9392 fputs (" [cantunwind]\n", stdout);
9393 }
9394 else if (exidx_entry & 0x80000000)
9395 {
9396 print_vma (exidx_entry, PREFIX_HEX);
9397 fputc ('\n', stdout);
dda8d76d 9398 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9399 }
9400 else
9401 {
8f73510c 9402 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9403 Elf_Internal_Shdr *table_sec;
9404
9405 fputs ("@", stdout);
dda8d76d 9406 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9407 print_vma (table, PREFIX_HEX);
9408 printf ("\n");
9409
9410 /* Locate the matching .ARM.extab. */
9411 if (entry_addr.section != SHN_UNDEF
dda8d76d 9412 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9413 {
dda8d76d 9414 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9415 table_offset = entry_addr.offset;
1a915552
NC
9416 /* PR 18879 */
9417 if (table_offset > table_sec->sh_size
9418 || ((bfd_signed_vma) table_offset) < 0)
9419 {
9420 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9421 (unsigned long) table_offset,
dda8d76d 9422 printable_section_name (filedata, table_sec));
32ec8896 9423 res = FALSE;
1a915552
NC
9424 continue;
9425 }
0b6ae522
DJ
9426 }
9427 else
9428 {
dda8d76d 9429 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9430 if (table_sec != NULL)
9431 table_offset = table - table_sec->sh_addr;
9432 }
32ec8896 9433
0b6ae522
DJ
9434 if (table_sec == NULL)
9435 {
9436 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9437 (unsigned long) table);
32ec8896 9438 res = FALSE;
0b6ae522
DJ
9439 continue;
9440 }
32ec8896 9441
dda8d76d 9442 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896
NC
9443 &extab_arm_sec))
9444 res = FALSE;
0b6ae522
DJ
9445 }
9446 }
9447
9448 printf ("\n");
9449
948f632f 9450 free (aux->funtab);
0b6ae522
DJ
9451 arm_free_section (&exidx_arm_sec);
9452 arm_free_section (&extab_arm_sec);
32ec8896
NC
9453
9454 return res;
0b6ae522
DJ
9455}
9456
fa197c1c 9457/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9458
32ec8896 9459static bfd_boolean
dda8d76d 9460arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9461{
9462 struct arm_unw_aux_info aux;
9463 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9464 Elf_Internal_Shdr *sec;
9465 unsigned long i;
fa197c1c 9466 unsigned int sec_type;
32ec8896 9467 bfd_boolean res = TRUE;
0b6ae522 9468
dda8d76d 9469 switch (filedata->file_header.e_machine)
fa197c1c
PB
9470 {
9471 case EM_ARM:
9472 sec_type = SHT_ARM_EXIDX;
9473 break;
9474
9475 case EM_TI_C6000:
9476 sec_type = SHT_C6000_UNWIND;
9477 break;
9478
0b4362b0 9479 default:
74e1a04b 9480 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9481 filedata->file_header.e_machine);
32ec8896 9482 return FALSE;
fa197c1c
PB
9483 }
9484
dda8d76d 9485 if (filedata->string_table == NULL)
32ec8896 9486 return FALSE;
1b31d05e
NC
9487
9488 memset (& aux, 0, sizeof (aux));
dda8d76d 9489 aux.filedata = filedata;
0b6ae522 9490
dda8d76d 9491 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9492 {
28d13567 9493 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9494 {
28d13567 9495 if (aux.symtab)
74e1a04b 9496 {
28d13567
AM
9497 error (_("Multiple symbol tables encountered\n"));
9498 free (aux.symtab);
9499 aux.symtab = NULL;
74e1a04b 9500 free (aux.strtab);
28d13567 9501 aux.strtab = NULL;
74e1a04b 9502 }
28d13567
AM
9503 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9504 &aux.strtab, &aux.strtab_size))
9505 return FALSE;
0b6ae522 9506 }
fa197c1c 9507 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9508 unwsec = sec;
9509 }
9510
1b31d05e 9511 if (unwsec == NULL)
0b6ae522 9512 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9513 else
dda8d76d 9514 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9515 {
9516 if (sec->sh_type == sec_type)
9517 {
d3a49aa8
AM
9518 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9519 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9520 "contains %lu entry:\n",
9521 "\nUnwind section '%s' at offset 0x%lx "
9522 "contains %lu entries:\n",
9523 num_unwind),
dda8d76d 9524 printable_section_name (filedata, sec),
1b31d05e 9525 (unsigned long) sec->sh_offset,
d3a49aa8 9526 num_unwind);
0b6ae522 9527
dda8d76d 9528 if (! dump_arm_unwind (filedata, &aux, sec))
32ec8896 9529 res = FALSE;
1b31d05e
NC
9530 }
9531 }
0b6ae522
DJ
9532
9533 if (aux.symtab)
9534 free (aux.symtab);
9535 if (aux.strtab)
9536 free ((char *) aux.strtab);
32ec8896
NC
9537
9538 return res;
0b6ae522
DJ
9539}
9540
32ec8896 9541static bfd_boolean
dda8d76d 9542process_unwind (Filedata * filedata)
57346661 9543{
2cf0635d
NC
9544 struct unwind_handler
9545 {
32ec8896 9546 unsigned int machtype;
dda8d76d 9547 bfd_boolean (* handler)(Filedata *);
2cf0635d
NC
9548 } handlers[] =
9549 {
0b6ae522 9550 { EM_ARM, arm_process_unwind },
57346661
AM
9551 { EM_IA_64, ia64_process_unwind },
9552 { EM_PARISC, hppa_process_unwind },
fa197c1c 9553 { EM_TI_C6000, arm_process_unwind },
32ec8896 9554 { 0, NULL }
57346661
AM
9555 };
9556 int i;
9557
9558 if (!do_unwind)
32ec8896 9559 return TRUE;
57346661
AM
9560
9561 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9562 if (filedata->file_header.e_machine == handlers[i].machtype)
9563 return handlers[i].handler (filedata);
57346661 9564
1b31d05e 9565 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9566 get_machine_name (filedata->file_header.e_machine));
32ec8896 9567 return TRUE;
57346661
AM
9568}
9569
37c18eed
SD
9570static void
9571dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
9572{
9573 switch (entry->d_tag)
9574 {
9575 case DT_AARCH64_BTI_PLT:
1dbade74 9576 case DT_AARCH64_PAC_PLT:
37c18eed
SD
9577 break;
9578 default:
9579 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9580 break;
9581 }
9582 putchar ('\n');
9583}
9584
252b5132 9585static void
978c4450 9586dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
9587{
9588 switch (entry->d_tag)
9589 {
9590 case DT_MIPS_FLAGS:
9591 if (entry->d_un.d_val == 0)
4b68bca3 9592 printf (_("NONE"));
252b5132
RH
9593 else
9594 {
9595 static const char * opts[] =
9596 {
9597 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9598 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9599 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9600 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9601 "RLD_ORDER_SAFE"
9602 };
9603 unsigned int cnt;
32ec8896 9604 bfd_boolean first = TRUE;
2b692964 9605
60bca95a 9606 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9607 if (entry->d_un.d_val & (1 << cnt))
9608 {
9609 printf ("%s%s", first ? "" : " ", opts[cnt]);
32ec8896 9610 first = FALSE;
252b5132 9611 }
252b5132
RH
9612 }
9613 break;
103f02d3 9614
252b5132 9615 case DT_MIPS_IVERSION:
978c4450
AM
9616 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
9617 printf (_("Interface Version: %s"),
9618 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 9619 else
76ca31c0
NC
9620 {
9621 char buf[40];
9622 sprintf_vma (buf, entry->d_un.d_ptr);
9623 /* Note: coded this way so that there is a single string for translation. */
9624 printf (_("<corrupt: %s>"), buf);
9625 }
252b5132 9626 break;
103f02d3 9627
252b5132
RH
9628 case DT_MIPS_TIME_STAMP:
9629 {
d5b07ef4 9630 char timebuf[128];
2cf0635d 9631 struct tm * tmp;
91d6fa6a 9632 time_t atime = entry->d_un.d_val;
82b1b41b 9633
91d6fa6a 9634 tmp = gmtime (&atime);
82b1b41b
NC
9635 /* PR 17531: file: 6accc532. */
9636 if (tmp == NULL)
9637 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9638 else
9639 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9640 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9641 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9642 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9643 }
9644 break;
103f02d3 9645
252b5132
RH
9646 case DT_MIPS_RLD_VERSION:
9647 case DT_MIPS_LOCAL_GOTNO:
9648 case DT_MIPS_CONFLICTNO:
9649 case DT_MIPS_LIBLISTNO:
9650 case DT_MIPS_SYMTABNO:
9651 case DT_MIPS_UNREFEXTNO:
9652 case DT_MIPS_HIPAGENO:
9653 case DT_MIPS_DELTA_CLASS_NO:
9654 case DT_MIPS_DELTA_INSTANCE_NO:
9655 case DT_MIPS_DELTA_RELOC_NO:
9656 case DT_MIPS_DELTA_SYM_NO:
9657 case DT_MIPS_DELTA_CLASSSYM_NO:
9658 case DT_MIPS_COMPACT_SIZE:
c69075ac 9659 print_vma (entry->d_un.d_val, DEC);
252b5132 9660 break;
103f02d3 9661
f16a9783 9662 case DT_MIPS_XHASH:
978c4450
AM
9663 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
9664 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
9665 /* Falls through. */
9666
103f02d3 9667 default:
4b68bca3 9668 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9669 }
4b68bca3 9670 putchar ('\n');
103f02d3
UD
9671}
9672
103f02d3 9673static void
2cf0635d 9674dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9675{
9676 switch (entry->d_tag)
9677 {
9678 case DT_HP_DLD_FLAGS:
9679 {
9680 static struct
9681 {
9682 long int bit;
2cf0635d 9683 const char * str;
5e220199
NC
9684 }
9685 flags[] =
9686 {
9687 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9688 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9689 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9690 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9691 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9692 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9693 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9694 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9695 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9696 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9697 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9698 { DT_HP_GST, "HP_GST" },
9699 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
9700 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
9701 { DT_HP_NODELETE, "HP_NODELETE" },
9702 { DT_HP_GROUP, "HP_GROUP" },
9703 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 9704 };
32ec8896 9705 bfd_boolean first = TRUE;
5e220199 9706 size_t cnt;
f7a99963 9707 bfd_vma val = entry->d_un.d_val;
103f02d3 9708
60bca95a 9709 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 9710 if (val & flags[cnt].bit)
30800947
NC
9711 {
9712 if (! first)
9713 putchar (' ');
9714 fputs (flags[cnt].str, stdout);
32ec8896 9715 first = FALSE;
30800947
NC
9716 val ^= flags[cnt].bit;
9717 }
76da6bbe 9718
103f02d3 9719 if (val != 0 || first)
f7a99963
NC
9720 {
9721 if (! first)
9722 putchar (' ');
9723 print_vma (val, HEX);
9724 }
103f02d3
UD
9725 }
9726 break;
76da6bbe 9727
252b5132 9728 default:
f7a99963
NC
9729 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9730 break;
252b5132 9731 }
35b1837e 9732 putchar ('\n');
252b5132
RH
9733}
9734
28f997cf
TG
9735#ifdef BFD64
9736
9737/* VMS vs Unix time offset and factor. */
9738
9739#define VMS_EPOCH_OFFSET 35067168000000000LL
9740#define VMS_GRANULARITY_FACTOR 10000000
9741
9742/* Display a VMS time in a human readable format. */
9743
9744static void
9745print_vms_time (bfd_int64_t vmstime)
9746{
9747 struct tm *tm;
9748 time_t unxtime;
9749
9750 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
9751 tm = gmtime (&unxtime);
9752 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
9753 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
9754 tm->tm_hour, tm->tm_min, tm->tm_sec);
9755}
9756#endif /* BFD64 */
9757
ecc51f48 9758static void
2cf0635d 9759dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
9760{
9761 switch (entry->d_tag)
9762 {
0de14b54 9763 case DT_IA_64_PLT_RESERVE:
bdf4d63a 9764 /* First 3 slots reserved. */
ecc51f48
NC
9765 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9766 printf (" -- ");
9767 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
9768 break;
9769
28f997cf
TG
9770 case DT_IA_64_VMS_LINKTIME:
9771#ifdef BFD64
9772 print_vms_time (entry->d_un.d_val);
9773#endif
9774 break;
9775
9776 case DT_IA_64_VMS_LNKFLAGS:
9777 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9778 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
9779 printf (" CALL_DEBUG");
9780 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
9781 printf (" NOP0BUFS");
9782 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
9783 printf (" P0IMAGE");
9784 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
9785 printf (" MKTHREADS");
9786 if (entry->d_un.d_val & VMS_LF_UPCALLS)
9787 printf (" UPCALLS");
9788 if (entry->d_un.d_val & VMS_LF_IMGSTA)
9789 printf (" IMGSTA");
9790 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
9791 printf (" INITIALIZE");
9792 if (entry->d_un.d_val & VMS_LF_MAIN)
9793 printf (" MAIN");
9794 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
9795 printf (" EXE_INIT");
9796 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
9797 printf (" TBK_IN_IMG");
9798 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
9799 printf (" DBG_IN_IMG");
9800 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
9801 printf (" TBK_IN_DSF");
9802 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
9803 printf (" DBG_IN_DSF");
9804 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
9805 printf (" SIGNATURES");
9806 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
9807 printf (" REL_SEG_OFF");
9808 break;
9809
bdf4d63a
JJ
9810 default:
9811 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9812 break;
ecc51f48 9813 }
bdf4d63a 9814 putchar ('\n');
ecc51f48
NC
9815}
9816
32ec8896 9817static bfd_boolean
dda8d76d 9818get_32bit_dynamic_section (Filedata * filedata)
252b5132 9819{
2cf0635d
NC
9820 Elf32_External_Dyn * edyn;
9821 Elf32_External_Dyn * ext;
9822 Elf_Internal_Dyn * entry;
103f02d3 9823
978c4450
AM
9824 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
9825 filedata->dynamic_addr, 1,
9826 filedata->dynamic_size,
9827 _("dynamic section"));
a6e9f9df 9828 if (!edyn)
32ec8896 9829 return FALSE;
103f02d3 9830
071436c6
NC
9831 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9832 might not have the luxury of section headers. Look for the DT_NULL
9833 terminator to determine the number of entries. */
978c4450
AM
9834 for (ext = edyn, filedata->dynamic_nent = 0;
9835 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
9836 ext++)
9837 {
978c4450 9838 filedata->dynamic_nent++;
ba2685cc
AM
9839 if (BYTE_GET (ext->d_tag) == DT_NULL)
9840 break;
9841 }
252b5132 9842
978c4450
AM
9843 filedata->dynamic_section
9844 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
9845 if (filedata->dynamic_section == NULL)
252b5132 9846 {
8b73c356 9847 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 9848 (unsigned long) filedata->dynamic_nent);
9ea033b2 9849 free (edyn);
32ec8896 9850 return FALSE;
9ea033b2 9851 }
252b5132 9852
978c4450
AM
9853 for (ext = edyn, entry = filedata->dynamic_section;
9854 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 9855 ext++, entry++)
9ea033b2 9856 {
fb514b26
AM
9857 entry->d_tag = BYTE_GET (ext->d_tag);
9858 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9859 }
9860
9ea033b2
NC
9861 free (edyn);
9862
32ec8896 9863 return TRUE;
9ea033b2
NC
9864}
9865
32ec8896 9866static bfd_boolean
dda8d76d 9867get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 9868{
2cf0635d
NC
9869 Elf64_External_Dyn * edyn;
9870 Elf64_External_Dyn * ext;
9871 Elf_Internal_Dyn * entry;
103f02d3 9872
071436c6 9873 /* Read in the data. */
978c4450
AM
9874 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
9875 filedata->dynamic_addr, 1,
9876 filedata->dynamic_size,
9877 _("dynamic section"));
a6e9f9df 9878 if (!edyn)
32ec8896 9879 return FALSE;
103f02d3 9880
071436c6
NC
9881 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9882 might not have the luxury of section headers. Look for the DT_NULL
9883 terminator to determine the number of entries. */
978c4450 9884 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 9885 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 9886 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
9887 ext++)
9888 {
978c4450 9889 filedata->dynamic_nent++;
66543521 9890 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
9891 break;
9892 }
252b5132 9893
978c4450
AM
9894 filedata->dynamic_section
9895 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
9896 if (filedata->dynamic_section == NULL)
252b5132 9897 {
8b73c356 9898 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 9899 (unsigned long) filedata->dynamic_nent);
252b5132 9900 free (edyn);
32ec8896 9901 return FALSE;
252b5132
RH
9902 }
9903
071436c6 9904 /* Convert from external to internal formats. */
978c4450
AM
9905 for (ext = edyn, entry = filedata->dynamic_section;
9906 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 9907 ext++, entry++)
252b5132 9908 {
66543521
AM
9909 entry->d_tag = BYTE_GET (ext->d_tag);
9910 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9911 }
9912
9913 free (edyn);
9914
32ec8896 9915 return TRUE;
9ea033b2
NC
9916}
9917
e9e44622
JJ
9918static void
9919print_dynamic_flags (bfd_vma flags)
d1133906 9920{
32ec8896 9921 bfd_boolean first = TRUE;
13ae64f3 9922
d1133906
NC
9923 while (flags)
9924 {
9925 bfd_vma flag;
9926
9927 flag = flags & - flags;
9928 flags &= ~ flag;
9929
e9e44622 9930 if (first)
32ec8896 9931 first = FALSE;
e9e44622
JJ
9932 else
9933 putc (' ', stdout);
13ae64f3 9934
d1133906
NC
9935 switch (flag)
9936 {
e9e44622
JJ
9937 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
9938 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
9939 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
9940 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
9941 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 9942 default: fputs (_("unknown"), stdout); break;
d1133906
NC
9943 }
9944 }
e9e44622 9945 puts ("");
d1133906
NC
9946}
9947
10ca4b04
L
9948static bfd_vma *
9949get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
9950{
9951 unsigned char * e_data;
9952 bfd_vma * i_data;
9953
9954 /* If the size_t type is smaller than the bfd_size_type, eg because
9955 you are building a 32-bit tool on a 64-bit host, then make sure
9956 that when (number) is cast to (size_t) no information is lost. */
9957 if (sizeof (size_t) < sizeof (bfd_size_type)
9958 && (bfd_size_type) ((size_t) number) != number)
9959 {
9960 error (_("Size truncation prevents reading %s elements of size %u\n"),
9961 bfd_vmatoa ("u", number), ent_size);
9962 return NULL;
9963 }
9964
9965 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
9966 attempting to allocate memory when the read is bound to fail. */
9967 if (ent_size * number > filedata->file_size)
9968 {
9969 error (_("Invalid number of dynamic entries: %s\n"),
9970 bfd_vmatoa ("u", number));
9971 return NULL;
9972 }
9973
9974 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
9975 if (e_data == NULL)
9976 {
9977 error (_("Out of memory reading %s dynamic entries\n"),
9978 bfd_vmatoa ("u", number));
9979 return NULL;
9980 }
9981
9982 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
9983 {
9984 error (_("Unable to read in %s bytes of dynamic data\n"),
9985 bfd_vmatoa ("u", number * ent_size));
9986 free (e_data);
9987 return NULL;
9988 }
9989
9990 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
9991 if (i_data == NULL)
9992 {
9993 error (_("Out of memory allocating space for %s dynamic entries\n"),
9994 bfd_vmatoa ("u", number));
9995 free (e_data);
9996 return NULL;
9997 }
9998
9999 while (number--)
10000 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10001
10002 free (e_data);
10003
10004 return i_data;
10005}
10006
10007static unsigned long
10008get_num_dynamic_syms (Filedata * filedata)
10009{
10010 unsigned long num_of_syms = 0;
10011
10012 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10013 return num_of_syms;
10014
978c4450 10015 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10016 {
10017 unsigned char nb[8];
10018 unsigned char nc[8];
10019 unsigned int hash_ent_size = 4;
10020
10021 if ((filedata->file_header.e_machine == EM_ALPHA
10022 || filedata->file_header.e_machine == EM_S390
10023 || filedata->file_header.e_machine == EM_S390_OLD)
10024 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10025 hash_ent_size = 8;
10026
10027 if (fseek (filedata->handle,
978c4450
AM
10028 (filedata->archive_file_offset
10029 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10030 sizeof nb + sizeof nc)),
10031 SEEK_SET))
10032 {
10033 error (_("Unable to seek to start of dynamic information\n"));
10034 goto no_hash;
10035 }
10036
10037 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10038 {
10039 error (_("Failed to read in number of buckets\n"));
10040 goto no_hash;
10041 }
10042
10043 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10044 {
10045 error (_("Failed to read in number of chains\n"));
10046 goto no_hash;
10047 }
10048
978c4450
AM
10049 filedata->nbuckets = byte_get (nb, hash_ent_size);
10050 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10051
2482f306
AM
10052 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10053 {
10054 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10055 hash_ent_size);
10056 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10057 hash_ent_size);
001890e1 10058
2482f306
AM
10059 if (filedata->buckets != NULL && filedata->chains != NULL)
10060 num_of_syms = filedata->nchains;
10061 }
ceb9bf11 10062 no_hash:
10ca4b04
L
10063 if (num_of_syms == 0)
10064 {
978c4450 10065 if (filedata->buckets)
10ca4b04 10066 {
978c4450
AM
10067 free (filedata->buckets);
10068 filedata->buckets = NULL;
10ca4b04 10069 }
978c4450 10070 if (filedata->chains)
10ca4b04 10071 {
978c4450
AM
10072 free (filedata->chains);
10073 filedata->chains = NULL;
10ca4b04 10074 }
978c4450 10075 filedata->nbuckets = 0;
10ca4b04
L
10076 }
10077 }
10078
978c4450 10079 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10080 {
10081 unsigned char nb[16];
10082 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10083 bfd_vma buckets_vma;
10084 unsigned long hn;
10ca4b04
L
10085
10086 if (fseek (filedata->handle,
978c4450
AM
10087 (filedata->archive_file_offset
10088 + offset_from_vma (filedata,
10089 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10090 sizeof nb)),
10091 SEEK_SET))
10092 {
10093 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10094 goto no_gnu_hash;
10095 }
10096
10097 if (fread (nb, 16, 1, filedata->handle) != 1)
10098 {
10099 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10100 goto no_gnu_hash;
10101 }
10102
978c4450
AM
10103 filedata->ngnubuckets = byte_get (nb, 4);
10104 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10105 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10106 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10107 if (is_32bit_elf)
10108 buckets_vma += bitmaskwords * 4;
10109 else
10110 buckets_vma += bitmaskwords * 8;
10111
10112 if (fseek (filedata->handle,
978c4450 10113 (filedata->archive_file_offset
10ca4b04
L
10114 + offset_from_vma (filedata, buckets_vma, 4)),
10115 SEEK_SET))
10116 {
10117 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10118 goto no_gnu_hash;
10119 }
10120
978c4450
AM
10121 filedata->gnubuckets
10122 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10123
978c4450 10124 if (filedata->gnubuckets == NULL)
90837ea7 10125 goto no_gnu_hash;
10ca4b04 10126
978c4450
AM
10127 for (i = 0; i < filedata->ngnubuckets; i++)
10128 if (filedata->gnubuckets[i] != 0)
10ca4b04 10129 {
978c4450 10130 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10131 goto no_gnu_hash;
10ca4b04 10132
978c4450
AM
10133 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10134 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10135 }
10136
10137 if (maxchain == 0xffffffff)
90837ea7 10138 goto no_gnu_hash;
10ca4b04 10139
978c4450 10140 maxchain -= filedata->gnusymidx;
10ca4b04
L
10141
10142 if (fseek (filedata->handle,
978c4450
AM
10143 (filedata->archive_file_offset
10144 + offset_from_vma (filedata,
10145 buckets_vma + 4 * (filedata->ngnubuckets
10146 + maxchain),
10147 4)),
10ca4b04
L
10148 SEEK_SET))
10149 {
10150 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10151 goto no_gnu_hash;
10152 }
10153
10154 do
10155 {
10156 if (fread (nb, 4, 1, filedata->handle) != 1)
10157 {
10158 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10159 goto no_gnu_hash;
10160 }
10161
10162 if (maxchain + 1 == 0)
90837ea7 10163 goto no_gnu_hash;
10ca4b04
L
10164
10165 ++maxchain;
10166 }
10167 while ((byte_get (nb, 4) & 1) == 0);
10168
10169 if (fseek (filedata->handle,
978c4450
AM
10170 (filedata->archive_file_offset
10171 + offset_from_vma (filedata, (buckets_vma
10172 + 4 * filedata->ngnubuckets),
10173 4)),
10ca4b04
L
10174 SEEK_SET))
10175 {
10176 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10177 goto no_gnu_hash;
10178 }
10179
978c4450
AM
10180 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10181 filedata->ngnuchains = maxchain;
10ca4b04 10182
978c4450 10183 if (filedata->gnuchains == NULL)
90837ea7 10184 goto no_gnu_hash;
10ca4b04 10185
978c4450 10186 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10187 {
10188 if (fseek (filedata->handle,
978c4450 10189 (filedata->archive_file_offset
10ca4b04 10190 + offset_from_vma (filedata, (buckets_vma
978c4450 10191 + 4 * (filedata->ngnubuckets
10ca4b04
L
10192 + maxchain)), 4)),
10193 SEEK_SET))
10194 {
10195 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10196 goto no_gnu_hash;
10197 }
10198
978c4450 10199 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10200 if (filedata->mipsxlat == NULL)
10201 goto no_gnu_hash;
10ca4b04
L
10202 }
10203
978c4450
AM
10204 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10205 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10206 {
978c4450
AM
10207 bfd_vma si = filedata->gnubuckets[hn];
10208 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10209
10210 do
10211 {
978c4450 10212 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 10213 {
c31ab5a0
AM
10214 if (off < filedata->ngnuchains
10215 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 10216 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
10217 }
10218 else
10219 {
10220 if (si >= num_of_syms)
10221 num_of_syms = si + 1;
10222 }
10223 si++;
10224 }
978c4450
AM
10225 while (off < filedata->ngnuchains
10226 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
10227 }
10228
90837ea7 10229 if (num_of_syms == 0)
10ca4b04 10230 {
90837ea7 10231 no_gnu_hash:
978c4450 10232 if (filedata->mipsxlat)
10ca4b04 10233 {
978c4450
AM
10234 free (filedata->mipsxlat);
10235 filedata->mipsxlat = NULL;
10ca4b04 10236 }
978c4450 10237 if (filedata->gnuchains)
10ca4b04 10238 {
978c4450
AM
10239 free (filedata->gnuchains);
10240 filedata->gnuchains = NULL;
10ca4b04 10241 }
978c4450 10242 if (filedata->gnubuckets)
10ca4b04 10243 {
978c4450
AM
10244 free (filedata->gnubuckets);
10245 filedata->gnubuckets = NULL;
10ca4b04 10246 }
978c4450
AM
10247 filedata->ngnubuckets = 0;
10248 filedata->ngnuchains = 0;
10ca4b04
L
10249 }
10250 }
10251
10252 return num_of_syms;
10253}
10254
b2d38a17
NC
10255/* Parse and display the contents of the dynamic section. */
10256
32ec8896 10257static bfd_boolean
dda8d76d 10258process_dynamic_section (Filedata * filedata)
9ea033b2 10259{
2cf0635d 10260 Elf_Internal_Dyn * entry;
9ea033b2 10261
978c4450 10262 if (filedata->dynamic_size == 0)
9ea033b2
NC
10263 {
10264 if (do_dynamic)
b2d38a17 10265 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2 10266
32ec8896 10267 return TRUE;
9ea033b2
NC
10268 }
10269
10270 if (is_32bit_elf)
10271 {
dda8d76d 10272 if (! get_32bit_dynamic_section (filedata))
32ec8896
NC
10273 return FALSE;
10274 }
10275 else
10276 {
dda8d76d 10277 if (! get_64bit_dynamic_section (filedata))
32ec8896 10278 return FALSE;
9ea033b2 10279 }
9ea033b2 10280
252b5132 10281 /* Find the appropriate symbol table. */
978c4450 10282 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 10283 {
2482f306
AM
10284 unsigned long num_of_syms;
10285
978c4450
AM
10286 for (entry = filedata->dynamic_section;
10287 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10288 ++entry)
10ca4b04 10289 if (entry->d_tag == DT_SYMTAB)
978c4450 10290 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 10291 else if (entry->d_tag == DT_SYMENT)
978c4450 10292 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 10293 else if (entry->d_tag == DT_HASH)
978c4450 10294 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 10295 else if (entry->d_tag == DT_GNU_HASH)
978c4450 10296 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
10297 else if ((filedata->file_header.e_machine == EM_MIPS
10298 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10299 && entry->d_tag == DT_MIPS_XHASH)
10300 {
978c4450
AM
10301 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10302 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 10303 }
252b5132 10304
2482f306
AM
10305 num_of_syms = get_num_dynamic_syms (filedata);
10306
10307 if (num_of_syms != 0
10308 && filedata->dynamic_symbols == NULL
10309 && filedata->dynamic_info[DT_SYMTAB]
978c4450 10310 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
10311 {
10312 Elf_Internal_Phdr *seg;
2482f306 10313 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 10314
2482f306
AM
10315 if (! get_program_headers (filedata))
10316 {
10317 error (_("Cannot interpret virtual addresses "
10318 "without program headers.\n"));
10319 return FALSE;
10320 }
252b5132 10321
2482f306
AM
10322 for (seg = filedata->program_headers;
10323 seg < filedata->program_headers + filedata->file_header.e_phnum;
10324 ++seg)
10325 {
10326 if (seg->p_type != PT_LOAD)
10327 continue;
252b5132 10328
2482f306
AM
10329 if (seg->p_offset + seg->p_filesz > filedata->file_size)
10330 {
10331 /* See PR 21379 for a reproducer. */
10332 error (_("Invalid PT_LOAD entry\n"));
10333 return FALSE;
10334 }
252b5132 10335
2482f306
AM
10336 if (vma >= (seg->p_vaddr & -seg->p_align)
10337 && vma < seg->p_vaddr + seg->p_filesz)
10338 {
10339 /* Since we do not know how big the symbol table is,
10340 we default to reading in up to the end of PT_LOAD
10341 segment and processing that. This is overkill, I
10342 know, but it should work. */
10343 Elf_Internal_Shdr section;
10344 section.sh_offset = (vma - seg->p_vaddr
10345 + seg->p_offset);
10346 section.sh_size = (num_of_syms
10347 * filedata->dynamic_info[DT_SYMENT]);
10348 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
10349
10350 if (do_checks
10351 && filedata->dynamic_symtab_section != NULL
10352 && ((filedata->dynamic_symtab_section->sh_offset
10353 != section.sh_offset)
10354 || (filedata->dynamic_symtab_section->sh_size
10355 != section.sh_size)
10356 || (filedata->dynamic_symtab_section->sh_entsize
10357 != section.sh_entsize)))
10358 warn (_("\
10359the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
10360
2482f306
AM
10361 section.sh_name = filedata->string_table_length;
10362 filedata->dynamic_symbols
10363 = GET_ELF_SYMBOLS (filedata, &section,
10364 &filedata->num_dynamic_syms);
10365 if (filedata->dynamic_symbols == NULL
10366 || filedata->num_dynamic_syms != num_of_syms)
10367 {
10368 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
10369 return FALSE;
10370 }
10371 break;
10372 }
10373 }
10374 }
10375 }
252b5132
RH
10376
10377 /* Similarly find a string table. */
978c4450
AM
10378 if (filedata->dynamic_strings == NULL)
10379 for (entry = filedata->dynamic_section;
10380 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
10381 ++entry)
10382 {
10383 if (entry->d_tag == DT_STRTAB)
978c4450 10384 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 10385
10ca4b04 10386 if (entry->d_tag == DT_STRSZ)
978c4450 10387 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10388
978c4450
AM
10389 if (filedata->dynamic_info[DT_STRTAB]
10390 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
10391 {
10392 unsigned long offset;
978c4450 10393 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
10394
10395 offset = offset_from_vma (filedata,
978c4450 10396 filedata->dynamic_info[DT_STRTAB],
10ca4b04 10397 str_tab_len);
8ac10c5b
L
10398 if (do_checks
10399 && filedata->dynamic_strtab_section
10400 && ((filedata->dynamic_strtab_section->sh_offset
10401 != (file_ptr) offset)
10402 || (filedata->dynamic_strtab_section->sh_size
10403 != str_tab_len)))
10404 warn (_("\
10405the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
10406
978c4450
AM
10407 filedata->dynamic_strings
10408 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
10409 _("dynamic string table"));
10410 if (filedata->dynamic_strings == NULL)
10ca4b04
L
10411 {
10412 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10413 break;
10414 }
e3d39609 10415
978c4450 10416 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
10417 break;
10418 }
10419 }
252b5132
RH
10420
10421 /* And find the syminfo section if available. */
978c4450 10422 if (filedata->dynamic_syminfo == NULL)
252b5132 10423 {
3e8bba36 10424 unsigned long syminsz = 0;
252b5132 10425
978c4450
AM
10426 for (entry = filedata->dynamic_section;
10427 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10428 ++entry)
252b5132
RH
10429 {
10430 if (entry->d_tag == DT_SYMINENT)
10431 {
10432 /* Note: these braces are necessary to avoid a syntax
10433 error from the SunOS4 C compiler. */
049b0c3a
NC
10434 /* PR binutils/17531: A corrupt file can trigger this test.
10435 So do not use an assert, instead generate an error message. */
10436 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10437 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10438 (int) entry->d_un.d_val);
252b5132
RH
10439 }
10440 else if (entry->d_tag == DT_SYMINSZ)
10441 syminsz = entry->d_un.d_val;
10442 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
10443 filedata->dynamic_syminfo_offset
10444 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
10445 }
10446
978c4450 10447 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 10448 {
2cf0635d
NC
10449 Elf_External_Syminfo * extsyminfo;
10450 Elf_External_Syminfo * extsym;
10451 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10452
10453 /* There is a syminfo section. Read the data. */
3f5e193b 10454 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
10455 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
10456 1, syminsz, _("symbol information"));
a6e9f9df 10457 if (!extsyminfo)
32ec8896 10458 return FALSE;
252b5132 10459
978c4450 10460 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
10461 {
10462 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 10463 free (filedata->dynamic_syminfo);
e3d39609 10464 }
978c4450
AM
10465 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
10466 if (filedata->dynamic_syminfo == NULL)
252b5132 10467 {
2482f306
AM
10468 error (_("Out of memory allocating %lu bytes "
10469 "for dynamic symbol info\n"),
8b73c356 10470 (unsigned long) syminsz);
32ec8896 10471 return FALSE;
252b5132
RH
10472 }
10473
2482f306
AM
10474 filedata->dynamic_syminfo_nent
10475 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 10476 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
10477 syminfo < (filedata->dynamic_syminfo
10478 + filedata->dynamic_syminfo_nent);
86dba8ee 10479 ++syminfo, ++extsym)
252b5132 10480 {
86dba8ee
AM
10481 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10482 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10483 }
10484
10485 free (extsyminfo);
10486 }
10487 }
10488
978c4450 10489 if (do_dynamic && filedata->dynamic_addr)
d3a49aa8
AM
10490 printf (ngettext ("\nDynamic section at offset 0x%lx "
10491 "contains %lu entry:\n",
10492 "\nDynamic section at offset 0x%lx "
10493 "contains %lu entries:\n",
978c4450
AM
10494 filedata->dynamic_nent),
10495 filedata->dynamic_addr, (unsigned long) filedata->dynamic_nent);
252b5132
RH
10496 if (do_dynamic)
10497 printf (_(" Tag Type Name/Value\n"));
10498
978c4450
AM
10499 for (entry = filedata->dynamic_section;
10500 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10501 entry++)
252b5132
RH
10502 {
10503 if (do_dynamic)
f7a99963 10504 {
2cf0635d 10505 const char * dtype;
e699b9ff 10506
f7a99963
NC
10507 putchar (' ');
10508 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10509 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10510 printf (" (%s)%*s", dtype,
32ec8896 10511 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10512 }
252b5132
RH
10513
10514 switch (entry->d_tag)
10515 {
d1133906
NC
10516 case DT_FLAGS:
10517 if (do_dynamic)
e9e44622 10518 print_dynamic_flags (entry->d_un.d_val);
d1133906 10519 break;
76da6bbe 10520
252b5132
RH
10521 case DT_AUXILIARY:
10522 case DT_FILTER:
019148e4
L
10523 case DT_CONFIG:
10524 case DT_DEPAUDIT:
10525 case DT_AUDIT:
252b5132
RH
10526 if (do_dynamic)
10527 {
019148e4 10528 switch (entry->d_tag)
b34976b6 10529 {
019148e4
L
10530 case DT_AUXILIARY:
10531 printf (_("Auxiliary library"));
10532 break;
10533
10534 case DT_FILTER:
10535 printf (_("Filter library"));
10536 break;
10537
b34976b6 10538 case DT_CONFIG:
019148e4
L
10539 printf (_("Configuration file"));
10540 break;
10541
10542 case DT_DEPAUDIT:
10543 printf (_("Dependency audit library"));
10544 break;
10545
10546 case DT_AUDIT:
10547 printf (_("Audit library"));
10548 break;
10549 }
252b5132 10550
978c4450
AM
10551 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10552 printf (": [%s]\n",
10553 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 10554 else
f7a99963
NC
10555 {
10556 printf (": ");
10557 print_vma (entry->d_un.d_val, PREFIX_HEX);
10558 putchar ('\n');
10559 }
252b5132
RH
10560 }
10561 break;
10562
dcefbbbd 10563 case DT_FEATURE:
252b5132
RH
10564 if (do_dynamic)
10565 {
10566 printf (_("Flags:"));
86f55779 10567
252b5132
RH
10568 if (entry->d_un.d_val == 0)
10569 printf (_(" None\n"));
10570 else
10571 {
10572 unsigned long int val = entry->d_un.d_val;
86f55779 10573
252b5132
RH
10574 if (val & DTF_1_PARINIT)
10575 {
10576 printf (" PARINIT");
10577 val ^= DTF_1_PARINIT;
10578 }
dcefbbbd
L
10579 if (val & DTF_1_CONFEXP)
10580 {
10581 printf (" CONFEXP");
10582 val ^= DTF_1_CONFEXP;
10583 }
252b5132
RH
10584 if (val != 0)
10585 printf (" %lx", val);
10586 puts ("");
10587 }
10588 }
10589 break;
10590
10591 case DT_POSFLAG_1:
10592 if (do_dynamic)
10593 {
10594 printf (_("Flags:"));
86f55779 10595
252b5132
RH
10596 if (entry->d_un.d_val == 0)
10597 printf (_(" None\n"));
10598 else
10599 {
10600 unsigned long int val = entry->d_un.d_val;
86f55779 10601
252b5132
RH
10602 if (val & DF_P1_LAZYLOAD)
10603 {
10604 printf (" LAZYLOAD");
10605 val ^= DF_P1_LAZYLOAD;
10606 }
10607 if (val & DF_P1_GROUPPERM)
10608 {
10609 printf (" GROUPPERM");
10610 val ^= DF_P1_GROUPPERM;
10611 }
10612 if (val != 0)
10613 printf (" %lx", val);
10614 puts ("");
10615 }
10616 }
10617 break;
10618
10619 case DT_FLAGS_1:
10620 if (do_dynamic)
10621 {
10622 printf (_("Flags:"));
10623 if (entry->d_un.d_val == 0)
10624 printf (_(" None\n"));
10625 else
10626 {
10627 unsigned long int val = entry->d_un.d_val;
86f55779 10628
252b5132
RH
10629 if (val & DF_1_NOW)
10630 {
10631 printf (" NOW");
10632 val ^= DF_1_NOW;
10633 }
10634 if (val & DF_1_GLOBAL)
10635 {
10636 printf (" GLOBAL");
10637 val ^= DF_1_GLOBAL;
10638 }
10639 if (val & DF_1_GROUP)
10640 {
10641 printf (" GROUP");
10642 val ^= DF_1_GROUP;
10643 }
10644 if (val & DF_1_NODELETE)
10645 {
10646 printf (" NODELETE");
10647 val ^= DF_1_NODELETE;
10648 }
10649 if (val & DF_1_LOADFLTR)
10650 {
10651 printf (" LOADFLTR");
10652 val ^= DF_1_LOADFLTR;
10653 }
10654 if (val & DF_1_INITFIRST)
10655 {
10656 printf (" INITFIRST");
10657 val ^= DF_1_INITFIRST;
10658 }
10659 if (val & DF_1_NOOPEN)
10660 {
10661 printf (" NOOPEN");
10662 val ^= DF_1_NOOPEN;
10663 }
10664 if (val & DF_1_ORIGIN)
10665 {
10666 printf (" ORIGIN");
10667 val ^= DF_1_ORIGIN;
10668 }
10669 if (val & DF_1_DIRECT)
10670 {
10671 printf (" DIRECT");
10672 val ^= DF_1_DIRECT;
10673 }
10674 if (val & DF_1_TRANS)
10675 {
10676 printf (" TRANS");
10677 val ^= DF_1_TRANS;
10678 }
10679 if (val & DF_1_INTERPOSE)
10680 {
10681 printf (" INTERPOSE");
10682 val ^= DF_1_INTERPOSE;
10683 }
f7db6139 10684 if (val & DF_1_NODEFLIB)
dcefbbbd 10685 {
f7db6139
L
10686 printf (" NODEFLIB");
10687 val ^= DF_1_NODEFLIB;
dcefbbbd
L
10688 }
10689 if (val & DF_1_NODUMP)
10690 {
10691 printf (" NODUMP");
10692 val ^= DF_1_NODUMP;
10693 }
34b60028 10694 if (val & DF_1_CONFALT)
dcefbbbd 10695 {
34b60028
L
10696 printf (" CONFALT");
10697 val ^= DF_1_CONFALT;
10698 }
10699 if (val & DF_1_ENDFILTEE)
10700 {
10701 printf (" ENDFILTEE");
10702 val ^= DF_1_ENDFILTEE;
10703 }
10704 if (val & DF_1_DISPRELDNE)
10705 {
10706 printf (" DISPRELDNE");
10707 val ^= DF_1_DISPRELDNE;
10708 }
10709 if (val & DF_1_DISPRELPND)
10710 {
10711 printf (" DISPRELPND");
10712 val ^= DF_1_DISPRELPND;
10713 }
10714 if (val & DF_1_NODIRECT)
10715 {
10716 printf (" NODIRECT");
10717 val ^= DF_1_NODIRECT;
10718 }
10719 if (val & DF_1_IGNMULDEF)
10720 {
10721 printf (" IGNMULDEF");
10722 val ^= DF_1_IGNMULDEF;
10723 }
10724 if (val & DF_1_NOKSYMS)
10725 {
10726 printf (" NOKSYMS");
10727 val ^= DF_1_NOKSYMS;
10728 }
10729 if (val & DF_1_NOHDR)
10730 {
10731 printf (" NOHDR");
10732 val ^= DF_1_NOHDR;
10733 }
10734 if (val & DF_1_EDITED)
10735 {
10736 printf (" EDITED");
10737 val ^= DF_1_EDITED;
10738 }
10739 if (val & DF_1_NORELOC)
10740 {
10741 printf (" NORELOC");
10742 val ^= DF_1_NORELOC;
10743 }
10744 if (val & DF_1_SYMINTPOSE)
10745 {
10746 printf (" SYMINTPOSE");
10747 val ^= DF_1_SYMINTPOSE;
10748 }
10749 if (val & DF_1_GLOBAUDIT)
10750 {
10751 printf (" GLOBAUDIT");
10752 val ^= DF_1_GLOBAUDIT;
10753 }
10754 if (val & DF_1_SINGLETON)
10755 {
10756 printf (" SINGLETON");
10757 val ^= DF_1_SINGLETON;
dcefbbbd 10758 }
5c383f02
RO
10759 if (val & DF_1_STUB)
10760 {
10761 printf (" STUB");
10762 val ^= DF_1_STUB;
10763 }
10764 if (val & DF_1_PIE)
10765 {
10766 printf (" PIE");
10767 val ^= DF_1_PIE;
10768 }
b1202ffa
L
10769 if (val & DF_1_KMOD)
10770 {
10771 printf (" KMOD");
10772 val ^= DF_1_KMOD;
10773 }
10774 if (val & DF_1_WEAKFILTER)
10775 {
10776 printf (" WEAKFILTER");
10777 val ^= DF_1_WEAKFILTER;
10778 }
10779 if (val & DF_1_NOCOMMON)
10780 {
10781 printf (" NOCOMMON");
10782 val ^= DF_1_NOCOMMON;
10783 }
252b5132
RH
10784 if (val != 0)
10785 printf (" %lx", val);
10786 puts ("");
10787 }
10788 }
10789 break;
10790
10791 case DT_PLTREL:
978c4450 10792 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 10793 if (do_dynamic)
dda8d76d 10794 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
10795 break;
10796
10797 case DT_NULL :
10798 case DT_NEEDED :
10799 case DT_PLTGOT :
10800 case DT_HASH :
10801 case DT_STRTAB :
10802 case DT_SYMTAB :
10803 case DT_RELA :
10804 case DT_INIT :
10805 case DT_FINI :
10806 case DT_SONAME :
10807 case DT_RPATH :
10808 case DT_SYMBOLIC:
10809 case DT_REL :
10810 case DT_DEBUG :
10811 case DT_TEXTREL :
10812 case DT_JMPREL :
019148e4 10813 case DT_RUNPATH :
978c4450 10814 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
10815
10816 if (do_dynamic)
10817 {
2cf0635d 10818 char * name;
252b5132 10819
978c4450
AM
10820 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10821 name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 10822 else
d79b3d50 10823 name = NULL;
252b5132
RH
10824
10825 if (name)
10826 {
10827 switch (entry->d_tag)
10828 {
10829 case DT_NEEDED:
10830 printf (_("Shared library: [%s]"), name);
10831
978c4450 10832 if (streq (name, filedata->program_interpreter))
f7a99963 10833 printf (_(" program interpreter"));
252b5132
RH
10834 break;
10835
10836 case DT_SONAME:
f7a99963 10837 printf (_("Library soname: [%s]"), name);
252b5132
RH
10838 break;
10839
10840 case DT_RPATH:
f7a99963 10841 printf (_("Library rpath: [%s]"), name);
252b5132
RH
10842 break;
10843
019148e4
L
10844 case DT_RUNPATH:
10845 printf (_("Library runpath: [%s]"), name);
10846 break;
10847
252b5132 10848 default:
f7a99963
NC
10849 print_vma (entry->d_un.d_val, PREFIX_HEX);
10850 break;
252b5132
RH
10851 }
10852 }
10853 else
f7a99963
NC
10854 print_vma (entry->d_un.d_val, PREFIX_HEX);
10855
10856 putchar ('\n');
252b5132
RH
10857 }
10858 break;
10859
10860 case DT_PLTRELSZ:
10861 case DT_RELASZ :
10862 case DT_STRSZ :
10863 case DT_RELSZ :
10864 case DT_RELAENT :
10865 case DT_SYMENT :
10866 case DT_RELENT :
978c4450 10867 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 10868 /* Fall through. */
252b5132
RH
10869 case DT_PLTPADSZ:
10870 case DT_MOVEENT :
10871 case DT_MOVESZ :
10872 case DT_INIT_ARRAYSZ:
10873 case DT_FINI_ARRAYSZ:
047b2264
JJ
10874 case DT_GNU_CONFLICTSZ:
10875 case DT_GNU_LIBLISTSZ:
252b5132 10876 if (do_dynamic)
f7a99963
NC
10877 {
10878 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 10879 printf (_(" (bytes)\n"));
f7a99963 10880 }
252b5132
RH
10881 break;
10882
10883 case DT_VERDEFNUM:
10884 case DT_VERNEEDNUM:
10885 case DT_RELACOUNT:
10886 case DT_RELCOUNT:
10887 if (do_dynamic)
f7a99963
NC
10888 {
10889 print_vma (entry->d_un.d_val, UNSIGNED);
10890 putchar ('\n');
10891 }
252b5132
RH
10892 break;
10893
10894 case DT_SYMINSZ:
10895 case DT_SYMINENT:
10896 case DT_SYMINFO:
10897 case DT_USED:
10898 case DT_INIT_ARRAY:
10899 case DT_FINI_ARRAY:
10900 if (do_dynamic)
10901 {
d79b3d50 10902 if (entry->d_tag == DT_USED
978c4450 10903 && VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
252b5132 10904 {
978c4450 10905 char * name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 10906
b34976b6 10907 if (*name)
252b5132
RH
10908 {
10909 printf (_("Not needed object: [%s]\n"), name);
10910 break;
10911 }
10912 }
103f02d3 10913
f7a99963
NC
10914 print_vma (entry->d_un.d_val, PREFIX_HEX);
10915 putchar ('\n');
252b5132
RH
10916 }
10917 break;
10918
10919 case DT_BIND_NOW:
10920 /* The value of this entry is ignored. */
35b1837e
AM
10921 if (do_dynamic)
10922 putchar ('\n');
252b5132 10923 break;
103f02d3 10924
047b2264
JJ
10925 case DT_GNU_PRELINKED:
10926 if (do_dynamic)
10927 {
2cf0635d 10928 struct tm * tmp;
91d6fa6a 10929 time_t atime = entry->d_un.d_val;
047b2264 10930
91d6fa6a 10931 tmp = gmtime (&atime);
071436c6
NC
10932 /* PR 17533 file: 041-1244816-0.004. */
10933 if (tmp == NULL)
5a2cbcf4
L
10934 printf (_("<corrupt time val: %lx"),
10935 (unsigned long) atime);
071436c6
NC
10936 else
10937 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
10938 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10939 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
10940
10941 }
10942 break;
10943
fdc90cb4 10944 case DT_GNU_HASH:
978c4450 10945 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
10946 if (do_dynamic)
10947 {
10948 print_vma (entry->d_un.d_val, PREFIX_HEX);
10949 putchar ('\n');
10950 }
10951 break;
10952
252b5132
RH
10953 default:
10954 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
10955 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
10956 = entry->d_un.d_val;
252b5132
RH
10957
10958 if (do_dynamic)
10959 {
dda8d76d 10960 switch (filedata->file_header.e_machine)
252b5132 10961 {
37c18eed
SD
10962 case EM_AARCH64:
10963 dynamic_section_aarch64_val (entry);
10964 break;
252b5132 10965 case EM_MIPS:
4fe85591 10966 case EM_MIPS_RS3_LE:
978c4450 10967 dynamic_section_mips_val (filedata, entry);
252b5132 10968 break;
103f02d3 10969 case EM_PARISC:
b2d38a17 10970 dynamic_section_parisc_val (entry);
103f02d3 10971 break;
ecc51f48 10972 case EM_IA_64:
b2d38a17 10973 dynamic_section_ia64_val (entry);
ecc51f48 10974 break;
252b5132 10975 default:
f7a99963
NC
10976 print_vma (entry->d_un.d_val, PREFIX_HEX);
10977 putchar ('\n');
252b5132
RH
10978 }
10979 }
10980 break;
10981 }
10982 }
10983
32ec8896 10984 return TRUE;
252b5132
RH
10985}
10986
10987static char *
d3ba0551 10988get_ver_flags (unsigned int flags)
252b5132 10989{
6d4f21f6 10990 static char buff[128];
252b5132
RH
10991
10992 buff[0] = 0;
10993
10994 if (flags == 0)
10995 return _("none");
10996
10997 if (flags & VER_FLG_BASE)
7bb1ad17 10998 strcat (buff, "BASE");
252b5132
RH
10999
11000 if (flags & VER_FLG_WEAK)
11001 {
11002 if (flags & VER_FLG_BASE)
7bb1ad17 11003 strcat (buff, " | ");
252b5132 11004
7bb1ad17 11005 strcat (buff, "WEAK");
252b5132
RH
11006 }
11007
44ec90b9
RO
11008 if (flags & VER_FLG_INFO)
11009 {
11010 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11011 strcat (buff, " | ");
44ec90b9 11012
7bb1ad17 11013 strcat (buff, "INFO");
44ec90b9
RO
11014 }
11015
11016 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11017 {
11018 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11019 strcat (buff, " | ");
11020
11021 strcat (buff, _("<unknown>"));
11022 }
252b5132
RH
11023
11024 return buff;
11025}
11026
11027/* Display the contents of the version sections. */
98fb390a 11028
32ec8896 11029static bfd_boolean
dda8d76d 11030process_version_sections (Filedata * filedata)
252b5132 11031{
2cf0635d 11032 Elf_Internal_Shdr * section;
b34976b6 11033 unsigned i;
32ec8896 11034 bfd_boolean found = FALSE;
252b5132
RH
11035
11036 if (! do_version)
32ec8896 11037 return TRUE;
252b5132 11038
dda8d76d
NC
11039 for (i = 0, section = filedata->section_headers;
11040 i < filedata->file_header.e_shnum;
b34976b6 11041 i++, section++)
252b5132
RH
11042 {
11043 switch (section->sh_type)
11044 {
11045 case SHT_GNU_verdef:
11046 {
2cf0635d 11047 Elf_External_Verdef * edefs;
452bf675
AM
11048 unsigned long idx;
11049 unsigned long cnt;
2cf0635d 11050 char * endbuf;
252b5132 11051
32ec8896 11052 found = TRUE;
252b5132 11053
d3a49aa8
AM
11054 printf (ngettext ("\nVersion definition section '%s' "
11055 "contains %u entry:\n",
11056 "\nVersion definition section '%s' "
11057 "contains %u entries:\n",
11058 section->sh_info),
dda8d76d 11059 printable_section_name (filedata, section),
74e1a04b 11060 section->sh_info);
252b5132 11061
ae9ac79e 11062 printf (_(" Addr: 0x"));
252b5132 11063 printf_vma (section->sh_addr);
233f82cf 11064 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11065 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11066 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11067
3f5e193b 11068 edefs = (Elf_External_Verdef *)
dda8d76d 11069 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11070 _("version definition section"));
a6e9f9df
AM
11071 if (!edefs)
11072 break;
59245841 11073 endbuf = (char *) edefs + section->sh_size;
252b5132 11074
1445030f 11075 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11076 {
2cf0635d
NC
11077 char * vstart;
11078 Elf_External_Verdef * edef;
b34976b6 11079 Elf_Internal_Verdef ent;
2cf0635d 11080 Elf_External_Verdaux * eaux;
b34976b6 11081 Elf_Internal_Verdaux aux;
452bf675 11082 unsigned long isum;
b34976b6 11083 int j;
103f02d3 11084
252b5132 11085 vstart = ((char *) edefs) + idx;
54806181
AM
11086 if (vstart + sizeof (*edef) > endbuf)
11087 break;
252b5132
RH
11088
11089 edef = (Elf_External_Verdef *) vstart;
11090
11091 ent.vd_version = BYTE_GET (edef->vd_version);
11092 ent.vd_flags = BYTE_GET (edef->vd_flags);
11093 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11094 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11095 ent.vd_hash = BYTE_GET (edef->vd_hash);
11096 ent.vd_aux = BYTE_GET (edef->vd_aux);
11097 ent.vd_next = BYTE_GET (edef->vd_next);
11098
452bf675 11099 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11100 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11101
11102 printf (_(" Index: %d Cnt: %d "),
11103 ent.vd_ndx, ent.vd_cnt);
11104
452bf675 11105 /* Check for overflow. */
1445030f 11106 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11107 break;
11108
252b5132
RH
11109 vstart += ent.vd_aux;
11110
1445030f
AM
11111 if (vstart + sizeof (*eaux) > endbuf)
11112 break;
252b5132
RH
11113 eaux = (Elf_External_Verdaux *) vstart;
11114
11115 aux.vda_name = BYTE_GET (eaux->vda_name);
11116 aux.vda_next = BYTE_GET (eaux->vda_next);
11117
978c4450
AM
11118 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
11119 printf (_("Name: %s\n"),
11120 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132
RH
11121 else
11122 printf (_("Name index: %ld\n"), aux.vda_name);
11123
11124 isum = idx + ent.vd_aux;
11125
b34976b6 11126 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11127 {
1445030f
AM
11128 if (aux.vda_next < sizeof (*eaux)
11129 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11130 {
11131 warn (_("Invalid vda_next field of %lx\n"),
11132 aux.vda_next);
11133 j = ent.vd_cnt;
11134 break;
11135 }
dd24e3da 11136 /* Check for overflow. */
7e26601c 11137 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11138 break;
11139
252b5132
RH
11140 isum += aux.vda_next;
11141 vstart += aux.vda_next;
11142
54806181
AM
11143 if (vstart + sizeof (*eaux) > endbuf)
11144 break;
1445030f 11145 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11146
11147 aux.vda_name = BYTE_GET (eaux->vda_name);
11148 aux.vda_next = BYTE_GET (eaux->vda_next);
11149
978c4450 11150 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
452bf675 11151 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450
AM
11152 isum, j,
11153 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132 11154 else
452bf675 11155 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11156 isum, j, aux.vda_name);
11157 }
dd24e3da 11158
54806181
AM
11159 if (j < ent.vd_cnt)
11160 printf (_(" Version def aux past end of section\n"));
252b5132 11161
c9f02c3e
MR
11162 /* PR 17531:
11163 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11164 if (ent.vd_next < sizeof (*edef)
11165 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11166 {
11167 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11168 cnt = section->sh_info;
11169 break;
11170 }
452bf675 11171 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11172 break;
11173
252b5132
RH
11174 idx += ent.vd_next;
11175 }
dd24e3da 11176
54806181
AM
11177 if (cnt < section->sh_info)
11178 printf (_(" Version definition past end of section\n"));
252b5132
RH
11179
11180 free (edefs);
11181 }
11182 break;
103f02d3 11183
252b5132
RH
11184 case SHT_GNU_verneed:
11185 {
2cf0635d 11186 Elf_External_Verneed * eneed;
452bf675
AM
11187 unsigned long idx;
11188 unsigned long cnt;
2cf0635d 11189 char * endbuf;
252b5132 11190
32ec8896 11191 found = TRUE;
252b5132 11192
d3a49aa8
AM
11193 printf (ngettext ("\nVersion needs section '%s' "
11194 "contains %u entry:\n",
11195 "\nVersion needs section '%s' "
11196 "contains %u entries:\n",
11197 section->sh_info),
dda8d76d 11198 printable_section_name (filedata, section), section->sh_info);
252b5132
RH
11199
11200 printf (_(" Addr: 0x"));
11201 printf_vma (section->sh_addr);
72de5009 11202 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11203 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11204 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11205
dda8d76d 11206 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11207 section->sh_offset, 1,
11208 section->sh_size,
9cf03b7e 11209 _("Version Needs section"));
a6e9f9df
AM
11210 if (!eneed)
11211 break;
59245841 11212 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11213
11214 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11215 {
2cf0635d 11216 Elf_External_Verneed * entry;
b34976b6 11217 Elf_Internal_Verneed ent;
452bf675 11218 unsigned long isum;
b34976b6 11219 int j;
2cf0635d 11220 char * vstart;
252b5132
RH
11221
11222 vstart = ((char *) eneed) + idx;
54806181
AM
11223 if (vstart + sizeof (*entry) > endbuf)
11224 break;
252b5132
RH
11225
11226 entry = (Elf_External_Verneed *) vstart;
11227
11228 ent.vn_version = BYTE_GET (entry->vn_version);
11229 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11230 ent.vn_file = BYTE_GET (entry->vn_file);
11231 ent.vn_aux = BYTE_GET (entry->vn_aux);
11232 ent.vn_next = BYTE_GET (entry->vn_next);
11233
452bf675 11234 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11235
978c4450
AM
11236 if (VALID_DYNAMIC_NAME (filedata, ent.vn_file))
11237 printf (_(" File: %s"),
11238 GET_DYNAMIC_NAME (filedata, ent.vn_file));
252b5132
RH
11239 else
11240 printf (_(" File: %lx"), ent.vn_file);
11241
11242 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11243
dd24e3da 11244 /* Check for overflow. */
7e26601c 11245 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11246 break;
252b5132
RH
11247 vstart += ent.vn_aux;
11248
11249 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11250 {
2cf0635d 11251 Elf_External_Vernaux * eaux;
b34976b6 11252 Elf_Internal_Vernaux aux;
252b5132 11253
54806181
AM
11254 if (vstart + sizeof (*eaux) > endbuf)
11255 break;
252b5132
RH
11256 eaux = (Elf_External_Vernaux *) vstart;
11257
11258 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11259 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11260 aux.vna_other = BYTE_GET (eaux->vna_other);
11261 aux.vna_name = BYTE_GET (eaux->vna_name);
11262 aux.vna_next = BYTE_GET (eaux->vna_next);
11263
978c4450 11264 if (VALID_DYNAMIC_NAME (filedata, aux.vna_name))
452bf675 11265 printf (_(" %#06lx: Name: %s"),
978c4450 11266 isum, GET_DYNAMIC_NAME (filedata, aux.vna_name));
252b5132 11267 else
452bf675 11268 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11269 isum, aux.vna_name);
11270
11271 printf (_(" Flags: %s Version: %d\n"),
11272 get_ver_flags (aux.vna_flags), aux.vna_other);
11273
1445030f
AM
11274 if (aux.vna_next < sizeof (*eaux)
11275 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11276 {
11277 warn (_("Invalid vna_next field of %lx\n"),
11278 aux.vna_next);
11279 j = ent.vn_cnt;
11280 break;
11281 }
1445030f
AM
11282 /* Check for overflow. */
11283 if (aux.vna_next > (size_t) (endbuf - vstart))
11284 break;
252b5132
RH
11285 isum += aux.vna_next;
11286 vstart += aux.vna_next;
11287 }
9cf03b7e 11288
54806181 11289 if (j < ent.vn_cnt)
9cf03b7e 11290 warn (_("Missing Version Needs auxillary information\n"));
252b5132 11291
1445030f
AM
11292 if (ent.vn_next < sizeof (*entry)
11293 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11294 {
452bf675 11295 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11296 cnt = section->sh_info;
11297 break;
11298 }
1445030f
AM
11299 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11300 break;
252b5132
RH
11301 idx += ent.vn_next;
11302 }
9cf03b7e 11303
54806181 11304 if (cnt < section->sh_info)
9cf03b7e 11305 warn (_("Missing Version Needs information\n"));
103f02d3 11306
252b5132
RH
11307 free (eneed);
11308 }
11309 break;
11310
11311 case SHT_GNU_versym:
11312 {
2cf0635d 11313 Elf_Internal_Shdr * link_section;
8b73c356
NC
11314 size_t total;
11315 unsigned int cnt;
2cf0635d
NC
11316 unsigned char * edata;
11317 unsigned short * data;
11318 char * strtab;
11319 Elf_Internal_Sym * symbols;
11320 Elf_Internal_Shdr * string_sec;
ba5cdace 11321 unsigned long num_syms;
d3ba0551 11322 long off;
252b5132 11323
dda8d76d 11324 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11325 break;
11326
dda8d76d 11327 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11328 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11329
dda8d76d 11330 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11331 break;
11332
32ec8896 11333 found = TRUE;
252b5132 11334
dda8d76d 11335 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
11336 if (symbols == NULL)
11337 break;
252b5132 11338
dda8d76d 11339 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11340
dda8d76d 11341 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11342 string_sec->sh_size,
11343 _("version string table"));
a6e9f9df 11344 if (!strtab)
0429c154
MS
11345 {
11346 free (symbols);
11347 break;
11348 }
252b5132 11349
d3a49aa8
AM
11350 printf (ngettext ("\nVersion symbols section '%s' "
11351 "contains %lu entry:\n",
11352 "\nVersion symbols section '%s' "
11353 "contains %lu entries:\n",
11354 total),
dda8d76d 11355 printable_section_name (filedata, section), (unsigned long) total);
252b5132 11356
ae9ac79e 11357 printf (_(" Addr: 0x"));
252b5132 11358 printf_vma (section->sh_addr);
72de5009 11359 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11360 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11361 printable_section_name (filedata, link_section));
252b5132 11362
dda8d76d 11363 off = offset_from_vma (filedata,
978c4450 11364 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11365 total * sizeof (short));
95099889
AM
11366 edata = (unsigned char *) get_data (NULL, filedata, off,
11367 sizeof (short), total,
11368 _("version symbol data"));
a6e9f9df
AM
11369 if (!edata)
11370 {
11371 free (strtab);
0429c154 11372 free (symbols);
a6e9f9df
AM
11373 break;
11374 }
252b5132 11375
3f5e193b 11376 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11377
11378 for (cnt = total; cnt --;)
b34976b6
AM
11379 data[cnt] = byte_get (edata + cnt * sizeof (short),
11380 sizeof (short));
252b5132
RH
11381
11382 free (edata);
11383
11384 for (cnt = 0; cnt < total; cnt += 4)
11385 {
11386 int j, nn;
ab273396
AM
11387 char *name;
11388 char *invalid = _("*invalid*");
252b5132
RH
11389
11390 printf (" %03x:", cnt);
11391
11392 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11393 switch (data[cnt + j])
252b5132
RH
11394 {
11395 case 0:
11396 fputs (_(" 0 (*local*) "), stdout);
11397 break;
11398
11399 case 1:
11400 fputs (_(" 1 (*global*) "), stdout);
11401 break;
11402
11403 default:
c244d050
NC
11404 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11405 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11406
dd24e3da 11407 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11408 array, break to avoid an out-of-bounds read. */
11409 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11410 {
11411 warn (_("invalid index into symbol array\n"));
11412 break;
11413 }
11414
ab273396 11415 name = NULL;
978c4450 11416 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11417 {
b34976b6
AM
11418 Elf_Internal_Verneed ivn;
11419 unsigned long offset;
252b5132 11420
d93f0186 11421 offset = offset_from_vma
978c4450
AM
11422 (filedata,
11423 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11424 sizeof (Elf_External_Verneed));
252b5132 11425
b34976b6 11426 do
252b5132 11427 {
b34976b6
AM
11428 Elf_Internal_Vernaux ivna;
11429 Elf_External_Verneed evn;
11430 Elf_External_Vernaux evna;
11431 unsigned long a_off;
252b5132 11432
dda8d76d 11433 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11434 _("version need")) == NULL)
11435 break;
0b4362b0 11436
252b5132
RH
11437 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11438 ivn.vn_next = BYTE_GET (evn.vn_next);
11439
11440 a_off = offset + ivn.vn_aux;
11441
11442 do
11443 {
dda8d76d 11444 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11445 1, _("version need aux (2)")) == NULL)
11446 {
11447 ivna.vna_next = 0;
11448 ivna.vna_other = 0;
11449 }
11450 else
11451 {
11452 ivna.vna_next = BYTE_GET (evna.vna_next);
11453 ivna.vna_other = BYTE_GET (evna.vna_other);
11454 }
252b5132
RH
11455
11456 a_off += ivna.vna_next;
11457 }
b34976b6 11458 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11459 && ivna.vna_next != 0);
11460
b34976b6 11461 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11462 {
11463 ivna.vna_name = BYTE_GET (evna.vna_name);
11464
54806181 11465 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11466 name = invalid;
54806181
AM
11467 else
11468 name = strtab + ivna.vna_name;
252b5132
RH
11469 break;
11470 }
11471
11472 offset += ivn.vn_next;
11473 }
11474 while (ivn.vn_next);
11475 }
00d93f34 11476
ab273396 11477 if (data[cnt + j] != 0x8001
978c4450 11478 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 11479 {
b34976b6
AM
11480 Elf_Internal_Verdef ivd;
11481 Elf_External_Verdef evd;
11482 unsigned long offset;
252b5132 11483
d93f0186 11484 offset = offset_from_vma
978c4450
AM
11485 (filedata,
11486 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 11487 sizeof evd);
252b5132
RH
11488
11489 do
11490 {
dda8d76d 11491 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
11492 _("version def")) == NULL)
11493 {
11494 ivd.vd_next = 0;
948f632f 11495 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
11496 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
11497 break;
59245841
NC
11498 }
11499 else
11500 {
11501 ivd.vd_next = BYTE_GET (evd.vd_next);
11502 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11503 }
252b5132
RH
11504
11505 offset += ivd.vd_next;
11506 }
c244d050 11507 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
11508 && ivd.vd_next != 0);
11509
c244d050 11510 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 11511 {
b34976b6
AM
11512 Elf_External_Verdaux evda;
11513 Elf_Internal_Verdaux ivda;
252b5132
RH
11514
11515 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11516
dda8d76d 11517 if (get_data (&evda, filedata,
59245841
NC
11518 offset - ivd.vd_next + ivd.vd_aux,
11519 sizeof (evda), 1,
11520 _("version def aux")) == NULL)
11521 break;
252b5132
RH
11522
11523 ivda.vda_name = BYTE_GET (evda.vda_name);
11524
54806181 11525 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
11526 name = invalid;
11527 else if (name != NULL && name != invalid)
11528 name = _("*both*");
54806181
AM
11529 else
11530 name = strtab + ivda.vda_name;
252b5132
RH
11531 }
11532 }
ab273396
AM
11533 if (name != NULL)
11534 nn += printf ("(%s%-*s",
11535 name,
11536 12 - (int) strlen (name),
11537 ")");
252b5132
RH
11538
11539 if (nn < 18)
11540 printf ("%*c", 18 - nn, ' ');
11541 }
11542
11543 putchar ('\n');
11544 }
11545
11546 free (data);
11547 free (strtab);
11548 free (symbols);
11549 }
11550 break;
103f02d3 11551
252b5132
RH
11552 default:
11553 break;
11554 }
11555 }
11556
11557 if (! found)
11558 printf (_("\nNo version information found in this file.\n"));
11559
32ec8896 11560 return TRUE;
252b5132
RH
11561}
11562
d1133906 11563static const char *
dda8d76d 11564get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 11565{
89246a0e 11566 static char buff[64];
252b5132
RH
11567
11568 switch (binding)
11569 {
b34976b6
AM
11570 case STB_LOCAL: return "LOCAL";
11571 case STB_GLOBAL: return "GLOBAL";
11572 case STB_WEAK: return "WEAK";
252b5132
RH
11573 default:
11574 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
11575 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
11576 binding);
252b5132 11577 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
11578 {
11579 if (binding == STB_GNU_UNIQUE
df3a023b 11580 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
11581 return "UNIQUE";
11582 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
11583 }
252b5132 11584 else
e9e44622 11585 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
11586 return buff;
11587 }
11588}
11589
d1133906 11590static const char *
dda8d76d 11591get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 11592{
89246a0e 11593 static char buff[64];
252b5132
RH
11594
11595 switch (type)
11596 {
b34976b6
AM
11597 case STT_NOTYPE: return "NOTYPE";
11598 case STT_OBJECT: return "OBJECT";
11599 case STT_FUNC: return "FUNC";
11600 case STT_SECTION: return "SECTION";
11601 case STT_FILE: return "FILE";
11602 case STT_COMMON: return "COMMON";
11603 case STT_TLS: return "TLS";
15ab5209
DB
11604 case STT_RELC: return "RELC";
11605 case STT_SRELC: return "SRELC";
252b5132
RH
11606 default:
11607 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 11608 {
dda8d76d 11609 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 11610 return "THUMB_FUNC";
103f02d3 11611
dda8d76d 11612 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
11613 return "REGISTER";
11614
dda8d76d 11615 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
11616 return "PARISC_MILLI";
11617
e9e44622 11618 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 11619 }
252b5132 11620 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 11621 {
dda8d76d 11622 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
11623 {
11624 if (type == STT_HP_OPAQUE)
11625 return "HP_OPAQUE";
11626 if (type == STT_HP_STUB)
11627 return "HP_STUB";
11628 }
11629
d8045f23 11630 if (type == STT_GNU_IFUNC
dda8d76d 11631 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 11632 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
11633 return "IFUNC";
11634
e9e44622 11635 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 11636 }
252b5132 11637 else
e9e44622 11638 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
11639 return buff;
11640 }
11641}
11642
d1133906 11643static const char *
d3ba0551 11644get_symbol_visibility (unsigned int visibility)
d1133906
NC
11645{
11646 switch (visibility)
11647 {
b34976b6
AM
11648 case STV_DEFAULT: return "DEFAULT";
11649 case STV_INTERNAL: return "INTERNAL";
11650 case STV_HIDDEN: return "HIDDEN";
d1133906 11651 case STV_PROTECTED: return "PROTECTED";
bee0ee85 11652 default:
27a45f42 11653 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 11654 return _("<unknown>");
d1133906
NC
11655 }
11656}
11657
2057d69d
CZ
11658static const char *
11659get_alpha_symbol_other (unsigned int other)
9abca702 11660{
2057d69d
CZ
11661 switch (other)
11662 {
11663 case STO_ALPHA_NOPV: return "NOPV";
11664 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
11665 default:
27a45f42 11666 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 11667 return _("<unknown>");
9abca702 11668 }
2057d69d
CZ
11669}
11670
fd85a6a1
NC
11671static const char *
11672get_solaris_symbol_visibility (unsigned int visibility)
11673{
11674 switch (visibility)
11675 {
11676 case 4: return "EXPORTED";
11677 case 5: return "SINGLETON";
11678 case 6: return "ELIMINATE";
11679 default: return get_symbol_visibility (visibility);
11680 }
11681}
11682
2301ed1c
SN
11683static const char *
11684get_aarch64_symbol_other (unsigned int other)
11685{
11686 static char buf[32];
11687
11688 if (other & STO_AARCH64_VARIANT_PCS)
11689 {
11690 other &= ~STO_AARCH64_VARIANT_PCS;
11691 if (other == 0)
11692 return "VARIANT_PCS";
11693 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
11694 return buf;
11695 }
11696 return NULL;
11697}
11698
5e2b0d47
NC
11699static const char *
11700get_mips_symbol_other (unsigned int other)
11701{
11702 switch (other)
11703 {
32ec8896
NC
11704 case STO_OPTIONAL: return "OPTIONAL";
11705 case STO_MIPS_PLT: return "MIPS PLT";
11706 case STO_MIPS_PIC: return "MIPS PIC";
11707 case STO_MICROMIPS: return "MICROMIPS";
11708 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
11709 case STO_MIPS16: return "MIPS16";
11710 default: return NULL;
5e2b0d47
NC
11711 }
11712}
11713
28f997cf 11714static const char *
dda8d76d 11715get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 11716{
dda8d76d 11717 if (is_ia64_vms (filedata))
28f997cf
TG
11718 {
11719 static char res[32];
11720
11721 res[0] = 0;
11722
11723 /* Function types is for images and .STB files only. */
dda8d76d 11724 switch (filedata->file_header.e_type)
28f997cf
TG
11725 {
11726 case ET_DYN:
11727 case ET_EXEC:
11728 switch (VMS_ST_FUNC_TYPE (other))
11729 {
11730 case VMS_SFT_CODE_ADDR:
11731 strcat (res, " CA");
11732 break;
11733 case VMS_SFT_SYMV_IDX:
11734 strcat (res, " VEC");
11735 break;
11736 case VMS_SFT_FD:
11737 strcat (res, " FD");
11738 break;
11739 case VMS_SFT_RESERVE:
11740 strcat (res, " RSV");
11741 break;
11742 default:
bee0ee85
NC
11743 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
11744 VMS_ST_FUNC_TYPE (other));
11745 strcat (res, " <unknown>");
11746 break;
28f997cf
TG
11747 }
11748 break;
11749 default:
11750 break;
11751 }
11752 switch (VMS_ST_LINKAGE (other))
11753 {
11754 case VMS_STL_IGNORE:
11755 strcat (res, " IGN");
11756 break;
11757 case VMS_STL_RESERVE:
11758 strcat (res, " RSV");
11759 break;
11760 case VMS_STL_STD:
11761 strcat (res, " STD");
11762 break;
11763 case VMS_STL_LNK:
11764 strcat (res, " LNK");
11765 break;
11766 default:
bee0ee85
NC
11767 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
11768 VMS_ST_LINKAGE (other));
11769 strcat (res, " <unknown>");
11770 break;
28f997cf
TG
11771 }
11772
11773 if (res[0] != 0)
11774 return res + 1;
11775 else
11776 return res;
11777 }
11778 return NULL;
11779}
11780
6911b7dc
AM
11781static const char *
11782get_ppc64_symbol_other (unsigned int other)
11783{
14732552
AM
11784 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
11785 return NULL;
11786
11787 other >>= STO_PPC64_LOCAL_BIT;
11788 if (other <= 6)
6911b7dc 11789 {
89246a0e 11790 static char buf[64];
14732552
AM
11791 if (other >= 2)
11792 other = ppc64_decode_local_entry (other);
11793 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
11794 return buf;
11795 }
11796 return NULL;
11797}
11798
5e2b0d47 11799static const char *
dda8d76d 11800get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
11801{
11802 const char * result = NULL;
89246a0e 11803 static char buff [64];
5e2b0d47
NC
11804
11805 if (other == 0)
11806 return "";
11807
dda8d76d 11808 switch (filedata->file_header.e_machine)
5e2b0d47 11809 {
2057d69d
CZ
11810 case EM_ALPHA:
11811 result = get_alpha_symbol_other (other);
11812 break;
2301ed1c
SN
11813 case EM_AARCH64:
11814 result = get_aarch64_symbol_other (other);
11815 break;
5e2b0d47
NC
11816 case EM_MIPS:
11817 result = get_mips_symbol_other (other);
28f997cf
TG
11818 break;
11819 case EM_IA_64:
dda8d76d 11820 result = get_ia64_symbol_other (filedata, other);
28f997cf 11821 break;
6911b7dc
AM
11822 case EM_PPC64:
11823 result = get_ppc64_symbol_other (other);
11824 break;
5e2b0d47 11825 default:
fd85a6a1 11826 result = NULL;
5e2b0d47
NC
11827 break;
11828 }
11829
11830 if (result)
11831 return result;
11832
11833 snprintf (buff, sizeof buff, _("<other>: %x"), other);
11834 return buff;
11835}
11836
d1133906 11837static const char *
dda8d76d 11838get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 11839{
b34976b6 11840 static char buff[32];
5cf1065c 11841
252b5132
RH
11842 switch (type)
11843 {
b34976b6
AM
11844 case SHN_UNDEF: return "UND";
11845 case SHN_ABS: return "ABS";
11846 case SHN_COMMON: return "COM";
252b5132 11847 default:
9ce701e2 11848 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
11849 && filedata->file_header.e_machine == EM_IA_64
11850 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
11851 return "ANSI_COM";
11852 else if ((filedata->file_header.e_machine == EM_X86_64
11853 || filedata->file_header.e_machine == EM_L1OM
11854 || filedata->file_header.e_machine == EM_K1OM)
11855 && type == SHN_X86_64_LCOMMON)
11856 return "LARGE_COM";
11857 else if ((type == SHN_MIPS_SCOMMON
11858 && filedata->file_header.e_machine == EM_MIPS)
11859 || (type == SHN_TIC6X_SCOMMON
11860 && filedata->file_header.e_machine == EM_TI_C6000))
11861 return "SCOM";
11862 else if (type == SHN_MIPS_SUNDEFINED
11863 && filedata->file_header.e_machine == EM_MIPS)
11864 return "SUND";
11865 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
11866 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
11867 else if (type >= SHN_LOOS && type <= SHN_HIOS)
11868 sprintf (buff, "OS [0x%04x]", type & 0xffff);
11869 else if (type >= SHN_LORESERVE)
11870 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
11871 else if (filedata->file_header.e_shnum != 0
11872 && type >= filedata->file_header.e_shnum)
11873 sprintf (buff, _("bad section index[%3d]"), type);
11874 else
11875 sprintf (buff, "%3d", type);
11876 break;
fd85a6a1
NC
11877 }
11878
10ca4b04 11879 return buff;
6bd1a22c
L
11880}
11881
bb4d2ac2 11882static const char *
dda8d76d 11883get_symbol_version_string (Filedata * filedata,
1449284b
NC
11884 bfd_boolean is_dynsym,
11885 const char * strtab,
11886 unsigned long int strtab_size,
11887 unsigned int si,
11888 Elf_Internal_Sym * psym,
11889 enum versioned_symbol_info * sym_info,
11890 unsigned short * vna_other)
bb4d2ac2 11891{
ab273396
AM
11892 unsigned char data[2];
11893 unsigned short vers_data;
11894 unsigned long offset;
7a815dd5 11895 unsigned short max_vd_ndx;
bb4d2ac2 11896
ab273396 11897 if (!is_dynsym
978c4450 11898 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 11899 return NULL;
bb4d2ac2 11900
978c4450
AM
11901 offset = offset_from_vma (filedata,
11902 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 11903 sizeof data + si * sizeof (vers_data));
bb4d2ac2 11904
dda8d76d 11905 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
11906 sizeof (data), 1, _("version data")) == NULL)
11907 return NULL;
11908
11909 vers_data = byte_get (data, 2);
bb4d2ac2 11910
1f6f5dba 11911 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 11912 return NULL;
bb4d2ac2 11913
0b8b7609 11914 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
11915 max_vd_ndx = 0;
11916
ab273396
AM
11917 /* Usually we'd only see verdef for defined symbols, and verneed for
11918 undefined symbols. However, symbols defined by the linker in
11919 .dynbss for variables copied from a shared library in order to
11920 avoid text relocations are defined yet have verneed. We could
11921 use a heuristic to detect the special case, for example, check
11922 for verneed first on symbols defined in SHT_NOBITS sections, but
11923 it is simpler and more reliable to just look for both verdef and
11924 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 11925
ab273396
AM
11926 if (psym->st_shndx != SHN_UNDEF
11927 && vers_data != 0x8001
978c4450 11928 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
11929 {
11930 Elf_Internal_Verdef ivd;
11931 Elf_Internal_Verdaux ivda;
11932 Elf_External_Verdaux evda;
11933 unsigned long off;
bb4d2ac2 11934
dda8d76d 11935 off = offset_from_vma (filedata,
978c4450 11936 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
11937 sizeof (Elf_External_Verdef));
11938
11939 do
bb4d2ac2 11940 {
ab273396
AM
11941 Elf_External_Verdef evd;
11942
dda8d76d 11943 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
11944 _("version def")) == NULL)
11945 {
11946 ivd.vd_ndx = 0;
11947 ivd.vd_aux = 0;
11948 ivd.vd_next = 0;
1f6f5dba 11949 ivd.vd_flags = 0;
ab273396
AM
11950 }
11951 else
bb4d2ac2 11952 {
ab273396
AM
11953 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11954 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11955 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 11956 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 11957 }
bb4d2ac2 11958
7a815dd5
L
11959 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
11960 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
11961
ab273396
AM
11962 off += ivd.vd_next;
11963 }
11964 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 11965
ab273396
AM
11966 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
11967 {
9abca702 11968 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
11969 return NULL;
11970
ab273396
AM
11971 off -= ivd.vd_next;
11972 off += ivd.vd_aux;
bb4d2ac2 11973
dda8d76d 11974 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
11975 _("version def aux")) != NULL)
11976 {
11977 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 11978
ab273396 11979 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
11980 return (ivda.vda_name < strtab_size
11981 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
11982 }
11983 }
11984 }
bb4d2ac2 11985
978c4450 11986 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
11987 {
11988 Elf_External_Verneed evn;
11989 Elf_Internal_Verneed ivn;
11990 Elf_Internal_Vernaux ivna;
bb4d2ac2 11991
dda8d76d 11992 offset = offset_from_vma (filedata,
978c4450 11993 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
11994 sizeof evn);
11995 do
11996 {
11997 unsigned long vna_off;
bb4d2ac2 11998
dda8d76d 11999 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12000 _("version need")) == NULL)
12001 {
12002 ivna.vna_next = 0;
12003 ivna.vna_other = 0;
12004 ivna.vna_name = 0;
12005 break;
12006 }
bb4d2ac2 12007
ab273396
AM
12008 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12009 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12010
ab273396 12011 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12012
ab273396
AM
12013 do
12014 {
12015 Elf_External_Vernaux evna;
bb4d2ac2 12016
dda8d76d 12017 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12018 _("version need aux (3)")) == NULL)
bb4d2ac2 12019 {
ab273396
AM
12020 ivna.vna_next = 0;
12021 ivna.vna_other = 0;
12022 ivna.vna_name = 0;
bb4d2ac2 12023 }
bb4d2ac2 12024 else
bb4d2ac2 12025 {
ab273396
AM
12026 ivna.vna_other = BYTE_GET (evna.vna_other);
12027 ivna.vna_next = BYTE_GET (evna.vna_next);
12028 ivna.vna_name = BYTE_GET (evna.vna_name);
12029 }
bb4d2ac2 12030
ab273396
AM
12031 vna_off += ivna.vna_next;
12032 }
12033 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12034
ab273396
AM
12035 if (ivna.vna_other == vers_data)
12036 break;
bb4d2ac2 12037
ab273396
AM
12038 offset += ivn.vn_next;
12039 }
12040 while (ivn.vn_next != 0);
bb4d2ac2 12041
ab273396
AM
12042 if (ivna.vna_other == vers_data)
12043 {
12044 *sym_info = symbol_undefined;
12045 *vna_other = ivna.vna_other;
12046 return (ivna.vna_name < strtab_size
12047 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12048 }
7a815dd5
L
12049 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12050 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12051 return _("<corrupt>");
bb4d2ac2 12052 }
ab273396 12053 return NULL;
bb4d2ac2
L
12054}
12055
10ca4b04
L
12056static void
12057print_dynamic_symbol (Filedata *filedata, unsigned long si,
12058 Elf_Internal_Sym *symtab,
12059 Elf_Internal_Shdr *section,
12060 char *strtab, size_t strtab_size)
252b5132 12061{
10ca4b04
L
12062 const char *version_string;
12063 enum versioned_symbol_info sym_info;
12064 unsigned short vna_other;
12065 Elf_Internal_Sym *psym = symtab + si;
252b5132 12066
10ca4b04
L
12067 printf ("%6ld: ", si);
12068 print_vma (psym->st_value, LONG_HEX);
12069 putchar (' ');
12070 print_vma (psym->st_size, DEC_5);
12071 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12072 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12073 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12074 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12075 else
252b5132 12076 {
10ca4b04 12077 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12078
10ca4b04
L
12079 printf (" %-7s", get_symbol_visibility (vis));
12080 /* Check to see if any other bits in the st_other field are set.
12081 Note - displaying this information disrupts the layout of the
12082 table being generated, but for the moment this case is very rare. */
12083 if (psym->st_other ^ vis)
12084 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12085 }
10ca4b04
L
12086 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
12087 print_symbol (25, VALID_SYMBOL_NAME (strtab, strtab_size,
12088 psym->st_name)
12089 ? strtab + psym->st_name : _("<corrupt>"));
12090
12091 version_string
12092 = get_symbol_version_string (filedata,
12093 (section == NULL
12094 || section->sh_type == SHT_DYNSYM),
12095 strtab, strtab_size, si,
12096 psym, &sym_info, &vna_other);
12097 if (version_string)
12098 {
12099 if (sym_info == symbol_undefined)
12100 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12101 else
10ca4b04
L
12102 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12103 version_string);
12104 }
6bd1a22c 12105
10ca4b04 12106 putchar ('\n');
6bd1a22c 12107
10ca4b04
L
12108 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12109 && section != NULL
12110 && si >= section->sh_info
12111 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12112 && filedata->file_header.e_machine != EM_MIPS
12113 /* Solaris binaries have been found to violate this requirement as
12114 well. Not sure if this is a bug or an ABI requirement. */
12115 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12116 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12117 si, printable_section_name (filedata, section), section->sh_info);
12118}
f16a9783 12119
10ca4b04
L
12120/* Dump the symbol table. */
12121static bfd_boolean
12122process_symbol_table (Filedata * filedata)
12123{
12124 Elf_Internal_Shdr * section;
f16a9783 12125
10ca4b04
L
12126 if (!do_syms && !do_dyn_syms && !do_histogram)
12127 return TRUE;
6bd1a22c 12128
978c4450 12129 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
12130 && do_syms
12131 && do_using_dynamic
978c4450
AM
12132 && filedata->dynamic_strings != NULL
12133 && filedata->dynamic_symbols != NULL)
6bd1a22c 12134 {
10ca4b04 12135 unsigned long si;
6bd1a22c 12136
10ca4b04
L
12137 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12138 "\nSymbol table for image contains %lu entries:\n",
978c4450
AM
12139 filedata->num_dynamic_syms),
12140 filedata->num_dynamic_syms);
10ca4b04
L
12141 if (is_32bit_elf)
12142 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12143 else
12144 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12145
978c4450
AM
12146 for (si = 0; si < filedata->num_dynamic_syms; si++)
12147 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
12148 filedata->dynamic_strings,
12149 filedata->dynamic_strings_length);
252b5132 12150 }
8b73c356 12151 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 12152 && filedata->section_headers != NULL)
252b5132 12153 {
b34976b6 12154 unsigned int i;
252b5132 12155
dda8d76d
NC
12156 for (i = 0, section = filedata->section_headers;
12157 i < filedata->file_header.e_shnum;
252b5132
RH
12158 i++, section++)
12159 {
2cf0635d 12160 char * strtab = NULL;
c256ffe7 12161 unsigned long int strtab_size = 0;
2cf0635d 12162 Elf_Internal_Sym * symtab;
ef3df110 12163 unsigned long si, num_syms;
252b5132 12164
2c610e4b
L
12165 if ((section->sh_type != SHT_SYMTAB
12166 && section->sh_type != SHT_DYNSYM)
12167 || (!do_syms
12168 && section->sh_type == SHT_SYMTAB))
252b5132
RH
12169 continue;
12170
dd24e3da
NC
12171 if (section->sh_entsize == 0)
12172 {
12173 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 12174 printable_section_name (filedata, section));
dd24e3da
NC
12175 continue;
12176 }
12177
d3a49aa8
AM
12178 num_syms = section->sh_size / section->sh_entsize;
12179 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
12180 "\nSymbol table '%s' contains %lu entries:\n",
12181 num_syms),
dda8d76d 12182 printable_section_name (filedata, section),
d3a49aa8 12183 num_syms);
dd24e3da 12184
f7a99963 12185 if (is_32bit_elf)
ca47b30c 12186 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 12187 else
ca47b30c 12188 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 12189
dda8d76d 12190 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
12191 if (symtab == NULL)
12192 continue;
12193
dda8d76d 12194 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 12195 {
dda8d76d
NC
12196 strtab = filedata->string_table;
12197 strtab_size = filedata->string_table_length;
c256ffe7 12198 }
dda8d76d 12199 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 12200 {
2cf0635d 12201 Elf_Internal_Shdr * string_sec;
252b5132 12202
dda8d76d 12203 string_sec = filedata->section_headers + section->sh_link;
252b5132 12204
dda8d76d 12205 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
12206 1, string_sec->sh_size,
12207 _("string table"));
c256ffe7 12208 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
12209 }
12210
10ca4b04
L
12211 for (si = 0; si < num_syms; si++)
12212 print_dynamic_symbol (filedata, si, symtab, section,
12213 strtab, strtab_size);
252b5132
RH
12214
12215 free (symtab);
dda8d76d 12216 if (strtab != filedata->string_table)
252b5132
RH
12217 free (strtab);
12218 }
12219 }
12220 else if (do_syms)
12221 printf
12222 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
12223
978c4450 12224 if (do_histogram && filedata->buckets != NULL)
252b5132 12225 {
2cf0635d
NC
12226 unsigned long * lengths;
12227 unsigned long * counts;
66543521
AM
12228 unsigned long hn;
12229 bfd_vma si;
12230 unsigned long maxlength = 0;
12231 unsigned long nzero_counts = 0;
12232 unsigned long nsyms = 0;
6bd6a03d 12233 char *visited;
252b5132 12234
d3a49aa8
AM
12235 printf (ngettext ("\nHistogram for bucket list length "
12236 "(total of %lu bucket):\n",
12237 "\nHistogram for bucket list length "
12238 "(total of %lu buckets):\n",
978c4450
AM
12239 (unsigned long) filedata->nbuckets),
12240 (unsigned long) filedata->nbuckets);
252b5132 12241
978c4450
AM
12242 lengths = (unsigned long *) calloc (filedata->nbuckets,
12243 sizeof (*lengths));
252b5132
RH
12244 if (lengths == NULL)
12245 {
8b73c356 12246 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 12247 goto err_out;
252b5132 12248 }
978c4450
AM
12249 visited = xcmalloc (filedata->nchains, 1);
12250 memset (visited, 0, filedata->nchains);
8b73c356
NC
12251
12252 printf (_(" Length Number %% of total Coverage\n"));
978c4450 12253 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 12254 {
978c4450 12255 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 12256 {
b34976b6 12257 ++nsyms;
252b5132 12258 if (maxlength < ++lengths[hn])
b34976b6 12259 ++maxlength;
978c4450 12260 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
12261 {
12262 error (_("histogram chain is corrupt\n"));
12263 break;
12264 }
12265 visited[si] = 1;
252b5132
RH
12266 }
12267 }
6bd6a03d 12268 free (visited);
252b5132 12269
3f5e193b 12270 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
12271 if (counts == NULL)
12272 {
b2e951ec 12273 free (lengths);
8b73c356 12274 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 12275 goto err_out;
252b5132
RH
12276 }
12277
978c4450 12278 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 12279 ++counts[lengths[hn]];
252b5132 12280
978c4450 12281 if (filedata->nbuckets > 0)
252b5132 12282 {
66543521
AM
12283 unsigned long i;
12284 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12285 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 12286 for (i = 1; i <= maxlength; ++i)
103f02d3 12287 {
66543521
AM
12288 nzero_counts += counts[i] * i;
12289 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12290 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
12291 (nzero_counts * 100.0) / nsyms);
12292 }
252b5132
RH
12293 }
12294
12295 free (counts);
12296 free (lengths);
12297 }
12298
978c4450
AM
12299 free (filedata->buckets);
12300 filedata->buckets = NULL;
12301 filedata->nbuckets = 0;
12302 free (filedata->chains);
12303 filedata->chains = NULL;
252b5132 12304
978c4450 12305 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 12306 {
2cf0635d
NC
12307 unsigned long * lengths;
12308 unsigned long * counts;
fdc90cb4
JJ
12309 unsigned long hn;
12310 unsigned long maxlength = 0;
12311 unsigned long nzero_counts = 0;
12312 unsigned long nsyms = 0;
fdc90cb4 12313
f16a9783 12314 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 12315 "(total of %lu bucket):\n",
f16a9783 12316 "\nHistogram for `%s' bucket list length "
d3a49aa8 12317 "(total of %lu buckets):\n",
978c4450
AM
12318 (unsigned long) filedata->ngnubuckets),
12319 GNU_HASH_SECTION_NAME (filedata),
12320 (unsigned long) filedata->ngnubuckets);
8b73c356 12321
978c4450
AM
12322 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
12323 sizeof (*lengths));
fdc90cb4
JJ
12324 if (lengths == NULL)
12325 {
8b73c356 12326 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 12327 goto err_out;
fdc90cb4
JJ
12328 }
12329
fdc90cb4
JJ
12330 printf (_(" Length Number %% of total Coverage\n"));
12331
978c4450
AM
12332 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
12333 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
12334 {
12335 bfd_vma off, length = 1;
12336
978c4450 12337 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 12338 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
12339 off < filedata->ngnuchains
12340 && (filedata->gnuchains[off] & 1) == 0;
071436c6 12341 ++off)
fdc90cb4
JJ
12342 ++length;
12343 lengths[hn] = length;
12344 if (length > maxlength)
12345 maxlength = length;
12346 nsyms += length;
12347 }
12348
3f5e193b 12349 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
12350 if (counts == NULL)
12351 {
b2e951ec 12352 free (lengths);
8b73c356 12353 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 12354 goto err_out;
fdc90cb4
JJ
12355 }
12356
978c4450 12357 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
12358 ++counts[lengths[hn]];
12359
978c4450 12360 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
12361 {
12362 unsigned long j;
12363 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12364 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
12365 for (j = 1; j <= maxlength; ++j)
12366 {
12367 nzero_counts += counts[j] * j;
12368 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12369 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
12370 (nzero_counts * 100.0) / nsyms);
12371 }
12372 }
12373
12374 free (counts);
12375 free (lengths);
fdc90cb4 12376 }
978c4450
AM
12377 free (filedata->gnubuckets);
12378 filedata->gnubuckets = NULL;
12379 filedata->ngnubuckets = 0;
12380 free (filedata->gnuchains);
12381 filedata->gnuchains = NULL;
12382 filedata->ngnuchains = 0;
12383 free (filedata->mipsxlat);
12384 filedata->mipsxlat = NULL;
32ec8896 12385 return TRUE;
fd486f32
AM
12386
12387 err_out:
978c4450
AM
12388 free (filedata->gnubuckets);
12389 filedata->gnubuckets = NULL;
12390 filedata->ngnubuckets = 0;
12391 free (filedata->gnuchains);
12392 filedata->gnuchains = NULL;
12393 filedata->ngnuchains = 0;
12394 free (filedata->mipsxlat);
12395 filedata->mipsxlat = NULL;
12396 free (filedata->buckets);
12397 filedata->buckets = NULL;
12398 filedata->nbuckets = 0;
12399 free (filedata->chains);
12400 filedata->chains = NULL;
fd486f32 12401 return FALSE;
252b5132
RH
12402}
12403
32ec8896 12404static bfd_boolean
dda8d76d 12405process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
252b5132 12406{
b4c96d0d 12407 unsigned int i;
252b5132 12408
978c4450 12409 if (filedata->dynamic_syminfo == NULL
252b5132
RH
12410 || !do_dynamic)
12411 /* No syminfo, this is ok. */
32ec8896 12412 return TRUE;
252b5132
RH
12413
12414 /* There better should be a dynamic symbol section. */
978c4450 12415 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
32ec8896 12416 return FALSE;
252b5132 12417
978c4450 12418 if (filedata->dynamic_addr)
d3a49aa8
AM
12419 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
12420 "contains %d entry:\n",
12421 "\nDynamic info segment at offset 0x%lx "
12422 "contains %d entries:\n",
978c4450
AM
12423 filedata->dynamic_syminfo_nent),
12424 filedata->dynamic_syminfo_offset, filedata->dynamic_syminfo_nent);
252b5132
RH
12425
12426 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 12427 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 12428 {
978c4450 12429 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 12430
31104126 12431 printf ("%4d: ", i);
978c4450 12432 if (i >= filedata->num_dynamic_syms)
4082ef84 12433 printf (_("<corrupt index>"));
978c4450
AM
12434 else if (VALID_DYNAMIC_NAME (filedata, filedata->dynamic_symbols[i].st_name))
12435 print_symbol (30, GET_DYNAMIC_NAME (filedata,
12436 filedata->dynamic_symbols[i].st_name));
d79b3d50 12437 else
978c4450 12438 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 12439 putchar (' ');
252b5132 12440
978c4450 12441 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
12442 {
12443 case SYMINFO_BT_SELF:
12444 fputs ("SELF ", stdout);
12445 break;
12446 case SYMINFO_BT_PARENT:
12447 fputs ("PARENT ", stdout);
12448 break;
12449 default:
978c4450
AM
12450 if (filedata->dynamic_syminfo[i].si_boundto > 0
12451 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
12452 && VALID_DYNAMIC_NAME (filedata,
12453 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 12454 {
978c4450
AM
12455 print_symbol (10, GET_DYNAMIC_NAME (filedata,
12456 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
12457 putchar (' ' );
12458 }
252b5132 12459 else
978c4450 12460 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
12461 break;
12462 }
12463
12464 if (flags & SYMINFO_FLG_DIRECT)
12465 printf (" DIRECT");
12466 if (flags & SYMINFO_FLG_PASSTHRU)
12467 printf (" PASSTHRU");
12468 if (flags & SYMINFO_FLG_COPY)
12469 printf (" COPY");
12470 if (flags & SYMINFO_FLG_LAZYLOAD)
12471 printf (" LAZYLOAD");
12472
12473 puts ("");
12474 }
12475
32ec8896 12476 return TRUE;
252b5132
RH
12477}
12478
75802ccb
CE
12479/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
12480 is contained by the region START .. END. The types of ADDR, START
12481 and END should all be the same. Note both ADDR + NELEM and END
12482 point to just beyond the end of the regions that are being tested. */
12483#define IN_RANGE(START,END,ADDR,NELEM) \
12484 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 12485
cf13d699
NC
12486/* Check to see if the given reloc needs to be handled in a target specific
12487 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
12488 FALSE.
12489
12490 If called with reloc == NULL, then this is a signal that reloc processing
12491 for the current section has finished, and any saved state should be
12492 discarded. */
09c11c86 12493
cf13d699 12494static bfd_boolean
dda8d76d
NC
12495target_specific_reloc_handling (Filedata * filedata,
12496 Elf_Internal_Rela * reloc,
12497 unsigned char * start,
12498 unsigned char * end,
12499 Elf_Internal_Sym * symtab,
12500 unsigned long num_syms)
252b5132 12501{
f84ce13b
NC
12502 unsigned int reloc_type = 0;
12503 unsigned long sym_index = 0;
12504
12505 if (reloc)
12506 {
dda8d76d 12507 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
12508 sym_index = get_reloc_symindex (reloc->r_info);
12509 }
252b5132 12510
dda8d76d 12511 switch (filedata->file_header.e_machine)
252b5132 12512 {
13761a11
NC
12513 case EM_MSP430:
12514 case EM_MSP430_OLD:
12515 {
12516 static Elf_Internal_Sym * saved_sym = NULL;
12517
f84ce13b
NC
12518 if (reloc == NULL)
12519 {
12520 saved_sym = NULL;
12521 return TRUE;
12522 }
12523
13761a11
NC
12524 switch (reloc_type)
12525 {
12526 case 10: /* R_MSP430_SYM_DIFF */
dda8d76d 12527 if (uses_msp430x_relocs (filedata))
13761a11 12528 break;
1a0670f3 12529 /* Fall through. */
13761a11 12530 case 21: /* R_MSP430X_SYM_DIFF */
f84ce13b
NC
12531 /* PR 21139. */
12532 if (sym_index >= num_syms)
12533 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
12534 sym_index);
12535 else
12536 saved_sym = symtab + sym_index;
13761a11
NC
12537 return TRUE;
12538
12539 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
12540 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
12541 goto handle_sym_diff;
0b4362b0 12542
13761a11
NC
12543 case 5: /* R_MSP430_16_BYTE */
12544 case 9: /* R_MSP430_8 */
dda8d76d 12545 if (uses_msp430x_relocs (filedata))
13761a11
NC
12546 break;
12547 goto handle_sym_diff;
12548
12549 case 2: /* R_MSP430_ABS16 */
12550 case 15: /* R_MSP430X_ABS16 */
dda8d76d 12551 if (! uses_msp430x_relocs (filedata))
13761a11
NC
12552 break;
12553 goto handle_sym_diff;
0b4362b0 12554
13761a11
NC
12555 handle_sym_diff:
12556 if (saved_sym != NULL)
12557 {
03f7786e 12558 int reloc_size = reloc_type == 1 ? 4 : 2;
13761a11
NC
12559 bfd_vma value;
12560
f84ce13b
NC
12561 if (sym_index >= num_syms)
12562 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
12563 sym_index);
03f7786e 12564 else
f84ce13b
NC
12565 {
12566 value = reloc->r_addend + (symtab[sym_index].st_value
12567 - saved_sym->st_value);
12568
b32e566b 12569 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12570 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12571 else
12572 /* PR 21137 */
12573 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
12574 (long) reloc->r_offset);
f84ce13b 12575 }
13761a11
NC
12576
12577 saved_sym = NULL;
12578 return TRUE;
12579 }
12580 break;
12581
12582 default:
12583 if (saved_sym != NULL)
071436c6 12584 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
12585 break;
12586 }
12587 break;
12588 }
12589
cf13d699
NC
12590 case EM_MN10300:
12591 case EM_CYGNUS_MN10300:
12592 {
12593 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 12594
f84ce13b
NC
12595 if (reloc == NULL)
12596 {
12597 saved_sym = NULL;
12598 return TRUE;
12599 }
12600
cf13d699
NC
12601 switch (reloc_type)
12602 {
12603 case 34: /* R_MN10300_ALIGN */
12604 return TRUE;
12605 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
12606 if (sym_index >= num_syms)
12607 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
12608 sym_index);
12609 else
12610 saved_sym = symtab + sym_index;
cf13d699 12611 return TRUE;
f84ce13b 12612
cf13d699
NC
12613 case 1: /* R_MN10300_32 */
12614 case 2: /* R_MN10300_16 */
12615 if (saved_sym != NULL)
12616 {
03f7786e 12617 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 12618 bfd_vma value;
252b5132 12619
f84ce13b
NC
12620 if (sym_index >= num_syms)
12621 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
12622 sym_index);
03f7786e 12623 else
f84ce13b
NC
12624 {
12625 value = reloc->r_addend + (symtab[sym_index].st_value
12626 - saved_sym->st_value);
12627
b32e566b 12628 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12629 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12630 else
12631 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
12632 (long) reloc->r_offset);
f84ce13b 12633 }
252b5132 12634
cf13d699
NC
12635 saved_sym = NULL;
12636 return TRUE;
12637 }
12638 break;
12639 default:
12640 if (saved_sym != NULL)
071436c6 12641 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
12642 break;
12643 }
12644 break;
12645 }
6ff71e76
NC
12646
12647 case EM_RL78:
12648 {
12649 static bfd_vma saved_sym1 = 0;
12650 static bfd_vma saved_sym2 = 0;
12651 static bfd_vma value;
12652
f84ce13b
NC
12653 if (reloc == NULL)
12654 {
12655 saved_sym1 = saved_sym2 = 0;
12656 return TRUE;
12657 }
12658
6ff71e76
NC
12659 switch (reloc_type)
12660 {
12661 case 0x80: /* R_RL78_SYM. */
12662 saved_sym1 = saved_sym2;
f84ce13b
NC
12663 if (sym_index >= num_syms)
12664 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
12665 sym_index);
12666 else
12667 {
12668 saved_sym2 = symtab[sym_index].st_value;
12669 saved_sym2 += reloc->r_addend;
12670 }
6ff71e76
NC
12671 return TRUE;
12672
12673 case 0x83: /* R_RL78_OPsub. */
12674 value = saved_sym1 - saved_sym2;
12675 saved_sym2 = saved_sym1 = 0;
12676 return TRUE;
12677 break;
12678
12679 case 0x41: /* R_RL78_ABS32. */
b32e566b 12680 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 12681 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
12682 else
12683 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12684 (long) reloc->r_offset);
6ff71e76
NC
12685 value = 0;
12686 return TRUE;
12687
12688 case 0x43: /* R_RL78_ABS16. */
b32e566b 12689 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 12690 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
12691 else
12692 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12693 (long) reloc->r_offset);
6ff71e76
NC
12694 value = 0;
12695 return TRUE;
12696
12697 default:
12698 break;
12699 }
12700 break;
12701 }
252b5132
RH
12702 }
12703
cf13d699 12704 return FALSE;
252b5132
RH
12705}
12706
aca88567
NC
12707/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
12708 DWARF debug sections. This is a target specific test. Note - we do not
12709 go through the whole including-target-headers-multiple-times route, (as
12710 we have already done with <elf/h8.h>) because this would become very
12711 messy and even then this function would have to contain target specific
12712 information (the names of the relocs instead of their numeric values).
12713 FIXME: This is not the correct way to solve this problem. The proper way
12714 is to have target specific reloc sizing and typing functions created by
12715 the reloc-macros.h header, in the same way that it already creates the
12716 reloc naming functions. */
12717
12718static bfd_boolean
dda8d76d 12719is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12720{
d347c9df 12721 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12722 switch (filedata->file_header.e_machine)
aca88567 12723 {
41e92641 12724 case EM_386:
22abe556 12725 case EM_IAMCU:
41e92641 12726 return reloc_type == 1; /* R_386_32. */
aca88567
NC
12727 case EM_68K:
12728 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
12729 case EM_860:
12730 return reloc_type == 1; /* R_860_32. */
12731 case EM_960:
12732 return reloc_type == 2; /* R_960_32. */
a06ea964 12733 case EM_AARCH64:
9282b95a
JW
12734 return (reloc_type == 258
12735 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
12736 case EM_BPF:
12737 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
12738 case EM_ADAPTEVA_EPIPHANY:
12739 return reloc_type == 3;
aca88567 12740 case EM_ALPHA:
137b6b5f 12741 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
12742 case EM_ARC:
12743 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
12744 case EM_ARC_COMPACT:
12745 case EM_ARC_COMPACT2:
12746 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
12747 case EM_ARM:
12748 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 12749 case EM_AVR_OLD:
aca88567
NC
12750 case EM_AVR:
12751 return reloc_type == 1;
12752 case EM_BLACKFIN:
12753 return reloc_type == 0x12; /* R_byte4_data. */
12754 case EM_CRIS:
12755 return reloc_type == 3; /* R_CRIS_32. */
12756 case EM_CR16:
12757 return reloc_type == 3; /* R_CR16_NUM32. */
12758 case EM_CRX:
12759 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
12760 case EM_CSKY:
12761 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
12762 case EM_CYGNUS_FRV:
12763 return reloc_type == 1;
41e92641
NC
12764 case EM_CYGNUS_D10V:
12765 case EM_D10V:
12766 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
12767 case EM_CYGNUS_D30V:
12768 case EM_D30V:
12769 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
12770 case EM_DLX:
12771 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
12772 case EM_CYGNUS_FR30:
12773 case EM_FR30:
12774 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
12775 case EM_FT32:
12776 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
12777 case EM_H8S:
12778 case EM_H8_300:
12779 case EM_H8_300H:
12780 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 12781 case EM_IA_64:
262cdac7
AM
12782 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
12783 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
12784 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
12785 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
12786 case EM_IP2K_OLD:
12787 case EM_IP2K:
12788 return reloc_type == 2; /* R_IP2K_32. */
12789 case EM_IQ2000:
12790 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
12791 case EM_LATTICEMICO32:
12792 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 12793 case EM_M32C_OLD:
aca88567
NC
12794 case EM_M32C:
12795 return reloc_type == 3; /* R_M32C_32. */
12796 case EM_M32R:
12797 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
12798 case EM_68HC11:
12799 case EM_68HC12:
12800 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 12801 case EM_S12Z:
2849d19f
JD
12802 return reloc_type == 7 || /* R_S12Z_EXT32 */
12803 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
12804 case EM_MCORE:
12805 return reloc_type == 1; /* R_MCORE_ADDR32. */
12806 case EM_CYGNUS_MEP:
12807 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
12808 case EM_METAG:
12809 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
12810 case EM_MICROBLAZE:
12811 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
12812 case EM_MIPS:
12813 return reloc_type == 2; /* R_MIPS_32. */
12814 case EM_MMIX:
12815 return reloc_type == 4; /* R_MMIX_32. */
12816 case EM_CYGNUS_MN10200:
12817 case EM_MN10200:
12818 return reloc_type == 1; /* R_MN10200_32. */
12819 case EM_CYGNUS_MN10300:
12820 case EM_MN10300:
12821 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
12822 case EM_MOXIE:
12823 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
12824 case EM_MSP430_OLD:
12825 case EM_MSP430:
13761a11 12826 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
12827 case EM_MT:
12828 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
12829 case EM_NDS32:
12830 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 12831 case EM_ALTERA_NIOS2:
36591ba1 12832 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
12833 case EM_NIOS32:
12834 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
12835 case EM_OR1K:
12836 return reloc_type == 1; /* R_OR1K_32. */
aca88567 12837 case EM_PARISC:
9abca702 12838 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 12839 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 12840 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
12841 case EM_PJ:
12842 case EM_PJ_OLD:
12843 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
12844 case EM_PPC64:
12845 return reloc_type == 1; /* R_PPC64_ADDR32. */
12846 case EM_PPC:
12847 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
12848 case EM_TI_PRU:
12849 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
12850 case EM_RISCV:
12851 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
12852 case EM_RL78:
12853 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
12854 case EM_RX:
12855 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
12856 case EM_S370:
12857 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
12858 case EM_S390_OLD:
12859 case EM_S390:
12860 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
12861 case EM_SCORE:
12862 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
12863 case EM_SH:
12864 return reloc_type == 1; /* R_SH_DIR32. */
12865 case EM_SPARC32PLUS:
12866 case EM_SPARCV9:
12867 case EM_SPARC:
12868 return reloc_type == 3 /* R_SPARC_32. */
12869 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
12870 case EM_SPU:
12871 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
12872 case EM_TI_C6000:
12873 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
12874 case EM_TILEGX:
12875 return reloc_type == 2; /* R_TILEGX_32. */
12876 case EM_TILEPRO:
12877 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
12878 case EM_CYGNUS_V850:
12879 case EM_V850:
12880 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
12881 case EM_V800:
12882 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
12883 case EM_VAX:
12884 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
12885 case EM_VISIUM:
12886 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
12887 case EM_WEBASSEMBLY:
12888 return reloc_type == 1; /* R_WASM32_32. */
aca88567 12889 case EM_X86_64:
8a9036a4 12890 case EM_L1OM:
7a9068fe 12891 case EM_K1OM:
aca88567 12892 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
12893 case EM_XC16X:
12894 case EM_C166:
12895 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
12896 case EM_XGATE:
12897 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
12898 case EM_XSTORMY16:
12899 return reloc_type == 1; /* R_XSTROMY16_32. */
12900 case EM_XTENSA_OLD:
12901 case EM_XTENSA:
12902 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
12903 case EM_Z80:
12904 return reloc_type == 6; /* R_Z80_32. */
aca88567 12905 default:
bee0ee85
NC
12906 {
12907 static unsigned int prev_warn = 0;
12908
12909 /* Avoid repeating the same warning multiple times. */
dda8d76d 12910 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 12911 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
12912 filedata->file_header.e_machine);
12913 prev_warn = filedata->file_header.e_machine;
bee0ee85
NC
12914 return FALSE;
12915 }
aca88567
NC
12916 }
12917}
12918
12919/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12920 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
12921
12922static bfd_boolean
dda8d76d 12923is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12924{
dda8d76d 12925 switch (filedata->file_header.e_machine)
d347c9df 12926 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 12927 {
41e92641 12928 case EM_386:
22abe556 12929 case EM_IAMCU:
3e0873ac 12930 return reloc_type == 2; /* R_386_PC32. */
aca88567 12931 case EM_68K:
3e0873ac 12932 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
12933 case EM_AARCH64:
12934 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
12935 case EM_ADAPTEVA_EPIPHANY:
12936 return reloc_type == 6;
aca88567
NC
12937 case EM_ALPHA:
12938 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
12939 case EM_ARC_COMPACT:
12940 case EM_ARC_COMPACT2:
12941 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 12942 case EM_ARM:
3e0873ac 12943 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
12944 case EM_AVR_OLD:
12945 case EM_AVR:
12946 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
12947 case EM_MICROBLAZE:
12948 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
12949 case EM_OR1K:
12950 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 12951 case EM_PARISC:
85acf597 12952 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
12953 case EM_PPC:
12954 return reloc_type == 26; /* R_PPC_REL32. */
12955 case EM_PPC64:
3e0873ac 12956 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
12957 case EM_RISCV:
12958 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
12959 case EM_S390_OLD:
12960 case EM_S390:
3e0873ac 12961 return reloc_type == 5; /* R_390_PC32. */
aca88567 12962 case EM_SH:
3e0873ac 12963 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
12964 case EM_SPARC32PLUS:
12965 case EM_SPARCV9:
12966 case EM_SPARC:
3e0873ac 12967 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
12968 case EM_SPU:
12969 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
12970 case EM_TILEGX:
12971 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
12972 case EM_TILEPRO:
12973 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
12974 case EM_VISIUM:
12975 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 12976 case EM_X86_64:
8a9036a4 12977 case EM_L1OM:
7a9068fe 12978 case EM_K1OM:
3e0873ac 12979 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
12980 case EM_VAX:
12981 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
12982 case EM_XTENSA_OLD:
12983 case EM_XTENSA:
12984 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
12985 default:
12986 /* Do not abort or issue an error message here. Not all targets use
12987 pc-relative 32-bit relocs in their DWARF debug information and we
12988 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
12989 more helpful warning message will be generated by apply_relocations
12990 anyway, so just return. */
aca88567
NC
12991 return FALSE;
12992 }
12993}
12994
12995/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12996 a 64-bit absolute RELA relocation used in DWARF debug sections. */
12997
12998static bfd_boolean
dda8d76d 12999is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13000{
dda8d76d 13001 switch (filedata->file_header.e_machine)
aca88567 13002 {
a06ea964
NC
13003 case EM_AARCH64:
13004 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
13005 case EM_ALPHA:
13006 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 13007 case EM_IA_64:
262cdac7
AM
13008 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
13009 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
13010 case EM_PARISC:
13011 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
13012 case EM_PPC64:
13013 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
13014 case EM_RISCV:
13015 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
13016 case EM_SPARC32PLUS:
13017 case EM_SPARCV9:
13018 case EM_SPARC:
714da62f
NC
13019 return reloc_type == 32 /* R_SPARC_64. */
13020 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 13021 case EM_X86_64:
8a9036a4 13022 case EM_L1OM:
7a9068fe 13023 case EM_K1OM:
aca88567 13024 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
13025 case EM_S390_OLD:
13026 case EM_S390:
aa137e4d
NC
13027 return reloc_type == 22; /* R_S390_64. */
13028 case EM_TILEGX:
13029 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 13030 case EM_MIPS:
aa137e4d 13031 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
13032 default:
13033 return FALSE;
13034 }
13035}
13036
85acf597
RH
13037/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
13038 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
13039
13040static bfd_boolean
dda8d76d 13041is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 13042{
dda8d76d 13043 switch (filedata->file_header.e_machine)
85acf597 13044 {
a06ea964
NC
13045 case EM_AARCH64:
13046 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 13047 case EM_ALPHA:
aa137e4d 13048 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 13049 case EM_IA_64:
262cdac7
AM
13050 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
13051 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 13052 case EM_PARISC:
aa137e4d 13053 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 13054 case EM_PPC64:
aa137e4d 13055 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
13056 case EM_SPARC32PLUS:
13057 case EM_SPARCV9:
13058 case EM_SPARC:
aa137e4d 13059 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 13060 case EM_X86_64:
8a9036a4 13061 case EM_L1OM:
7a9068fe 13062 case EM_K1OM:
aa137e4d 13063 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
13064 case EM_S390_OLD:
13065 case EM_S390:
aa137e4d
NC
13066 return reloc_type == 23; /* R_S390_PC64. */
13067 case EM_TILEGX:
13068 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
13069 default:
13070 return FALSE;
13071 }
13072}
13073
4dc3c23d
AM
13074/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13075 a 24-bit absolute RELA relocation used in DWARF debug sections. */
13076
13077static bfd_boolean
dda8d76d 13078is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 13079{
dda8d76d 13080 switch (filedata->file_header.e_machine)
4dc3c23d
AM
13081 {
13082 case EM_CYGNUS_MN10200:
13083 case EM_MN10200:
13084 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
13085 case EM_FT32:
13086 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
13087 case EM_Z80:
13088 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d
AM
13089 default:
13090 return FALSE;
13091 }
13092}
13093
aca88567
NC
13094/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13095 a 16-bit absolute RELA relocation used in DWARF debug sections. */
13096
13097static bfd_boolean
dda8d76d 13098is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 13099{
d347c9df 13100 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13101 switch (filedata->file_header.e_machine)
4b78141a 13102 {
886a2506
NC
13103 case EM_ARC:
13104 case EM_ARC_COMPACT:
13105 case EM_ARC_COMPACT2:
13106 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
13107 case EM_ADAPTEVA_EPIPHANY:
13108 return reloc_type == 5;
aca88567
NC
13109 case EM_AVR_OLD:
13110 case EM_AVR:
13111 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
13112 case EM_CYGNUS_D10V:
13113 case EM_D10V:
13114 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
13115 case EM_FT32:
13116 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
13117 case EM_H8S:
13118 case EM_H8_300:
13119 case EM_H8_300H:
aca88567
NC
13120 return reloc_type == R_H8_DIR16;
13121 case EM_IP2K_OLD:
13122 case EM_IP2K:
13123 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 13124 case EM_M32C_OLD:
f4236fe4
DD
13125 case EM_M32C:
13126 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
13127 case EM_CYGNUS_MN10200:
13128 case EM_MN10200:
13129 return reloc_type == 2; /* R_MN10200_16. */
13130 case EM_CYGNUS_MN10300:
13131 case EM_MN10300:
13132 return reloc_type == 2; /* R_MN10300_16. */
aca88567 13133 case EM_MSP430:
dda8d76d 13134 if (uses_msp430x_relocs (filedata))
13761a11 13135 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 13136 /* Fall through. */
78c8d46c 13137 case EM_MSP430_OLD:
aca88567 13138 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
13139 case EM_NDS32:
13140 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 13141 case EM_ALTERA_NIOS2:
36591ba1 13142 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
13143 case EM_NIOS32:
13144 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
13145 case EM_OR1K:
13146 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
13147 case EM_RISCV:
13148 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
13149 case EM_TI_PRU:
13150 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
13151 case EM_TI_C6000:
13152 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
13153 case EM_VISIUM:
13154 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
13155 case EM_XC16X:
13156 case EM_C166:
13157 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
13158 case EM_XGATE:
13159 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
13160 case EM_Z80:
13161 return reloc_type == 4; /* R_Z80_16. */
4b78141a 13162 default:
aca88567 13163 return FALSE;
4b78141a
NC
13164 }
13165}
13166
39e07931
AS
13167/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13168 a 8-bit absolute RELA relocation used in DWARF debug sections. */
13169
13170static bfd_boolean
13171is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13172{
13173 switch (filedata->file_header.e_machine)
13174 {
13175 case EM_RISCV:
13176 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
13177 case EM_Z80:
13178 return reloc_type == 1; /* R_Z80_8. */
39e07931
AS
13179 default:
13180 return FALSE;
13181 }
13182}
13183
13184/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13185 a 6-bit absolute RELA relocation used in DWARF debug sections. */
13186
13187static bfd_boolean
13188is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13189{
13190 switch (filedata->file_header.e_machine)
13191 {
13192 case EM_RISCV:
13193 return reloc_type == 53; /* R_RISCV_SET6. */
13194 default:
13195 return FALSE;
13196 }
13197}
13198
03336641
JW
13199/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13200 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
13201
13202static bfd_boolean
13203is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13204{
13205 /* Please keep this table alpha-sorted for ease of visual lookup. */
13206 switch (filedata->file_header.e_machine)
13207 {
13208 case EM_RISCV:
13209 return reloc_type == 35; /* R_RISCV_ADD32. */
13210 default:
13211 return FALSE;
13212 }
13213}
13214
13215/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13216 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
13217
13218static bfd_boolean
13219is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13220{
13221 /* Please keep this table alpha-sorted for ease of visual lookup. */
13222 switch (filedata->file_header.e_machine)
13223 {
13224 case EM_RISCV:
13225 return reloc_type == 39; /* R_RISCV_SUB32. */
13226 default:
13227 return FALSE;
13228 }
13229}
13230
13231/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13232 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
13233
13234static bfd_boolean
13235is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13236{
13237 /* Please keep this table alpha-sorted for ease of visual lookup. */
13238 switch (filedata->file_header.e_machine)
13239 {
13240 case EM_RISCV:
13241 return reloc_type == 36; /* R_RISCV_ADD64. */
13242 default:
13243 return FALSE;
13244 }
13245}
13246
13247/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13248 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
13249
13250static bfd_boolean
13251is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13252{
13253 /* Please keep this table alpha-sorted for ease of visual lookup. */
13254 switch (filedata->file_header.e_machine)
13255 {
13256 case EM_RISCV:
13257 return reloc_type == 40; /* R_RISCV_SUB64. */
13258 default:
13259 return FALSE;
13260 }
13261}
13262
13263/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13264 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
13265
13266static bfd_boolean
13267is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13268{
13269 /* Please keep this table alpha-sorted for ease of visual lookup. */
13270 switch (filedata->file_header.e_machine)
13271 {
13272 case EM_RISCV:
13273 return reloc_type == 34; /* R_RISCV_ADD16. */
13274 default:
13275 return FALSE;
13276 }
13277}
13278
13279/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13280 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
13281
13282static bfd_boolean
13283is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13284{
13285 /* Please keep this table alpha-sorted for ease of visual lookup. */
13286 switch (filedata->file_header.e_machine)
13287 {
13288 case EM_RISCV:
13289 return reloc_type == 38; /* R_RISCV_SUB16. */
13290 default:
13291 return FALSE;
13292 }
13293}
13294
13295/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13296 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
13297
13298static bfd_boolean
13299is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13300{
13301 /* Please keep this table alpha-sorted for ease of visual lookup. */
13302 switch (filedata->file_header.e_machine)
13303 {
13304 case EM_RISCV:
13305 return reloc_type == 33; /* R_RISCV_ADD8. */
13306 default:
13307 return FALSE;
13308 }
13309}
13310
13311/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13312 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
13313
13314static bfd_boolean
13315is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13316{
13317 /* Please keep this table alpha-sorted for ease of visual lookup. */
13318 switch (filedata->file_header.e_machine)
13319 {
13320 case EM_RISCV:
13321 return reloc_type == 37; /* R_RISCV_SUB8. */
13322 default:
13323 return FALSE;
13324 }
13325}
13326
39e07931
AS
13327/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13328 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
13329
13330static bfd_boolean
13331is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13332{
13333 switch (filedata->file_header.e_machine)
13334 {
13335 case EM_RISCV:
13336 return reloc_type == 52; /* R_RISCV_SUB6. */
13337 default:
13338 return FALSE;
13339 }
13340}
13341
2a7b2e88
JK
13342/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
13343 relocation entries (possibly formerly used for SHT_GROUP sections). */
13344
13345static bfd_boolean
dda8d76d 13346is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 13347{
dda8d76d 13348 switch (filedata->file_header.e_machine)
2a7b2e88 13349 {
cb8f3167 13350 case EM_386: /* R_386_NONE. */
d347c9df 13351 case EM_68K: /* R_68K_NONE. */
cfb8c092 13352 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
13353 case EM_ALPHA: /* R_ALPHA_NONE. */
13354 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 13355 case EM_ARC: /* R_ARC_NONE. */
886a2506 13356 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 13357 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 13358 case EM_ARM: /* R_ARM_NONE. */
d347c9df 13359 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 13360 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
13361 case EM_FT32: /* R_FT32_NONE. */
13362 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 13363 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
13364 case EM_L1OM: /* R_X86_64_NONE. */
13365 case EM_M32R: /* R_M32R_NONE. */
13366 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 13367 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 13368 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
13369 case EM_NIOS32: /* R_NIOS_NONE. */
13370 case EM_OR1K: /* R_OR1K_NONE. */
13371 case EM_PARISC: /* R_PARISC_NONE. */
13372 case EM_PPC64: /* R_PPC64_NONE. */
13373 case EM_PPC: /* R_PPC_NONE. */
e23eba97 13374 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
13375 case EM_S390: /* R_390_NONE. */
13376 case EM_S390_OLD:
13377 case EM_SH: /* R_SH_NONE. */
13378 case EM_SPARC32PLUS:
13379 case EM_SPARC: /* R_SPARC_NONE. */
13380 case EM_SPARCV9:
aa137e4d
NC
13381 case EM_TILEGX: /* R_TILEGX_NONE. */
13382 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
13383 case EM_TI_C6000:/* R_C6000_NONE. */
13384 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 13385 case EM_XC16X:
6655dba2 13386 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 13387 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 13388 return reloc_type == 0;
d347c9df 13389
a06ea964
NC
13390 case EM_AARCH64:
13391 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
13392 case EM_AVR_OLD:
13393 case EM_AVR:
13394 return (reloc_type == 0 /* R_AVR_NONE. */
13395 || reloc_type == 30 /* R_AVR_DIFF8. */
13396 || reloc_type == 31 /* R_AVR_DIFF16. */
13397 || reloc_type == 32 /* R_AVR_DIFF32. */);
13398 case EM_METAG:
13399 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
13400 case EM_NDS32:
13401 return (reloc_type == 0 /* R_XTENSA_NONE. */
13402 || reloc_type == 204 /* R_NDS32_DIFF8. */
13403 || reloc_type == 205 /* R_NDS32_DIFF16. */
13404 || reloc_type == 206 /* R_NDS32_DIFF32. */
13405 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
13406 case EM_TI_PRU:
13407 return (reloc_type == 0 /* R_PRU_NONE. */
13408 || reloc_type == 65 /* R_PRU_DIFF8. */
13409 || reloc_type == 66 /* R_PRU_DIFF16. */
13410 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
13411 case EM_XTENSA_OLD:
13412 case EM_XTENSA:
4dc3c23d
AM
13413 return (reloc_type == 0 /* R_XTENSA_NONE. */
13414 || reloc_type == 17 /* R_XTENSA_DIFF8. */
13415 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
13416 || reloc_type == 19 /* R_XTENSA_DIFF32. */
13417 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
13418 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
13419 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
13420 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
13421 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
13422 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88
JK
13423 }
13424 return FALSE;
13425}
13426
d1c4b12b
NC
13427/* Returns TRUE if there is a relocation against
13428 section NAME at OFFSET bytes. */
13429
13430bfd_boolean
13431reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
13432{
13433 Elf_Internal_Rela * relocs;
13434 Elf_Internal_Rela * rp;
13435
13436 if (dsec == NULL || dsec->reloc_info == NULL)
13437 return FALSE;
13438
13439 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
13440
13441 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
13442 if (rp->r_offset == offset)
13443 return TRUE;
13444
13445 return FALSE;
13446}
13447
cf13d699 13448/* Apply relocations to a section.
32ec8896
NC
13449 Returns TRUE upon success, FALSE otherwise.
13450 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
13451 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
13452 will be set to the number of relocs loaded.
13453
cf13d699 13454 Note: So far support has been added only for those relocations
32ec8896
NC
13455 which can be found in debug sections. FIXME: Add support for
13456 more relocations ? */
1b315056 13457
32ec8896 13458static bfd_boolean
dda8d76d 13459apply_relocations (Filedata * filedata,
d1c4b12b
NC
13460 const Elf_Internal_Shdr * section,
13461 unsigned char * start,
13462 bfd_size_type size,
1449284b 13463 void ** relocs_return,
d1c4b12b 13464 unsigned long * num_relocs_return)
1b315056 13465{
cf13d699 13466 Elf_Internal_Shdr * relsec;
0d2a7a93 13467 unsigned char * end = start + size;
cb8f3167 13468
d1c4b12b
NC
13469 if (relocs_return != NULL)
13470 {
13471 * (Elf_Internal_Rela **) relocs_return = NULL;
13472 * num_relocs_return = 0;
13473 }
13474
dda8d76d 13475 if (filedata->file_header.e_type != ET_REL)
32ec8896
NC
13476 /* No relocs to apply. */
13477 return TRUE;
1b315056 13478
cf13d699 13479 /* Find the reloc section associated with the section. */
dda8d76d
NC
13480 for (relsec = filedata->section_headers;
13481 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 13482 ++relsec)
252b5132 13483 {
41e92641
NC
13484 bfd_boolean is_rela;
13485 unsigned long num_relocs;
2cf0635d
NC
13486 Elf_Internal_Rela * relocs;
13487 Elf_Internal_Rela * rp;
13488 Elf_Internal_Shdr * symsec;
13489 Elf_Internal_Sym * symtab;
ba5cdace 13490 unsigned long num_syms;
2cf0635d 13491 Elf_Internal_Sym * sym;
252b5132 13492
41e92641 13493 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13494 || relsec->sh_info >= filedata->file_header.e_shnum
13495 || filedata->section_headers + relsec->sh_info != section
c256ffe7 13496 || relsec->sh_size == 0
dda8d76d 13497 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 13498 continue;
428409d5 13499
a788aedd
AM
13500 symsec = filedata->section_headers + relsec->sh_link;
13501 if (symsec->sh_type != SHT_SYMTAB
13502 && symsec->sh_type != SHT_DYNSYM)
13503 return FALSE;
13504
41e92641
NC
13505 is_rela = relsec->sh_type == SHT_RELA;
13506
13507 if (is_rela)
13508 {
dda8d76d 13509 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 13510 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13511 return FALSE;
41e92641
NC
13512 }
13513 else
13514 {
dda8d76d 13515 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 13516 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13517 return FALSE;
41e92641
NC
13518 }
13519
13520 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 13521 if (filedata->file_header.e_machine == EM_SH)
41e92641 13522 is_rela = FALSE;
428409d5 13523
dda8d76d 13524 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 13525
41e92641 13526 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 13527 {
41e92641
NC
13528 bfd_vma addend;
13529 unsigned int reloc_type;
13530 unsigned int reloc_size;
03336641
JW
13531 bfd_boolean reloc_inplace = FALSE;
13532 bfd_boolean reloc_subtract = FALSE;
91d6fa6a 13533 unsigned char * rloc;
ba5cdace 13534 unsigned long sym_index;
4b78141a 13535
dda8d76d 13536 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 13537
dda8d76d 13538 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 13539 continue;
dda8d76d 13540 else if (is_none_reloc (filedata, reloc_type))
98fb390a 13541 continue;
dda8d76d
NC
13542 else if (is_32bit_abs_reloc (filedata, reloc_type)
13543 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 13544 reloc_size = 4;
dda8d76d
NC
13545 else if (is_64bit_abs_reloc (filedata, reloc_type)
13546 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 13547 reloc_size = 8;
dda8d76d 13548 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 13549 reloc_size = 3;
dda8d76d 13550 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 13551 reloc_size = 2;
39e07931
AS
13552 else if (is_8bit_abs_reloc (filedata, reloc_type)
13553 || is_6bit_abs_reloc (filedata, reloc_type))
13554 reloc_size = 1;
03336641
JW
13555 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
13556 reloc_type))
13557 || is_32bit_inplace_add_reloc (filedata, reloc_type))
13558 {
13559 reloc_size = 4;
13560 reloc_inplace = TRUE;
13561 }
13562 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
13563 reloc_type))
13564 || is_64bit_inplace_add_reloc (filedata, reloc_type))
13565 {
13566 reloc_size = 8;
13567 reloc_inplace = TRUE;
13568 }
13569 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
13570 reloc_type))
13571 || is_16bit_inplace_add_reloc (filedata, reloc_type))
13572 {
13573 reloc_size = 2;
13574 reloc_inplace = TRUE;
13575 }
13576 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
13577 reloc_type))
13578 || is_8bit_inplace_add_reloc (filedata, reloc_type))
13579 {
13580 reloc_size = 1;
13581 reloc_inplace = TRUE;
13582 }
39e07931
AS
13583 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
13584 reloc_type)))
13585 {
13586 reloc_size = 1;
13587 reloc_inplace = TRUE;
13588 }
aca88567 13589 else
4b78141a 13590 {
bee0ee85 13591 static unsigned int prev_reloc = 0;
dda8d76d 13592
bee0ee85
NC
13593 if (reloc_type != prev_reloc)
13594 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 13595 reloc_type, printable_section_name (filedata, section));
bee0ee85 13596 prev_reloc = reloc_type;
4b78141a
NC
13597 continue;
13598 }
103f02d3 13599
91d6fa6a 13600 rloc = start + rp->r_offset;
75802ccb 13601 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
13602 {
13603 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
13604 (unsigned long) rp->r_offset,
dda8d76d 13605 printable_section_name (filedata, section));
700dd8b7
L
13606 continue;
13607 }
103f02d3 13608
ba5cdace
NC
13609 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
13610 if (sym_index >= num_syms)
13611 {
13612 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 13613 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
13614 continue;
13615 }
13616 sym = symtab + sym_index;
41e92641
NC
13617
13618 /* If the reloc has a symbol associated with it,
55f25fc3
L
13619 make sure that it is of an appropriate type.
13620
13621 Relocations against symbols without type can happen.
13622 Gcc -feliminate-dwarf2-dups may generate symbols
13623 without type for debug info.
13624
13625 Icc generates relocations against function symbols
13626 instead of local labels.
13627
13628 Relocations against object symbols can happen, eg when
13629 referencing a global array. For an example of this see
13630 the _clz.o binary in libgcc.a. */
aca88567 13631 if (sym != symtab
b8871f35 13632 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 13633 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 13634 {
d3a49aa8 13635 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
13636 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
13637 printable_section_name (filedata, relsec),
d3a49aa8 13638 (long int)(rp - relocs));
aca88567 13639 continue;
5b18a4bc 13640 }
252b5132 13641
4dc3c23d
AM
13642 addend = 0;
13643 if (is_rela)
13644 addend += rp->r_addend;
c47320c3
AM
13645 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
13646 partial_inplace. */
4dc3c23d 13647 if (!is_rela
dda8d76d 13648 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 13649 && reloc_type == 1)
dda8d76d
NC
13650 || ((filedata->file_header.e_machine == EM_PJ
13651 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 13652 && reloc_type == 1)
dda8d76d
NC
13653 || ((filedata->file_header.e_machine == EM_D30V
13654 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
13655 && reloc_type == 12)
13656 || reloc_inplace)
39e07931
AS
13657 {
13658 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
13659 addend += byte_get (rloc, reloc_size) & 0x3f;
13660 else
13661 addend += byte_get (rloc, reloc_size);
13662 }
cb8f3167 13663
dda8d76d
NC
13664 if (is_32bit_pcrel_reloc (filedata, reloc_type)
13665 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
13666 {
13667 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 13668 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 13669 addend -= 8;
91d6fa6a 13670 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
13671 reloc_size);
13672 }
39e07931
AS
13673 else if (is_6bit_abs_reloc (filedata, reloc_type)
13674 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
13675 {
13676 if (reloc_subtract)
13677 addend -= sym->st_value;
13678 else
13679 addend += sym->st_value;
13680 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
13681 byte_put (rloc, addend, reloc_size);
13682 }
03336641
JW
13683 else if (reloc_subtract)
13684 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 13685 else
91d6fa6a 13686 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 13687 }
252b5132 13688
5b18a4bc 13689 free (symtab);
f84ce13b
NC
13690 /* Let the target specific reloc processing code know that
13691 we have finished with these relocs. */
dda8d76d 13692 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
13693
13694 if (relocs_return)
13695 {
13696 * (Elf_Internal_Rela **) relocs_return = relocs;
13697 * num_relocs_return = num_relocs;
13698 }
13699 else
13700 free (relocs);
13701
5b18a4bc
NC
13702 break;
13703 }
32ec8896 13704
dfc616fa 13705 return TRUE;
5b18a4bc 13706}
103f02d3 13707
cf13d699 13708#ifdef SUPPORT_DISASSEMBLY
32ec8896 13709static bfd_boolean
dda8d76d 13710disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13711{
dda8d76d 13712 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 13713
74e1a04b 13714 /* FIXME: XXX -- to be done --- XXX */
cf13d699 13715
32ec8896 13716 return TRUE;
cf13d699
NC
13717}
13718#endif
13719
13720/* Reads in the contents of SECTION from FILE, returning a pointer
13721 to a malloc'ed buffer or NULL if something went wrong. */
13722
13723static char *
dda8d76d 13724get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13725{
dda8d76d 13726 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
13727
13728 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
13729 {
c6b78c96 13730 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 13731 printable_section_name (filedata, section));
cf13d699
NC
13732 return NULL;
13733 }
13734
dda8d76d 13735 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 13736 _("section contents"));
cf13d699
NC
13737}
13738
0e602686
NC
13739/* Uncompresses a section that was compressed using zlib, in place. */
13740
13741static bfd_boolean
dda8d76d
NC
13742uncompress_section_contents (unsigned char ** buffer,
13743 dwarf_size_type uncompressed_size,
13744 dwarf_size_type * size)
0e602686
NC
13745{
13746 dwarf_size_type compressed_size = *size;
13747 unsigned char * compressed_buffer = *buffer;
13748 unsigned char * uncompressed_buffer;
13749 z_stream strm;
13750 int rc;
13751
13752 /* It is possible the section consists of several compressed
13753 buffers concatenated together, so we uncompress in a loop. */
13754 /* PR 18313: The state field in the z_stream structure is supposed
13755 to be invisible to the user (ie us), but some compilers will
13756 still complain about it being used without initialisation. So
13757 we first zero the entire z_stream structure and then set the fields
13758 that we need. */
13759 memset (& strm, 0, sizeof strm);
13760 strm.avail_in = compressed_size;
13761 strm.next_in = (Bytef *) compressed_buffer;
13762 strm.avail_out = uncompressed_size;
13763 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
13764
13765 rc = inflateInit (& strm);
13766 while (strm.avail_in > 0)
13767 {
13768 if (rc != Z_OK)
13769 goto fail;
13770 strm.next_out = ((Bytef *) uncompressed_buffer
13771 + (uncompressed_size - strm.avail_out));
13772 rc = inflate (&strm, Z_FINISH);
13773 if (rc != Z_STREAM_END)
13774 goto fail;
13775 rc = inflateReset (& strm);
13776 }
13777 rc = inflateEnd (& strm);
13778 if (rc != Z_OK
13779 || strm.avail_out != 0)
13780 goto fail;
13781
13782 *buffer = uncompressed_buffer;
13783 *size = uncompressed_size;
13784 return TRUE;
13785
13786 fail:
13787 free (uncompressed_buffer);
13788 /* Indicate decompression failure. */
13789 *buffer = NULL;
13790 return FALSE;
13791}
dd24e3da 13792
32ec8896 13793static bfd_boolean
dda8d76d 13794dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13795{
0e602686
NC
13796 Elf_Internal_Shdr * relsec;
13797 bfd_size_type num_bytes;
fd8008d8
L
13798 unsigned char * data;
13799 unsigned char * end;
13800 unsigned char * real_start;
13801 unsigned char * start;
0e602686 13802 bfd_boolean some_strings_shown;
cf13d699 13803
dda8d76d 13804 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13805 if (start == NULL)
c6b78c96
NC
13806 /* PR 21820: Do not fail if the section was empty. */
13807 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
13808
0e602686 13809 num_bytes = section->sh_size;
cf13d699 13810
dda8d76d 13811 printf (_("\nString dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13812
0e602686
NC
13813 if (decompress_dumps)
13814 {
13815 dwarf_size_type new_size = num_bytes;
13816 dwarf_size_type uncompressed_size = 0;
13817
13818 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13819 {
13820 Elf_Internal_Chdr chdr;
13821 unsigned int compression_header_size
ebdf1ebf
NC
13822 = get_compression_header (& chdr, (unsigned char *) start,
13823 num_bytes);
5844b465
NC
13824 if (compression_header_size == 0)
13825 /* An error message will have already been generated
13826 by get_compression_header. */
13827 goto error_out;
0e602686 13828
813dabb9 13829 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13830 {
813dabb9 13831 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13832 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 13833 goto error_out;
813dabb9 13834 }
813dabb9
L
13835 uncompressed_size = chdr.ch_size;
13836 start += compression_header_size;
13837 new_size -= compression_header_size;
0e602686
NC
13838 }
13839 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13840 {
13841 /* Read the zlib header. In this case, it should be "ZLIB"
13842 followed by the uncompressed section size, 8 bytes in
13843 big-endian order. */
13844 uncompressed_size = start[4]; uncompressed_size <<= 8;
13845 uncompressed_size += start[5]; uncompressed_size <<= 8;
13846 uncompressed_size += start[6]; uncompressed_size <<= 8;
13847 uncompressed_size += start[7]; uncompressed_size <<= 8;
13848 uncompressed_size += start[8]; uncompressed_size <<= 8;
13849 uncompressed_size += start[9]; uncompressed_size <<= 8;
13850 uncompressed_size += start[10]; uncompressed_size <<= 8;
13851 uncompressed_size += start[11];
13852 start += 12;
13853 new_size -= 12;
13854 }
13855
1835f746
NC
13856 if (uncompressed_size)
13857 {
13858 if (uncompress_section_contents (& start,
13859 uncompressed_size, & new_size))
13860 num_bytes = new_size;
13861 else
13862 {
13863 error (_("Unable to decompress section %s\n"),
dda8d76d 13864 printable_section_name (filedata, section));
f761cb13 13865 goto error_out;
1835f746
NC
13866 }
13867 }
bc303e5d
NC
13868 else
13869 start = real_start;
0e602686 13870 }
fd8008d8 13871
cf13d699
NC
13872 /* If the section being dumped has relocations against it the user might
13873 be expecting these relocations to have been applied. Check for this
13874 case and issue a warning message in order to avoid confusion.
13875 FIXME: Maybe we ought to have an option that dumps a section with
13876 relocs applied ? */
dda8d76d
NC
13877 for (relsec = filedata->section_headers;
13878 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13879 ++relsec)
13880 {
13881 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13882 || relsec->sh_info >= filedata->file_header.e_shnum
13883 || filedata->section_headers + relsec->sh_info != section
cf13d699 13884 || relsec->sh_size == 0
dda8d76d 13885 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13886 continue;
13887
13888 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13889 break;
13890 }
13891
cf13d699
NC
13892 data = start;
13893 end = start + num_bytes;
13894 some_strings_shown = FALSE;
13895
ba3265d0
NC
13896#ifdef HAVE_MBSTATE_T
13897 mbstate_t state;
13898 /* Initialise the multibyte conversion state. */
13899 memset (& state, 0, sizeof (state));
13900#endif
13901
13902 bfd_boolean continuing = FALSE;
13903
cf13d699
NC
13904 while (data < end)
13905 {
13906 while (!ISPRINT (* data))
13907 if (++ data >= end)
13908 break;
13909
13910 if (data < end)
13911 {
071436c6
NC
13912 size_t maxlen = end - data;
13913
ba3265d0
NC
13914 if (continuing)
13915 {
13916 printf (" ");
13917 continuing = FALSE;
13918 }
13919 else
13920 {
cf13d699 13921#ifndef __MSVCRT__
ba3265d0
NC
13922 /* PR 11128: Use two separate invocations in order to work
13923 around bugs in the Solaris 8 implementation of printf. */
13924 printf (" [%6tx] ", data - start);
cf13d699 13925#else
ba3265d0 13926 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 13927#endif
ba3265d0
NC
13928 }
13929
4082ef84
NC
13930 if (maxlen > 0)
13931 {
ba3265d0
NC
13932 char c;
13933
13934 while (maxlen)
13935 {
13936 c = *data++;
13937
13938 if (c == 0)
13939 break;
13940
13941 /* PR 25543: Treat new-lines as string-ending characters. */
13942 if (c == '\n')
13943 {
13944 printf ("\\n\n");
13945 if (*data != 0)
13946 continuing = TRUE;
13947 break;
13948 }
13949
13950 /* Do not print control characters directly as they can affect terminal
13951 settings. Such characters usually appear in the names generated
13952 by the assembler for local labels. */
13953 if (ISCNTRL (c))
13954 {
13955 printf ("^%c", c + 0x40);
13956 }
13957 else if (ISPRINT (c))
13958 {
13959 putchar (c);
13960 }
13961 else
13962 {
13963 size_t n;
13964#ifdef HAVE_MBSTATE_T
13965 wchar_t w;
13966#endif
13967 /* Let printf do the hard work of displaying multibyte characters. */
13968 printf ("%.1s", data - 1);
13969#ifdef HAVE_MBSTATE_T
13970 /* Try to find out how many bytes made up the character that was
13971 just printed. Advance the symbol pointer past the bytes that
13972 were displayed. */
13973 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
13974#else
13975 n = 1;
13976#endif
13977 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
13978 data += (n - 1);
13979 }
13980 }
13981
13982 if (c != '\n')
13983 putchar ('\n');
4082ef84
NC
13984 }
13985 else
13986 {
13987 printf (_("<corrupt>\n"));
13988 data = end;
13989 }
cf13d699
NC
13990 some_strings_shown = TRUE;
13991 }
13992 }
13993
13994 if (! some_strings_shown)
13995 printf (_(" No strings found in this section."));
13996
0e602686 13997 free (real_start);
cf13d699
NC
13998
13999 putchar ('\n');
32ec8896 14000 return TRUE;
f761cb13
AM
14001
14002error_out:
14003 free (real_start);
14004 return FALSE;
cf13d699
NC
14005}
14006
32ec8896 14007static bfd_boolean
dda8d76d
NC
14008dump_section_as_bytes (Elf_Internal_Shdr * section,
14009 Filedata * filedata,
14010 bfd_boolean relocate)
cf13d699
NC
14011{
14012 Elf_Internal_Shdr * relsec;
0e602686
NC
14013 bfd_size_type bytes;
14014 bfd_size_type section_size;
14015 bfd_vma addr;
14016 unsigned char * data;
14017 unsigned char * real_start;
14018 unsigned char * start;
14019
dda8d76d 14020 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14021 if (start == NULL)
c6b78c96
NC
14022 /* PR 21820: Do not fail if the section was empty. */
14023 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
32ec8896 14024
0e602686 14025 section_size = section->sh_size;
cf13d699 14026
dda8d76d 14027 printf (_("\nHex dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 14028
0e602686
NC
14029 if (decompress_dumps)
14030 {
14031 dwarf_size_type new_size = section_size;
14032 dwarf_size_type uncompressed_size = 0;
14033
14034 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14035 {
14036 Elf_Internal_Chdr chdr;
14037 unsigned int compression_header_size
ebdf1ebf 14038 = get_compression_header (& chdr, start, section_size);
0e602686 14039
5844b465
NC
14040 if (compression_header_size == 0)
14041 /* An error message will have already been generated
14042 by get_compression_header. */
14043 goto error_out;
14044
813dabb9 14045 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14046 {
813dabb9 14047 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14048 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14049 goto error_out;
0e602686 14050 }
813dabb9
L
14051 uncompressed_size = chdr.ch_size;
14052 start += compression_header_size;
14053 new_size -= compression_header_size;
0e602686
NC
14054 }
14055 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14056 {
14057 /* Read the zlib header. In this case, it should be "ZLIB"
14058 followed by the uncompressed section size, 8 bytes in
14059 big-endian order. */
14060 uncompressed_size = start[4]; uncompressed_size <<= 8;
14061 uncompressed_size += start[5]; uncompressed_size <<= 8;
14062 uncompressed_size += start[6]; uncompressed_size <<= 8;
14063 uncompressed_size += start[7]; uncompressed_size <<= 8;
14064 uncompressed_size += start[8]; uncompressed_size <<= 8;
14065 uncompressed_size += start[9]; uncompressed_size <<= 8;
14066 uncompressed_size += start[10]; uncompressed_size <<= 8;
14067 uncompressed_size += start[11];
14068 start += 12;
14069 new_size -= 12;
14070 }
14071
f055032e
NC
14072 if (uncompressed_size)
14073 {
14074 if (uncompress_section_contents (& start, uncompressed_size,
14075 & new_size))
bc303e5d
NC
14076 {
14077 section_size = new_size;
14078 }
f055032e
NC
14079 else
14080 {
14081 error (_("Unable to decompress section %s\n"),
dda8d76d 14082 printable_section_name (filedata, section));
bc303e5d 14083 /* FIXME: Print the section anyway ? */
f761cb13 14084 goto error_out;
f055032e
NC
14085 }
14086 }
bc303e5d
NC
14087 else
14088 start = real_start;
0e602686 14089 }
14ae95f2 14090
cf13d699
NC
14091 if (relocate)
14092 {
dda8d76d 14093 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 14094 goto error_out;
cf13d699
NC
14095 }
14096 else
14097 {
14098 /* If the section being dumped has relocations against it the user might
14099 be expecting these relocations to have been applied. Check for this
14100 case and issue a warning message in order to avoid confusion.
14101 FIXME: Maybe we ought to have an option that dumps a section with
14102 relocs applied ? */
dda8d76d
NC
14103 for (relsec = filedata->section_headers;
14104 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14105 ++relsec)
14106 {
14107 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14108 || relsec->sh_info >= filedata->file_header.e_shnum
14109 || filedata->section_headers + relsec->sh_info != section
cf13d699 14110 || relsec->sh_size == 0
dda8d76d 14111 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14112 continue;
14113
14114 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14115 break;
14116 }
14117 }
14118
14119 addr = section->sh_addr;
0e602686 14120 bytes = section_size;
cf13d699
NC
14121 data = start;
14122
14123 while (bytes)
14124 {
14125 int j;
14126 int k;
14127 int lbytes;
14128
14129 lbytes = (bytes > 16 ? 16 : bytes);
14130
14131 printf (" 0x%8.8lx ", (unsigned long) addr);
14132
14133 for (j = 0; j < 16; j++)
14134 {
14135 if (j < lbytes)
14136 printf ("%2.2x", data[j]);
14137 else
14138 printf (" ");
14139
14140 if ((j & 3) == 3)
14141 printf (" ");
14142 }
14143
14144 for (j = 0; j < lbytes; j++)
14145 {
14146 k = data[j];
14147 if (k >= ' ' && k < 0x7f)
14148 printf ("%c", k);
14149 else
14150 printf (".");
14151 }
14152
14153 putchar ('\n');
14154
14155 data += lbytes;
14156 addr += lbytes;
14157 bytes -= lbytes;
14158 }
14159
0e602686 14160 free (real_start);
cf13d699
NC
14161
14162 putchar ('\n');
32ec8896 14163 return TRUE;
f761cb13
AM
14164
14165 error_out:
14166 free (real_start);
14167 return FALSE;
cf13d699
NC
14168}
14169
7d9813f1
NA
14170static ctf_sect_t *
14171shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
14172{
90bd5423 14173 buf->cts_name = SECTION_NAME (shdr);
7d9813f1
NA
14174 buf->cts_size = shdr->sh_size;
14175 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
14176
14177 return buf;
14178}
14179
14180/* Formatting callback function passed to ctf_dump. Returns either the pointer
14181 it is passed, or a pointer to newly-allocated storage, in which case
14182 dump_ctf() will free it when it no longer needs it. */
14183
14184static char *dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14185 char *s, void *arg)
14186{
3e50a591 14187 const char *blanks = arg;
7d9813f1
NA
14188 char *new_s;
14189
3e50a591 14190 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
14191 return s;
14192 return new_s;
14193}
14194
14195static bfd_boolean
14196dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
14197{
14198 Elf_Internal_Shdr * parent_sec = NULL;
14199 Elf_Internal_Shdr * symtab_sec = NULL;
14200 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
14201 void * data = NULL;
14202 void * symdata = NULL;
14203 void * strdata = NULL;
14204 void * parentdata = NULL;
14205 ctf_sect_t ctfsect, symsect, strsect, parentsect;
14206 ctf_sect_t * symsectp = NULL;
14207 ctf_sect_t * strsectp = NULL;
14208 ctf_file_t * ctf = NULL;
14209 ctf_file_t * parent = NULL;
7d9813f1 14210
9b32cba4
NA
14211 const char *things[] = {"Header", "Labels", "Data objects",
14212 "Function objects", "Variables", "Types", "Strings",
14213 ""};
7d9813f1
NA
14214 const char **thing;
14215 int err;
14216 bfd_boolean ret = FALSE;
14217 size_t i;
14218
14219 shdr_to_ctf_sect (&ctfsect, section, filedata);
14220 data = get_section_contents (section, filedata);
14221 ctfsect.cts_data = data;
14222
616febde
NA
14223 if (!dump_ctf_symtab_name)
14224 dump_ctf_symtab_name = strdup (".symtab");
14225
14226 if (!dump_ctf_strtab_name)
14227 dump_ctf_strtab_name = strdup (".strtab");
14228
14229 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
14230 {
14231 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
14232 {
14233 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
14234 goto fail;
14235 }
14236 if ((symdata = (void *) get_data (NULL, filedata,
14237 symtab_sec->sh_offset, 1,
14238 symtab_sec->sh_size,
14239 _("symbols"))) == NULL)
14240 goto fail;
14241 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
14242 symsect.cts_data = symdata;
14243 }
616febde 14244 if (dump_ctf_strtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
14245 {
14246 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
14247 {
14248 error (_("No string table section named %s\n"),
14249 dump_ctf_strtab_name);
14250 goto fail;
14251 }
14252 if ((strdata = (void *) get_data (NULL, filedata,
14253 strtab_sec->sh_offset, 1,
14254 strtab_sec->sh_size,
14255 _("strings"))) == NULL)
14256 goto fail;
14257 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
14258 strsect.cts_data = strdata;
14259 }
14260 if (dump_ctf_parent_name)
14261 {
14262 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
14263 {
14264 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
14265 goto fail;
14266 }
14267 if ((parentdata = (void *) get_data (NULL, filedata,
14268 parent_sec->sh_offset, 1,
14269 parent_sec->sh_size,
14270 _("CTF parent"))) == NULL)
14271 goto fail;
14272 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
14273 parentsect.cts_data = parentdata;
14274 }
14275
14276 /* Load the CTF file and dump it. */
14277
14278 if ((ctf = ctf_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
14279 {
14280 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14281 goto fail;
14282 }
14283
14284 if (parentdata)
14285 {
14286 if ((parent = ctf_bufopen (&parentsect, symsectp, strsectp, &err)) == NULL)
14287 {
14288 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14289 goto fail;
14290 }
14291
14292 ctf_import (ctf, parent);
14293 }
14294
14295 ret = TRUE;
14296
14297 printf (_("\nDump of CTF section '%s':\n"),
14298 printable_section_name (filedata, section));
14299
9b32cba4 14300 for (i = 0, thing = things; *thing[0]; thing++, i++)
7d9813f1
NA
14301 {
14302 ctf_dump_state_t *s = NULL;
14303 char *item;
14304
14305 printf ("\n %s:\n", *thing);
14306 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
14307 (void *) " ")) != NULL)
14308 {
14309 printf ("%s\n", item);
14310 free (item);
14311 }
14312
14313 if (ctf_errno (ctf))
14314 {
14315 error (_("Iteration failed: %s, %s\n"), *thing,
14316 ctf_errmsg (ctf_errno (ctf)));
14317 ret = FALSE;
14318 }
14319 }
14320
14321 fail:
14322 ctf_file_close (ctf);
14323 ctf_file_close (parent);
14324 free (parentdata);
14325 free (data);
14326 free (symdata);
14327 free (strdata);
14328 return ret;
14329}
14330
32ec8896 14331static bfd_boolean
dda8d76d
NC
14332load_specific_debug_section (enum dwarf_section_display_enum debug,
14333 const Elf_Internal_Shdr * sec,
14334 void * data)
1007acb3 14335{
2cf0635d 14336 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 14337 char buf [64];
dda8d76d 14338 Filedata * filedata = (Filedata *) data;
9abca702 14339
19e6b90e 14340 if (section->start != NULL)
dda8d76d
NC
14341 {
14342 /* If it is already loaded, do nothing. */
14343 if (streq (section->filename, filedata->file_name))
14344 return TRUE;
14345 free (section->start);
14346 }
1007acb3 14347
19e6b90e
L
14348 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
14349 section->address = sec->sh_addr;
06614111 14350 section->user_data = NULL;
dda8d76d
NC
14351 section->filename = filedata->file_name;
14352 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
14353 sec->sh_offset, 1,
14354 sec->sh_size, buf);
59245841
NC
14355 if (section->start == NULL)
14356 section->size = 0;
14357 else
14358 {
77115a4a
L
14359 unsigned char *start = section->start;
14360 dwarf_size_type size = sec->sh_size;
dab394de 14361 dwarf_size_type uncompressed_size = 0;
77115a4a
L
14362
14363 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
14364 {
14365 Elf_Internal_Chdr chdr;
d8024a91
NC
14366 unsigned int compression_header_size;
14367
f53be977
L
14368 if (size < (is_32bit_elf
14369 ? sizeof (Elf32_External_Chdr)
14370 : sizeof (Elf64_External_Chdr)))
d8024a91 14371 {
55be8fd0 14372 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 14373 section->name);
32ec8896 14374 return FALSE;
d8024a91
NC
14375 }
14376
ebdf1ebf 14377 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
14378 if (compression_header_size == 0)
14379 /* An error message will have already been generated
14380 by get_compression_header. */
14381 return FALSE;
d8024a91 14382
813dabb9
L
14383 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
14384 {
14385 warn (_("section '%s' has unsupported compress type: %d\n"),
14386 section->name, chdr.ch_type);
32ec8896 14387 return FALSE;
813dabb9 14388 }
dab394de 14389 uncompressed_size = chdr.ch_size;
77115a4a
L
14390 start += compression_header_size;
14391 size -= compression_header_size;
14392 }
dab394de
L
14393 else if (size > 12 && streq ((char *) start, "ZLIB"))
14394 {
14395 /* Read the zlib header. In this case, it should be "ZLIB"
14396 followed by the uncompressed section size, 8 bytes in
14397 big-endian order. */
14398 uncompressed_size = start[4]; uncompressed_size <<= 8;
14399 uncompressed_size += start[5]; uncompressed_size <<= 8;
14400 uncompressed_size += start[6]; uncompressed_size <<= 8;
14401 uncompressed_size += start[7]; uncompressed_size <<= 8;
14402 uncompressed_size += start[8]; uncompressed_size <<= 8;
14403 uncompressed_size += start[9]; uncompressed_size <<= 8;
14404 uncompressed_size += start[10]; uncompressed_size <<= 8;
14405 uncompressed_size += start[11];
14406 start += 12;
14407 size -= 12;
14408 }
14409
1835f746 14410 if (uncompressed_size)
77115a4a 14411 {
1835f746
NC
14412 if (uncompress_section_contents (&start, uncompressed_size,
14413 &size))
14414 {
14415 /* Free the compressed buffer, update the section buffer
14416 and the section size if uncompress is successful. */
14417 free (section->start);
14418 section->start = start;
14419 }
14420 else
14421 {
14422 error (_("Unable to decompress section %s\n"),
dda8d76d 14423 printable_section_name (filedata, sec));
32ec8896 14424 return FALSE;
1835f746 14425 }
77115a4a 14426 }
bc303e5d 14427
77115a4a 14428 section->size = size;
59245841 14429 }
4a114e3e 14430
1b315056 14431 if (section->start == NULL)
32ec8896 14432 return FALSE;
1b315056 14433
19e6b90e 14434 if (debug_displays [debug].relocate)
32ec8896 14435 {
dda8d76d 14436 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896
NC
14437 & section->reloc_info, & section->num_relocs))
14438 return FALSE;
14439 }
d1c4b12b
NC
14440 else
14441 {
14442 section->reloc_info = NULL;
14443 section->num_relocs = 0;
14444 }
1007acb3 14445
32ec8896 14446 return TRUE;
1007acb3
L
14447}
14448
301a9420
AM
14449#if HAVE_LIBDEBUGINFOD
14450/* Return a hex string representation of the build-id. */
14451unsigned char *
14452get_build_id (void * data)
14453{
14454 Filedata * filedata = (Filedata *)data;
14455 Elf_Internal_Shdr * shdr;
14456 unsigned long i;
14457
55be8fd0
NC
14458 /* Iterate through notes to find note.gnu.build-id.
14459 FIXME: Only the first note in any note section is examined. */
301a9420
AM
14460 for (i = 0, shdr = filedata->section_headers;
14461 i < filedata->file_header.e_shnum && shdr != NULL;
14462 i++, shdr++)
14463 {
14464 if (shdr->sh_type != SHT_NOTE)
14465 continue;
14466
14467 char * next;
14468 char * end;
14469 size_t data_remaining;
14470 size_t min_notesz;
14471 Elf_External_Note * enote;
14472 Elf_Internal_Note inote;
14473
14474 bfd_vma offset = shdr->sh_offset;
14475 bfd_vma align = shdr->sh_addralign;
14476 bfd_vma length = shdr->sh_size;
14477
14478 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
14479 if (enote == NULL)
14480 continue;
14481
14482 if (align < 4)
14483 align = 4;
14484 else if (align != 4 && align != 8)
f761cb13
AM
14485 {
14486 free (enote);
14487 continue;
14488 }
301a9420
AM
14489
14490 end = (char *) enote + length;
14491 data_remaining = end - (char *) enote;
14492
14493 if (!is_ia64_vms (filedata))
14494 {
14495 min_notesz = offsetof (Elf_External_Note, name);
14496 if (data_remaining < min_notesz)
14497 {
55be8fd0
NC
14498 warn (_("\
14499malformed note encountered in section %s whilst scanning for build-id note\n"),
14500 printable_section_name (filedata, shdr));
f761cb13 14501 free (enote);
55be8fd0 14502 continue;
301a9420
AM
14503 }
14504 data_remaining -= min_notesz;
14505
14506 inote.type = BYTE_GET (enote->type);
14507 inote.namesz = BYTE_GET (enote->namesz);
14508 inote.namedata = enote->name;
14509 inote.descsz = BYTE_GET (enote->descsz);
14510 inote.descdata = ((char *) enote
14511 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
14512 inote.descpos = offset + (inote.descdata - (char *) enote);
14513 next = ((char *) enote
14514 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
14515 }
14516 else
14517 {
14518 Elf64_External_VMS_Note *vms_enote;
14519
14520 /* PR binutils/15191
14521 Make sure that there is enough data to read. */
14522 min_notesz = offsetof (Elf64_External_VMS_Note, name);
14523 if (data_remaining < min_notesz)
14524 {
55be8fd0
NC
14525 warn (_("\
14526malformed note encountered in section %s whilst scanning for build-id note\n"),
14527 printable_section_name (filedata, shdr));
f761cb13 14528 free (enote);
55be8fd0 14529 continue;
301a9420
AM
14530 }
14531 data_remaining -= min_notesz;
14532
14533 vms_enote = (Elf64_External_VMS_Note *) enote;
14534 inote.type = BYTE_GET (vms_enote->type);
14535 inote.namesz = BYTE_GET (vms_enote->namesz);
14536 inote.namedata = vms_enote->name;
14537 inote.descsz = BYTE_GET (vms_enote->descsz);
14538 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
14539 inote.descpos = offset + (inote.descdata - (char *) enote);
14540 next = inote.descdata + align_power (inote.descsz, 3);
14541 }
14542
14543 /* Skip malformed notes. */
14544 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
14545 || (size_t) (inote.descdata - inote.namedata) > data_remaining
14546 || (size_t) (next - inote.descdata) < inote.descsz
14547 || ((size_t) (next - inote.descdata)
14548 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
14549 {
55be8fd0
NC
14550 warn (_("\
14551malformed note encountered in section %s whilst scanning for build-id note\n"),
14552 printable_section_name (filedata, shdr));
f761cb13 14553 free (enote);
301a9420
AM
14554 continue;
14555 }
14556
14557 /* Check if this is the build-id note. If so then convert the build-id
14558 bytes to a hex string. */
14559 if (inote.namesz > 0
14560 && const_strneq (inote.namedata, "GNU")
14561 && inote.type == NT_GNU_BUILD_ID)
14562 {
14563 unsigned long j;
14564 char * build_id;
14565
14566 build_id = malloc (inote.descsz * 2 + 1);
14567 if (build_id == NULL)
f761cb13
AM
14568 {
14569 free (enote);
14570 return NULL;
14571 }
301a9420
AM
14572
14573 for (j = 0; j < inote.descsz; ++j)
14574 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
14575 build_id[inote.descsz * 2] = '\0';
f761cb13 14576 free (enote);
301a9420 14577
55be8fd0 14578 return (unsigned char *) build_id;
301a9420 14579 }
f761cb13 14580 free (enote);
301a9420
AM
14581 }
14582
14583 return NULL;
14584}
14585#endif /* HAVE_LIBDEBUGINFOD */
14586
657d0d47
CC
14587/* If this is not NULL, load_debug_section will only look for sections
14588 within the list of sections given here. */
32ec8896 14589static unsigned int * section_subset = NULL;
657d0d47 14590
32ec8896 14591bfd_boolean
dda8d76d 14592load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 14593{
2cf0635d
NC
14594 struct dwarf_section * section = &debug_displays [debug].section;
14595 Elf_Internal_Shdr * sec;
dda8d76d
NC
14596 Filedata * filedata = (Filedata *) data;
14597
f425ec66
NC
14598 /* Without section headers we cannot find any sections. */
14599 if (filedata->section_headers == NULL)
14600 return FALSE;
14601
9c1ce108
AM
14602 if (filedata->string_table == NULL
14603 && filedata->file_header.e_shstrndx != SHN_UNDEF
14604 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
14605 {
14606 Elf_Internal_Shdr * strs;
14607
14608 /* Read in the string table, so that we have section names to scan. */
14609 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
14610
4dff97b2 14611 if (strs != NULL && strs->sh_size != 0)
dda8d76d 14612 {
9c1ce108
AM
14613 filedata->string_table
14614 = (char *) get_data (NULL, filedata, strs->sh_offset,
14615 1, strs->sh_size, _("string table"));
dda8d76d 14616
9c1ce108
AM
14617 filedata->string_table_length
14618 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
14619 }
14620 }
d966045b
DJ
14621
14622 /* Locate the debug section. */
dda8d76d 14623 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
14624 if (sec != NULL)
14625 section->name = section->uncompressed_name;
14626 else
14627 {
dda8d76d 14628 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
14629 if (sec != NULL)
14630 section->name = section->compressed_name;
14631 }
14632 if (sec == NULL)
32ec8896 14633 return FALSE;
d966045b 14634
657d0d47
CC
14635 /* If we're loading from a subset of sections, and we've loaded
14636 a section matching this name before, it's likely that it's a
14637 different one. */
14638 if (section_subset != NULL)
14639 free_debug_section (debug);
14640
dda8d76d 14641 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
14642}
14643
19e6b90e
L
14644void
14645free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 14646{
2cf0635d 14647 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 14648
19e6b90e
L
14649 if (section->start == NULL)
14650 return;
1007acb3 14651
19e6b90e
L
14652 free ((char *) section->start);
14653 section->start = NULL;
14654 section->address = 0;
14655 section->size = 0;
a788aedd
AM
14656
14657 if (section->reloc_info != NULL)
14658 {
14659 free (section->reloc_info);
14660 section->reloc_info = NULL;
14661 section->num_relocs = 0;
14662 }
1007acb3
L
14663}
14664
32ec8896 14665static bfd_boolean
dda8d76d 14666display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 14667{
2cf0635d 14668 char * name = SECTION_NAME (section);
dda8d76d 14669 const char * print_name = printable_section_name (filedata, section);
19e6b90e 14670 bfd_size_type length;
32ec8896 14671 bfd_boolean result = TRUE;
3f5e193b 14672 int i;
1007acb3 14673
19e6b90e
L
14674 length = section->sh_size;
14675 if (length == 0)
1007acb3 14676 {
74e1a04b 14677 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
32ec8896 14678 return TRUE;
1007acb3 14679 }
5dff79d8
NC
14680 if (section->sh_type == SHT_NOBITS)
14681 {
14682 /* There is no point in dumping the contents of a debugging section
14683 which has the NOBITS type - the bits in the file will be random.
14684 This can happen when a file containing a .eh_frame section is
14685 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
14686 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
14687 print_name);
32ec8896 14688 return FALSE;
5dff79d8 14689 }
1007acb3 14690
0112cd26 14691 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 14692 name = ".debug_info";
1007acb3 14693
19e6b90e
L
14694 /* See if we know how to display the contents of this section. */
14695 for (i = 0; i < max; i++)
d85bf2ba
NC
14696 {
14697 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
14698 struct dwarf_section_display * display = debug_displays + i;
14699 struct dwarf_section * sec = & display->section;
d966045b 14700
d85bf2ba
NC
14701 if (streq (sec->uncompressed_name, name)
14702 || (id == line && const_strneq (name, ".debug_line."))
14703 || streq (sec->compressed_name, name))
14704 {
14705 bfd_boolean secondary = (section != find_section (filedata, name));
1007acb3 14706
d85bf2ba
NC
14707 if (secondary)
14708 free_debug_section (id);
dda8d76d 14709
d85bf2ba
NC
14710 if (i == line && const_strneq (name, ".debug_line."))
14711 sec->name = name;
14712 else if (streq (sec->uncompressed_name, name))
14713 sec->name = sec->uncompressed_name;
14714 else
14715 sec->name = sec->compressed_name;
657d0d47 14716
d85bf2ba
NC
14717 if (load_specific_debug_section (id, section, filedata))
14718 {
14719 /* If this debug section is part of a CU/TU set in a .dwp file,
14720 restrict load_debug_section to the sections in that set. */
14721 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 14722
d85bf2ba 14723 result &= display->display (sec, filedata);
657d0d47 14724
d85bf2ba 14725 section_subset = NULL;
1007acb3 14726
d85bf2ba
NC
14727 if (secondary || (id != info && id != abbrev))
14728 free_debug_section (id);
14729 }
14730 break;
14731 }
14732 }
1007acb3 14733
19e6b90e 14734 if (i == max)
1007acb3 14735 {
74e1a04b 14736 printf (_("Unrecognized debug section: %s\n"), print_name);
32ec8896 14737 result = FALSE;
1007acb3
L
14738 }
14739
19e6b90e 14740 return result;
5b18a4bc 14741}
103f02d3 14742
aef1f6d0
DJ
14743/* Set DUMP_SECTS for all sections where dumps were requested
14744 based on section name. */
14745
14746static void
dda8d76d 14747initialise_dumps_byname (Filedata * filedata)
aef1f6d0 14748{
2cf0635d 14749 struct dump_list_entry * cur;
aef1f6d0
DJ
14750
14751 for (cur = dump_sects_byname; cur; cur = cur->next)
14752 {
14753 unsigned int i;
32ec8896 14754 bfd_boolean any = FALSE;
aef1f6d0 14755
dda8d76d
NC
14756 for (i = 0; i < filedata->file_header.e_shnum; i++)
14757 if (streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 14758 {
6431e409 14759 request_dump_bynumber (&filedata->dump, i, cur->type);
32ec8896 14760 any = TRUE;
aef1f6d0
DJ
14761 }
14762
14763 if (!any)
14764 warn (_("Section '%s' was not dumped because it does not exist!\n"),
14765 cur->name);
14766 }
14767}
14768
32ec8896 14769static bfd_boolean
dda8d76d 14770process_section_contents (Filedata * filedata)
5b18a4bc 14771{
2cf0635d 14772 Elf_Internal_Shdr * section;
19e6b90e 14773 unsigned int i;
32ec8896 14774 bfd_boolean res = TRUE;
103f02d3 14775
19e6b90e 14776 if (! do_dump)
32ec8896 14777 return TRUE;
103f02d3 14778
dda8d76d 14779 initialise_dumps_byname (filedata);
aef1f6d0 14780
dda8d76d 14781 for (i = 0, section = filedata->section_headers;
6431e409 14782 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
14783 i++, section++)
14784 {
6431e409 14785 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 14786
19e6b90e 14787#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
14788 if (dump & DISASS_DUMP)
14789 {
14790 if (! disassemble_section (section, filedata))
14791 res = FALSE;
14792 }
19e6b90e 14793#endif
dda8d76d 14794 if (dump & HEX_DUMP)
32ec8896 14795 {
dda8d76d 14796 if (! dump_section_as_bytes (section, filedata, FALSE))
32ec8896
NC
14797 res = FALSE;
14798 }
103f02d3 14799
dda8d76d 14800 if (dump & RELOC_DUMP)
32ec8896 14801 {
dda8d76d 14802 if (! dump_section_as_bytes (section, filedata, TRUE))
32ec8896
NC
14803 res = FALSE;
14804 }
09c11c86 14805
dda8d76d 14806 if (dump & STRING_DUMP)
32ec8896 14807 {
dda8d76d 14808 if (! dump_section_as_strings (section, filedata))
32ec8896
NC
14809 res = FALSE;
14810 }
cf13d699 14811
dda8d76d 14812 if (dump & DEBUG_DUMP)
32ec8896 14813 {
dda8d76d 14814 if (! display_debug_section (i, section, filedata))
32ec8896
NC
14815 res = FALSE;
14816 }
7d9813f1
NA
14817
14818 if (dump & CTF_DUMP)
14819 {
14820 if (! dump_section_as_ctf (section, filedata))
14821 res = FALSE;
14822 }
5b18a4bc 14823 }
103f02d3 14824
19e6b90e
L
14825 /* Check to see if the user requested a
14826 dump of a section that does not exist. */
6431e409 14827 while (i < filedata->dump.num_dump_sects)
0ee3043f 14828 {
6431e409 14829 if (filedata->dump.dump_sects[i])
32ec8896
NC
14830 {
14831 warn (_("Section %d was not dumped because it does not exist!\n"), i);
14832 res = FALSE;
14833 }
0ee3043f
NC
14834 i++;
14835 }
32ec8896
NC
14836
14837 return res;
5b18a4bc 14838}
103f02d3 14839
5b18a4bc 14840static void
19e6b90e 14841process_mips_fpe_exception (int mask)
5b18a4bc 14842{
19e6b90e
L
14843 if (mask)
14844 {
32ec8896
NC
14845 bfd_boolean first = TRUE;
14846
19e6b90e 14847 if (mask & OEX_FPU_INEX)
32ec8896 14848 fputs ("INEX", stdout), first = FALSE;
19e6b90e 14849 if (mask & OEX_FPU_UFLO)
32ec8896 14850 printf ("%sUFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14851 if (mask & OEX_FPU_OFLO)
32ec8896 14852 printf ("%sOFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14853 if (mask & OEX_FPU_DIV0)
32ec8896 14854 printf ("%sDIV0", first ? "" : "|"), first = FALSE;
19e6b90e
L
14855 if (mask & OEX_FPU_INVAL)
14856 printf ("%sINVAL", first ? "" : "|");
14857 }
5b18a4bc 14858 else
19e6b90e 14859 fputs ("0", stdout);
5b18a4bc 14860}
103f02d3 14861
f6f0e17b
NC
14862/* Display's the value of TAG at location P. If TAG is
14863 greater than 0 it is assumed to be an unknown tag, and
14864 a message is printed to this effect. Otherwise it is
14865 assumed that a message has already been printed.
14866
14867 If the bottom bit of TAG is set it assumed to have a
14868 string value, otherwise it is assumed to have an integer
14869 value.
14870
14871 Returns an updated P pointing to the first unread byte
14872 beyond the end of TAG's value.
14873
14874 Reads at or beyond END will not be made. */
14875
14876static unsigned char *
60abdbed 14877display_tag_value (signed int tag,
f6f0e17b
NC
14878 unsigned char * p,
14879 const unsigned char * const end)
14880{
14881 unsigned long val;
14882
14883 if (tag > 0)
14884 printf (" Tag_unknown_%d: ", tag);
14885
14886 if (p >= end)
14887 {
4082ef84 14888 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
14889 }
14890 else if (tag & 1)
14891 {
071436c6
NC
14892 /* PR 17531 file: 027-19978-0.004. */
14893 size_t maxlen = (end - p) - 1;
14894
14895 putchar ('"');
4082ef84
NC
14896 if (maxlen > 0)
14897 {
14898 print_symbol ((int) maxlen, (const char *) p);
14899 p += strnlen ((char *) p, maxlen) + 1;
14900 }
14901 else
14902 {
14903 printf (_("<corrupt string tag>"));
14904 p = (unsigned char *) end;
14905 }
071436c6 14906 printf ("\"\n");
f6f0e17b
NC
14907 }
14908 else
14909 {
cd30bcef 14910 READ_ULEB (val, p, end);
f6f0e17b
NC
14911 printf ("%ld (0x%lx)\n", val, val);
14912 }
14913
4082ef84 14914 assert (p <= end);
f6f0e17b
NC
14915 return p;
14916}
14917
53a346d8
CZ
14918/* ARC ABI attributes section. */
14919
14920static unsigned char *
14921display_arc_attribute (unsigned char * p,
14922 const unsigned char * const end)
14923{
14924 unsigned int tag;
53a346d8
CZ
14925 unsigned int val;
14926
cd30bcef 14927 READ_ULEB (tag, p, end);
53a346d8
CZ
14928
14929 switch (tag)
14930 {
14931 case Tag_ARC_PCS_config:
cd30bcef 14932 READ_ULEB (val, p, end);
53a346d8
CZ
14933 printf (" Tag_ARC_PCS_config: ");
14934 switch (val)
14935 {
14936 case 0:
14937 printf (_("Absent/Non standard\n"));
14938 break;
14939 case 1:
14940 printf (_("Bare metal/mwdt\n"));
14941 break;
14942 case 2:
14943 printf (_("Bare metal/newlib\n"));
14944 break;
14945 case 3:
14946 printf (_("Linux/uclibc\n"));
14947 break;
14948 case 4:
14949 printf (_("Linux/glibc\n"));
14950 break;
14951 default:
14952 printf (_("Unknown\n"));
14953 break;
14954 }
14955 break;
14956
14957 case Tag_ARC_CPU_base:
cd30bcef 14958 READ_ULEB (val, p, end);
53a346d8
CZ
14959 printf (" Tag_ARC_CPU_base: ");
14960 switch (val)
14961 {
14962 default:
14963 case TAG_CPU_NONE:
14964 printf (_("Absent\n"));
14965 break;
14966 case TAG_CPU_ARC6xx:
14967 printf ("ARC6xx\n");
14968 break;
14969 case TAG_CPU_ARC7xx:
14970 printf ("ARC7xx\n");
14971 break;
14972 case TAG_CPU_ARCEM:
14973 printf ("ARCEM\n");
14974 break;
14975 case TAG_CPU_ARCHS:
14976 printf ("ARCHS\n");
14977 break;
14978 }
14979 break;
14980
14981 case Tag_ARC_CPU_variation:
cd30bcef 14982 READ_ULEB (val, p, end);
53a346d8
CZ
14983 printf (" Tag_ARC_CPU_variation: ");
14984 switch (val)
14985 {
14986 default:
14987 if (val > 0 && val < 16)
53a346d8 14988 printf ("Core%d\n", val);
d8cbc93b
JL
14989 else
14990 printf ("Unknown\n");
14991 break;
14992
53a346d8
CZ
14993 case 0:
14994 printf (_("Absent\n"));
14995 break;
14996 }
14997 break;
14998
14999 case Tag_ARC_CPU_name:
15000 printf (" Tag_ARC_CPU_name: ");
15001 p = display_tag_value (-1, p, end);
15002 break;
15003
15004 case Tag_ARC_ABI_rf16:
cd30bcef 15005 READ_ULEB (val, p, end);
53a346d8
CZ
15006 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
15007 break;
15008
15009 case Tag_ARC_ABI_osver:
cd30bcef 15010 READ_ULEB (val, p, end);
53a346d8
CZ
15011 printf (" Tag_ARC_ABI_osver: v%d\n", val);
15012 break;
15013
15014 case Tag_ARC_ABI_pic:
15015 case Tag_ARC_ABI_sda:
cd30bcef 15016 READ_ULEB (val, p, end);
53a346d8
CZ
15017 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
15018 : " Tag_ARC_ABI_pic: ");
15019 switch (val)
15020 {
15021 case 0:
15022 printf (_("Absent\n"));
15023 break;
15024 case 1:
15025 printf ("MWDT\n");
15026 break;
15027 case 2:
15028 printf ("GNU\n");
15029 break;
15030 default:
15031 printf (_("Unknown\n"));
15032 break;
15033 }
15034 break;
15035
15036 case Tag_ARC_ABI_tls:
cd30bcef 15037 READ_ULEB (val, p, end);
53a346d8
CZ
15038 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
15039 break;
15040
15041 case Tag_ARC_ABI_enumsize:
cd30bcef 15042 READ_ULEB (val, p, end);
53a346d8
CZ
15043 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
15044 _("smallest"));
15045 break;
15046
15047 case Tag_ARC_ABI_exceptions:
cd30bcef 15048 READ_ULEB (val, p, end);
53a346d8
CZ
15049 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
15050 : _("default"));
15051 break;
15052
15053 case Tag_ARC_ABI_double_size:
cd30bcef 15054 READ_ULEB (val, p, end);
53a346d8
CZ
15055 printf (" Tag_ARC_ABI_double_size: %d\n", val);
15056 break;
15057
15058 case Tag_ARC_ISA_config:
15059 printf (" Tag_ARC_ISA_config: ");
15060 p = display_tag_value (-1, p, end);
15061 break;
15062
15063 case Tag_ARC_ISA_apex:
15064 printf (" Tag_ARC_ISA_apex: ");
15065 p = display_tag_value (-1, p, end);
15066 break;
15067
15068 case Tag_ARC_ISA_mpy_option:
cd30bcef 15069 READ_ULEB (val, p, end);
53a346d8
CZ
15070 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
15071 break;
15072
db1e1b45 15073 case Tag_ARC_ATR_version:
cd30bcef 15074 READ_ULEB (val, p, end);
db1e1b45 15075 printf (" Tag_ARC_ATR_version: %d\n", val);
15076 break;
15077
53a346d8
CZ
15078 default:
15079 return display_tag_value (tag & 1, p, end);
15080 }
15081
15082 return p;
15083}
15084
11c1ff18
PB
15085/* ARM EABI attributes section. */
15086typedef struct
15087{
70e99720 15088 unsigned int tag;
2cf0635d 15089 const char * name;
11c1ff18 15090 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 15091 unsigned int type;
2cf0635d 15092 const char ** table;
11c1ff18
PB
15093} arm_attr_public_tag;
15094
2cf0635d 15095static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 15096 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 15097 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 15098 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
2cf0635d
NC
15099static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
15100static const char * arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 15101 {"No", "Thumb-1", "Thumb-2", "Yes"};
75375b3e 15102static const char * arm_attr_tag_FP_arch[] =
bca38921 15103 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 15104 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 15105static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 15106static const char * arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
15107 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
15108 "NEON for ARMv8.1"};
2cf0635d 15109static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
15110 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
15111 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 15112static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 15113 {"V6", "SB", "TLS", "Unused"};
2cf0635d 15114static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 15115 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 15116static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 15117 {"Absolute", "PC-relative", "None"};
2cf0635d 15118static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 15119 {"None", "direct", "GOT-indirect"};
2cf0635d 15120static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 15121 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
15122static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
15123static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 15124 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
15125static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
15126static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
15127static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 15128 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 15129static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 15130 {"Unused", "small", "int", "forced to int"};
2cf0635d 15131static const char * arm_attr_tag_ABI_HardFP_use[] =
99654aaf 15132 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
2cf0635d 15133static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 15134 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 15135static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 15136 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 15137static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
15138 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15139 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 15140static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
15141 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15142 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 15143static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 15144static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 15145 {"Not Allowed", "Allowed"};
2cf0635d 15146static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 15147 {"None", "IEEE 754", "Alternative Format"};
15afaa63
TP
15148static const char * arm_attr_tag_DSP_extension[] =
15149 {"Follow architecture", "Allowed"};
dd24e3da 15150static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
15151 {"Not Allowed", "Allowed"};
15152static const char * arm_attr_tag_DIV_use[] =
dd24e3da 15153 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 15154 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
15155static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
15156static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 15157 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 15158 "TrustZone and Virtualization Extensions"};
dd24e3da 15159static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 15160 {"Not Allowed", "Allowed"};
11c1ff18 15161
a7ad558c
AV
15162static const char * arm_attr_tag_MVE_arch[] =
15163 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
15164
11c1ff18
PB
15165#define LOOKUP(id, name) \
15166 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 15167static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
15168{
15169 {4, "CPU_raw_name", 1, NULL},
15170 {5, "CPU_name", 1, NULL},
15171 LOOKUP(6, CPU_arch),
15172 {7, "CPU_arch_profile", 0, NULL},
15173 LOOKUP(8, ARM_ISA_use),
15174 LOOKUP(9, THUMB_ISA_use),
75375b3e 15175 LOOKUP(10, FP_arch),
11c1ff18 15176 LOOKUP(11, WMMX_arch),
f5f53991
AS
15177 LOOKUP(12, Advanced_SIMD_arch),
15178 LOOKUP(13, PCS_config),
11c1ff18
PB
15179 LOOKUP(14, ABI_PCS_R9_use),
15180 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 15181 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
15182 LOOKUP(17, ABI_PCS_GOT_use),
15183 LOOKUP(18, ABI_PCS_wchar_t),
15184 LOOKUP(19, ABI_FP_rounding),
15185 LOOKUP(20, ABI_FP_denormal),
15186 LOOKUP(21, ABI_FP_exceptions),
15187 LOOKUP(22, ABI_FP_user_exceptions),
15188 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
15189 {24, "ABI_align_needed", 0, NULL},
15190 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
15191 LOOKUP(26, ABI_enum_size),
15192 LOOKUP(27, ABI_HardFP_use),
15193 LOOKUP(28, ABI_VFP_args),
15194 LOOKUP(29, ABI_WMMX_args),
15195 LOOKUP(30, ABI_optimization_goals),
15196 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 15197 {32, "compatibility", 0, NULL},
f5f53991 15198 LOOKUP(34, CPU_unaligned_access),
75375b3e 15199 LOOKUP(36, FP_HP_extension),
8e79c3df 15200 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
15201 LOOKUP(42, MPextension_use),
15202 LOOKUP(44, DIV_use),
15afaa63 15203 LOOKUP(46, DSP_extension),
a7ad558c 15204 LOOKUP(48, MVE_arch),
f5f53991
AS
15205 {64, "nodefaults", 0, NULL},
15206 {65, "also_compatible_with", 0, NULL},
15207 LOOKUP(66, T2EE_use),
15208 {67, "conformance", 1, NULL},
15209 LOOKUP(68, Virtualization_use),
cd21e546 15210 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
15211};
15212#undef LOOKUP
15213
11c1ff18 15214static unsigned char *
f6f0e17b
NC
15215display_arm_attribute (unsigned char * p,
15216 const unsigned char * const end)
11c1ff18 15217{
70e99720 15218 unsigned int tag;
70e99720 15219 unsigned int val;
2cf0635d 15220 arm_attr_public_tag * attr;
11c1ff18 15221 unsigned i;
70e99720 15222 unsigned int type;
11c1ff18 15223
cd30bcef 15224 READ_ULEB (tag, p, end);
11c1ff18 15225 attr = NULL;
2cf0635d 15226 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
15227 {
15228 if (arm_attr_public_tags[i].tag == tag)
15229 {
15230 attr = &arm_attr_public_tags[i];
15231 break;
15232 }
15233 }
15234
15235 if (attr)
15236 {
15237 printf (" Tag_%s: ", attr->name);
15238 switch (attr->type)
15239 {
15240 case 0:
15241 switch (tag)
15242 {
15243 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 15244 READ_ULEB (val, p, end);
11c1ff18
PB
15245 switch (val)
15246 {
2b692964
NC
15247 case 0: printf (_("None\n")); break;
15248 case 'A': printf (_("Application\n")); break;
15249 case 'R': printf (_("Realtime\n")); break;
15250 case 'M': printf (_("Microcontroller\n")); break;
15251 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
15252 default: printf ("??? (%d)\n", val); break;
15253 }
15254 break;
15255
75375b3e 15256 case 24: /* Tag_align_needed. */
cd30bcef 15257 READ_ULEB (val, p, end);
75375b3e
MGD
15258 switch (val)
15259 {
2b692964
NC
15260 case 0: printf (_("None\n")); break;
15261 case 1: printf (_("8-byte\n")); break;
15262 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
15263 case 3: printf ("??? 3\n"); break;
15264 default:
15265 if (val <= 12)
dd24e3da 15266 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15267 1 << val);
15268 else
15269 printf ("??? (%d)\n", val);
15270 break;
15271 }
15272 break;
15273
15274 case 25: /* Tag_align_preserved. */
cd30bcef 15275 READ_ULEB (val, p, end);
75375b3e
MGD
15276 switch (val)
15277 {
2b692964
NC
15278 case 0: printf (_("None\n")); break;
15279 case 1: printf (_("8-byte, except leaf SP\n")); break;
15280 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
15281 case 3: printf ("??? 3\n"); break;
15282 default:
15283 if (val <= 12)
dd24e3da 15284 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15285 1 << val);
15286 else
15287 printf ("??? (%d)\n", val);
15288 break;
15289 }
15290 break;
15291
11c1ff18 15292 case 32: /* Tag_compatibility. */
071436c6 15293 {
cd30bcef 15294 READ_ULEB (val, p, end);
071436c6 15295 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
15296 if (p < end - 1)
15297 {
15298 size_t maxlen = (end - p) - 1;
15299
15300 print_symbol ((int) maxlen, (const char *) p);
15301 p += strnlen ((char *) p, maxlen) + 1;
15302 }
15303 else
15304 {
15305 printf (_("<corrupt>"));
15306 p = (unsigned char *) end;
15307 }
071436c6 15308 putchar ('\n');
071436c6 15309 }
11c1ff18
PB
15310 break;
15311
f5f53991 15312 case 64: /* Tag_nodefaults. */
541a3cbd
NC
15313 /* PR 17531: file: 001-505008-0.01. */
15314 if (p < end)
15315 p++;
2b692964 15316 printf (_("True\n"));
f5f53991
AS
15317 break;
15318
15319 case 65: /* Tag_also_compatible_with. */
cd30bcef 15320 READ_ULEB (val, p, end);
f5f53991
AS
15321 if (val == 6 /* Tag_CPU_arch. */)
15322 {
cd30bcef 15323 READ_ULEB (val, p, end);
071436c6 15324 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
15325 printf ("??? (%d)\n", val);
15326 else
15327 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
15328 }
15329 else
15330 printf ("???\n");
071436c6
NC
15331 while (p < end && *(p++) != '\0' /* NUL terminator. */)
15332 ;
f5f53991
AS
15333 break;
15334
11c1ff18 15335 default:
bee0ee85
NC
15336 printf (_("<unknown: %d>\n"), tag);
15337 break;
11c1ff18
PB
15338 }
15339 return p;
15340
15341 case 1:
f6f0e17b 15342 return display_tag_value (-1, p, end);
11c1ff18 15343 case 2:
f6f0e17b 15344 return display_tag_value (0, p, end);
11c1ff18
PB
15345
15346 default:
15347 assert (attr->type & 0x80);
cd30bcef 15348 READ_ULEB (val, p, end);
11c1ff18
PB
15349 type = attr->type & 0x7f;
15350 if (val >= type)
15351 printf ("??? (%d)\n", val);
15352 else
15353 printf ("%s\n", attr->table[val]);
15354 return p;
15355 }
15356 }
11c1ff18 15357
f6f0e17b 15358 return display_tag_value (tag, p, end);
11c1ff18
PB
15359}
15360
104d59d1 15361static unsigned char *
60bca95a 15362display_gnu_attribute (unsigned char * p,
60abdbed 15363 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 15364 const unsigned char * const end)
104d59d1 15365{
cd30bcef 15366 unsigned int tag;
60abdbed 15367 unsigned int val;
104d59d1 15368
cd30bcef 15369 READ_ULEB (tag, p, end);
104d59d1
JM
15370
15371 /* Tag_compatibility is the only generic GNU attribute defined at
15372 present. */
15373 if (tag == 32)
15374 {
cd30bcef 15375 READ_ULEB (val, p, end);
071436c6
NC
15376
15377 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
15378 if (p == end)
15379 {
071436c6 15380 printf (_("<corrupt>\n"));
f6f0e17b
NC
15381 warn (_("corrupt vendor attribute\n"));
15382 }
15383 else
15384 {
4082ef84
NC
15385 if (p < end - 1)
15386 {
15387 size_t maxlen = (end - p) - 1;
071436c6 15388
4082ef84
NC
15389 print_symbol ((int) maxlen, (const char *) p);
15390 p += strnlen ((char *) p, maxlen) + 1;
15391 }
15392 else
15393 {
15394 printf (_("<corrupt>"));
15395 p = (unsigned char *) end;
15396 }
071436c6 15397 putchar ('\n');
f6f0e17b 15398 }
104d59d1
JM
15399 return p;
15400 }
15401
15402 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 15403 return display_proc_gnu_attribute (p, tag, end);
104d59d1 15404
f6f0e17b 15405 return display_tag_value (tag, p, end);
104d59d1
JM
15406}
15407
34c8bcba 15408static unsigned char *
f6f0e17b 15409display_power_gnu_attribute (unsigned char * p,
60abdbed 15410 unsigned int tag,
f6f0e17b 15411 const unsigned char * const end)
34c8bcba 15412{
005d79fd 15413 unsigned int val;
34c8bcba
JM
15414
15415 if (tag == Tag_GNU_Power_ABI_FP)
15416 {
34c8bcba 15417 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 15418 if (p == end)
005d79fd
AM
15419 {
15420 printf (_("<corrupt>\n"));
15421 return p;
15422 }
cd30bcef 15423 READ_ULEB (val, p, end);
60bca95a 15424
005d79fd
AM
15425 if (val > 15)
15426 printf ("(%#x), ", val);
15427
15428 switch (val & 3)
34c8bcba
JM
15429 {
15430 case 0:
005d79fd 15431 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
15432 break;
15433 case 1:
005d79fd 15434 printf (_("hard float, "));
34c8bcba
JM
15435 break;
15436 case 2:
005d79fd 15437 printf (_("soft float, "));
34c8bcba 15438 break;
3c7b9897 15439 case 3:
005d79fd 15440 printf (_("single-precision hard float, "));
3c7b9897 15441 break;
005d79fd
AM
15442 }
15443
15444 switch (val & 0xC)
15445 {
15446 case 0:
15447 printf (_("unspecified long double\n"));
15448 break;
15449 case 4:
15450 printf (_("128-bit IBM long double\n"));
15451 break;
15452 case 8:
15453 printf (_("64-bit long double\n"));
15454 break;
15455 case 12:
15456 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
15457 break;
15458 }
15459 return p;
005d79fd 15460 }
34c8bcba 15461
c6e65352
DJ
15462 if (tag == Tag_GNU_Power_ABI_Vector)
15463 {
c6e65352 15464 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 15465 if (p == end)
005d79fd
AM
15466 {
15467 printf (_("<corrupt>\n"));
15468 return p;
15469 }
cd30bcef 15470 READ_ULEB (val, p, end);
005d79fd
AM
15471
15472 if (val > 3)
15473 printf ("(%#x), ", val);
15474
15475 switch (val & 3)
c6e65352
DJ
15476 {
15477 case 0:
005d79fd 15478 printf (_("unspecified\n"));
c6e65352
DJ
15479 break;
15480 case 1:
005d79fd 15481 printf (_("generic\n"));
c6e65352
DJ
15482 break;
15483 case 2:
15484 printf ("AltiVec\n");
15485 break;
15486 case 3:
15487 printf ("SPE\n");
15488 break;
c6e65352
DJ
15489 }
15490 return p;
005d79fd 15491 }
c6e65352 15492
f82e0623
NF
15493 if (tag == Tag_GNU_Power_ABI_Struct_Return)
15494 {
005d79fd 15495 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 15496 if (p == end)
f6f0e17b 15497 {
005d79fd 15498 printf (_("<corrupt>\n"));
f6f0e17b
NC
15499 return p;
15500 }
cd30bcef 15501 READ_ULEB (val, p, end);
0b4362b0 15502
005d79fd
AM
15503 if (val > 2)
15504 printf ("(%#x), ", val);
15505
15506 switch (val & 3)
15507 {
15508 case 0:
15509 printf (_("unspecified\n"));
15510 break;
15511 case 1:
15512 printf ("r3/r4\n");
15513 break;
15514 case 2:
15515 printf (_("memory\n"));
15516 break;
15517 case 3:
15518 printf ("???\n");
15519 break;
15520 }
f82e0623
NF
15521 return p;
15522 }
15523
f6f0e17b 15524 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
15525}
15526
643f7afb
AK
15527static unsigned char *
15528display_s390_gnu_attribute (unsigned char * p,
60abdbed 15529 unsigned int tag,
643f7afb
AK
15530 const unsigned char * const end)
15531{
cd30bcef 15532 unsigned int val;
643f7afb
AK
15533
15534 if (tag == Tag_GNU_S390_ABI_Vector)
15535 {
643f7afb 15536 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 15537 READ_ULEB (val, p, end);
643f7afb
AK
15538
15539 switch (val)
15540 {
15541 case 0:
15542 printf (_("any\n"));
15543 break;
15544 case 1:
15545 printf (_("software\n"));
15546 break;
15547 case 2:
15548 printf (_("hardware\n"));
15549 break;
15550 default:
15551 printf ("??? (%d)\n", val);
15552 break;
15553 }
15554 return p;
15555 }
15556
15557 return display_tag_value (tag & 1, p, end);
15558}
15559
9e8c70f9 15560static void
60abdbed 15561display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
15562{
15563 if (mask)
15564 {
32ec8896 15565 bfd_boolean first = TRUE;
071436c6 15566
9e8c70f9 15567 if (mask & ELF_SPARC_HWCAP_MUL32)
32ec8896 15568 fputs ("mul32", stdout), first = FALSE;
9e8c70f9 15569 if (mask & ELF_SPARC_HWCAP_DIV32)
32ec8896 15570 printf ("%sdiv32", first ? "" : "|"), first = FALSE;
9e8c70f9 15571 if (mask & ELF_SPARC_HWCAP_FSMULD)
32ec8896 15572 printf ("%sfsmuld", first ? "" : "|"), first = FALSE;
9e8c70f9 15573 if (mask & ELF_SPARC_HWCAP_V8PLUS)
32ec8896 15574 printf ("%sv8plus", first ? "" : "|"), first = FALSE;
9e8c70f9 15575 if (mask & ELF_SPARC_HWCAP_POPC)
32ec8896 15576 printf ("%spopc", first ? "" : "|"), first = FALSE;
9e8c70f9 15577 if (mask & ELF_SPARC_HWCAP_VIS)
32ec8896 15578 printf ("%svis", first ? "" : "|"), first = FALSE;
9e8c70f9 15579 if (mask & ELF_SPARC_HWCAP_VIS2)
32ec8896 15580 printf ("%svis2", first ? "" : "|"), first = FALSE;
9e8c70f9 15581 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
32ec8896 15582 printf ("%sASIBlkInit", first ? "" : "|"), first = FALSE;
9e8c70f9 15583 if (mask & ELF_SPARC_HWCAP_FMAF)
32ec8896 15584 printf ("%sfmaf", first ? "" : "|"), first = FALSE;
9e8c70f9 15585 if (mask & ELF_SPARC_HWCAP_VIS3)
32ec8896 15586 printf ("%svis3", first ? "" : "|"), first = FALSE;
9e8c70f9 15587 if (mask & ELF_SPARC_HWCAP_HPC)
32ec8896 15588 printf ("%shpc", first ? "" : "|"), first = FALSE;
9e8c70f9 15589 if (mask & ELF_SPARC_HWCAP_RANDOM)
32ec8896 15590 printf ("%srandom", first ? "" : "|"), first = FALSE;
9e8c70f9 15591 if (mask & ELF_SPARC_HWCAP_TRANS)
32ec8896 15592 printf ("%strans", first ? "" : "|"), first = FALSE;
9e8c70f9 15593 if (mask & ELF_SPARC_HWCAP_FJFMAU)
32ec8896 15594 printf ("%sfjfmau", first ? "" : "|"), first = FALSE;
9e8c70f9 15595 if (mask & ELF_SPARC_HWCAP_IMA)
32ec8896 15596 printf ("%sima", first ? "" : "|"), first = FALSE;
9e8c70f9 15597 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
32ec8896 15598 printf ("%scspare", first ? "" : "|"), first = FALSE;
9e8c70f9
DM
15599 }
15600 else
071436c6
NC
15601 fputc ('0', stdout);
15602 fputc ('\n', stdout);
9e8c70f9
DM
15603}
15604
3d68f91c 15605static void
60abdbed 15606display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
15607{
15608 if (mask)
15609 {
32ec8896 15610 bfd_boolean first = TRUE;
071436c6 15611
3d68f91c 15612 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
32ec8896 15613 fputs ("fjathplus", stdout), first = FALSE;
3d68f91c 15614 if (mask & ELF_SPARC_HWCAP2_VIS3B)
32ec8896 15615 printf ("%svis3b", first ? "" : "|"), first = FALSE;
3d68f91c 15616 if (mask & ELF_SPARC_HWCAP2_ADP)
32ec8896 15617 printf ("%sadp", first ? "" : "|"), first = FALSE;
3d68f91c 15618 if (mask & ELF_SPARC_HWCAP2_SPARC5)
32ec8896 15619 printf ("%ssparc5", first ? "" : "|"), first = FALSE;
3d68f91c 15620 if (mask & ELF_SPARC_HWCAP2_MWAIT)
32ec8896 15621 printf ("%smwait", first ? "" : "|"), first = FALSE;
3d68f91c 15622 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
32ec8896 15623 printf ("%sxmpmul", first ? "" : "|"), first = FALSE;
3d68f91c 15624 if (mask & ELF_SPARC_HWCAP2_XMONT)
32ec8896 15625 printf ("%sxmont2", first ? "" : "|"), first = FALSE;
3d68f91c 15626 if (mask & ELF_SPARC_HWCAP2_NSEC)
32ec8896 15627 printf ("%snsec", first ? "" : "|"), first = FALSE;
3d68f91c 15628 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
32ec8896 15629 printf ("%sfjathhpc", first ? "" : "|"), first = FALSE;
3d68f91c 15630 if (mask & ELF_SPARC_HWCAP2_FJDES)
32ec8896 15631 printf ("%sfjdes", first ? "" : "|"), first = FALSE;
3d68f91c 15632 if (mask & ELF_SPARC_HWCAP2_FJAES)
32ec8896 15633 printf ("%sfjaes", first ? "" : "|"), first = FALSE;
3d68f91c
JM
15634 }
15635 else
071436c6
NC
15636 fputc ('0', stdout);
15637 fputc ('\n', stdout);
3d68f91c
JM
15638}
15639
9e8c70f9 15640static unsigned char *
f6f0e17b 15641display_sparc_gnu_attribute (unsigned char * p,
60abdbed 15642 unsigned int tag,
f6f0e17b 15643 const unsigned char * const end)
9e8c70f9 15644{
cd30bcef 15645 unsigned int val;
3d68f91c 15646
9e8c70f9
DM
15647 if (tag == Tag_GNU_Sparc_HWCAPS)
15648 {
cd30bcef 15649 READ_ULEB (val, p, end);
9e8c70f9 15650 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
15651 display_sparc_hwcaps (val);
15652 return p;
3d68f91c
JM
15653 }
15654 if (tag == Tag_GNU_Sparc_HWCAPS2)
15655 {
cd30bcef 15656 READ_ULEB (val, p, end);
3d68f91c
JM
15657 printf (" Tag_GNU_Sparc_HWCAPS2: ");
15658 display_sparc_hwcaps2 (val);
15659 return p;
15660 }
9e8c70f9 15661
f6f0e17b 15662 return display_tag_value (tag, p, end);
9e8c70f9
DM
15663}
15664
351cdf24 15665static void
32ec8896 15666print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
15667{
15668 switch (val)
15669 {
15670 case Val_GNU_MIPS_ABI_FP_ANY:
15671 printf (_("Hard or soft float\n"));
15672 break;
15673 case Val_GNU_MIPS_ABI_FP_DOUBLE:
15674 printf (_("Hard float (double precision)\n"));
15675 break;
15676 case Val_GNU_MIPS_ABI_FP_SINGLE:
15677 printf (_("Hard float (single precision)\n"));
15678 break;
15679 case Val_GNU_MIPS_ABI_FP_SOFT:
15680 printf (_("Soft float\n"));
15681 break;
15682 case Val_GNU_MIPS_ABI_FP_OLD_64:
15683 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
15684 break;
15685 case Val_GNU_MIPS_ABI_FP_XX:
15686 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
15687 break;
15688 case Val_GNU_MIPS_ABI_FP_64:
15689 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
15690 break;
15691 case Val_GNU_MIPS_ABI_FP_64A:
15692 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
15693 break;
3350cc01
CM
15694 case Val_GNU_MIPS_ABI_FP_NAN2008:
15695 printf (_("NaN 2008 compatibility\n"));
15696 break;
351cdf24
MF
15697 default:
15698 printf ("??? (%d)\n", val);
15699 break;
15700 }
15701}
15702
2cf19d5c 15703static unsigned char *
f6f0e17b 15704display_mips_gnu_attribute (unsigned char * p,
60abdbed 15705 unsigned int tag,
f6f0e17b 15706 const unsigned char * const end)
2cf19d5c 15707{
2cf19d5c
JM
15708 if (tag == Tag_GNU_MIPS_ABI_FP)
15709 {
32ec8896 15710 unsigned int val;
f6f0e17b 15711
2cf19d5c 15712 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 15713 READ_ULEB (val, p, end);
351cdf24 15714 print_mips_fp_abi_value (val);
2cf19d5c
JM
15715 return p;
15716 }
15717
a9f58168
CF
15718 if (tag == Tag_GNU_MIPS_ABI_MSA)
15719 {
32ec8896 15720 unsigned int val;
a9f58168 15721
a9f58168 15722 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 15723 READ_ULEB (val, p, end);
a9f58168
CF
15724
15725 switch (val)
15726 {
15727 case Val_GNU_MIPS_ABI_MSA_ANY:
15728 printf (_("Any MSA or not\n"));
15729 break;
15730 case Val_GNU_MIPS_ABI_MSA_128:
15731 printf (_("128-bit MSA\n"));
15732 break;
15733 default:
15734 printf ("??? (%d)\n", val);
15735 break;
15736 }
15737 return p;
15738 }
15739
f6f0e17b 15740 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
15741}
15742
59e6276b 15743static unsigned char *
f6f0e17b
NC
15744display_tic6x_attribute (unsigned char * p,
15745 const unsigned char * const end)
59e6276b 15746{
60abdbed 15747 unsigned int tag;
cd30bcef 15748 unsigned int val;
59e6276b 15749
cd30bcef 15750 READ_ULEB (tag, p, end);
59e6276b
JM
15751
15752 switch (tag)
15753 {
75fa6dc1 15754 case Tag_ISA:
75fa6dc1 15755 printf (" Tag_ISA: ");
cd30bcef 15756 READ_ULEB (val, p, end);
59e6276b
JM
15757
15758 switch (val)
15759 {
75fa6dc1 15760 case C6XABI_Tag_ISA_none:
59e6276b
JM
15761 printf (_("None\n"));
15762 break;
75fa6dc1 15763 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
15764 printf ("C62x\n");
15765 break;
75fa6dc1 15766 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
15767 printf ("C67x\n");
15768 break;
75fa6dc1 15769 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
15770 printf ("C67x+\n");
15771 break;
75fa6dc1 15772 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
15773 printf ("C64x\n");
15774 break;
75fa6dc1 15775 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
15776 printf ("C64x+\n");
15777 break;
75fa6dc1 15778 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
15779 printf ("C674x\n");
15780 break;
15781 default:
15782 printf ("??? (%d)\n", val);
15783 break;
15784 }
15785 return p;
15786
87779176 15787 case Tag_ABI_wchar_t:
87779176 15788 printf (" Tag_ABI_wchar_t: ");
cd30bcef 15789 READ_ULEB (val, p, end);
87779176
JM
15790 switch (val)
15791 {
15792 case 0:
15793 printf (_("Not used\n"));
15794 break;
15795 case 1:
15796 printf (_("2 bytes\n"));
15797 break;
15798 case 2:
15799 printf (_("4 bytes\n"));
15800 break;
15801 default:
15802 printf ("??? (%d)\n", val);
15803 break;
15804 }
15805 return p;
15806
15807 case Tag_ABI_stack_align_needed:
87779176 15808 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 15809 READ_ULEB (val, p, end);
87779176
JM
15810 switch (val)
15811 {
15812 case 0:
15813 printf (_("8-byte\n"));
15814 break;
15815 case 1:
15816 printf (_("16-byte\n"));
15817 break;
15818 default:
15819 printf ("??? (%d)\n", val);
15820 break;
15821 }
15822 return p;
15823
15824 case Tag_ABI_stack_align_preserved:
cd30bcef 15825 READ_ULEB (val, p, end);
87779176
JM
15826 printf (" Tag_ABI_stack_align_preserved: ");
15827 switch (val)
15828 {
15829 case 0:
15830 printf (_("8-byte\n"));
15831 break;
15832 case 1:
15833 printf (_("16-byte\n"));
15834 break;
15835 default:
15836 printf ("??? (%d)\n", val);
15837 break;
15838 }
15839 return p;
15840
b5593623 15841 case Tag_ABI_DSBT:
cd30bcef 15842 READ_ULEB (val, p, end);
b5593623
JM
15843 printf (" Tag_ABI_DSBT: ");
15844 switch (val)
15845 {
15846 case 0:
15847 printf (_("DSBT addressing not used\n"));
15848 break;
15849 case 1:
15850 printf (_("DSBT addressing used\n"));
15851 break;
15852 default:
15853 printf ("??? (%d)\n", val);
15854 break;
15855 }
15856 return p;
15857
87779176 15858 case Tag_ABI_PID:
cd30bcef 15859 READ_ULEB (val, p, end);
87779176
JM
15860 printf (" Tag_ABI_PID: ");
15861 switch (val)
15862 {
15863 case 0:
15864 printf (_("Data addressing position-dependent\n"));
15865 break;
15866 case 1:
15867 printf (_("Data addressing position-independent, GOT near DP\n"));
15868 break;
15869 case 2:
15870 printf (_("Data addressing position-independent, GOT far from DP\n"));
15871 break;
15872 default:
15873 printf ("??? (%d)\n", val);
15874 break;
15875 }
15876 return p;
15877
15878 case Tag_ABI_PIC:
cd30bcef 15879 READ_ULEB (val, p, end);
87779176
JM
15880 printf (" Tag_ABI_PIC: ");
15881 switch (val)
15882 {
15883 case 0:
15884 printf (_("Code addressing position-dependent\n"));
15885 break;
15886 case 1:
15887 printf (_("Code addressing position-independent\n"));
15888 break;
15889 default:
15890 printf ("??? (%d)\n", val);
15891 break;
15892 }
15893 return p;
15894
15895 case Tag_ABI_array_object_alignment:
cd30bcef 15896 READ_ULEB (val, p, end);
87779176
JM
15897 printf (" Tag_ABI_array_object_alignment: ");
15898 switch (val)
15899 {
15900 case 0:
15901 printf (_("8-byte\n"));
15902 break;
15903 case 1:
15904 printf (_("4-byte\n"));
15905 break;
15906 case 2:
15907 printf (_("16-byte\n"));
15908 break;
15909 default:
15910 printf ("??? (%d)\n", val);
15911 break;
15912 }
15913 return p;
15914
15915 case Tag_ABI_array_object_align_expected:
cd30bcef 15916 READ_ULEB (val, p, end);
87779176
JM
15917 printf (" Tag_ABI_array_object_align_expected: ");
15918 switch (val)
15919 {
15920 case 0:
15921 printf (_("8-byte\n"));
15922 break;
15923 case 1:
15924 printf (_("4-byte\n"));
15925 break;
15926 case 2:
15927 printf (_("16-byte\n"));
15928 break;
15929 default:
15930 printf ("??? (%d)\n", val);
15931 break;
15932 }
15933 return p;
15934
3cbd1c06 15935 case Tag_ABI_compatibility:
071436c6 15936 {
cd30bcef 15937 READ_ULEB (val, p, end);
071436c6 15938 printf (" Tag_ABI_compatibility: ");
071436c6 15939 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
15940 if (p < end - 1)
15941 {
15942 size_t maxlen = (end - p) - 1;
15943
15944 print_symbol ((int) maxlen, (const char *) p);
15945 p += strnlen ((char *) p, maxlen) + 1;
15946 }
15947 else
15948 {
15949 printf (_("<corrupt>"));
15950 p = (unsigned char *) end;
15951 }
071436c6 15952 putchar ('\n');
071436c6
NC
15953 return p;
15954 }
87779176
JM
15955
15956 case Tag_ABI_conformance:
071436c6 15957 {
4082ef84
NC
15958 printf (" Tag_ABI_conformance: \"");
15959 if (p < end - 1)
15960 {
15961 size_t maxlen = (end - p) - 1;
071436c6 15962
4082ef84
NC
15963 print_symbol ((int) maxlen, (const char *) p);
15964 p += strnlen ((char *) p, maxlen) + 1;
15965 }
15966 else
15967 {
15968 printf (_("<corrupt>"));
15969 p = (unsigned char *) end;
15970 }
071436c6 15971 printf ("\"\n");
071436c6
NC
15972 return p;
15973 }
59e6276b
JM
15974 }
15975
f6f0e17b
NC
15976 return display_tag_value (tag, p, end);
15977}
59e6276b 15978
f6f0e17b 15979static void
60abdbed 15980display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
15981{
15982 unsigned long addr = 0;
15983 size_t bytes = end - p;
15984
feceaa59 15985 assert (end >= p);
f6f0e17b 15986 while (bytes)
87779176 15987 {
f6f0e17b
NC
15988 int j;
15989 int k;
15990 int lbytes = (bytes > 16 ? 16 : bytes);
15991
15992 printf (" 0x%8.8lx ", addr);
15993
15994 for (j = 0; j < 16; j++)
15995 {
15996 if (j < lbytes)
15997 printf ("%2.2x", p[j]);
15998 else
15999 printf (" ");
16000
16001 if ((j & 3) == 3)
16002 printf (" ");
16003 }
16004
16005 for (j = 0; j < lbytes; j++)
16006 {
16007 k = p[j];
16008 if (k >= ' ' && k < 0x7f)
16009 printf ("%c", k);
16010 else
16011 printf (".");
16012 }
16013
16014 putchar ('\n');
16015
16016 p += lbytes;
16017 bytes -= lbytes;
16018 addr += lbytes;
87779176 16019 }
59e6276b 16020
f6f0e17b 16021 putchar ('\n');
59e6276b
JM
16022}
16023
13761a11
NC
16024static unsigned char *
16025display_msp430x_attribute (unsigned char * p,
16026 const unsigned char * const end)
16027{
60abdbed
NC
16028 unsigned int val;
16029 unsigned int tag;
13761a11 16030
cd30bcef 16031 READ_ULEB (tag, p, end);
0b4362b0 16032
13761a11
NC
16033 switch (tag)
16034 {
16035 case OFBA_MSPABI_Tag_ISA:
13761a11 16036 printf (" Tag_ISA: ");
cd30bcef 16037 READ_ULEB (val, p, end);
13761a11
NC
16038 switch (val)
16039 {
16040 case 0: printf (_("None\n")); break;
16041 case 1: printf (_("MSP430\n")); break;
16042 case 2: printf (_("MSP430X\n")); break;
16043 default: printf ("??? (%d)\n", val); break;
16044 }
16045 break;
16046
16047 case OFBA_MSPABI_Tag_Code_Model:
13761a11 16048 printf (" Tag_Code_Model: ");
cd30bcef 16049 READ_ULEB (val, p, end);
13761a11
NC
16050 switch (val)
16051 {
16052 case 0: printf (_("None\n")); break;
16053 case 1: printf (_("Small\n")); break;
16054 case 2: printf (_("Large\n")); break;
16055 default: printf ("??? (%d)\n", val); break;
16056 }
16057 break;
16058
16059 case OFBA_MSPABI_Tag_Data_Model:
13761a11 16060 printf (" Tag_Data_Model: ");
cd30bcef 16061 READ_ULEB (val, p, end);
13761a11
NC
16062 switch (val)
16063 {
16064 case 0: printf (_("None\n")); break;
16065 case 1: printf (_("Small\n")); break;
16066 case 2: printf (_("Large\n")); break;
16067 case 3: printf (_("Restricted Large\n")); break;
16068 default: printf ("??? (%d)\n", val); break;
16069 }
16070 break;
16071
16072 default:
16073 printf (_(" <unknown tag %d>: "), tag);
16074
16075 if (tag & 1)
16076 {
071436c6 16077 putchar ('"');
4082ef84
NC
16078 if (p < end - 1)
16079 {
16080 size_t maxlen = (end - p) - 1;
16081
16082 print_symbol ((int) maxlen, (const char *) p);
16083 p += strnlen ((char *) p, maxlen) + 1;
16084 }
16085 else
16086 {
16087 printf (_("<corrupt>"));
16088 p = (unsigned char *) end;
16089 }
071436c6 16090 printf ("\"\n");
13761a11
NC
16091 }
16092 else
16093 {
cd30bcef 16094 READ_ULEB (val, p, end);
13761a11
NC
16095 printf ("%d (0x%x)\n", val, val);
16096 }
16097 break;
16098 }
16099
4082ef84 16100 assert (p <= end);
13761a11
NC
16101 return p;
16102}
16103
c0ea7c52
JL
16104static unsigned char *
16105display_msp430_gnu_attribute (unsigned char * p,
16106 unsigned int tag,
16107 const unsigned char * const end)
16108{
16109 if (tag == Tag_GNU_MSP430_Data_Region)
16110 {
cd30bcef 16111 unsigned int val;
c0ea7c52 16112
c0ea7c52 16113 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 16114 READ_ULEB (val, p, end);
c0ea7c52
JL
16115
16116 switch (val)
16117 {
16118 case Val_GNU_MSP430_Data_Region_Any:
16119 printf (_("Any Region\n"));
16120 break;
16121 case Val_GNU_MSP430_Data_Region_Lower:
16122 printf (_("Lower Region Only\n"));
16123 break;
16124 default:
cd30bcef 16125 printf ("??? (%u)\n", val);
c0ea7c52
JL
16126 }
16127 return p;
16128 }
16129 return display_tag_value (tag & 1, p, end);
16130}
16131
2dc8dd17
JW
16132struct riscv_attr_tag_t {
16133 const char *name;
cd30bcef 16134 unsigned int tag;
2dc8dd17
JW
16135};
16136
16137static struct riscv_attr_tag_t riscv_attr_tag[] =
16138{
16139#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
16140 T(arch),
16141 T(priv_spec),
16142 T(priv_spec_minor),
16143 T(priv_spec_revision),
16144 T(unaligned_access),
16145 T(stack_align),
16146#undef T
16147};
16148
16149static unsigned char *
16150display_riscv_attribute (unsigned char *p,
16151 const unsigned char * const end)
16152{
cd30bcef
AM
16153 unsigned int val;
16154 unsigned int tag;
2dc8dd17
JW
16155 struct riscv_attr_tag_t *attr = NULL;
16156 unsigned i;
16157
cd30bcef 16158 READ_ULEB (tag, p, end);
2dc8dd17
JW
16159
16160 /* Find the name of attribute. */
16161 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
16162 {
16163 if (riscv_attr_tag[i].tag == tag)
16164 {
16165 attr = &riscv_attr_tag[i];
16166 break;
16167 }
16168 }
16169
16170 if (attr)
16171 printf (" %s: ", attr->name);
16172 else
16173 return display_tag_value (tag, p, end);
16174
16175 switch (tag)
16176 {
16177 case Tag_RISCV_priv_spec:
16178 case Tag_RISCV_priv_spec_minor:
16179 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
16180 READ_ULEB (val, p, end);
16181 printf (_("%u\n"), val);
2dc8dd17
JW
16182 break;
16183 case Tag_RISCV_unaligned_access:
cd30bcef 16184 READ_ULEB (val, p, end);
2dc8dd17
JW
16185 switch (val)
16186 {
16187 case 0:
16188 printf (_("No unaligned access\n"));
16189 break;
16190 case 1:
16191 printf (_("Unaligned access\n"));
16192 break;
16193 }
16194 break;
16195 case Tag_RISCV_stack_align:
cd30bcef
AM
16196 READ_ULEB (val, p, end);
16197 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
16198 break;
16199 case Tag_RISCV_arch:
16200 p = display_tag_value (-1, p, end);
16201 break;
16202 default:
16203 return display_tag_value (tag, p, end);
16204 }
16205
16206 return p;
16207}
16208
32ec8896 16209static bfd_boolean
dda8d76d 16210process_attributes (Filedata * filedata,
60bca95a 16211 const char * public_name,
104d59d1 16212 unsigned int proc_type,
f6f0e17b 16213 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 16214 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 16215{
2cf0635d 16216 Elf_Internal_Shdr * sect;
11c1ff18 16217 unsigned i;
32ec8896 16218 bfd_boolean res = TRUE;
11c1ff18
PB
16219
16220 /* Find the section header so that we get the size. */
dda8d76d
NC
16221 for (i = 0, sect = filedata->section_headers;
16222 i < filedata->file_header.e_shnum;
11c1ff18
PB
16223 i++, sect++)
16224 {
071436c6
NC
16225 unsigned char * contents;
16226 unsigned char * p;
16227
104d59d1 16228 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
16229 continue;
16230
dda8d76d 16231 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 16232 sect->sh_size, _("attributes"));
60bca95a 16233 if (contents == NULL)
32ec8896
NC
16234 {
16235 res = FALSE;
16236 continue;
16237 }
60bca95a 16238
11c1ff18 16239 p = contents;
60abdbed
NC
16240 /* The first character is the version of the attributes.
16241 Currently only version 1, (aka 'A') is recognised here. */
16242 if (*p != 'A')
32ec8896
NC
16243 {
16244 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
16245 res = FALSE;
16246 }
60abdbed 16247 else
11c1ff18 16248 {
071436c6
NC
16249 bfd_vma section_len;
16250
16251 section_len = sect->sh_size - 1;
11c1ff18 16252 p++;
60bca95a 16253
071436c6 16254 while (section_len > 0)
11c1ff18 16255 {
071436c6 16256 bfd_vma attr_len;
e9847026 16257 unsigned int namelen;
11c1ff18 16258 bfd_boolean public_section;
104d59d1 16259 bfd_boolean gnu_section;
11c1ff18 16260
071436c6 16261 if (section_len <= 4)
e0a31db1
NC
16262 {
16263 error (_("Tag section ends prematurely\n"));
32ec8896 16264 res = FALSE;
e0a31db1
NC
16265 break;
16266 }
071436c6 16267 attr_len = byte_get (p, 4);
11c1ff18 16268 p += 4;
60bca95a 16269
071436c6 16270 if (attr_len > section_len)
11c1ff18 16271 {
071436c6
NC
16272 error (_("Bad attribute length (%u > %u)\n"),
16273 (unsigned) attr_len, (unsigned) section_len);
16274 attr_len = section_len;
32ec8896 16275 res = FALSE;
11c1ff18 16276 }
74e1a04b 16277 /* PR 17531: file: 001-101425-0.004 */
071436c6 16278 else if (attr_len < 5)
74e1a04b 16279 {
071436c6 16280 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
32ec8896 16281 res = FALSE;
74e1a04b
NC
16282 break;
16283 }
e9847026 16284
071436c6
NC
16285 section_len -= attr_len;
16286 attr_len -= 4;
16287
16288 namelen = strnlen ((char *) p, attr_len) + 1;
16289 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
16290 {
16291 error (_("Corrupt attribute section name\n"));
32ec8896 16292 res = FALSE;
e9847026
NC
16293 break;
16294 }
16295
071436c6
NC
16296 printf (_("Attribute Section: "));
16297 print_symbol (INT_MAX, (const char *) p);
16298 putchar ('\n');
60bca95a
NC
16299
16300 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
16301 public_section = TRUE;
16302 else
16303 public_section = FALSE;
60bca95a
NC
16304
16305 if (streq ((char *) p, "gnu"))
104d59d1
JM
16306 gnu_section = TRUE;
16307 else
16308 gnu_section = FALSE;
60bca95a 16309
11c1ff18 16310 p += namelen;
071436c6 16311 attr_len -= namelen;
e0a31db1 16312
071436c6 16313 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 16314 {
e0a31db1 16315 int tag;
cd30bcef 16316 unsigned int val;
11c1ff18 16317 bfd_vma size;
071436c6 16318 unsigned char * end;
60bca95a 16319
e0a31db1 16320 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 16321 if (attr_len < 6)
e0a31db1
NC
16322 {
16323 error (_("Unused bytes at end of section\n"));
32ec8896 16324 res = FALSE;
e0a31db1
NC
16325 section_len = 0;
16326 break;
16327 }
16328
16329 tag = *(p++);
11c1ff18 16330 size = byte_get (p, 4);
071436c6 16331 if (size > attr_len)
11c1ff18 16332 {
e9847026 16333 error (_("Bad subsection length (%u > %u)\n"),
071436c6 16334 (unsigned) size, (unsigned) attr_len);
32ec8896 16335 res = FALSE;
071436c6 16336 size = attr_len;
11c1ff18 16337 }
e0a31db1
NC
16338 /* PR binutils/17531: Safe handling of corrupt files. */
16339 if (size < 6)
16340 {
16341 error (_("Bad subsection length (%u < 6)\n"),
16342 (unsigned) size);
32ec8896 16343 res = FALSE;
e0a31db1
NC
16344 section_len = 0;
16345 break;
16346 }
60bca95a 16347
071436c6 16348 attr_len -= size;
11c1ff18 16349 end = p + size - 1;
071436c6 16350 assert (end <= contents + sect->sh_size);
11c1ff18 16351 p += 4;
60bca95a 16352
11c1ff18
PB
16353 switch (tag)
16354 {
16355 case 1:
2b692964 16356 printf (_("File Attributes\n"));
11c1ff18
PB
16357 break;
16358 case 2:
2b692964 16359 printf (_("Section Attributes:"));
11c1ff18
PB
16360 goto do_numlist;
16361 case 3:
2b692964 16362 printf (_("Symbol Attributes:"));
1a0670f3 16363 /* Fall through. */
11c1ff18
PB
16364 do_numlist:
16365 for (;;)
16366 {
cd30bcef 16367 READ_ULEB (val, p, end);
11c1ff18
PB
16368 if (val == 0)
16369 break;
16370 printf (" %d", val);
16371 }
16372 printf ("\n");
16373 break;
16374 default:
2b692964 16375 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
16376 public_section = FALSE;
16377 break;
16378 }
60bca95a 16379
071436c6 16380 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
16381 {
16382 while (p < end)
f6f0e17b 16383 p = display_pub_attribute (p, end);
60abdbed 16384 assert (p == end);
104d59d1 16385 }
071436c6 16386 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
16387 {
16388 while (p < end)
16389 p = display_gnu_attribute (p,
f6f0e17b
NC
16390 display_proc_gnu_attribute,
16391 end);
60abdbed 16392 assert (p == end);
11c1ff18 16393 }
071436c6 16394 else if (p < end)
11c1ff18 16395 {
071436c6 16396 printf (_(" Unknown attribute:\n"));
f6f0e17b 16397 display_raw_attribute (p, end);
11c1ff18
PB
16398 p = end;
16399 }
071436c6
NC
16400 else
16401 attr_len = 0;
11c1ff18
PB
16402 }
16403 }
16404 }
d70c5fc7 16405
60bca95a 16406 free (contents);
11c1ff18 16407 }
32ec8896
NC
16408
16409 return res;
11c1ff18
PB
16410}
16411
ccb4c951
RS
16412/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
16413 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
16414 and return the VMA of the next entry, or -1 if there was a problem.
16415 Does not read from DATA_END or beyond. */
ccb4c951
RS
16416
16417static bfd_vma
82b1b41b
NC
16418print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
16419 unsigned char * data_end)
ccb4c951
RS
16420{
16421 printf (" ");
16422 print_vma (addr, LONG_HEX);
16423 printf (" ");
16424 if (addr < pltgot + 0xfff0)
16425 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
16426 else
16427 printf ("%10s", "");
16428 printf (" ");
16429 if (data == NULL)
2b692964 16430 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
16431 else
16432 {
16433 bfd_vma entry;
82b1b41b 16434 unsigned char * from = data + addr - pltgot;
ccb4c951 16435
82b1b41b
NC
16436 if (from + (is_32bit_elf ? 4 : 8) > data_end)
16437 {
16438 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
16439 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
16440 return (bfd_vma) -1;
16441 }
16442 else
16443 {
16444 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
16445 print_vma (entry, LONG_HEX);
16446 }
ccb4c951
RS
16447 }
16448 return addr + (is_32bit_elf ? 4 : 8);
16449}
16450
861fb55a
DJ
16451/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
16452 PLTGOT. Print the Address and Initial fields of an entry at VMA
16453 ADDR and return the VMA of the next entry. */
16454
16455static bfd_vma
2cf0635d 16456print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
16457{
16458 printf (" ");
16459 print_vma (addr, LONG_HEX);
16460 printf (" ");
16461 if (data == NULL)
2b692964 16462 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
16463 else
16464 {
16465 bfd_vma entry;
16466
16467 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
16468 print_vma (entry, LONG_HEX);
16469 }
16470 return addr + (is_32bit_elf ? 4 : 8);
16471}
16472
351cdf24
MF
16473static void
16474print_mips_ases (unsigned int mask)
16475{
16476 if (mask & AFL_ASE_DSP)
16477 fputs ("\n\tDSP ASE", stdout);
16478 if (mask & AFL_ASE_DSPR2)
16479 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
16480 if (mask & AFL_ASE_DSPR3)
16481 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
16482 if (mask & AFL_ASE_EVA)
16483 fputs ("\n\tEnhanced VA Scheme", stdout);
16484 if (mask & AFL_ASE_MCU)
16485 fputs ("\n\tMCU (MicroController) ASE", stdout);
16486 if (mask & AFL_ASE_MDMX)
16487 fputs ("\n\tMDMX ASE", stdout);
16488 if (mask & AFL_ASE_MIPS3D)
16489 fputs ("\n\tMIPS-3D ASE", stdout);
16490 if (mask & AFL_ASE_MT)
16491 fputs ("\n\tMT ASE", stdout);
16492 if (mask & AFL_ASE_SMARTMIPS)
16493 fputs ("\n\tSmartMIPS ASE", stdout);
16494 if (mask & AFL_ASE_VIRT)
16495 fputs ("\n\tVZ ASE", stdout);
16496 if (mask & AFL_ASE_MSA)
16497 fputs ("\n\tMSA ASE", stdout);
16498 if (mask & AFL_ASE_MIPS16)
16499 fputs ("\n\tMIPS16 ASE", stdout);
16500 if (mask & AFL_ASE_MICROMIPS)
16501 fputs ("\n\tMICROMIPS ASE", stdout);
16502 if (mask & AFL_ASE_XPA)
16503 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
16504 if (mask & AFL_ASE_MIPS16E2)
16505 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
16506 if (mask & AFL_ASE_CRC)
16507 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
16508 if (mask & AFL_ASE_GINV)
16509 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
16510 if (mask & AFL_ASE_LOONGSON_MMI)
16511 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
16512 if (mask & AFL_ASE_LOONGSON_CAM)
16513 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
16514 if (mask & AFL_ASE_LOONGSON_EXT)
16515 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
16516 if (mask & AFL_ASE_LOONGSON_EXT2)
16517 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
16518 if (mask == 0)
16519 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
16520 else if ((mask & ~AFL_ASE_MASK) != 0)
16521 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
16522}
16523
16524static void
16525print_mips_isa_ext (unsigned int isa_ext)
16526{
16527 switch (isa_ext)
16528 {
16529 case 0:
16530 fputs (_("None"), stdout);
16531 break;
16532 case AFL_EXT_XLR:
16533 fputs ("RMI XLR", stdout);
16534 break;
2c629856
N
16535 case AFL_EXT_OCTEON3:
16536 fputs ("Cavium Networks Octeon3", stdout);
16537 break;
351cdf24
MF
16538 case AFL_EXT_OCTEON2:
16539 fputs ("Cavium Networks Octeon2", stdout);
16540 break;
16541 case AFL_EXT_OCTEONP:
16542 fputs ("Cavium Networks OcteonP", stdout);
16543 break;
351cdf24
MF
16544 case AFL_EXT_OCTEON:
16545 fputs ("Cavium Networks Octeon", stdout);
16546 break;
16547 case AFL_EXT_5900:
16548 fputs ("Toshiba R5900", stdout);
16549 break;
16550 case AFL_EXT_4650:
16551 fputs ("MIPS R4650", stdout);
16552 break;
16553 case AFL_EXT_4010:
16554 fputs ("LSI R4010", stdout);
16555 break;
16556 case AFL_EXT_4100:
16557 fputs ("NEC VR4100", stdout);
16558 break;
16559 case AFL_EXT_3900:
16560 fputs ("Toshiba R3900", stdout);
16561 break;
16562 case AFL_EXT_10000:
16563 fputs ("MIPS R10000", stdout);
16564 break;
16565 case AFL_EXT_SB1:
16566 fputs ("Broadcom SB-1", stdout);
16567 break;
16568 case AFL_EXT_4111:
16569 fputs ("NEC VR4111/VR4181", stdout);
16570 break;
16571 case AFL_EXT_4120:
16572 fputs ("NEC VR4120", stdout);
16573 break;
16574 case AFL_EXT_5400:
16575 fputs ("NEC VR5400", stdout);
16576 break;
16577 case AFL_EXT_5500:
16578 fputs ("NEC VR5500", stdout);
16579 break;
16580 case AFL_EXT_LOONGSON_2E:
16581 fputs ("ST Microelectronics Loongson 2E", stdout);
16582 break;
16583 case AFL_EXT_LOONGSON_2F:
16584 fputs ("ST Microelectronics Loongson 2F", stdout);
16585 break;
38bf472a
MR
16586 case AFL_EXT_INTERAPTIV_MR2:
16587 fputs ("Imagination interAptiv MR2", stdout);
16588 break;
351cdf24 16589 default:
00ac7aa0 16590 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
16591 }
16592}
16593
32ec8896 16594static signed int
351cdf24
MF
16595get_mips_reg_size (int reg_size)
16596{
16597 return (reg_size == AFL_REG_NONE) ? 0
16598 : (reg_size == AFL_REG_32) ? 32
16599 : (reg_size == AFL_REG_64) ? 64
16600 : (reg_size == AFL_REG_128) ? 128
16601 : -1;
16602}
16603
32ec8896 16604static bfd_boolean
dda8d76d 16605process_mips_specific (Filedata * filedata)
5b18a4bc 16606{
2cf0635d 16607 Elf_Internal_Dyn * entry;
351cdf24 16608 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
16609 size_t liblist_offset = 0;
16610 size_t liblistno = 0;
16611 size_t conflictsno = 0;
16612 size_t options_offset = 0;
16613 size_t conflicts_offset = 0;
861fb55a
DJ
16614 size_t pltrelsz = 0;
16615 size_t pltrel = 0;
ccb4c951 16616 bfd_vma pltgot = 0;
861fb55a
DJ
16617 bfd_vma mips_pltgot = 0;
16618 bfd_vma jmprel = 0;
ccb4c951
RS
16619 bfd_vma local_gotno = 0;
16620 bfd_vma gotsym = 0;
16621 bfd_vma symtabno = 0;
32ec8896 16622 bfd_boolean res = TRUE;
103f02d3 16623
dda8d76d 16624 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896
NC
16625 display_mips_gnu_attribute))
16626 res = FALSE;
2cf19d5c 16627
dda8d76d 16628 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
16629
16630 if (sect != NULL)
16631 {
16632 Elf_External_ABIFlags_v0 *abiflags_ext;
16633 Elf_Internal_ABIFlags_v0 abiflags_in;
16634
16635 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
16636 {
16637 error (_("Corrupt MIPS ABI Flags section.\n"));
16638 res = FALSE;
16639 }
351cdf24
MF
16640 else
16641 {
dda8d76d 16642 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
16643 sect->sh_size, _("MIPS ABI Flags section"));
16644 if (abiflags_ext)
16645 {
16646 abiflags_in.version = BYTE_GET (abiflags_ext->version);
16647 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
16648 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
16649 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
16650 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
16651 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
16652 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
16653 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
16654 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
16655 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
16656 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
16657
16658 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
16659 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
16660 if (abiflags_in.isa_rev > 1)
16661 printf ("r%d", abiflags_in.isa_rev);
16662 printf ("\nGPR size: %d",
16663 get_mips_reg_size (abiflags_in.gpr_size));
16664 printf ("\nCPR1 size: %d",
16665 get_mips_reg_size (abiflags_in.cpr1_size));
16666 printf ("\nCPR2 size: %d",
16667 get_mips_reg_size (abiflags_in.cpr2_size));
16668 fputs ("\nFP ABI: ", stdout);
16669 print_mips_fp_abi_value (abiflags_in.fp_abi);
16670 fputs ("ISA Extension: ", stdout);
16671 print_mips_isa_ext (abiflags_in.isa_ext);
16672 fputs ("\nASEs:", stdout);
16673 print_mips_ases (abiflags_in.ases);
16674 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
16675 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
16676 fputc ('\n', stdout);
16677 free (abiflags_ext);
16678 }
16679 }
16680 }
16681
19e6b90e 16682 /* We have a lot of special sections. Thanks SGI! */
978c4450 16683 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
16684 {
16685 /* No dynamic information available. See if there is static GOT. */
dda8d76d 16686 sect = find_section (filedata, ".got");
bbdd9a68
MR
16687 if (sect != NULL)
16688 {
16689 unsigned char *data_end;
16690 unsigned char *data;
16691 bfd_vma ent, end;
16692 int addr_size;
16693
16694 pltgot = sect->sh_addr;
16695
16696 ent = pltgot;
16697 addr_size = (is_32bit_elf ? 4 : 8);
16698 end = pltgot + sect->sh_size;
16699
dda8d76d 16700 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
16701 end - pltgot, 1,
16702 _("Global Offset Table data"));
16703 /* PR 12855: Null data is handled gracefully throughout. */
16704 data_end = data + (end - pltgot);
16705
16706 printf (_("\nStatic GOT:\n"));
16707 printf (_(" Canonical gp value: "));
16708 print_vma (ent + 0x7ff0, LONG_HEX);
16709 printf ("\n\n");
16710
16711 /* In a dynamic binary GOT[0] is reserved for the dynamic
16712 loader to store the lazy resolver pointer, however in
16713 a static binary it may well have been omitted and GOT
16714 reduced to a table of addresses.
16715 PR 21344: Check for the entry being fully available
16716 before fetching it. */
16717 if (data
16718 && data + ent - pltgot + addr_size <= data_end
16719 && byte_get (data + ent - pltgot, addr_size) == 0)
16720 {
16721 printf (_(" Reserved entries:\n"));
16722 printf (_(" %*s %10s %*s\n"),
16723 addr_size * 2, _("Address"), _("Access"),
16724 addr_size * 2, _("Value"));
16725 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16726 printf ("\n");
16727 if (ent == (bfd_vma) -1)
16728 goto sgot_print_fail;
16729
16730 /* Check for the MSB of GOT[1] being set, identifying a
16731 GNU object. This entry will be used by some runtime
16732 loaders, to store the module pointer. Otherwise this
16733 is an ordinary local entry.
16734 PR 21344: Check for the entry being fully available
16735 before fetching it. */
16736 if (data
16737 && data + ent - pltgot + addr_size <= data_end
16738 && (byte_get (data + ent - pltgot, addr_size)
16739 >> (addr_size * 8 - 1)) != 0)
16740 {
16741 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16742 printf ("\n");
16743 if (ent == (bfd_vma) -1)
16744 goto sgot_print_fail;
16745 }
16746 printf ("\n");
16747 }
16748
f17e9d8a 16749 if (data != NULL && ent < end)
bbdd9a68
MR
16750 {
16751 printf (_(" Local entries:\n"));
16752 printf (" %*s %10s %*s\n",
16753 addr_size * 2, _("Address"), _("Access"),
16754 addr_size * 2, _("Value"));
16755 while (ent < end)
16756 {
16757 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16758 printf ("\n");
16759 if (ent == (bfd_vma) -1)
16760 goto sgot_print_fail;
16761 }
16762 printf ("\n");
16763 }
16764
16765 sgot_print_fail:
16766 if (data)
16767 free (data);
16768 }
16769 return res;
16770 }
252b5132 16771
978c4450 16772 for (entry = filedata->dynamic_section;
071436c6 16773 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
16774 (entry < filedata->dynamic_section + filedata->dynamic_nent
16775 && entry->d_tag != DT_NULL);
071436c6 16776 ++entry)
252b5132
RH
16777 switch (entry->d_tag)
16778 {
16779 case DT_MIPS_LIBLIST:
d93f0186 16780 liblist_offset
dda8d76d 16781 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 16782 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
16783 break;
16784 case DT_MIPS_LIBLISTNO:
16785 liblistno = entry->d_un.d_val;
16786 break;
16787 case DT_MIPS_OPTIONS:
dda8d76d 16788 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
16789 break;
16790 case DT_MIPS_CONFLICT:
d93f0186 16791 conflicts_offset
dda8d76d 16792 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 16793 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
16794 break;
16795 case DT_MIPS_CONFLICTNO:
16796 conflictsno = entry->d_un.d_val;
16797 break;
ccb4c951 16798 case DT_PLTGOT:
861fb55a
DJ
16799 pltgot = entry->d_un.d_ptr;
16800 break;
ccb4c951
RS
16801 case DT_MIPS_LOCAL_GOTNO:
16802 local_gotno = entry->d_un.d_val;
16803 break;
16804 case DT_MIPS_GOTSYM:
16805 gotsym = entry->d_un.d_val;
16806 break;
16807 case DT_MIPS_SYMTABNO:
16808 symtabno = entry->d_un.d_val;
16809 break;
861fb55a
DJ
16810 case DT_MIPS_PLTGOT:
16811 mips_pltgot = entry->d_un.d_ptr;
16812 break;
16813 case DT_PLTREL:
16814 pltrel = entry->d_un.d_val;
16815 break;
16816 case DT_PLTRELSZ:
16817 pltrelsz = entry->d_un.d_val;
16818 break;
16819 case DT_JMPREL:
16820 jmprel = entry->d_un.d_ptr;
16821 break;
252b5132
RH
16822 default:
16823 break;
16824 }
16825
16826 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
16827 {
2cf0635d 16828 Elf32_External_Lib * elib;
252b5132
RH
16829 size_t cnt;
16830
dda8d76d 16831 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
16832 sizeof (Elf32_External_Lib),
16833 liblistno,
16834 _("liblist section data"));
a6e9f9df 16835 if (elib)
252b5132 16836 {
d3a49aa8
AM
16837 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
16838 "\nSection '.liblist' contains %lu entries:\n",
16839 (unsigned long) liblistno),
a6e9f9df 16840 (unsigned long) liblistno);
2b692964 16841 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
16842 stdout);
16843
16844 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 16845 {
a6e9f9df 16846 Elf32_Lib liblist;
91d6fa6a 16847 time_t atime;
d5b07ef4 16848 char timebuf[128];
2cf0635d 16849 struct tm * tmp;
a6e9f9df
AM
16850
16851 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 16852 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
16853 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
16854 liblist.l_version = BYTE_GET (elib[cnt].l_version);
16855 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
16856
91d6fa6a 16857 tmp = gmtime (&atime);
e9e44622
JJ
16858 snprintf (timebuf, sizeof (timebuf),
16859 "%04u-%02u-%02uT%02u:%02u:%02u",
16860 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
16861 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 16862
31104126 16863 printf ("%3lu: ", (unsigned long) cnt);
978c4450
AM
16864 if (VALID_DYNAMIC_NAME (filedata, liblist.l_name))
16865 print_symbol (20, GET_DYNAMIC_NAME (filedata, liblist.l_name));
d79b3d50 16866 else
2b692964 16867 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
16868 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
16869 liblist.l_version);
a6e9f9df
AM
16870
16871 if (liblist.l_flags == 0)
2b692964 16872 puts (_(" NONE"));
a6e9f9df
AM
16873 else
16874 {
16875 static const struct
252b5132 16876 {
2cf0635d 16877 const char * name;
a6e9f9df 16878 int bit;
252b5132 16879 }
a6e9f9df
AM
16880 l_flags_vals[] =
16881 {
16882 { " EXACT_MATCH", LL_EXACT_MATCH },
16883 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
16884 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
16885 { " EXPORTS", LL_EXPORTS },
16886 { " DELAY_LOAD", LL_DELAY_LOAD },
16887 { " DELTA", LL_DELTA }
16888 };
16889 int flags = liblist.l_flags;
16890 size_t fcnt;
16891
60bca95a 16892 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
16893 if ((flags & l_flags_vals[fcnt].bit) != 0)
16894 {
16895 fputs (l_flags_vals[fcnt].name, stdout);
16896 flags ^= l_flags_vals[fcnt].bit;
16897 }
16898 if (flags != 0)
16899 printf (" %#x", (unsigned int) flags);
252b5132 16900
a6e9f9df
AM
16901 puts ("");
16902 }
252b5132 16903 }
252b5132 16904
a6e9f9df
AM
16905 free (elib);
16906 }
32ec8896
NC
16907 else
16908 res = FALSE;
252b5132
RH
16909 }
16910
16911 if (options_offset != 0)
16912 {
2cf0635d 16913 Elf_External_Options * eopt;
252b5132
RH
16914 size_t offset;
16915 int cnt;
dda8d76d 16916 sect = filedata->section_headers;
252b5132
RH
16917
16918 /* Find the section header so that we get the size. */
dda8d76d 16919 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 16920 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
16921 if (sect == NULL)
16922 {
16923 error (_("No MIPS_OPTIONS header found\n"));
32ec8896 16924 return FALSE;
071436c6 16925 }
7fc0c668
NC
16926 /* PR 24243 */
16927 if (sect->sh_size < sizeof (* eopt))
16928 {
16929 error (_("The MIPS options section is too small.\n"));
16930 return FALSE;
16931 }
252b5132 16932
dda8d76d 16933 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 16934 sect->sh_size, _("options"));
a6e9f9df 16935 if (eopt)
252b5132 16936 {
2e6be59c
NC
16937 Elf_Internal_Options * iopt;
16938 Elf_Internal_Options * option;
16939 Elf_Internal_Options * iopt_end;
16940
3f5e193b
NC
16941 iopt = (Elf_Internal_Options *)
16942 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
16943 if (iopt == NULL)
16944 {
fb324ee9 16945 error (_("Out of memory allocating space for MIPS options\n"));
645f43a8 16946 free (eopt);
32ec8896 16947 return FALSE;
a6e9f9df 16948 }
76da6bbe 16949
a6e9f9df
AM
16950 offset = cnt = 0;
16951 option = iopt;
2e6be59c
NC
16952 iopt_end = iopt + (sect->sh_size / sizeof (eopt));
16953
82b1b41b 16954 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 16955 {
2cf0635d 16956 Elf_External_Options * eoption;
252b5132 16957
a6e9f9df 16958 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 16959
a6e9f9df
AM
16960 option->kind = BYTE_GET (eoption->kind);
16961 option->size = BYTE_GET (eoption->size);
16962 option->section = BYTE_GET (eoption->section);
16963 option->info = BYTE_GET (eoption->info);
76da6bbe 16964
82b1b41b
NC
16965 /* PR 17531: file: ffa0fa3b. */
16966 if (option->size < sizeof (* eopt)
16967 || offset + option->size > sect->sh_size)
16968 {
645f43a8
AM
16969 error (_("Invalid size (%u) for MIPS option\n"),
16970 option->size);
16971 free (iopt);
16972 free (eopt);
32ec8896 16973 return FALSE;
82b1b41b 16974 }
a6e9f9df 16975 offset += option->size;
14ae95f2 16976
a6e9f9df
AM
16977 ++option;
16978 ++cnt;
16979 }
252b5132 16980
d3a49aa8
AM
16981 printf (ngettext ("\nSection '%s' contains %d entry:\n",
16982 "\nSection '%s' contains %d entries:\n",
16983 cnt),
dda8d76d 16984 printable_section_name (filedata, sect), cnt);
76da6bbe 16985
a6e9f9df 16986 option = iopt;
82b1b41b 16987 offset = 0;
252b5132 16988
a6e9f9df 16989 while (cnt-- > 0)
252b5132 16990 {
a6e9f9df
AM
16991 size_t len;
16992
16993 switch (option->kind)
252b5132 16994 {
a6e9f9df
AM
16995 case ODK_NULL:
16996 /* This shouldn't happen. */
16997 printf (" NULL %d %lx", option->section, option->info);
16998 break;
2e6be59c 16999
a6e9f9df
AM
17000 case ODK_REGINFO:
17001 printf (" REGINFO ");
dda8d76d 17002 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 17003 {
2cf0635d 17004 Elf32_External_RegInfo * ereg;
b34976b6 17005 Elf32_RegInfo reginfo;
a6e9f9df 17006
2e6be59c
NC
17007 /* 32bit form. */
17008 if (option + 2 > iopt_end)
17009 {
17010 printf (_("<corrupt>\n"));
17011 error (_("Truncated MIPS REGINFO option\n"));
17012 cnt = 0;
17013 break;
17014 }
17015
a6e9f9df 17016 ereg = (Elf32_External_RegInfo *) (option + 1);
2e6be59c 17017
a6e9f9df
AM
17018 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17019 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17020 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17021 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17022 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
17023 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
17024
17025 printf ("GPR %08lx GP 0x%lx\n",
17026 reginfo.ri_gprmask,
17027 (unsigned long) reginfo.ri_gp_value);
17028 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
17029 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17030 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17031 }
17032 else
17033 {
17034 /* 64 bit form. */
2cf0635d 17035 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
17036 Elf64_Internal_RegInfo reginfo;
17037
2e6be59c
NC
17038 if (option + 2 > iopt_end)
17039 {
17040 printf (_("<corrupt>\n"));
17041 error (_("Truncated MIPS REGINFO option\n"));
17042 cnt = 0;
17043 break;
17044 }
17045
a6e9f9df
AM
17046 ereg = (Elf64_External_RegInfo *) (option + 1);
17047 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17048 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17049 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17050 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17051 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 17052 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
17053
17054 printf ("GPR %08lx GP 0x",
17055 reginfo.ri_gprmask);
17056 printf_vma (reginfo.ri_gp_value);
17057 printf ("\n");
17058
17059 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
17060 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17061 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17062 }
17063 ++option;
17064 continue;
2e6be59c 17065
a6e9f9df
AM
17066 case ODK_EXCEPTIONS:
17067 fputs (" EXCEPTIONS fpe_min(", stdout);
17068 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
17069 fputs (") fpe_max(", stdout);
17070 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
17071 fputs (")", stdout);
17072
17073 if (option->info & OEX_PAGE0)
17074 fputs (" PAGE0", stdout);
17075 if (option->info & OEX_SMM)
17076 fputs (" SMM", stdout);
17077 if (option->info & OEX_FPDBUG)
17078 fputs (" FPDBUG", stdout);
17079 if (option->info & OEX_DISMISS)
17080 fputs (" DISMISS", stdout);
17081 break;
2e6be59c 17082
a6e9f9df
AM
17083 case ODK_PAD:
17084 fputs (" PAD ", stdout);
17085 if (option->info & OPAD_PREFIX)
17086 fputs (" PREFIX", stdout);
17087 if (option->info & OPAD_POSTFIX)
17088 fputs (" POSTFIX", stdout);
17089 if (option->info & OPAD_SYMBOL)
17090 fputs (" SYMBOL", stdout);
17091 break;
2e6be59c 17092
a6e9f9df
AM
17093 case ODK_HWPATCH:
17094 fputs (" HWPATCH ", stdout);
17095 if (option->info & OHW_R4KEOP)
17096 fputs (" R4KEOP", stdout);
17097 if (option->info & OHW_R8KPFETCH)
17098 fputs (" R8KPFETCH", stdout);
17099 if (option->info & OHW_R5KEOP)
17100 fputs (" R5KEOP", stdout);
17101 if (option->info & OHW_R5KCVTL)
17102 fputs (" R5KCVTL", stdout);
17103 break;
2e6be59c 17104
a6e9f9df
AM
17105 case ODK_FILL:
17106 fputs (" FILL ", stdout);
17107 /* XXX Print content of info word? */
17108 break;
2e6be59c 17109
a6e9f9df
AM
17110 case ODK_TAGS:
17111 fputs (" TAGS ", stdout);
17112 /* XXX Print content of info word? */
17113 break;
2e6be59c 17114
a6e9f9df
AM
17115 case ODK_HWAND:
17116 fputs (" HWAND ", stdout);
17117 if (option->info & OHWA0_R4KEOP_CHECKED)
17118 fputs (" R4KEOP_CHECKED", stdout);
17119 if (option->info & OHWA0_R4KEOP_CLEAN)
17120 fputs (" R4KEOP_CLEAN", stdout);
17121 break;
2e6be59c 17122
a6e9f9df
AM
17123 case ODK_HWOR:
17124 fputs (" HWOR ", stdout);
17125 if (option->info & OHWA0_R4KEOP_CHECKED)
17126 fputs (" R4KEOP_CHECKED", stdout);
17127 if (option->info & OHWA0_R4KEOP_CLEAN)
17128 fputs (" R4KEOP_CLEAN", stdout);
17129 break;
2e6be59c 17130
a6e9f9df
AM
17131 case ODK_GP_GROUP:
17132 printf (" GP_GROUP %#06lx self-contained %#06lx",
17133 option->info & OGP_GROUP,
17134 (option->info & OGP_SELF) >> 16);
17135 break;
2e6be59c 17136
a6e9f9df
AM
17137 case ODK_IDENT:
17138 printf (" IDENT %#06lx self-contained %#06lx",
17139 option->info & OGP_GROUP,
17140 (option->info & OGP_SELF) >> 16);
17141 break;
2e6be59c 17142
a6e9f9df
AM
17143 default:
17144 /* This shouldn't happen. */
17145 printf (" %3d ??? %d %lx",
17146 option->kind, option->section, option->info);
17147 break;
252b5132 17148 }
a6e9f9df 17149
2cf0635d 17150 len = sizeof (* eopt);
a6e9f9df 17151 while (len < option->size)
82b1b41b 17152 {
7e27a9d5 17153 unsigned char datum = * ((unsigned char *) eopt + offset + len);
a6e9f9df 17154
82b1b41b
NC
17155 if (ISPRINT (datum))
17156 printf ("%c", datum);
17157 else
17158 printf ("\\%03o", datum);
17159 len ++;
17160 }
a6e9f9df 17161 fputs ("\n", stdout);
82b1b41b
NC
17162
17163 offset += option->size;
252b5132 17164 ++option;
252b5132 17165 }
645f43a8 17166 free (iopt);
a6e9f9df 17167 free (eopt);
252b5132 17168 }
32ec8896
NC
17169 else
17170 res = FALSE;
252b5132
RH
17171 }
17172
17173 if (conflicts_offset != 0 && conflictsno != 0)
17174 {
2cf0635d 17175 Elf32_Conflict * iconf;
252b5132
RH
17176 size_t cnt;
17177
978c4450 17178 if (filedata->dynamic_symbols == NULL)
252b5132 17179 {
591a748a 17180 error (_("conflict list found without a dynamic symbol table\n"));
32ec8896 17181 return FALSE;
252b5132
RH
17182 }
17183
7296a62a
NC
17184 /* PR 21345 - print a slightly more helpful error message
17185 if we are sure that the cmalloc will fail. */
645f43a8 17186 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
17187 {
17188 error (_("Overlarge number of conflicts detected: %lx\n"),
17189 (long) conflictsno);
17190 return FALSE;
17191 }
17192
3f5e193b 17193 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
17194 if (iconf == NULL)
17195 {
8b73c356 17196 error (_("Out of memory allocating space for dynamic conflicts\n"));
32ec8896 17197 return FALSE;
252b5132
RH
17198 }
17199
9ea033b2 17200 if (is_32bit_elf)
252b5132 17201 {
2cf0635d 17202 Elf32_External_Conflict * econf32;
a6e9f9df 17203
3f5e193b 17204 econf32 = (Elf32_External_Conflict *)
95099889
AM
17205 get_data (NULL, filedata, conflicts_offset,
17206 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 17207 if (!econf32)
5a814d6d
AM
17208 {
17209 free (iconf);
17210 return FALSE;
17211 }
252b5132
RH
17212
17213 for (cnt = 0; cnt < conflictsno; ++cnt)
17214 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
17215
17216 free (econf32);
252b5132
RH
17217 }
17218 else
17219 {
2cf0635d 17220 Elf64_External_Conflict * econf64;
a6e9f9df 17221
3f5e193b 17222 econf64 = (Elf64_External_Conflict *)
95099889
AM
17223 get_data (NULL, filedata, conflicts_offset,
17224 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 17225 if (!econf64)
5a814d6d
AM
17226 {
17227 free (iconf);
17228 return FALSE;
17229 }
252b5132
RH
17230
17231 for (cnt = 0; cnt < conflictsno; ++cnt)
17232 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
17233
17234 free (econf64);
252b5132
RH
17235 }
17236
d3a49aa8
AM
17237 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
17238 "\nSection '.conflict' contains %lu entries:\n",
17239 (unsigned long) conflictsno),
c7e7ca54 17240 (unsigned long) conflictsno);
252b5132
RH
17241 puts (_(" Num: Index Value Name"));
17242
17243 for (cnt = 0; cnt < conflictsno; ++cnt)
17244 {
b34976b6 17245 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 17246
978c4450 17247 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 17248 printf (_("<corrupt symbol index>"));
d79b3d50 17249 else
e0a31db1
NC
17250 {
17251 Elf_Internal_Sym * psym;
17252
978c4450 17253 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
17254 print_vma (psym->st_value, FULL_HEX);
17255 putchar (' ');
978c4450
AM
17256 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17257 print_symbol (25, GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17258 else
17259 printf (_("<corrupt: %14ld>"), psym->st_name);
17260 }
31104126 17261 putchar ('\n');
252b5132
RH
17262 }
17263
252b5132
RH
17264 free (iconf);
17265 }
17266
ccb4c951
RS
17267 if (pltgot != 0 && local_gotno != 0)
17268 {
91d6fa6a 17269 bfd_vma ent, local_end, global_end;
bbeee7ea 17270 size_t i, offset;
2cf0635d 17271 unsigned char * data;
82b1b41b 17272 unsigned char * data_end;
bbeee7ea 17273 int addr_size;
ccb4c951 17274
91d6fa6a 17275 ent = pltgot;
ccb4c951
RS
17276 addr_size = (is_32bit_elf ? 4 : 8);
17277 local_end = pltgot + local_gotno * addr_size;
ccb4c951 17278
74e1a04b
NC
17279 /* PR binutils/17533 file: 012-111227-0.004 */
17280 if (symtabno < gotsym)
17281 {
17282 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 17283 (unsigned long) gotsym, (unsigned long) symtabno);
32ec8896 17284 return FALSE;
74e1a04b 17285 }
82b1b41b 17286
74e1a04b 17287 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
17288 /* PR 17531: file: 54c91a34. */
17289 if (global_end < local_end)
17290 {
17291 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
32ec8896 17292 return FALSE;
82b1b41b 17293 }
948f632f 17294
dda8d76d
NC
17295 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
17296 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
17297 global_end - pltgot, 1,
17298 _("Global Offset Table data"));
919383ac 17299 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 17300 data_end = data + (global_end - pltgot);
59245841 17301
ccb4c951
RS
17302 printf (_("\nPrimary GOT:\n"));
17303 printf (_(" Canonical gp value: "));
17304 print_vma (pltgot + 0x7ff0, LONG_HEX);
17305 printf ("\n\n");
17306
17307 printf (_(" Reserved entries:\n"));
17308 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
17309 addr_size * 2, _("Address"), _("Access"),
17310 addr_size * 2, _("Initial"));
82b1b41b 17311 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 17312 printf (_(" Lazy resolver\n"));
82b1b41b
NC
17313 if (ent == (bfd_vma) -1)
17314 goto got_print_fail;
75ec1fdb 17315
c4ab9505
MR
17316 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
17317 This entry will be used by some runtime loaders, to store the
17318 module pointer. Otherwise this is an ordinary local entry.
17319 PR 21344: Check for the entry being fully available before
17320 fetching it. */
17321 if (data
17322 && data + ent - pltgot + addr_size <= data_end
17323 && (byte_get (data + ent - pltgot, addr_size)
17324 >> (addr_size * 8 - 1)) != 0)
17325 {
17326 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17327 printf (_(" Module pointer (GNU extension)\n"));
17328 if (ent == (bfd_vma) -1)
17329 goto got_print_fail;
ccb4c951
RS
17330 }
17331 printf ("\n");
17332
f17e9d8a 17333 if (data != NULL && ent < local_end)
ccb4c951
RS
17334 {
17335 printf (_(" Local entries:\n"));
cc5914eb 17336 printf (" %*s %10s %*s\n",
2b692964
NC
17337 addr_size * 2, _("Address"), _("Access"),
17338 addr_size * 2, _("Initial"));
91d6fa6a 17339 while (ent < local_end)
ccb4c951 17340 {
82b1b41b 17341 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 17342 printf ("\n");
82b1b41b
NC
17343 if (ent == (bfd_vma) -1)
17344 goto got_print_fail;
ccb4c951
RS
17345 }
17346 printf ("\n");
17347 }
17348
f17e9d8a 17349 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
17350 {
17351 int sym_width;
17352
17353 printf (_(" Global entries:\n"));
cc5914eb 17354 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
17355 addr_size * 2, _("Address"),
17356 _("Access"),
2b692964 17357 addr_size * 2, _("Initial"),
9cf03b7e
NC
17358 addr_size * 2, _("Sym.Val."),
17359 _("Type"),
17360 /* Note for translators: "Ndx" = abbreviated form of "Index". */
17361 _("Ndx"), _("Name"));
0b4362b0 17362
ccb4c951 17363 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 17364
ccb4c951
RS
17365 for (i = gotsym; i < symtabno; i++)
17366 {
82b1b41b 17367 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 17368 printf (" ");
e0a31db1 17369
978c4450 17370 if (filedata->dynamic_symbols == NULL)
e0a31db1 17371 printf (_("<no dynamic symbols>"));
978c4450 17372 else if (i < filedata->num_dynamic_syms)
e0a31db1 17373 {
978c4450 17374 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
17375
17376 print_vma (psym->st_value, LONG_HEX);
17377 printf (" %-7s %3s ",
dda8d76d
NC
17378 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
17379 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 17380
978c4450
AM
17381 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17382 print_symbol (sym_width,
17383 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17384 else
17385 printf (_("<corrupt: %14ld>"), psym->st_name);
17386 }
ccb4c951 17387 else
7fc5ac57
JBG
17388 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
17389 (unsigned long) i);
e0a31db1 17390
ccb4c951 17391 printf ("\n");
82b1b41b
NC
17392 if (ent == (bfd_vma) -1)
17393 break;
ccb4c951
RS
17394 }
17395 printf ("\n");
17396 }
17397
82b1b41b 17398 got_print_fail:
ccb4c951
RS
17399 if (data)
17400 free (data);
17401 }
17402
861fb55a
DJ
17403 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
17404 {
91d6fa6a 17405 bfd_vma ent, end;
861fb55a
DJ
17406 size_t offset, rel_offset;
17407 unsigned long count, i;
2cf0635d 17408 unsigned char * data;
861fb55a 17409 int addr_size, sym_width;
2cf0635d 17410 Elf_Internal_Rela * rels;
861fb55a 17411
dda8d76d 17412 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
17413 if (pltrel == DT_RELA)
17414 {
dda8d76d 17415 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 17416 return FALSE;
861fb55a
DJ
17417 }
17418 else
17419 {
dda8d76d 17420 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 17421 return FALSE;
861fb55a
DJ
17422 }
17423
91d6fa6a 17424 ent = mips_pltgot;
861fb55a
DJ
17425 addr_size = (is_32bit_elf ? 4 : 8);
17426 end = mips_pltgot + (2 + count) * addr_size;
17427
dda8d76d
NC
17428 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
17429 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 17430 1, _("Procedure Linkage Table data"));
59245841 17431 if (data == NULL)
32ec8896 17432 return FALSE;
59245841 17433
9cf03b7e 17434 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
17435 printf (_(" Reserved entries:\n"));
17436 printf (_(" %*s %*s Purpose\n"),
2b692964 17437 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 17438 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 17439 printf (_(" PLT lazy resolver\n"));
91d6fa6a 17440 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 17441 printf (_(" Module pointer\n"));
861fb55a
DJ
17442 printf ("\n");
17443
17444 printf (_(" Entries:\n"));
cc5914eb 17445 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
17446 addr_size * 2, _("Address"),
17447 addr_size * 2, _("Initial"),
17448 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
17449 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
17450 for (i = 0; i < count; i++)
17451 {
df97ab2a 17452 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 17453
91d6fa6a 17454 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 17455 printf (" ");
e0a31db1 17456
978c4450 17457 if (idx >= filedata->num_dynamic_syms)
df97ab2a 17458 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 17459 else
e0a31db1 17460 {
978c4450 17461 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
17462
17463 print_vma (psym->st_value, LONG_HEX);
17464 printf (" %-7s %3s ",
dda8d76d
NC
17465 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
17466 get_symbol_index_type (filedata, psym->st_shndx));
978c4450
AM
17467 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17468 print_symbol (sym_width,
17469 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17470 else
17471 printf (_("<corrupt: %14ld>"), psym->st_name);
17472 }
861fb55a
DJ
17473 printf ("\n");
17474 }
17475 printf ("\n");
17476
17477 if (data)
17478 free (data);
17479 free (rels);
17480 }
17481
32ec8896 17482 return res;
252b5132
RH
17483}
17484
32ec8896 17485static bfd_boolean
dda8d76d 17486process_nds32_specific (Filedata * filedata)
35c08157
KLC
17487{
17488 Elf_Internal_Shdr *sect = NULL;
17489
dda8d76d 17490 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 17491 if (sect != NULL && sect->sh_size >= 4)
35c08157 17492 {
9c7b8e9b
AM
17493 unsigned char *buf;
17494 unsigned int flag;
35c08157
KLC
17495
17496 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
17497 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
17498 _("NDS32 elf flags section"));
35c08157 17499
9c7b8e9b 17500 if (buf == NULL)
32ec8896
NC
17501 return FALSE;
17502
9c7b8e9b
AM
17503 flag = byte_get (buf, 4);
17504 free (buf);
17505 switch (flag & 0x3)
35c08157
KLC
17506 {
17507 case 0:
17508 printf ("(VEC_SIZE):\tNo entry.\n");
17509 break;
17510 case 1:
17511 printf ("(VEC_SIZE):\t4 bytes\n");
17512 break;
17513 case 2:
17514 printf ("(VEC_SIZE):\t16 bytes\n");
17515 break;
17516 case 3:
17517 printf ("(VEC_SIZE):\treserved\n");
17518 break;
17519 }
17520 }
17521
17522 return TRUE;
17523}
17524
32ec8896 17525static bfd_boolean
dda8d76d 17526process_gnu_liblist (Filedata * filedata)
047b2264 17527{
2cf0635d
NC
17528 Elf_Internal_Shdr * section;
17529 Elf_Internal_Shdr * string_sec;
17530 Elf32_External_Lib * elib;
17531 char * strtab;
c256ffe7 17532 size_t strtab_size;
047b2264 17533 size_t cnt;
d3a49aa8 17534 unsigned long num_liblist;
047b2264 17535 unsigned i;
32ec8896 17536 bfd_boolean res = TRUE;
047b2264
JJ
17537
17538 if (! do_arch)
32ec8896 17539 return TRUE;
047b2264 17540
dda8d76d
NC
17541 for (i = 0, section = filedata->section_headers;
17542 i < filedata->file_header.e_shnum;
b34976b6 17543 i++, section++)
047b2264
JJ
17544 {
17545 switch (section->sh_type)
17546 {
17547 case SHT_GNU_LIBLIST:
dda8d76d 17548 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
17549 break;
17550
3f5e193b 17551 elib = (Elf32_External_Lib *)
dda8d76d 17552 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 17553 _("liblist section data"));
047b2264
JJ
17554
17555 if (elib == NULL)
32ec8896
NC
17556 {
17557 res = FALSE;
17558 break;
17559 }
047b2264 17560
dda8d76d
NC
17561 string_sec = filedata->section_headers + section->sh_link;
17562 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
17563 string_sec->sh_size,
17564 _("liblist string table"));
047b2264
JJ
17565 if (strtab == NULL
17566 || section->sh_entsize != sizeof (Elf32_External_Lib))
17567 {
17568 free (elib);
2842702f 17569 free (strtab);
32ec8896 17570 res = FALSE;
047b2264
JJ
17571 break;
17572 }
59245841 17573 strtab_size = string_sec->sh_size;
047b2264 17574
d3a49aa8
AM
17575 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
17576 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
17577 "\nLibrary list section '%s' contains %lu entries:\n",
17578 num_liblist),
dda8d76d 17579 printable_section_name (filedata, section),
d3a49aa8 17580 num_liblist);
047b2264 17581
2b692964 17582 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
17583
17584 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
17585 ++cnt)
17586 {
17587 Elf32_Lib liblist;
91d6fa6a 17588 time_t atime;
d5b07ef4 17589 char timebuf[128];
2cf0635d 17590 struct tm * tmp;
047b2264
JJ
17591
17592 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17593 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
17594 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17595 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17596 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17597
91d6fa6a 17598 tmp = gmtime (&atime);
e9e44622
JJ
17599 snprintf (timebuf, sizeof (timebuf),
17600 "%04u-%02u-%02uT%02u:%02u:%02u",
17601 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17602 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
17603
17604 printf ("%3lu: ", (unsigned long) cnt);
17605 if (do_wide)
c256ffe7 17606 printf ("%-20s", liblist.l_name < strtab_size
2b692964 17607 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 17608 else
c256ffe7 17609 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 17610 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
17611 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
17612 liblist.l_version, liblist.l_flags);
17613 }
17614
17615 free (elib);
2842702f 17616 free (strtab);
047b2264
JJ
17617 }
17618 }
17619
32ec8896 17620 return res;
047b2264
JJ
17621}
17622
9437c45b 17623static const char *
dda8d76d 17624get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
17625{
17626 static char buff[64];
103f02d3 17627
dda8d76d 17628 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
17629 switch (e_type)
17630 {
57346661 17631 case NT_AUXV:
1ec5cd37 17632 return _("NT_AUXV (auxiliary vector)");
57346661 17633 case NT_PRSTATUS:
1ec5cd37 17634 return _("NT_PRSTATUS (prstatus structure)");
57346661 17635 case NT_FPREGSET:
1ec5cd37 17636 return _("NT_FPREGSET (floating point registers)");
57346661 17637 case NT_PRPSINFO:
1ec5cd37 17638 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 17639 case NT_TASKSTRUCT:
1ec5cd37 17640 return _("NT_TASKSTRUCT (task structure)");
57346661 17641 case NT_PRXFPREG:
1ec5cd37 17642 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
17643 case NT_PPC_VMX:
17644 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
17645 case NT_PPC_VSX:
17646 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
17647 case NT_PPC_TAR:
17648 return _("NT_PPC_TAR (ppc TAR register)");
17649 case NT_PPC_PPR:
17650 return _("NT_PPC_PPR (ppc PPR register)");
17651 case NT_PPC_DSCR:
17652 return _("NT_PPC_DSCR (ppc DSCR register)");
17653 case NT_PPC_EBB:
17654 return _("NT_PPC_EBB (ppc EBB registers)");
17655 case NT_PPC_PMU:
17656 return _("NT_PPC_PMU (ppc PMU registers)");
17657 case NT_PPC_TM_CGPR:
17658 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
17659 case NT_PPC_TM_CFPR:
17660 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
17661 case NT_PPC_TM_CVMX:
17662 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
17663 case NT_PPC_TM_CVSX:
3fd21718 17664 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
17665 case NT_PPC_TM_SPR:
17666 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
17667 case NT_PPC_TM_CTAR:
17668 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
17669 case NT_PPC_TM_CPPR:
17670 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
17671 case NT_PPC_TM_CDSCR:
17672 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
17673 case NT_386_TLS:
17674 return _("NT_386_TLS (x86 TLS information)");
17675 case NT_386_IOPERM:
17676 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
17677 case NT_X86_XSTATE:
17678 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
17679 case NT_S390_HIGH_GPRS:
17680 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
17681 case NT_S390_TIMER:
17682 return _("NT_S390_TIMER (s390 timer register)");
17683 case NT_S390_TODCMP:
17684 return _("NT_S390_TODCMP (s390 TOD comparator register)");
17685 case NT_S390_TODPREG:
17686 return _("NT_S390_TODPREG (s390 TOD programmable register)");
17687 case NT_S390_CTRS:
17688 return _("NT_S390_CTRS (s390 control registers)");
17689 case NT_S390_PREFIX:
17690 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
17691 case NT_S390_LAST_BREAK:
17692 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
17693 case NT_S390_SYSTEM_CALL:
17694 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
17695 case NT_S390_TDB:
17696 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
17697 case NT_S390_VXRS_LOW:
17698 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
17699 case NT_S390_VXRS_HIGH:
17700 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
17701 case NT_S390_GS_CB:
17702 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
17703 case NT_S390_GS_BC:
17704 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
17705 case NT_ARM_VFP:
17706 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
17707 case NT_ARM_TLS:
17708 return _("NT_ARM_TLS (AArch TLS registers)");
17709 case NT_ARM_HW_BREAK:
17710 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
17711 case NT_ARM_HW_WATCH:
17712 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
27456742
AK
17713 case NT_ARC_V2:
17714 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
57346661 17715 case NT_PSTATUS:
1ec5cd37 17716 return _("NT_PSTATUS (pstatus structure)");
57346661 17717 case NT_FPREGS:
1ec5cd37 17718 return _("NT_FPREGS (floating point registers)");
57346661 17719 case NT_PSINFO:
1ec5cd37 17720 return _("NT_PSINFO (psinfo structure)");
57346661 17721 case NT_LWPSTATUS:
1ec5cd37 17722 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 17723 case NT_LWPSINFO:
1ec5cd37 17724 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 17725 case NT_WIN32PSTATUS:
1ec5cd37 17726 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
17727 case NT_SIGINFO:
17728 return _("NT_SIGINFO (siginfo_t data)");
17729 case NT_FILE:
17730 return _("NT_FILE (mapped files)");
1ec5cd37
NC
17731 default:
17732 break;
17733 }
17734 else
17735 switch (e_type)
17736 {
17737 case NT_VERSION:
17738 return _("NT_VERSION (version)");
17739 case NT_ARCH:
17740 return _("NT_ARCH (architecture)");
9ef920e9 17741 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 17742 return _("OPEN");
9ef920e9 17743 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 17744 return _("func");
1ec5cd37
NC
17745 default:
17746 break;
17747 }
17748
e9e44622 17749 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 17750 return buff;
779fe533
NC
17751}
17752
32ec8896 17753static bfd_boolean
9ece1fa9
TT
17754print_core_note (Elf_Internal_Note *pnote)
17755{
17756 unsigned int addr_size = is_32bit_elf ? 4 : 8;
17757 bfd_vma count, page_size;
17758 unsigned char *descdata, *filenames, *descend;
17759
17760 if (pnote->type != NT_FILE)
04ac15ab
AS
17761 {
17762 if (do_wide)
17763 printf ("\n");
17764 return TRUE;
17765 }
9ece1fa9
TT
17766
17767#ifndef BFD64
17768 if (!is_32bit_elf)
17769 {
17770 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
17771 /* Still "successful". */
32ec8896 17772 return TRUE;
9ece1fa9
TT
17773 }
17774#endif
17775
17776 if (pnote->descsz < 2 * addr_size)
17777 {
32ec8896
NC
17778 error (_(" Malformed note - too short for header\n"));
17779 return FALSE;
9ece1fa9
TT
17780 }
17781
17782 descdata = (unsigned char *) pnote->descdata;
17783 descend = descdata + pnote->descsz;
17784
17785 if (descdata[pnote->descsz - 1] != '\0')
17786 {
32ec8896
NC
17787 error (_(" Malformed note - does not end with \\0\n"));
17788 return FALSE;
9ece1fa9
TT
17789 }
17790
17791 count = byte_get (descdata, addr_size);
17792 descdata += addr_size;
17793
17794 page_size = byte_get (descdata, addr_size);
17795 descdata += addr_size;
17796
5396a86e
AM
17797 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
17798 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 17799 {
32ec8896
NC
17800 error (_(" Malformed note - too short for supplied file count\n"));
17801 return FALSE;
9ece1fa9
TT
17802 }
17803
17804 printf (_(" Page size: "));
17805 print_vma (page_size, DEC);
17806 printf ("\n");
17807
17808 printf (_(" %*s%*s%*s\n"),
17809 (int) (2 + 2 * addr_size), _("Start"),
17810 (int) (4 + 2 * addr_size), _("End"),
17811 (int) (4 + 2 * addr_size), _("Page Offset"));
17812 filenames = descdata + count * 3 * addr_size;
595712bb 17813 while (count-- > 0)
9ece1fa9
TT
17814 {
17815 bfd_vma start, end, file_ofs;
17816
17817 if (filenames == descend)
17818 {
32ec8896
NC
17819 error (_(" Malformed note - filenames end too early\n"));
17820 return FALSE;
9ece1fa9
TT
17821 }
17822
17823 start = byte_get (descdata, addr_size);
17824 descdata += addr_size;
17825 end = byte_get (descdata, addr_size);
17826 descdata += addr_size;
17827 file_ofs = byte_get (descdata, addr_size);
17828 descdata += addr_size;
17829
17830 printf (" ");
17831 print_vma (start, FULL_HEX);
17832 printf (" ");
17833 print_vma (end, FULL_HEX);
17834 printf (" ");
17835 print_vma (file_ofs, FULL_HEX);
17836 printf ("\n %s\n", filenames);
17837
17838 filenames += 1 + strlen ((char *) filenames);
17839 }
17840
32ec8896 17841 return TRUE;
9ece1fa9
TT
17842}
17843
1118d252
RM
17844static const char *
17845get_gnu_elf_note_type (unsigned e_type)
17846{
1449284b 17847 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
17848 switch (e_type)
17849 {
17850 case NT_GNU_ABI_TAG:
17851 return _("NT_GNU_ABI_TAG (ABI version tag)");
17852 case NT_GNU_HWCAP:
17853 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
17854 case NT_GNU_BUILD_ID:
17855 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
17856 case NT_GNU_GOLD_VERSION:
17857 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
17858 case NT_GNU_PROPERTY_TYPE_0:
17859 return _("NT_GNU_PROPERTY_TYPE_0");
17860 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
17861 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
17862 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
17863 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 17864 default:
1449284b
NC
17865 {
17866 static char buff[64];
1118d252 17867
1449284b
NC
17868 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
17869 return buff;
17870 }
17871 }
1118d252
RM
17872}
17873
a9eafb08
L
17874static void
17875decode_x86_compat_isa (unsigned int bitmask)
17876{
17877 while (bitmask)
17878 {
17879 unsigned int bit = bitmask & (- bitmask);
17880
17881 bitmask &= ~ bit;
17882 switch (bit)
17883 {
17884 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
17885 printf ("i486");
17886 break;
17887 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
17888 printf ("586");
17889 break;
17890 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
17891 printf ("686");
17892 break;
17893 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
17894 printf ("SSE");
17895 break;
17896 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
17897 printf ("SSE2");
17898 break;
17899 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
17900 printf ("SSE3");
17901 break;
17902 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
17903 printf ("SSSE3");
17904 break;
17905 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
17906 printf ("SSE4_1");
17907 break;
17908 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
17909 printf ("SSE4_2");
17910 break;
17911 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
17912 printf ("AVX");
17913 break;
17914 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
17915 printf ("AVX2");
17916 break;
17917 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
17918 printf ("AVX512F");
17919 break;
17920 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
17921 printf ("AVX512CD");
17922 break;
17923 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
17924 printf ("AVX512ER");
17925 break;
17926 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
17927 printf ("AVX512PF");
17928 break;
17929 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
17930 printf ("AVX512VL");
17931 break;
17932 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
17933 printf ("AVX512DQ");
17934 break;
17935 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
17936 printf ("AVX512BW");
17937 break;
65b3d26e
L
17938 default:
17939 printf (_("<unknown: %x>"), bit);
17940 break;
a9eafb08
L
17941 }
17942 if (bitmask)
17943 printf (", ");
17944 }
17945}
17946
9ef920e9 17947static void
1fc87489 17948decode_x86_isa (unsigned int bitmask)
9ef920e9 17949{
0a59decb 17950 if (!bitmask)
90c745dc
L
17951 {
17952 printf (_("<None>"));
17953 return;
17954 }
90c745dc 17955
9ef920e9
NC
17956 while (bitmask)
17957 {
1fc87489 17958 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
17959
17960 bitmask &= ~ bit;
17961 switch (bit)
17962 {
a9eafb08
L
17963 case GNU_PROPERTY_X86_ISA_1_CMOV:
17964 printf ("CMOV");
17965 break;
17966 case GNU_PROPERTY_X86_ISA_1_SSE:
17967 printf ("SSE");
17968 break;
17969 case GNU_PROPERTY_X86_ISA_1_SSE2:
17970 printf ("SSE2");
17971 break;
17972 case GNU_PROPERTY_X86_ISA_1_SSE3:
17973 printf ("SSE3");
17974 break;
17975 case GNU_PROPERTY_X86_ISA_1_SSSE3:
17976 printf ("SSSE3");
17977 break;
17978 case GNU_PROPERTY_X86_ISA_1_SSE4_1:
17979 printf ("SSE4_1");
17980 break;
17981 case GNU_PROPERTY_X86_ISA_1_SSE4_2:
17982 printf ("SSE4_2");
17983 break;
17984 case GNU_PROPERTY_X86_ISA_1_AVX:
17985 printf ("AVX");
17986 break;
17987 case GNU_PROPERTY_X86_ISA_1_AVX2:
17988 printf ("AVX2");
17989 break;
17990 case GNU_PROPERTY_X86_ISA_1_FMA:
17991 printf ("FMA");
17992 break;
17993 case GNU_PROPERTY_X86_ISA_1_AVX512F:
17994 printf ("AVX512F");
17995 break;
17996 case GNU_PROPERTY_X86_ISA_1_AVX512CD:
17997 printf ("AVX512CD");
17998 break;
17999 case GNU_PROPERTY_X86_ISA_1_AVX512ER:
18000 printf ("AVX512ER");
18001 break;
18002 case GNU_PROPERTY_X86_ISA_1_AVX512PF:
18003 printf ("AVX512PF");
18004 break;
18005 case GNU_PROPERTY_X86_ISA_1_AVX512VL:
18006 printf ("AVX512VL");
18007 break;
18008 case GNU_PROPERTY_X86_ISA_1_AVX512DQ:
18009 printf ("AVX512DQ");
18010 break;
18011 case GNU_PROPERTY_X86_ISA_1_AVX512BW:
18012 printf ("AVX512BW");
18013 break;
18014 case GNU_PROPERTY_X86_ISA_1_AVX512_4FMAPS:
18015 printf ("AVX512_4FMAPS");
18016 break;
18017 case GNU_PROPERTY_X86_ISA_1_AVX512_4VNNIW:
18018 printf ("AVX512_4VNNIW");
18019 break;
18020 case GNU_PROPERTY_X86_ISA_1_AVX512_BITALG:
18021 printf ("AVX512_BITALG");
18022 break;
18023 case GNU_PROPERTY_X86_ISA_1_AVX512_IFMA:
18024 printf ("AVX512_IFMA");
18025 break;
18026 case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI:
18027 printf ("AVX512_VBMI");
18028 break;
18029 case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI2:
18030 printf ("AVX512_VBMI2");
18031 break;
18032 case GNU_PROPERTY_X86_ISA_1_AVX512_VNNI:
18033 printf ("AVX512_VNNI");
18034 break;
462cac58
L
18035 case GNU_PROPERTY_X86_ISA_1_AVX512_BF16:
18036 printf ("AVX512_BF16");
18037 break;
65b3d26e
L
18038 default:
18039 printf (_("<unknown: %x>"), bit);
18040 break;
9ef920e9
NC
18041 }
18042 if (bitmask)
18043 printf (", ");
18044 }
18045}
18046
ee2fdd6f 18047static void
a9eafb08 18048decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 18049{
0a59decb 18050 if (!bitmask)
90c745dc
L
18051 {
18052 printf (_("<None>"));
18053 return;
18054 }
90c745dc 18055
ee2fdd6f
L
18056 while (bitmask)
18057 {
18058 unsigned int bit = bitmask & (- bitmask);
18059
18060 bitmask &= ~ bit;
18061 switch (bit)
18062 {
18063 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 18064 printf ("IBT");
ee2fdd6f 18065 break;
48580982 18066 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 18067 printf ("SHSTK");
48580982 18068 break;
ee2fdd6f
L
18069 default:
18070 printf (_("<unknown: %x>"), bit);
18071 break;
18072 }
18073 if (bitmask)
18074 printf (", ");
18075 }
18076}
18077
a9eafb08
L
18078static void
18079decode_x86_feature_2 (unsigned int bitmask)
18080{
0a59decb 18081 if (!bitmask)
90c745dc
L
18082 {
18083 printf (_("<None>"));
18084 return;
18085 }
90c745dc 18086
a9eafb08
L
18087 while (bitmask)
18088 {
18089 unsigned int bit = bitmask & (- bitmask);
18090
18091 bitmask &= ~ bit;
18092 switch (bit)
18093 {
18094 case GNU_PROPERTY_X86_FEATURE_2_X86:
18095 printf ("x86");
18096 break;
18097 case GNU_PROPERTY_X86_FEATURE_2_X87:
18098 printf ("x87");
18099 break;
18100 case GNU_PROPERTY_X86_FEATURE_2_MMX:
18101 printf ("MMX");
18102 break;
18103 case GNU_PROPERTY_X86_FEATURE_2_XMM:
18104 printf ("XMM");
18105 break;
18106 case GNU_PROPERTY_X86_FEATURE_2_YMM:
18107 printf ("YMM");
18108 break;
18109 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
18110 printf ("ZMM");
18111 break;
18112 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
18113 printf ("FXSR");
18114 break;
18115 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
18116 printf ("XSAVE");
18117 break;
18118 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
18119 printf ("XSAVEOPT");
18120 break;
18121 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
18122 printf ("XSAVEC");
18123 break;
65b3d26e
L
18124 default:
18125 printf (_("<unknown: %x>"), bit);
18126 break;
a9eafb08
L
18127 }
18128 if (bitmask)
18129 printf (", ");
18130 }
18131}
18132
cd702818
SD
18133static void
18134decode_aarch64_feature_1_and (unsigned int bitmask)
18135{
18136 while (bitmask)
18137 {
18138 unsigned int bit = bitmask & (- bitmask);
18139
18140 bitmask &= ~ bit;
18141 switch (bit)
18142 {
18143 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
18144 printf ("BTI");
18145 break;
18146
18147 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
18148 printf ("PAC");
18149 break;
18150
18151 default:
18152 printf (_("<unknown: %x>"), bit);
18153 break;
18154 }
18155 if (bitmask)
18156 printf (", ");
18157 }
18158}
18159
9ef920e9 18160static void
dda8d76d 18161print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
18162{
18163 unsigned char * ptr = (unsigned char *) pnote->descdata;
18164 unsigned char * ptr_end = ptr + pnote->descsz;
18165 unsigned int size = is_32bit_elf ? 4 : 8;
18166
18167 printf (_(" Properties: "));
18168
1fc87489 18169 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
18170 {
18171 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
18172 return;
18173 }
18174
6ab2c4ed 18175 while (ptr < ptr_end)
9ef920e9 18176 {
1fc87489 18177 unsigned int j;
6ab2c4ed
MC
18178 unsigned int type;
18179 unsigned int datasz;
18180
18181 if ((size_t) (ptr_end - ptr) < 8)
18182 {
18183 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
18184 break;
18185 }
18186
18187 type = byte_get (ptr, 4);
18188 datasz = byte_get (ptr + 4, 4);
9ef920e9 18189
1fc87489 18190 ptr += 8;
9ef920e9 18191
6ab2c4ed 18192 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 18193 {
1fc87489
L
18194 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
18195 type, datasz);
9ef920e9 18196 break;
1fc87489 18197 }
9ef920e9 18198
1fc87489
L
18199 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
18200 {
dda8d76d
NC
18201 if (filedata->file_header.e_machine == EM_X86_64
18202 || filedata->file_header.e_machine == EM_IAMCU
18203 || filedata->file_header.e_machine == EM_386)
1fc87489 18204 {
aa7bca9b
L
18205 unsigned int bitmask;
18206
18207 if (datasz == 4)
0a59decb 18208 bitmask = byte_get (ptr, 4);
aa7bca9b
L
18209 else
18210 bitmask = 0;
18211
1fc87489
L
18212 switch (type)
18213 {
18214 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 18215 if (datasz != 4)
aa7bca9b
L
18216 printf (_("x86 ISA used: <corrupt length: %#x> "),
18217 datasz);
1fc87489 18218 else
aa7bca9b
L
18219 {
18220 printf ("x86 ISA used: ");
18221 decode_x86_isa (bitmask);
18222 }
1fc87489 18223 goto next;
9ef920e9 18224
1fc87489 18225 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 18226 if (datasz != 4)
aa7bca9b
L
18227 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18228 datasz);
1fc87489 18229 else
aa7bca9b
L
18230 {
18231 printf ("x86 ISA needed: ");
18232 decode_x86_isa (bitmask);
18233 }
1fc87489 18234 goto next;
9ef920e9 18235
ee2fdd6f 18236 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 18237 if (datasz != 4)
aa7bca9b
L
18238 printf (_("x86 feature: <corrupt length: %#x> "),
18239 datasz);
ee2fdd6f 18240 else
aa7bca9b
L
18241 {
18242 printf ("x86 feature: ");
a9eafb08
L
18243 decode_x86_feature_1 (bitmask);
18244 }
18245 goto next;
18246
18247 case GNU_PROPERTY_X86_FEATURE_2_USED:
18248 if (datasz != 4)
18249 printf (_("x86 feature used: <corrupt length: %#x> "),
18250 datasz);
18251 else
18252 {
18253 printf ("x86 feature used: ");
18254 decode_x86_feature_2 (bitmask);
18255 }
18256 goto next;
18257
18258 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
18259 if (datasz != 4)
18260 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
18261 else
18262 {
18263 printf ("x86 feature needed: ");
18264 decode_x86_feature_2 (bitmask);
18265 }
18266 goto next;
18267
18268 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
18269 if (datasz != 4)
18270 printf (_("x86 ISA used: <corrupt length: %#x> "),
18271 datasz);
18272 else
18273 {
18274 printf ("x86 ISA used: ");
18275 decode_x86_compat_isa (bitmask);
18276 }
18277 goto next;
18278
18279 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
18280 if (datasz != 4)
18281 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18282 datasz);
18283 else
18284 {
18285 printf ("x86 ISA needed: ");
18286 decode_x86_compat_isa (bitmask);
aa7bca9b 18287 }
ee2fdd6f
L
18288 goto next;
18289
1fc87489
L
18290 default:
18291 break;
18292 }
18293 }
cd702818
SD
18294 else if (filedata->file_header.e_machine == EM_AARCH64)
18295 {
18296 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
18297 {
18298 printf ("AArch64 feature: ");
18299 if (datasz != 4)
18300 printf (_("<corrupt length: %#x> "), datasz);
18301 else
18302 decode_aarch64_feature_1_and (byte_get (ptr, 4));
18303 goto next;
18304 }
18305 }
1fc87489
L
18306 }
18307 else
18308 {
18309 switch (type)
9ef920e9 18310 {
1fc87489
L
18311 case GNU_PROPERTY_STACK_SIZE:
18312 printf (_("stack size: "));
18313 if (datasz != size)
18314 printf (_("<corrupt length: %#x> "), datasz);
18315 else
18316 printf ("%#lx", (unsigned long) byte_get (ptr, size));
18317 goto next;
18318
18319 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
18320 printf ("no copy on protected ");
18321 if (datasz)
18322 printf (_("<corrupt length: %#x> "), datasz);
18323 goto next;
18324
18325 default:
9ef920e9
NC
18326 break;
18327 }
9ef920e9
NC
18328 }
18329
1fc87489
L
18330 if (type < GNU_PROPERTY_LOPROC)
18331 printf (_("<unknown type %#x data: "), type);
18332 else if (type < GNU_PROPERTY_LOUSER)
18333 printf (_("<procesor-specific type %#x data: "), type);
18334 else
18335 printf (_("<application-specific type %#x data: "), type);
18336 for (j = 0; j < datasz; ++j)
18337 printf ("%02x ", ptr[j] & 0xff);
18338 printf (">");
18339
dc1e8a47 18340 next:
9ef920e9 18341 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
18342 if (ptr == ptr_end)
18343 break;
1fc87489 18344
6ab2c4ed
MC
18345 if (do_wide)
18346 printf (", ");
18347 else
18348 printf ("\n\t");
9ef920e9
NC
18349 }
18350
18351 printf ("\n");
18352}
18353
32ec8896 18354static bfd_boolean
dda8d76d 18355print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 18356{
1449284b 18357 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
18358 switch (pnote->type)
18359 {
18360 case NT_GNU_BUILD_ID:
18361 {
18362 unsigned long i;
18363
18364 printf (_(" Build ID: "));
18365 for (i = 0; i < pnote->descsz; ++i)
18366 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 18367 printf ("\n");
664f90a3
TT
18368 }
18369 break;
18370
18371 case NT_GNU_ABI_TAG:
18372 {
18373 unsigned long os, major, minor, subminor;
18374 const char *osname;
18375
3102e897
NC
18376 /* PR 17531: file: 030-599401-0.004. */
18377 if (pnote->descsz < 16)
18378 {
18379 printf (_(" <corrupt GNU_ABI_TAG>\n"));
18380 break;
18381 }
18382
664f90a3
TT
18383 os = byte_get ((unsigned char *) pnote->descdata, 4);
18384 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
18385 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
18386 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
18387
18388 switch (os)
18389 {
18390 case GNU_ABI_TAG_LINUX:
18391 osname = "Linux";
18392 break;
18393 case GNU_ABI_TAG_HURD:
18394 osname = "Hurd";
18395 break;
18396 case GNU_ABI_TAG_SOLARIS:
18397 osname = "Solaris";
18398 break;
18399 case GNU_ABI_TAG_FREEBSD:
18400 osname = "FreeBSD";
18401 break;
18402 case GNU_ABI_TAG_NETBSD:
18403 osname = "NetBSD";
18404 break;
14ae95f2
RM
18405 case GNU_ABI_TAG_SYLLABLE:
18406 osname = "Syllable";
18407 break;
18408 case GNU_ABI_TAG_NACL:
18409 osname = "NaCl";
18410 break;
664f90a3
TT
18411 default:
18412 osname = "Unknown";
18413 break;
18414 }
18415
18416 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
18417 major, minor, subminor);
18418 }
18419 break;
926c5385
CC
18420
18421 case NT_GNU_GOLD_VERSION:
18422 {
18423 unsigned long i;
18424
18425 printf (_(" Version: "));
18426 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
18427 printf ("%c", pnote->descdata[i]);
18428 printf ("\n");
18429 }
18430 break;
1449284b
NC
18431
18432 case NT_GNU_HWCAP:
18433 {
18434 unsigned long num_entries, mask;
18435
18436 /* Hardware capabilities information. Word 0 is the number of entries.
18437 Word 1 is a bitmask of enabled entries. The rest of the descriptor
18438 is a series of entries, where each entry is a single byte followed
18439 by a nul terminated string. The byte gives the bit number to test
18440 if enabled in the bitmask. */
18441 printf (_(" Hardware Capabilities: "));
18442 if (pnote->descsz < 8)
18443 {
32ec8896
NC
18444 error (_("<corrupt GNU_HWCAP>\n"));
18445 return FALSE;
1449284b
NC
18446 }
18447 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
18448 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
18449 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
18450 /* FIXME: Add code to display the entries... */
18451 }
18452 break;
18453
9ef920e9 18454 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 18455 print_gnu_property_note (filedata, pnote);
9ef920e9 18456 break;
9abca702 18457
1449284b
NC
18458 default:
18459 /* Handle unrecognised types. An error message should have already been
18460 created by get_gnu_elf_note_type(), so all that we need to do is to
18461 display the data. */
18462 {
18463 unsigned long i;
18464
18465 printf (_(" Description data: "));
18466 for (i = 0; i < pnote->descsz; ++i)
18467 printf ("%02x ", pnote->descdata[i] & 0xff);
18468 printf ("\n");
18469 }
18470 break;
664f90a3
TT
18471 }
18472
32ec8896 18473 return TRUE;
664f90a3
TT
18474}
18475
685080f2
NC
18476static const char *
18477get_v850_elf_note_type (enum v850_notes n_type)
18478{
18479 static char buff[64];
18480
18481 switch (n_type)
18482 {
18483 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
18484 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
18485 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
18486 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
18487 case V850_NOTE_CACHE_INFO: return _("Use of cache");
18488 case V850_NOTE_MMU_INFO: return _("Use of MMU");
18489 default:
18490 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
18491 return buff;
18492 }
18493}
18494
32ec8896 18495static bfd_boolean
685080f2
NC
18496print_v850_note (Elf_Internal_Note * pnote)
18497{
18498 unsigned int val;
18499
18500 if (pnote->descsz != 4)
32ec8896
NC
18501 return FALSE;
18502
685080f2
NC
18503 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
18504
18505 if (val == 0)
18506 {
18507 printf (_("not set\n"));
32ec8896 18508 return TRUE;
685080f2
NC
18509 }
18510
18511 switch (pnote->type)
18512 {
18513 case V850_NOTE_ALIGNMENT:
18514 switch (val)
18515 {
32ec8896
NC
18516 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return TRUE;
18517 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return TRUE;
685080f2
NC
18518 }
18519 break;
14ae95f2 18520
685080f2
NC
18521 case V850_NOTE_DATA_SIZE:
18522 switch (val)
18523 {
32ec8896
NC
18524 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return TRUE;
18525 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return TRUE;
685080f2
NC
18526 }
18527 break;
14ae95f2 18528
685080f2
NC
18529 case V850_NOTE_FPU_INFO:
18530 switch (val)
18531 {
32ec8896
NC
18532 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return TRUE;
18533 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return TRUE;
685080f2
NC
18534 }
18535 break;
14ae95f2 18536
685080f2
NC
18537 case V850_NOTE_MMU_INFO:
18538 case V850_NOTE_CACHE_INFO:
18539 case V850_NOTE_SIMD_INFO:
18540 if (val == EF_RH850_SIMD)
18541 {
18542 printf (_("yes\n"));
32ec8896 18543 return TRUE;
685080f2
NC
18544 }
18545 break;
18546
18547 default:
18548 /* An 'unknown note type' message will already have been displayed. */
18549 break;
18550 }
18551
18552 printf (_("unknown value: %x\n"), val);
32ec8896 18553 return FALSE;
685080f2
NC
18554}
18555
32ec8896 18556static bfd_boolean
c6056a74
SF
18557process_netbsd_elf_note (Elf_Internal_Note * pnote)
18558{
18559 unsigned int version;
18560
18561 switch (pnote->type)
18562 {
18563 case NT_NETBSD_IDENT:
b966f55f
AM
18564 if (pnote->descsz < 1)
18565 break;
c6056a74
SF
18566 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
18567 if ((version / 10000) % 100)
b966f55f 18568 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
18569 version, version / 100000000, (version / 1000000) % 100,
18570 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 18571 'A' + (version / 10000) % 26);
c6056a74
SF
18572 else
18573 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 18574 version, version / 100000000, (version / 1000000) % 100,
15f205b1 18575 (version / 100) % 100);
32ec8896 18576 return TRUE;
c6056a74
SF
18577
18578 case NT_NETBSD_MARCH:
9abca702 18579 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 18580 pnote->descdata);
32ec8896 18581 return TRUE;
c6056a74 18582
9abca702
CZ
18583#ifdef NT_NETBSD_PAX
18584 case NT_NETBSD_PAX:
b966f55f
AM
18585 if (pnote->descsz < 1)
18586 break;
9abca702
CZ
18587 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
18588 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
18589 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
18590 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
18591 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
18592 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
18593 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
18594 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
18595 return TRUE;
18596#endif
c6056a74 18597 }
b966f55f
AM
18598
18599 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
18600 pnote->descsz, pnote->type);
18601 return FALSE;
c6056a74
SF
18602}
18603
f4ddf30f 18604static const char *
dda8d76d 18605get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 18606{
f4ddf30f
JB
18607 switch (e_type)
18608 {
18609 case NT_FREEBSD_THRMISC:
18610 return _("NT_THRMISC (thrmisc structure)");
18611 case NT_FREEBSD_PROCSTAT_PROC:
18612 return _("NT_PROCSTAT_PROC (proc data)");
18613 case NT_FREEBSD_PROCSTAT_FILES:
18614 return _("NT_PROCSTAT_FILES (files data)");
18615 case NT_FREEBSD_PROCSTAT_VMMAP:
18616 return _("NT_PROCSTAT_VMMAP (vmmap data)");
18617 case NT_FREEBSD_PROCSTAT_GROUPS:
18618 return _("NT_PROCSTAT_GROUPS (groups data)");
18619 case NT_FREEBSD_PROCSTAT_UMASK:
18620 return _("NT_PROCSTAT_UMASK (umask data)");
18621 case NT_FREEBSD_PROCSTAT_RLIMIT:
18622 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
18623 case NT_FREEBSD_PROCSTAT_OSREL:
18624 return _("NT_PROCSTAT_OSREL (osreldate data)");
18625 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
18626 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
18627 case NT_FREEBSD_PROCSTAT_AUXV:
18628 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
18629 case NT_FREEBSD_PTLWPINFO:
18630 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 18631 }
dda8d76d 18632 return get_note_type (filedata, e_type);
f4ddf30f
JB
18633}
18634
9437c45b 18635static const char *
dda8d76d 18636get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
18637{
18638 static char buff[64];
18639
540e6170
CZ
18640 switch (e_type)
18641 {
18642 case NT_NETBSDCORE_PROCINFO:
18643 /* NetBSD core "procinfo" structure. */
18644 return _("NetBSD procinfo structure");
9437c45b 18645
540e6170
CZ
18646#ifdef NT_NETBSDCORE_AUXV
18647 case NT_NETBSDCORE_AUXV:
18648 return _("NetBSD ELF auxiliary vector data");
18649#endif
9437c45b 18650
06d949ec
KR
18651#ifdef NT_NETBSDCORE_LWPSTATUS
18652 case NT_NETBSDCORE_LWPSTATUS:
18653 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
18654#endif
18655
540e6170 18656 default:
06d949ec 18657 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
18658 defined for NetBSD core files. If the note type is less
18659 than the start of the machine-dependent note types, we don't
18660 understand it. */
18661
18662 if (e_type < NT_NETBSDCORE_FIRSTMACH)
18663 {
18664 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18665 return buff;
18666 }
18667 break;
9437c45b
JT
18668 }
18669
dda8d76d 18670 switch (filedata->file_header.e_machine)
9437c45b
JT
18671 {
18672 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
18673 and PT_GETFPREGS == mach+2. */
18674
18675 case EM_OLD_ALPHA:
18676 case EM_ALPHA:
18677 case EM_SPARC:
18678 case EM_SPARC32PLUS:
18679 case EM_SPARCV9:
18680 switch (e_type)
18681 {
2b692964 18682 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 18683 return _("PT_GETREGS (reg structure)");
2b692964 18684 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 18685 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
18686 default:
18687 break;
18688 }
18689 break;
18690
c0d38b0e
CZ
18691 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
18692 There's also old PT___GETREGS40 == mach + 1 for old reg
18693 structure which lacks GBR. */
18694 case EM_SH:
18695 switch (e_type)
18696 {
18697 case NT_NETBSDCORE_FIRSTMACH + 1:
18698 return _("PT___GETREGS40 (old reg structure)");
18699 case NT_NETBSDCORE_FIRSTMACH + 3:
18700 return _("PT_GETREGS (reg structure)");
18701 case NT_NETBSDCORE_FIRSTMACH + 5:
18702 return _("PT_GETFPREGS (fpreg structure)");
18703 default:
18704 break;
18705 }
18706 break;
18707
9437c45b
JT
18708 /* On all other arch's, PT_GETREGS == mach+1 and
18709 PT_GETFPREGS == mach+3. */
18710 default:
18711 switch (e_type)
18712 {
2b692964 18713 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 18714 return _("PT_GETREGS (reg structure)");
2b692964 18715 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 18716 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
18717 default:
18718 break;
18719 }
18720 }
18721
9cf03b7e 18722 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 18723 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
18724 return buff;
18725}
18726
70616151
TT
18727static const char *
18728get_stapsdt_note_type (unsigned e_type)
18729{
18730 static char buff[64];
18731
18732 switch (e_type)
18733 {
18734 case NT_STAPSDT:
18735 return _("NT_STAPSDT (SystemTap probe descriptors)");
18736
18737 default:
18738 break;
18739 }
18740
18741 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18742 return buff;
18743}
18744
32ec8896 18745static bfd_boolean
c6a9fc58
TT
18746print_stapsdt_note (Elf_Internal_Note *pnote)
18747{
3ca60c57
NC
18748 size_t len, maxlen;
18749 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
18750 char *data = pnote->descdata;
18751 char *data_end = pnote->descdata + pnote->descsz;
18752 bfd_vma pc, base_addr, semaphore;
18753 char *provider, *probe, *arg_fmt;
18754
3ca60c57
NC
18755 if (pnote->descsz < (addr_size * 3))
18756 goto stapdt_note_too_small;
18757
c6a9fc58
TT
18758 pc = byte_get ((unsigned char *) data, addr_size);
18759 data += addr_size;
3ca60c57 18760
c6a9fc58
TT
18761 base_addr = byte_get ((unsigned char *) data, addr_size);
18762 data += addr_size;
3ca60c57 18763
c6a9fc58
TT
18764 semaphore = byte_get ((unsigned char *) data, addr_size);
18765 data += addr_size;
18766
3ca60c57
NC
18767 if (data >= data_end)
18768 goto stapdt_note_too_small;
18769 maxlen = data_end - data;
18770 len = strnlen (data, maxlen);
18771 if (len < maxlen)
18772 {
18773 provider = data;
18774 data += len + 1;
18775 }
18776 else
18777 goto stapdt_note_too_small;
18778
18779 if (data >= data_end)
18780 goto stapdt_note_too_small;
18781 maxlen = data_end - data;
18782 len = strnlen (data, maxlen);
18783 if (len < maxlen)
18784 {
18785 probe = data;
18786 data += len + 1;
18787 }
18788 else
18789 goto stapdt_note_too_small;
9abca702 18790
3ca60c57
NC
18791 if (data >= data_end)
18792 goto stapdt_note_too_small;
18793 maxlen = data_end - data;
18794 len = strnlen (data, maxlen);
18795 if (len < maxlen)
18796 {
18797 arg_fmt = data;
18798 data += len + 1;
18799 }
18800 else
18801 goto stapdt_note_too_small;
c6a9fc58
TT
18802
18803 printf (_(" Provider: %s\n"), provider);
18804 printf (_(" Name: %s\n"), probe);
18805 printf (_(" Location: "));
18806 print_vma (pc, FULL_HEX);
18807 printf (_(", Base: "));
18808 print_vma (base_addr, FULL_HEX);
18809 printf (_(", Semaphore: "));
18810 print_vma (semaphore, FULL_HEX);
9cf03b7e 18811 printf ("\n");
c6a9fc58
TT
18812 printf (_(" Arguments: %s\n"), arg_fmt);
18813
18814 return data == data_end;
3ca60c57
NC
18815
18816 stapdt_note_too_small:
18817 printf (_(" <corrupt - note is too small>\n"));
18818 error (_("corrupt stapdt note - the data size is too small\n"));
18819 return FALSE;
c6a9fc58
TT
18820}
18821
00e98fc7
TG
18822static const char *
18823get_ia64_vms_note_type (unsigned e_type)
18824{
18825 static char buff[64];
18826
18827 switch (e_type)
18828 {
18829 case NT_VMS_MHD:
18830 return _("NT_VMS_MHD (module header)");
18831 case NT_VMS_LNM:
18832 return _("NT_VMS_LNM (language name)");
18833 case NT_VMS_SRC:
18834 return _("NT_VMS_SRC (source files)");
18835 case NT_VMS_TITLE:
9cf03b7e 18836 return "NT_VMS_TITLE";
00e98fc7
TG
18837 case NT_VMS_EIDC:
18838 return _("NT_VMS_EIDC (consistency check)");
18839 case NT_VMS_FPMODE:
18840 return _("NT_VMS_FPMODE (FP mode)");
18841 case NT_VMS_LINKTIME:
9cf03b7e 18842 return "NT_VMS_LINKTIME";
00e98fc7
TG
18843 case NT_VMS_IMGNAM:
18844 return _("NT_VMS_IMGNAM (image name)");
18845 case NT_VMS_IMGID:
18846 return _("NT_VMS_IMGID (image id)");
18847 case NT_VMS_LINKID:
18848 return _("NT_VMS_LINKID (link id)");
18849 case NT_VMS_IMGBID:
18850 return _("NT_VMS_IMGBID (build id)");
18851 case NT_VMS_GSTNAM:
18852 return _("NT_VMS_GSTNAM (sym table name)");
18853 case NT_VMS_ORIG_DYN:
9cf03b7e 18854 return "NT_VMS_ORIG_DYN";
00e98fc7 18855 case NT_VMS_PATCHTIME:
9cf03b7e 18856 return "NT_VMS_PATCHTIME";
00e98fc7
TG
18857 default:
18858 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18859 return buff;
18860 }
18861}
18862
32ec8896 18863static bfd_boolean
00e98fc7
TG
18864print_ia64_vms_note (Elf_Internal_Note * pnote)
18865{
8d18bf79
NC
18866 int maxlen = pnote->descsz;
18867
18868 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
18869 goto desc_size_fail;
18870
00e98fc7
TG
18871 switch (pnote->type)
18872 {
18873 case NT_VMS_MHD:
8d18bf79
NC
18874 if (maxlen <= 36)
18875 goto desc_size_fail;
18876
18877 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
18878
18879 printf (_(" Creation date : %.17s\n"), pnote->descdata);
18880 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
18881 if (l + 34 < maxlen)
18882 {
18883 printf (_(" Module name : %s\n"), pnote->descdata + 34);
18884 if (l + 35 < maxlen)
18885 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
18886 else
18887 printf (_(" Module version : <missing>\n"));
18888 }
00e98fc7 18889 else
8d18bf79
NC
18890 {
18891 printf (_(" Module name : <missing>\n"));
18892 printf (_(" Module version : <missing>\n"));
18893 }
00e98fc7 18894 break;
8d18bf79 18895
00e98fc7 18896 case NT_VMS_LNM:
8d18bf79 18897 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18898 break;
8d18bf79 18899
00e98fc7
TG
18900#ifdef BFD64
18901 case NT_VMS_FPMODE:
9cf03b7e 18902 printf (_(" Floating Point mode: "));
8d18bf79
NC
18903 if (maxlen < 8)
18904 goto desc_size_fail;
18905 /* FIXME: Generate an error if descsz > 8 ? */
18906
4a5cb34f 18907 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 18908 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 18909 break;
8d18bf79 18910
00e98fc7
TG
18911 case NT_VMS_LINKTIME:
18912 printf (_(" Link time: "));
8d18bf79
NC
18913 if (maxlen < 8)
18914 goto desc_size_fail;
18915 /* FIXME: Generate an error if descsz > 8 ? */
18916
00e98fc7 18917 print_vms_time
8d18bf79 18918 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
18919 printf ("\n");
18920 break;
8d18bf79 18921
00e98fc7
TG
18922 case NT_VMS_PATCHTIME:
18923 printf (_(" Patch time: "));
8d18bf79
NC
18924 if (maxlen < 8)
18925 goto desc_size_fail;
18926 /* FIXME: Generate an error if descsz > 8 ? */
18927
00e98fc7 18928 print_vms_time
8d18bf79 18929 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
18930 printf ("\n");
18931 break;
8d18bf79 18932
00e98fc7 18933 case NT_VMS_ORIG_DYN:
8d18bf79
NC
18934 if (maxlen < 34)
18935 goto desc_size_fail;
18936
00e98fc7
TG
18937 printf (_(" Major id: %u, minor id: %u\n"),
18938 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
18939 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 18940 printf (_(" Last modified : "));
00e98fc7
TG
18941 print_vms_time
18942 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 18943 printf (_("\n Link flags : "));
4a5cb34f 18944 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 18945 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 18946 printf (_(" Header flags: 0x%08x\n"),
948f632f 18947 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 18948 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
18949 break;
18950#endif
8d18bf79 18951
00e98fc7 18952 case NT_VMS_IMGNAM:
8d18bf79 18953 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18954 break;
8d18bf79 18955
00e98fc7 18956 case NT_VMS_GSTNAM:
8d18bf79 18957 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18958 break;
8d18bf79 18959
00e98fc7 18960 case NT_VMS_IMGID:
8d18bf79 18961 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18962 break;
8d18bf79 18963
00e98fc7 18964 case NT_VMS_LINKID:
8d18bf79 18965 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 18966 break;
8d18bf79 18967
00e98fc7 18968 default:
32ec8896 18969 return FALSE;
00e98fc7 18970 }
8d18bf79 18971
32ec8896 18972 return TRUE;
8d18bf79
NC
18973
18974 desc_size_fail:
18975 printf (_(" <corrupt - data size is too small>\n"));
18976 error (_("corrupt IA64 note: data size is too small\n"));
18977 return FALSE;
00e98fc7
TG
18978}
18979
fd486f32
AM
18980struct build_attr_cache {
18981 Filedata *filedata;
18982 char *strtab;
18983 unsigned long strtablen;
18984 Elf_Internal_Sym *symtab;
18985 unsigned long nsyms;
18986} ba_cache;
18987
6f156d7a
NC
18988/* Find the symbol associated with a build attribute that is attached
18989 to address OFFSET. If PNAME is non-NULL then store the name of
18990 the symbol (if found) in the provided pointer, Returns NULL if a
18991 symbol could not be found. */
c799a79d 18992
6f156d7a
NC
18993static Elf_Internal_Sym *
18994get_symbol_for_build_attribute (Filedata * filedata,
18995 unsigned long offset,
18996 bfd_boolean is_open_attr,
18997 const char ** pname)
9ef920e9 18998{
fd486f32
AM
18999 Elf_Internal_Sym *saved_sym = NULL;
19000 Elf_Internal_Sym *sym;
9ef920e9 19001
dda8d76d 19002 if (filedata->section_headers != NULL
fd486f32 19003 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 19004 {
c799a79d 19005 Elf_Internal_Shdr * symsec;
9ef920e9 19006
fd486f32
AM
19007 free (ba_cache.strtab);
19008 ba_cache.strtab = NULL;
19009 free (ba_cache.symtab);
19010 ba_cache.symtab = NULL;
19011
c799a79d 19012 /* Load the symbol and string sections. */
dda8d76d
NC
19013 for (symsec = filedata->section_headers;
19014 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 19015 symsec ++)
9ef920e9 19016 {
28d13567
AM
19017 if (symsec->sh_type == SHT_SYMTAB
19018 && get_symtab (filedata, symsec,
19019 &ba_cache.symtab, &ba_cache.nsyms,
19020 &ba_cache.strtab, &ba_cache.strtablen))
19021 break;
9ef920e9 19022 }
fd486f32 19023 ba_cache.filedata = filedata;
9ef920e9
NC
19024 }
19025
fd486f32 19026 if (ba_cache.symtab == NULL)
6f156d7a 19027 return NULL;
9ef920e9 19028
c799a79d 19029 /* Find a symbol whose value matches offset. */
fd486f32 19030 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
19031 if (sym->st_value == offset)
19032 {
fd486f32 19033 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
19034 /* Huh ? This should not happen. */
19035 continue;
9ef920e9 19036
fd486f32 19037 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 19038 continue;
9ef920e9 19039
8fd75781
NC
19040 /* The AArch64 and ARM architectures define mapping symbols
19041 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
19042 if (ba_cache.strtab[sym->st_name] == '$'
19043 && ba_cache.strtab[sym->st_name + 1] != 0
19044 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
19045 continue;
19046
c799a79d
NC
19047 if (is_open_attr)
19048 {
19049 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
19050 and FILE or OBJECT symbols over NOTYPE symbols. We skip
19051 FUNC symbols entirely. */
19052 switch (ELF_ST_TYPE (sym->st_info))
19053 {
c799a79d 19054 case STT_OBJECT:
6f156d7a 19055 case STT_FILE:
c799a79d 19056 saved_sym = sym;
6f156d7a
NC
19057 if (sym->st_size)
19058 {
19059 /* If the symbol has a size associated
19060 with it then we can stop searching. */
fd486f32 19061 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 19062 }
c799a79d 19063 continue;
9ef920e9 19064
c799a79d
NC
19065 case STT_FUNC:
19066 /* Ignore function symbols. */
19067 continue;
19068
19069 default:
19070 break;
19071 }
19072
19073 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 19074 {
c799a79d
NC
19075 case STB_GLOBAL:
19076 if (saved_sym == NULL
19077 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
19078 saved_sym = sym;
19079 break;
c871dade 19080
c799a79d
NC
19081 case STB_LOCAL:
19082 if (saved_sym == NULL)
19083 saved_sym = sym;
19084 break;
19085
19086 default:
9ef920e9
NC
19087 break;
19088 }
19089 }
c799a79d
NC
19090 else
19091 {
19092 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
19093 continue;
19094
19095 saved_sym = sym;
19096 break;
19097 }
19098 }
19099
6f156d7a 19100 if (saved_sym && pname)
fd486f32 19101 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
19102
19103 return saved_sym;
c799a79d
NC
19104}
19105
d20e98ab
NC
19106/* Returns true iff addr1 and addr2 are in the same section. */
19107
19108static bfd_boolean
19109same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
19110{
19111 Elf_Internal_Shdr * a1;
19112 Elf_Internal_Shdr * a2;
19113
19114 a1 = find_section_by_address (filedata, addr1);
19115 a2 = find_section_by_address (filedata, addr2);
9abca702 19116
d20e98ab
NC
19117 return a1 == a2 && a1 != NULL;
19118}
19119
c799a79d 19120static bfd_boolean
dda8d76d
NC
19121print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
19122 Filedata * filedata)
c799a79d 19123{
6f156d7a
NC
19124 static unsigned long global_offset = 0;
19125 static unsigned long global_end = 0;
19126 static unsigned long func_offset = 0;
19127 static unsigned long func_end = 0;
c871dade 19128
6f156d7a
NC
19129 Elf_Internal_Sym * sym;
19130 const char * name;
19131 unsigned long start;
19132 unsigned long end;
19133 bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
19134
19135 switch (pnote->descsz)
c799a79d 19136 {
6f156d7a
NC
19137 case 0:
19138 /* A zero-length description means that the range of
19139 the previous note of the same type should be used. */
c799a79d 19140 if (is_open_attr)
c871dade 19141 {
6f156d7a
NC
19142 if (global_end > global_offset)
19143 printf (_(" Applies to region from %#lx to %#lx\n"),
19144 global_offset, global_end);
19145 else
19146 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
19147 }
19148 else
19149 {
6f156d7a
NC
19150 if (func_end > func_offset)
19151 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
19152 else
19153 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 19154 }
6f156d7a 19155 return TRUE;
9ef920e9 19156
6f156d7a
NC
19157 case 4:
19158 start = byte_get ((unsigned char *) pnote->descdata, 4);
19159 end = 0;
19160 break;
19161
19162 case 8:
19163 if (is_32bit_elf)
19164 {
19165 /* FIXME: We should check that version 3+ notes are being used here... */
19166 start = byte_get ((unsigned char *) pnote->descdata, 4);
19167 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19168 }
19169 else
19170 {
19171 start = byte_get ((unsigned char *) pnote->descdata, 8);
19172 end = 0;
19173 }
19174 break;
19175
19176 case 16:
19177 start = byte_get ((unsigned char *) pnote->descdata, 8);
19178 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
19179 break;
9abca702 19180
6f156d7a 19181 default:
c799a79d
NC
19182 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
19183 printf (_(" <invalid descsz>"));
19184 return FALSE;
19185 }
19186
6f156d7a
NC
19187 name = NULL;
19188 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
19189 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
19190 in order to avoid them being confused with the start address of the
19191 first function in the file... */
19192 if (sym == NULL && is_open_attr)
19193 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
19194 & name);
6f156d7a
NC
19195
19196 if (end == 0 && sym != NULL && sym->st_size > 0)
19197 end = start + sym->st_size;
c799a79d
NC
19198
19199 if (is_open_attr)
19200 {
d20e98ab
NC
19201 /* FIXME: Need to properly allow for section alignment.
19202 16 is just the alignment used on x86_64. */
19203 if (global_end > 0
19204 && start > BFD_ALIGN (global_end, 16)
19205 /* Build notes are not guaranteed to be organised in order of
19206 increasing address, but we should find the all of the notes
19207 for one section in the same place. */
19208 && same_section (filedata, start, global_end))
6f156d7a
NC
19209 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
19210 global_end + 1, start - 1);
19211
19212 printf (_(" Applies to region from %#lx"), start);
19213 global_offset = start;
19214
19215 if (end)
19216 {
19217 printf (_(" to %#lx"), end);
19218 global_end = end;
19219 }
c799a79d
NC
19220 }
19221 else
19222 {
6f156d7a
NC
19223 printf (_(" Applies to region from %#lx"), start);
19224 func_offset = start;
19225
19226 if (end)
19227 {
19228 printf (_(" to %#lx"), end);
19229 func_end = end;
19230 }
c799a79d
NC
19231 }
19232
6f156d7a
NC
19233 if (sym && name)
19234 printf (_(" (%s)"), name);
19235
19236 printf ("\n");
19237 return TRUE;
9ef920e9
NC
19238}
19239
19240static bfd_boolean
19241print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
19242{
1d15e434
NC
19243 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
19244 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
19245 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
19246 char name_type;
19247 char name_attribute;
1d15e434 19248 const char * expected_types;
9ef920e9
NC
19249 const char * name = pnote->namedata;
19250 const char * text;
88305e1b 19251 signed int left;
9ef920e9
NC
19252
19253 if (name == NULL || pnote->namesz < 2)
19254 {
19255 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 19256 print_symbol (-20, _(" <corrupt name>"));
9ef920e9
NC
19257 return FALSE;
19258 }
19259
6f156d7a
NC
19260 if (do_wide)
19261 left = 28;
19262 else
19263 left = 20;
88305e1b
NC
19264
19265 /* Version 2 of the spec adds a "GA" prefix to the name field. */
19266 if (name[0] == 'G' && name[1] == 'A')
19267 {
6f156d7a
NC
19268 if (pnote->namesz < 4)
19269 {
19270 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
19271 print_symbol (-20, _(" <corrupt name>"));
19272 return FALSE;
19273 }
19274
88305e1b
NC
19275 printf ("GA");
19276 name += 2;
19277 left -= 2;
19278 }
19279
9ef920e9
NC
19280 switch ((name_type = * name))
19281 {
19282 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
19283 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
19284 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
19285 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
19286 printf ("%c", * name);
88305e1b 19287 left --;
9ef920e9
NC
19288 break;
19289 default:
19290 error (_("unrecognised attribute type in name field: %d\n"), name_type);
19291 print_symbol (-20, _("<unknown name type>"));
19292 return FALSE;
19293 }
19294
9ef920e9
NC
19295 ++ name;
19296 text = NULL;
19297
19298 switch ((name_attribute = * name))
19299 {
19300 case GNU_BUILD_ATTRIBUTE_VERSION:
19301 text = _("<version>");
1d15e434 19302 expected_types = string_expected;
9ef920e9
NC
19303 ++ name;
19304 break;
19305 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
19306 text = _("<stack prot>");
75d7d298 19307 expected_types = "!+*";
9ef920e9
NC
19308 ++ name;
19309 break;
19310 case GNU_BUILD_ATTRIBUTE_RELRO:
19311 text = _("<relro>");
1d15e434 19312 expected_types = bool_expected;
9ef920e9
NC
19313 ++ name;
19314 break;
19315 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
19316 text = _("<stack size>");
1d15e434 19317 expected_types = number_expected;
9ef920e9
NC
19318 ++ name;
19319 break;
19320 case GNU_BUILD_ATTRIBUTE_TOOL:
19321 text = _("<tool>");
1d15e434 19322 expected_types = string_expected;
9ef920e9
NC
19323 ++ name;
19324 break;
19325 case GNU_BUILD_ATTRIBUTE_ABI:
19326 text = _("<ABI>");
19327 expected_types = "$*";
19328 ++ name;
19329 break;
19330 case GNU_BUILD_ATTRIBUTE_PIC:
19331 text = _("<PIC>");
1d15e434 19332 expected_types = number_expected;
9ef920e9
NC
19333 ++ name;
19334 break;
a8be5506
NC
19335 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
19336 text = _("<short enum>");
1d15e434 19337 expected_types = bool_expected;
a8be5506
NC
19338 ++ name;
19339 break;
9ef920e9
NC
19340 default:
19341 if (ISPRINT (* name))
19342 {
19343 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
19344
19345 if (len > left && ! do_wide)
19346 len = left;
75d7d298 19347 printf ("%.*s:", len, name);
9ef920e9 19348 left -= len;
0dd6ae21 19349 name += len;
9ef920e9
NC
19350 }
19351 else
19352 {
3e6b6445 19353 static char tmpbuf [128];
88305e1b 19354
3e6b6445
NC
19355 error (_("unrecognised byte in name field: %d\n"), * name);
19356 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
19357 text = tmpbuf;
19358 name ++;
9ef920e9
NC
19359 }
19360 expected_types = "*$!+";
19361 break;
19362 }
19363
19364 if (text)
88305e1b 19365 left -= printf ("%s", text);
9ef920e9
NC
19366
19367 if (strchr (expected_types, name_type) == NULL)
75d7d298 19368 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
19369
19370 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
19371 {
19372 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
19373 (unsigned long) pnote->namesz,
19374 (long) (name - pnote->namedata));
19375 return FALSE;
19376 }
19377
19378 if (left < 1 && ! do_wide)
19379 return TRUE;
19380
19381 switch (name_type)
19382 {
19383 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
19384 {
b06b2c92 19385 unsigned int bytes;
ddef72cd
NC
19386 unsigned long long val = 0;
19387 unsigned int shift = 0;
19388 char * decoded = NULL;
19389
b06b2c92
NC
19390 bytes = pnote->namesz - (name - pnote->namedata);
19391 if (bytes > 0)
19392 /* The -1 is because the name field is always 0 terminated, and we
19393 want to be able to ensure that the shift in the while loop below
19394 will not overflow. */
19395 -- bytes;
19396
ddef72cd
NC
19397 if (bytes > sizeof (val))
19398 {
3e6b6445
NC
19399 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
19400 bytes);
19401 bytes = sizeof (val);
ddef72cd 19402 }
3e6b6445
NC
19403 /* We do not bother to warn if bytes == 0 as this can
19404 happen with some early versions of the gcc plugin. */
9ef920e9
NC
19405
19406 while (bytes --)
19407 {
79a964dc
NC
19408 unsigned long byte = (* name ++) & 0xff;
19409
19410 val |= byte << shift;
9ef920e9
NC
19411 shift += 8;
19412 }
19413
75d7d298 19414 switch (name_attribute)
9ef920e9 19415 {
75d7d298 19416 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
19417 switch (val)
19418 {
75d7d298
NC
19419 case 0: decoded = "static"; break;
19420 case 1: decoded = "pic"; break;
19421 case 2: decoded = "PIC"; break;
19422 case 3: decoded = "pie"; break;
19423 case 4: decoded = "PIE"; break;
19424 default: break;
9ef920e9 19425 }
75d7d298
NC
19426 break;
19427 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
19428 switch (val)
9ef920e9 19429 {
75d7d298
NC
19430 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
19431 case 0: decoded = "off"; break;
19432 case 1: decoded = "on"; break;
19433 case 2: decoded = "all"; break;
19434 case 3: decoded = "strong"; break;
19435 case 4: decoded = "explicit"; break;
19436 default: break;
9ef920e9 19437 }
75d7d298
NC
19438 break;
19439 default:
19440 break;
9ef920e9
NC
19441 }
19442
75d7d298 19443 if (decoded != NULL)
3e6b6445
NC
19444 {
19445 print_symbol (-left, decoded);
19446 left = 0;
19447 }
19448 else if (val == 0)
19449 {
19450 printf ("0x0");
19451 left -= 3;
19452 }
9ef920e9 19453 else
75d7d298
NC
19454 {
19455 if (do_wide)
ddef72cd 19456 left -= printf ("0x%llx", val);
75d7d298 19457 else
ddef72cd 19458 left -= printf ("0x%-.*llx", left, val);
75d7d298 19459 }
9ef920e9
NC
19460 }
19461 break;
19462 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
19463 left -= print_symbol (- left, name);
19464 break;
19465 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
19466 left -= print_symbol (- left, "true");
19467 break;
19468 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
19469 left -= print_symbol (- left, "false");
19470 break;
19471 }
19472
19473 if (do_wide && left > 0)
19474 printf ("%-*s", left, " ");
9abca702 19475
9ef920e9
NC
19476 return TRUE;
19477}
19478
6d118b09
NC
19479/* Note that by the ELF standard, the name field is already null byte
19480 terminated, and namesz includes the terminating null byte.
19481 I.E. the value of namesz for the name "FSF" is 4.
19482
e3c8793a 19483 If the value of namesz is zero, there is no name present. */
9ef920e9 19484
32ec8896 19485static bfd_boolean
9ef920e9 19486process_note (Elf_Internal_Note * pnote,
dda8d76d 19487 Filedata * filedata)
779fe533 19488{
2cf0635d
NC
19489 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
19490 const char * nt;
9437c45b
JT
19491
19492 if (pnote->namesz == 0)
1ec5cd37
NC
19493 /* If there is no note name, then use the default set of
19494 note type strings. */
dda8d76d 19495 nt = get_note_type (filedata, pnote->type);
1ec5cd37 19496
1118d252
RM
19497 else if (const_strneq (pnote->namedata, "GNU"))
19498 /* GNU-specific object file notes. */
19499 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
19500
19501 else if (const_strneq (pnote->namedata, "FreeBSD"))
19502 /* FreeBSD-specific core file notes. */
dda8d76d 19503 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 19504
0112cd26 19505 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 19506 /* NetBSD-specific core file notes. */
dda8d76d 19507 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 19508
c6056a74
SF
19509 else if (const_strneq (pnote->namedata, "NetBSD"))
19510 /* NetBSD-specific core file notes. */
19511 return process_netbsd_elf_note (pnote);
19512
9abca702
CZ
19513 else if (const_strneq (pnote->namedata, "PaX"))
19514 /* NetBSD-specific core file notes. */
19515 return process_netbsd_elf_note (pnote);
19516
b15fa79e
AM
19517 else if (strneq (pnote->namedata, "SPU/", 4))
19518 {
19519 /* SPU-specific core file notes. */
19520 nt = pnote->namedata + 4;
19521 name = "SPU";
19522 }
19523
00e98fc7
TG
19524 else if (const_strneq (pnote->namedata, "IPF/VMS"))
19525 /* VMS/ia64-specific file notes. */
19526 nt = get_ia64_vms_note_type (pnote->type);
19527
70616151
TT
19528 else if (const_strneq (pnote->namedata, "stapsdt"))
19529 nt = get_stapsdt_note_type (pnote->type);
19530
9437c45b 19531 else
1ec5cd37
NC
19532 /* Don't recognize this note name; just use the default set of
19533 note type strings. */
dda8d76d 19534 nt = get_note_type (filedata, pnote->type);
9437c45b 19535
1449284b 19536 printf (" ");
9ef920e9 19537
483767a3
AM
19538 if (((const_strneq (pnote->namedata, "GA")
19539 && strchr ("*$!+", pnote->namedata[2]) != NULL)
19540 || strchr ("*$!+", pnote->namedata[0]) != NULL)
19541 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
19542 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
19543 print_gnu_build_attribute_name (pnote);
19544 else
19545 print_symbol (-20, name);
19546
19547 if (do_wide)
19548 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
19549 else
19550 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7
TG
19551
19552 if (const_strneq (pnote->namedata, "IPF/VMS"))
19553 return print_ia64_vms_note (pnote);
664f90a3 19554 else if (const_strneq (pnote->namedata, "GNU"))
dda8d76d 19555 return print_gnu_note (filedata, pnote);
c6a9fc58
TT
19556 else if (const_strneq (pnote->namedata, "stapsdt"))
19557 return print_stapsdt_note (pnote);
9ece1fa9
TT
19558 else if (const_strneq (pnote->namedata, "CORE"))
19559 return print_core_note (pnote);
483767a3
AM
19560 else if (((const_strneq (pnote->namedata, "GA")
19561 && strchr ("*$!+", pnote->namedata[2]) != NULL)
19562 || strchr ("*$!+", pnote->namedata[0]) != NULL)
19563 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
19564 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 19565 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 19566
9ef920e9 19567 if (pnote->descsz)
1449284b
NC
19568 {
19569 unsigned long i;
19570
19571 printf (_(" description data: "));
19572 for (i = 0; i < pnote->descsz; i++)
178d8719 19573 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
19574 if (!do_wide)
19575 printf ("\n");
1449284b
NC
19576 }
19577
9ef920e9
NC
19578 if (do_wide)
19579 printf ("\n");
19580
32ec8896 19581 return TRUE;
1449284b 19582}
6d118b09 19583
32ec8896 19584static bfd_boolean
dda8d76d
NC
19585process_notes_at (Filedata * filedata,
19586 Elf_Internal_Shdr * section,
19587 bfd_vma offset,
82ed9683
L
19588 bfd_vma length,
19589 bfd_vma align)
779fe533 19590{
2cf0635d
NC
19591 Elf_External_Note * pnotes;
19592 Elf_External_Note * external;
4dff97b2
NC
19593 char * end;
19594 bfd_boolean res = TRUE;
103f02d3 19595
779fe533 19596 if (length <= 0)
32ec8896 19597 return FALSE;
103f02d3 19598
1449284b
NC
19599 if (section)
19600 {
dda8d76d 19601 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 19602 if (pnotes)
32ec8896 19603 {
dda8d76d 19604 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
19605 {
19606 free (pnotes);
19607 return FALSE;
19608 }
32ec8896 19609 }
1449284b
NC
19610 }
19611 else
82ed9683 19612 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 19613 _("notes"));
4dff97b2 19614
dd24e3da 19615 if (pnotes == NULL)
32ec8896 19616 return FALSE;
779fe533 19617
103f02d3 19618 external = pnotes;
103f02d3 19619
1449284b 19620 if (section)
dda8d76d 19621 printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b
NC
19622 else
19623 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
19624 (unsigned long) offset, (unsigned long) length);
19625
82ed9683
L
19626 /* NB: Some note sections may have alignment value of 0 or 1. gABI
19627 specifies that notes should be aligned to 4 bytes in 32-bit
19628 objects and to 8 bytes in 64-bit objects. As a Linux extension,
19629 we also support 4 byte alignment in 64-bit objects. If section
19630 alignment is less than 4, we treate alignment as 4 bytes. */
19631 if (align < 4)
19632 align = 4;
19633 else if (align != 4 && align != 8)
19634 {
19635 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
19636 (long) align);
a788aedd 19637 free (pnotes);
82ed9683
L
19638 return FALSE;
19639 }
19640
dbe15e4e 19641 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 19642
c8071705
NC
19643 end = (char *) pnotes + length;
19644 while ((char *) external < end)
779fe533 19645 {
b34976b6 19646 Elf_Internal_Note inote;
15b42fb0 19647 size_t min_notesz;
4dff97b2 19648 char * next;
2cf0635d 19649 char * temp = NULL;
c8071705 19650 size_t data_remaining = end - (char *) external;
6d118b09 19651
dda8d76d 19652 if (!is_ia64_vms (filedata))
15b42fb0 19653 {
9dd3a467
NC
19654 /* PR binutils/15191
19655 Make sure that there is enough data to read. */
15b42fb0
AM
19656 min_notesz = offsetof (Elf_External_Note, name);
19657 if (data_remaining < min_notesz)
9dd3a467 19658 {
d3a49aa8
AM
19659 warn (ngettext ("Corrupt note: only %ld byte remains, "
19660 "not enough for a full note\n",
19661 "Corrupt note: only %ld bytes remain, "
19662 "not enough for a full note\n",
19663 data_remaining),
19664 (long) data_remaining);
9dd3a467
NC
19665 break;
19666 }
5396a86e
AM
19667 data_remaining -= min_notesz;
19668
15b42fb0
AM
19669 inote.type = BYTE_GET (external->type);
19670 inote.namesz = BYTE_GET (external->namesz);
19671 inote.namedata = external->name;
19672 inote.descsz = BYTE_GET (external->descsz);
276da9b3 19673 inote.descdata = ((char *) external
4dff97b2 19674 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 19675 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 19676 next = ((char *) external
4dff97b2 19677 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 19678 }
00e98fc7 19679 else
15b42fb0
AM
19680 {
19681 Elf64_External_VMS_Note *vms_external;
00e98fc7 19682
9dd3a467
NC
19683 /* PR binutils/15191
19684 Make sure that there is enough data to read. */
15b42fb0
AM
19685 min_notesz = offsetof (Elf64_External_VMS_Note, name);
19686 if (data_remaining < min_notesz)
9dd3a467 19687 {
d3a49aa8
AM
19688 warn (ngettext ("Corrupt note: only %ld byte remains, "
19689 "not enough for a full note\n",
19690 "Corrupt note: only %ld bytes remain, "
19691 "not enough for a full note\n",
19692 data_remaining),
19693 (long) data_remaining);
9dd3a467
NC
19694 break;
19695 }
5396a86e 19696 data_remaining -= min_notesz;
3e55a963 19697
15b42fb0
AM
19698 vms_external = (Elf64_External_VMS_Note *) external;
19699 inote.type = BYTE_GET (vms_external->type);
19700 inote.namesz = BYTE_GET (vms_external->namesz);
19701 inote.namedata = vms_external->name;
19702 inote.descsz = BYTE_GET (vms_external->descsz);
19703 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
19704 inote.descpos = offset + (inote.descdata - (char *) pnotes);
19705 next = inote.descdata + align_power (inote.descsz, 3);
19706 }
19707
5396a86e
AM
19708 /* PR 17531: file: 3443835e. */
19709 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
19710 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
19711 || (size_t) (inote.descdata - inote.namedata) > data_remaining
19712 || (size_t) (next - inote.descdata) < inote.descsz
19713 || ((size_t) (next - inote.descdata)
19714 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 19715 {
15b42fb0 19716 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 19717 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
19718 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
19719 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
19720 break;
19721 }
19722
15b42fb0 19723 external = (Elf_External_Note *) next;
dd24e3da 19724
6d118b09
NC
19725 /* Verify that name is null terminated. It appears that at least
19726 one version of Linux (RedHat 6.0) generates corefiles that don't
19727 comply with the ELF spec by failing to include the null byte in
19728 namesz. */
18344509 19729 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 19730 {
5396a86e 19731 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 19732 {
5396a86e
AM
19733 temp = (char *) malloc (inote.namesz + 1);
19734 if (temp == NULL)
19735 {
19736 error (_("Out of memory allocating space for inote name\n"));
19737 res = FALSE;
19738 break;
19739 }
76da6bbe 19740
5396a86e
AM
19741 memcpy (temp, inote.namedata, inote.namesz);
19742 inote.namedata = temp;
19743 }
19744 inote.namedata[inote.namesz] = 0;
6d118b09
NC
19745 }
19746
dda8d76d 19747 if (! process_note (& inote, filedata))
6b4bf3bc 19748 res = FALSE;
103f02d3 19749
6d118b09
NC
19750 if (temp != NULL)
19751 {
19752 free (temp);
19753 temp = NULL;
19754 }
779fe533
NC
19755 }
19756
19757 free (pnotes);
103f02d3 19758
779fe533
NC
19759 return res;
19760}
19761
32ec8896 19762static bfd_boolean
dda8d76d 19763process_corefile_note_segments (Filedata * filedata)
779fe533 19764{
2cf0635d 19765 Elf_Internal_Phdr * segment;
b34976b6 19766 unsigned int i;
32ec8896 19767 bfd_boolean res = TRUE;
103f02d3 19768
dda8d76d 19769 if (! get_program_headers (filedata))
6b4bf3bc 19770 return TRUE;
103f02d3 19771
dda8d76d
NC
19772 for (i = 0, segment = filedata->program_headers;
19773 i < filedata->file_header.e_phnum;
b34976b6 19774 i++, segment++)
779fe533
NC
19775 {
19776 if (segment->p_type == PT_NOTE)
dda8d76d 19777 if (! process_notes_at (filedata, NULL,
32ec8896 19778 (bfd_vma) segment->p_offset,
82ed9683
L
19779 (bfd_vma) segment->p_filesz,
19780 (bfd_vma) segment->p_align))
32ec8896 19781 res = FALSE;
779fe533 19782 }
103f02d3 19783
779fe533
NC
19784 return res;
19785}
19786
32ec8896 19787static bfd_boolean
dda8d76d 19788process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
19789{
19790 Elf_External_Note * pnotes;
19791 Elf_External_Note * external;
c8071705 19792 char * end;
32ec8896 19793 bfd_boolean res = TRUE;
685080f2
NC
19794
19795 if (length <= 0)
32ec8896 19796 return FALSE;
685080f2 19797
dda8d76d 19798 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
19799 _("v850 notes"));
19800 if (pnotes == NULL)
32ec8896 19801 return FALSE;
685080f2
NC
19802
19803 external = pnotes;
c8071705 19804 end = (char*) pnotes + length;
685080f2
NC
19805
19806 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
19807 (unsigned long) offset, (unsigned long) length);
19808
c8071705 19809 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
19810 {
19811 Elf_External_Note * next;
19812 Elf_Internal_Note inote;
19813
19814 inote.type = BYTE_GET (external->type);
19815 inote.namesz = BYTE_GET (external->namesz);
19816 inote.namedata = external->name;
19817 inote.descsz = BYTE_GET (external->descsz);
19818 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
19819 inote.descpos = offset + (inote.descdata - (char *) pnotes);
19820
c8071705
NC
19821 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
19822 {
19823 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
19824 inote.descdata = inote.namedata;
19825 inote.namesz = 0;
19826 }
19827
685080f2
NC
19828 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
19829
c8071705 19830 if ( ((char *) next > end)
685080f2
NC
19831 || ((char *) next < (char *) pnotes))
19832 {
19833 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
19834 (unsigned long) ((char *) external - (char *) pnotes));
19835 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
19836 inote.type, inote.namesz, inote.descsz);
19837 break;
19838 }
19839
19840 external = next;
19841
19842 /* Prevent out-of-bounds indexing. */
c8071705 19843 if ( inote.namedata + inote.namesz > end
685080f2
NC
19844 || inote.namedata + inote.namesz < inote.namedata)
19845 {
19846 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
19847 (unsigned long) ((char *) external - (char *) pnotes));
19848 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
19849 inote.type, inote.namesz, inote.descsz);
19850 break;
19851 }
19852
19853 printf (" %s: ", get_v850_elf_note_type (inote.type));
19854
19855 if (! print_v850_note (& inote))
19856 {
32ec8896 19857 res = FALSE;
685080f2
NC
19858 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
19859 inote.namesz, inote.descsz);
19860 }
19861 }
19862
19863 free (pnotes);
19864
19865 return res;
19866}
19867
32ec8896 19868static bfd_boolean
dda8d76d 19869process_note_sections (Filedata * filedata)
1ec5cd37 19870{
2cf0635d 19871 Elf_Internal_Shdr * section;
1ec5cd37 19872 unsigned long i;
32ec8896
NC
19873 unsigned int n = 0;
19874 bfd_boolean res = TRUE;
1ec5cd37 19875
dda8d76d
NC
19876 for (i = 0, section = filedata->section_headers;
19877 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 19878 i++, section++)
685080f2
NC
19879 {
19880 if (section->sh_type == SHT_NOTE)
19881 {
dda8d76d 19882 if (! process_notes_at (filedata, section,
32ec8896 19883 (bfd_vma) section->sh_offset,
82ed9683
L
19884 (bfd_vma) section->sh_size,
19885 (bfd_vma) section->sh_addralign))
32ec8896 19886 res = FALSE;
685080f2
NC
19887 n++;
19888 }
19889
dda8d76d
NC
19890 if (( filedata->file_header.e_machine == EM_V800
19891 || filedata->file_header.e_machine == EM_V850
19892 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
19893 && section->sh_type == SHT_RENESAS_INFO)
19894 {
dda8d76d 19895 if (! process_v850_notes (filedata,
32ec8896
NC
19896 (bfd_vma) section->sh_offset,
19897 (bfd_vma) section->sh_size))
19898 res = FALSE;
685080f2
NC
19899 n++;
19900 }
19901 }
df565f32
NC
19902
19903 if (n == 0)
19904 /* Try processing NOTE segments instead. */
dda8d76d 19905 return process_corefile_note_segments (filedata);
1ec5cd37
NC
19906
19907 return res;
19908}
19909
32ec8896 19910static bfd_boolean
dda8d76d 19911process_notes (Filedata * filedata)
779fe533
NC
19912{
19913 /* If we have not been asked to display the notes then do nothing. */
19914 if (! do_notes)
32ec8896 19915 return TRUE;
103f02d3 19916
dda8d76d
NC
19917 if (filedata->file_header.e_type != ET_CORE)
19918 return process_note_sections (filedata);
103f02d3 19919
779fe533 19920 /* No program headers means no NOTE segment. */
dda8d76d
NC
19921 if (filedata->file_header.e_phnum > 0)
19922 return process_corefile_note_segments (filedata);
779fe533 19923
1ec5cd37 19924 printf (_("No note segments present in the core file.\n"));
32ec8896 19925 return TRUE;
779fe533
NC
19926}
19927
60abdbed
NC
19928static unsigned char *
19929display_public_gnu_attributes (unsigned char * start,
19930 const unsigned char * const end)
19931{
19932 printf (_(" Unknown GNU attribute: %s\n"), start);
19933
19934 start += strnlen ((char *) start, end - start);
19935 display_raw_attribute (start, end);
19936
19937 return (unsigned char *) end;
19938}
19939
19940static unsigned char *
19941display_generic_attribute (unsigned char * start,
19942 unsigned int tag,
19943 const unsigned char * const end)
19944{
19945 if (tag == 0)
19946 return (unsigned char *) end;
19947
19948 return display_tag_value (tag, start, end);
19949}
19950
32ec8896 19951static bfd_boolean
dda8d76d 19952process_arch_specific (Filedata * filedata)
252b5132 19953{
a952a375 19954 if (! do_arch)
32ec8896 19955 return TRUE;
a952a375 19956
dda8d76d 19957 switch (filedata->file_header.e_machine)
252b5132 19958 {
53a346d8
CZ
19959 case EM_ARC:
19960 case EM_ARC_COMPACT:
19961 case EM_ARC_COMPACT2:
dda8d76d 19962 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
19963 display_arc_attribute,
19964 display_generic_attribute);
11c1ff18 19965 case EM_ARM:
dda8d76d 19966 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
19967 display_arm_attribute,
19968 display_generic_attribute);
19969
252b5132 19970 case EM_MIPS:
4fe85591 19971 case EM_MIPS_RS3_LE:
dda8d76d 19972 return process_mips_specific (filedata);
60abdbed
NC
19973
19974 case EM_MSP430:
dda8d76d
NC
19975 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
19976 display_msp430x_attribute,
c0ea7c52 19977 display_msp430_gnu_attribute);
60abdbed 19978
2dc8dd17
JW
19979 case EM_RISCV:
19980 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
19981 display_riscv_attribute,
19982 display_generic_attribute);
19983
35c08157 19984 case EM_NDS32:
dda8d76d 19985 return process_nds32_specific (filedata);
60abdbed 19986
34c8bcba 19987 case EM_PPC:
b82317dd 19988 case EM_PPC64:
dda8d76d 19989 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
19990 display_power_gnu_attribute);
19991
643f7afb
AK
19992 case EM_S390:
19993 case EM_S390_OLD:
dda8d76d 19994 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
19995 display_s390_gnu_attribute);
19996
9e8c70f9
DM
19997 case EM_SPARC:
19998 case EM_SPARC32PLUS:
19999 case EM_SPARCV9:
dda8d76d 20000 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20001 display_sparc_gnu_attribute);
20002
59e6276b 20003 case EM_TI_C6000:
dda8d76d 20004 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
20005 display_tic6x_attribute,
20006 display_generic_attribute);
20007
252b5132 20008 default:
dda8d76d 20009 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
20010 display_public_gnu_attributes,
20011 display_generic_attribute);
252b5132 20012 }
252b5132
RH
20013}
20014
32ec8896 20015static bfd_boolean
dda8d76d 20016get_file_header (Filedata * filedata)
252b5132 20017{
9ea033b2 20018 /* Read in the identity array. */
dda8d76d 20019 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20020 return FALSE;
252b5132 20021
9ea033b2 20022 /* Determine how to read the rest of the header. */
dda8d76d 20023 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 20024 {
1a0670f3
AM
20025 default:
20026 case ELFDATANONE:
adab8cdc
AO
20027 case ELFDATA2LSB:
20028 byte_get = byte_get_little_endian;
20029 byte_put = byte_put_little_endian;
20030 break;
20031 case ELFDATA2MSB:
20032 byte_get = byte_get_big_endian;
20033 byte_put = byte_put_big_endian;
20034 break;
9ea033b2
NC
20035 }
20036
20037 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 20038 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
20039
20040 /* Read in the rest of the header. */
20041 if (is_32bit_elf)
20042 {
20043 Elf32_External_Ehdr ehdr32;
252b5132 20044
dda8d76d 20045 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20046 return FALSE;
103f02d3 20047
dda8d76d
NC
20048 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
20049 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
20050 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
20051 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
20052 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
20053 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
20054 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
20055 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
20056 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
20057 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
20058 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
20059 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
20060 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 20061 }
252b5132 20062 else
9ea033b2
NC
20063 {
20064 Elf64_External_Ehdr ehdr64;
a952a375
NC
20065
20066 /* If we have been compiled with sizeof (bfd_vma) == 4, then
20067 we will not be able to cope with the 64bit data found in
20068 64 ELF files. Detect this now and abort before we start
50c2245b 20069 overwriting things. */
a952a375
NC
20070 if (sizeof (bfd_vma) < 8)
20071 {
e3c8793a
NC
20072 error (_("This instance of readelf has been built without support for a\n\
2007364 bit data type and so it cannot read 64 bit ELF files.\n"));
32ec8896 20074 return FALSE;
a952a375 20075 }
103f02d3 20076
dda8d76d 20077 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20078 return FALSE;
103f02d3 20079
dda8d76d
NC
20080 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
20081 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
20082 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
20083 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
20084 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
20085 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
20086 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
20087 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
20088 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
20089 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
20090 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
20091 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
20092 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 20093 }
252b5132 20094
dda8d76d 20095 if (filedata->file_header.e_shoff)
7ece0d85
JJ
20096 {
20097 /* There may be some extensions in the first section header. Don't
20098 bomb if we can't read it. */
20099 if (is_32bit_elf)
dda8d76d 20100 get_32bit_section_headers (filedata, TRUE);
7ece0d85 20101 else
dda8d76d 20102 get_64bit_section_headers (filedata, TRUE);
7ece0d85 20103 }
560f3c1c 20104
32ec8896 20105 return TRUE;
252b5132
RH
20106}
20107
dda8d76d
NC
20108static void
20109close_file (Filedata * filedata)
20110{
20111 if (filedata)
20112 {
20113 if (filedata->handle)
20114 fclose (filedata->handle);
20115 free (filedata);
20116 }
20117}
20118
20119void
20120close_debug_file (void * data)
20121{
20122 close_file ((Filedata *) data);
20123}
20124
20125static Filedata *
20126open_file (const char * pathname)
20127{
20128 struct stat statbuf;
20129 Filedata * filedata = NULL;
20130
20131 if (stat (pathname, & statbuf) < 0
20132 || ! S_ISREG (statbuf.st_mode))
20133 goto fail;
20134
20135 filedata = calloc (1, sizeof * filedata);
20136 if (filedata == NULL)
20137 goto fail;
20138
20139 filedata->handle = fopen (pathname, "rb");
20140 if (filedata->handle == NULL)
20141 goto fail;
20142
20143 filedata->file_size = (bfd_size_type) statbuf.st_size;
20144 filedata->file_name = pathname;
20145
20146 if (! get_file_header (filedata))
20147 goto fail;
20148
20149 if (filedata->file_header.e_shoff)
20150 {
20151 bfd_boolean res;
20152
20153 /* Read the section headers again, this time for real. */
20154 if (is_32bit_elf)
20155 res = get_32bit_section_headers (filedata, FALSE);
20156 else
20157 res = get_64bit_section_headers (filedata, FALSE);
20158
20159 if (!res)
20160 goto fail;
20161 }
20162
20163 return filedata;
20164
20165 fail:
20166 if (filedata)
20167 {
20168 if (filedata->handle)
20169 fclose (filedata->handle);
20170 free (filedata);
20171 }
20172 return NULL;
20173}
20174
20175void *
20176open_debug_file (const char * pathname)
20177{
20178 return open_file (pathname);
20179}
20180
fb52b2f4
NC
20181/* Process one ELF object file according to the command line options.
20182 This file may actually be stored in an archive. The file is
32ec8896
NC
20183 positioned at the start of the ELF object. Returns TRUE if no
20184 problems were encountered, FALSE otherwise. */
fb52b2f4 20185
32ec8896 20186static bfd_boolean
dda8d76d 20187process_object (Filedata * filedata)
252b5132 20188{
24841daa 20189 bfd_boolean have_separate_files;
252b5132 20190 unsigned int i;
2482f306 20191 bfd_boolean res;
252b5132 20192
dda8d76d 20193 if (! get_file_header (filedata))
252b5132 20194 {
dda8d76d 20195 error (_("%s: Failed to read file header\n"), filedata->file_name);
32ec8896 20196 return FALSE;
252b5132
RH
20197 }
20198
20199 /* Initialise per file variables. */
978c4450
AM
20200 for (i = ARRAY_SIZE (filedata->version_info); i--;)
20201 filedata->version_info[i] = 0;
252b5132 20202
978c4450
AM
20203 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
20204 filedata->dynamic_info[i] = 0;
20205 filedata->dynamic_info_DT_GNU_HASH = 0;
20206 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
20207
20208 /* Process the file. */
20209 if (show_name)
dda8d76d 20210 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 20211
18bd398b
NC
20212 /* Initialise the dump_sects array from the cmdline_dump_sects array.
20213 Note we do this even if cmdline_dump_sects is empty because we
20214 must make sure that the dump_sets array is zeroed out before each
20215 object file is processed. */
6431e409
AM
20216 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
20217 memset (filedata->dump.dump_sects, 0,
20218 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20219
dda8d76d 20220 if (cmdline.num_dump_sects > 0)
18bd398b 20221 {
6431e409 20222 if (filedata->dump.num_dump_sects == 0)
18bd398b 20223 /* A sneaky way of allocating the dump_sects array. */
6431e409 20224 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
18bd398b 20225
6431e409
AM
20226 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
20227 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
20228 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20229 }
d70c5fc7 20230
dda8d76d 20231 if (! process_file_header (filedata))
32ec8896 20232 return FALSE;
252b5132 20233
dda8d76d 20234 if (! process_section_headers (filedata))
2f62977e 20235 {
32ec8896
NC
20236 /* Without loaded section headers we cannot process lots of things. */
20237 do_unwind = do_version = do_dump = do_arch = FALSE;
252b5132 20238
2f62977e 20239 if (! do_using_dynamic)
32ec8896 20240 do_syms = do_dyn_syms = do_reloc = FALSE;
2f62977e 20241 }
252b5132 20242
dda8d76d 20243 if (! process_section_groups (filedata))
32ec8896
NC
20244 /* Without loaded section groups we cannot process unwind. */
20245 do_unwind = FALSE;
d1f5c6e3 20246
2482f306
AM
20247 res = process_program_headers (filedata);
20248 if (res)
20249 res = process_dynamic_section (filedata);
252b5132 20250
dda8d76d 20251 if (! process_relocs (filedata))
32ec8896 20252 res = FALSE;
252b5132 20253
dda8d76d 20254 if (! process_unwind (filedata))
32ec8896 20255 res = FALSE;
4d6ed7c8 20256
dda8d76d 20257 if (! process_symbol_table (filedata))
32ec8896 20258 res = FALSE;
252b5132 20259
dda8d76d 20260 if (! process_syminfo (filedata))
32ec8896 20261 res = FALSE;
252b5132 20262
dda8d76d 20263 if (! process_version_sections (filedata))
32ec8896 20264 res = FALSE;
252b5132 20265
82ed9683 20266 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 20267 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 20268 else
24841daa 20269 have_separate_files = FALSE;
dda8d76d
NC
20270
20271 if (! process_section_contents (filedata))
32ec8896 20272 res = FALSE;
f5842774 20273
24841daa 20274 if (have_separate_files)
dda8d76d 20275 {
24841daa
NC
20276 separate_info * d;
20277
20278 for (d = first_separate_info; d != NULL; d = d->next)
20279 {
20280 if (! process_section_headers (d->handle))
20281 res = FALSE;
20282 else if (! process_section_contents (d->handle))
20283 res = FALSE;
20284 }
20285
20286 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
20287 }
20288
20289 if (! process_notes (filedata))
32ec8896 20290 res = FALSE;
103f02d3 20291
dda8d76d 20292 if (! process_gnu_liblist (filedata))
32ec8896 20293 res = FALSE;
047b2264 20294
dda8d76d 20295 if (! process_arch_specific (filedata))
32ec8896 20296 res = FALSE;
252b5132 20297
dda8d76d
NC
20298 free (filedata->program_headers);
20299 filedata->program_headers = NULL;
d93f0186 20300
dda8d76d
NC
20301 free (filedata->section_headers);
20302 filedata->section_headers = NULL;
252b5132 20303
dda8d76d
NC
20304 free (filedata->string_table);
20305 filedata->string_table = NULL;
20306 filedata->string_table_length = 0;
252b5132 20307
6431e409 20308 if (filedata->dump.dump_sects != NULL)
a788aedd 20309 {
6431e409
AM
20310 free (filedata->dump.dump_sects);
20311 filedata->dump.dump_sects = NULL;
20312 filedata->dump.num_dump_sects = 0;
a788aedd
AM
20313 }
20314
978c4450 20315 if (filedata->dynamic_strings)
252b5132 20316 {
978c4450
AM
20317 free (filedata->dynamic_strings);
20318 filedata->dynamic_strings = NULL;
20319 filedata->dynamic_strings_length = 0;
252b5132
RH
20320 }
20321
978c4450 20322 if (filedata->dynamic_symbols)
252b5132 20323 {
978c4450
AM
20324 free (filedata->dynamic_symbols);
20325 filedata->dynamic_symbols = NULL;
20326 filedata->num_dynamic_syms = 0;
252b5132
RH
20327 }
20328
978c4450 20329 if (filedata->dynamic_syminfo)
252b5132 20330 {
978c4450
AM
20331 free (filedata->dynamic_syminfo);
20332 filedata->dynamic_syminfo = NULL;
252b5132 20333 }
ff78d6d6 20334
978c4450 20335 if (filedata->dynamic_section)
293c573e 20336 {
978c4450
AM
20337 free (filedata->dynamic_section);
20338 filedata->dynamic_section = NULL;
293c573e
MR
20339 }
20340
978c4450 20341 while (filedata->symtab_shndx_list != NULL)
8fb879cd 20342 {
978c4450
AM
20343 elf_section_list *next = filedata->symtab_shndx_list->next;
20344 free (filedata->symtab_shndx_list);
20345 filedata->symtab_shndx_list = next;
8fb879cd
AM
20346 }
20347
978c4450 20348 if (filedata->section_headers_groups)
e4b17d5c 20349 {
978c4450
AM
20350 free (filedata->section_headers_groups);
20351 filedata->section_headers_groups = NULL;
e4b17d5c
L
20352 }
20353
978c4450 20354 if (filedata->section_groups)
e4b17d5c 20355 {
2cf0635d
NC
20356 struct group_list * g;
20357 struct group_list * next;
e4b17d5c 20358
978c4450 20359 for (i = 0; i < filedata->group_count; i++)
e4b17d5c 20360 {
978c4450 20361 for (g = filedata->section_groups [i].root; g != NULL; g = next)
e4b17d5c
L
20362 {
20363 next = g->next;
20364 free (g);
20365 }
20366 }
20367
978c4450
AM
20368 free (filedata->section_groups);
20369 filedata->section_groups = NULL;
e4b17d5c
L
20370 }
20371
19e6b90e 20372 free_debug_memory ();
18bd398b 20373
32ec8896 20374 return res;
252b5132
RH
20375}
20376
2cf0635d 20377/* Process an ELF archive.
32ec8896
NC
20378 On entry the file is positioned just after the ARMAG string.
20379 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 20380
32ec8896 20381static bfd_boolean
dda8d76d 20382process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
2cf0635d
NC
20383{
20384 struct archive_info arch;
20385 struct archive_info nested_arch;
20386 size_t got;
32ec8896 20387 bfd_boolean ret = TRUE;
2cf0635d 20388
32ec8896 20389 show_name = TRUE;
2cf0635d
NC
20390
20391 /* The ARCH structure is used to hold information about this archive. */
20392 arch.file_name = NULL;
20393 arch.file = NULL;
20394 arch.index_array = NULL;
20395 arch.sym_table = NULL;
20396 arch.longnames = NULL;
20397
20398 /* The NESTED_ARCH structure is used as a single-item cache of information
20399 about a nested archive (when members of a thin archive reside within
20400 another regular archive file). */
20401 nested_arch.file_name = NULL;
20402 nested_arch.file = NULL;
20403 nested_arch.index_array = NULL;
20404 nested_arch.sym_table = NULL;
20405 nested_arch.longnames = NULL;
20406
dda8d76d 20407 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
20408 filedata->file_size, is_thin_archive,
20409 do_archive_index) != 0)
2cf0635d 20410 {
32ec8896 20411 ret = FALSE;
2cf0635d 20412 goto out;
4145f1d5 20413 }
fb52b2f4 20414
4145f1d5
NC
20415 if (do_archive_index)
20416 {
2cf0635d 20417 if (arch.sym_table == NULL)
1cb7d8b1
AM
20418 error (_("%s: unable to dump the index as none was found\n"),
20419 filedata->file_name);
4145f1d5
NC
20420 else
20421 {
591f7597 20422 unsigned long i, l;
4145f1d5
NC
20423 unsigned long current_pos;
20424
1cb7d8b1
AM
20425 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
20426 "in the symbol table)\n"),
20427 filedata->file_name, (unsigned long) arch.index_num,
20428 arch.sym_size);
dda8d76d
NC
20429
20430 current_pos = ftell (filedata->handle);
4145f1d5 20431
2cf0635d 20432 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 20433 {
1cb7d8b1
AM
20434 if (i == 0
20435 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
20436 {
20437 char * member_name
20438 = get_archive_member_name_at (&arch, arch.index_array[i],
20439 &nested_arch);
2cf0635d 20440
1cb7d8b1
AM
20441 if (member_name != NULL)
20442 {
20443 char * qualified_name
20444 = make_qualified_name (&arch, &nested_arch,
20445 member_name);
2cf0635d 20446
1cb7d8b1
AM
20447 if (qualified_name != NULL)
20448 {
20449 printf (_("Contents of binary %s at offset "),
20450 qualified_name);
c2a7d3f5
NC
20451 (void) print_vma (arch.index_array[i], PREFIX_HEX);
20452 putchar ('\n');
1cb7d8b1
AM
20453 free (qualified_name);
20454 }
fd486f32 20455 free (member_name);
4145f1d5
NC
20456 }
20457 }
2cf0635d
NC
20458
20459 if (l >= arch.sym_size)
4145f1d5 20460 {
1cb7d8b1
AM
20461 error (_("%s: end of the symbol table reached "
20462 "before the end of the index\n"),
dda8d76d 20463 filedata->file_name);
32ec8896 20464 ret = FALSE;
cb8f3167 20465 break;
4145f1d5 20466 }
591f7597 20467 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
20468 printf ("\t%.*s\n",
20469 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 20470 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
20471 }
20472
67ce483b 20473 if (arch.uses_64bit_indices)
c2a7d3f5
NC
20474 l = (l + 7) & ~ 7;
20475 else
20476 l += l & 1;
20477
2cf0635d 20478 if (l < arch.sym_size)
32ec8896 20479 {
d3a49aa8
AM
20480 error (ngettext ("%s: %ld byte remains in the symbol table, "
20481 "but without corresponding entries in "
20482 "the index table\n",
20483 "%s: %ld bytes remain in the symbol table, "
20484 "but without corresponding entries in "
20485 "the index table\n",
20486 arch.sym_size - l),
dda8d76d 20487 filedata->file_name, arch.sym_size - l);
32ec8896
NC
20488 ret = FALSE;
20489 }
4145f1d5 20490
dda8d76d 20491 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 20492 {
1cb7d8b1
AM
20493 error (_("%s: failed to seek back to start of object files "
20494 "in the archive\n"),
dda8d76d 20495 filedata->file_name);
32ec8896 20496 ret = FALSE;
2cf0635d 20497 goto out;
4145f1d5 20498 }
fb52b2f4 20499 }
4145f1d5
NC
20500
20501 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
20502 && !do_segments && !do_header && !do_dump && !do_version
20503 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 20504 && !do_section_groups && !do_dyn_syms)
2cf0635d 20505 {
32ec8896 20506 ret = TRUE; /* Archive index only. */
2cf0635d
NC
20507 goto out;
20508 }
fb52b2f4
NC
20509 }
20510
fb52b2f4
NC
20511 while (1)
20512 {
2cf0635d
NC
20513 char * name;
20514 size_t namelen;
20515 char * qualified_name;
20516
20517 /* Read the next archive header. */
dda8d76d 20518 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
20519 {
20520 error (_("%s: failed to seek to next archive header\n"),
20521 arch.file_name);
20522 ret = FALSE;
20523 break;
20524 }
dda8d76d 20525 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 20526 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
20527 {
20528 if (got == 0)
2cf0635d 20529 break;
28e817cc
NC
20530 /* PR 24049 - we cannot use filedata->file_name as this will
20531 have already been freed. */
20532 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 20533
1cb7d8b1
AM
20534 ret = FALSE;
20535 break;
20536 }
2cf0635d 20537 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
20538 {
20539 error (_("%s: did not find a valid archive header\n"),
20540 arch.file_name);
20541 ret = FALSE;
20542 break;
20543 }
2cf0635d
NC
20544
20545 arch.next_arhdr_offset += sizeof arch.arhdr;
20546
978c4450
AM
20547 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
20548 if (filedata->archive_file_size & 01)
20549 ++filedata->archive_file_size;
2cf0635d
NC
20550
20551 name = get_archive_member_name (&arch, &nested_arch);
20552 if (name == NULL)
fb52b2f4 20553 {
28e817cc 20554 error (_("%s: bad archive file name\n"), arch.file_name);
32ec8896 20555 ret = FALSE;
d989285c 20556 break;
fb52b2f4 20557 }
2cf0635d 20558 namelen = strlen (name);
fb52b2f4 20559
2cf0635d
NC
20560 qualified_name = make_qualified_name (&arch, &nested_arch, name);
20561 if (qualified_name == NULL)
fb52b2f4 20562 {
28e817cc 20563 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 20564 free (name);
32ec8896 20565 ret = FALSE;
d989285c 20566 break;
fb52b2f4
NC
20567 }
20568
2cf0635d 20569 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
20570 {
20571 /* This is a proxy for an external member of a thin archive. */
20572 Filedata * member_filedata;
20573 char * member_file_name = adjust_relative_path
dda8d76d 20574 (filedata->file_name, name, namelen);
32ec8896 20575
fd486f32 20576 free (name);
1cb7d8b1
AM
20577 if (member_file_name == NULL)
20578 {
fd486f32 20579 free (qualified_name);
1cb7d8b1
AM
20580 ret = FALSE;
20581 break;
20582 }
2cf0635d 20583
1cb7d8b1
AM
20584 member_filedata = open_file (member_file_name);
20585 if (member_filedata == NULL)
20586 {
20587 error (_("Input file '%s' is not readable.\n"), member_file_name);
20588 free (member_file_name);
fd486f32 20589 free (qualified_name);
1cb7d8b1
AM
20590 ret = FALSE;
20591 break;
20592 }
2cf0635d 20593
978c4450 20594 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 20595 member_filedata->file_name = qualified_name;
2cf0635d 20596
1cb7d8b1 20597 if (! process_object (member_filedata))
32ec8896 20598 ret = FALSE;
2cf0635d 20599
1cb7d8b1
AM
20600 close_file (member_filedata);
20601 free (member_file_name);
1cb7d8b1 20602 }
2cf0635d 20603 else if (is_thin_archive)
1cb7d8b1
AM
20604 {
20605 Filedata thin_filedata;
eb02c04d 20606
1cb7d8b1 20607 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 20608
a043396b
NC
20609 /* PR 15140: Allow for corrupt thin archives. */
20610 if (nested_arch.file == NULL)
20611 {
20612 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 20613 qualified_name, name);
fd486f32
AM
20614 free (qualified_name);
20615 free (name);
32ec8896 20616 ret = FALSE;
a043396b
NC
20617 break;
20618 }
fd486f32 20619 free (name);
a043396b 20620
1cb7d8b1 20621 /* This is a proxy for a member of a nested archive. */
978c4450
AM
20622 filedata->archive_file_offset
20623 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 20624
1cb7d8b1
AM
20625 /* The nested archive file will have been opened and setup by
20626 get_archive_member_name. */
978c4450
AM
20627 if (fseek (nested_arch.file, filedata->archive_file_offset,
20628 SEEK_SET) != 0)
1cb7d8b1
AM
20629 {
20630 error (_("%s: failed to seek to archive member.\n"),
20631 nested_arch.file_name);
fd486f32 20632 free (qualified_name);
1cb7d8b1
AM
20633 ret = FALSE;
20634 break;
20635 }
2cf0635d 20636
dda8d76d
NC
20637 thin_filedata.handle = nested_arch.file;
20638 thin_filedata.file_name = qualified_name;
9abca702 20639
1cb7d8b1 20640 if (! process_object (& thin_filedata))
32ec8896 20641 ret = FALSE;
1cb7d8b1 20642 }
2cf0635d 20643 else
1cb7d8b1 20644 {
fd486f32 20645 free (name);
978c4450 20646 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 20647 filedata->file_name = qualified_name;
1cb7d8b1 20648 if (! process_object (filedata))
32ec8896 20649 ret = FALSE;
978c4450 20650 arch.next_arhdr_offset += filedata->archive_file_size;
4c836627 20651 /* Stop looping with "negative" archive_file_size. */
978c4450 20652 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 20653 arch.next_arhdr_offset = -1ul;
1cb7d8b1 20654 }
fb52b2f4 20655
2cf0635d 20656 free (qualified_name);
fb52b2f4
NC
20657 }
20658
4145f1d5 20659 out:
2cf0635d
NC
20660 if (nested_arch.file != NULL)
20661 fclose (nested_arch.file);
20662 release_archive (&nested_arch);
20663 release_archive (&arch);
fb52b2f4 20664
d989285c 20665 return ret;
fb52b2f4
NC
20666}
20667
32ec8896 20668static bfd_boolean
2cf0635d 20669process_file (char * file_name)
fb52b2f4 20670{
dda8d76d 20671 Filedata * filedata = NULL;
fb52b2f4
NC
20672 struct stat statbuf;
20673 char armag[SARMAG];
32ec8896 20674 bfd_boolean ret = TRUE;
fb52b2f4
NC
20675
20676 if (stat (file_name, &statbuf) < 0)
20677 {
f24ddbdd
NC
20678 if (errno == ENOENT)
20679 error (_("'%s': No such file\n"), file_name);
20680 else
20681 error (_("Could not locate '%s'. System error message: %s\n"),
20682 file_name, strerror (errno));
32ec8896 20683 return FALSE;
f24ddbdd
NC
20684 }
20685
20686 if (! S_ISREG (statbuf.st_mode))
20687 {
20688 error (_("'%s' is not an ordinary file\n"), file_name);
32ec8896 20689 return FALSE;
fb52b2f4
NC
20690 }
20691
dda8d76d
NC
20692 filedata = calloc (1, sizeof * filedata);
20693 if (filedata == NULL)
20694 {
20695 error (_("Out of memory allocating file data structure\n"));
20696 return FALSE;
20697 }
20698
20699 filedata->file_name = file_name;
20700 filedata->handle = fopen (file_name, "rb");
20701 if (filedata->handle == NULL)
fb52b2f4 20702 {
f24ddbdd 20703 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 20704 free (filedata);
32ec8896 20705 return FALSE;
fb52b2f4
NC
20706 }
20707
dda8d76d 20708 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 20709 {
4145f1d5 20710 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
20711 fclose (filedata->handle);
20712 free (filedata);
32ec8896 20713 return FALSE;
fb52b2f4
NC
20714 }
20715
dda8d76d 20716 filedata->file_size = (bfd_size_type) statbuf.st_size;
f54498b4 20717
fb52b2f4 20718 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 20719 {
dda8d76d 20720 if (! process_archive (filedata, FALSE))
32ec8896
NC
20721 ret = FALSE;
20722 }
2cf0635d 20723 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 20724 {
dda8d76d 20725 if ( ! process_archive (filedata, TRUE))
32ec8896
NC
20726 ret = FALSE;
20727 }
fb52b2f4
NC
20728 else
20729 {
1b513401 20730 if (do_archive_index && !check_all)
4145f1d5
NC
20731 error (_("File %s is not an archive so its index cannot be displayed.\n"),
20732 file_name);
20733
dda8d76d 20734 rewind (filedata->handle);
978c4450 20735 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 20736
dda8d76d 20737 if (! process_object (filedata))
32ec8896 20738 ret = FALSE;
fb52b2f4
NC
20739 }
20740
dda8d76d 20741 fclose (filedata->handle);
8fb879cd
AM
20742 free (filedata->section_headers);
20743 free (filedata->program_headers);
20744 free (filedata->string_table);
6431e409 20745 free (filedata->dump.dump_sects);
dda8d76d 20746 free (filedata);
32ec8896 20747
fd486f32 20748 free (ba_cache.strtab);
1bd6175a 20749 ba_cache.strtab = NULL;
fd486f32 20750 free (ba_cache.symtab);
1bd6175a 20751 ba_cache.symtab = NULL;
fd486f32
AM
20752 ba_cache.filedata = NULL;
20753
fb52b2f4
NC
20754 return ret;
20755}
20756
252b5132
RH
20757#ifdef SUPPORT_DISASSEMBLY
20758/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 20759 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 20760 symbols. */
252b5132
RH
20761
20762void
2cf0635d 20763print_address (unsigned int addr, FILE * outfile)
252b5132
RH
20764{
20765 fprintf (outfile,"0x%8.8x", addr);
20766}
20767
e3c8793a 20768/* Needed by the i386 disassembler. */
dda8d76d 20769
252b5132
RH
20770void
20771db_task_printsym (unsigned int addr)
20772{
20773 print_address (addr, stderr);
20774}
20775#endif
20776
20777int
2cf0635d 20778main (int argc, char ** argv)
252b5132 20779{
ff78d6d6
L
20780 int err;
20781
252b5132
RH
20782#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
20783 setlocale (LC_MESSAGES, "");
3882b010
L
20784#endif
20785#if defined (HAVE_SETLOCALE)
20786 setlocale (LC_CTYPE, "");
252b5132
RH
20787#endif
20788 bindtextdomain (PACKAGE, LOCALEDIR);
20789 textdomain (PACKAGE);
20790
869b9d07
MM
20791 expandargv (&argc, &argv);
20792
dda8d76d 20793 parse_args (& cmdline, argc, argv);
59f14fc0 20794
18bd398b 20795 if (optind < (argc - 1))
1b513401
NC
20796 /* When displaying information for more than one file,
20797 prefix the information with the file name. */
32ec8896 20798 show_name = TRUE;
5656ba2c
L
20799 else if (optind >= argc)
20800 {
1b513401
NC
20801 /* Ensure that the warning is always displayed. */
20802 do_checks = TRUE;
20803
5656ba2c
L
20804 warn (_("Nothing to do.\n"));
20805 usage (stderr);
20806 }
18bd398b 20807
32ec8896 20808 err = FALSE;
252b5132 20809 while (optind < argc)
32ec8896
NC
20810 if (! process_file (argv[optind++]))
20811 err = TRUE;
252b5132 20812
dda8d76d
NC
20813 if (cmdline.dump_sects != NULL)
20814 free (cmdline.dump_sects);
252b5132 20815
7d9813f1
NA
20816 free (dump_ctf_symtab_name);
20817 free (dump_ctf_strtab_name);
20818 free (dump_ctf_parent_name);
20819
32ec8896 20820 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 20821}