]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
gdb: unify parts of the Linux and FreeBSD core dumping code
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
250d07de 2 Copyright (C) 1998-2021 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056 46#include <zlib.h>
3bfcb652 47#ifdef HAVE_WCHAR_H
7bfd842d 48#include <wchar.h>
3bfcb652 49#endif
252b5132 50
a952a375 51#if __GNUC__ >= 2
19936277 52/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 53 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 54 Only do this if we believe that the compiler can support a 64 bit
a952a375 55 data type. For now we only rely on GCC being able to do this. */
19936277 56#define BFD64
a952a375
NC
57#endif
58
3db64b00
AM
59#include "bfd.h"
60#include "bucomm.h"
3284fe0c 61#include "elfcomm.h"
19e6b90e 62#include "dwarf.h"
7d9813f1 63#include "ctf-api.h"
79bc120c 64#include "demangle.h"
252b5132
RH
65
66#include "elf/common.h"
67#include "elf/external.h"
68#include "elf/internal.h"
252b5132 69
4b78141a
NC
70
71/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
72 we can obtain the H8 reloc numbers. We need these for the
73 get_reloc_size() function. We include h8.h again after defining
74 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
75
76#include "elf/h8.h"
77#undef _ELF_H8_H
78
79/* Undo the effects of #including reloc-macros.h. */
80
81#undef START_RELOC_NUMBERS
82#undef RELOC_NUMBER
83#undef FAKE_RELOC
84#undef EMPTY_RELOC
85#undef END_RELOC_NUMBERS
86#undef _RELOC_MACROS_H
87
252b5132
RH
88/* The following headers use the elf/reloc-macros.h file to
89 automatically generate relocation recognition functions
90 such as elf_mips_reloc_type() */
91
92#define RELOC_MACROS_GEN_FUNC
93
a06ea964 94#include "elf/aarch64.h"
252b5132 95#include "elf/alpha.h"
3b16e843 96#include "elf/arc.h"
252b5132 97#include "elf/arm.h"
3b16e843 98#include "elf/avr.h"
1d65ded4 99#include "elf/bfin.h"
60bca95a 100#include "elf/cr16.h"
3b16e843 101#include "elf/cris.h"
1c0d3aa6 102#include "elf/crx.h"
b8891f8d 103#include "elf/csky.h"
252b5132
RH
104#include "elf/d10v.h"
105#include "elf/d30v.h"
d172d4ba 106#include "elf/dlx.h"
aca4efc7 107#include "elf/bpf.h"
cfb8c092 108#include "elf/epiphany.h"
252b5132 109#include "elf/fr30.h"
5c70f934 110#include "elf/frv.h"
3f8107ab 111#include "elf/ft32.h"
3b16e843
NC
112#include "elf/h8.h"
113#include "elf/hppa.h"
114#include "elf/i386.h"
f954747f
AM
115#include "elf/i370.h"
116#include "elf/i860.h"
117#include "elf/i960.h"
3b16e843 118#include "elf/ia64.h"
1e4cf259 119#include "elf/ip2k.h"
84e94c90 120#include "elf/lm32.h"
1c0d3aa6 121#include "elf/iq2000.h"
49f58d10 122#include "elf/m32c.h"
3b16e843
NC
123#include "elf/m32r.h"
124#include "elf/m68k.h"
75751cd9 125#include "elf/m68hc11.h"
7b4ae824 126#include "elf/s12z.h"
252b5132 127#include "elf/mcore.h"
15ab5209 128#include "elf/mep.h"
a3c62988 129#include "elf/metag.h"
7ba29e2a 130#include "elf/microblaze.h"
3b16e843 131#include "elf/mips.h"
3c3bdf30 132#include "elf/mmix.h"
3b16e843
NC
133#include "elf/mn10200.h"
134#include "elf/mn10300.h"
5506d11a 135#include "elf/moxie.h"
4970f871 136#include "elf/mt.h"
2469cfa2 137#include "elf/msp430.h"
35c08157 138#include "elf/nds32.h"
fe944acf 139#include "elf/nfp.h"
13761a11 140#include "elf/nios2.h"
73589c9d 141#include "elf/or1k.h"
7d466069 142#include "elf/pj.h"
3b16e843 143#include "elf/ppc.h"
c833c019 144#include "elf/ppc64.h"
2b100bb5 145#include "elf/pru.h"
03336641 146#include "elf/riscv.h"
99c513f6 147#include "elf/rl78.h"
c7927a3c 148#include "elf/rx.h"
a85d7ed0 149#include "elf/s390.h"
1c0d3aa6 150#include "elf/score.h"
3b16e843
NC
151#include "elf/sh.h"
152#include "elf/sparc.h"
e9f53129 153#include "elf/spu.h"
40b36596 154#include "elf/tic6x.h"
aa137e4d
NC
155#include "elf/tilegx.h"
156#include "elf/tilepro.h"
3b16e843 157#include "elf/v850.h"
179d3252 158#include "elf/vax.h"
619ed720 159#include "elf/visium.h"
f96bd6c2 160#include "elf/wasm32.h"
3b16e843 161#include "elf/x86-64.h"
c29aca4a 162#include "elf/xc16x.h"
f6c1a2d5 163#include "elf/xgate.h"
93fbbb04 164#include "elf/xstormy16.h"
88da6820 165#include "elf/xtensa.h"
6655dba2 166#include "elf/z80.h"
252b5132 167
252b5132 168#include "getopt.h"
566b0d53 169#include "libiberty.h"
09c11c86 170#include "safe-ctype.h"
2cf0635d 171#include "filenames.h"
252b5132 172
15b42fb0
AM
173#ifndef offsetof
174#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
175#endif
176
6a40cf0c
NC
177typedef struct elf_section_list
178{
dda8d76d
NC
179 Elf_Internal_Shdr * hdr;
180 struct elf_section_list * next;
6a40cf0c
NC
181} elf_section_list;
182
dda8d76d
NC
183/* Flag bits indicating particular types of dump. */
184#define HEX_DUMP (1 << 0) /* The -x command line switch. */
185#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
186#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
187#define STRING_DUMP (1 << 3) /* The -p command line switch. */
188#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 189#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
190
191typedef unsigned char dump_type;
192
193/* A linked list of the section names for which dumps were requested. */
194struct dump_list_entry
195{
196 char * name;
197 dump_type type;
198 struct dump_list_entry * next;
199};
200
6431e409
AM
201/* A dynamic array of flags indicating for which sections a dump
202 has been requested via command line switches. */
1b513401
NC
203struct dump_data
204{
6431e409
AM
205 dump_type * dump_sects;
206 unsigned int num_dump_sects;
207};
208
209static struct dump_data cmdline;
210
211static struct dump_list_entry * dump_sects_byname;
212
2cf0635d 213char * program_name = "readelf";
dda8d76d 214
32ec8896
NC
215static bfd_boolean show_name = FALSE;
216static bfd_boolean do_dynamic = FALSE;
217static bfd_boolean do_syms = FALSE;
218static bfd_boolean do_dyn_syms = FALSE;
0f03783c 219static bfd_boolean do_lto_syms = FALSE;
32ec8896
NC
220static bfd_boolean do_reloc = FALSE;
221static bfd_boolean do_sections = FALSE;
222static bfd_boolean do_section_groups = FALSE;
223static bfd_boolean do_section_details = FALSE;
224static bfd_boolean do_segments = FALSE;
225static bfd_boolean do_unwind = FALSE;
226static bfd_boolean do_using_dynamic = FALSE;
227static bfd_boolean do_header = FALSE;
228static bfd_boolean do_dump = FALSE;
229static bfd_boolean do_version = FALSE;
230static bfd_boolean do_histogram = FALSE;
231static bfd_boolean do_debugging = FALSE;
7d9813f1 232static bfd_boolean do_ctf = FALSE;
32ec8896
NC
233static bfd_boolean do_arch = FALSE;
234static bfd_boolean do_notes = FALSE;
235static bfd_boolean do_archive_index = FALSE;
1b513401 236static bfd_boolean check_all = FALSE;
32ec8896
NC
237static bfd_boolean is_32bit_elf = FALSE;
238static bfd_boolean decompress_dumps = FALSE;
0942c7ab 239static bfd_boolean do_not_show_symbol_truncation = FALSE;
79bc120c 240static bfd_boolean do_demangle = FALSE; /* Pretty print C++ symbol names. */
ca0e11aa 241static bfd_boolean process_links = FALSE;
79bc120c 242static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
252b5132 243
7d9813f1
NA
244static char *dump_ctf_parent_name;
245static char *dump_ctf_symtab_name;
246static char *dump_ctf_strtab_name;
247
e4b17d5c
L
248struct group_list
249{
dda8d76d
NC
250 struct group_list * next;
251 unsigned int section_index;
e4b17d5c
L
252};
253
254struct group
255{
dda8d76d
NC
256 struct group_list * root;
257 unsigned int group_index;
e4b17d5c
L
258};
259
978c4450
AM
260typedef struct filedata
261{
262 const char * file_name;
ca0e11aa 263 bfd_boolean is_separate;
978c4450
AM
264 FILE * handle;
265 bfd_size_type file_size;
266 Elf_Internal_Ehdr file_header;
267 Elf_Internal_Shdr * section_headers;
268 Elf_Internal_Phdr * program_headers;
269 char * string_table;
270 unsigned long string_table_length;
271 unsigned long archive_file_offset;
272 unsigned long archive_file_size;
273 unsigned long dynamic_addr;
274 bfd_size_type dynamic_size;
275 size_t dynamic_nent;
276 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 277 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450
AM
278 char * dynamic_strings;
279 unsigned long dynamic_strings_length;
8ac10c5b 280 Elf_Internal_Shdr * dynamic_symtab_section;
978c4450
AM
281 unsigned long num_dynamic_syms;
282 Elf_Internal_Sym * dynamic_symbols;
283 bfd_vma version_info[16];
284 unsigned int dynamic_syminfo_nent;
285 Elf_Internal_Syminfo * dynamic_syminfo;
286 unsigned long dynamic_syminfo_offset;
287 bfd_size_type nbuckets;
288 bfd_size_type nchains;
289 bfd_vma * buckets;
290 bfd_vma * chains;
291 bfd_size_type ngnubuckets;
292 bfd_size_type ngnuchains;
293 bfd_vma * gnubuckets;
294 bfd_vma * gnuchains;
295 bfd_vma * mipsxlat;
296 bfd_vma gnusymidx;
297 char program_interpreter[PATH_MAX];
298 bfd_vma dynamic_info[DT_ENCODING];
299 bfd_vma dynamic_info_DT_GNU_HASH;
300 bfd_vma dynamic_info_DT_MIPS_XHASH;
301 elf_section_list * symtab_shndx_list;
302 size_t group_count;
303 struct group * section_groups;
304 struct group ** section_headers_groups;
305 /* A dynamic array of flags indicating for which sections a dump of
306 some kind has been requested. It is reset on a per-object file
307 basis and then initialised from the cmdline_dump_sects array,
308 the results of interpreting the -w switch, and the
309 dump_sects_byname list. */
310 struct dump_data dump;
311} Filedata;
aef1f6d0 312
c256ffe7 313/* How to print a vma value. */
843dd992
NC
314typedef enum print_mode
315{
316 HEX,
317 DEC,
318 DEC_5,
319 UNSIGNED,
320 PREFIX_HEX,
321 FULL_HEX,
322 LONG_HEX
323}
324print_mode;
325
bb4d2ac2
L
326/* Versioned symbol info. */
327enum versioned_symbol_info
328{
329 symbol_undefined,
330 symbol_hidden,
331 symbol_public
332};
333
32ec8896 334static const char * get_symbol_version_string
dda8d76d 335 (Filedata *, bfd_boolean, const char *, unsigned long, unsigned,
32ec8896 336 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 337
9c19a809
NC
338#define UNKNOWN -1
339
b9e920ec
AM
340#define SECTION_NAME(X) \
341 (filedata->string_table + (X)->sh_name)
342
343#define SECTION_NAME_VALID(X) \
344 ((X) != NULL \
345 && filedata->string_table != NULL \
346 && (X)->sh_name < filedata->string_table_length)
347
348#define SECTION_NAME_PRINT(X) \
349 ((X) == NULL ? _("<none>") \
350 : filedata->string_table == NULL ? _("<no-strings>") \
351 : (X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
352 : filedata->string_table + (X)->sh_name)
252b5132 353
ee42cf8c 354#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 355
ba5cdace
NC
356#define GET_ELF_SYMBOLS(file, section, sym_count) \
357 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
358 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 359
10ca4b04
L
360#define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
361 (strtab != NULL && offset < strtab_size)
978c4450
AM
362#define VALID_DYNAMIC_NAME(filedata, offset) \
363 VALID_SYMBOL_NAME (filedata->dynamic_strings, \
364 filedata->dynamic_strings_length, offset)
d79b3d50
NC
365/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
366 already been called and verified that the string exists. */
978c4450
AM
367#define GET_DYNAMIC_NAME(filedata, offset) \
368 (filedata->dynamic_strings + offset)
18bd398b 369
61865e30
NC
370#define REMOVE_ARCH_BITS(ADDR) \
371 do \
372 { \
dda8d76d 373 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
374 (ADDR) &= ~1; \
375 } \
376 while (0)
f16a9783
MS
377
378/* Get the correct GNU hash section name. */
978c4450
AM
379#define GNU_HASH_SECTION_NAME(filedata) \
380 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 381\f
66cfc0fd
AM
382/* Print a BFD_VMA to an internal buffer, for use in error messages.
383 BFD_FMA_FMT can't be used in translated strings. */
384
385static const char *
386bfd_vmatoa (char *fmtch, bfd_vma value)
387{
388 /* bfd_vmatoa is used more then once in a printf call for output.
389 Cycle through an array of buffers. */
390 static int buf_pos = 0;
391 static struct bfd_vmatoa_buf
392 {
393 char place[64];
394 } buf[4];
395 char *ret;
396 char fmt[32];
397
398 ret = buf[buf_pos++].place;
399 buf_pos %= ARRAY_SIZE (buf);
400
401 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
402 snprintf (ret, sizeof (buf[0].place), fmt, value);
403 return ret;
404}
405
dda8d76d
NC
406/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
407 OFFSET + the offset of the current archive member, if we are examining an
408 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
409 allocate a buffer using malloc and fill that. In either case return the
410 pointer to the start of the retrieved data or NULL if something went wrong.
411 If something does go wrong and REASON is not NULL then emit an error
412 message using REASON as part of the context. */
59245841 413
c256ffe7 414static void *
dda8d76d
NC
415get_data (void * var,
416 Filedata * filedata,
417 unsigned long offset,
418 bfd_size_type size,
419 bfd_size_type nmemb,
420 const char * reason)
a6e9f9df 421{
2cf0635d 422 void * mvar;
57028622 423 bfd_size_type amt = size * nmemb;
a6e9f9df 424
c256ffe7 425 if (size == 0 || nmemb == 0)
a6e9f9df
AM
426 return NULL;
427
57028622
NC
428 /* If the size_t type is smaller than the bfd_size_type, eg because
429 you are building a 32-bit tool on a 64-bit host, then make sure
430 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
431 if ((size_t) size != size
432 || (size_t) nmemb != nmemb
433 || (size_t) amt != amt)
57028622
NC
434 {
435 if (reason)
66cfc0fd
AM
436 error (_("Size truncation prevents reading %s"
437 " elements of size %s for %s\n"),
438 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
439 return NULL;
440 }
441
442 /* Check for size overflow. */
7c1c1904 443 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
444 {
445 if (reason)
66cfc0fd
AM
446 error (_("Size overflow prevents reading %s"
447 " elements of size %s for %s\n"),
448 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
449 return NULL;
450 }
451
c22b42ce 452 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 453 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
454 if (filedata->archive_file_offset > filedata->file_size
455 || offset > filedata->file_size - filedata->archive_file_offset
456 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 457 {
049b0c3a 458 if (reason)
66cfc0fd
AM
459 error (_("Reading %s bytes extends past end of file for %s\n"),
460 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
461 return NULL;
462 }
463
978c4450
AM
464 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
465 SEEK_SET))
071436c6
NC
466 {
467 if (reason)
c9c1d674 468 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 469 filedata->archive_file_offset + offset, reason);
071436c6
NC
470 return NULL;
471 }
472
a6e9f9df
AM
473 mvar = var;
474 if (mvar == NULL)
475 {
7c1c1904
AM
476 /* + 1 so that we can '\0' terminate invalid string table sections. */
477 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
478
479 if (mvar == NULL)
480 {
049b0c3a 481 if (reason)
66cfc0fd
AM
482 error (_("Out of memory allocating %s bytes for %s\n"),
483 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
484 return NULL;
485 }
c256ffe7 486
c9c1d674 487 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
488 }
489
dda8d76d 490 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 491 {
049b0c3a 492 if (reason)
66cfc0fd
AM
493 error (_("Unable to read in %s bytes of %s\n"),
494 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
495 if (mvar != var)
496 free (mvar);
497 return NULL;
498 }
499
500 return mvar;
501}
502
32ec8896
NC
503/* Print a VMA value in the MODE specified.
504 Returns the number of characters displayed. */
cb8f3167 505
32ec8896 506static unsigned int
14a91970 507print_vma (bfd_vma vma, print_mode mode)
66543521 508{
32ec8896 509 unsigned int nc = 0;
66543521 510
14a91970 511 switch (mode)
66543521 512 {
14a91970
AM
513 case FULL_HEX:
514 nc = printf ("0x");
1a0670f3 515 /* Fall through. */
14a91970 516 case LONG_HEX:
f7a99963 517#ifdef BFD64
14a91970 518 if (is_32bit_elf)
437c2fb7 519 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 520#endif
14a91970
AM
521 printf_vma (vma);
522 return nc + 16;
b19aac67 523
14a91970
AM
524 case DEC_5:
525 if (vma <= 99999)
526 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 527 /* Fall through. */
14a91970
AM
528 case PREFIX_HEX:
529 nc = printf ("0x");
1a0670f3 530 /* Fall through. */
14a91970
AM
531 case HEX:
532 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 533
14a91970
AM
534 case DEC:
535 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 536
14a91970
AM
537 case UNSIGNED:
538 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896
NC
539
540 default:
541 /* FIXME: Report unrecognised mode ? */
542 return 0;
f7a99963 543 }
f7a99963
NC
544}
545
7bfd842d 546/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 547 multibye characters (assuming the host environment supports them).
31104126 548
7bfd842d
NC
549 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
550
0942c7ab
NC
551 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
552 abs(WIDTH) - 5 characters followed by "[...]".
553
7bfd842d
NC
554 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
555 padding as necessary.
171191ba
NC
556
557 Returns the number of emitted characters. */
558
559static unsigned int
0942c7ab 560print_symbol (signed int width, const char * symbol)
31104126 561{
171191ba 562 bfd_boolean extra_padding = FALSE;
0942c7ab 563 bfd_boolean do_dots = FALSE;
32ec8896 564 signed int num_printed = 0;
3bfcb652 565#ifdef HAVE_MBSTATE_T
7bfd842d 566 mbstate_t state;
3bfcb652 567#endif
32ec8896 568 unsigned int width_remaining;
79bc120c 569 const void * alloced_symbol = NULL;
961c521f 570
7bfd842d 571 if (width < 0)
961c521f 572 {
88305e1b 573 /* Keep the width positive. This helps the code below. */
961c521f 574 width = - width;
171191ba 575 extra_padding = TRUE;
0b4362b0 576 }
56d8f8a9
NC
577 else if (width == 0)
578 return 0;
961c521f 579
7bfd842d
NC
580 if (do_wide)
581 /* Set the remaining width to a very large value.
582 This simplifies the code below. */
583 width_remaining = INT_MAX;
584 else
0942c7ab
NC
585 {
586 width_remaining = width;
587 if (! do_not_show_symbol_truncation
588 && (int) strlen (symbol) > width)
589 {
590 width_remaining -= 5;
591 if ((int) width_remaining < 0)
592 width_remaining = 0;
593 do_dots = TRUE;
594 }
595 }
cb8f3167 596
3bfcb652 597#ifdef HAVE_MBSTATE_T
7bfd842d
NC
598 /* Initialise the multibyte conversion state. */
599 memset (& state, 0, sizeof (state));
3bfcb652 600#endif
961c521f 601
79bc120c
NC
602 if (do_demangle && *symbol)
603 {
604 const char * res = cplus_demangle (symbol, demangle_flags);
605
606 if (res != NULL)
607 alloced_symbol = symbol = res;
608 }
609
7bfd842d
NC
610 while (width_remaining)
611 {
612 size_t n;
7bfd842d 613 const char c = *symbol++;
961c521f 614
7bfd842d 615 if (c == 0)
961c521f
NC
616 break;
617
7bfd842d
NC
618 /* Do not print control characters directly as they can affect terminal
619 settings. Such characters usually appear in the names generated
620 by the assembler for local labels. */
621 if (ISCNTRL (c))
961c521f 622 {
7bfd842d 623 if (width_remaining < 2)
961c521f
NC
624 break;
625
7bfd842d
NC
626 printf ("^%c", c + 0x40);
627 width_remaining -= 2;
171191ba 628 num_printed += 2;
961c521f 629 }
7bfd842d
NC
630 else if (ISPRINT (c))
631 {
632 putchar (c);
633 width_remaining --;
634 num_printed ++;
635 }
961c521f
NC
636 else
637 {
3bfcb652
NC
638#ifdef HAVE_MBSTATE_T
639 wchar_t w;
640#endif
7bfd842d
NC
641 /* Let printf do the hard work of displaying multibyte characters. */
642 printf ("%.1s", symbol - 1);
643 width_remaining --;
644 num_printed ++;
645
3bfcb652 646#ifdef HAVE_MBSTATE_T
7bfd842d
NC
647 /* Try to find out how many bytes made up the character that was
648 just printed. Advance the symbol pointer past the bytes that
649 were displayed. */
650 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
651#else
652 n = 1;
653#endif
7bfd842d
NC
654 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
655 symbol += (n - 1);
961c521f 656 }
961c521f 657 }
171191ba 658
0942c7ab
NC
659 if (do_dots)
660 num_printed += printf ("[...]");
661
7bfd842d 662 if (extra_padding && num_printed < width)
171191ba
NC
663 {
664 /* Fill in the remaining spaces. */
7bfd842d
NC
665 printf ("%-*s", width - num_printed, " ");
666 num_printed = width;
171191ba
NC
667 }
668
79bc120c 669 free ((void *) alloced_symbol);
171191ba 670 return num_printed;
31104126
NC
671}
672
1449284b 673/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
674 the given section's name. Like print_symbol, except that it does not try
675 to print multibyte characters, it just interprets them as hex values. */
676
677static const char *
dda8d76d 678printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 679{
ca0e11aa 680#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 681 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
b9e920ec 682 const char * name = SECTION_NAME_PRINT (sec);
74e1a04b
NC
683 char * buf = sec_name_buf;
684 char c;
685 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
686
687 while ((c = * name ++) != 0)
688 {
689 if (ISCNTRL (c))
690 {
691 if (remaining < 2)
692 break;
948f632f 693
74e1a04b
NC
694 * buf ++ = '^';
695 * buf ++ = c + 0x40;
696 remaining -= 2;
697 }
698 else if (ISPRINT (c))
699 {
700 * buf ++ = c;
701 remaining -= 1;
702 }
703 else
704 {
705 static char hex[17] = "0123456789ABCDEF";
706
707 if (remaining < 4)
708 break;
709 * buf ++ = '<';
710 * buf ++ = hex[(c & 0xf0) >> 4];
711 * buf ++ = hex[c & 0x0f];
712 * buf ++ = '>';
713 remaining -= 4;
714 }
715
716 if (remaining == 0)
717 break;
718 }
719
720 * buf = 0;
721 return sec_name_buf;
722}
723
724static const char *
dda8d76d 725printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 726{
dda8d76d 727 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
728 return _("<corrupt>");
729
dda8d76d 730 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
731}
732
89fac5e3
RS
733/* Return a pointer to section NAME, or NULL if no such section exists. */
734
735static Elf_Internal_Shdr *
dda8d76d 736find_section (Filedata * filedata, const char * name)
89fac5e3
RS
737{
738 unsigned int i;
739
68807c3c
NC
740 if (filedata->section_headers == NULL)
741 return NULL;
dda8d76d
NC
742
743 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
744 if (SECTION_NAME_VALID (filedata->section_headers + i)
745 && streq (SECTION_NAME (filedata->section_headers + i), name))
dda8d76d 746 return filedata->section_headers + i;
89fac5e3
RS
747
748 return NULL;
749}
750
0b6ae522
DJ
751/* Return a pointer to a section containing ADDR, or NULL if no such
752 section exists. */
753
754static Elf_Internal_Shdr *
dda8d76d 755find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
756{
757 unsigned int i;
758
68807c3c
NC
759 if (filedata->section_headers == NULL)
760 return NULL;
761
dda8d76d 762 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 763 {
dda8d76d
NC
764 Elf_Internal_Shdr *sec = filedata->section_headers + i;
765
0b6ae522
DJ
766 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
767 return sec;
768 }
769
770 return NULL;
771}
772
071436c6 773static Elf_Internal_Shdr *
dda8d76d 774find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
775{
776 unsigned int i;
777
68807c3c
NC
778 if (filedata->section_headers == NULL)
779 return NULL;
780
dda8d76d 781 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 782 {
dda8d76d
NC
783 Elf_Internal_Shdr *sec = filedata->section_headers + i;
784
071436c6
NC
785 if (sec->sh_type == type)
786 return sec;
787 }
788
789 return NULL;
790}
791
657d0d47
CC
792/* Return a pointer to section NAME, or NULL if no such section exists,
793 restricted to the list of sections given in SET. */
794
795static Elf_Internal_Shdr *
dda8d76d 796find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
797{
798 unsigned int i;
799
68807c3c
NC
800 if (filedata->section_headers == NULL)
801 return NULL;
802
657d0d47
CC
803 if (set != NULL)
804 {
805 while ((i = *set++) > 0)
b814a36d
NC
806 {
807 /* See PR 21156 for a reproducer. */
dda8d76d 808 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
809 continue; /* FIXME: Should we issue an error message ? */
810
b9e920ec
AM
811 if (SECTION_NAME_VALID (filedata->section_headers + i)
812 && streq (SECTION_NAME (filedata->section_headers + i), name))
dda8d76d 813 return filedata->section_headers + i;
b814a36d 814 }
657d0d47
CC
815 }
816
dda8d76d 817 return find_section (filedata, name);
657d0d47
CC
818}
819
32ec8896 820/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
821 This OS has so many departures from the ELF standard that we test it at
822 many places. */
823
32ec8896 824static inline bfd_boolean
dda8d76d 825is_ia64_vms (Filedata * filedata)
28f997cf 826{
dda8d76d
NC
827 return filedata->file_header.e_machine == EM_IA_64
828 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
829}
830
bcedfee6 831/* Guess the relocation size commonly used by the specific machines. */
252b5132 832
32ec8896 833static bfd_boolean
2dc4cec1 834guess_is_rela (unsigned int e_machine)
252b5132 835{
9c19a809 836 switch (e_machine)
252b5132
RH
837 {
838 /* Targets that use REL relocations. */
252b5132 839 case EM_386:
22abe556 840 case EM_IAMCU:
f954747f 841 case EM_960:
e9f53129 842 case EM_ARM:
2b0337b0 843 case EM_D10V:
252b5132 844 case EM_CYGNUS_D10V:
e9f53129 845 case EM_DLX:
252b5132 846 case EM_MIPS:
4fe85591 847 case EM_MIPS_RS3_LE:
e9f53129 848 case EM_CYGNUS_M32R:
1c0d3aa6 849 case EM_SCORE:
f6c1a2d5 850 case EM_XGATE:
fe944acf 851 case EM_NFP:
aca4efc7 852 case EM_BPF:
9c19a809 853 return FALSE;
103f02d3 854
252b5132
RH
855 /* Targets that use RELA relocations. */
856 case EM_68K:
f954747f 857 case EM_860:
a06ea964 858 case EM_AARCH64:
cfb8c092 859 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
860 case EM_ALPHA:
861 case EM_ALTERA_NIOS2:
886a2506
NC
862 case EM_ARC:
863 case EM_ARC_COMPACT:
864 case EM_ARC_COMPACT2:
e9f53129
AM
865 case EM_AVR:
866 case EM_AVR_OLD:
867 case EM_BLACKFIN:
60bca95a 868 case EM_CR16:
e9f53129
AM
869 case EM_CRIS:
870 case EM_CRX:
b8891f8d 871 case EM_CSKY:
2b0337b0 872 case EM_D30V:
252b5132 873 case EM_CYGNUS_D30V:
2b0337b0 874 case EM_FR30:
3f8107ab 875 case EM_FT32:
252b5132 876 case EM_CYGNUS_FR30:
5c70f934 877 case EM_CYGNUS_FRV:
e9f53129
AM
878 case EM_H8S:
879 case EM_H8_300:
880 case EM_H8_300H:
800eeca4 881 case EM_IA_64:
1e4cf259
NC
882 case EM_IP2K:
883 case EM_IP2K_OLD:
3b36097d 884 case EM_IQ2000:
84e94c90 885 case EM_LATTICEMICO32:
ff7eeb89 886 case EM_M32C_OLD:
49f58d10 887 case EM_M32C:
e9f53129
AM
888 case EM_M32R:
889 case EM_MCORE:
15ab5209 890 case EM_CYGNUS_MEP:
a3c62988 891 case EM_METAG:
e9f53129
AM
892 case EM_MMIX:
893 case EM_MN10200:
894 case EM_CYGNUS_MN10200:
895 case EM_MN10300:
896 case EM_CYGNUS_MN10300:
5506d11a 897 case EM_MOXIE:
e9f53129
AM
898 case EM_MSP430:
899 case EM_MSP430_OLD:
d031aafb 900 case EM_MT:
35c08157 901 case EM_NDS32:
64fd6348 902 case EM_NIOS32:
73589c9d 903 case EM_OR1K:
e9f53129
AM
904 case EM_PPC64:
905 case EM_PPC:
2b100bb5 906 case EM_TI_PRU:
e23eba97 907 case EM_RISCV:
99c513f6 908 case EM_RL78:
c7927a3c 909 case EM_RX:
e9f53129
AM
910 case EM_S390:
911 case EM_S390_OLD:
912 case EM_SH:
913 case EM_SPARC:
914 case EM_SPARC32PLUS:
915 case EM_SPARCV9:
916 case EM_SPU:
40b36596 917 case EM_TI_C6000:
aa137e4d
NC
918 case EM_TILEGX:
919 case EM_TILEPRO:
708e2187 920 case EM_V800:
e9f53129
AM
921 case EM_V850:
922 case EM_CYGNUS_V850:
923 case EM_VAX:
619ed720 924 case EM_VISIUM:
e9f53129 925 case EM_X86_64:
8a9036a4 926 case EM_L1OM:
7a9068fe 927 case EM_K1OM:
e9f53129
AM
928 case EM_XSTORMY16:
929 case EM_XTENSA:
930 case EM_XTENSA_OLD:
7ba29e2a
NC
931 case EM_MICROBLAZE:
932 case EM_MICROBLAZE_OLD:
f96bd6c2 933 case EM_WEBASSEMBLY:
9c19a809 934 return TRUE;
103f02d3 935
e9f53129
AM
936 case EM_68HC05:
937 case EM_68HC08:
938 case EM_68HC11:
939 case EM_68HC16:
940 case EM_FX66:
941 case EM_ME16:
d1133906 942 case EM_MMA:
d1133906
NC
943 case EM_NCPU:
944 case EM_NDR1:
e9f53129 945 case EM_PCP:
d1133906 946 case EM_ST100:
e9f53129 947 case EM_ST19:
d1133906 948 case EM_ST7:
e9f53129
AM
949 case EM_ST9PLUS:
950 case EM_STARCORE:
d1133906 951 case EM_SVX:
e9f53129 952 case EM_TINYJ:
9c19a809
NC
953 default:
954 warn (_("Don't know about relocations on this machine architecture\n"));
955 return FALSE;
956 }
957}
252b5132 958
dda8d76d 959/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
960 Returns TRUE upon success, FALSE otherwise. If successful then a
961 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
962 and the number of relocs loaded is placed in *NRELASP. It is the caller's
963 responsibility to free the allocated buffer. */
964
965static bfd_boolean
dda8d76d
NC
966slurp_rela_relocs (Filedata * filedata,
967 unsigned long rel_offset,
968 unsigned long rel_size,
969 Elf_Internal_Rela ** relasp,
970 unsigned long * nrelasp)
9c19a809 971{
2cf0635d 972 Elf_Internal_Rela * relas;
8b73c356 973 size_t nrelas;
4d6ed7c8 974 unsigned int i;
252b5132 975
4d6ed7c8
NC
976 if (is_32bit_elf)
977 {
2cf0635d 978 Elf32_External_Rela * erelas;
103f02d3 979
dda8d76d 980 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 981 rel_size, _("32-bit relocation data"));
a6e9f9df 982 if (!erelas)
32ec8896 983 return FALSE;
252b5132 984
4d6ed7c8 985 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 986
3f5e193b
NC
987 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
988 sizeof (Elf_Internal_Rela));
103f02d3 989
4d6ed7c8
NC
990 if (relas == NULL)
991 {
c256ffe7 992 free (erelas);
591a748a 993 error (_("out of memory parsing relocs\n"));
32ec8896 994 return FALSE;
4d6ed7c8 995 }
103f02d3 996
4d6ed7c8
NC
997 for (i = 0; i < nrelas; i++)
998 {
999 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1000 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1001 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1002 }
103f02d3 1003
4d6ed7c8
NC
1004 free (erelas);
1005 }
1006 else
1007 {
2cf0635d 1008 Elf64_External_Rela * erelas;
103f02d3 1009
dda8d76d 1010 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1011 rel_size, _("64-bit relocation data"));
a6e9f9df 1012 if (!erelas)
32ec8896 1013 return FALSE;
4d6ed7c8
NC
1014
1015 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1016
3f5e193b
NC
1017 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1018 sizeof (Elf_Internal_Rela));
103f02d3 1019
4d6ed7c8
NC
1020 if (relas == NULL)
1021 {
c256ffe7 1022 free (erelas);
591a748a 1023 error (_("out of memory parsing relocs\n"));
32ec8896 1024 return FALSE;
9c19a809 1025 }
4d6ed7c8
NC
1026
1027 for (i = 0; i < nrelas; i++)
9c19a809 1028 {
66543521
AM
1029 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1030 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1031 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1032
1033 /* The #ifdef BFD64 below is to prevent a compile time
1034 warning. We know that if we do not have a 64 bit data
1035 type that we will never execute this code anyway. */
1036#ifdef BFD64
dda8d76d
NC
1037 if (filedata->file_header.e_machine == EM_MIPS
1038 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1039 {
1040 /* In little-endian objects, r_info isn't really a
1041 64-bit little-endian value: it has a 32-bit
1042 little-endian symbol index followed by four
1043 individual byte fields. Reorder INFO
1044 accordingly. */
91d6fa6a
NC
1045 bfd_vma inf = relas[i].r_info;
1046 inf = (((inf & 0xffffffff) << 32)
1047 | ((inf >> 56) & 0xff)
1048 | ((inf >> 40) & 0xff00)
1049 | ((inf >> 24) & 0xff0000)
1050 | ((inf >> 8) & 0xff000000));
1051 relas[i].r_info = inf;
861fb55a
DJ
1052 }
1053#endif /* BFD64 */
4d6ed7c8 1054 }
103f02d3 1055
4d6ed7c8
NC
1056 free (erelas);
1057 }
32ec8896 1058
4d6ed7c8
NC
1059 *relasp = relas;
1060 *nrelasp = nrelas;
32ec8896 1061 return TRUE;
4d6ed7c8 1062}
103f02d3 1063
dda8d76d 1064/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1065 Returns TRUE upon success, FALSE otherwise. If successful then a
1066 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1067 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1068 responsibility to free the allocated buffer. */
1069
1070static bfd_boolean
dda8d76d
NC
1071slurp_rel_relocs (Filedata * filedata,
1072 unsigned long rel_offset,
1073 unsigned long rel_size,
1074 Elf_Internal_Rela ** relsp,
1075 unsigned long * nrelsp)
4d6ed7c8 1076{
2cf0635d 1077 Elf_Internal_Rela * rels;
8b73c356 1078 size_t nrels;
4d6ed7c8 1079 unsigned int i;
103f02d3 1080
4d6ed7c8
NC
1081 if (is_32bit_elf)
1082 {
2cf0635d 1083 Elf32_External_Rel * erels;
103f02d3 1084
dda8d76d 1085 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1086 rel_size, _("32-bit relocation data"));
a6e9f9df 1087 if (!erels)
32ec8896 1088 return FALSE;
103f02d3 1089
4d6ed7c8 1090 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1091
3f5e193b 1092 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1093
4d6ed7c8
NC
1094 if (rels == NULL)
1095 {
c256ffe7 1096 free (erels);
591a748a 1097 error (_("out of memory parsing relocs\n"));
32ec8896 1098 return FALSE;
4d6ed7c8
NC
1099 }
1100
1101 for (i = 0; i < nrels; i++)
1102 {
1103 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1104 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1105 rels[i].r_addend = 0;
9ea033b2 1106 }
4d6ed7c8
NC
1107
1108 free (erels);
9c19a809
NC
1109 }
1110 else
1111 {
2cf0635d 1112 Elf64_External_Rel * erels;
9ea033b2 1113
dda8d76d 1114 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1115 rel_size, _("64-bit relocation data"));
a6e9f9df 1116 if (!erels)
32ec8896 1117 return FALSE;
103f02d3 1118
4d6ed7c8 1119 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1120
3f5e193b 1121 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1122
4d6ed7c8 1123 if (rels == NULL)
9c19a809 1124 {
c256ffe7 1125 free (erels);
591a748a 1126 error (_("out of memory parsing relocs\n"));
32ec8896 1127 return FALSE;
4d6ed7c8 1128 }
103f02d3 1129
4d6ed7c8
NC
1130 for (i = 0; i < nrels; i++)
1131 {
66543521
AM
1132 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1133 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1134 rels[i].r_addend = 0;
861fb55a
DJ
1135
1136 /* The #ifdef BFD64 below is to prevent a compile time
1137 warning. We know that if we do not have a 64 bit data
1138 type that we will never execute this code anyway. */
1139#ifdef BFD64
dda8d76d
NC
1140 if (filedata->file_header.e_machine == EM_MIPS
1141 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1142 {
1143 /* In little-endian objects, r_info isn't really a
1144 64-bit little-endian value: it has a 32-bit
1145 little-endian symbol index followed by four
1146 individual byte fields. Reorder INFO
1147 accordingly. */
91d6fa6a
NC
1148 bfd_vma inf = rels[i].r_info;
1149 inf = (((inf & 0xffffffff) << 32)
1150 | ((inf >> 56) & 0xff)
1151 | ((inf >> 40) & 0xff00)
1152 | ((inf >> 24) & 0xff0000)
1153 | ((inf >> 8) & 0xff000000));
1154 rels[i].r_info = inf;
861fb55a
DJ
1155 }
1156#endif /* BFD64 */
4d6ed7c8 1157 }
103f02d3 1158
4d6ed7c8
NC
1159 free (erels);
1160 }
32ec8896 1161
4d6ed7c8
NC
1162 *relsp = rels;
1163 *nrelsp = nrels;
32ec8896 1164 return TRUE;
4d6ed7c8 1165}
103f02d3 1166
aca88567
NC
1167/* Returns the reloc type extracted from the reloc info field. */
1168
1169static unsigned int
dda8d76d 1170get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1171{
1172 if (is_32bit_elf)
1173 return ELF32_R_TYPE (reloc_info);
1174
dda8d76d 1175 switch (filedata->file_header.e_machine)
aca88567
NC
1176 {
1177 case EM_MIPS:
1178 /* Note: We assume that reloc_info has already been adjusted for us. */
1179 return ELF64_MIPS_R_TYPE (reloc_info);
1180
1181 case EM_SPARCV9:
1182 return ELF64_R_TYPE_ID (reloc_info);
1183
1184 default:
1185 return ELF64_R_TYPE (reloc_info);
1186 }
1187}
1188
1189/* Return the symbol index extracted from the reloc info field. */
1190
1191static bfd_vma
1192get_reloc_symindex (bfd_vma reloc_info)
1193{
1194 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1195}
1196
13761a11 1197static inline bfd_boolean
dda8d76d 1198uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1199{
1200 return
dda8d76d 1201 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1202 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1203 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1204 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1205 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1206}
1207
d3ba0551
AM
1208/* Display the contents of the relocation data found at the specified
1209 offset. */
ee42cf8c 1210
32ec8896 1211static bfd_boolean
dda8d76d
NC
1212dump_relocations (Filedata * filedata,
1213 unsigned long rel_offset,
1214 unsigned long rel_size,
1215 Elf_Internal_Sym * symtab,
1216 unsigned long nsyms,
1217 char * strtab,
1218 unsigned long strtablen,
1219 int is_rela,
1220 bfd_boolean is_dynsym)
4d6ed7c8 1221{
32ec8896 1222 unsigned long i;
2cf0635d 1223 Elf_Internal_Rela * rels;
32ec8896 1224 bfd_boolean res = TRUE;
103f02d3 1225
4d6ed7c8 1226 if (is_rela == UNKNOWN)
dda8d76d 1227 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1228
4d6ed7c8
NC
1229 if (is_rela)
1230 {
dda8d76d 1231 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1232 return FALSE;
4d6ed7c8
NC
1233 }
1234 else
1235 {
dda8d76d 1236 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1237 return FALSE;
252b5132
RH
1238 }
1239
410f7a12
L
1240 if (is_32bit_elf)
1241 {
1242 if (is_rela)
2c71103e
NC
1243 {
1244 if (do_wide)
1245 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1246 else
1247 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1248 }
410f7a12 1249 else
2c71103e
NC
1250 {
1251 if (do_wide)
1252 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1253 else
1254 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1255 }
410f7a12 1256 }
252b5132 1257 else
410f7a12
L
1258 {
1259 if (is_rela)
2c71103e
NC
1260 {
1261 if (do_wide)
8beeaeb7 1262 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1263 else
1264 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1265 }
410f7a12 1266 else
2c71103e
NC
1267 {
1268 if (do_wide)
8beeaeb7 1269 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1270 else
1271 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1272 }
410f7a12 1273 }
252b5132
RH
1274
1275 for (i = 0; i < rel_size; i++)
1276 {
2cf0635d 1277 const char * rtype;
b34976b6 1278 bfd_vma offset;
91d6fa6a 1279 bfd_vma inf;
b34976b6
AM
1280 bfd_vma symtab_index;
1281 bfd_vma type;
103f02d3 1282
b34976b6 1283 offset = rels[i].r_offset;
91d6fa6a 1284 inf = rels[i].r_info;
103f02d3 1285
dda8d76d 1286 type = get_reloc_type (filedata, inf);
91d6fa6a 1287 symtab_index = get_reloc_symindex (inf);
252b5132 1288
410f7a12
L
1289 if (is_32bit_elf)
1290 {
39dbeff8
AM
1291 printf ("%8.8lx %8.8lx ",
1292 (unsigned long) offset & 0xffffffff,
91d6fa6a 1293 (unsigned long) inf & 0xffffffff);
410f7a12
L
1294 }
1295 else
1296 {
39dbeff8 1297 printf (do_wide
d1ce973e
AM
1298 ? "%16.16" BFD_VMA_FMT "x %16.16" BFD_VMA_FMT "x "
1299 : "%12.12" BFD_VMA_FMT "x %12.12" BFD_VMA_FMT "x ",
91d6fa6a 1300 offset, inf);
410f7a12 1301 }
103f02d3 1302
dda8d76d 1303 switch (filedata->file_header.e_machine)
252b5132
RH
1304 {
1305 default:
1306 rtype = NULL;
1307 break;
1308
a06ea964
NC
1309 case EM_AARCH64:
1310 rtype = elf_aarch64_reloc_type (type);
1311 break;
1312
2b0337b0 1313 case EM_M32R:
252b5132 1314 case EM_CYGNUS_M32R:
9ea033b2 1315 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1316 break;
1317
1318 case EM_386:
22abe556 1319 case EM_IAMCU:
9ea033b2 1320 rtype = elf_i386_reloc_type (type);
252b5132
RH
1321 break;
1322
ba2685cc
AM
1323 case EM_68HC11:
1324 case EM_68HC12:
1325 rtype = elf_m68hc11_reloc_type (type);
1326 break;
75751cd9 1327
7b4ae824
JD
1328 case EM_S12Z:
1329 rtype = elf_s12z_reloc_type (type);
1330 break;
1331
252b5132 1332 case EM_68K:
9ea033b2 1333 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1334 break;
1335
f954747f
AM
1336 case EM_960:
1337 rtype = elf_i960_reloc_type (type);
1338 break;
1339
adde6300 1340 case EM_AVR:
2b0337b0 1341 case EM_AVR_OLD:
adde6300
AM
1342 rtype = elf_avr_reloc_type (type);
1343 break;
1344
9ea033b2
NC
1345 case EM_OLD_SPARCV9:
1346 case EM_SPARC32PLUS:
1347 case EM_SPARCV9:
252b5132 1348 case EM_SPARC:
9ea033b2 1349 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1350 break;
1351
e9f53129
AM
1352 case EM_SPU:
1353 rtype = elf_spu_reloc_type (type);
1354 break;
1355
708e2187
NC
1356 case EM_V800:
1357 rtype = v800_reloc_type (type);
1358 break;
2b0337b0 1359 case EM_V850:
252b5132 1360 case EM_CYGNUS_V850:
9ea033b2 1361 rtype = v850_reloc_type (type);
252b5132
RH
1362 break;
1363
2b0337b0 1364 case EM_D10V:
252b5132 1365 case EM_CYGNUS_D10V:
9ea033b2 1366 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1367 break;
1368
2b0337b0 1369 case EM_D30V:
252b5132 1370 case EM_CYGNUS_D30V:
9ea033b2 1371 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1372 break;
1373
d172d4ba
NC
1374 case EM_DLX:
1375 rtype = elf_dlx_reloc_type (type);
1376 break;
1377
252b5132 1378 case EM_SH:
9ea033b2 1379 rtype = elf_sh_reloc_type (type);
252b5132
RH
1380 break;
1381
2b0337b0 1382 case EM_MN10300:
252b5132 1383 case EM_CYGNUS_MN10300:
9ea033b2 1384 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1385 break;
1386
2b0337b0 1387 case EM_MN10200:
252b5132 1388 case EM_CYGNUS_MN10200:
9ea033b2 1389 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1390 break;
1391
2b0337b0 1392 case EM_FR30:
252b5132 1393 case EM_CYGNUS_FR30:
9ea033b2 1394 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1395 break;
1396
ba2685cc
AM
1397 case EM_CYGNUS_FRV:
1398 rtype = elf_frv_reloc_type (type);
1399 break;
5c70f934 1400
b8891f8d
AJ
1401 case EM_CSKY:
1402 rtype = elf_csky_reloc_type (type);
1403 break;
1404
3f8107ab
AM
1405 case EM_FT32:
1406 rtype = elf_ft32_reloc_type (type);
1407 break;
1408
252b5132 1409 case EM_MCORE:
9ea033b2 1410 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1411 break;
1412
3c3bdf30
NC
1413 case EM_MMIX:
1414 rtype = elf_mmix_reloc_type (type);
1415 break;
1416
5506d11a
AM
1417 case EM_MOXIE:
1418 rtype = elf_moxie_reloc_type (type);
1419 break;
1420
2469cfa2 1421 case EM_MSP430:
dda8d76d 1422 if (uses_msp430x_relocs (filedata))
13761a11
NC
1423 {
1424 rtype = elf_msp430x_reloc_type (type);
1425 break;
1426 }
1a0670f3 1427 /* Fall through. */
2469cfa2
NC
1428 case EM_MSP430_OLD:
1429 rtype = elf_msp430_reloc_type (type);
1430 break;
1431
35c08157
KLC
1432 case EM_NDS32:
1433 rtype = elf_nds32_reloc_type (type);
1434 break;
1435
252b5132 1436 case EM_PPC:
9ea033b2 1437 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1438 break;
1439
c833c019
AM
1440 case EM_PPC64:
1441 rtype = elf_ppc64_reloc_type (type);
1442 break;
1443
252b5132 1444 case EM_MIPS:
4fe85591 1445 case EM_MIPS_RS3_LE:
9ea033b2 1446 rtype = elf_mips_reloc_type (type);
252b5132
RH
1447 break;
1448
e23eba97
NC
1449 case EM_RISCV:
1450 rtype = elf_riscv_reloc_type (type);
1451 break;
1452
252b5132 1453 case EM_ALPHA:
9ea033b2 1454 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1455 break;
1456
1457 case EM_ARM:
9ea033b2 1458 rtype = elf_arm_reloc_type (type);
252b5132
RH
1459 break;
1460
584da044 1461 case EM_ARC:
886a2506
NC
1462 case EM_ARC_COMPACT:
1463 case EM_ARC_COMPACT2:
9ea033b2 1464 rtype = elf_arc_reloc_type (type);
252b5132
RH
1465 break;
1466
1467 case EM_PARISC:
69e617ca 1468 rtype = elf_hppa_reloc_type (type);
252b5132 1469 break;
7d466069 1470
b8720f9d
JL
1471 case EM_H8_300:
1472 case EM_H8_300H:
1473 case EM_H8S:
1474 rtype = elf_h8_reloc_type (type);
1475 break;
1476
73589c9d
CS
1477 case EM_OR1K:
1478 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1479 break;
1480
7d466069 1481 case EM_PJ:
2b0337b0 1482 case EM_PJ_OLD:
7d466069
ILT
1483 rtype = elf_pj_reloc_type (type);
1484 break;
800eeca4
JW
1485 case EM_IA_64:
1486 rtype = elf_ia64_reloc_type (type);
1487 break;
1b61cf92
HPN
1488
1489 case EM_CRIS:
1490 rtype = elf_cris_reloc_type (type);
1491 break;
535c37ff 1492
f954747f
AM
1493 case EM_860:
1494 rtype = elf_i860_reloc_type (type);
1495 break;
1496
bcedfee6 1497 case EM_X86_64:
8a9036a4 1498 case EM_L1OM:
7a9068fe 1499 case EM_K1OM:
bcedfee6
NC
1500 rtype = elf_x86_64_reloc_type (type);
1501 break;
a85d7ed0 1502
f954747f
AM
1503 case EM_S370:
1504 rtype = i370_reloc_type (type);
1505 break;
1506
53c7db4b
KH
1507 case EM_S390_OLD:
1508 case EM_S390:
1509 rtype = elf_s390_reloc_type (type);
1510 break;
93fbbb04 1511
1c0d3aa6
NC
1512 case EM_SCORE:
1513 rtype = elf_score_reloc_type (type);
1514 break;
1515
93fbbb04
GK
1516 case EM_XSTORMY16:
1517 rtype = elf_xstormy16_reloc_type (type);
1518 break;
179d3252 1519
1fe1f39c
NC
1520 case EM_CRX:
1521 rtype = elf_crx_reloc_type (type);
1522 break;
1523
179d3252
JT
1524 case EM_VAX:
1525 rtype = elf_vax_reloc_type (type);
1526 break;
1e4cf259 1527
619ed720
EB
1528 case EM_VISIUM:
1529 rtype = elf_visium_reloc_type (type);
1530 break;
1531
aca4efc7
JM
1532 case EM_BPF:
1533 rtype = elf_bpf_reloc_type (type);
1534 break;
1535
cfb8c092
NC
1536 case EM_ADAPTEVA_EPIPHANY:
1537 rtype = elf_epiphany_reloc_type (type);
1538 break;
1539
1e4cf259
NC
1540 case EM_IP2K:
1541 case EM_IP2K_OLD:
1542 rtype = elf_ip2k_reloc_type (type);
1543 break;
3b36097d
SC
1544
1545 case EM_IQ2000:
1546 rtype = elf_iq2000_reloc_type (type);
1547 break;
88da6820
NC
1548
1549 case EM_XTENSA_OLD:
1550 case EM_XTENSA:
1551 rtype = elf_xtensa_reloc_type (type);
1552 break;
a34e3ecb 1553
84e94c90
NC
1554 case EM_LATTICEMICO32:
1555 rtype = elf_lm32_reloc_type (type);
1556 break;
1557
ff7eeb89 1558 case EM_M32C_OLD:
49f58d10
JB
1559 case EM_M32C:
1560 rtype = elf_m32c_reloc_type (type);
1561 break;
1562
d031aafb
NS
1563 case EM_MT:
1564 rtype = elf_mt_reloc_type (type);
a34e3ecb 1565 break;
1d65ded4
CM
1566
1567 case EM_BLACKFIN:
1568 rtype = elf_bfin_reloc_type (type);
1569 break;
15ab5209
DB
1570
1571 case EM_CYGNUS_MEP:
1572 rtype = elf_mep_reloc_type (type);
1573 break;
60bca95a
NC
1574
1575 case EM_CR16:
1576 rtype = elf_cr16_reloc_type (type);
1577 break;
dd24e3da 1578
7ba29e2a
NC
1579 case EM_MICROBLAZE:
1580 case EM_MICROBLAZE_OLD:
1581 rtype = elf_microblaze_reloc_type (type);
1582 break;
c7927a3c 1583
99c513f6
DD
1584 case EM_RL78:
1585 rtype = elf_rl78_reloc_type (type);
1586 break;
1587
c7927a3c
NC
1588 case EM_RX:
1589 rtype = elf_rx_reloc_type (type);
1590 break;
c29aca4a 1591
a3c62988
NC
1592 case EM_METAG:
1593 rtype = elf_metag_reloc_type (type);
1594 break;
1595
c29aca4a
NC
1596 case EM_XC16X:
1597 case EM_C166:
1598 rtype = elf_xc16x_reloc_type (type);
1599 break;
40b36596
JM
1600
1601 case EM_TI_C6000:
1602 rtype = elf_tic6x_reloc_type (type);
1603 break;
aa137e4d
NC
1604
1605 case EM_TILEGX:
1606 rtype = elf_tilegx_reloc_type (type);
1607 break;
1608
1609 case EM_TILEPRO:
1610 rtype = elf_tilepro_reloc_type (type);
1611 break;
f6c1a2d5 1612
f96bd6c2
PC
1613 case EM_WEBASSEMBLY:
1614 rtype = elf_wasm32_reloc_type (type);
1615 break;
1616
f6c1a2d5
NC
1617 case EM_XGATE:
1618 rtype = elf_xgate_reloc_type (type);
1619 break;
36591ba1
SL
1620
1621 case EM_ALTERA_NIOS2:
1622 rtype = elf_nios2_reloc_type (type);
1623 break;
2b100bb5
DD
1624
1625 case EM_TI_PRU:
1626 rtype = elf_pru_reloc_type (type);
1627 break;
fe944acf
FT
1628
1629 case EM_NFP:
1630 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1631 rtype = elf_nfp3200_reloc_type (type);
1632 else
1633 rtype = elf_nfp_reloc_type (type);
1634 break;
6655dba2
SB
1635
1636 case EM_Z80:
1637 rtype = elf_z80_reloc_type (type);
1638 break;
252b5132
RH
1639 }
1640
1641 if (rtype == NULL)
39dbeff8 1642 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1643 else
5c144731 1644 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1645
dda8d76d 1646 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1647 && rtype != NULL
7ace3541
RH
1648 && streq (rtype, "R_ALPHA_LITUSE")
1649 && is_rela)
1650 {
1651 switch (rels[i].r_addend)
1652 {
1653 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1654 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1655 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1656 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1657 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1658 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1659 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1660 default: rtype = NULL;
1661 }
32ec8896 1662
7ace3541
RH
1663 if (rtype)
1664 printf (" (%s)", rtype);
1665 else
1666 {
1667 putchar (' ');
1668 printf (_("<unknown addend: %lx>"),
1669 (unsigned long) rels[i].r_addend);
32ec8896 1670 res = FALSE;
7ace3541
RH
1671 }
1672 }
1673 else if (symtab_index)
252b5132 1674 {
af3fc3bc 1675 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1676 {
27a45f42
AS
1677 error (_(" bad symbol index: %08lx in reloc\n"),
1678 (unsigned long) symtab_index);
32ec8896
NC
1679 res = FALSE;
1680 }
af3fc3bc 1681 else
19936277 1682 {
2cf0635d 1683 Elf_Internal_Sym * psym;
bb4d2ac2
L
1684 const char * version_string;
1685 enum versioned_symbol_info sym_info;
1686 unsigned short vna_other;
19936277 1687
af3fc3bc 1688 psym = symtab + symtab_index;
103f02d3 1689
bb4d2ac2 1690 version_string
dda8d76d 1691 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1692 strtab, strtablen,
1693 symtab_index,
1694 psym,
1695 &sym_info,
1696 &vna_other);
1697
af3fc3bc 1698 printf (" ");
171191ba 1699
d8045f23
NC
1700 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1701 {
1702 const char * name;
1703 unsigned int len;
1704 unsigned int width = is_32bit_elf ? 8 : 14;
1705
1706 /* Relocations against GNU_IFUNC symbols do not use the value
1707 of the symbol as the address to relocate against. Instead
1708 they invoke the function named by the symbol and use its
1709 result as the address for relocation.
1710
1711 To indicate this to the user, do not display the value of
1712 the symbol in the "Symbols's Value" field. Instead show
1713 its name followed by () as a hint that the symbol is
1714 invoked. */
1715
1716 if (strtab == NULL
1717 || psym->st_name == 0
1718 || psym->st_name >= strtablen)
1719 name = "??";
1720 else
1721 name = strtab + psym->st_name;
1722
1723 len = print_symbol (width, name);
bb4d2ac2
L
1724 if (version_string)
1725 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1726 version_string);
d8045f23
NC
1727 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1728 }
1729 else
1730 {
1731 print_vma (psym->st_value, LONG_HEX);
171191ba 1732
d8045f23
NC
1733 printf (is_32bit_elf ? " " : " ");
1734 }
103f02d3 1735
af3fc3bc 1736 if (psym->st_name == 0)
f1ef08cb 1737 {
2cf0635d 1738 const char * sec_name = "<null>";
f1ef08cb
AM
1739 char name_buf[40];
1740
1741 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1742 {
dda8d76d 1743 if (psym->st_shndx < filedata->file_header.e_shnum)
b9e920ec
AM
1744 sec_name = SECTION_NAME_PRINT (filedata->section_headers
1745 + psym->st_shndx);
f1ef08cb
AM
1746 else if (psym->st_shndx == SHN_ABS)
1747 sec_name = "ABS";
1748 else if (psym->st_shndx == SHN_COMMON)
1749 sec_name = "COMMON";
dda8d76d 1750 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1751 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1752 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1753 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1754 sec_name = "SCOMMON";
dda8d76d 1755 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1756 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1757 sec_name = "SUNDEF";
dda8d76d
NC
1758 else if ((filedata->file_header.e_machine == EM_X86_64
1759 || filedata->file_header.e_machine == EM_L1OM
1760 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1761 && psym->st_shndx == SHN_X86_64_LCOMMON)
1762 sec_name = "LARGE_COMMON";
dda8d76d
NC
1763 else if (filedata->file_header.e_machine == EM_IA_64
1764 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1765 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1766 sec_name = "ANSI_COM";
dda8d76d 1767 else if (is_ia64_vms (filedata)
148b93f2
NC
1768 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1769 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1770 else
1771 {
1772 sprintf (name_buf, "<section 0x%x>",
1773 (unsigned int) psym->st_shndx);
1774 sec_name = name_buf;
1775 }
1776 }
1777 print_symbol (22, sec_name);
1778 }
af3fc3bc 1779 else if (strtab == NULL)
d79b3d50 1780 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1781 else if (psym->st_name >= strtablen)
32ec8896 1782 {
27a45f42
AS
1783 error (_("<corrupt string table index: %3ld>\n"),
1784 psym->st_name);
32ec8896
NC
1785 res = FALSE;
1786 }
af3fc3bc 1787 else
bb4d2ac2
L
1788 {
1789 print_symbol (22, strtab + psym->st_name);
1790 if (version_string)
1791 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1792 version_string);
1793 }
103f02d3 1794
af3fc3bc 1795 if (is_rela)
171191ba 1796 {
7360e63f 1797 bfd_vma off = rels[i].r_addend;
171191ba 1798
7360e63f 1799 if ((bfd_signed_vma) off < 0)
598aaa76 1800 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1801 else
598aaa76 1802 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1803 }
19936277 1804 }
252b5132 1805 }
1b228002 1806 else if (is_rela)
f7a99963 1807 {
7360e63f 1808 bfd_vma off = rels[i].r_addend;
e04d7088
L
1809
1810 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1811 if ((bfd_signed_vma) off < 0)
e04d7088
L
1812 printf ("-%" BFD_VMA_FMT "x", - off);
1813 else
1814 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1815 }
252b5132 1816
dda8d76d 1817 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1818 && rtype != NULL
1819 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1820 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1821
252b5132 1822 putchar ('\n');
2c71103e 1823
aca88567 1824#ifdef BFD64
dda8d76d 1825 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1826 {
91d6fa6a
NC
1827 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1828 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1829 const char * rtype2 = elf_mips_reloc_type (type2);
1830 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1831
2c71103e
NC
1832 printf (" Type2: ");
1833
1834 if (rtype2 == NULL)
39dbeff8
AM
1835 printf (_("unrecognized: %-7lx"),
1836 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1837 else
1838 printf ("%-17.17s", rtype2);
1839
18bd398b 1840 printf ("\n Type3: ");
2c71103e
NC
1841
1842 if (rtype3 == NULL)
39dbeff8
AM
1843 printf (_("unrecognized: %-7lx"),
1844 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1845 else
1846 printf ("%-17.17s", rtype3);
1847
53c7db4b 1848 putchar ('\n');
2c71103e 1849 }
aca88567 1850#endif /* BFD64 */
252b5132
RH
1851 }
1852
c8286bd1 1853 free (rels);
32ec8896
NC
1854
1855 return res;
252b5132
RH
1856}
1857
37c18eed
SD
1858static const char *
1859get_aarch64_dynamic_type (unsigned long type)
1860{
1861 switch (type)
1862 {
1863 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 1864 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 1865 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
1866 default:
1867 return NULL;
1868 }
1869}
1870
252b5132 1871static const char *
d3ba0551 1872get_mips_dynamic_type (unsigned long type)
252b5132
RH
1873{
1874 switch (type)
1875 {
1876 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1877 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1878 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1879 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1880 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1881 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1882 case DT_MIPS_MSYM: return "MIPS_MSYM";
1883 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1884 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1885 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1886 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1887 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1888 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1889 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1890 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1891 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1892 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1893 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1894 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1895 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1896 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1897 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1898 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1899 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1900 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1901 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1902 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1903 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1904 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1905 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1906 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1907 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1908 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1909 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1910 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1911 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1912 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1913 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1914 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1915 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1916 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1917 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1918 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1919 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1920 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1921 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 1922 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
1923 default:
1924 return NULL;
1925 }
1926}
1927
9a097730 1928static const char *
d3ba0551 1929get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1930{
1931 switch (type)
1932 {
1933 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1934 default:
1935 return NULL;
1936 }
103f02d3
UD
1937}
1938
7490d522
AM
1939static const char *
1940get_ppc_dynamic_type (unsigned long type)
1941{
1942 switch (type)
1943 {
a7f2871e 1944 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1945 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1946 default:
1947 return NULL;
1948 }
1949}
1950
f1cb7e17 1951static const char *
d3ba0551 1952get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1953{
1954 switch (type)
1955 {
a7f2871e
AM
1956 case DT_PPC64_GLINK: return "PPC64_GLINK";
1957 case DT_PPC64_OPD: return "PPC64_OPD";
1958 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1959 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1960 default:
1961 return NULL;
1962 }
1963}
1964
103f02d3 1965static const char *
d3ba0551 1966get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1967{
1968 switch (type)
1969 {
1970 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1971 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1972 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1973 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1974 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1975 case DT_HP_PREINIT: return "HP_PREINIT";
1976 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1977 case DT_HP_NEEDED: return "HP_NEEDED";
1978 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1979 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1980 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1981 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1982 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1983 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1984 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1985 case DT_HP_FILTERED: return "HP_FILTERED";
1986 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1987 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1988 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1989 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1990 case DT_PLT: return "PLT";
1991 case DT_PLT_SIZE: return "PLT_SIZE";
1992 case DT_DLT: return "DLT";
1993 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1994 default:
1995 return NULL;
1996 }
1997}
9a097730 1998
ecc51f48 1999static const char *
d3ba0551 2000get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2001{
2002 switch (type)
2003 {
148b93f2
NC
2004 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2005 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2006 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2007 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2008 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2009 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2010 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2011 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2012 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2013 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2014 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2015 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2016 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2017 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2018 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2019 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2020 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2021 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2022 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2023 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2024 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2025 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2026 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2027 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2028 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2029 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2030 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2031 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2032 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2033 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2034 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2035 default:
2036 return NULL;
2037 }
2038}
2039
fd85a6a1
NC
2040static const char *
2041get_solaris_section_type (unsigned long type)
2042{
2043 switch (type)
2044 {
2045 case 0x6fffffee: return "SUNW_ancillary";
2046 case 0x6fffffef: return "SUNW_capchain";
2047 case 0x6ffffff0: return "SUNW_capinfo";
2048 case 0x6ffffff1: return "SUNW_symsort";
2049 case 0x6ffffff2: return "SUNW_tlssort";
2050 case 0x6ffffff3: return "SUNW_LDYNSYM";
2051 case 0x6ffffff4: return "SUNW_dof";
2052 case 0x6ffffff5: return "SUNW_cap";
2053 case 0x6ffffff6: return "SUNW_SIGNATURE";
2054 case 0x6ffffff7: return "SUNW_ANNOTATE";
2055 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2056 case 0x6ffffff9: return "SUNW_DEBUG";
2057 case 0x6ffffffa: return "SUNW_move";
2058 case 0x6ffffffb: return "SUNW_COMDAT";
2059 case 0x6ffffffc: return "SUNW_syminfo";
2060 case 0x6ffffffd: return "SUNW_verdef";
2061 case 0x6ffffffe: return "SUNW_verneed";
2062 case 0x6fffffff: return "SUNW_versym";
2063 case 0x70000000: return "SPARC_GOTDATA";
2064 default: return NULL;
2065 }
2066}
2067
fabcb361
RH
2068static const char *
2069get_alpha_dynamic_type (unsigned long type)
2070{
2071 switch (type)
2072 {
2073 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2074 default: return NULL;
fabcb361
RH
2075 }
2076}
2077
1c0d3aa6
NC
2078static const char *
2079get_score_dynamic_type (unsigned long type)
2080{
2081 switch (type)
2082 {
2083 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2084 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2085 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2086 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2087 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2088 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2089 default: return NULL;
1c0d3aa6
NC
2090 }
2091}
2092
40b36596
JM
2093static const char *
2094get_tic6x_dynamic_type (unsigned long type)
2095{
2096 switch (type)
2097 {
2098 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2099 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2100 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2101 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2102 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2103 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2104 default: return NULL;
40b36596
JM
2105 }
2106}
1c0d3aa6 2107
36591ba1
SL
2108static const char *
2109get_nios2_dynamic_type (unsigned long type)
2110{
2111 switch (type)
2112 {
2113 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2114 default: return NULL;
36591ba1
SL
2115 }
2116}
2117
fd85a6a1
NC
2118static const char *
2119get_solaris_dynamic_type (unsigned long type)
2120{
2121 switch (type)
2122 {
2123 case 0x6000000d: return "SUNW_AUXILIARY";
2124 case 0x6000000e: return "SUNW_RTLDINF";
2125 case 0x6000000f: return "SUNW_FILTER";
2126 case 0x60000010: return "SUNW_CAP";
2127 case 0x60000011: return "SUNW_SYMTAB";
2128 case 0x60000012: return "SUNW_SYMSZ";
2129 case 0x60000013: return "SUNW_SORTENT";
2130 case 0x60000014: return "SUNW_SYMSORT";
2131 case 0x60000015: return "SUNW_SYMSORTSZ";
2132 case 0x60000016: return "SUNW_TLSSORT";
2133 case 0x60000017: return "SUNW_TLSSORTSZ";
2134 case 0x60000018: return "SUNW_CAPINFO";
2135 case 0x60000019: return "SUNW_STRPAD";
2136 case 0x6000001a: return "SUNW_CAPCHAIN";
2137 case 0x6000001b: return "SUNW_LDMACH";
2138 case 0x6000001d: return "SUNW_CAPCHAINENT";
2139 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2140 case 0x60000021: return "SUNW_PARENT";
2141 case 0x60000023: return "SUNW_ASLR";
2142 case 0x60000025: return "SUNW_RELAX";
2143 case 0x60000029: return "SUNW_NXHEAP";
2144 case 0x6000002b: return "SUNW_NXSTACK";
2145
2146 case 0x70000001: return "SPARC_REGISTER";
2147 case 0x7ffffffd: return "AUXILIARY";
2148 case 0x7ffffffe: return "USED";
2149 case 0x7fffffff: return "FILTER";
2150
15f205b1 2151 default: return NULL;
fd85a6a1
NC
2152 }
2153}
2154
252b5132 2155static const char *
dda8d76d 2156get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2157{
e9e44622 2158 static char buff[64];
252b5132
RH
2159
2160 switch (type)
2161 {
2162 case DT_NULL: return "NULL";
2163 case DT_NEEDED: return "NEEDED";
2164 case DT_PLTRELSZ: return "PLTRELSZ";
2165 case DT_PLTGOT: return "PLTGOT";
2166 case DT_HASH: return "HASH";
2167 case DT_STRTAB: return "STRTAB";
2168 case DT_SYMTAB: return "SYMTAB";
2169 case DT_RELA: return "RELA";
2170 case DT_RELASZ: return "RELASZ";
2171 case DT_RELAENT: return "RELAENT";
2172 case DT_STRSZ: return "STRSZ";
2173 case DT_SYMENT: return "SYMENT";
2174 case DT_INIT: return "INIT";
2175 case DT_FINI: return "FINI";
2176 case DT_SONAME: return "SONAME";
2177 case DT_RPATH: return "RPATH";
2178 case DT_SYMBOLIC: return "SYMBOLIC";
2179 case DT_REL: return "REL";
2180 case DT_RELSZ: return "RELSZ";
2181 case DT_RELENT: return "RELENT";
2182 case DT_PLTREL: return "PLTREL";
2183 case DT_DEBUG: return "DEBUG";
2184 case DT_TEXTREL: return "TEXTREL";
2185 case DT_JMPREL: return "JMPREL";
2186 case DT_BIND_NOW: return "BIND_NOW";
2187 case DT_INIT_ARRAY: return "INIT_ARRAY";
2188 case DT_FINI_ARRAY: return "FINI_ARRAY";
2189 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2190 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2191 case DT_RUNPATH: return "RUNPATH";
2192 case DT_FLAGS: return "FLAGS";
2d0e6f43 2193
d1133906
NC
2194 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2195 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2196 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2197
05107a46 2198 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2199 case DT_PLTPADSZ: return "PLTPADSZ";
2200 case DT_MOVEENT: return "MOVEENT";
2201 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2202 case DT_FEATURE: return "FEATURE";
252b5132
RH
2203 case DT_POSFLAG_1: return "POSFLAG_1";
2204 case DT_SYMINSZ: return "SYMINSZ";
2205 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2206
252b5132 2207 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2208 case DT_CONFIG: return "CONFIG";
2209 case DT_DEPAUDIT: return "DEPAUDIT";
2210 case DT_AUDIT: return "AUDIT";
2211 case DT_PLTPAD: return "PLTPAD";
2212 case DT_MOVETAB: return "MOVETAB";
252b5132 2213 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2214
252b5132 2215 case DT_VERSYM: return "VERSYM";
103f02d3 2216
67a4f2b7
AO
2217 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2218 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2219 case DT_RELACOUNT: return "RELACOUNT";
2220 case DT_RELCOUNT: return "RELCOUNT";
2221 case DT_FLAGS_1: return "FLAGS_1";
2222 case DT_VERDEF: return "VERDEF";
2223 case DT_VERDEFNUM: return "VERDEFNUM";
2224 case DT_VERNEED: return "VERNEED";
2225 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2226
019148e4 2227 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2228 case DT_USED: return "USED";
2229 case DT_FILTER: return "FILTER";
103f02d3 2230
047b2264
JJ
2231 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2232 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2233 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2234 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2235 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2236 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2237 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2238
252b5132
RH
2239 default:
2240 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2241 {
2cf0635d 2242 const char * result;
103f02d3 2243
dda8d76d 2244 switch (filedata->file_header.e_machine)
252b5132 2245 {
37c18eed
SD
2246 case EM_AARCH64:
2247 result = get_aarch64_dynamic_type (type);
2248 break;
252b5132 2249 case EM_MIPS:
4fe85591 2250 case EM_MIPS_RS3_LE:
252b5132
RH
2251 result = get_mips_dynamic_type (type);
2252 break;
9a097730
RH
2253 case EM_SPARCV9:
2254 result = get_sparc64_dynamic_type (type);
2255 break;
7490d522
AM
2256 case EM_PPC:
2257 result = get_ppc_dynamic_type (type);
2258 break;
f1cb7e17
AM
2259 case EM_PPC64:
2260 result = get_ppc64_dynamic_type (type);
2261 break;
ecc51f48
NC
2262 case EM_IA_64:
2263 result = get_ia64_dynamic_type (type);
2264 break;
fabcb361
RH
2265 case EM_ALPHA:
2266 result = get_alpha_dynamic_type (type);
2267 break;
1c0d3aa6
NC
2268 case EM_SCORE:
2269 result = get_score_dynamic_type (type);
2270 break;
40b36596
JM
2271 case EM_TI_C6000:
2272 result = get_tic6x_dynamic_type (type);
2273 break;
36591ba1
SL
2274 case EM_ALTERA_NIOS2:
2275 result = get_nios2_dynamic_type (type);
2276 break;
252b5132 2277 default:
dda8d76d 2278 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2279 result = get_solaris_dynamic_type (type);
2280 else
2281 result = NULL;
252b5132
RH
2282 break;
2283 }
2284
2285 if (result != NULL)
2286 return result;
2287
e9e44622 2288 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2289 }
eec8f817 2290 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2291 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2292 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2293 {
2cf0635d 2294 const char * result;
103f02d3 2295
dda8d76d 2296 switch (filedata->file_header.e_machine)
103f02d3
UD
2297 {
2298 case EM_PARISC:
2299 result = get_parisc_dynamic_type (type);
2300 break;
148b93f2
NC
2301 case EM_IA_64:
2302 result = get_ia64_dynamic_type (type);
2303 break;
103f02d3 2304 default:
dda8d76d 2305 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2306 result = get_solaris_dynamic_type (type);
2307 else
2308 result = NULL;
103f02d3
UD
2309 break;
2310 }
2311
2312 if (result != NULL)
2313 return result;
2314
e9e44622
JJ
2315 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2316 type);
103f02d3 2317 }
252b5132 2318 else
e9e44622 2319 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2320
252b5132
RH
2321 return buff;
2322 }
2323}
2324
2325static char *
d3ba0551 2326get_file_type (unsigned e_type)
252b5132 2327{
89246a0e 2328 static char buff[64];
252b5132
RH
2329
2330 switch (e_type)
2331 {
32ec8896
NC
2332 case ET_NONE: return _("NONE (None)");
2333 case ET_REL: return _("REL (Relocatable file)");
2334 case ET_EXEC: return _("EXEC (Executable file)");
2335 case ET_DYN: return _("DYN (Shared object file)");
2336 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2337
2338 default:
2339 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2340 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2341 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2342 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2343 else
e9e44622 2344 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2345 return buff;
2346 }
2347}
2348
2349static char *
d3ba0551 2350get_machine_name (unsigned e_machine)
252b5132 2351{
b34976b6 2352 static char buff[64]; /* XXX */
252b5132
RH
2353
2354 switch (e_machine)
2355 {
55e22ca8
NC
2356 /* Please keep this switch table sorted by increasing EM_ value. */
2357 /* 0 */
c45021f2
NC
2358 case EM_NONE: return _("None");
2359 case EM_M32: return "WE32100";
2360 case EM_SPARC: return "Sparc";
2361 case EM_386: return "Intel 80386";
2362 case EM_68K: return "MC68000";
2363 case EM_88K: return "MC88000";
22abe556 2364 case EM_IAMCU: return "Intel MCU";
fb70ec17 2365 case EM_860: return "Intel 80860";
c45021f2
NC
2366 case EM_MIPS: return "MIPS R3000";
2367 case EM_S370: return "IBM System/370";
55e22ca8 2368 /* 10 */
7036c0e1 2369 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2370 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2371 case EM_PARISC: return "HPPA";
55e22ca8 2372 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2373 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2374 case EM_960: return "Intel 80960";
c45021f2 2375 case EM_PPC: return "PowerPC";
55e22ca8 2376 /* 20 */
285d1771 2377 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2378 case EM_S390_OLD:
2379 case EM_S390: return "IBM S/390";
2380 case EM_SPU: return "SPU";
2381 /* 30 */
2382 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2383 case EM_FR20: return "Fujitsu FR20";
2384 case EM_RH32: return "TRW RH32";
b34976b6 2385 case EM_MCORE: return "MCORE";
55e22ca8 2386 /* 40 */
7036c0e1
AJ
2387 case EM_ARM: return "ARM";
2388 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2389 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2390 case EM_SPARCV9: return "Sparc v9";
2391 case EM_TRICORE: return "Siemens Tricore";
584da044 2392 case EM_ARC: return "ARC";
c2dcd04e
NC
2393 case EM_H8_300: return "Renesas H8/300";
2394 case EM_H8_300H: return "Renesas H8/300H";
2395 case EM_H8S: return "Renesas H8S";
2396 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2397 /* 50 */
30800947 2398 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2399 case EM_MIPS_X: return "Stanford MIPS-X";
2400 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2401 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2402 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2403 case EM_PCP: return "Siemens PCP";
2404 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2405 case EM_NDR1: return "Denso NDR1 microprocesspr";
2406 case EM_STARCORE: return "Motorola Star*Core processor";
2407 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2408 /* 60 */
7036c0e1
AJ
2409 case EM_ST100: return "STMicroelectronics ST100 processor";
2410 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2411 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2412 case EM_PDSP: return "Sony DSP processor";
2413 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2414 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2415 case EM_FX66: return "Siemens FX66 microcontroller";
2416 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2417 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2418 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2419 /* 70 */
7036c0e1
AJ
2420 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2421 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2422 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2423 case EM_SVX: return "Silicon Graphics SVx";
2424 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2425 case EM_VAX: return "Digital VAX";
1b61cf92 2426 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2427 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2428 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2429 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2430 /* 80 */
b34976b6 2431 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2432 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2433 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2434 case EM_AVR_OLD:
2435 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2436 case EM_CYGNUS_FR30:
2437 case EM_FR30: return "Fujitsu FR30";
2438 case EM_CYGNUS_D10V:
2439 case EM_D10V: return "d10v";
2440 case EM_CYGNUS_D30V:
2441 case EM_D30V: return "d30v";
2442 case EM_CYGNUS_V850:
2443 case EM_V850: return "Renesas V850";
2444 case EM_CYGNUS_M32R:
2445 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2446 case EM_CYGNUS_MN10300:
2447 case EM_MN10300: return "mn10300";
2448 /* 90 */
2449 case EM_CYGNUS_MN10200:
2450 case EM_MN10200: return "mn10200";
2451 case EM_PJ: return "picoJava";
73589c9d 2452 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2453 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2454 case EM_XTENSA_OLD:
2455 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2456 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2457 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2458 case EM_NS32K: return "National Semiconductor 32000 series";
2459 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2460 case EM_SNP1K: return "Trebia SNP 1000 processor";
2461 /* 100 */
9abca702 2462 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2463 case EM_IP2K_OLD:
2464 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2465 case EM_MAX: return "MAX Processor";
2466 case EM_CR: return "National Semiconductor CompactRISC";
2467 case EM_F2MC16: return "Fujitsu F2MC16";
2468 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2469 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2470 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2471 case EM_SEP: return "Sharp embedded microprocessor";
2472 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2473 /* 110 */
11636f9e
JM
2474 case EM_UNICORE: return "Unicore";
2475 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2476 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2477 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2478 case EM_CRX: return "National Semiconductor CRX microprocessor";
2479 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2480 case EM_C166:
d70c5fc7 2481 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2482 case EM_M16C: return "Renesas M16C series microprocessors";
2483 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2484 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2485 /* 120 */
2486 case EM_M32C: return "Renesas M32c";
2487 /* 130 */
11636f9e
JM
2488 case EM_TSK3000: return "Altium TSK3000 core";
2489 case EM_RS08: return "Freescale RS08 embedded processor";
2490 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2491 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2492 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2493 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2494 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2495 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2496 /* 140 */
11636f9e
JM
2497 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2498 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2499 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2500 case EM_TI_PRU: return "TI PRU I/O processor";
2501 /* 160 */
11636f9e
JM
2502 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2503 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2504 case EM_R32C: return "Renesas R32C series microprocessors";
2505 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2506 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2507 case EM_8051: return "Intel 8051 and variants";
2508 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2509 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2510 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2511 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2512 /* 170 */
11636f9e
JM
2513 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2514 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2515 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2516 case EM_RX: return "Renesas RX";
a3c62988 2517 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2518 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2519 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2520 case EM_CR16:
2521 case EM_MICROBLAZE:
2522 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2523 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2524 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2525 /* 180 */
2526 case EM_L1OM: return "Intel L1OM";
2527 case EM_K1OM: return "Intel K1OM";
2528 case EM_INTEL182: return "Intel (reserved)";
2529 case EM_AARCH64: return "AArch64";
2530 case EM_ARM184: return "ARM (reserved)";
2531 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2532 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2533 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2534 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2535 /* 190 */
11636f9e 2536 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2537 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2538 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2539 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2540 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2541 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2542 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2543 case EM_RL78: return "Renesas RL78";
6d913794 2544 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2545 case EM_78K0R: return "Renesas 78K0R";
2546 /* 200 */
6d913794 2547 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2548 case EM_BA1: return "Beyond BA1 CPU architecture";
2549 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2550 case EM_XCORE: return "XMOS xCORE processor family";
2551 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
55e22ca8 2552 /* 210 */
6d913794
NC
2553 case EM_KM32: return "KM211 KM32 32-bit processor";
2554 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2555 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2556 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2557 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2558 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2559 case EM_COGE: return "Cognitive Smart Memory Processor";
2560 case EM_COOL: return "Bluechip Systems CoolEngine";
2561 case EM_NORC: return "Nanoradio Optimized RISC";
2562 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2563 /* 220 */
15f205b1 2564 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2565 case EM_VISIUM: return "CDS VISIUMcore processor";
2566 case EM_FT32: return "FTDI Chip FT32";
2567 case EM_MOXIE: return "Moxie";
2568 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2569 /* 230 (all reserved) */
2570 /* 240 */
55e22ca8
NC
2571 case EM_RISCV: return "RISC-V";
2572 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2573 case EM_CEVA: return "CEVA Processor Architecture Family";
2574 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2575 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2576 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2577 case EM_IMG1: return "Imagination Technologies";
2578 /* 250 */
fe944acf 2579 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2580 case EM_VE: return "NEC Vector Engine";
2581 case EM_CSKY: return "C-SKY";
2582 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2583 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2584 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2585 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2586 case EM_65816: return "WDC 65816/65C816";
2587 case EM_LOONGARCH: return "Loongson Loongarch";
2588 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2589
2590 /* Large numbers... */
2591 case EM_MT: return "Morpho Techologies MT processor";
2592 case EM_ALPHA: return "Alpha";
2593 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2594 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2595 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2596 case EM_IQ2000: return "Vitesse IQ2000";
2597 case EM_M32C_OLD:
2598 case EM_NIOS32: return "Altera Nios";
2599 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2600 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2601 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2602 case EM_S12Z: return "Freescale S12Z";
55e22ca8 2603
252b5132 2604 default:
35d9dd2f 2605 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2606 return buff;
2607 }
2608}
2609
a9522a21
AB
2610static void
2611decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2612{
2613 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 2614 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
2615 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2616 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2617 architectures.
2618
2619 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2620 but also sets a specific architecture type in the e_flags field.
2621
2622 However, when decoding the flags we don't worry if we see an
2623 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2624 ARCEM architecture type. */
2625
2626 switch (e_flags & EF_ARC_MACH_MSK)
2627 {
2628 /* We only expect these to occur for EM_ARC_COMPACT2. */
2629 case EF_ARC_CPU_ARCV2EM:
2630 strcat (buf, ", ARC EM");
2631 break;
2632 case EF_ARC_CPU_ARCV2HS:
2633 strcat (buf, ", ARC HS");
2634 break;
2635
2636 /* We only expect these to occur for EM_ARC_COMPACT. */
2637 case E_ARC_MACH_ARC600:
2638 strcat (buf, ", ARC600");
2639 break;
2640 case E_ARC_MACH_ARC601:
2641 strcat (buf, ", ARC601");
2642 break;
2643 case E_ARC_MACH_ARC700:
2644 strcat (buf, ", ARC700");
2645 break;
2646
2647 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2648 new ELF with new architecture being read by an old version of
2649 readelf, or (c) An ELF built with non-GNU compiler that does not
2650 set the architecture in the e_flags. */
2651 default:
2652 if (e_machine == EM_ARC_COMPACT)
2653 strcat (buf, ", Unknown ARCompact");
2654 else
2655 strcat (buf, ", Unknown ARC");
2656 break;
2657 }
2658
2659 switch (e_flags & EF_ARC_OSABI_MSK)
2660 {
2661 case E_ARC_OSABI_ORIG:
2662 strcat (buf, ", (ABI:legacy)");
2663 break;
2664 case E_ARC_OSABI_V2:
2665 strcat (buf, ", (ABI:v2)");
2666 break;
2667 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2668 case E_ARC_OSABI_V3:
2669 strcat (buf, ", v3 no-legacy-syscalls ABI");
2670 break;
53a346d8
CZ
2671 case E_ARC_OSABI_V4:
2672 strcat (buf, ", v4 ABI");
2673 break;
a9522a21
AB
2674 default:
2675 strcat (buf, ", unrecognised ARC OSABI flag");
2676 break;
2677 }
2678}
2679
f3485b74 2680static void
d3ba0551 2681decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2682{
2683 unsigned eabi;
32ec8896 2684 bfd_boolean unknown = FALSE;
f3485b74
NC
2685
2686 eabi = EF_ARM_EABI_VERSION (e_flags);
2687 e_flags &= ~ EF_ARM_EABIMASK;
2688
2689 /* Handle "generic" ARM flags. */
2690 if (e_flags & EF_ARM_RELEXEC)
2691 {
2692 strcat (buf, ", relocatable executable");
2693 e_flags &= ~ EF_ARM_RELEXEC;
2694 }
76da6bbe 2695
18a20338
CL
2696 if (e_flags & EF_ARM_PIC)
2697 {
2698 strcat (buf, ", position independent");
2699 e_flags &= ~ EF_ARM_PIC;
2700 }
2701
f3485b74
NC
2702 /* Now handle EABI specific flags. */
2703 switch (eabi)
2704 {
2705 default:
2c71103e 2706 strcat (buf, ", <unrecognized EABI>");
f3485b74 2707 if (e_flags)
32ec8896 2708 unknown = TRUE;
f3485b74
NC
2709 break;
2710
2711 case EF_ARM_EABI_VER1:
a5bcd848 2712 strcat (buf, ", Version1 EABI");
f3485b74
NC
2713 while (e_flags)
2714 {
2715 unsigned flag;
76da6bbe 2716
f3485b74
NC
2717 /* Process flags one bit at a time. */
2718 flag = e_flags & - e_flags;
2719 e_flags &= ~ flag;
76da6bbe 2720
f3485b74
NC
2721 switch (flag)
2722 {
a5bcd848 2723 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2724 strcat (buf, ", sorted symbol tables");
2725 break;
76da6bbe 2726
f3485b74 2727 default:
32ec8896 2728 unknown = TRUE;
f3485b74
NC
2729 break;
2730 }
2731 }
2732 break;
76da6bbe 2733
a5bcd848
PB
2734 case EF_ARM_EABI_VER2:
2735 strcat (buf, ", Version2 EABI");
2736 while (e_flags)
2737 {
2738 unsigned flag;
2739
2740 /* Process flags one bit at a time. */
2741 flag = e_flags & - e_flags;
2742 e_flags &= ~ flag;
2743
2744 switch (flag)
2745 {
2746 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2747 strcat (buf, ", sorted symbol tables");
2748 break;
2749
2750 case EF_ARM_DYNSYMSUSESEGIDX:
2751 strcat (buf, ", dynamic symbols use segment index");
2752 break;
2753
2754 case EF_ARM_MAPSYMSFIRST:
2755 strcat (buf, ", mapping symbols precede others");
2756 break;
2757
2758 default:
32ec8896 2759 unknown = TRUE;
a5bcd848
PB
2760 break;
2761 }
2762 }
2763 break;
2764
d507cf36
PB
2765 case EF_ARM_EABI_VER3:
2766 strcat (buf, ", Version3 EABI");
8cb51566
PB
2767 break;
2768
2769 case EF_ARM_EABI_VER4:
2770 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2771 while (e_flags)
2772 {
2773 unsigned flag;
2774
2775 /* Process flags one bit at a time. */
2776 flag = e_flags & - e_flags;
2777 e_flags &= ~ flag;
2778
2779 switch (flag)
2780 {
2781 case EF_ARM_BE8:
2782 strcat (buf, ", BE8");
2783 break;
2784
2785 case EF_ARM_LE8:
2786 strcat (buf, ", LE8");
2787 break;
2788
2789 default:
32ec8896 2790 unknown = TRUE;
3bfcb652
NC
2791 break;
2792 }
3bfcb652
NC
2793 }
2794 break;
3a4a14e9
PB
2795
2796 case EF_ARM_EABI_VER5:
2797 strcat (buf, ", Version5 EABI");
d507cf36
PB
2798 while (e_flags)
2799 {
2800 unsigned flag;
2801
2802 /* Process flags one bit at a time. */
2803 flag = e_flags & - e_flags;
2804 e_flags &= ~ flag;
2805
2806 switch (flag)
2807 {
2808 case EF_ARM_BE8:
2809 strcat (buf, ", BE8");
2810 break;
2811
2812 case EF_ARM_LE8:
2813 strcat (buf, ", LE8");
2814 break;
2815
3bfcb652
NC
2816 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2817 strcat (buf, ", soft-float ABI");
2818 break;
2819
2820 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2821 strcat (buf, ", hard-float ABI");
2822 break;
2823
d507cf36 2824 default:
32ec8896 2825 unknown = TRUE;
d507cf36
PB
2826 break;
2827 }
2828 }
2829 break;
2830
f3485b74 2831 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2832 strcat (buf, ", GNU EABI");
f3485b74
NC
2833 while (e_flags)
2834 {
2835 unsigned flag;
76da6bbe 2836
f3485b74
NC
2837 /* Process flags one bit at a time. */
2838 flag = e_flags & - e_flags;
2839 e_flags &= ~ flag;
76da6bbe 2840
f3485b74
NC
2841 switch (flag)
2842 {
a5bcd848 2843 case EF_ARM_INTERWORK:
f3485b74
NC
2844 strcat (buf, ", interworking enabled");
2845 break;
76da6bbe 2846
a5bcd848 2847 case EF_ARM_APCS_26:
f3485b74
NC
2848 strcat (buf, ", uses APCS/26");
2849 break;
76da6bbe 2850
a5bcd848 2851 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2852 strcat (buf, ", uses APCS/float");
2853 break;
76da6bbe 2854
a5bcd848 2855 case EF_ARM_PIC:
f3485b74
NC
2856 strcat (buf, ", position independent");
2857 break;
76da6bbe 2858
a5bcd848 2859 case EF_ARM_ALIGN8:
f3485b74
NC
2860 strcat (buf, ", 8 bit structure alignment");
2861 break;
76da6bbe 2862
a5bcd848 2863 case EF_ARM_NEW_ABI:
f3485b74
NC
2864 strcat (buf, ", uses new ABI");
2865 break;
76da6bbe 2866
a5bcd848 2867 case EF_ARM_OLD_ABI:
f3485b74
NC
2868 strcat (buf, ", uses old ABI");
2869 break;
76da6bbe 2870
a5bcd848 2871 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2872 strcat (buf, ", software FP");
2873 break;
76da6bbe 2874
90e01f86
ILT
2875 case EF_ARM_VFP_FLOAT:
2876 strcat (buf, ", VFP");
2877 break;
2878
fde78edd
NC
2879 case EF_ARM_MAVERICK_FLOAT:
2880 strcat (buf, ", Maverick FP");
2881 break;
2882
f3485b74 2883 default:
32ec8896 2884 unknown = TRUE;
f3485b74
NC
2885 break;
2886 }
2887 }
2888 }
f3485b74
NC
2889
2890 if (unknown)
2b692964 2891 strcat (buf,_(", <unknown>"));
f3485b74
NC
2892}
2893
343433df
AB
2894static void
2895decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2896{
2897 --size; /* Leave space for null terminator. */
2898
2899 switch (e_flags & EF_AVR_MACH)
2900 {
2901 case E_AVR_MACH_AVR1:
2902 strncat (buf, ", avr:1", size);
2903 break;
2904 case E_AVR_MACH_AVR2:
2905 strncat (buf, ", avr:2", size);
2906 break;
2907 case E_AVR_MACH_AVR25:
2908 strncat (buf, ", avr:25", size);
2909 break;
2910 case E_AVR_MACH_AVR3:
2911 strncat (buf, ", avr:3", size);
2912 break;
2913 case E_AVR_MACH_AVR31:
2914 strncat (buf, ", avr:31", size);
2915 break;
2916 case E_AVR_MACH_AVR35:
2917 strncat (buf, ", avr:35", size);
2918 break;
2919 case E_AVR_MACH_AVR4:
2920 strncat (buf, ", avr:4", size);
2921 break;
2922 case E_AVR_MACH_AVR5:
2923 strncat (buf, ", avr:5", size);
2924 break;
2925 case E_AVR_MACH_AVR51:
2926 strncat (buf, ", avr:51", size);
2927 break;
2928 case E_AVR_MACH_AVR6:
2929 strncat (buf, ", avr:6", size);
2930 break;
2931 case E_AVR_MACH_AVRTINY:
2932 strncat (buf, ", avr:100", size);
2933 break;
2934 case E_AVR_MACH_XMEGA1:
2935 strncat (buf, ", avr:101", size);
2936 break;
2937 case E_AVR_MACH_XMEGA2:
2938 strncat (buf, ", avr:102", size);
2939 break;
2940 case E_AVR_MACH_XMEGA3:
2941 strncat (buf, ", avr:103", size);
2942 break;
2943 case E_AVR_MACH_XMEGA4:
2944 strncat (buf, ", avr:104", size);
2945 break;
2946 case E_AVR_MACH_XMEGA5:
2947 strncat (buf, ", avr:105", size);
2948 break;
2949 case E_AVR_MACH_XMEGA6:
2950 strncat (buf, ", avr:106", size);
2951 break;
2952 case E_AVR_MACH_XMEGA7:
2953 strncat (buf, ", avr:107", size);
2954 break;
2955 default:
2956 strncat (buf, ", avr:<unknown>", size);
2957 break;
2958 }
2959
2960 size -= strlen (buf);
2961 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2962 strncat (buf, ", link-relax", size);
2963}
2964
35c08157
KLC
2965static void
2966decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2967{
2968 unsigned abi;
2969 unsigned arch;
2970 unsigned config;
2971 unsigned version;
32ec8896
NC
2972 bfd_boolean has_fpu = FALSE;
2973 unsigned int r = 0;
35c08157
KLC
2974
2975 static const char *ABI_STRINGS[] =
2976 {
2977 "ABI v0", /* use r5 as return register; only used in N1213HC */
2978 "ABI v1", /* use r0 as return register */
2979 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2980 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2981 "AABI",
2982 "ABI2 FP+"
35c08157
KLC
2983 };
2984 static const char *VER_STRINGS[] =
2985 {
2986 "Andes ELF V1.3 or older",
2987 "Andes ELF V1.3.1",
2988 "Andes ELF V1.4"
2989 };
2990 static const char *ARCH_STRINGS[] =
2991 {
2992 "",
2993 "Andes Star v1.0",
2994 "Andes Star v2.0",
2995 "Andes Star v3.0",
2996 "Andes Star v3.0m"
2997 };
2998
2999 abi = EF_NDS_ABI & e_flags;
3000 arch = EF_NDS_ARCH & e_flags;
3001 config = EF_NDS_INST & e_flags;
3002 version = EF_NDS32_ELF_VERSION & e_flags;
3003
3004 memset (buf, 0, size);
3005
3006 switch (abi)
3007 {
3008 case E_NDS_ABI_V0:
3009 case E_NDS_ABI_V1:
3010 case E_NDS_ABI_V2:
3011 case E_NDS_ABI_V2FP:
3012 case E_NDS_ABI_AABI:
40c7a7cb 3013 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3014 /* In case there are holes in the array. */
3015 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3016 break;
3017
3018 default:
3019 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3020 break;
3021 }
3022
3023 switch (version)
3024 {
3025 case E_NDS32_ELF_VER_1_2:
3026 case E_NDS32_ELF_VER_1_3:
3027 case E_NDS32_ELF_VER_1_4:
3028 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3029 break;
3030
3031 default:
3032 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3033 break;
3034 }
3035
3036 if (E_NDS_ABI_V0 == abi)
3037 {
3038 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3039 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3040 if (arch == E_NDS_ARCH_STAR_V1_0)
3041 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3042 return;
3043 }
3044
3045 switch (arch)
3046 {
3047 case E_NDS_ARCH_STAR_V1_0:
3048 case E_NDS_ARCH_STAR_V2_0:
3049 case E_NDS_ARCH_STAR_V3_0:
3050 case E_NDS_ARCH_STAR_V3_M:
3051 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3052 break;
3053
3054 default:
3055 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3056 /* ARCH version determines how the e_flags are interpreted.
3057 If it is unknown, we cannot proceed. */
3058 return;
3059 }
3060
3061 /* Newer ABI; Now handle architecture specific flags. */
3062 if (arch == E_NDS_ARCH_STAR_V1_0)
3063 {
3064 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3065 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3066
3067 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3068 r += snprintf (buf + r, size -r, ", MAC");
3069
3070 if (config & E_NDS32_HAS_DIV_INST)
3071 r += snprintf (buf + r, size -r, ", DIV");
3072
3073 if (config & E_NDS32_HAS_16BIT_INST)
3074 r += snprintf (buf + r, size -r, ", 16b");
3075 }
3076 else
3077 {
3078 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3079 {
3080 if (version <= E_NDS32_ELF_VER_1_3)
3081 r += snprintf (buf + r, size -r, ", [B8]");
3082 else
3083 r += snprintf (buf + r, size -r, ", EX9");
3084 }
3085
3086 if (config & E_NDS32_HAS_MAC_DX_INST)
3087 r += snprintf (buf + r, size -r, ", MAC_DX");
3088
3089 if (config & E_NDS32_HAS_DIV_DX_INST)
3090 r += snprintf (buf + r, size -r, ", DIV_DX");
3091
3092 if (config & E_NDS32_HAS_16BIT_INST)
3093 {
3094 if (version <= E_NDS32_ELF_VER_1_3)
3095 r += snprintf (buf + r, size -r, ", 16b");
3096 else
3097 r += snprintf (buf + r, size -r, ", IFC");
3098 }
3099 }
3100
3101 if (config & E_NDS32_HAS_EXT_INST)
3102 r += snprintf (buf + r, size -r, ", PERF1");
3103
3104 if (config & E_NDS32_HAS_EXT2_INST)
3105 r += snprintf (buf + r, size -r, ", PERF2");
3106
3107 if (config & E_NDS32_HAS_FPU_INST)
3108 {
32ec8896 3109 has_fpu = TRUE;
35c08157
KLC
3110 r += snprintf (buf + r, size -r, ", FPU_SP");
3111 }
3112
3113 if (config & E_NDS32_HAS_FPU_DP_INST)
3114 {
32ec8896 3115 has_fpu = TRUE;
35c08157
KLC
3116 r += snprintf (buf + r, size -r, ", FPU_DP");
3117 }
3118
3119 if (config & E_NDS32_HAS_FPU_MAC_INST)
3120 {
32ec8896 3121 has_fpu = TRUE;
35c08157
KLC
3122 r += snprintf (buf + r, size -r, ", FPU_MAC");
3123 }
3124
3125 if (has_fpu)
3126 {
3127 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3128 {
3129 case E_NDS32_FPU_REG_8SP_4DP:
3130 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3131 break;
3132 case E_NDS32_FPU_REG_16SP_8DP:
3133 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3134 break;
3135 case E_NDS32_FPU_REG_32SP_16DP:
3136 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3137 break;
3138 case E_NDS32_FPU_REG_32SP_32DP:
3139 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3140 break;
3141 }
3142 }
3143
3144 if (config & E_NDS32_HAS_AUDIO_INST)
3145 r += snprintf (buf + r, size -r, ", AUDIO");
3146
3147 if (config & E_NDS32_HAS_STRING_INST)
3148 r += snprintf (buf + r, size -r, ", STR");
3149
3150 if (config & E_NDS32_HAS_REDUCED_REGS)
3151 r += snprintf (buf + r, size -r, ", 16REG");
3152
3153 if (config & E_NDS32_HAS_VIDEO_INST)
3154 {
3155 if (version <= E_NDS32_ELF_VER_1_3)
3156 r += snprintf (buf + r, size -r, ", VIDEO");
3157 else
3158 r += snprintf (buf + r, size -r, ", SATURATION");
3159 }
3160
3161 if (config & E_NDS32_HAS_ENCRIPT_INST)
3162 r += snprintf (buf + r, size -r, ", ENCRP");
3163
3164 if (config & E_NDS32_HAS_L2C_INST)
3165 r += snprintf (buf + r, size -r, ", L2C");
3166}
3167
252b5132 3168static char *
dda8d76d 3169get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3170{
b34976b6 3171 static char buf[1024];
252b5132
RH
3172
3173 buf[0] = '\0';
76da6bbe 3174
252b5132
RH
3175 if (e_flags)
3176 {
3177 switch (e_machine)
3178 {
3179 default:
3180 break;
3181
886a2506 3182 case EM_ARC_COMPACT2:
886a2506 3183 case EM_ARC_COMPACT:
a9522a21
AB
3184 decode_ARC_machine_flags (e_flags, e_machine, buf);
3185 break;
886a2506 3186
f3485b74
NC
3187 case EM_ARM:
3188 decode_ARM_machine_flags (e_flags, buf);
3189 break;
76da6bbe 3190
343433df
AB
3191 case EM_AVR:
3192 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3193 break;
3194
781303ce
MF
3195 case EM_BLACKFIN:
3196 if (e_flags & EF_BFIN_PIC)
3197 strcat (buf, ", PIC");
3198
3199 if (e_flags & EF_BFIN_FDPIC)
3200 strcat (buf, ", FDPIC");
3201
3202 if (e_flags & EF_BFIN_CODE_IN_L1)
3203 strcat (buf, ", code in L1");
3204
3205 if (e_flags & EF_BFIN_DATA_IN_L1)
3206 strcat (buf, ", data in L1");
3207
3208 break;
3209
ec2dfb42
AO
3210 case EM_CYGNUS_FRV:
3211 switch (e_flags & EF_FRV_CPU_MASK)
3212 {
3213 case EF_FRV_CPU_GENERIC:
3214 break;
3215
3216 default:
3217 strcat (buf, ", fr???");
3218 break;
57346661 3219
ec2dfb42
AO
3220 case EF_FRV_CPU_FR300:
3221 strcat (buf, ", fr300");
3222 break;
3223
3224 case EF_FRV_CPU_FR400:
3225 strcat (buf, ", fr400");
3226 break;
3227 case EF_FRV_CPU_FR405:
3228 strcat (buf, ", fr405");
3229 break;
3230
3231 case EF_FRV_CPU_FR450:
3232 strcat (buf, ", fr450");
3233 break;
3234
3235 case EF_FRV_CPU_FR500:
3236 strcat (buf, ", fr500");
3237 break;
3238 case EF_FRV_CPU_FR550:
3239 strcat (buf, ", fr550");
3240 break;
3241
3242 case EF_FRV_CPU_SIMPLE:
3243 strcat (buf, ", simple");
3244 break;
3245 case EF_FRV_CPU_TOMCAT:
3246 strcat (buf, ", tomcat");
3247 break;
3248 }
1c877e87 3249 break;
ec2dfb42 3250
53c7db4b 3251 case EM_68K:
425c6cb0 3252 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3253 strcat (buf, ", m68000");
425c6cb0 3254 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3255 strcat (buf, ", cpu32");
3256 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3257 strcat (buf, ", fido_a");
425c6cb0 3258 else
266abb8f 3259 {
2cf0635d
NC
3260 char const * isa = _("unknown");
3261 char const * mac = _("unknown mac");
3262 char const * additional = NULL;
0112cd26 3263
c694fd50 3264 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3265 {
c694fd50 3266 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3267 isa = "A";
3268 additional = ", nodiv";
3269 break;
c694fd50 3270 case EF_M68K_CF_ISA_A:
266abb8f
NS
3271 isa = "A";
3272 break;
c694fd50 3273 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3274 isa = "A+";
3275 break;
c694fd50 3276 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3277 isa = "B";
3278 additional = ", nousp";
3279 break;
c694fd50 3280 case EF_M68K_CF_ISA_B:
266abb8f
NS
3281 isa = "B";
3282 break;
f608cd77
NS
3283 case EF_M68K_CF_ISA_C:
3284 isa = "C";
3285 break;
3286 case EF_M68K_CF_ISA_C_NODIV:
3287 isa = "C";
3288 additional = ", nodiv";
3289 break;
266abb8f
NS
3290 }
3291 strcat (buf, ", cf, isa ");
3292 strcat (buf, isa);
0b2e31dc
NS
3293 if (additional)
3294 strcat (buf, additional);
c694fd50 3295 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3296 strcat (buf, ", float");
c694fd50 3297 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3298 {
3299 case 0:
3300 mac = NULL;
3301 break;
c694fd50 3302 case EF_M68K_CF_MAC:
266abb8f
NS
3303 mac = "mac";
3304 break;
c694fd50 3305 case EF_M68K_CF_EMAC:
266abb8f
NS
3306 mac = "emac";
3307 break;
f608cd77
NS
3308 case EF_M68K_CF_EMAC_B:
3309 mac = "emac_b";
3310 break;
266abb8f
NS
3311 }
3312 if (mac)
3313 {
3314 strcat (buf, ", ");
3315 strcat (buf, mac);
3316 }
266abb8f 3317 }
53c7db4b 3318 break;
33c63f9d 3319
153a2776
NC
3320 case EM_CYGNUS_MEP:
3321 switch (e_flags & EF_MEP_CPU_MASK)
3322 {
3323 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3324 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3325 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3326 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3327 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3328 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3329 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3330 }
3331
3332 switch (e_flags & EF_MEP_COP_MASK)
3333 {
3334 case EF_MEP_COP_NONE: break;
3335 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3336 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3337 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3338 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3339 default: strcat (buf, _("<unknown MeP copro type>")); break;
3340 }
3341
3342 if (e_flags & EF_MEP_LIBRARY)
3343 strcat (buf, ", Built for Library");
3344
3345 if (e_flags & EF_MEP_INDEX_MASK)
3346 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3347 e_flags & EF_MEP_INDEX_MASK);
3348
3349 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3350 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3351 e_flags & ~ EF_MEP_ALL_FLAGS);
3352 break;
3353
252b5132
RH
3354 case EM_PPC:
3355 if (e_flags & EF_PPC_EMB)
3356 strcat (buf, ", emb");
3357
3358 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3359 strcat (buf, _(", relocatable"));
252b5132
RH
3360
3361 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3362 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3363 break;
3364
ee67d69a
AM
3365 case EM_PPC64:
3366 if (e_flags & EF_PPC64_ABI)
3367 {
3368 char abi[] = ", abiv0";
3369
3370 abi[6] += e_flags & EF_PPC64_ABI;
3371 strcat (buf, abi);
3372 }
3373 break;
3374
708e2187
NC
3375 case EM_V800:
3376 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3377 strcat (buf, ", RH850 ABI");
0b4362b0 3378
708e2187
NC
3379 if (e_flags & EF_V800_850E3)
3380 strcat (buf, ", V3 architecture");
3381
3382 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3383 strcat (buf, ", FPU not used");
3384
3385 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3386 strcat (buf, ", regmode: COMMON");
3387
3388 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3389 strcat (buf, ", r4 not used");
3390
3391 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3392 strcat (buf, ", r30 not used");
3393
3394 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3395 strcat (buf, ", r5 not used");
3396
3397 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3398 strcat (buf, ", r2 not used");
3399
3400 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3401 {
3402 switch (e_flags & - e_flags)
3403 {
3404 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3405 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3406 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3407 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3408 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3409 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3410 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3411 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3412 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3413 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3414 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3415 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3416 default: break;
3417 }
3418 }
3419 break;
3420
2b0337b0 3421 case EM_V850:
252b5132
RH
3422 case EM_CYGNUS_V850:
3423 switch (e_flags & EF_V850_ARCH)
3424 {
78c8d46c
NC
3425 case E_V850E3V5_ARCH:
3426 strcat (buf, ", v850e3v5");
3427 break;
1cd986c5
NC
3428 case E_V850E2V3_ARCH:
3429 strcat (buf, ", v850e2v3");
3430 break;
3431 case E_V850E2_ARCH:
3432 strcat (buf, ", v850e2");
3433 break;
3434 case E_V850E1_ARCH:
3435 strcat (buf, ", v850e1");
8ad30312 3436 break;
252b5132
RH
3437 case E_V850E_ARCH:
3438 strcat (buf, ", v850e");
3439 break;
252b5132
RH
3440 case E_V850_ARCH:
3441 strcat (buf, ", v850");
3442 break;
3443 default:
2b692964 3444 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3445 break;
3446 }
3447 break;
3448
2b0337b0 3449 case EM_M32R:
252b5132
RH
3450 case EM_CYGNUS_M32R:
3451 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3452 strcat (buf, ", m32r");
252b5132
RH
3453 break;
3454
3455 case EM_MIPS:
4fe85591 3456 case EM_MIPS_RS3_LE:
252b5132
RH
3457 if (e_flags & EF_MIPS_NOREORDER)
3458 strcat (buf, ", noreorder");
3459
3460 if (e_flags & EF_MIPS_PIC)
3461 strcat (buf, ", pic");
3462
3463 if (e_flags & EF_MIPS_CPIC)
3464 strcat (buf, ", cpic");
3465
d1bdd336
TS
3466 if (e_flags & EF_MIPS_UCODE)
3467 strcat (buf, ", ugen_reserved");
3468
252b5132
RH
3469 if (e_flags & EF_MIPS_ABI2)
3470 strcat (buf, ", abi2");
3471
43521d43
TS
3472 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3473 strcat (buf, ", odk first");
3474
a5d22d2a
TS
3475 if (e_flags & EF_MIPS_32BITMODE)
3476 strcat (buf, ", 32bitmode");
3477
ba92f887
MR
3478 if (e_flags & EF_MIPS_NAN2008)
3479 strcat (buf, ", nan2008");
3480
fef1b0b3
SE
3481 if (e_flags & EF_MIPS_FP64)
3482 strcat (buf, ", fp64");
3483
156c2f8b
NC
3484 switch ((e_flags & EF_MIPS_MACH))
3485 {
3486 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3487 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3488 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3489 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3490 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3491 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3492 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3493 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3494 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3495 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3496 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3497 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3498 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3499 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3500 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3501 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3502 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3503 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3504 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3505 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3506 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3507 case 0:
3508 /* We simply ignore the field in this case to avoid confusion:
3509 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3510 extension. */
3511 break;
2b692964 3512 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3513 }
43521d43
TS
3514
3515 switch ((e_flags & EF_MIPS_ABI))
3516 {
3517 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3518 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3519 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3520 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3521 case 0:
3522 /* We simply ignore the field in this case to avoid confusion:
3523 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3524 This means it is likely to be an o32 file, but not for
3525 sure. */
3526 break;
2b692964 3527 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3528 }
3529
3530 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3531 strcat (buf, ", mdmx");
3532
3533 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3534 strcat (buf, ", mips16");
3535
df58fc94
RS
3536 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3537 strcat (buf, ", micromips");
3538
43521d43
TS
3539 switch ((e_flags & EF_MIPS_ARCH))
3540 {
3541 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3542 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3543 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3544 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3545 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3546 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3547 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3548 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3549 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3550 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3551 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3552 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3553 }
252b5132 3554 break;
351b4b40 3555
35c08157
KLC
3556 case EM_NDS32:
3557 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3558 break;
3559
fe944acf
FT
3560 case EM_NFP:
3561 switch (EF_NFP_MACH (e_flags))
3562 {
3563 case E_NFP_MACH_3200:
3564 strcat (buf, ", NFP-32xx");
3565 break;
3566 case E_NFP_MACH_6000:
3567 strcat (buf, ", NFP-6xxx");
3568 break;
3569 }
3570 break;
3571
e23eba97
NC
3572 case EM_RISCV:
3573 if (e_flags & EF_RISCV_RVC)
3574 strcat (buf, ", RVC");
2922d21d 3575
7f999549
JW
3576 if (e_flags & EF_RISCV_RVE)
3577 strcat (buf, ", RVE");
3578
2922d21d
AW
3579 switch (e_flags & EF_RISCV_FLOAT_ABI)
3580 {
3581 case EF_RISCV_FLOAT_ABI_SOFT:
3582 strcat (buf, ", soft-float ABI");
3583 break;
3584
3585 case EF_RISCV_FLOAT_ABI_SINGLE:
3586 strcat (buf, ", single-float ABI");
3587 break;
3588
3589 case EF_RISCV_FLOAT_ABI_DOUBLE:
3590 strcat (buf, ", double-float ABI");
3591 break;
3592
3593 case EF_RISCV_FLOAT_ABI_QUAD:
3594 strcat (buf, ", quad-float ABI");
3595 break;
3596 }
e23eba97
NC
3597 break;
3598
ccde1100
AO
3599 case EM_SH:
3600 switch ((e_flags & EF_SH_MACH_MASK))
3601 {
3602 case EF_SH1: strcat (buf, ", sh1"); break;
3603 case EF_SH2: strcat (buf, ", sh2"); break;
3604 case EF_SH3: strcat (buf, ", sh3"); break;
3605 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3606 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3607 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3608 case EF_SH3E: strcat (buf, ", sh3e"); break;
3609 case EF_SH4: strcat (buf, ", sh4"); break;
3610 case EF_SH5: strcat (buf, ", sh5"); break;
3611 case EF_SH2E: strcat (buf, ", sh2e"); break;
3612 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3613 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3614 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3615 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3616 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3617 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3618 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3619 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3620 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3621 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3622 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3623 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3624 }
3625
cec6a5b8
MR
3626 if (e_flags & EF_SH_PIC)
3627 strcat (buf, ", pic");
3628
3629 if (e_flags & EF_SH_FDPIC)
3630 strcat (buf, ", fdpic");
ccde1100 3631 break;
948f632f 3632
73589c9d
CS
3633 case EM_OR1K:
3634 if (e_flags & EF_OR1K_NODELAY)
3635 strcat (buf, ", no delay");
3636 break;
57346661 3637
351b4b40
RH
3638 case EM_SPARCV9:
3639 if (e_flags & EF_SPARC_32PLUS)
3640 strcat (buf, ", v8+");
3641
3642 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3643 strcat (buf, ", ultrasparcI");
3644
3645 if (e_flags & EF_SPARC_SUN_US3)
3646 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3647
3648 if (e_flags & EF_SPARC_HAL_R1)
3649 strcat (buf, ", halr1");
3650
3651 if (e_flags & EF_SPARC_LEDATA)
3652 strcat (buf, ", ledata");
3653
3654 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3655 strcat (buf, ", tso");
3656
3657 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3658 strcat (buf, ", pso");
3659
3660 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3661 strcat (buf, ", rmo");
3662 break;
7d466069 3663
103f02d3
UD
3664 case EM_PARISC:
3665 switch (e_flags & EF_PARISC_ARCH)
3666 {
3667 case EFA_PARISC_1_0:
3668 strcpy (buf, ", PA-RISC 1.0");
3669 break;
3670 case EFA_PARISC_1_1:
3671 strcpy (buf, ", PA-RISC 1.1");
3672 break;
3673 case EFA_PARISC_2_0:
3674 strcpy (buf, ", PA-RISC 2.0");
3675 break;
3676 default:
3677 break;
3678 }
3679 if (e_flags & EF_PARISC_TRAPNIL)
3680 strcat (buf, ", trapnil");
3681 if (e_flags & EF_PARISC_EXT)
3682 strcat (buf, ", ext");
3683 if (e_flags & EF_PARISC_LSB)
3684 strcat (buf, ", lsb");
3685 if (e_flags & EF_PARISC_WIDE)
3686 strcat (buf, ", wide");
3687 if (e_flags & EF_PARISC_NO_KABP)
3688 strcat (buf, ", no kabp");
3689 if (e_flags & EF_PARISC_LAZYSWAP)
3690 strcat (buf, ", lazyswap");
30800947 3691 break;
76da6bbe 3692
7d466069 3693 case EM_PJ:
2b0337b0 3694 case EM_PJ_OLD:
7d466069
ILT
3695 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3696 strcat (buf, ", new calling convention");
3697
3698 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3699 strcat (buf, ", gnu calling convention");
3700 break;
4d6ed7c8
NC
3701
3702 case EM_IA_64:
3703 if ((e_flags & EF_IA_64_ABI64))
3704 strcat (buf, ", 64-bit");
3705 else
3706 strcat (buf, ", 32-bit");
3707 if ((e_flags & EF_IA_64_REDUCEDFP))
3708 strcat (buf, ", reduced fp model");
3709 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3710 strcat (buf, ", no function descriptors, constant gp");
3711 else if ((e_flags & EF_IA_64_CONS_GP))
3712 strcat (buf, ", constant gp");
3713 if ((e_flags & EF_IA_64_ABSOLUTE))
3714 strcat (buf, ", absolute");
dda8d76d 3715 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3716 {
3717 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3718 strcat (buf, ", vms_linkages");
3719 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3720 {
3721 case EF_IA_64_VMS_COMCOD_SUCCESS:
3722 break;
3723 case EF_IA_64_VMS_COMCOD_WARNING:
3724 strcat (buf, ", warning");
3725 break;
3726 case EF_IA_64_VMS_COMCOD_ERROR:
3727 strcat (buf, ", error");
3728 break;
3729 case EF_IA_64_VMS_COMCOD_ABORT:
3730 strcat (buf, ", abort");
3731 break;
3732 default:
bee0ee85
NC
3733 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3734 e_flags & EF_IA_64_VMS_COMCOD);
3735 strcat (buf, ", <unknown>");
28f997cf
TG
3736 }
3737 }
4d6ed7c8 3738 break;
179d3252
JT
3739
3740 case EM_VAX:
3741 if ((e_flags & EF_VAX_NONPIC))
3742 strcat (buf, ", non-PIC");
3743 if ((e_flags & EF_VAX_DFLOAT))
3744 strcat (buf, ", D-Float");
3745 if ((e_flags & EF_VAX_GFLOAT))
3746 strcat (buf, ", G-Float");
3747 break;
c7927a3c 3748
619ed720
EB
3749 case EM_VISIUM:
3750 if (e_flags & EF_VISIUM_ARCH_MCM)
3751 strcat (buf, ", mcm");
3752 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3753 strcat (buf, ", mcm24");
3754 if (e_flags & EF_VISIUM_ARCH_GR6)
3755 strcat (buf, ", gr6");
3756 break;
3757
4046d87a 3758 case EM_RL78:
1740ba0c
NC
3759 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3760 {
3761 case E_FLAG_RL78_ANY_CPU: break;
3762 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3763 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3764 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3765 }
856ea05c
KP
3766 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3767 strcat (buf, ", 64-bit doubles");
4046d87a 3768 break;
0b4362b0 3769
c7927a3c
NC
3770 case EM_RX:
3771 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3772 strcat (buf, ", 64-bit doubles");
3773 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3774 strcat (buf, ", dsp");
d4cb0ea0 3775 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3776 strcat (buf, ", pid");
708e2187
NC
3777 if (e_flags & E_FLAG_RX_ABI)
3778 strcat (buf, ", RX ABI");
3525236c
NC
3779 if (e_flags & E_FLAG_RX_SINSNS_SET)
3780 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3781 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3782 if (e_flags & E_FLAG_RX_V2)
3783 strcat (buf, ", V2");
f87673e0
YS
3784 if (e_flags & E_FLAG_RX_V3)
3785 strcat (buf, ", V3");
d4cb0ea0 3786 break;
55786da2
AK
3787
3788 case EM_S390:
3789 if (e_flags & EF_S390_HIGH_GPRS)
3790 strcat (buf, ", highgprs");
d4cb0ea0 3791 break;
40b36596
JM
3792
3793 case EM_TI_C6000:
3794 if ((e_flags & EF_C6000_REL))
3795 strcat (buf, ", relocatable module");
d4cb0ea0 3796 break;
13761a11
NC
3797
3798 case EM_MSP430:
3799 strcat (buf, _(": architecture variant: "));
3800 switch (e_flags & EF_MSP430_MACH)
3801 {
3802 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3803 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3804 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3805 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3806 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3807 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3808 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3809 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3810 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3811 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3812 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3813 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3814 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3815 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3816 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3817 default:
3818 strcat (buf, _(": unknown")); break;
3819 }
3820
3821 if (e_flags & ~ EF_MSP430_MACH)
3822 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
3823 break;
3824
3825 case EM_Z80:
3826 switch (e_flags & EF_Z80_MACH_MSK)
3827 {
3828 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
3829 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
3830 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
3831 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
3832 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
3833 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 3834 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
3835 default:
3836 strcat (buf, _(", unknown")); break;
3837 }
3838 break;
252b5132
RH
3839 }
3840 }
3841
3842 return buf;
3843}
3844
252b5132 3845static const char *
dda8d76d 3846get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3847{
3848 static char buff[32];
3849
3850 switch (osabi)
3851 {
3852 case ELFOSABI_NONE: return "UNIX - System V";
3853 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3854 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3855 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3856 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3857 case ELFOSABI_AIX: return "UNIX - AIX";
3858 case ELFOSABI_IRIX: return "UNIX - IRIX";
3859 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3860 case ELFOSABI_TRU64: return "UNIX - TRU64";
3861 case ELFOSABI_MODESTO: return "Novell - Modesto";
3862 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3863 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3864 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3865 case ELFOSABI_AROS: return "AROS";
11636f9e 3866 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3867 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3868 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3869 default:
40b36596 3870 if (osabi >= 64)
dda8d76d 3871 switch (filedata->file_header.e_machine)
40b36596
JM
3872 {
3873 case EM_ARM:
3874 switch (osabi)
3875 {
3876 case ELFOSABI_ARM: return "ARM";
18a20338 3877 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3878 default:
3879 break;
3880 }
3881 break;
3882
3883 case EM_MSP430:
3884 case EM_MSP430_OLD:
619ed720 3885 case EM_VISIUM:
40b36596
JM
3886 switch (osabi)
3887 {
3888 case ELFOSABI_STANDALONE: return _("Standalone App");
3889 default:
3890 break;
3891 }
3892 break;
3893
3894 case EM_TI_C6000:
3895 switch (osabi)
3896 {
3897 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3898 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3899 default:
3900 break;
3901 }
3902 break;
3903
3904 default:
3905 break;
3906 }
e9e44622 3907 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3908 return buff;
3909 }
3910}
3911
a06ea964
NC
3912static const char *
3913get_aarch64_segment_type (unsigned long type)
3914{
3915 switch (type)
3916 {
32ec8896
NC
3917 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3918 default: return NULL;
a06ea964 3919 }
a06ea964
NC
3920}
3921
b294bdf8
MM
3922static const char *
3923get_arm_segment_type (unsigned long type)
3924{
3925 switch (type)
3926 {
32ec8896
NC
3927 case PT_ARM_EXIDX: return "EXIDX";
3928 default: return NULL;
b294bdf8 3929 }
b294bdf8
MM
3930}
3931
b4cbbe8f
AK
3932static const char *
3933get_s390_segment_type (unsigned long type)
3934{
3935 switch (type)
3936 {
3937 case PT_S390_PGSTE: return "S390_PGSTE";
3938 default: return NULL;
3939 }
3940}
3941
d3ba0551
AM
3942static const char *
3943get_mips_segment_type (unsigned long type)
252b5132
RH
3944{
3945 switch (type)
3946 {
32ec8896
NC
3947 case PT_MIPS_REGINFO: return "REGINFO";
3948 case PT_MIPS_RTPROC: return "RTPROC";
3949 case PT_MIPS_OPTIONS: return "OPTIONS";
3950 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3951 default: return NULL;
252b5132 3952 }
252b5132
RH
3953}
3954
103f02d3 3955static const char *
d3ba0551 3956get_parisc_segment_type (unsigned long type)
103f02d3
UD
3957{
3958 switch (type)
3959 {
103f02d3
UD
3960 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3961 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3962 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3963 default: return NULL;
103f02d3 3964 }
103f02d3
UD
3965}
3966
4d6ed7c8 3967static const char *
d3ba0551 3968get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3969{
3970 switch (type)
3971 {
3972 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3973 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 3974 default: return NULL;
4d6ed7c8 3975 }
4d6ed7c8
NC
3976}
3977
40b36596
JM
3978static const char *
3979get_tic6x_segment_type (unsigned long type)
3980{
3981 switch (type)
3982 {
32ec8896
NC
3983 case PT_C6000_PHATTR: return "C6000_PHATTR";
3984 default: return NULL;
40b36596 3985 }
40b36596
JM
3986}
3987
df3a023b
AM
3988static const char *
3989get_hpux_segment_type (unsigned long type, unsigned e_machine)
3990{
3991 if (e_machine == EM_PARISC)
3992 switch (type)
3993 {
3994 case PT_HP_TLS: return "HP_TLS";
3995 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3996 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3997 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3998 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3999 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4000 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4001 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4002 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4003 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4004 case PT_HP_PARALLEL: return "HP_PARALLEL";
4005 case PT_HP_FASTBIND: return "HP_FASTBIND";
4006 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4007 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4008 case PT_HP_STACK: return "HP_STACK";
4009 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4010 default: return NULL;
4011 }
4012
4013 if (e_machine == EM_IA_64)
4014 switch (type)
4015 {
4016 case PT_HP_TLS: return "HP_TLS";
4017 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4018 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4019 case PT_IA_64_HP_STACK: return "HP_STACK";
4020 default: return NULL;
4021 }
4022
4023 return NULL;
4024}
4025
5522f910
NC
4026static const char *
4027get_solaris_segment_type (unsigned long type)
4028{
4029 switch (type)
4030 {
4031 case 0x6464e550: return "PT_SUNW_UNWIND";
4032 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4033 case 0x6ffffff7: return "PT_LOSUNW";
4034 case 0x6ffffffa: return "PT_SUNWBSS";
4035 case 0x6ffffffb: return "PT_SUNWSTACK";
4036 case 0x6ffffffc: return "PT_SUNWDTRACE";
4037 case 0x6ffffffd: return "PT_SUNWCAP";
4038 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4039 default: return NULL;
5522f910
NC
4040 }
4041}
4042
252b5132 4043static const char *
dda8d76d 4044get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4045{
b34976b6 4046 static char buff[32];
252b5132
RH
4047
4048 switch (p_type)
4049 {
b34976b6
AM
4050 case PT_NULL: return "NULL";
4051 case PT_LOAD: return "LOAD";
252b5132 4052 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4053 case PT_INTERP: return "INTERP";
4054 case PT_NOTE: return "NOTE";
4055 case PT_SHLIB: return "SHLIB";
4056 case PT_PHDR: return "PHDR";
13ae64f3 4057 case PT_TLS: return "TLS";
32ec8896 4058 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4059 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4060 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4061 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4062
3eba3ef3
NC
4063 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4064 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4065 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4066
252b5132 4067 default:
df3a023b 4068 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4069 {
2cf0635d 4070 const char * result;
103f02d3 4071
dda8d76d 4072 switch (filedata->file_header.e_machine)
252b5132 4073 {
a06ea964
NC
4074 case EM_AARCH64:
4075 result = get_aarch64_segment_type (p_type);
4076 break;
b294bdf8
MM
4077 case EM_ARM:
4078 result = get_arm_segment_type (p_type);
4079 break;
252b5132 4080 case EM_MIPS:
4fe85591 4081 case EM_MIPS_RS3_LE:
252b5132
RH
4082 result = get_mips_segment_type (p_type);
4083 break;
103f02d3
UD
4084 case EM_PARISC:
4085 result = get_parisc_segment_type (p_type);
4086 break;
4d6ed7c8
NC
4087 case EM_IA_64:
4088 result = get_ia64_segment_type (p_type);
4089 break;
40b36596
JM
4090 case EM_TI_C6000:
4091 result = get_tic6x_segment_type (p_type);
4092 break;
b4cbbe8f
AK
4093 case EM_S390:
4094 case EM_S390_OLD:
4095 result = get_s390_segment_type (p_type);
4096 break;
252b5132
RH
4097 default:
4098 result = NULL;
4099 break;
4100 }
103f02d3 4101
252b5132
RH
4102 if (result != NULL)
4103 return result;
103f02d3 4104
1a9ccd70 4105 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4106 }
4107 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4108 {
df3a023b 4109 const char * result = NULL;
103f02d3 4110
df3a023b 4111 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4112 {
df3a023b
AM
4113 case ELFOSABI_GNU:
4114 case ELFOSABI_FREEBSD:
4115 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4116 {
4117 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4118 result = buff;
4119 }
103f02d3 4120 break;
df3a023b
AM
4121 case ELFOSABI_HPUX:
4122 result = get_hpux_segment_type (p_type,
4123 filedata->file_header.e_machine);
4124 break;
4125 case ELFOSABI_SOLARIS:
4126 result = get_solaris_segment_type (p_type);
00428cca 4127 break;
103f02d3 4128 default:
103f02d3
UD
4129 break;
4130 }
103f02d3
UD
4131 if (result != NULL)
4132 return result;
4133
1a9ccd70 4134 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4135 }
252b5132 4136 else
e9e44622 4137 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4138
4139 return buff;
4140 }
4141}
4142
53a346d8
CZ
4143static const char *
4144get_arc_section_type_name (unsigned int sh_type)
4145{
4146 switch (sh_type)
4147 {
4148 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4149 default:
4150 break;
4151 }
4152 return NULL;
4153}
4154
252b5132 4155static const char *
d3ba0551 4156get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4157{
4158 switch (sh_type)
4159 {
b34976b6
AM
4160 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4161 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4162 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4163 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4164 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4165 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4166 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4167 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4168 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4169 case SHT_MIPS_RELD: return "MIPS_RELD";
4170 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4171 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4172 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4173 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4174 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4175 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4176 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4177 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4178 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4179 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4180 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4181 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4182 case SHT_MIPS_LINE: return "MIPS_LINE";
4183 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4184 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4185 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4186 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4187 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4188 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4189 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4190 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4191 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4192 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4193 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4194 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4195 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4196 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4197 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4198 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4199 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4200 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4201 default:
4202 break;
4203 }
4204 return NULL;
4205}
4206
103f02d3 4207static const char *
d3ba0551 4208get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4209{
4210 switch (sh_type)
4211 {
4212 case SHT_PARISC_EXT: return "PARISC_EXT";
4213 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4214 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4215 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4216 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4217 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4218 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4219 default: return NULL;
103f02d3 4220 }
103f02d3
UD
4221}
4222
4d6ed7c8 4223static const char *
dda8d76d 4224get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4225{
18bd398b 4226 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4227 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4228 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4229
4d6ed7c8
NC
4230 switch (sh_type)
4231 {
148b93f2
NC
4232 case SHT_IA_64_EXT: return "IA_64_EXT";
4233 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4234 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4235 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4236 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4237 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4238 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4239 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4240 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4241 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4242 default:
4243 break;
4244 }
4245 return NULL;
4246}
4247
d2b2c203
DJ
4248static const char *
4249get_x86_64_section_type_name (unsigned int sh_type)
4250{
4251 switch (sh_type)
4252 {
4253 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4254 default: return NULL;
d2b2c203 4255 }
d2b2c203
DJ
4256}
4257
a06ea964
NC
4258static const char *
4259get_aarch64_section_type_name (unsigned int sh_type)
4260{
4261 switch (sh_type)
4262 {
32ec8896
NC
4263 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4264 default: return NULL;
a06ea964 4265 }
a06ea964
NC
4266}
4267
40a18ebd
NC
4268static const char *
4269get_arm_section_type_name (unsigned int sh_type)
4270{
4271 switch (sh_type)
4272 {
7f6fed87
NC
4273 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4274 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4275 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4276 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4277 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4278 default: return NULL;
40a18ebd 4279 }
40a18ebd
NC
4280}
4281
40b36596
JM
4282static const char *
4283get_tic6x_section_type_name (unsigned int sh_type)
4284{
4285 switch (sh_type)
4286 {
32ec8896
NC
4287 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4288 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4289 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4290 case SHT_TI_ICODE: return "TI_ICODE";
4291 case SHT_TI_XREF: return "TI_XREF";
4292 case SHT_TI_HANDLER: return "TI_HANDLER";
4293 case SHT_TI_INITINFO: return "TI_INITINFO";
4294 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4295 default: return NULL;
40b36596 4296 }
40b36596
JM
4297}
4298
13761a11 4299static const char *
b0191216 4300get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4301{
4302 switch (sh_type)
4303 {
32ec8896
NC
4304 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4305 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4306 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4307 default: return NULL;
13761a11
NC
4308 }
4309}
4310
fe944acf
FT
4311static const char *
4312get_nfp_section_type_name (unsigned int sh_type)
4313{
4314 switch (sh_type)
4315 {
4316 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4317 case SHT_NFP_INITREG: return "NFP_INITREG";
4318 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4319 default: return NULL;
4320 }
4321}
4322
685080f2
NC
4323static const char *
4324get_v850_section_type_name (unsigned int sh_type)
4325{
4326 switch (sh_type)
4327 {
32ec8896
NC
4328 case SHT_V850_SCOMMON: return "V850 Small Common";
4329 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4330 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4331 case SHT_RENESAS_IOP: return "RENESAS IOP";
4332 case SHT_RENESAS_INFO: return "RENESAS INFO";
4333 default: return NULL;
685080f2
NC
4334 }
4335}
4336
2dc8dd17
JW
4337static const char *
4338get_riscv_section_type_name (unsigned int sh_type)
4339{
4340 switch (sh_type)
4341 {
4342 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4343 default: return NULL;
4344 }
4345}
4346
0861f561
CQ
4347static const char *
4348get_csky_section_type_name (unsigned int sh_type)
4349{
4350 switch (sh_type)
4351 {
4352 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4353 default: return NULL;
4354 }
4355}
4356
252b5132 4357static const char *
dda8d76d 4358get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4359{
b34976b6 4360 static char buff[32];
9fb71ee4 4361 const char * result;
252b5132
RH
4362
4363 switch (sh_type)
4364 {
4365 case SHT_NULL: return "NULL";
4366 case SHT_PROGBITS: return "PROGBITS";
4367 case SHT_SYMTAB: return "SYMTAB";
4368 case SHT_STRTAB: return "STRTAB";
4369 case SHT_RELA: return "RELA";
4370 case SHT_HASH: return "HASH";
4371 case SHT_DYNAMIC: return "DYNAMIC";
4372 case SHT_NOTE: return "NOTE";
4373 case SHT_NOBITS: return "NOBITS";
4374 case SHT_REL: return "REL";
4375 case SHT_SHLIB: return "SHLIB";
4376 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4377 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4378 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4379 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4380 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4381 case SHT_GROUP: return "GROUP";
67ce483b 4382 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4383 case SHT_GNU_verdef: return "VERDEF";
4384 case SHT_GNU_verneed: return "VERNEED";
4385 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4386 case 0x6ffffff0: return "VERSYM";
4387 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4388 case 0x7ffffffd: return "AUXILIARY";
4389 case 0x7fffffff: return "FILTER";
047b2264 4390 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4391
4392 default:
4393 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4394 {
dda8d76d 4395 switch (filedata->file_header.e_machine)
252b5132 4396 {
53a346d8
CZ
4397 case EM_ARC:
4398 case EM_ARC_COMPACT:
4399 case EM_ARC_COMPACT2:
4400 result = get_arc_section_type_name (sh_type);
4401 break;
252b5132 4402 case EM_MIPS:
4fe85591 4403 case EM_MIPS_RS3_LE:
252b5132
RH
4404 result = get_mips_section_type_name (sh_type);
4405 break;
103f02d3
UD
4406 case EM_PARISC:
4407 result = get_parisc_section_type_name (sh_type);
4408 break;
4d6ed7c8 4409 case EM_IA_64:
dda8d76d 4410 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4411 break;
d2b2c203 4412 case EM_X86_64:
8a9036a4 4413 case EM_L1OM:
7a9068fe 4414 case EM_K1OM:
d2b2c203
DJ
4415 result = get_x86_64_section_type_name (sh_type);
4416 break;
a06ea964
NC
4417 case EM_AARCH64:
4418 result = get_aarch64_section_type_name (sh_type);
4419 break;
40a18ebd
NC
4420 case EM_ARM:
4421 result = get_arm_section_type_name (sh_type);
4422 break;
40b36596
JM
4423 case EM_TI_C6000:
4424 result = get_tic6x_section_type_name (sh_type);
4425 break;
13761a11 4426 case EM_MSP430:
b0191216 4427 result = get_msp430_section_type_name (sh_type);
13761a11 4428 break;
fe944acf
FT
4429 case EM_NFP:
4430 result = get_nfp_section_type_name (sh_type);
4431 break;
685080f2
NC
4432 case EM_V800:
4433 case EM_V850:
4434 case EM_CYGNUS_V850:
4435 result = get_v850_section_type_name (sh_type);
4436 break;
2dc8dd17
JW
4437 case EM_RISCV:
4438 result = get_riscv_section_type_name (sh_type);
4439 break;
0861f561
CQ
4440 case EM_CSKY:
4441 result = get_csky_section_type_name (sh_type);
4442 break;
252b5132
RH
4443 default:
4444 result = NULL;
4445 break;
4446 }
4447
4448 if (result != NULL)
4449 return result;
4450
9fb71ee4 4451 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4452 }
4453 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4454 {
dda8d76d 4455 switch (filedata->file_header.e_machine)
148b93f2
NC
4456 {
4457 case EM_IA_64:
dda8d76d 4458 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4459 break;
4460 default:
dda8d76d 4461 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4462 result = get_solaris_section_type (sh_type);
4463 else
1b4b80bf
NC
4464 {
4465 switch (sh_type)
4466 {
4467 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4468 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4469 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4470 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4471 default:
4472 result = NULL;
4473 break;
4474 }
4475 }
148b93f2
NC
4476 break;
4477 }
4478
4479 if (result != NULL)
4480 return result;
4481
9fb71ee4 4482 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4483 }
252b5132 4484 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4485 {
dda8d76d 4486 switch (filedata->file_header.e_machine)
685080f2
NC
4487 {
4488 case EM_V800:
4489 case EM_V850:
4490 case EM_CYGNUS_V850:
9fb71ee4 4491 result = get_v850_section_type_name (sh_type);
a9fb83be 4492 break;
685080f2 4493 default:
9fb71ee4 4494 result = NULL;
685080f2
NC
4495 break;
4496 }
4497
9fb71ee4
NC
4498 if (result != NULL)
4499 return result;
4500
4501 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4502 }
252b5132 4503 else
a7dbfd1c
NC
4504 /* This message is probably going to be displayed in a 15
4505 character wide field, so put the hex value first. */
4506 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4507
252b5132
RH
4508 return buff;
4509 }
4510}
4511
79bc120c
NC
4512enum long_option_values
4513{
4514 OPTION_DEBUG_DUMP = 512,
4515 OPTION_DYN_SYMS,
0f03783c 4516 OPTION_LTO_SYMS,
79bc120c
NC
4517 OPTION_DWARF_DEPTH,
4518 OPTION_DWARF_START,
4519 OPTION_DWARF_CHECK,
4520 OPTION_CTF_DUMP,
4521 OPTION_CTF_PARENT,
4522 OPTION_CTF_SYMBOLS,
4523 OPTION_CTF_STRINGS,
4524 OPTION_WITH_SYMBOL_VERSIONS,
4525 OPTION_RECURSE_LIMIT,
4526 OPTION_NO_RECURSE_LIMIT,
4527 OPTION_NO_DEMANGLING
4528};
2979dc34 4529
85b1c36d 4530static struct option options[] =
252b5132 4531{
79bc120c
NC
4532 /* Note - This table is alpha-sorted on the 'val'
4533 field in order to make adding new options easier. */
4534 {"arch-specific", no_argument, 0, 'A'},
b34976b6 4535 {"all", no_argument, 0, 'a'},
79bc120c
NC
4536 {"demangle", optional_argument, 0, 'C'},
4537 {"archive-index", no_argument, 0, 'c'},
4538 {"use-dynamic", no_argument, 0, 'D'},
4539 {"dynamic", no_argument, 0, 'd'},
b34976b6 4540 {"headers", no_argument, 0, 'e'},
79bc120c
NC
4541 {"section-groups", no_argument, 0, 'g'},
4542 {"help", no_argument, 0, 'H'},
4543 {"file-header", no_argument, 0, 'h'},
b34976b6 4544 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
4545 {"lint", no_argument, 0, 'L'},
4546 {"enable-checks", no_argument, 0, 'L'},
4547 {"program-headers", no_argument, 0, 'l'},
b34976b6 4548 {"segments", no_argument, 0, 'l'},
595cf52e 4549 {"full-section-name",no_argument, 0, 'N'},
79bc120c 4550 {"notes", no_argument, 0, 'n'},
ca0e11aa 4551 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
4552 {"string-dump", required_argument, 0, 'p'},
4553 {"relocated-dump", required_argument, 0, 'R'},
4554 {"relocs", no_argument, 0, 'r'},
4555 {"section-headers", no_argument, 0, 'S'},
4556 {"sections", no_argument, 0, 'S'},
b34976b6
AM
4557 {"symbols", no_argument, 0, 's'},
4558 {"syms", no_argument, 0, 's'},
79bc120c
NC
4559 {"silent-truncation",no_argument, 0, 'T'},
4560 {"section-details", no_argument, 0, 't'},
09c11c86 4561 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
4562 {"version-info", no_argument, 0, 'V'},
4563 {"version", no_argument, 0, 'v'},
4564 {"wide", no_argument, 0, 'W'},
b34976b6 4565 {"hex-dump", required_argument, 0, 'x'},
0e602686 4566 {"decompress", no_argument, 0, 'z'},
252b5132 4567
79bc120c
NC
4568 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
4569 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
4570 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4571 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4572 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 4573 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 4574 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
4575 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4576 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4577 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 4578#ifdef ENABLE_LIBCTF
d344b407 4579 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
4580 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
4581 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
4582 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 4583#endif
7d9813f1 4584
b34976b6 4585 {0, no_argument, 0, 0}
252b5132
RH
4586};
4587
4588static void
2cf0635d 4589usage (FILE * stream)
252b5132 4590{
92f01d61
JM
4591 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4592 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4593 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4594 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4595 -h --file-header Display the ELF file header\n\
4596 -l --program-headers Display the program headers\n\
4597 --segments An alias for --program-headers\n\
4598 -S --section-headers Display the sections' header\n\
4599 --sections An alias for --section-headers\n\
f5842774 4600 -g --section-groups Display the section groups\n\
5477e8a0 4601 -t --section-details Display the section details\n\
8b53311e
NC
4602 -e --headers Equivalent to: -h -l -S\n\
4603 -s --syms Display the symbol table\n\
3f08eb35 4604 --symbols An alias for --syms\n\
1b513401 4605 --dyn-syms Display the dynamic symbol table\n\
0f03783c 4606 --lto-syms Display LTO symbol tables\n\
79bc120c
NC
4607 -C --demangle[=STYLE] Decode low-level symbol names into user-level names\n\
4608 The STYLE, if specified, can be `auto' (the default),\n\
4609 `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
4610 or `gnat'\n\
4611 --no-demangle Do not demangle low-level symbol names. (This is the default)\n\
4612 --recurse-limit Enable a demangling recursion limit. (This is the default)\n\
4613 --no-recurse-limit Disable a demangling recursion limit\n\
8b53311e
NC
4614 -n --notes Display the core notes (if present)\n\
4615 -r --relocs Display the relocations (if present)\n\
4616 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4617 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4618 -V --version-info Display the version sections (if present)\n\
1b31d05e 4619 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4620 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4621 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
1b513401 4622 -L --lint|--enable-checks Display warning messages for possible problems\n\
09c11c86
NC
4623 -x --hex-dump=<number|name>\n\
4624 Dump the contents of section <number|name> as bytes\n\
4625 -p --string-dump=<number|name>\n\
4626 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4627 -R --relocated-dump=<number|name>\n\
4628 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4629 -z --decompress Decompress section before dumping it\n\
ca0e11aa 4630 -w[lLiaprmfFsoORtUuTgAc] or\n\
1ed06042 4631 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
e4b7104b 4632 =frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,\n\
657d0d47 4633 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
ca0e11aa
NC
4634 =addr,=cu_index]\n\
4635 Display the contents of DWARF debug sections\n\
4636 -wk,--debug-dump=links Display the contents of sections that link to separate debuginfo files\n\
4637 -P,--process-links Display the contents of non-debug sections in separate debuginfo files. (Implies -wK)\n"));
c46b7066
NC
4638#if DEFAULT_FOR_FOLLOW_LINKS
4639 fprintf (stream, _("\
4640 -wK,--debug-dump=follow-links Follow links to separate debug info files (default)\n\
4641 -wN,--debug-dump=no-follow-links Do not follow links to separate debug info files\n\
4642"));
4643#else
4644 fprintf (stream, _("\
4645 -wK,--debug-dump=follow-links Follow links to separate debug info files\n\
4646 -wN,--debug-dump=no-follow-links Do not follow links to separate debug info files (default)\n\
4647"));
4648#endif
fd2f0033
TT
4649 fprintf (stream, _("\
4650 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4651 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4652 or deeper\n"));
094e34f2 4653#ifdef ENABLE_LIBCTF
7d9813f1
NA
4654 fprintf (stream, _("\
4655 --ctf=<number|name> Display CTF info from section <number|name>\n\
4656 --ctf-parent=<number|name>\n\
4657 Use section <number|name> as the CTF parent\n\n\
4658 --ctf-symbols=<number|name>\n\
4659 Use section <number|name> as the CTF external symtab\n\n\
4660 --ctf-strings=<number|name>\n\
4661 Use section <number|name> as the CTF external strtab\n\n"));
094e34f2 4662#endif
7d9813f1 4663
252b5132 4664#ifdef SUPPORT_DISASSEMBLY
92f01d61 4665 fprintf (stream, _("\
09c11c86
NC
4666 -i --instruction-dump=<number|name>\n\
4667 Disassemble the contents of section <number|name>\n"));
252b5132 4668#endif
92f01d61 4669 fprintf (stream, _("\
8b53311e
NC
4670 -I --histogram Display histogram of bucket list lengths\n\
4671 -W --wide Allow output width to exceed 80 characters\n\
0942c7ab 4672 -T --silent-truncation If a symbol name is truncated, do not add a suffix [...]\n\
07012eee 4673 @<file> Read options from <file>\n\
8b53311e
NC
4674 -H --help Display this information\n\
4675 -v --version Display the version number of readelf\n"));
1118d252 4676
92f01d61
JM
4677 if (REPORT_BUGS_TO[0] && stream == stdout)
4678 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4679
92f01d61 4680 exit (stream == stdout ? 0 : 1);
252b5132
RH
4681}
4682
18bd398b
NC
4683/* Record the fact that the user wants the contents of section number
4684 SECTION to be displayed using the method(s) encoded as flags bits
4685 in TYPE. Note, TYPE can be zero if we are creating the array for
4686 the first time. */
4687
252b5132 4688static void
6431e409
AM
4689request_dump_bynumber (struct dump_data *dumpdata,
4690 unsigned int section, dump_type type)
252b5132 4691{
6431e409 4692 if (section >= dumpdata->num_dump_sects)
252b5132 4693 {
2cf0635d 4694 dump_type * new_dump_sects;
252b5132 4695
3f5e193b 4696 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4697 sizeof (* new_dump_sects));
252b5132
RH
4698
4699 if (new_dump_sects == NULL)
591a748a 4700 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4701 else
4702 {
6431e409 4703 if (dumpdata->dump_sects)
21b65bac
NC
4704 {
4705 /* Copy current flag settings. */
6431e409
AM
4706 memcpy (new_dump_sects, dumpdata->dump_sects,
4707 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4708
6431e409 4709 free (dumpdata->dump_sects);
21b65bac 4710 }
252b5132 4711
6431e409
AM
4712 dumpdata->dump_sects = new_dump_sects;
4713 dumpdata->num_dump_sects = section + 1;
252b5132
RH
4714 }
4715 }
4716
6431e409
AM
4717 if (dumpdata->dump_sects)
4718 dumpdata->dump_sects[section] |= type;
252b5132
RH
4719}
4720
aef1f6d0
DJ
4721/* Request a dump by section name. */
4722
4723static void
2cf0635d 4724request_dump_byname (const char * section, dump_type type)
aef1f6d0 4725{
2cf0635d 4726 struct dump_list_entry * new_request;
aef1f6d0 4727
3f5e193b
NC
4728 new_request = (struct dump_list_entry *)
4729 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4730 if (!new_request)
591a748a 4731 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4732
4733 new_request->name = strdup (section);
4734 if (!new_request->name)
591a748a 4735 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4736
4737 new_request->type = type;
4738
4739 new_request->next = dump_sects_byname;
4740 dump_sects_byname = new_request;
4741}
4742
cf13d699 4743static inline void
6431e409 4744request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
4745{
4746 int section;
4747 char * cp;
4748
4749 do_dump++;
4750 section = strtoul (optarg, & cp, 0);
4751
4752 if (! *cp && section >= 0)
6431e409 4753 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
4754 else
4755 request_dump_byname (optarg, type);
4756}
4757
252b5132 4758static void
6431e409 4759parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
4760{
4761 int c;
4762
4763 if (argc < 2)
92f01d61 4764 usage (stderr);
252b5132
RH
4765
4766 while ((c = getopt_long
ca0e11aa 4767 (argc, argv, "ACDHILNPR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4768 {
252b5132
RH
4769 switch (c)
4770 {
4771 case 0:
4772 /* Long options. */
4773 break;
4774 case 'H':
92f01d61 4775 usage (stdout);
252b5132
RH
4776 break;
4777
4778 case 'a':
32ec8896
NC
4779 do_syms = TRUE;
4780 do_reloc = TRUE;
4781 do_unwind = TRUE;
4782 do_dynamic = TRUE;
4783 do_header = TRUE;
4784 do_sections = TRUE;
4785 do_section_groups = TRUE;
4786 do_segments = TRUE;
4787 do_version = TRUE;
4788 do_histogram = TRUE;
4789 do_arch = TRUE;
4790 do_notes = TRUE;
252b5132 4791 break;
79bc120c 4792
f5842774 4793 case 'g':
32ec8896 4794 do_section_groups = TRUE;
f5842774 4795 break;
5477e8a0 4796 case 't':
595cf52e 4797 case 'N':
32ec8896
NC
4798 do_sections = TRUE;
4799 do_section_details = TRUE;
595cf52e 4800 break;
252b5132 4801 case 'e':
32ec8896
NC
4802 do_header = TRUE;
4803 do_sections = TRUE;
4804 do_segments = TRUE;
252b5132 4805 break;
a952a375 4806 case 'A':
32ec8896 4807 do_arch = TRUE;
a952a375 4808 break;
252b5132 4809 case 'D':
32ec8896 4810 do_using_dynamic = TRUE;
252b5132
RH
4811 break;
4812 case 'r':
32ec8896 4813 do_reloc = TRUE;
252b5132 4814 break;
4d6ed7c8 4815 case 'u':
32ec8896 4816 do_unwind = TRUE;
4d6ed7c8 4817 break;
252b5132 4818 case 'h':
32ec8896 4819 do_header = TRUE;
252b5132
RH
4820 break;
4821 case 'l':
32ec8896 4822 do_segments = TRUE;
252b5132
RH
4823 break;
4824 case 's':
32ec8896 4825 do_syms = TRUE;
252b5132
RH
4826 break;
4827 case 'S':
32ec8896 4828 do_sections = TRUE;
252b5132
RH
4829 break;
4830 case 'd':
32ec8896 4831 do_dynamic = TRUE;
252b5132 4832 break;
a952a375 4833 case 'I':
32ec8896 4834 do_histogram = TRUE;
a952a375 4835 break;
779fe533 4836 case 'n':
32ec8896 4837 do_notes = TRUE;
779fe533 4838 break;
4145f1d5 4839 case 'c':
32ec8896 4840 do_archive_index = TRUE;
4145f1d5 4841 break;
1b513401
NC
4842 case 'L':
4843 do_checks = TRUE;
4844 break;
ca0e11aa
NC
4845 case 'P':
4846 process_links = TRUE;
4847 do_follow_links = TRUE;
4848 break;
252b5132 4849 case 'x':
6431e409 4850 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 4851 break;
09c11c86 4852 case 'p':
6431e409 4853 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
4854 break;
4855 case 'R':
6431e409 4856 request_dump (dumpdata, RELOC_DUMP);
09c11c86 4857 break;
0e602686 4858 case 'z':
32ec8896 4859 decompress_dumps = TRUE;
0e602686 4860 break;
252b5132 4861 case 'w':
32ec8896 4862 do_dump = TRUE;
0f03783c 4863 if (optarg == NULL)
613ff48b 4864 {
32ec8896 4865 do_debugging = TRUE;
613ff48b
CC
4866 dwarf_select_sections_all ();
4867 }
252b5132
RH
4868 else
4869 {
32ec8896 4870 do_debugging = FALSE;
4cb93e3b 4871 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4872 }
4873 break;
2979dc34 4874 case OPTION_DEBUG_DUMP:
32ec8896 4875 do_dump = TRUE;
0f03783c 4876 if (optarg == NULL)
32ec8896 4877 do_debugging = TRUE;
2979dc34
JJ
4878 else
4879 {
32ec8896 4880 do_debugging = FALSE;
4cb93e3b 4881 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4882 }
4883 break;
fd2f0033
TT
4884 case OPTION_DWARF_DEPTH:
4885 {
4886 char *cp;
4887
4888 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4889 }
4890 break;
4891 case OPTION_DWARF_START:
4892 {
4893 char *cp;
4894
4895 dwarf_start_die = strtoul (optarg, & cp, 0);
4896 }
4897 break;
4723351a 4898 case OPTION_DWARF_CHECK:
32ec8896 4899 dwarf_check = TRUE;
4723351a 4900 break;
7d9813f1
NA
4901 case OPTION_CTF_DUMP:
4902 do_ctf = TRUE;
6431e409 4903 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
4904 break;
4905 case OPTION_CTF_SYMBOLS:
df16e041 4906 free (dump_ctf_symtab_name);
7d9813f1
NA
4907 dump_ctf_symtab_name = strdup (optarg);
4908 break;
4909 case OPTION_CTF_STRINGS:
df16e041 4910 free (dump_ctf_strtab_name);
7d9813f1
NA
4911 dump_ctf_strtab_name = strdup (optarg);
4912 break;
4913 case OPTION_CTF_PARENT:
df16e041 4914 free (dump_ctf_parent_name);
7d9813f1
NA
4915 dump_ctf_parent_name = strdup (optarg);
4916 break;
2c610e4b 4917 case OPTION_DYN_SYMS:
32ec8896 4918 do_dyn_syms = TRUE;
2c610e4b 4919 break;
0f03783c
NC
4920 case OPTION_LTO_SYMS:
4921 do_lto_syms = TRUE;
4922 break;
252b5132
RH
4923#ifdef SUPPORT_DISASSEMBLY
4924 case 'i':
6431e409 4925 request_dump (dumpdata, DISASS_DUMP);
cf13d699 4926 break;
252b5132
RH
4927#endif
4928 case 'v':
4929 print_version (program_name);
4930 break;
4931 case 'V':
32ec8896 4932 do_version = TRUE;
252b5132 4933 break;
d974e256 4934 case 'W':
32ec8896 4935 do_wide = TRUE;
d974e256 4936 break;
0942c7ab
NC
4937 case 'T':
4938 do_not_show_symbol_truncation = TRUE;
4939 break;
79bc120c
NC
4940 case 'C':
4941 do_demangle = TRUE;
4942 if (optarg != NULL)
4943 {
4944 enum demangling_styles style;
4945
4946 style = cplus_demangle_name_to_style (optarg);
4947 if (style == unknown_demangling)
4948 error (_("unknown demangling style `%s'"), optarg);
4949
4950 cplus_demangle_set_style (style);
4951 }
4952 break;
4953 case OPTION_NO_DEMANGLING:
4954 do_demangle = FALSE;
4955 break;
4956 case OPTION_RECURSE_LIMIT:
4957 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
4958 break;
4959 case OPTION_NO_RECURSE_LIMIT:
4960 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
4961 break;
4962 case OPTION_WITH_SYMBOL_VERSIONS:
4963 /* Ignored for backward compatibility. */
4964 break;
b9e920ec 4965
252b5132 4966 default:
252b5132
RH
4967 /* xgettext:c-format */
4968 error (_("Invalid option '-%c'\n"), c);
1a0670f3 4969 /* Fall through. */
252b5132 4970 case '?':
92f01d61 4971 usage (stderr);
252b5132
RH
4972 }
4973 }
4974
4d6ed7c8 4975 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4976 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4977 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 4978 && !do_section_groups && !do_archive_index
0f03783c 4979 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
4980 {
4981 if (do_checks)
4982 {
4983 check_all = TRUE;
4984 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = TRUE;
4985 do_segments = do_header = do_dump = do_version = TRUE;
4986 do_histogram = do_debugging = do_arch = do_notes = TRUE;
4987 do_section_groups = do_archive_index = do_dyn_syms = TRUE;
0f03783c 4988 do_lto_syms = TRUE;
1b513401
NC
4989 }
4990 else
4991 usage (stderr);
4992 }
252b5132
RH
4993}
4994
4995static const char *
d3ba0551 4996get_elf_class (unsigned int elf_class)
252b5132 4997{
b34976b6 4998 static char buff[32];
103f02d3 4999
252b5132
RH
5000 switch (elf_class)
5001 {
5002 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5003 case ELFCLASS32: return "ELF32";
5004 case ELFCLASS64: return "ELF64";
ab5e7794 5005 default:
e9e44622 5006 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5007 return buff;
252b5132
RH
5008 }
5009}
5010
5011static const char *
d3ba0551 5012get_data_encoding (unsigned int encoding)
252b5132 5013{
b34976b6 5014 static char buff[32];
103f02d3 5015
252b5132
RH
5016 switch (encoding)
5017 {
5018 case ELFDATANONE: return _("none");
33c63f9d
CM
5019 case ELFDATA2LSB: return _("2's complement, little endian");
5020 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5021 default:
e9e44622 5022 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5023 return buff;
252b5132
RH
5024 }
5025}
5026
dda8d76d 5027/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5028
32ec8896 5029static bfd_boolean
dda8d76d 5030process_file_header (Filedata * filedata)
252b5132 5031{
dda8d76d
NC
5032 Elf_Internal_Ehdr * header = & filedata->file_header;
5033
5034 if ( header->e_ident[EI_MAG0] != ELFMAG0
5035 || header->e_ident[EI_MAG1] != ELFMAG1
5036 || header->e_ident[EI_MAG2] != ELFMAG2
5037 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5038 {
5039 error
5040 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
32ec8896 5041 return FALSE;
252b5132
RH
5042 }
5043
ca0e11aa
NC
5044 if (! filedata->is_separate)
5045 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5046
252b5132
RH
5047 if (do_header)
5048 {
32ec8896 5049 unsigned i;
252b5132 5050
ca0e11aa
NC
5051 if (filedata->is_separate)
5052 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5053 else
5054 printf (_("ELF Header:\n"));
252b5132 5055 printf (_(" Magic: "));
b34976b6 5056 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5057 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5058 printf ("\n");
5059 printf (_(" Class: %s\n"),
dda8d76d 5060 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5061 printf (_(" Data: %s\n"),
dda8d76d 5062 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5063 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5064 header->e_ident[EI_VERSION],
5065 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5066 ? _(" (current)")
dda8d76d 5067 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5068 ? _(" <unknown>")
789be9f7 5069 : "")));
252b5132 5070 printf (_(" OS/ABI: %s\n"),
dda8d76d 5071 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5072 printf (_(" ABI Version: %d\n"),
dda8d76d 5073 header->e_ident[EI_ABIVERSION]);
252b5132 5074 printf (_(" Type: %s\n"),
dda8d76d 5075 get_file_type (header->e_type));
252b5132 5076 printf (_(" Machine: %s\n"),
dda8d76d 5077 get_machine_name (header->e_machine));
252b5132 5078 printf (_(" Version: 0x%lx\n"),
e8a64888 5079 header->e_version);
76da6bbe 5080
f7a99963 5081 printf (_(" Entry point address: "));
e8a64888 5082 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5083 printf (_("\n Start of program headers: "));
e8a64888 5084 print_vma (header->e_phoff, DEC);
f7a99963 5085 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5086 print_vma (header->e_shoff, DEC);
f7a99963 5087 printf (_(" (bytes into file)\n"));
76da6bbe 5088
252b5132 5089 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5090 header->e_flags,
dda8d76d 5091 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5092 printf (_(" Size of this header: %u (bytes)\n"),
5093 header->e_ehsize);
5094 printf (_(" Size of program headers: %u (bytes)\n"),
5095 header->e_phentsize);
5096 printf (_(" Number of program headers: %u"),
5097 header->e_phnum);
dda8d76d
NC
5098 if (filedata->section_headers != NULL
5099 && header->e_phnum == PN_XNUM
5100 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
5101 {
5102 header->e_phnum = filedata->section_headers[0].sh_info;
5103 printf (" (%u)", header->e_phnum);
5104 }
2046a35d 5105 putc ('\n', stdout);
e8a64888
AM
5106 printf (_(" Size of section headers: %u (bytes)\n"),
5107 header->e_shentsize);
5108 printf (_(" Number of section headers: %u"),
5109 header->e_shnum);
dda8d76d 5110 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5111 {
5112 header->e_shnum = filedata->section_headers[0].sh_size;
5113 printf (" (%u)", header->e_shnum);
5114 }
560f3c1c 5115 putc ('\n', stdout);
e8a64888
AM
5116 printf (_(" Section header string table index: %u"),
5117 header->e_shstrndx);
dda8d76d
NC
5118 if (filedata->section_headers != NULL
5119 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5120 {
5121 header->e_shstrndx = filedata->section_headers[0].sh_link;
5122 printf (" (%u)", header->e_shstrndx);
5123 }
5124 if (header->e_shstrndx != SHN_UNDEF
5125 && header->e_shstrndx >= header->e_shnum)
5126 {
5127 header->e_shstrndx = SHN_UNDEF;
5128 printf (_(" <corrupt: out of range>"));
5129 }
560f3c1c
AM
5130 putc ('\n', stdout);
5131 }
5132
dda8d76d 5133 if (filedata->section_headers != NULL)
560f3c1c 5134 {
dda8d76d
NC
5135 if (header->e_phnum == PN_XNUM
5136 && filedata->section_headers[0].sh_info != 0)
5137 header->e_phnum = filedata->section_headers[0].sh_info;
5138 if (header->e_shnum == SHN_UNDEF)
5139 header->e_shnum = filedata->section_headers[0].sh_size;
5140 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5141 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5142 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
5143 header->e_shstrndx = SHN_UNDEF;
5144 free (filedata->section_headers);
5145 filedata->section_headers = NULL;
252b5132 5146 }
103f02d3 5147
32ec8896 5148 return TRUE;
9ea033b2
NC
5149}
5150
dda8d76d
NC
5151/* Read in the program headers from FILEDATA and store them in PHEADERS.
5152 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5153
e0a31db1 5154static bfd_boolean
dda8d76d 5155get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5156{
2cf0635d
NC
5157 Elf32_External_Phdr * phdrs;
5158 Elf32_External_Phdr * external;
5159 Elf_Internal_Phdr * internal;
b34976b6 5160 unsigned int i;
dda8d76d
NC
5161 unsigned int size = filedata->file_header.e_phentsize;
5162 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5163
5164 /* PR binutils/17531: Cope with unexpected section header sizes. */
5165 if (size == 0 || num == 0)
5166 return FALSE;
5167 if (size < sizeof * phdrs)
5168 {
5169 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5170 return FALSE;
5171 }
5172 if (size > sizeof * phdrs)
5173 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5174
dda8d76d 5175 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5176 size, num, _("program headers"));
5177 if (phdrs == NULL)
5178 return FALSE;
9ea033b2 5179
91d6fa6a 5180 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5181 i < filedata->file_header.e_phnum;
b34976b6 5182 i++, internal++, external++)
252b5132 5183 {
9ea033b2
NC
5184 internal->p_type = BYTE_GET (external->p_type);
5185 internal->p_offset = BYTE_GET (external->p_offset);
5186 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5187 internal->p_paddr = BYTE_GET (external->p_paddr);
5188 internal->p_filesz = BYTE_GET (external->p_filesz);
5189 internal->p_memsz = BYTE_GET (external->p_memsz);
5190 internal->p_flags = BYTE_GET (external->p_flags);
5191 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5192 }
5193
9ea033b2 5194 free (phdrs);
e0a31db1 5195 return TRUE;
252b5132
RH
5196}
5197
dda8d76d
NC
5198/* Read in the program headers from FILEDATA and store them in PHEADERS.
5199 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5200
e0a31db1 5201static bfd_boolean
dda8d76d 5202get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5203{
2cf0635d
NC
5204 Elf64_External_Phdr * phdrs;
5205 Elf64_External_Phdr * external;
5206 Elf_Internal_Phdr * internal;
b34976b6 5207 unsigned int i;
dda8d76d
NC
5208 unsigned int size = filedata->file_header.e_phentsize;
5209 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5210
5211 /* PR binutils/17531: Cope with unexpected section header sizes. */
5212 if (size == 0 || num == 0)
5213 return FALSE;
5214 if (size < sizeof * phdrs)
5215 {
5216 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5217 return FALSE;
5218 }
5219 if (size > sizeof * phdrs)
5220 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5221
dda8d76d 5222 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5223 size, num, _("program headers"));
a6e9f9df 5224 if (!phdrs)
e0a31db1 5225 return FALSE;
9ea033b2 5226
91d6fa6a 5227 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5228 i < filedata->file_header.e_phnum;
b34976b6 5229 i++, internal++, external++)
9ea033b2
NC
5230 {
5231 internal->p_type = BYTE_GET (external->p_type);
5232 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5233 internal->p_offset = BYTE_GET (external->p_offset);
5234 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5235 internal->p_paddr = BYTE_GET (external->p_paddr);
5236 internal->p_filesz = BYTE_GET (external->p_filesz);
5237 internal->p_memsz = BYTE_GET (external->p_memsz);
5238 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5239 }
5240
5241 free (phdrs);
e0a31db1 5242 return TRUE;
9ea033b2 5243}
252b5132 5244
32ec8896 5245/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5246
32ec8896 5247static bfd_boolean
dda8d76d 5248get_program_headers (Filedata * filedata)
d93f0186 5249{
2cf0635d 5250 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5251
5252 /* Check cache of prior read. */
dda8d76d 5253 if (filedata->program_headers != NULL)
32ec8896 5254 return TRUE;
d93f0186 5255
82156ab7
NC
5256 /* Be kind to memory checkers by looking for
5257 e_phnum values which we know must be invalid. */
dda8d76d 5258 if (filedata->file_header.e_phnum
82156ab7 5259 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5260 >= filedata->file_size)
82156ab7
NC
5261 {
5262 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5263 filedata->file_header.e_phnum);
82156ab7
NC
5264 return FALSE;
5265 }
d93f0186 5266
dda8d76d 5267 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5268 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5269 if (phdrs == NULL)
5270 {
8b73c356 5271 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5272 filedata->file_header.e_phnum);
32ec8896 5273 return FALSE;
d93f0186
NC
5274 }
5275
5276 if (is_32bit_elf
dda8d76d
NC
5277 ? get_32bit_program_headers (filedata, phdrs)
5278 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5279 {
dda8d76d 5280 filedata->program_headers = phdrs;
32ec8896 5281 return TRUE;
d93f0186
NC
5282 }
5283
5284 free (phdrs);
32ec8896 5285 return FALSE;
d93f0186
NC
5286}
5287
32ec8896 5288/* Returns TRUE if the program headers were loaded. */
2f62977e 5289
32ec8896 5290static bfd_boolean
dda8d76d 5291process_program_headers (Filedata * filedata)
252b5132 5292{
2cf0635d 5293 Elf_Internal_Phdr * segment;
b34976b6 5294 unsigned int i;
1a9ccd70 5295 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5296
978c4450
AM
5297 filedata->dynamic_addr = 0;
5298 filedata->dynamic_size = 0;
663f67df 5299
dda8d76d 5300 if (filedata->file_header.e_phnum == 0)
252b5132 5301 {
82f2dbf7 5302 /* PR binutils/12467. */
dda8d76d 5303 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5304 {
5305 warn (_("possibly corrupt ELF header - it has a non-zero program"
5306 " header offset, but no program headers\n"));
5307 return FALSE;
5308 }
82f2dbf7 5309 else if (do_segments)
ca0e11aa
NC
5310 {
5311 if (filedata->is_separate)
5312 printf (_("\nThere are no program headers in linked file '%s'.\n"),
5313 filedata->file_name);
5314 else
5315 printf (_("\nThere are no program headers in this file.\n"));
5316 }
32ec8896 5317 return TRUE;
252b5132
RH
5318 }
5319
5320 if (do_segments && !do_header)
5321 {
ca0e11aa
NC
5322 if (filedata->is_separate)
5323 printf ("\nIn linked file '%s' the ELF file type is %s\n",
5324 filedata->file_name,
5325 get_file_type (filedata->file_header.e_type));
5326 else
5327 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
dda8d76d 5328 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5329 printf (ngettext ("There is %d program header, starting at offset %s\n",
5330 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5331 filedata->file_header.e_phnum),
5332 filedata->file_header.e_phnum,
5333 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5334 }
5335
dda8d76d 5336 if (! get_program_headers (filedata))
6b4bf3bc 5337 return TRUE;
103f02d3 5338
252b5132
RH
5339 if (do_segments)
5340 {
dda8d76d 5341 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5342 printf (_("\nProgram Headers:\n"));
5343 else
5344 printf (_("\nProgram Headers:\n"));
76da6bbe 5345
f7a99963
NC
5346 if (is_32bit_elf)
5347 printf
5348 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5349 else if (do_wide)
5350 printf
5351 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5352 else
5353 {
5354 printf
5355 (_(" Type Offset VirtAddr PhysAddr\n"));
5356 printf
5357 (_(" FileSiz MemSiz Flags Align\n"));
5358 }
252b5132
RH
5359 }
5360
dda8d76d
NC
5361 for (i = 0, segment = filedata->program_headers;
5362 i < filedata->file_header.e_phnum;
b34976b6 5363 i++, segment++)
252b5132
RH
5364 {
5365 if (do_segments)
5366 {
dda8d76d 5367 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5368
5369 if (is_32bit_elf)
5370 {
5371 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5372 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5373 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5374 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5375 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5376 printf ("%c%c%c ",
5377 (segment->p_flags & PF_R ? 'R' : ' '),
5378 (segment->p_flags & PF_W ? 'W' : ' '),
5379 (segment->p_flags & PF_X ? 'E' : ' '));
5380 printf ("%#lx", (unsigned long) segment->p_align);
5381 }
d974e256
JJ
5382 else if (do_wide)
5383 {
5384 if ((unsigned long) segment->p_offset == segment->p_offset)
5385 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5386 else
5387 {
5388 print_vma (segment->p_offset, FULL_HEX);
5389 putchar (' ');
5390 }
5391
5392 print_vma (segment->p_vaddr, FULL_HEX);
5393 putchar (' ');
5394 print_vma (segment->p_paddr, FULL_HEX);
5395 putchar (' ');
5396
5397 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5398 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5399 else
5400 {
5401 print_vma (segment->p_filesz, FULL_HEX);
5402 putchar (' ');
5403 }
5404
5405 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5406 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5407 else
5408 {
f48e6c45 5409 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5410 }
5411
5412 printf (" %c%c%c ",
5413 (segment->p_flags & PF_R ? 'R' : ' '),
5414 (segment->p_flags & PF_W ? 'W' : ' '),
5415 (segment->p_flags & PF_X ? 'E' : ' '));
5416
5417 if ((unsigned long) segment->p_align == segment->p_align)
5418 printf ("%#lx", (unsigned long) segment->p_align);
5419 else
5420 {
5421 print_vma (segment->p_align, PREFIX_HEX);
5422 }
5423 }
f7a99963
NC
5424 else
5425 {
5426 print_vma (segment->p_offset, FULL_HEX);
5427 putchar (' ');
5428 print_vma (segment->p_vaddr, FULL_HEX);
5429 putchar (' ');
5430 print_vma (segment->p_paddr, FULL_HEX);
5431 printf ("\n ");
5432 print_vma (segment->p_filesz, FULL_HEX);
5433 putchar (' ');
5434 print_vma (segment->p_memsz, FULL_HEX);
5435 printf (" %c%c%c ",
5436 (segment->p_flags & PF_R ? 'R' : ' '),
5437 (segment->p_flags & PF_W ? 'W' : ' '),
5438 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5439 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5440 }
252b5132 5441
1a9ccd70
NC
5442 putc ('\n', stdout);
5443 }
f54498b4 5444
252b5132
RH
5445 switch (segment->p_type)
5446 {
1a9ccd70 5447 case PT_LOAD:
502d895c
NC
5448#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5449 required by the ELF standard, several programs, including the Linux
5450 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5451 if (previous_load
5452 && previous_load->p_vaddr > segment->p_vaddr)
5453 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5454#endif
1a9ccd70
NC
5455 if (segment->p_memsz < segment->p_filesz)
5456 error (_("the segment's file size is larger than its memory size\n"));
5457 previous_load = segment;
5458 break;
5459
5460 case PT_PHDR:
5461 /* PR 20815 - Verify that the program header is loaded into memory. */
5462 if (i > 0 && previous_load != NULL)
5463 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5464 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5465 {
5466 unsigned int j;
5467
dda8d76d 5468 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5469 {
5470 Elf_Internal_Phdr *load = filedata->program_headers + j;
5471 if (load->p_type == PT_LOAD
5472 && load->p_offset <= segment->p_offset
5473 && (load->p_offset + load->p_filesz
5474 >= segment->p_offset + segment->p_filesz)
5475 && load->p_vaddr <= segment->p_vaddr
5476 && (load->p_vaddr + load->p_filesz
5477 >= segment->p_vaddr + segment->p_filesz))
5478 break;
5479 }
dda8d76d 5480 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5481 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5482 }
5483 break;
5484
252b5132 5485 case PT_DYNAMIC:
978c4450 5486 if (filedata->dynamic_addr)
252b5132
RH
5487 error (_("more than one dynamic segment\n"));
5488
20737c13
AM
5489 /* By default, assume that the .dynamic section is the first
5490 section in the DYNAMIC segment. */
978c4450
AM
5491 filedata->dynamic_addr = segment->p_offset;
5492 filedata->dynamic_size = segment->p_filesz;
20737c13 5493
b2d38a17
NC
5494 /* Try to locate the .dynamic section. If there is
5495 a section header table, we can easily locate it. */
dda8d76d 5496 if (filedata->section_headers != NULL)
b2d38a17 5497 {
2cf0635d 5498 Elf_Internal_Shdr * sec;
b2d38a17 5499
dda8d76d 5500 sec = find_section (filedata, ".dynamic");
89fac5e3 5501 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5502 {
28f997cf
TG
5503 /* A corresponding .dynamic section is expected, but on
5504 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5505 if (!is_ia64_vms (filedata))
28f997cf 5506 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5507 break;
5508 }
5509
42bb2e33 5510 if (sec->sh_type == SHT_NOBITS)
20737c13 5511 {
978c4450 5512 filedata->dynamic_size = 0;
20737c13
AM
5513 break;
5514 }
42bb2e33 5515
978c4450
AM
5516 filedata->dynamic_addr = sec->sh_offset;
5517 filedata->dynamic_size = sec->sh_size;
b2d38a17 5518
8ac10c5b
L
5519 /* The PT_DYNAMIC segment, which is used by the run-time
5520 loader, should exactly match the .dynamic section. */
5521 if (do_checks
5522 && (filedata->dynamic_addr != segment->p_offset
5523 || filedata->dynamic_size != segment->p_filesz))
5524 warn (_("\
5525the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 5526 }
39e224f6
MW
5527
5528 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5529 segment. Check this after matching against the section headers
5530 so we don't warn on debuginfo file (which have NOBITS .dynamic
5531 sections). */
978c4450
AM
5532 if (filedata->dynamic_addr > filedata->file_size
5533 || (filedata->dynamic_size
5534 > filedata->file_size - filedata->dynamic_addr))
39e224f6
MW
5535 {
5536 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
978c4450 5537 filedata->dynamic_addr = filedata->dynamic_size = 0;
39e224f6 5538 }
252b5132
RH
5539 break;
5540
5541 case PT_INTERP:
978c4450
AM
5542 if (fseek (filedata->handle,
5543 filedata->archive_file_offset + (long) segment->p_offset,
fb52b2f4 5544 SEEK_SET))
252b5132
RH
5545 error (_("Unable to find program interpreter name\n"));
5546 else
5547 {
f8eae8b2 5548 char fmt [32];
9495b2e6 5549 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
5550
5551 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 5552 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 5553
978c4450
AM
5554 filedata->program_interpreter[0] = 0;
5555 if (fscanf (filedata->handle, fmt,
5556 filedata->program_interpreter) <= 0)
7bd7b3ef 5557 error (_("Unable to read program interpreter name\n"));
252b5132
RH
5558
5559 if (do_segments)
f54498b4 5560 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 5561 filedata->program_interpreter);
252b5132
RH
5562 }
5563 break;
5564 }
252b5132
RH
5565 }
5566
dda8d76d
NC
5567 if (do_segments
5568 && filedata->section_headers != NULL
5569 && filedata->string_table != NULL)
252b5132
RH
5570 {
5571 printf (_("\n Section to Segment mapping:\n"));
5572 printf (_(" Segment Sections...\n"));
5573
dda8d76d 5574 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5575 {
9ad5cbcf 5576 unsigned int j;
2cf0635d 5577 Elf_Internal_Shdr * section;
252b5132 5578
dda8d76d
NC
5579 segment = filedata->program_headers + i;
5580 section = filedata->section_headers + 1;
252b5132
RH
5581
5582 printf (" %2.2d ", i);
5583
dda8d76d 5584 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5585 {
f4638467
AM
5586 if (!ELF_TBSS_SPECIAL (section, segment)
5587 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5588 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5589 }
5590
5591 putc ('\n',stdout);
5592 }
5593 }
5594
32ec8896 5595 return TRUE;
252b5132
RH
5596}
5597
5598
d93f0186
NC
5599/* Find the file offset corresponding to VMA by using the program headers. */
5600
5601static long
dda8d76d 5602offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5603{
2cf0635d 5604 Elf_Internal_Phdr * seg;
d93f0186 5605
dda8d76d 5606 if (! get_program_headers (filedata))
d93f0186
NC
5607 {
5608 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5609 return (long) vma;
5610 }
5611
dda8d76d
NC
5612 for (seg = filedata->program_headers;
5613 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5614 ++seg)
5615 {
5616 if (seg->p_type != PT_LOAD)
5617 continue;
5618
5619 if (vma >= (seg->p_vaddr & -seg->p_align)
5620 && vma + size <= seg->p_vaddr + seg->p_filesz)
5621 return vma - seg->p_vaddr + seg->p_offset;
5622 }
5623
5624 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5625 (unsigned long) vma);
d93f0186
NC
5626 return (long) vma;
5627}
5628
5629
dda8d76d
NC
5630/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5631 If PROBE is true, this is just a probe and we do not generate any error
5632 messages if the load fails. */
049b0c3a
NC
5633
5634static bfd_boolean
dda8d76d 5635get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
252b5132 5636{
2cf0635d
NC
5637 Elf32_External_Shdr * shdrs;
5638 Elf_Internal_Shdr * internal;
dda8d76d
NC
5639 unsigned int i;
5640 unsigned int size = filedata->file_header.e_shentsize;
5641 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5642
5643 /* PR binutils/17531: Cope with unexpected section header sizes. */
5644 if (size == 0 || num == 0)
5645 return FALSE;
5646 if (size < sizeof * shdrs)
5647 {
5648 if (! probe)
5649 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5650 return FALSE;
5651 }
5652 if (!probe && size > sizeof * shdrs)
5653 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5654
dda8d76d 5655 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5656 size, num,
5657 probe ? NULL : _("section headers"));
5658 if (shdrs == NULL)
5659 return FALSE;
252b5132 5660
dda8d76d
NC
5661 free (filedata->section_headers);
5662 filedata->section_headers = (Elf_Internal_Shdr *)
5663 cmalloc (num, sizeof (Elf_Internal_Shdr));
5664 if (filedata->section_headers == NULL)
252b5132 5665 {
049b0c3a 5666 if (!probe)
8b73c356 5667 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5668 free (shdrs);
049b0c3a 5669 return FALSE;
252b5132
RH
5670 }
5671
dda8d76d 5672 for (i = 0, internal = filedata->section_headers;
560f3c1c 5673 i < num;
b34976b6 5674 i++, internal++)
252b5132
RH
5675 {
5676 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5677 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5678 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5679 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5680 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5681 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5682 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5683 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5684 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5685 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5686 if (!probe && internal->sh_link > num)
5687 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5688 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5689 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5690 }
5691
5692 free (shdrs);
049b0c3a 5693 return TRUE;
252b5132
RH
5694}
5695
dda8d76d
NC
5696/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5697
049b0c3a 5698static bfd_boolean
dda8d76d 5699get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
9ea033b2 5700{
dda8d76d
NC
5701 Elf64_External_Shdr * shdrs;
5702 Elf_Internal_Shdr * internal;
5703 unsigned int i;
5704 unsigned int size = filedata->file_header.e_shentsize;
5705 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5706
5707 /* PR binutils/17531: Cope with unexpected section header sizes. */
5708 if (size == 0 || num == 0)
5709 return FALSE;
dda8d76d 5710
049b0c3a
NC
5711 if (size < sizeof * shdrs)
5712 {
5713 if (! probe)
5714 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5715 return FALSE;
5716 }
dda8d76d 5717
049b0c3a
NC
5718 if (! probe && size > sizeof * shdrs)
5719 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5720
dda8d76d
NC
5721 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5722 filedata->file_header.e_shoff,
049b0c3a
NC
5723 size, num,
5724 probe ? NULL : _("section headers"));
5725 if (shdrs == NULL)
5726 return FALSE;
9ea033b2 5727
dda8d76d
NC
5728 free (filedata->section_headers);
5729 filedata->section_headers = (Elf_Internal_Shdr *)
5730 cmalloc (num, sizeof (Elf_Internal_Shdr));
5731 if (filedata->section_headers == NULL)
9ea033b2 5732 {
049b0c3a 5733 if (! probe)
8b73c356 5734 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5735 free (shdrs);
049b0c3a 5736 return FALSE;
9ea033b2
NC
5737 }
5738
dda8d76d 5739 for (i = 0, internal = filedata->section_headers;
560f3c1c 5740 i < num;
b34976b6 5741 i++, internal++)
9ea033b2
NC
5742 {
5743 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5744 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5745 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5746 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5747 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5748 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5749 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5750 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5751 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5752 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5753 if (!probe && internal->sh_link > num)
5754 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5755 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5756 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5757 }
5758
5759 free (shdrs);
049b0c3a 5760 return TRUE;
9ea033b2
NC
5761}
5762
252b5132 5763static Elf_Internal_Sym *
dda8d76d
NC
5764get_32bit_elf_symbols (Filedata * filedata,
5765 Elf_Internal_Shdr * section,
5766 unsigned long * num_syms_return)
252b5132 5767{
ba5cdace 5768 unsigned long number = 0;
dd24e3da 5769 Elf32_External_Sym * esyms = NULL;
ba5cdace 5770 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5771 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5772 Elf_Internal_Sym * psym;
b34976b6 5773 unsigned int j;
e3d39609 5774 elf_section_list * entry;
252b5132 5775
c9c1d674
EG
5776 if (section->sh_size == 0)
5777 {
5778 if (num_syms_return != NULL)
5779 * num_syms_return = 0;
5780 return NULL;
5781 }
5782
dd24e3da 5783 /* Run some sanity checks first. */
c9c1d674 5784 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5785 {
c9c1d674 5786 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5787 printable_section_name (filedata, section),
5788 (unsigned long) section->sh_entsize);
ba5cdace 5789 goto exit_point;
dd24e3da
NC
5790 }
5791
dda8d76d 5792 if (section->sh_size > filedata->file_size)
f54498b4
NC
5793 {
5794 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5795 printable_section_name (filedata, section),
5796 (unsigned long) section->sh_size);
f54498b4
NC
5797 goto exit_point;
5798 }
5799
dd24e3da
NC
5800 number = section->sh_size / section->sh_entsize;
5801
5802 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5803 {
c9c1d674 5804 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5805 (unsigned long) section->sh_size,
dda8d76d 5806 printable_section_name (filedata, section),
8066deb1 5807 (unsigned long) section->sh_entsize);
ba5cdace 5808 goto exit_point;
dd24e3da
NC
5809 }
5810
dda8d76d 5811 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5812 section->sh_size, _("symbols"));
dd24e3da 5813 if (esyms == NULL)
ba5cdace 5814 goto exit_point;
252b5132 5815
e3d39609 5816 shndx = NULL;
978c4450 5817 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5818 {
5819 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5820 continue;
5821
5822 if (shndx != NULL)
5823 {
5824 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5825 free (shndx);
5826 }
5827
5828 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5829 entry->hdr->sh_offset,
5830 1, entry->hdr->sh_size,
5831 _("symbol table section indices"));
5832 if (shndx == NULL)
5833 goto exit_point;
5834
5835 /* PR17531: file: heap-buffer-overflow */
5836 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5837 {
5838 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5839 printable_section_name (filedata, entry->hdr),
5840 (unsigned long) entry->hdr->sh_size,
5841 (unsigned long) section->sh_size);
5842 goto exit_point;
c9c1d674 5843 }
e3d39609 5844 }
9ad5cbcf 5845
3f5e193b 5846 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5847
5848 if (isyms == NULL)
5849 {
8b73c356
NC
5850 error (_("Out of memory reading %lu symbols\n"),
5851 (unsigned long) number);
dd24e3da 5852 goto exit_point;
252b5132
RH
5853 }
5854
dd24e3da 5855 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5856 {
5857 psym->st_name = BYTE_GET (esyms[j].st_name);
5858 psym->st_value = BYTE_GET (esyms[j].st_value);
5859 psym->st_size = BYTE_GET (esyms[j].st_size);
5860 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5861 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5862 psym->st_shndx
5863 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5864 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5865 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5866 psym->st_info = BYTE_GET (esyms[j].st_info);
5867 psym->st_other = BYTE_GET (esyms[j].st_other);
5868 }
5869
dd24e3da 5870 exit_point:
e3d39609
NC
5871 free (shndx);
5872 free (esyms);
252b5132 5873
ba5cdace
NC
5874 if (num_syms_return != NULL)
5875 * num_syms_return = isyms == NULL ? 0 : number;
5876
252b5132
RH
5877 return isyms;
5878}
5879
9ea033b2 5880static Elf_Internal_Sym *
dda8d76d
NC
5881get_64bit_elf_symbols (Filedata * filedata,
5882 Elf_Internal_Shdr * section,
5883 unsigned long * num_syms_return)
9ea033b2 5884{
ba5cdace
NC
5885 unsigned long number = 0;
5886 Elf64_External_Sym * esyms = NULL;
5887 Elf_External_Sym_Shndx * shndx = NULL;
5888 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5889 Elf_Internal_Sym * psym;
b34976b6 5890 unsigned int j;
e3d39609 5891 elf_section_list * entry;
9ea033b2 5892
c9c1d674
EG
5893 if (section->sh_size == 0)
5894 {
5895 if (num_syms_return != NULL)
5896 * num_syms_return = 0;
5897 return NULL;
5898 }
5899
dd24e3da 5900 /* Run some sanity checks first. */
c9c1d674 5901 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5902 {
c9c1d674 5903 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5904 printable_section_name (filedata, section),
8066deb1 5905 (unsigned long) section->sh_entsize);
ba5cdace 5906 goto exit_point;
dd24e3da
NC
5907 }
5908
dda8d76d 5909 if (section->sh_size > filedata->file_size)
f54498b4
NC
5910 {
5911 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5912 printable_section_name (filedata, section),
8066deb1 5913 (unsigned long) section->sh_size);
f54498b4
NC
5914 goto exit_point;
5915 }
5916
dd24e3da
NC
5917 number = section->sh_size / section->sh_entsize;
5918
5919 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5920 {
c9c1d674 5921 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5922 (unsigned long) section->sh_size,
dda8d76d 5923 printable_section_name (filedata, section),
8066deb1 5924 (unsigned long) section->sh_entsize);
ba5cdace 5925 goto exit_point;
dd24e3da
NC
5926 }
5927
dda8d76d 5928 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5929 section->sh_size, _("symbols"));
a6e9f9df 5930 if (!esyms)
ba5cdace 5931 goto exit_point;
9ea033b2 5932
e3d39609 5933 shndx = NULL;
978c4450 5934 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5935 {
5936 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5937 continue;
5938
5939 if (shndx != NULL)
5940 {
5941 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5942 free (shndx);
c9c1d674 5943 }
e3d39609
NC
5944
5945 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5946 entry->hdr->sh_offset,
5947 1, entry->hdr->sh_size,
5948 _("symbol table section indices"));
5949 if (shndx == NULL)
5950 goto exit_point;
5951
5952 /* PR17531: file: heap-buffer-overflow */
5953 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5954 {
5955 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5956 printable_section_name (filedata, entry->hdr),
5957 (unsigned long) entry->hdr->sh_size,
5958 (unsigned long) section->sh_size);
5959 goto exit_point;
5960 }
5961 }
9ad5cbcf 5962
3f5e193b 5963 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5964
5965 if (isyms == NULL)
5966 {
8b73c356
NC
5967 error (_("Out of memory reading %lu symbols\n"),
5968 (unsigned long) number);
ba5cdace 5969 goto exit_point;
9ea033b2
NC
5970 }
5971
ba5cdace 5972 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5973 {
5974 psym->st_name = BYTE_GET (esyms[j].st_name);
5975 psym->st_info = BYTE_GET (esyms[j].st_info);
5976 psym->st_other = BYTE_GET (esyms[j].st_other);
5977 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5978
4fbb74a6 5979 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5980 psym->st_shndx
5981 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5982 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5983 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5984
66543521
AM
5985 psym->st_value = BYTE_GET (esyms[j].st_value);
5986 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5987 }
5988
ba5cdace 5989 exit_point:
e3d39609
NC
5990 free (shndx);
5991 free (esyms);
ba5cdace
NC
5992
5993 if (num_syms_return != NULL)
5994 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5995
5996 return isyms;
5997}
5998
d1133906 5999static const char *
dda8d76d 6000get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 6001{
5477e8a0 6002 static char buff[1024];
2cf0635d 6003 char * p = buff;
32ec8896
NC
6004 unsigned int field_size = is_32bit_elf ? 8 : 16;
6005 signed int sindex;
6006 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
6007 bfd_vma os_flags = 0;
6008 bfd_vma proc_flags = 0;
6009 bfd_vma unknown_flags = 0;
148b93f2 6010 static const struct
5477e8a0 6011 {
2cf0635d 6012 const char * str;
32ec8896 6013 unsigned int len;
5477e8a0
L
6014 }
6015 flags [] =
6016 {
cfcac11d
NC
6017 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6018 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6019 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6020 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6021 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6022 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6023 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6024 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6025 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6026 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6027 /* IA-64 specific. */
6028 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6029 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6030 /* IA-64 OpenVMS specific. */
6031 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6032 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6033 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6034 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6035 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6036 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6037 /* Generic. */
cfcac11d 6038 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6039 /* SPARC specific. */
77115a4a 6040 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6041 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6042 /* ARM specific. */
6043 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6044 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6045 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6046 /* GNU specific. */
6047 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6048 /* VLE specific. */
6049 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6050 /* GNU specific. */
6051 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6052 };
6053
6054 if (do_section_details)
6055 {
8d5ff12c
L
6056 sprintf (buff, "[%*.*lx]: ",
6057 field_size, field_size, (unsigned long) sh_flags);
6058 p += field_size + 4;
5477e8a0 6059 }
76da6bbe 6060
d1133906
NC
6061 while (sh_flags)
6062 {
6063 bfd_vma flag;
6064
6065 flag = sh_flags & - sh_flags;
6066 sh_flags &= ~ flag;
76da6bbe 6067
5477e8a0 6068 if (do_section_details)
d1133906 6069 {
5477e8a0
L
6070 switch (flag)
6071 {
91d6fa6a
NC
6072 case SHF_WRITE: sindex = 0; break;
6073 case SHF_ALLOC: sindex = 1; break;
6074 case SHF_EXECINSTR: sindex = 2; break;
6075 case SHF_MERGE: sindex = 3; break;
6076 case SHF_STRINGS: sindex = 4; break;
6077 case SHF_INFO_LINK: sindex = 5; break;
6078 case SHF_LINK_ORDER: sindex = 6; break;
6079 case SHF_OS_NONCONFORMING: sindex = 7; break;
6080 case SHF_GROUP: sindex = 8; break;
6081 case SHF_TLS: sindex = 9; break;
18ae9cc1 6082 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6083 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6084
5477e8a0 6085 default:
91d6fa6a 6086 sindex = -1;
dda8d76d 6087 switch (filedata->file_header.e_machine)
148b93f2 6088 {
cfcac11d 6089 case EM_IA_64:
148b93f2 6090 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6091 sindex = 10;
148b93f2 6092 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6093 sindex = 11;
148b93f2 6094#ifdef BFD64
dda8d76d 6095 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6096 switch (flag)
6097 {
91d6fa6a
NC
6098 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6099 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6100 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6101 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6102 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6103 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6104 default: break;
6105 }
6106#endif
cfcac11d
NC
6107 break;
6108
caa83f8b 6109 case EM_386:
22abe556 6110 case EM_IAMCU:
caa83f8b 6111 case EM_X86_64:
7f502d6c 6112 case EM_L1OM:
7a9068fe 6113 case EM_K1OM:
cfcac11d
NC
6114 case EM_OLD_SPARCV9:
6115 case EM_SPARC32PLUS:
6116 case EM_SPARCV9:
6117 case EM_SPARC:
18ae9cc1 6118 if (flag == SHF_ORDERED)
91d6fa6a 6119 sindex = 19;
cfcac11d 6120 break;
ac4c9b04
MG
6121
6122 case EM_ARM:
6123 switch (flag)
6124 {
6125 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6126 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6127 case SHF_COMDEF: sindex = 23; break;
6128 default: break;
6129 }
6130 break;
83eef883
AFB
6131 case EM_PPC:
6132 if (flag == SHF_PPC_VLE)
6133 sindex = 25;
6134 break;
99fabbc9
JL
6135 default:
6136 break;
6137 }
ac4c9b04 6138
99fabbc9
JL
6139 switch (filedata->file_header.e_ident[EI_OSABI])
6140 {
6141 case ELFOSABI_GNU:
6142 case ELFOSABI_FREEBSD:
6143 if (flag == SHF_GNU_RETAIN)
6144 sindex = 26;
6145 /* Fall through */
6146 case ELFOSABI_NONE:
6147 if (flag == SHF_GNU_MBIND)
6148 /* We should not recognize SHF_GNU_MBIND for
6149 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6150 not set the EI_OSABI header byte. */
6151 sindex = 24;
6152 break;
cfcac11d
NC
6153 default:
6154 break;
148b93f2 6155 }
99fabbc9 6156 break;
5477e8a0
L
6157 }
6158
91d6fa6a 6159 if (sindex != -1)
5477e8a0 6160 {
8d5ff12c
L
6161 if (p != buff + field_size + 4)
6162 {
6163 if (size < (10 + 2))
bee0ee85
NC
6164 {
6165 warn (_("Internal error: not enough buffer room for section flag info"));
6166 return _("<unknown>");
6167 }
8d5ff12c
L
6168 size -= 2;
6169 *p++ = ',';
6170 *p++ = ' ';
6171 }
6172
91d6fa6a
NC
6173 size -= flags [sindex].len;
6174 p = stpcpy (p, flags [sindex].str);
5477e8a0 6175 }
3b22753a 6176 else if (flag & SHF_MASKOS)
8d5ff12c 6177 os_flags |= flag;
d1133906 6178 else if (flag & SHF_MASKPROC)
8d5ff12c 6179 proc_flags |= flag;
d1133906 6180 else
8d5ff12c 6181 unknown_flags |= flag;
5477e8a0
L
6182 }
6183 else
6184 {
6185 switch (flag)
6186 {
6187 case SHF_WRITE: *p = 'W'; break;
6188 case SHF_ALLOC: *p = 'A'; break;
6189 case SHF_EXECINSTR: *p = 'X'; break;
6190 case SHF_MERGE: *p = 'M'; break;
6191 case SHF_STRINGS: *p = 'S'; break;
6192 case SHF_INFO_LINK: *p = 'I'; break;
6193 case SHF_LINK_ORDER: *p = 'L'; break;
6194 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6195 case SHF_GROUP: *p = 'G'; break;
6196 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6197 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6198 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6199
6200 default:
dda8d76d
NC
6201 if ((filedata->file_header.e_machine == EM_X86_64
6202 || filedata->file_header.e_machine == EM_L1OM
6203 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6204 && flag == SHF_X86_64_LARGE)
6205 *p = 'l';
dda8d76d 6206 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6207 && flag == SHF_ARM_PURECODE)
99fabbc9 6208 *p = 'y';
dda8d76d 6209 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6210 && flag == SHF_PPC_VLE)
99fabbc9 6211 *p = 'v';
5477e8a0
L
6212 else if (flag & SHF_MASKOS)
6213 {
99fabbc9
JL
6214 switch (filedata->file_header.e_ident[EI_OSABI])
6215 {
6216 case ELFOSABI_GNU:
6217 case ELFOSABI_FREEBSD:
6218 if (flag == SHF_GNU_RETAIN)
6219 {
6220 *p = 'R';
6221 break;
6222 }
6223 /* Fall through */
6224 case ELFOSABI_NONE:
6225 if (flag == SHF_GNU_MBIND)
6226 {
6227 /* We should not recognize SHF_GNU_MBIND for
6228 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6229 not set the EI_OSABI header byte. */
6230 *p = 'D';
6231 break;
6232 }
6233 /* Fall through */
6234 default:
6235 *p = 'o';
6236 sh_flags &= ~SHF_MASKOS;
6237 break;
6238 }
5477e8a0
L
6239 }
6240 else if (flag & SHF_MASKPROC)
6241 {
6242 *p = 'p';
6243 sh_flags &= ~ SHF_MASKPROC;
6244 }
6245 else
6246 *p = 'x';
6247 break;
6248 }
6249 p++;
d1133906
NC
6250 }
6251 }
76da6bbe 6252
8d5ff12c
L
6253 if (do_section_details)
6254 {
6255 if (os_flags)
6256 {
6257 size -= 5 + field_size;
6258 if (p != buff + field_size + 4)
6259 {
6260 if (size < (2 + 1))
bee0ee85
NC
6261 {
6262 warn (_("Internal error: not enough buffer room for section flag info"));
6263 return _("<unknown>");
6264 }
8d5ff12c
L
6265 size -= 2;
6266 *p++ = ',';
6267 *p++ = ' ';
6268 }
6269 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6270 (unsigned long) os_flags);
6271 p += 5 + field_size;
6272 }
6273 if (proc_flags)
6274 {
6275 size -= 7 + field_size;
6276 if (p != buff + field_size + 4)
6277 {
6278 if (size < (2 + 1))
bee0ee85
NC
6279 {
6280 warn (_("Internal error: not enough buffer room for section flag info"));
6281 return _("<unknown>");
6282 }
8d5ff12c
L
6283 size -= 2;
6284 *p++ = ',';
6285 *p++ = ' ';
6286 }
6287 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6288 (unsigned long) proc_flags);
6289 p += 7 + field_size;
6290 }
6291 if (unknown_flags)
6292 {
6293 size -= 10 + field_size;
6294 if (p != buff + field_size + 4)
6295 {
6296 if (size < (2 + 1))
bee0ee85
NC
6297 {
6298 warn (_("Internal error: not enough buffer room for section flag info"));
6299 return _("<unknown>");
6300 }
8d5ff12c
L
6301 size -= 2;
6302 *p++ = ',';
6303 *p++ = ' ';
6304 }
2b692964 6305 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6306 (unsigned long) unknown_flags);
6307 p += 10 + field_size;
6308 }
6309 }
6310
e9e44622 6311 *p = '\0';
d1133906
NC
6312 return buff;
6313}
6314
5844b465 6315static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6316get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6317{
6318 if (is_32bit_elf)
6319 {
6320 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6321
ebdf1ebf
NC
6322 if (size < sizeof (* echdr))
6323 {
6324 error (_("Compressed section is too small even for a compression header\n"));
6325 return 0;
6326 }
6327
77115a4a
L
6328 chdr->ch_type = BYTE_GET (echdr->ch_type);
6329 chdr->ch_size = BYTE_GET (echdr->ch_size);
6330 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6331 return sizeof (*echdr);
6332 }
6333 else
6334 {
6335 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6336
ebdf1ebf
NC
6337 if (size < sizeof (* echdr))
6338 {
6339 error (_("Compressed section is too small even for a compression header\n"));
6340 return 0;
6341 }
6342
77115a4a
L
6343 chdr->ch_type = BYTE_GET (echdr->ch_type);
6344 chdr->ch_size = BYTE_GET (echdr->ch_size);
6345 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6346 return sizeof (*echdr);
6347 }
6348}
6349
32ec8896 6350static bfd_boolean
dda8d76d 6351process_section_headers (Filedata * filedata)
252b5132 6352{
2cf0635d 6353 Elf_Internal_Shdr * section;
b34976b6 6354 unsigned int i;
252b5132 6355
8fb879cd 6356 free (filedata->section_headers);
dda8d76d 6357 filedata->section_headers = NULL;
978c4450
AM
6358 free (filedata->dynamic_symbols);
6359 filedata->dynamic_symbols = NULL;
6360 filedata->num_dynamic_syms = 0;
6361 free (filedata->dynamic_strings);
6362 filedata->dynamic_strings = NULL;
6363 filedata->dynamic_strings_length = 0;
6364 free (filedata->dynamic_syminfo);
6365 filedata->dynamic_syminfo = NULL;
6366 while (filedata->symtab_shndx_list != NULL)
8ff66993 6367 {
978c4450
AM
6368 elf_section_list *next = filedata->symtab_shndx_list->next;
6369 free (filedata->symtab_shndx_list);
6370 filedata->symtab_shndx_list = next;
8ff66993 6371 }
252b5132 6372
dda8d76d 6373 if (filedata->file_header.e_shnum == 0)
252b5132 6374 {
82f2dbf7 6375 /* PR binutils/12467. */
dda8d76d 6376 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6377 {
6378 warn (_("possibly corrupt ELF file header - it has a non-zero"
6379 " section header offset, but no section headers\n"));
6380 return FALSE;
6381 }
82f2dbf7 6382 else if (do_sections)
252b5132
RH
6383 printf (_("\nThere are no sections in this file.\n"));
6384
32ec8896 6385 return TRUE;
252b5132
RH
6386 }
6387
6388 if (do_sections && !do_header)
ca0e11aa
NC
6389 {
6390 if (filedata->is_separate && process_links)
6391 printf (_("In linked file '%s': "), filedata->file_name);
6392 if (! filedata->is_separate || process_links)
6393 printf (ngettext ("There is %d section header, "
6394 "starting at offset 0x%lx:\n",
6395 "There are %d section headers, "
6396 "starting at offset 0x%lx:\n",
6397 filedata->file_header.e_shnum),
6398 filedata->file_header.e_shnum,
6399 (unsigned long) filedata->file_header.e_shoff);
6400 }
252b5132 6401
9ea033b2
NC
6402 if (is_32bit_elf)
6403 {
dda8d76d 6404 if (! get_32bit_section_headers (filedata, FALSE))
32ec8896
NC
6405 return FALSE;
6406 }
6407 else
6408 {
dda8d76d 6409 if (! get_64bit_section_headers (filedata, FALSE))
32ec8896 6410 return FALSE;
9ea033b2 6411 }
252b5132
RH
6412
6413 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6414 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6415 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6416 {
dda8d76d 6417 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6418
c256ffe7
JJ
6419 if (section->sh_size != 0)
6420 {
dda8d76d
NC
6421 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6422 1, section->sh_size,
6423 _("string table"));
0de14b54 6424
dda8d76d 6425 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6426 }
252b5132
RH
6427 }
6428
6429 /* Scan the sections for the dynamic symbol table
e3c8793a 6430 and dynamic string table and debug sections. */
89fac5e3 6431 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6432 switch (filedata->file_header.e_machine)
89fac5e3
RS
6433 {
6434 case EM_MIPS:
6435 case EM_MIPS_RS3_LE:
6436 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6437 FDE addresses. However, the ABI also has a semi-official ILP32
6438 variant for which the normal FDE address size rules apply.
6439
6440 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6441 section, where XX is the size of longs in bits. Unfortunately,
6442 earlier compilers provided no way of distinguishing ILP32 objects
6443 from LP64 objects, so if there's any doubt, we should assume that
6444 the official LP64 form is being used. */
dda8d76d
NC
6445 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6446 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6447 eh_addr_size = 8;
6448 break;
0f56a26a
DD
6449
6450 case EM_H8_300:
6451 case EM_H8_300H:
dda8d76d 6452 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6453 {
6454 case E_H8_MACH_H8300:
6455 case E_H8_MACH_H8300HN:
6456 case E_H8_MACH_H8300SN:
6457 case E_H8_MACH_H8300SXN:
6458 eh_addr_size = 2;
6459 break;
6460 case E_H8_MACH_H8300H:
6461 case E_H8_MACH_H8300S:
6462 case E_H8_MACH_H8300SX:
6463 eh_addr_size = 4;
6464 break;
6465 }
f4236fe4
DD
6466 break;
6467
ff7eeb89 6468 case EM_M32C_OLD:
f4236fe4 6469 case EM_M32C:
dda8d76d 6470 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6471 {
6472 case EF_M32C_CPU_M16C:
6473 eh_addr_size = 2;
6474 break;
6475 }
6476 break;
89fac5e3
RS
6477 }
6478
76ca31c0
NC
6479#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6480 do \
6481 { \
6482 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6483 if (section->sh_entsize != expected_entsize) \
9dd3a467 6484 { \
76ca31c0
NC
6485 char buf[40]; \
6486 sprintf_vma (buf, section->sh_entsize); \
6487 /* Note: coded this way so that there is a single string for \
6488 translation. */ \
6489 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6490 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6491 (unsigned) expected_entsize); \
9dd3a467 6492 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6493 } \
6494 } \
08d8fa11 6495 while (0)
9dd3a467
NC
6496
6497#define CHECK_ENTSIZE(section, i, type) \
1b513401 6498 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
6499 sizeof (Elf64_External_##type))
6500
dda8d76d
NC
6501 for (i = 0, section = filedata->section_headers;
6502 i < filedata->file_header.e_shnum;
b34976b6 6503 i++, section++)
252b5132 6504 {
b9e920ec 6505 char * name = SECTION_NAME_PRINT (section);
252b5132 6506
1b513401
NC
6507 /* Run some sanity checks on the headers and
6508 possibly fill in some file data as well. */
6509 switch (section->sh_type)
252b5132 6510 {
1b513401 6511 case SHT_DYNSYM:
978c4450 6512 if (filedata->dynamic_symbols != NULL)
252b5132
RH
6513 {
6514 error (_("File contains multiple dynamic symbol tables\n"));
6515 continue;
6516 }
6517
08d8fa11 6518 CHECK_ENTSIZE (section, i, Sym);
978c4450
AM
6519 filedata->dynamic_symbols
6520 = GET_ELF_SYMBOLS (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 6521 filedata->dynamic_symtab_section = section;
1b513401
NC
6522 break;
6523
6524 case SHT_STRTAB:
6525 if (streq (name, ".dynstr"))
252b5132 6526 {
1b513401
NC
6527 if (filedata->dynamic_strings != NULL)
6528 {
6529 error (_("File contains multiple dynamic string tables\n"));
6530 continue;
6531 }
6532
6533 filedata->dynamic_strings
6534 = (char *) get_data (NULL, filedata, section->sh_offset,
6535 1, section->sh_size, _("dynamic strings"));
6536 filedata->dynamic_strings_length
6537 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 6538 filedata->dynamic_strtab_section = section;
252b5132 6539 }
1b513401
NC
6540 break;
6541
6542 case SHT_SYMTAB_SHNDX:
6543 {
6544 elf_section_list * entry = xmalloc (sizeof * entry);
6545
6546 entry->hdr = section;
6547 entry->next = filedata->symtab_shndx_list;
6548 filedata->symtab_shndx_list = entry;
6549 }
6550 break;
6551
6552 case SHT_SYMTAB:
6553 CHECK_ENTSIZE (section, i, Sym);
6554 break;
6555
6556 case SHT_GROUP:
6557 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6558 break;
252b5132 6559
1b513401
NC
6560 case SHT_REL:
6561 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 6562 if (do_checks && section->sh_size == 0)
1b513401
NC
6563 warn (_("Section '%s': zero-sized relocation section\n"), name);
6564 break;
6565
6566 case SHT_RELA:
6567 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 6568 if (do_checks && section->sh_size == 0)
1b513401
NC
6569 warn (_("Section '%s': zero-sized relocation section\n"), name);
6570 break;
6571
6572 case SHT_NOTE:
6573 case SHT_PROGBITS:
546cb2d8
NC
6574 /* Having a zero sized section is not illegal according to the
6575 ELF standard, but it might be an indication that something
6576 is wrong. So issue a warning if we are running in lint mode. */
6577 if (do_checks && section->sh_size == 0)
1b513401
NC
6578 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
6579 break;
6580
6581 default:
6582 break;
6583 }
6584
6585 if ((do_debugging || do_debug_info || do_debug_abbrevs
6586 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
6587 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
6588 || do_debug_str || do_debug_str_offsets || do_debug_loc
6589 || do_debug_ranges
1b513401
NC
6590 || do_debug_addr || do_debug_cu_index || do_debug_links)
6591 && (const_strneq (name, ".debug_")
6592 || const_strneq (name, ".zdebug_")))
252b5132 6593 {
1b315056
CS
6594 if (name[1] == 'z')
6595 name += sizeof (".zdebug_") - 1;
6596 else
6597 name += sizeof (".debug_") - 1;
252b5132
RH
6598
6599 if (do_debugging
4723351a
CC
6600 || (do_debug_info && const_strneq (name, "info"))
6601 || (do_debug_info && const_strneq (name, "types"))
6602 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
6603 || (do_debug_lines && strcmp (name, "line") == 0)
6604 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
6605 || (do_debug_pubnames && const_strneq (name, "pubnames"))
6606 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
6607 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
6608 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
6609 || (do_debug_aranges && const_strneq (name, "aranges"))
6610 || (do_debug_ranges && const_strneq (name, "ranges"))
77145576 6611 || (do_debug_ranges && const_strneq (name, "rnglists"))
4723351a
CC
6612 || (do_debug_frames && const_strneq (name, "frame"))
6613 || (do_debug_macinfo && const_strneq (name, "macinfo"))
6614 || (do_debug_macinfo && const_strneq (name, "macro"))
6615 || (do_debug_str && const_strneq (name, "str"))
e38332c2 6616 || (do_debug_links && const_strneq (name, "sup"))
e4b7104b 6617 || (do_debug_str_offsets && const_strneq (name, "str_offsets"))
4723351a 6618 || (do_debug_loc && const_strneq (name, "loc"))
77145576 6619 || (do_debug_loc && const_strneq (name, "loclists"))
657d0d47
CC
6620 || (do_debug_addr && const_strneq (name, "addr"))
6621 || (do_debug_cu_index && const_strneq (name, "cu_index"))
6622 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 6623 )
6431e409 6624 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6625 }
a262ae96 6626 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6627 else if ((do_debugging || do_debug_info)
0112cd26 6628 && const_strneq (name, ".gnu.linkonce.wi."))
6431e409 6629 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6630 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6631 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6632 else if (do_gdb_index && (streq (name, ".gdb_index")
6633 || streq (name, ".debug_names")))
6431e409 6634 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6635 /* Trace sections for Itanium VMS. */
6636 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6637 || do_trace_aranges)
6638 && const_strneq (name, ".trace_"))
6639 {
6640 name += sizeof (".trace_") - 1;
6641
6642 if (do_debugging
6643 || (do_trace_info && streq (name, "info"))
6644 || (do_trace_abbrevs && streq (name, "abbrev"))
6645 || (do_trace_aranges && streq (name, "aranges"))
6646 )
6431e409 6647 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6648 }
dda8d76d
NC
6649 else if ((do_debugging || do_debug_links)
6650 && (const_strneq (name, ".gnu_debuglink")
6651 || const_strneq (name, ".gnu_debugaltlink")))
6431e409 6652 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6653 }
6654
6655 if (! do_sections)
32ec8896 6656 return TRUE;
252b5132 6657
ca0e11aa
NC
6658 if (filedata->is_separate && ! process_links)
6659 return TRUE;
6660
6661 if (filedata->is_separate)
6662 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
6663 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6664 printf (_("\nSection Headers:\n"));
6665 else
6666 printf (_("\nSection Header:\n"));
76da6bbe 6667
f7a99963 6668 if (is_32bit_elf)
595cf52e 6669 {
5477e8a0 6670 if (do_section_details)
595cf52e
L
6671 {
6672 printf (_(" [Nr] Name\n"));
5477e8a0 6673 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6674 }
6675 else
6676 printf
6677 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6678 }
d974e256 6679 else if (do_wide)
595cf52e 6680 {
5477e8a0 6681 if (do_section_details)
595cf52e
L
6682 {
6683 printf (_(" [Nr] Name\n"));
5477e8a0 6684 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6685 }
6686 else
6687 printf
6688 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6689 }
f7a99963
NC
6690 else
6691 {
5477e8a0 6692 if (do_section_details)
595cf52e
L
6693 {
6694 printf (_(" [Nr] Name\n"));
5477e8a0
L
6695 printf (_(" Type Address Offset Link\n"));
6696 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6697 }
6698 else
6699 {
6700 printf (_(" [Nr] Name Type Address Offset\n"));
6701 printf (_(" Size EntSize Flags Link Info Align\n"));
6702 }
f7a99963 6703 }
252b5132 6704
5477e8a0
L
6705 if (do_section_details)
6706 printf (_(" Flags\n"));
6707
dda8d76d
NC
6708 for (i = 0, section = filedata->section_headers;
6709 i < filedata->file_header.e_shnum;
b34976b6 6710 i++, section++)
252b5132 6711 {
dd905818
NC
6712 /* Run some sanity checks on the section header. */
6713
6714 /* Check the sh_link field. */
6715 switch (section->sh_type)
6716 {
285e3f99
AM
6717 case SHT_REL:
6718 case SHT_RELA:
6719 if (section->sh_link == 0
6720 && (filedata->file_header.e_type == ET_EXEC
6721 || filedata->file_header.e_type == ET_DYN))
6722 /* A dynamic relocation section where all entries use a
6723 zero symbol index need not specify a symtab section. */
6724 break;
6725 /* Fall through. */
dd905818
NC
6726 case SHT_SYMTAB_SHNDX:
6727 case SHT_GROUP:
6728 case SHT_HASH:
6729 case SHT_GNU_HASH:
6730 case SHT_GNU_versym:
285e3f99 6731 if (section->sh_link == 0
dda8d76d
NC
6732 || section->sh_link >= filedata->file_header.e_shnum
6733 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6734 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6735 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6736 i, section->sh_link);
6737 break;
6738
6739 case SHT_DYNAMIC:
6740 case SHT_SYMTAB:
6741 case SHT_DYNSYM:
6742 case SHT_GNU_verneed:
6743 case SHT_GNU_verdef:
6744 case SHT_GNU_LIBLIST:
285e3f99 6745 if (section->sh_link == 0
dda8d76d
NC
6746 || section->sh_link >= filedata->file_header.e_shnum
6747 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6748 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6749 i, section->sh_link);
6750 break;
6751
6752 case SHT_INIT_ARRAY:
6753 case SHT_FINI_ARRAY:
6754 case SHT_PREINIT_ARRAY:
6755 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6756 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6757 i, section->sh_link);
6758 break;
6759
6760 default:
6761 /* FIXME: Add support for target specific section types. */
6762#if 0 /* Currently we do not check other section types as there are too
6763 many special cases. Stab sections for example have a type
6764 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6765 section. */
6766 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6767 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6768 i, section->sh_link);
6769#endif
6770 break;
6771 }
6772
6773 /* Check the sh_info field. */
6774 switch (section->sh_type)
6775 {
6776 case SHT_REL:
6777 case SHT_RELA:
285e3f99
AM
6778 if (section->sh_info == 0
6779 && (filedata->file_header.e_type == ET_EXEC
6780 || filedata->file_header.e_type == ET_DYN))
6781 /* Dynamic relocations apply to segments, so they do not
6782 need to specify the section they relocate. */
6783 break;
6784 if (section->sh_info == 0
dda8d76d
NC
6785 || section->sh_info >= filedata->file_header.e_shnum
6786 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6787 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6788 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6789 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6790 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6791 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6792 /* FIXME: Are other section types valid ? */
dda8d76d 6793 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6794 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6795 i, section->sh_info);
dd905818
NC
6796 break;
6797
6798 case SHT_DYNAMIC:
6799 case SHT_HASH:
6800 case SHT_SYMTAB_SHNDX:
6801 case SHT_INIT_ARRAY:
6802 case SHT_FINI_ARRAY:
6803 case SHT_PREINIT_ARRAY:
6804 if (section->sh_info != 0)
6805 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6806 i, section->sh_info);
6807 break;
6808
6809 case SHT_GROUP:
6810 case SHT_SYMTAB:
6811 case SHT_DYNSYM:
6812 /* A symbol index - we assume that it is valid. */
6813 break;
6814
6815 default:
6816 /* FIXME: Add support for target specific section types. */
6817 if (section->sh_type == SHT_NOBITS)
6818 /* NOBITS section headers with non-zero sh_info fields can be
6819 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6820 information. The stripped sections have their headers
6821 preserved but their types set to SHT_NOBITS. So do not check
6822 this type of section. */
dd905818
NC
6823 ;
6824 else if (section->sh_flags & SHF_INFO_LINK)
6825 {
dda8d76d 6826 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6827 warn (_("[%2u]: Expected link to another section in info field"), i);
6828 }
a91e1603
L
6829 else if (section->sh_type < SHT_LOOS
6830 && (section->sh_flags & SHF_GNU_MBIND) == 0
6831 && section->sh_info != 0)
dd905818
NC
6832 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6833 i, section->sh_info);
6834 break;
6835 }
6836
3e6b6445 6837 /* Check the sh_size field. */
dda8d76d 6838 if (section->sh_size > filedata->file_size
3e6b6445
NC
6839 && section->sh_type != SHT_NOBITS
6840 && section->sh_type != SHT_NULL
6841 && section->sh_type < SHT_LOOS)
6842 warn (_("Size of section %u is larger than the entire file!\n"), i);
6843
7bfd842d 6844 printf (" [%2u] ", i);
5477e8a0 6845 if (do_section_details)
dda8d76d 6846 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6847 else
b9e920ec 6848 print_symbol (-17, SECTION_NAME_PRINT (section));
0b4362b0 6849
ea52a088 6850 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6851 get_section_type_name (filedata, section->sh_type));
0b4362b0 6852
f7a99963
NC
6853 if (is_32bit_elf)
6854 {
cfcac11d
NC
6855 const char * link_too_big = NULL;
6856
f7a99963 6857 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6858
f7a99963
NC
6859 printf ( " %6.6lx %6.6lx %2.2lx",
6860 (unsigned long) section->sh_offset,
6861 (unsigned long) section->sh_size,
6862 (unsigned long) section->sh_entsize);
d1133906 6863
5477e8a0
L
6864 if (do_section_details)
6865 fputs (" ", stdout);
6866 else
dda8d76d 6867 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6868
dda8d76d 6869 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6870 {
6871 link_too_big = "";
6872 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6873 an error but it can have special values in Solaris binaries. */
dda8d76d 6874 switch (filedata->file_header.e_machine)
cfcac11d 6875 {
caa83f8b 6876 case EM_386:
22abe556 6877 case EM_IAMCU:
caa83f8b 6878 case EM_X86_64:
7f502d6c 6879 case EM_L1OM:
7a9068fe 6880 case EM_K1OM:
cfcac11d
NC
6881 case EM_OLD_SPARCV9:
6882 case EM_SPARC32PLUS:
6883 case EM_SPARCV9:
6884 case EM_SPARC:
6885 if (section->sh_link == (SHN_BEFORE & 0xffff))
6886 link_too_big = "BEFORE";
6887 else if (section->sh_link == (SHN_AFTER & 0xffff))
6888 link_too_big = "AFTER";
6889 break;
6890 default:
6891 break;
6892 }
6893 }
6894
6895 if (do_section_details)
6896 {
6897 if (link_too_big != NULL && * link_too_big)
6898 printf ("<%s> ", link_too_big);
6899 else
6900 printf ("%2u ", section->sh_link);
6901 printf ("%3u %2lu\n", section->sh_info,
6902 (unsigned long) section->sh_addralign);
6903 }
6904 else
6905 printf ("%2u %3u %2lu\n",
6906 section->sh_link,
6907 section->sh_info,
6908 (unsigned long) section->sh_addralign);
6909
6910 if (link_too_big && ! * link_too_big)
6911 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6912 i, section->sh_link);
f7a99963 6913 }
d974e256
JJ
6914 else if (do_wide)
6915 {
6916 print_vma (section->sh_addr, LONG_HEX);
6917
6918 if ((long) section->sh_offset == section->sh_offset)
6919 printf (" %6.6lx", (unsigned long) section->sh_offset);
6920 else
6921 {
6922 putchar (' ');
6923 print_vma (section->sh_offset, LONG_HEX);
6924 }
6925
6926 if ((unsigned long) section->sh_size == section->sh_size)
6927 printf (" %6.6lx", (unsigned long) section->sh_size);
6928 else
6929 {
6930 putchar (' ');
6931 print_vma (section->sh_size, LONG_HEX);
6932 }
6933
6934 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6935 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6936 else
6937 {
6938 putchar (' ');
6939 print_vma (section->sh_entsize, LONG_HEX);
6940 }
6941
5477e8a0
L
6942 if (do_section_details)
6943 fputs (" ", stdout);
6944 else
dda8d76d 6945 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6946
72de5009 6947 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6948
6949 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6950 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6951 else
6952 {
6953 print_vma (section->sh_addralign, DEC);
6954 putchar ('\n');
6955 }
6956 }
5477e8a0 6957 else if (do_section_details)
595cf52e 6958 {
55cc53e9 6959 putchar (' ');
595cf52e
L
6960 print_vma (section->sh_addr, LONG_HEX);
6961 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 6962 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
6963 else
6964 {
6965 printf (" ");
6966 print_vma (section->sh_offset, LONG_HEX);
6967 }
72de5009 6968 printf (" %u\n ", section->sh_link);
595cf52e 6969 print_vma (section->sh_size, LONG_HEX);
5477e8a0 6970 putchar (' ');
595cf52e
L
6971 print_vma (section->sh_entsize, LONG_HEX);
6972
72de5009
AM
6973 printf (" %-16u %lu\n",
6974 section->sh_info,
595cf52e
L
6975 (unsigned long) section->sh_addralign);
6976 }
f7a99963
NC
6977 else
6978 {
6979 putchar (' ');
6980 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
6981 if ((long) section->sh_offset == section->sh_offset)
6982 printf (" %8.8lx", (unsigned long) section->sh_offset);
6983 else
6984 {
6985 printf (" ");
6986 print_vma (section->sh_offset, LONG_HEX);
6987 }
f7a99963
NC
6988 printf ("\n ");
6989 print_vma (section->sh_size, LONG_HEX);
6990 printf (" ");
6991 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 6992
dda8d76d 6993 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6994
72de5009
AM
6995 printf (" %2u %3u %lu\n",
6996 section->sh_link,
6997 section->sh_info,
f7a99963
NC
6998 (unsigned long) section->sh_addralign);
6999 }
5477e8a0
L
7000
7001 if (do_section_details)
77115a4a 7002 {
dda8d76d 7003 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7004 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7005 {
7006 /* Minimum section size is 12 bytes for 32-bit compression
7007 header + 12 bytes for compressed data header. */
7008 unsigned char buf[24];
d8024a91 7009
77115a4a 7010 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7011 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7012 sizeof (buf), _("compression header")))
7013 {
7014 Elf_Internal_Chdr chdr;
d8024a91 7015
5844b465
NC
7016 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7017 printf (_(" [<corrupt>]\n"));
77115a4a 7018 else
5844b465
NC
7019 {
7020 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7021 printf (" ZLIB, ");
7022 else
7023 printf (_(" [<unknown>: 0x%x], "),
7024 chdr.ch_type);
7025 print_vma (chdr.ch_size, LONG_HEX);
7026 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7027 }
77115a4a
L
7028 }
7029 }
7030 }
252b5132
RH
7031 }
7032
5477e8a0 7033 if (!do_section_details)
3dbcc61d 7034 {
9fb71ee4
NC
7035 /* The ordering of the letters shown here matches the ordering of the
7036 corresponding SHF_xxx values, and hence the order in which these
7037 letters will be displayed to the user. */
7038 printf (_("Key to Flags:\n\
7039 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7040 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7041 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7042 switch (filedata->file_header.e_ident[EI_OSABI])
7043 {
7044 case ELFOSABI_GNU:
7045 case ELFOSABI_FREEBSD:
7046 printf (_("R (retain), "));
7047 /* Fall through */
7048 case ELFOSABI_NONE:
7049 printf (_("D (mbind), "));
7050 break;
7051 default:
7052 break;
7053 }
dda8d76d
NC
7054 if (filedata->file_header.e_machine == EM_X86_64
7055 || filedata->file_header.e_machine == EM_L1OM
7056 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7057 printf (_("l (large), "));
dda8d76d 7058 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7059 printf (_("y (purecode), "));
dda8d76d 7060 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7061 printf (_("v (VLE), "));
9fb71ee4 7062 printf ("p (processor specific)\n");
0b4362b0 7063 }
d1133906 7064
32ec8896 7065 return TRUE;
252b5132
RH
7066}
7067
28d13567
AM
7068static bfd_boolean
7069get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7070 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7071 char **strtab, unsigned long *strtablen)
7072{
7073 *strtab = NULL;
7074 *strtablen = 0;
7075 *symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms);
7076
7077 if (*symtab == NULL)
7078 return FALSE;
7079
7080 if (symsec->sh_link != 0)
7081 {
7082 Elf_Internal_Shdr *strsec;
7083
7084 if (symsec->sh_link >= filedata->file_header.e_shnum)
7085 {
7086 error (_("Bad sh_link in symbol table section\n"));
7087 free (*symtab);
7088 *symtab = NULL;
7089 *nsyms = 0;
7090 return FALSE;
7091 }
7092
7093 strsec = filedata->section_headers + symsec->sh_link;
7094
7095 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7096 1, strsec->sh_size, _("string table"));
7097 if (*strtab == NULL)
7098 {
7099 free (*symtab);
7100 *symtab = NULL;
7101 *nsyms = 0;
7102 return FALSE;
7103 }
7104 *strtablen = strsec->sh_size;
7105 }
7106 return TRUE;
7107}
7108
f5842774
L
7109static const char *
7110get_group_flags (unsigned int flags)
7111{
1449284b 7112 static char buff[128];
220453ec 7113
6d913794
NC
7114 if (flags == 0)
7115 return "";
7116 else if (flags == GRP_COMDAT)
7117 return "COMDAT ";
f5842774 7118
89246a0e
AM
7119 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7120 flags,
7121 flags & GRP_MASKOS ? _("<OS specific>") : "",
7122 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7123 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7124 ? _("<unknown>") : ""));
6d913794 7125
f5842774
L
7126 return buff;
7127}
7128
32ec8896 7129static bfd_boolean
dda8d76d 7130process_section_groups (Filedata * filedata)
f5842774 7131{
2cf0635d 7132 Elf_Internal_Shdr * section;
f5842774 7133 unsigned int i;
2cf0635d
NC
7134 struct group * group;
7135 Elf_Internal_Shdr * symtab_sec;
7136 Elf_Internal_Shdr * strtab_sec;
7137 Elf_Internal_Sym * symtab;
ba5cdace 7138 unsigned long num_syms;
2cf0635d 7139 char * strtab;
c256ffe7 7140 size_t strtab_size;
d1f5c6e3
L
7141
7142 /* Don't process section groups unless needed. */
7143 if (!do_unwind && !do_section_groups)
32ec8896 7144 return TRUE;
f5842774 7145
dda8d76d 7146 if (filedata->file_header.e_shnum == 0)
f5842774
L
7147 {
7148 if (do_section_groups)
ca0e11aa
NC
7149 {
7150 if (filedata->is_separate)
7151 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7152 filedata->file_name);
7153 else
7154 printf (_("\nThere are no section groups in this file.\n"));
7155 }
32ec8896 7156 return TRUE;
f5842774
L
7157 }
7158
dda8d76d 7159 if (filedata->section_headers == NULL)
f5842774
L
7160 {
7161 error (_("Section headers are not available!\n"));
fa1908fd 7162 /* PR 13622: This can happen with a corrupt ELF header. */
32ec8896 7163 return FALSE;
f5842774
L
7164 }
7165
978c4450
AM
7166 filedata->section_headers_groups
7167 = (struct group **) calloc (filedata->file_header.e_shnum,
7168 sizeof (struct group *));
e4b17d5c 7169
978c4450 7170 if (filedata->section_headers_groups == NULL)
e4b17d5c 7171 {
8b73c356 7172 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7173 filedata->file_header.e_shnum);
32ec8896 7174 return FALSE;
e4b17d5c
L
7175 }
7176
f5842774 7177 /* Scan the sections for the group section. */
978c4450 7178 filedata->group_count = 0;
dda8d76d
NC
7179 for (i = 0, section = filedata->section_headers;
7180 i < filedata->file_header.e_shnum;
f5842774 7181 i++, section++)
e4b17d5c 7182 if (section->sh_type == SHT_GROUP)
978c4450 7183 filedata->group_count++;
e4b17d5c 7184
978c4450 7185 if (filedata->group_count == 0)
d1f5c6e3
L
7186 {
7187 if (do_section_groups)
ca0e11aa
NC
7188 {
7189 if (filedata->is_separate)
7190 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7191 filedata->file_name);
7192 else
7193 printf (_("\nThere are no section groups in this file.\n"));
7194 }
d1f5c6e3 7195
32ec8896 7196 return TRUE;
d1f5c6e3
L
7197 }
7198
978c4450
AM
7199 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7200 sizeof (struct group));
e4b17d5c 7201
978c4450 7202 if (filedata->section_groups == NULL)
e4b17d5c 7203 {
8b73c356 7204 error (_("Out of memory reading %lu groups\n"),
978c4450 7205 (unsigned long) filedata->group_count);
32ec8896 7206 return FALSE;
e4b17d5c
L
7207 }
7208
d1f5c6e3
L
7209 symtab_sec = NULL;
7210 strtab_sec = NULL;
7211 symtab = NULL;
ba5cdace 7212 num_syms = 0;
d1f5c6e3 7213 strtab = NULL;
c256ffe7 7214 strtab_size = 0;
ca0e11aa
NC
7215
7216 if (filedata->is_separate)
7217 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
7218
978c4450 7219 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7220 i < filedata->file_header.e_shnum;
e4b17d5c 7221 i++, section++)
f5842774
L
7222 {
7223 if (section->sh_type == SHT_GROUP)
7224 {
dda8d76d 7225 const char * name = printable_section_name (filedata, section);
74e1a04b 7226 const char * group_name;
2cf0635d
NC
7227 unsigned char * start;
7228 unsigned char * indices;
f5842774 7229 unsigned int entry, j, size;
2cf0635d
NC
7230 Elf_Internal_Shdr * sec;
7231 Elf_Internal_Sym * sym;
f5842774
L
7232
7233 /* Get the symbol table. */
dda8d76d
NC
7234 if (section->sh_link >= filedata->file_header.e_shnum
7235 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7236 != SHT_SYMTAB))
f5842774
L
7237 {
7238 error (_("Bad sh_link in group section `%s'\n"), name);
7239 continue;
7240 }
d1f5c6e3
L
7241
7242 if (symtab_sec != sec)
7243 {
7244 symtab_sec = sec;
9db70fc3 7245 free (symtab);
dda8d76d 7246 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 7247 }
f5842774 7248
dd24e3da
NC
7249 if (symtab == NULL)
7250 {
7251 error (_("Corrupt header in group section `%s'\n"), name);
7252 continue;
7253 }
7254
ba5cdace
NC
7255 if (section->sh_info >= num_syms)
7256 {
7257 error (_("Bad sh_info in group section `%s'\n"), name);
7258 continue;
7259 }
7260
f5842774
L
7261 sym = symtab + section->sh_info;
7262
7263 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7264 {
4fbb74a6 7265 if (sym->st_shndx == 0
dda8d76d 7266 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7267 {
7268 error (_("Bad sh_info in group section `%s'\n"), name);
7269 continue;
7270 }
ba2685cc 7271
b9e920ec
AM
7272 group_name = SECTION_NAME_PRINT (filedata->section_headers
7273 + sym->st_shndx);
c256ffe7 7274 strtab_sec = NULL;
9db70fc3 7275 free (strtab);
f5842774 7276 strtab = NULL;
c256ffe7 7277 strtab_size = 0;
f5842774
L
7278 }
7279 else
7280 {
7281 /* Get the string table. */
dda8d76d 7282 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7283 {
7284 strtab_sec = NULL;
9db70fc3 7285 free (strtab);
c256ffe7
JJ
7286 strtab = NULL;
7287 strtab_size = 0;
7288 }
7289 else if (strtab_sec
dda8d76d 7290 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7291 {
7292 strtab_sec = sec;
9db70fc3 7293 free (strtab);
071436c6 7294
dda8d76d 7295 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7296 1, strtab_sec->sh_size,
7297 _("string table"));
c256ffe7 7298 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7299 }
c256ffe7 7300 group_name = sym->st_name < strtab_size
2b692964 7301 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7302 }
7303
c9c1d674
EG
7304 /* PR 17531: file: loop. */
7305 if (section->sh_entsize > section->sh_size)
7306 {
7307 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7308 printable_section_name (filedata, section),
8066deb1
AM
7309 (unsigned long) section->sh_entsize,
7310 (unsigned long) section->sh_size);
61dd8e19 7311 continue;
c9c1d674
EG
7312 }
7313
dda8d76d 7314 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7315 1, section->sh_size,
7316 _("section data"));
59245841
NC
7317 if (start == NULL)
7318 continue;
f5842774
L
7319
7320 indices = start;
7321 size = (section->sh_size / section->sh_entsize) - 1;
7322 entry = byte_get (indices, 4);
7323 indices += 4;
e4b17d5c
L
7324
7325 if (do_section_groups)
7326 {
2b692964 7327 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7328 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7329
e4b17d5c
L
7330 printf (_(" [Index] Name\n"));
7331 }
7332
7333 group->group_index = i;
7334
f5842774
L
7335 for (j = 0; j < size; j++)
7336 {
2cf0635d 7337 struct group_list * g;
e4b17d5c 7338
f5842774
L
7339 entry = byte_get (indices, 4);
7340 indices += 4;
7341
dda8d76d 7342 if (entry >= filedata->file_header.e_shnum)
391cb864 7343 {
57028622
NC
7344 static unsigned num_group_errors = 0;
7345
7346 if (num_group_errors ++ < 10)
7347 {
7348 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7349 entry, i, filedata->file_header.e_shnum - 1);
57028622 7350 if (num_group_errors == 10)
67ce483b 7351 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7352 }
391cb864
L
7353 continue;
7354 }
391cb864 7355
978c4450 7356 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7357 {
d1f5c6e3
L
7358 if (entry)
7359 {
57028622
NC
7360 static unsigned num_errs = 0;
7361
7362 if (num_errs ++ < 10)
7363 {
7364 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7365 entry, i,
978c4450 7366 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7367 if (num_errs == 10)
7368 warn (_("Further error messages about already contained group sections suppressed\n"));
7369 }
d1f5c6e3
L
7370 continue;
7371 }
7372 else
7373 {
7374 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7375 section group. We just warn it the first time
d1f5c6e3 7376 and ignore it afterwards. */
32ec8896 7377 static bfd_boolean warned = FALSE;
d1f5c6e3
L
7378 if (!warned)
7379 {
7380 error (_("section 0 in group section [%5u]\n"),
978c4450 7381 filedata->section_headers_groups [entry]->group_index);
32ec8896 7382 warned = TRUE;
d1f5c6e3
L
7383 }
7384 }
e4b17d5c
L
7385 }
7386
978c4450 7387 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7388
7389 if (do_section_groups)
7390 {
dda8d76d
NC
7391 sec = filedata->section_headers + entry;
7392 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7393 }
7394
3f5e193b 7395 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7396 g->section_index = entry;
7397 g->next = group->root;
7398 group->root = g;
f5842774
L
7399 }
7400
9db70fc3 7401 free (start);
e4b17d5c
L
7402
7403 group++;
f5842774
L
7404 }
7405 }
7406
9db70fc3
AM
7407 free (symtab);
7408 free (strtab);
32ec8896 7409 return TRUE;
f5842774
L
7410}
7411
28f997cf
TG
7412/* Data used to display dynamic fixups. */
7413
7414struct ia64_vms_dynfixup
7415{
7416 bfd_vma needed_ident; /* Library ident number. */
7417 bfd_vma needed; /* Index in the dstrtab of the library name. */
7418 bfd_vma fixup_needed; /* Index of the library. */
7419 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7420 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7421};
7422
7423/* Data used to display dynamic relocations. */
7424
7425struct ia64_vms_dynimgrela
7426{
7427 bfd_vma img_rela_cnt; /* Number of relocations. */
7428 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7429};
7430
7431/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7432 library). */
7433
32ec8896 7434static bfd_boolean
dda8d76d
NC
7435dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7436 struct ia64_vms_dynfixup * fixup,
7437 const char * strtab,
7438 unsigned int strtab_sz)
28f997cf 7439{
32ec8896 7440 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7441 long i;
32ec8896 7442 const char * lib_name;
28f997cf 7443
978c4450
AM
7444 imfs = get_data (NULL, filedata,
7445 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7446 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7447 _("dynamic section image fixups"));
7448 if (!imfs)
32ec8896 7449 return FALSE;
28f997cf
TG
7450
7451 if (fixup->needed < strtab_sz)
7452 lib_name = strtab + fixup->needed;
7453 else
7454 {
32ec8896 7455 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7456 (unsigned long) fixup->needed);
28f997cf
TG
7457 lib_name = "???";
7458 }
736990c4 7459
28f997cf
TG
7460 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7461 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7462 printf
7463 (_("Seg Offset Type SymVec DataType\n"));
7464
7465 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7466 {
7467 unsigned int type;
7468 const char *rtype;
7469
7470 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7471 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7472 type = BYTE_GET (imfs [i].type);
7473 rtype = elf_ia64_reloc_type (type);
7474 if (rtype == NULL)
7475 printf (" 0x%08x ", type);
7476 else
7477 printf (" %-32s ", rtype);
7478 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7479 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7480 }
7481
7482 free (imfs);
32ec8896 7483 return TRUE;
28f997cf
TG
7484}
7485
7486/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7487
32ec8896 7488static bfd_boolean
dda8d76d 7489dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7490{
7491 Elf64_External_VMS_IMAGE_RELA *imrs;
7492 long i;
7493
978c4450
AM
7494 imrs = get_data (NULL, filedata,
7495 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 7496 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7497 _("dynamic section image relocations"));
28f997cf 7498 if (!imrs)
32ec8896 7499 return FALSE;
28f997cf
TG
7500
7501 printf (_("\nImage relocs\n"));
7502 printf
7503 (_("Seg Offset Type Addend Seg Sym Off\n"));
7504
7505 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7506 {
7507 unsigned int type;
7508 const char *rtype;
7509
7510 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7511 printf ("%08" BFD_VMA_FMT "x ",
7512 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7513 type = BYTE_GET (imrs [i].type);
7514 rtype = elf_ia64_reloc_type (type);
7515 if (rtype == NULL)
7516 printf ("0x%08x ", type);
7517 else
7518 printf ("%-31s ", rtype);
7519 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7520 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7521 printf ("%08" BFD_VMA_FMT "x\n",
7522 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7523 }
7524
7525 free (imrs);
32ec8896 7526 return TRUE;
28f997cf
TG
7527}
7528
7529/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7530
32ec8896 7531static bfd_boolean
dda8d76d 7532process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7533{
7534 struct ia64_vms_dynfixup fixup;
7535 struct ia64_vms_dynimgrela imgrela;
7536 Elf_Internal_Dyn *entry;
28f997cf
TG
7537 bfd_vma strtab_off = 0;
7538 bfd_vma strtab_sz = 0;
7539 char *strtab = NULL;
32ec8896 7540 bfd_boolean res = TRUE;
28f997cf
TG
7541
7542 memset (&fixup, 0, sizeof (fixup));
7543 memset (&imgrela, 0, sizeof (imgrela));
7544
7545 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
7546 for (entry = filedata->dynamic_section;
7547 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
7548 entry++)
7549 {
7550 switch (entry->d_tag)
7551 {
7552 case DT_IA_64_VMS_STRTAB_OFFSET:
7553 strtab_off = entry->d_un.d_val;
7554 break;
7555 case DT_STRSZ:
7556 strtab_sz = entry->d_un.d_val;
7557 if (strtab == NULL)
978c4450
AM
7558 strtab = get_data (NULL, filedata,
7559 filedata->dynamic_addr + strtab_off,
28f997cf 7560 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7561 if (strtab == NULL)
7562 strtab_sz = 0;
28f997cf
TG
7563 break;
7564
7565 case DT_IA_64_VMS_NEEDED_IDENT:
7566 fixup.needed_ident = entry->d_un.d_val;
7567 break;
7568 case DT_NEEDED:
7569 fixup.needed = entry->d_un.d_val;
7570 break;
7571 case DT_IA_64_VMS_FIXUP_NEEDED:
7572 fixup.fixup_needed = entry->d_un.d_val;
7573 break;
7574 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7575 fixup.fixup_rela_cnt = entry->d_un.d_val;
7576 break;
7577 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7578 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7579 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
32ec8896 7580 res = FALSE;
28f997cf 7581 break;
28f997cf
TG
7582 case DT_IA_64_VMS_IMG_RELA_CNT:
7583 imgrela.img_rela_cnt = entry->d_un.d_val;
7584 break;
7585 case DT_IA_64_VMS_IMG_RELA_OFF:
7586 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7587 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
32ec8896 7588 res = FALSE;
28f997cf
TG
7589 break;
7590
7591 default:
7592 break;
7593 }
7594 }
7595
9db70fc3 7596 free (strtab);
28f997cf
TG
7597
7598 return res;
7599}
7600
85b1c36d 7601static struct
566b0d53 7602{
2cf0635d 7603 const char * name;
566b0d53
L
7604 int reloc;
7605 int size;
7606 int rela;
32ec8896
NC
7607}
7608 dynamic_relocations [] =
566b0d53 7609{
32ec8896
NC
7610 { "REL", DT_REL, DT_RELSZ, FALSE },
7611 { "RELA", DT_RELA, DT_RELASZ, TRUE },
7612 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7613};
7614
252b5132 7615/* Process the reloc section. */
18bd398b 7616
32ec8896 7617static bfd_boolean
dda8d76d 7618process_relocs (Filedata * filedata)
252b5132 7619{
b34976b6
AM
7620 unsigned long rel_size;
7621 unsigned long rel_offset;
252b5132 7622
252b5132 7623 if (!do_reloc)
32ec8896 7624 return TRUE;
252b5132
RH
7625
7626 if (do_using_dynamic)
7627 {
32ec8896 7628 int is_rela;
2cf0635d 7629 const char * name;
32ec8896 7630 bfd_boolean has_dynamic_reloc;
566b0d53 7631 unsigned int i;
0de14b54 7632
32ec8896 7633 has_dynamic_reloc = FALSE;
252b5132 7634
566b0d53 7635 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7636 {
566b0d53
L
7637 is_rela = dynamic_relocations [i].rela;
7638 name = dynamic_relocations [i].name;
978c4450
AM
7639 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
7640 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 7641
32ec8896
NC
7642 if (rel_size)
7643 has_dynamic_reloc = TRUE;
566b0d53
L
7644
7645 if (is_rela == UNKNOWN)
aa903cfb 7646 {
566b0d53 7647 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 7648 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
7649 {
7650 case DT_REL:
7651 is_rela = FALSE;
7652 break;
7653 case DT_RELA:
7654 is_rela = TRUE;
7655 break;
7656 }
aa903cfb 7657 }
252b5132 7658
566b0d53
L
7659 if (rel_size)
7660 {
ca0e11aa
NC
7661 if (filedata->is_separate)
7662 printf
7663 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
7664 filedata->file_name, name, rel_offset, rel_size);
7665 else
7666 printf
7667 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7668 name, rel_offset, rel_size);
7669
252b5132 7670
dda8d76d
NC
7671 dump_relocations (filedata,
7672 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7673 rel_size,
978c4450
AM
7674 filedata->dynamic_symbols,
7675 filedata->num_dynamic_syms,
7676 filedata->dynamic_strings,
7677 filedata->dynamic_strings_length,
32ec8896 7678 is_rela, TRUE /* is_dynamic */);
566b0d53 7679 }
252b5132 7680 }
566b0d53 7681
dda8d76d
NC
7682 if (is_ia64_vms (filedata))
7683 if (process_ia64_vms_dynamic_relocs (filedata))
32ec8896 7684 has_dynamic_reloc = TRUE;
28f997cf 7685
566b0d53 7686 if (! has_dynamic_reloc)
ca0e11aa
NC
7687 {
7688 if (filedata->is_separate)
7689 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
7690 filedata->file_name);
7691 else
7692 printf (_("\nThere are no dynamic relocations in this file.\n"));
7693 }
252b5132
RH
7694 }
7695 else
7696 {
2cf0635d 7697 Elf_Internal_Shdr * section;
b34976b6 7698 unsigned long i;
32ec8896 7699 bfd_boolean found = FALSE;
252b5132 7700
dda8d76d
NC
7701 for (i = 0, section = filedata->section_headers;
7702 i < filedata->file_header.e_shnum;
b34976b6 7703 i++, section++)
252b5132
RH
7704 {
7705 if ( section->sh_type != SHT_RELA
7706 && section->sh_type != SHT_REL)
7707 continue;
7708
7709 rel_offset = section->sh_offset;
7710 rel_size = section->sh_size;
7711
7712 if (rel_size)
7713 {
b34976b6 7714 int is_rela;
d3a49aa8 7715 unsigned long num_rela;
103f02d3 7716
ca0e11aa
NC
7717 if (filedata->is_separate)
7718 printf (_("\nIn linked file '%s' relocation section "),
7719 filedata->file_name);
7720 else
7721 printf (_("\nRelocation section "));
252b5132 7722
dda8d76d 7723 if (filedata->string_table == NULL)
19936277 7724 printf ("%d", section->sh_name);
252b5132 7725 else
dda8d76d 7726 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7727
d3a49aa8
AM
7728 num_rela = rel_size / section->sh_entsize;
7729 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7730 " at offset 0x%lx contains %lu entries:\n",
7731 num_rela),
7732 rel_offset, num_rela);
252b5132 7733
d79b3d50
NC
7734 is_rela = section->sh_type == SHT_RELA;
7735
4fbb74a6 7736 if (section->sh_link != 0
dda8d76d 7737 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7738 {
2cf0635d
NC
7739 Elf_Internal_Shdr * symsec;
7740 Elf_Internal_Sym * symtab;
d79b3d50 7741 unsigned long nsyms;
c256ffe7 7742 unsigned long strtablen = 0;
2cf0635d 7743 char * strtab = NULL;
57346661 7744
dda8d76d 7745 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7746 if (symsec->sh_type != SHT_SYMTAB
7747 && symsec->sh_type != SHT_DYNSYM)
7748 continue;
7749
28d13567
AM
7750 if (!get_symtab (filedata, symsec,
7751 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7752 continue;
252b5132 7753
dda8d76d 7754 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7755 symtab, nsyms, strtab, strtablen,
7756 is_rela,
7757 symsec->sh_type == SHT_DYNSYM);
9db70fc3 7758 free (strtab);
d79b3d50
NC
7759 free (symtab);
7760 }
7761 else
dda8d76d 7762 dump_relocations (filedata, rel_offset, rel_size,
32ec8896
NC
7763 NULL, 0, NULL, 0, is_rela,
7764 FALSE /* is_dynamic */);
252b5132 7765
32ec8896 7766 found = TRUE;
252b5132
RH
7767 }
7768 }
7769
7770 if (! found)
45ac8f4f
NC
7771 {
7772 /* Users sometimes forget the -D option, so try to be helpful. */
7773 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7774 {
978c4450 7775 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 7776 {
ca0e11aa
NC
7777 if (filedata->is_separate)
7778 printf (_("\nThere are no static relocations in linked file '%s'."),
7779 filedata->file_name);
7780 else
7781 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
7782 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7783
7784 break;
7785 }
7786 }
7787 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
7788 {
7789 if (filedata->is_separate)
7790 printf (_("\nThere are no relocations in linked file '%s'.\n"),
7791 filedata->file_name);
7792 else
7793 printf (_("\nThere are no relocations in this file.\n"));
7794 }
45ac8f4f 7795 }
252b5132
RH
7796 }
7797
32ec8896 7798 return TRUE;
252b5132
RH
7799}
7800
4d6ed7c8
NC
7801/* An absolute address consists of a section and an offset. If the
7802 section is NULL, the offset itself is the address, otherwise, the
7803 address equals to LOAD_ADDRESS(section) + offset. */
7804
7805struct absaddr
948f632f
DA
7806{
7807 unsigned short section;
7808 bfd_vma offset;
7809};
4d6ed7c8 7810
948f632f
DA
7811/* Find the nearest symbol at or below ADDR. Returns the symbol
7812 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7813
4d6ed7c8 7814static void
dda8d76d
NC
7815find_symbol_for_address (Filedata * filedata,
7816 Elf_Internal_Sym * symtab,
7817 unsigned long nsyms,
7818 const char * strtab,
7819 unsigned long strtab_size,
7820 struct absaddr addr,
7821 const char ** symname,
7822 bfd_vma * offset)
4d6ed7c8 7823{
d3ba0551 7824 bfd_vma dist = 0x100000;
2cf0635d 7825 Elf_Internal_Sym * sym;
948f632f
DA
7826 Elf_Internal_Sym * beg;
7827 Elf_Internal_Sym * end;
2cf0635d 7828 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7829
0b6ae522 7830 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7831 beg = symtab;
7832 end = symtab + nsyms;
0b6ae522 7833
948f632f 7834 while (beg < end)
4d6ed7c8 7835 {
948f632f
DA
7836 bfd_vma value;
7837
7838 sym = beg + (end - beg) / 2;
0b6ae522 7839
948f632f 7840 value = sym->st_value;
0b6ae522
DJ
7841 REMOVE_ARCH_BITS (value);
7842
948f632f 7843 if (sym->st_name != 0
4d6ed7c8 7844 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7845 && addr.offset >= value
7846 && addr.offset - value < dist)
4d6ed7c8
NC
7847 {
7848 best = sym;
0b6ae522 7849 dist = addr.offset - value;
4d6ed7c8
NC
7850 if (!dist)
7851 break;
7852 }
948f632f
DA
7853
7854 if (addr.offset < value)
7855 end = sym;
7856 else
7857 beg = sym + 1;
4d6ed7c8 7858 }
1b31d05e 7859
4d6ed7c8
NC
7860 if (best)
7861 {
57346661 7862 *symname = (best->st_name >= strtab_size
2b692964 7863 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7864 *offset = dist;
7865 return;
7866 }
1b31d05e 7867
4d6ed7c8
NC
7868 *symname = NULL;
7869 *offset = addr.offset;
7870}
7871
32ec8896 7872static /* signed */ int
948f632f
DA
7873symcmp (const void *p, const void *q)
7874{
7875 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7876 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7877
7878 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7879}
7880
7881/* Process the unwind section. */
7882
7883#include "unwind-ia64.h"
7884
7885struct ia64_unw_table_entry
7886{
7887 struct absaddr start;
7888 struct absaddr end;
7889 struct absaddr info;
7890};
7891
7892struct ia64_unw_aux_info
7893{
32ec8896
NC
7894 struct ia64_unw_table_entry * table; /* Unwind table. */
7895 unsigned long table_len; /* Length of unwind table. */
7896 unsigned char * info; /* Unwind info. */
7897 unsigned long info_size; /* Size of unwind info. */
7898 bfd_vma info_addr; /* Starting address of unwind info. */
7899 bfd_vma seg_base; /* Starting address of segment. */
7900 Elf_Internal_Sym * symtab; /* The symbol table. */
7901 unsigned long nsyms; /* Number of symbols. */
7902 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7903 unsigned long nfuns; /* Number of entries in funtab. */
7904 char * strtab; /* The string table. */
7905 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7906};
7907
32ec8896 7908static bfd_boolean
dda8d76d 7909dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7910{
2cf0635d 7911 struct ia64_unw_table_entry * tp;
948f632f 7912 unsigned long j, nfuns;
4d6ed7c8 7913 int in_body;
32ec8896 7914 bfd_boolean res = TRUE;
7036c0e1 7915
948f632f
DA
7916 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7917 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7918 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7919 aux->funtab[nfuns++] = aux->symtab[j];
7920 aux->nfuns = nfuns;
7921 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7922
4d6ed7c8
NC
7923 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7924 {
7925 bfd_vma stamp;
7926 bfd_vma offset;
2cf0635d
NC
7927 const unsigned char * dp;
7928 const unsigned char * head;
53774b7e 7929 const unsigned char * end;
2cf0635d 7930 const char * procname;
4d6ed7c8 7931
dda8d76d 7932 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7933 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7934
7935 fputs ("\n<", stdout);
7936
7937 if (procname)
7938 {
7939 fputs (procname, stdout);
7940
7941 if (offset)
7942 printf ("+%lx", (unsigned long) offset);
7943 }
7944
7945 fputs (">: [", stdout);
7946 print_vma (tp->start.offset, PREFIX_HEX);
7947 fputc ('-', stdout);
7948 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7949 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7950 (unsigned long) (tp->info.offset - aux->seg_base));
7951
53774b7e
NC
7952 /* PR 17531: file: 86232b32. */
7953 if (aux->info == NULL)
7954 continue;
7955
97c0a079
AM
7956 offset = tp->info.offset;
7957 if (tp->info.section)
7958 {
7959 if (tp->info.section >= filedata->file_header.e_shnum)
7960 {
7961 warn (_("Invalid section %u in table entry %ld\n"),
7962 tp->info.section, (long) (tp - aux->table));
7963 res = FALSE;
7964 continue;
7965 }
7966 offset += filedata->section_headers[tp->info.section].sh_addr;
7967 }
7968 offset -= aux->info_addr;
53774b7e 7969 /* PR 17531: file: 0997b4d1. */
90679903
AM
7970 if (offset >= aux->info_size
7971 || aux->info_size - offset < 8)
53774b7e
NC
7972 {
7973 warn (_("Invalid offset %lx in table entry %ld\n"),
7974 (long) tp->info.offset, (long) (tp - aux->table));
32ec8896 7975 res = FALSE;
53774b7e
NC
7976 continue;
7977 }
7978
97c0a079 7979 head = aux->info + offset;
a4a00738 7980 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 7981
86f55779 7982 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
7983 (unsigned) UNW_VER (stamp),
7984 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
7985 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
7986 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 7987 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
7988
7989 if (UNW_VER (stamp) != 1)
7990 {
2b692964 7991 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
7992 continue;
7993 }
7994
7995 in_body = 0;
53774b7e
NC
7996 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
7997 /* PR 17531: file: 16ceda89. */
7998 if (end > aux->info + aux->info_size)
7999 end = aux->info + aux->info_size;
8000 for (dp = head + 8; dp < end;)
b4477bc8 8001 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8002 }
948f632f
DA
8003
8004 free (aux->funtab);
32ec8896
NC
8005
8006 return res;
4d6ed7c8
NC
8007}
8008
53774b7e 8009static bfd_boolean
dda8d76d
NC
8010slurp_ia64_unwind_table (Filedata * filedata,
8011 struct ia64_unw_aux_info * aux,
8012 Elf_Internal_Shdr * sec)
4d6ed7c8 8013{
89fac5e3 8014 unsigned long size, nrelas, i;
2cf0635d
NC
8015 Elf_Internal_Phdr * seg;
8016 struct ia64_unw_table_entry * tep;
8017 Elf_Internal_Shdr * relsec;
8018 Elf_Internal_Rela * rela;
8019 Elf_Internal_Rela * rp;
8020 unsigned char * table;
8021 unsigned char * tp;
8022 Elf_Internal_Sym * sym;
8023 const char * relname;
4d6ed7c8 8024
53774b7e
NC
8025 aux->table_len = 0;
8026
4d6ed7c8
NC
8027 /* First, find the starting address of the segment that includes
8028 this section: */
8029
dda8d76d 8030 if (filedata->file_header.e_phnum)
4d6ed7c8 8031 {
dda8d76d 8032 if (! get_program_headers (filedata))
53774b7e 8033 return FALSE;
4d6ed7c8 8034
dda8d76d
NC
8035 for (seg = filedata->program_headers;
8036 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8037 ++seg)
4d6ed7c8
NC
8038 {
8039 if (seg->p_type != PT_LOAD)
8040 continue;
8041
8042 if (sec->sh_addr >= seg->p_vaddr
8043 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8044 {
8045 aux->seg_base = seg->p_vaddr;
8046 break;
8047 }
8048 }
4d6ed7c8
NC
8049 }
8050
8051 /* Second, build the unwind table from the contents of the unwind section: */
8052 size = sec->sh_size;
dda8d76d 8053 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8054 _("unwind table"));
a6e9f9df 8055 if (!table)
53774b7e 8056 return FALSE;
4d6ed7c8 8057
53774b7e 8058 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8059 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8060 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8061 tep = aux->table;
53774b7e
NC
8062
8063 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8064 {
8065 tep->start.section = SHN_UNDEF;
8066 tep->end.section = SHN_UNDEF;
8067 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8068 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8069 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8070 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8071 tep->start.offset += aux->seg_base;
8072 tep->end.offset += aux->seg_base;
8073 tep->info.offset += aux->seg_base;
8074 }
8075 free (table);
8076
41e92641 8077 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8078 for (relsec = filedata->section_headers;
8079 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8080 ++relsec)
8081 {
8082 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8083 || relsec->sh_info >= filedata->file_header.e_shnum
8084 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8085 continue;
8086
dda8d76d 8087 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8088 & rela, & nrelas))
53774b7e
NC
8089 {
8090 free (aux->table);
8091 aux->table = NULL;
8092 aux->table_len = 0;
8093 return FALSE;
8094 }
4d6ed7c8
NC
8095
8096 for (rp = rela; rp < rela + nrelas; ++rp)
8097 {
4770fb94 8098 unsigned int sym_ndx;
726bd37d
AM
8099 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8100 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8101
82b1b41b
NC
8102 /* PR 17531: file: 9fa67536. */
8103 if (relname == NULL)
8104 {
726bd37d 8105 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8106 continue;
8107 }
948f632f 8108
0112cd26 8109 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 8110 {
82b1b41b 8111 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8112 continue;
8113 }
8114
89fac5e3 8115 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8116
53774b7e
NC
8117 /* PR 17531: file: 5bc8d9bf. */
8118 if (i >= aux->table_len)
8119 {
8120 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8121 continue;
8122 }
8123
4770fb94
AM
8124 sym_ndx = get_reloc_symindex (rp->r_info);
8125 if (sym_ndx >= aux->nsyms)
8126 {
8127 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8128 sym_ndx);
8129 continue;
8130 }
8131 sym = aux->symtab + sym_ndx;
8132
53774b7e 8133 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8134 {
8135 case 0:
8136 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8137 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8138 break;
8139 case 1:
8140 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8141 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8142 break;
8143 case 2:
8144 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8145 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8146 break;
8147 default:
8148 break;
8149 }
8150 }
8151
8152 free (rela);
8153 }
8154
53774b7e 8155 return TRUE;
4d6ed7c8
NC
8156}
8157
32ec8896 8158static bfd_boolean
dda8d76d 8159ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8160{
2cf0635d
NC
8161 Elf_Internal_Shdr * sec;
8162 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8163 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8164 struct ia64_unw_aux_info aux;
32ec8896 8165 bfd_boolean res = TRUE;
f1467e33 8166
4d6ed7c8
NC
8167 memset (& aux, 0, sizeof (aux));
8168
dda8d76d 8169 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8170 {
28d13567 8171 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8172 {
28d13567 8173 if (aux.symtab)
4082ef84 8174 {
28d13567
AM
8175 error (_("Multiple symbol tables encountered\n"));
8176 free (aux.symtab);
8177 aux.symtab = NULL;
4082ef84 8178 free (aux.strtab);
28d13567 8179 aux.strtab = NULL;
4082ef84 8180 }
28d13567
AM
8181 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8182 &aux.strtab, &aux.strtab_size))
8183 return FALSE;
4d6ed7c8
NC
8184 }
8185 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8186 unwcount++;
8187 }
8188
8189 if (!unwcount)
8190 printf (_("\nThere are no unwind sections in this file.\n"));
8191
8192 while (unwcount-- > 0)
8193 {
2cf0635d 8194 char * suffix;
579f31ac
JJ
8195 size_t len, len2;
8196
dda8d76d
NC
8197 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8198 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8199 if (sec->sh_type == SHT_IA_64_UNWIND)
8200 {
8201 unwsec = sec;
8202 break;
8203 }
4082ef84
NC
8204 /* We have already counted the number of SHT_IA64_UNWIND
8205 sections so the loop above should never fail. */
8206 assert (unwsec != NULL);
579f31ac
JJ
8207
8208 unwstart = i + 1;
8209 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8210
e4b17d5c
L
8211 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8212 {
8213 /* We need to find which section group it is in. */
4082ef84 8214 struct group_list * g;
e4b17d5c 8215
978c4450
AM
8216 if (filedata->section_headers_groups == NULL
8217 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8218 i = filedata->file_header.e_shnum;
4082ef84 8219 else
e4b17d5c 8220 {
978c4450 8221 g = filedata->section_headers_groups[i]->root;
18bd398b 8222
4082ef84
NC
8223 for (; g != NULL; g = g->next)
8224 {
dda8d76d 8225 sec = filedata->section_headers + g->section_index;
e4b17d5c 8226
b9e920ec
AM
8227 if (SECTION_NAME_VALID (sec)
8228 && streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
4082ef84
NC
8229 break;
8230 }
8231
8232 if (g == NULL)
dda8d76d 8233 i = filedata->file_header.e_shnum;
4082ef84 8234 }
e4b17d5c 8235 }
b9e920ec
AM
8236 else if (SECTION_NAME_VALID (unwsec)
8237 && strneq (SECTION_NAME (unwsec),
8238 ELF_STRING_ia64_unwind_once, len))
579f31ac 8239 {
18bd398b 8240 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
8241 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
8242 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8243 for (i = 0, sec = filedata->section_headers;
8244 i < filedata->file_header.e_shnum;
579f31ac 8245 ++i, ++sec)
b9e920ec
AM
8246 if (SECTION_NAME_VALID (sec)
8247 && strneq (SECTION_NAME (sec),
8248 ELF_STRING_ia64_unwind_info_once, len2)
18bd398b 8249 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8250 break;
8251 }
8252 else
8253 {
8254 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8255 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8256 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8257 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8258 suffix = "";
b9e920ec
AM
8259 if (SECTION_NAME_VALID (unwsec)
8260 && strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac 8261 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8262 for (i = 0, sec = filedata->section_headers;
8263 i < filedata->file_header.e_shnum;
579f31ac 8264 ++i, ++sec)
b9e920ec
AM
8265 if (SECTION_NAME_VALID (sec)
8266 && strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
18bd398b 8267 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8268 break;
8269 }
8270
dda8d76d 8271 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8272 {
8273 printf (_("\nCould not find unwind info section for "));
8274
dda8d76d 8275 if (filedata->string_table == NULL)
579f31ac
JJ
8276 printf ("%d", unwsec->sh_name);
8277 else
dda8d76d 8278 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8279 }
8280 else
4d6ed7c8 8281 {
4d6ed7c8 8282 aux.info_addr = sec->sh_addr;
dda8d76d 8283 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8284 sec->sh_size,
8285 _("unwind info"));
59245841 8286 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8287
579f31ac 8288 printf (_("\nUnwind section "));
4d6ed7c8 8289
dda8d76d 8290 if (filedata->string_table == NULL)
579f31ac
JJ
8291 printf ("%d", unwsec->sh_name);
8292 else
dda8d76d 8293 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8294
579f31ac 8295 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8296 (unsigned long) unwsec->sh_offset,
89fac5e3 8297 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8298
dda8d76d 8299 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8300 && aux.table_len > 0)
dda8d76d 8301 dump_ia64_unwind (filedata, & aux);
579f31ac 8302
9db70fc3
AM
8303 free ((char *) aux.table);
8304 free ((char *) aux.info);
579f31ac
JJ
8305 aux.table = NULL;
8306 aux.info = NULL;
8307 }
4d6ed7c8 8308 }
4d6ed7c8 8309
9db70fc3
AM
8310 free (aux.symtab);
8311 free ((char *) aux.strtab);
32ec8896
NC
8312
8313 return res;
4d6ed7c8
NC
8314}
8315
3f5e193b 8316struct hppa_unw_table_entry
32ec8896
NC
8317{
8318 struct absaddr start;
8319 struct absaddr end;
8320 unsigned int Cannot_unwind:1; /* 0 */
8321 unsigned int Millicode:1; /* 1 */
8322 unsigned int Millicode_save_sr0:1; /* 2 */
8323 unsigned int Region_description:2; /* 3..4 */
8324 unsigned int reserved1:1; /* 5 */
8325 unsigned int Entry_SR:1; /* 6 */
8326 unsigned int Entry_FR:4; /* Number saved 7..10 */
8327 unsigned int Entry_GR:5; /* Number saved 11..15 */
8328 unsigned int Args_stored:1; /* 16 */
8329 unsigned int Variable_Frame:1; /* 17 */
8330 unsigned int Separate_Package_Body:1; /* 18 */
8331 unsigned int Frame_Extension_Millicode:1; /* 19 */
8332 unsigned int Stack_Overflow_Check:1; /* 20 */
8333 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8334 unsigned int Ada_Region:1; /* 22 */
8335 unsigned int cxx_info:1; /* 23 */
8336 unsigned int cxx_try_catch:1; /* 24 */
8337 unsigned int sched_entry_seq:1; /* 25 */
8338 unsigned int reserved2:1; /* 26 */
8339 unsigned int Save_SP:1; /* 27 */
8340 unsigned int Save_RP:1; /* 28 */
8341 unsigned int Save_MRP_in_frame:1; /* 29 */
8342 unsigned int extn_ptr_defined:1; /* 30 */
8343 unsigned int Cleanup_defined:1; /* 31 */
8344
8345 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8346 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8347 unsigned int Large_frame:1; /* 2 */
8348 unsigned int Pseudo_SP_Set:1; /* 3 */
8349 unsigned int reserved4:1; /* 4 */
8350 unsigned int Total_frame_size:27; /* 5..31 */
8351};
3f5e193b 8352
57346661 8353struct hppa_unw_aux_info
948f632f 8354{
32ec8896
NC
8355 struct hppa_unw_table_entry * table; /* Unwind table. */
8356 unsigned long table_len; /* Length of unwind table. */
8357 bfd_vma seg_base; /* Starting address of segment. */
8358 Elf_Internal_Sym * symtab; /* The symbol table. */
8359 unsigned long nsyms; /* Number of symbols. */
8360 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8361 unsigned long nfuns; /* Number of entries in funtab. */
8362 char * strtab; /* The string table. */
8363 unsigned long strtab_size; /* Size of string table. */
948f632f 8364};
57346661 8365
32ec8896 8366static bfd_boolean
dda8d76d 8367dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8368{
2cf0635d 8369 struct hppa_unw_table_entry * tp;
948f632f 8370 unsigned long j, nfuns;
32ec8896 8371 bfd_boolean res = TRUE;
948f632f
DA
8372
8373 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8374 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8375 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8376 aux->funtab[nfuns++] = aux->symtab[j];
8377 aux->nfuns = nfuns;
8378 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8379
57346661
AM
8380 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8381 {
8382 bfd_vma offset;
2cf0635d 8383 const char * procname;
57346661 8384
dda8d76d 8385 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8386 aux->strtab_size, tp->start, &procname,
8387 &offset);
8388
8389 fputs ("\n<", stdout);
8390
8391 if (procname)
8392 {
8393 fputs (procname, stdout);
8394
8395 if (offset)
8396 printf ("+%lx", (unsigned long) offset);
8397 }
8398
8399 fputs (">: [", stdout);
8400 print_vma (tp->start.offset, PREFIX_HEX);
8401 fputc ('-', stdout);
8402 print_vma (tp->end.offset, PREFIX_HEX);
8403 printf ("]\n\t");
8404
18bd398b
NC
8405#define PF(_m) if (tp->_m) printf (#_m " ");
8406#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8407 PF(Cannot_unwind);
8408 PF(Millicode);
8409 PF(Millicode_save_sr0);
18bd398b 8410 /* PV(Region_description); */
57346661
AM
8411 PF(Entry_SR);
8412 PV(Entry_FR);
8413 PV(Entry_GR);
8414 PF(Args_stored);
8415 PF(Variable_Frame);
8416 PF(Separate_Package_Body);
8417 PF(Frame_Extension_Millicode);
8418 PF(Stack_Overflow_Check);
8419 PF(Two_Instruction_SP_Increment);
8420 PF(Ada_Region);
8421 PF(cxx_info);
8422 PF(cxx_try_catch);
8423 PF(sched_entry_seq);
8424 PF(Save_SP);
8425 PF(Save_RP);
8426 PF(Save_MRP_in_frame);
8427 PF(extn_ptr_defined);
8428 PF(Cleanup_defined);
8429 PF(MPE_XL_interrupt_marker);
8430 PF(HP_UX_interrupt_marker);
8431 PF(Large_frame);
8432 PF(Pseudo_SP_Set);
8433 PV(Total_frame_size);
8434#undef PF
8435#undef PV
8436 }
8437
18bd398b 8438 printf ("\n");
948f632f
DA
8439
8440 free (aux->funtab);
32ec8896
NC
8441
8442 return res;
57346661
AM
8443}
8444
32ec8896 8445static bfd_boolean
dda8d76d
NC
8446slurp_hppa_unwind_table (Filedata * filedata,
8447 struct hppa_unw_aux_info * aux,
8448 Elf_Internal_Shdr * sec)
57346661 8449{
1c0751b2 8450 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8451 Elf_Internal_Phdr * seg;
8452 struct hppa_unw_table_entry * tep;
8453 Elf_Internal_Shdr * relsec;
8454 Elf_Internal_Rela * rela;
8455 Elf_Internal_Rela * rp;
8456 unsigned char * table;
8457 unsigned char * tp;
8458 Elf_Internal_Sym * sym;
8459 const char * relname;
57346661 8460
57346661
AM
8461 /* First, find the starting address of the segment that includes
8462 this section. */
dda8d76d 8463 if (filedata->file_header.e_phnum)
57346661 8464 {
dda8d76d 8465 if (! get_program_headers (filedata))
32ec8896 8466 return FALSE;
57346661 8467
dda8d76d
NC
8468 for (seg = filedata->program_headers;
8469 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8470 ++seg)
8471 {
8472 if (seg->p_type != PT_LOAD)
8473 continue;
8474
8475 if (sec->sh_addr >= seg->p_vaddr
8476 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8477 {
8478 aux->seg_base = seg->p_vaddr;
8479 break;
8480 }
8481 }
8482 }
8483
8484 /* Second, build the unwind table from the contents of the unwind
8485 section. */
8486 size = sec->sh_size;
dda8d76d 8487 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8488 _("unwind table"));
57346661 8489 if (!table)
32ec8896 8490 return FALSE;
57346661 8491
1c0751b2
DA
8492 unw_ent_size = 16;
8493 nentries = size / unw_ent_size;
8494 size = unw_ent_size * nentries;
57346661 8495
e3fdc001 8496 aux->table_len = nentries;
3f5e193b
NC
8497 tep = aux->table = (struct hppa_unw_table_entry *)
8498 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8499
1c0751b2 8500 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8501 {
8502 unsigned int tmp1, tmp2;
8503
8504 tep->start.section = SHN_UNDEF;
8505 tep->end.section = SHN_UNDEF;
8506
1c0751b2
DA
8507 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8508 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8509 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8510 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8511
8512 tep->start.offset += aux->seg_base;
8513 tep->end.offset += aux->seg_base;
57346661
AM
8514
8515 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8516 tep->Millicode = (tmp1 >> 30) & 0x1;
8517 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8518 tep->Region_description = (tmp1 >> 27) & 0x3;
8519 tep->reserved1 = (tmp1 >> 26) & 0x1;
8520 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8521 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8522 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8523 tep->Args_stored = (tmp1 >> 15) & 0x1;
8524 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8525 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8526 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8527 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8528 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8529 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8530 tep->cxx_info = (tmp1 >> 8) & 0x1;
8531 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8532 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8533 tep->reserved2 = (tmp1 >> 5) & 0x1;
8534 tep->Save_SP = (tmp1 >> 4) & 0x1;
8535 tep->Save_RP = (tmp1 >> 3) & 0x1;
8536 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8537 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8538 tep->Cleanup_defined = tmp1 & 0x1;
8539
8540 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8541 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8542 tep->Large_frame = (tmp2 >> 29) & 0x1;
8543 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8544 tep->reserved4 = (tmp2 >> 27) & 0x1;
8545 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8546 }
8547 free (table);
8548
8549 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8550 for (relsec = filedata->section_headers;
8551 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8552 ++relsec)
8553 {
8554 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8555 || relsec->sh_info >= filedata->file_header.e_shnum
8556 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8557 continue;
8558
dda8d76d 8559 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8560 & rela, & nrelas))
32ec8896 8561 return FALSE;
57346661
AM
8562
8563 for (rp = rela; rp < rela + nrelas; ++rp)
8564 {
4770fb94 8565 unsigned int sym_ndx;
726bd37d
AM
8566 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8567 relname = elf_hppa_reloc_type (r_type);
57346661 8568
726bd37d
AM
8569 if (relname == NULL)
8570 {
8571 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8572 continue;
8573 }
8574
57346661 8575 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 8576 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661 8577 {
726bd37d 8578 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8579 continue;
8580 }
8581
8582 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8583 if (i >= aux->table_len)
8584 {
8585 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8586 continue;
8587 }
57346661 8588
4770fb94
AM
8589 sym_ndx = get_reloc_symindex (rp->r_info);
8590 if (sym_ndx >= aux->nsyms)
8591 {
8592 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8593 sym_ndx);
8594 continue;
8595 }
8596 sym = aux->symtab + sym_ndx;
8597
43f6cd05 8598 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8599 {
8600 case 0:
8601 aux->table[i].start.section = sym->st_shndx;
1e456d54 8602 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8603 break;
8604 case 1:
8605 aux->table[i].end.section = sym->st_shndx;
1e456d54 8606 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8607 break;
8608 default:
8609 break;
8610 }
8611 }
8612
8613 free (rela);
8614 }
8615
32ec8896 8616 return TRUE;
57346661
AM
8617}
8618
32ec8896 8619static bfd_boolean
dda8d76d 8620hppa_process_unwind (Filedata * filedata)
57346661 8621{
57346661 8622 struct hppa_unw_aux_info aux;
2cf0635d 8623 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8624 Elf_Internal_Shdr * sec;
18bd398b 8625 unsigned long i;
32ec8896 8626 bfd_boolean res = TRUE;
57346661 8627
dda8d76d 8628 if (filedata->string_table == NULL)
32ec8896 8629 return FALSE;
1b31d05e
NC
8630
8631 memset (& aux, 0, sizeof (aux));
57346661 8632
dda8d76d 8633 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8634 {
28d13567 8635 if (sec->sh_type == SHT_SYMTAB)
57346661 8636 {
28d13567 8637 if (aux.symtab)
4082ef84 8638 {
28d13567
AM
8639 error (_("Multiple symbol tables encountered\n"));
8640 free (aux.symtab);
8641 aux.symtab = NULL;
4082ef84 8642 free (aux.strtab);
28d13567 8643 aux.strtab = NULL;
4082ef84 8644 }
28d13567
AM
8645 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8646 &aux.strtab, &aux.strtab_size))
8647 return FALSE;
57346661 8648 }
b9e920ec
AM
8649 else if (SECTION_NAME_VALID (sec)
8650 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8651 unwsec = sec;
8652 }
8653
8654 if (!unwsec)
8655 printf (_("\nThere are no unwind sections in this file.\n"));
8656
dda8d76d 8657 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8658 {
b9e920ec
AM
8659 if (SECTION_NAME_VALID (sec)
8660 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8661 {
43f6cd05 8662 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8663
d3a49aa8
AM
8664 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8665 "contains %lu entry:\n",
8666 "\nUnwind section '%s' at offset 0x%lx "
8667 "contains %lu entries:\n",
8668 num_unwind),
dda8d76d 8669 printable_section_name (filedata, sec),
57346661 8670 (unsigned long) sec->sh_offset,
d3a49aa8 8671 num_unwind);
57346661 8672
dda8d76d 8673 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
32ec8896 8674 res = FALSE;
66b09c7e
S
8675
8676 if (res && aux.table_len > 0)
32ec8896 8677 {
dda8d76d 8678 if (! dump_hppa_unwind (filedata, &aux))
32ec8896
NC
8679 res = FALSE;
8680 }
57346661 8681
9db70fc3 8682 free ((char *) aux.table);
57346661
AM
8683 aux.table = NULL;
8684 }
8685 }
8686
9db70fc3
AM
8687 free (aux.symtab);
8688 free ((char *) aux.strtab);
32ec8896
NC
8689
8690 return res;
57346661
AM
8691}
8692
0b6ae522
DJ
8693struct arm_section
8694{
a734115a
NC
8695 unsigned char * data; /* The unwind data. */
8696 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8697 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8698 unsigned long nrelas; /* The number of relocations. */
8699 unsigned int rel_type; /* REL or RELA ? */
8700 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8701};
8702
8703struct arm_unw_aux_info
8704{
dda8d76d 8705 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8706 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8707 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8708 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8709 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8710 char * strtab; /* The file's string table. */
8711 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8712};
8713
8714static const char *
dda8d76d
NC
8715arm_print_vma_and_name (Filedata * filedata,
8716 struct arm_unw_aux_info * aux,
8717 bfd_vma fn,
8718 struct absaddr addr)
0b6ae522
DJ
8719{
8720 const char *procname;
8721 bfd_vma sym_offset;
8722
8723 if (addr.section == SHN_UNDEF)
8724 addr.offset = fn;
8725
dda8d76d 8726 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8727 aux->strtab_size, addr, &procname,
8728 &sym_offset);
8729
8730 print_vma (fn, PREFIX_HEX);
8731
8732 if (procname)
8733 {
8734 fputs (" <", stdout);
8735 fputs (procname, stdout);
8736
8737 if (sym_offset)
8738 printf ("+0x%lx", (unsigned long) sym_offset);
8739 fputc ('>', stdout);
8740 }
8741
8742 return procname;
8743}
8744
8745static void
8746arm_free_section (struct arm_section *arm_sec)
8747{
9db70fc3
AM
8748 free (arm_sec->data);
8749 free (arm_sec->rela);
0b6ae522
DJ
8750}
8751
a734115a
NC
8752/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8753 cached section and install SEC instead.
8754 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8755 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8756 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8757 relocation's offset in ADDR.
1b31d05e
NC
8758 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8759 into the string table of the symbol associated with the reloc. If no
8760 reloc was applied store -1 there.
8761 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
8762
8763static bfd_boolean
dda8d76d
NC
8764get_unwind_section_word (Filedata * filedata,
8765 struct arm_unw_aux_info * aux,
1b31d05e
NC
8766 struct arm_section * arm_sec,
8767 Elf_Internal_Shdr * sec,
8768 bfd_vma word_offset,
8769 unsigned int * wordp,
8770 struct absaddr * addr,
8771 bfd_vma * sym_name)
0b6ae522
DJ
8772{
8773 Elf_Internal_Rela *rp;
8774 Elf_Internal_Sym *sym;
8775 const char * relname;
8776 unsigned int word;
8777 bfd_boolean wrapped;
8778
e0a31db1
NC
8779 if (sec == NULL || arm_sec == NULL)
8780 return FALSE;
8781
0b6ae522
DJ
8782 addr->section = SHN_UNDEF;
8783 addr->offset = 0;
8784
1b31d05e
NC
8785 if (sym_name != NULL)
8786 *sym_name = (bfd_vma) -1;
8787
a734115a 8788 /* If necessary, update the section cache. */
0b6ae522
DJ
8789 if (sec != arm_sec->sec)
8790 {
8791 Elf_Internal_Shdr *relsec;
8792
8793 arm_free_section (arm_sec);
8794
8795 arm_sec->sec = sec;
dda8d76d 8796 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8797 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8798 arm_sec->rela = NULL;
8799 arm_sec->nrelas = 0;
8800
dda8d76d
NC
8801 for (relsec = filedata->section_headers;
8802 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8803 ++relsec)
8804 {
dda8d76d
NC
8805 if (relsec->sh_info >= filedata->file_header.e_shnum
8806 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8807 /* PR 15745: Check the section type as well. */
8808 || (relsec->sh_type != SHT_REL
8809 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8810 continue;
8811
a734115a 8812 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8813 if (relsec->sh_type == SHT_REL)
8814 {
dda8d76d 8815 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8816 relsec->sh_size,
8817 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8818 return FALSE;
0b6ae522 8819 }
1ae40aa4 8820 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8821 {
dda8d76d 8822 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8823 relsec->sh_size,
8824 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8825 return FALSE;
0b6ae522 8826 }
1ae40aa4 8827 break;
0b6ae522
DJ
8828 }
8829
8830 arm_sec->next_rela = arm_sec->rela;
8831 }
8832
a734115a 8833 /* If there is no unwind data we can do nothing. */
0b6ae522 8834 if (arm_sec->data == NULL)
a734115a 8835 return FALSE;
0b6ae522 8836
e0a31db1 8837 /* If the offset is invalid then fail. */
f32ba729
NC
8838 if (/* PR 21343 *//* PR 18879 */
8839 sec->sh_size < 4
8840 || word_offset > (sec->sh_size - 4)
1a915552 8841 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
8842 return FALSE;
8843
a734115a 8844 /* Get the word at the required offset. */
0b6ae522
DJ
8845 word = byte_get (arm_sec->data + word_offset, 4);
8846
0eff7165
NC
8847 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8848 if (arm_sec->rela == NULL)
8849 {
8850 * wordp = word;
8851 return TRUE;
8852 }
8853
a734115a 8854 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
8855 wrapped = FALSE;
8856 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8857 {
8858 bfd_vma prelval, offset;
8859
8860 if (rp->r_offset > word_offset && !wrapped)
8861 {
8862 rp = arm_sec->rela;
8863 wrapped = TRUE;
8864 }
8865 if (rp->r_offset > word_offset)
8866 break;
8867
8868 if (rp->r_offset & 3)
8869 {
8870 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8871 (unsigned long) rp->r_offset);
8872 continue;
8873 }
8874
8875 if (rp->r_offset < word_offset)
8876 continue;
8877
74e1a04b
NC
8878 /* PR 17531: file: 027-161405-0.004 */
8879 if (aux->symtab == NULL)
8880 continue;
8881
0b6ae522
DJ
8882 if (arm_sec->rel_type == SHT_REL)
8883 {
8884 offset = word & 0x7fffffff;
8885 if (offset & 0x40000000)
8886 offset |= ~ (bfd_vma) 0x7fffffff;
8887 }
a734115a 8888 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8889 offset = rp->r_addend;
a734115a 8890 else
74e1a04b
NC
8891 {
8892 error (_("Unknown section relocation type %d encountered\n"),
8893 arm_sec->rel_type);
8894 break;
8895 }
0b6ae522 8896
071436c6
NC
8897 /* PR 17531 file: 027-1241568-0.004. */
8898 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8899 {
8900 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8901 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8902 break;
8903 }
8904
8905 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8906 offset += sym->st_value;
8907 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8908
a734115a 8909 /* Check that we are processing the expected reloc type. */
dda8d76d 8910 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8911 {
8912 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8913 if (relname == NULL)
8914 {
8915 warn (_("Skipping unknown ARM relocation type: %d\n"),
8916 (int) ELF32_R_TYPE (rp->r_info));
8917 continue;
8918 }
a734115a
NC
8919
8920 if (streq (relname, "R_ARM_NONE"))
8921 continue;
0b4362b0 8922
a734115a
NC
8923 if (! streq (relname, "R_ARM_PREL31"))
8924 {
071436c6 8925 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8926 continue;
8927 }
8928 }
dda8d76d 8929 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8930 {
8931 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8932 if (relname == NULL)
8933 {
8934 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8935 (int) ELF32_R_TYPE (rp->r_info));
8936 continue;
8937 }
0b4362b0 8938
a734115a
NC
8939 if (streq (relname, "R_C6000_NONE"))
8940 continue;
8941
8942 if (! streq (relname, "R_C6000_PREL31"))
8943 {
071436c6 8944 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8945 continue;
8946 }
8947
8948 prelval >>= 1;
8949 }
8950 else
74e1a04b
NC
8951 {
8952 /* This function currently only supports ARM and TI unwinders. */
8953 warn (_("Only TI and ARM unwinders are currently supported\n"));
8954 break;
8955 }
fa197c1c 8956
0b6ae522
DJ
8957 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
8958 addr->section = sym->st_shndx;
8959 addr->offset = offset;
74e1a04b 8960
1b31d05e
NC
8961 if (sym_name)
8962 * sym_name = sym->st_name;
0b6ae522
DJ
8963 break;
8964 }
8965
8966 *wordp = word;
8967 arm_sec->next_rela = rp;
8968
a734115a 8969 return TRUE;
0b6ae522
DJ
8970}
8971
a734115a
NC
8972static const char *tic6x_unwind_regnames[16] =
8973{
0b4362b0
RM
8974 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
8975 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
8976 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
8977};
fa197c1c 8978
0b6ae522 8979static void
fa197c1c 8980decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 8981{
fa197c1c
PB
8982 int i;
8983
8984 for (i = 12; mask; mask >>= 1, i--)
8985 {
8986 if (mask & 1)
8987 {
8988 fputs (tic6x_unwind_regnames[i], stdout);
8989 if (mask > 1)
8990 fputs (", ", stdout);
8991 }
8992 }
8993}
0b6ae522
DJ
8994
8995#define ADVANCE \
8996 if (remaining == 0 && more_words) \
8997 { \
8998 data_offset += 4; \
dda8d76d 8999 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9000 data_offset, & word, & addr, NULL)) \
32ec8896 9001 return FALSE; \
0b6ae522
DJ
9002 remaining = 4; \
9003 more_words--; \
9004 } \
9005
9006#define GET_OP(OP) \
9007 ADVANCE; \
9008 if (remaining) \
9009 { \
9010 remaining--; \
9011 (OP) = word >> 24; \
9012 word <<= 8; \
9013 } \
9014 else \
9015 { \
2b692964 9016 printf (_("[Truncated opcode]\n")); \
32ec8896 9017 return FALSE; \
0b6ae522 9018 } \
cc5914eb 9019 printf ("0x%02x ", OP)
0b6ae522 9020
32ec8896 9021static bfd_boolean
dda8d76d
NC
9022decode_arm_unwind_bytecode (Filedata * filedata,
9023 struct arm_unw_aux_info * aux,
948f632f
DA
9024 unsigned int word,
9025 unsigned int remaining,
9026 unsigned int more_words,
9027 bfd_vma data_offset,
9028 Elf_Internal_Shdr * data_sec,
9029 struct arm_section * data_arm_sec)
fa197c1c
PB
9030{
9031 struct absaddr addr;
32ec8896 9032 bfd_boolean res = TRUE;
0b6ae522
DJ
9033
9034 /* Decode the unwinding instructions. */
9035 while (1)
9036 {
9037 unsigned int op, op2;
9038
9039 ADVANCE;
9040 if (remaining == 0)
9041 break;
9042 remaining--;
9043 op = word >> 24;
9044 word <<= 8;
9045
cc5914eb 9046 printf (" 0x%02x ", op);
0b6ae522
DJ
9047
9048 if ((op & 0xc0) == 0x00)
9049 {
9050 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9051
cc5914eb 9052 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9053 }
9054 else if ((op & 0xc0) == 0x40)
9055 {
9056 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9057
cc5914eb 9058 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9059 }
9060 else if ((op & 0xf0) == 0x80)
9061 {
9062 GET_OP (op2);
9063 if (op == 0x80 && op2 == 0)
9064 printf (_("Refuse to unwind"));
9065 else
9066 {
9067 unsigned int mask = ((op & 0x0f) << 8) | op2;
32ec8896 9068 bfd_boolean first = TRUE;
0b6ae522 9069 int i;
2b692964 9070
0b6ae522
DJ
9071 printf ("pop {");
9072 for (i = 0; i < 12; i++)
9073 if (mask & (1 << i))
9074 {
9075 if (first)
32ec8896 9076 first = FALSE;
0b6ae522
DJ
9077 else
9078 printf (", ");
9079 printf ("r%d", 4 + i);
9080 }
9081 printf ("}");
9082 }
9083 }
9084 else if ((op & 0xf0) == 0x90)
9085 {
9086 if (op == 0x9d || op == 0x9f)
9087 printf (_(" [Reserved]"));
9088 else
cc5914eb 9089 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9090 }
9091 else if ((op & 0xf0) == 0xa0)
9092 {
9093 int end = 4 + (op & 0x07);
32ec8896 9094 bfd_boolean first = TRUE;
0b6ae522 9095 int i;
61865e30 9096
0b6ae522
DJ
9097 printf (" pop {");
9098 for (i = 4; i <= end; i++)
9099 {
9100 if (first)
32ec8896 9101 first = FALSE;
0b6ae522
DJ
9102 else
9103 printf (", ");
9104 printf ("r%d", i);
9105 }
9106 if (op & 0x08)
9107 {
1b31d05e 9108 if (!first)
0b6ae522
DJ
9109 printf (", ");
9110 printf ("r14");
9111 }
9112 printf ("}");
9113 }
9114 else if (op == 0xb0)
9115 printf (_(" finish"));
9116 else if (op == 0xb1)
9117 {
9118 GET_OP (op2);
9119 if (op2 == 0 || (op2 & 0xf0) != 0)
9120 printf (_("[Spare]"));
9121 else
9122 {
9123 unsigned int mask = op2 & 0x0f;
32ec8896 9124 bfd_boolean first = TRUE;
0b6ae522 9125 int i;
61865e30 9126
0b6ae522
DJ
9127 printf ("pop {");
9128 for (i = 0; i < 12; i++)
9129 if (mask & (1 << i))
9130 {
9131 if (first)
32ec8896 9132 first = FALSE;
0b6ae522
DJ
9133 else
9134 printf (", ");
9135 printf ("r%d", i);
9136 }
9137 printf ("}");
9138 }
9139 }
9140 else if (op == 0xb2)
9141 {
b115cf96 9142 unsigned char buf[9];
0b6ae522
DJ
9143 unsigned int i, len;
9144 unsigned long offset;
61865e30 9145
b115cf96 9146 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9147 {
9148 GET_OP (buf[i]);
9149 if ((buf[i] & 0x80) == 0)
9150 break;
9151 }
4082ef84 9152 if (i == sizeof (buf))
32ec8896 9153 {
27a45f42 9154 error (_("corrupt change to vsp\n"));
32ec8896
NC
9155 res = FALSE;
9156 }
4082ef84
NC
9157 else
9158 {
cd30bcef 9159 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
4082ef84
NC
9160 assert (len == i + 1);
9161 offset = offset * 4 + 0x204;
9162 printf ("vsp = vsp + %ld", offset);
9163 }
0b6ae522 9164 }
61865e30 9165 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9166 {
61865e30
NC
9167 unsigned int first, last;
9168
9169 GET_OP (op2);
9170 first = op2 >> 4;
9171 last = op2 & 0x0f;
9172 if (op == 0xc8)
9173 first = first + 16;
9174 printf ("pop {D%d", first);
9175 if (last)
9176 printf ("-D%d", first + last);
9177 printf ("}");
9178 }
9179 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9180 {
9181 unsigned int count = op & 0x07;
9182
9183 printf ("pop {D8");
9184 if (count)
9185 printf ("-D%d", 8 + count);
9186 printf ("}");
9187 }
9188 else if (op >= 0xc0 && op <= 0xc5)
9189 {
9190 unsigned int count = op & 0x07;
9191
9192 printf (" pop {wR10");
9193 if (count)
9194 printf ("-wR%d", 10 + count);
9195 printf ("}");
9196 }
9197 else if (op == 0xc6)
9198 {
9199 unsigned int first, last;
9200
9201 GET_OP (op2);
9202 first = op2 >> 4;
9203 last = op2 & 0x0f;
9204 printf ("pop {wR%d", first);
9205 if (last)
9206 printf ("-wR%d", first + last);
9207 printf ("}");
9208 }
9209 else if (op == 0xc7)
9210 {
9211 GET_OP (op2);
9212 if (op2 == 0 || (op2 & 0xf0) != 0)
9213 printf (_("[Spare]"));
0b6ae522
DJ
9214 else
9215 {
61865e30 9216 unsigned int mask = op2 & 0x0f;
32ec8896 9217 bfd_boolean first = TRUE;
61865e30
NC
9218 int i;
9219
9220 printf ("pop {");
9221 for (i = 0; i < 4; i++)
9222 if (mask & (1 << i))
9223 {
9224 if (first)
32ec8896 9225 first = FALSE;
61865e30
NC
9226 else
9227 printf (", ");
9228 printf ("wCGR%d", i);
9229 }
9230 printf ("}");
0b6ae522
DJ
9231 }
9232 }
61865e30 9233 else
32ec8896
NC
9234 {
9235 printf (_(" [unsupported opcode]"));
9236 res = FALSE;
9237 }
9238
0b6ae522
DJ
9239 printf ("\n");
9240 }
32ec8896
NC
9241
9242 return res;
fa197c1c
PB
9243}
9244
32ec8896 9245static bfd_boolean
dda8d76d
NC
9246decode_tic6x_unwind_bytecode (Filedata * filedata,
9247 struct arm_unw_aux_info * aux,
948f632f
DA
9248 unsigned int word,
9249 unsigned int remaining,
9250 unsigned int more_words,
9251 bfd_vma data_offset,
9252 Elf_Internal_Shdr * data_sec,
9253 struct arm_section * data_arm_sec)
fa197c1c
PB
9254{
9255 struct absaddr addr;
9256
9257 /* Decode the unwinding instructions. */
9258 while (1)
9259 {
9260 unsigned int op, op2;
9261
9262 ADVANCE;
9263 if (remaining == 0)
9264 break;
9265 remaining--;
9266 op = word >> 24;
9267 word <<= 8;
9268
9cf03b7e 9269 printf (" 0x%02x ", op);
fa197c1c
PB
9270
9271 if ((op & 0xc0) == 0x00)
9272 {
9273 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9274 printf (" sp = sp + %d", offset);
fa197c1c
PB
9275 }
9276 else if ((op & 0xc0) == 0x80)
9277 {
9278 GET_OP (op2);
9279 if (op == 0x80 && op2 == 0)
9280 printf (_("Refuse to unwind"));
9281 else
9282 {
9283 unsigned int mask = ((op & 0x1f) << 8) | op2;
9284 if (op & 0x20)
9285 printf ("pop compact {");
9286 else
9287 printf ("pop {");
9288
9289 decode_tic6x_unwind_regmask (mask);
9290 printf("}");
9291 }
9292 }
9293 else if ((op & 0xf0) == 0xc0)
9294 {
9295 unsigned int reg;
9296 unsigned int nregs;
9297 unsigned int i;
9298 const char *name;
a734115a
NC
9299 struct
9300 {
32ec8896
NC
9301 unsigned int offset;
9302 unsigned int reg;
fa197c1c
PB
9303 } regpos[16];
9304
9305 /* Scan entire instruction first so that GET_OP output is not
9306 interleaved with disassembly. */
9307 nregs = 0;
9308 for (i = 0; nregs < (op & 0xf); i++)
9309 {
9310 GET_OP (op2);
9311 reg = op2 >> 4;
9312 if (reg != 0xf)
9313 {
9314 regpos[nregs].offset = i * 2;
9315 regpos[nregs].reg = reg;
9316 nregs++;
9317 }
9318
9319 reg = op2 & 0xf;
9320 if (reg != 0xf)
9321 {
9322 regpos[nregs].offset = i * 2 + 1;
9323 regpos[nregs].reg = reg;
9324 nregs++;
9325 }
9326 }
9327
9328 printf (_("pop frame {"));
18344509 9329 if (nregs == 0)
fa197c1c 9330 {
18344509
NC
9331 printf (_("*corrupt* - no registers specified"));
9332 }
9333 else
9334 {
9335 reg = nregs - 1;
9336 for (i = i * 2; i > 0; i--)
fa197c1c 9337 {
18344509
NC
9338 if (regpos[reg].offset == i - 1)
9339 {
9340 name = tic6x_unwind_regnames[regpos[reg].reg];
9341 if (reg > 0)
9342 reg--;
9343 }
9344 else
9345 name = _("[pad]");
fa197c1c 9346
18344509
NC
9347 fputs (name, stdout);
9348 if (i > 1)
9349 printf (", ");
9350 }
fa197c1c
PB
9351 }
9352
9353 printf ("}");
9354 }
9355 else if (op == 0xd0)
9356 printf (" MOV FP, SP");
9357 else if (op == 0xd1)
9358 printf (" __c6xabi_pop_rts");
9359 else if (op == 0xd2)
9360 {
9361 unsigned char buf[9];
9362 unsigned int i, len;
9363 unsigned long offset;
a734115a 9364
fa197c1c
PB
9365 for (i = 0; i < sizeof (buf); i++)
9366 {
9367 GET_OP (buf[i]);
9368 if ((buf[i] & 0x80) == 0)
9369 break;
9370 }
0eff7165
NC
9371 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9372 if (i == sizeof (buf))
9373 {
0eff7165 9374 warn (_("Corrupt stack pointer adjustment detected\n"));
32ec8896 9375 return FALSE;
0eff7165 9376 }
948f632f 9377
cd30bcef 9378 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
fa197c1c
PB
9379 assert (len == i + 1);
9380 offset = offset * 8 + 0x408;
9381 printf (_("sp = sp + %ld"), offset);
9382 }
9383 else if ((op & 0xf0) == 0xe0)
9384 {
9385 if ((op & 0x0f) == 7)
9386 printf (" RETURN");
9387 else
9388 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9389 }
9390 else
9391 {
9392 printf (_(" [unsupported opcode]"));
9393 }
9394 putchar ('\n');
9395 }
32ec8896
NC
9396
9397 return TRUE;
fa197c1c
PB
9398}
9399
9400static bfd_vma
dda8d76d 9401arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9402{
9403 bfd_vma offset;
9404
9405 offset = word & 0x7fffffff;
9406 if (offset & 0x40000000)
9407 offset |= ~ (bfd_vma) 0x7fffffff;
9408
dda8d76d 9409 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9410 offset <<= 1;
9411
9412 return offset + where;
9413}
9414
32ec8896 9415static bfd_boolean
dda8d76d
NC
9416decode_arm_unwind (Filedata * filedata,
9417 struct arm_unw_aux_info * aux,
1b31d05e
NC
9418 unsigned int word,
9419 unsigned int remaining,
9420 bfd_vma data_offset,
9421 Elf_Internal_Shdr * data_sec,
9422 struct arm_section * data_arm_sec)
fa197c1c
PB
9423{
9424 int per_index;
9425 unsigned int more_words = 0;
37e14bc3 9426 struct absaddr addr;
1b31d05e 9427 bfd_vma sym_name = (bfd_vma) -1;
97953bab 9428 bfd_boolean res = TRUE;
fa197c1c
PB
9429
9430 if (remaining == 0)
9431 {
1b31d05e
NC
9432 /* Fetch the first word.
9433 Note - when decoding an object file the address extracted
9434 here will always be 0. So we also pass in the sym_name
9435 parameter so that we can find the symbol associated with
9436 the personality routine. */
dda8d76d 9437 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9438 & word, & addr, & sym_name))
32ec8896 9439 return FALSE;
1b31d05e 9440
fa197c1c
PB
9441 remaining = 4;
9442 }
c93dbb25
CZ
9443 else
9444 {
9445 addr.section = SHN_UNDEF;
9446 addr.offset = 0;
9447 }
fa197c1c
PB
9448
9449 if ((word & 0x80000000) == 0)
9450 {
9451 /* Expand prel31 for personality routine. */
9452 bfd_vma fn;
9453 const char *procname;
9454
dda8d76d 9455 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9456 printf (_(" Personality routine: "));
1b31d05e
NC
9457 if (fn == 0
9458 && addr.section == SHN_UNDEF && addr.offset == 0
9459 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9460 {
9461 procname = aux->strtab + sym_name;
9462 print_vma (fn, PREFIX_HEX);
9463 if (procname)
9464 {
9465 fputs (" <", stdout);
9466 fputs (procname, stdout);
9467 fputc ('>', stdout);
9468 }
9469 }
9470 else
dda8d76d 9471 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9472 fputc ('\n', stdout);
9473
9474 /* The GCC personality routines use the standard compact
9475 encoding, starting with one byte giving the number of
9476 words. */
9477 if (procname != NULL
9478 && (const_strneq (procname, "__gcc_personality_v0")
9479 || const_strneq (procname, "__gxx_personality_v0")
9480 || const_strneq (procname, "__gcj_personality_v0")
9481 || const_strneq (procname, "__gnu_objc_personality_v0")))
9482 {
9483 remaining = 0;
9484 more_words = 1;
9485 ADVANCE;
9486 if (!remaining)
9487 {
9488 printf (_(" [Truncated data]\n"));
32ec8896 9489 return FALSE;
fa197c1c
PB
9490 }
9491 more_words = word >> 24;
9492 word <<= 8;
9493 remaining--;
9494 per_index = -1;
9495 }
9496 else
32ec8896 9497 return TRUE;
fa197c1c
PB
9498 }
9499 else
9500 {
1b31d05e 9501 /* ARM EHABI Section 6.3:
0b4362b0 9502
1b31d05e 9503 An exception-handling table entry for the compact model looks like:
0b4362b0 9504
1b31d05e
NC
9505 31 30-28 27-24 23-0
9506 -- ----- ----- ----
9507 1 0 index Data for personalityRoutine[index] */
9508
dda8d76d 9509 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9510 && (word & 0x70000000))
32ec8896
NC
9511 {
9512 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
9513 res = FALSE;
9514 }
1b31d05e 9515
fa197c1c 9516 per_index = (word >> 24) & 0x7f;
1b31d05e 9517 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9518 if (per_index == 0)
9519 {
9520 more_words = 0;
9521 word <<= 8;
9522 remaining--;
9523 }
9524 else if (per_index < 3)
9525 {
9526 more_words = (word >> 16) & 0xff;
9527 word <<= 16;
9528 remaining -= 2;
9529 }
9530 }
9531
dda8d76d 9532 switch (filedata->file_header.e_machine)
fa197c1c
PB
9533 {
9534 case EM_ARM:
9535 if (per_index < 3)
9536 {
dda8d76d 9537 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9538 data_offset, data_sec, data_arm_sec))
9539 res = FALSE;
fa197c1c
PB
9540 }
9541 else
1b31d05e
NC
9542 {
9543 warn (_("Unknown ARM compact model index encountered\n"));
9544 printf (_(" [reserved]\n"));
32ec8896 9545 res = FALSE;
1b31d05e 9546 }
fa197c1c
PB
9547 break;
9548
9549 case EM_TI_C6000:
9550 if (per_index < 3)
9551 {
dda8d76d 9552 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9553 data_offset, data_sec, data_arm_sec))
9554 res = FALSE;
fa197c1c
PB
9555 }
9556 else if (per_index < 5)
9557 {
9558 if (((word >> 17) & 0x7f) == 0x7f)
9559 printf (_(" Restore stack from frame pointer\n"));
9560 else
9561 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9562 printf (_(" Registers restored: "));
9563 if (per_index == 4)
9564 printf (" (compact) ");
9565 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9566 putchar ('\n');
9567 printf (_(" Return register: %s\n"),
9568 tic6x_unwind_regnames[word & 0xf]);
9569 }
9570 else
1b31d05e 9571 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9572 break;
9573
9574 default:
74e1a04b 9575 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9576 filedata->file_header.e_machine);
32ec8896 9577 res = FALSE;
fa197c1c 9578 }
0b6ae522
DJ
9579
9580 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9581
9582 return res;
0b6ae522
DJ
9583}
9584
32ec8896 9585static bfd_boolean
dda8d76d
NC
9586dump_arm_unwind (Filedata * filedata,
9587 struct arm_unw_aux_info * aux,
9588 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9589{
9590 struct arm_section exidx_arm_sec, extab_arm_sec;
9591 unsigned int i, exidx_len;
948f632f 9592 unsigned long j, nfuns;
32ec8896 9593 bfd_boolean res = TRUE;
0b6ae522
DJ
9594
9595 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9596 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9597 exidx_len = exidx_sec->sh_size / 8;
9598
948f632f
DA
9599 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9600 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9601 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9602 aux->funtab[nfuns++] = aux->symtab[j];
9603 aux->nfuns = nfuns;
9604 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9605
0b6ae522
DJ
9606 for (i = 0; i < exidx_len; i++)
9607 {
9608 unsigned int exidx_fn, exidx_entry;
9609 struct absaddr fn_addr, entry_addr;
9610 bfd_vma fn;
9611
9612 fputc ('\n', stdout);
9613
dda8d76d 9614 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9615 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9616 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9617 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9618 {
948f632f 9619 free (aux->funtab);
1b31d05e
NC
9620 arm_free_section (& exidx_arm_sec);
9621 arm_free_section (& extab_arm_sec);
32ec8896 9622 return FALSE;
0b6ae522
DJ
9623 }
9624
83c257ca
NC
9625 /* ARM EHABI, Section 5:
9626 An index table entry consists of 2 words.
9627 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9628 if (exidx_fn & 0x80000000)
32ec8896
NC
9629 {
9630 warn (_("corrupt index table entry: %x\n"), exidx_fn);
9631 res = FALSE;
9632 }
83c257ca 9633
dda8d76d 9634 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9635
dda8d76d 9636 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9637 fputs (": ", stdout);
9638
9639 if (exidx_entry == 1)
9640 {
9641 print_vma (exidx_entry, PREFIX_HEX);
9642 fputs (" [cantunwind]\n", stdout);
9643 }
9644 else if (exidx_entry & 0x80000000)
9645 {
9646 print_vma (exidx_entry, PREFIX_HEX);
9647 fputc ('\n', stdout);
dda8d76d 9648 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9649 }
9650 else
9651 {
8f73510c 9652 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9653 Elf_Internal_Shdr *table_sec;
9654
9655 fputs ("@", stdout);
dda8d76d 9656 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9657 print_vma (table, PREFIX_HEX);
9658 printf ("\n");
9659
9660 /* Locate the matching .ARM.extab. */
9661 if (entry_addr.section != SHN_UNDEF
dda8d76d 9662 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9663 {
dda8d76d 9664 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9665 table_offset = entry_addr.offset;
1a915552
NC
9666 /* PR 18879 */
9667 if (table_offset > table_sec->sh_size
9668 || ((bfd_signed_vma) table_offset) < 0)
9669 {
9670 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9671 (unsigned long) table_offset,
dda8d76d 9672 printable_section_name (filedata, table_sec));
32ec8896 9673 res = FALSE;
1a915552
NC
9674 continue;
9675 }
0b6ae522
DJ
9676 }
9677 else
9678 {
dda8d76d 9679 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9680 if (table_sec != NULL)
9681 table_offset = table - table_sec->sh_addr;
9682 }
32ec8896 9683
0b6ae522
DJ
9684 if (table_sec == NULL)
9685 {
9686 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9687 (unsigned long) table);
32ec8896 9688 res = FALSE;
0b6ae522
DJ
9689 continue;
9690 }
32ec8896 9691
dda8d76d 9692 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896
NC
9693 &extab_arm_sec))
9694 res = FALSE;
0b6ae522
DJ
9695 }
9696 }
9697
9698 printf ("\n");
9699
948f632f 9700 free (aux->funtab);
0b6ae522
DJ
9701 arm_free_section (&exidx_arm_sec);
9702 arm_free_section (&extab_arm_sec);
32ec8896
NC
9703
9704 return res;
0b6ae522
DJ
9705}
9706
fa197c1c 9707/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9708
32ec8896 9709static bfd_boolean
dda8d76d 9710arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9711{
9712 struct arm_unw_aux_info aux;
9713 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9714 Elf_Internal_Shdr *sec;
9715 unsigned long i;
fa197c1c 9716 unsigned int sec_type;
32ec8896 9717 bfd_boolean res = TRUE;
0b6ae522 9718
dda8d76d 9719 switch (filedata->file_header.e_machine)
fa197c1c
PB
9720 {
9721 case EM_ARM:
9722 sec_type = SHT_ARM_EXIDX;
9723 break;
9724
9725 case EM_TI_C6000:
9726 sec_type = SHT_C6000_UNWIND;
9727 break;
9728
0b4362b0 9729 default:
74e1a04b 9730 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9731 filedata->file_header.e_machine);
32ec8896 9732 return FALSE;
fa197c1c
PB
9733 }
9734
dda8d76d 9735 if (filedata->string_table == NULL)
32ec8896 9736 return FALSE;
1b31d05e
NC
9737
9738 memset (& aux, 0, sizeof (aux));
dda8d76d 9739 aux.filedata = filedata;
0b6ae522 9740
dda8d76d 9741 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9742 {
28d13567 9743 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9744 {
28d13567 9745 if (aux.symtab)
74e1a04b 9746 {
28d13567
AM
9747 error (_("Multiple symbol tables encountered\n"));
9748 free (aux.symtab);
9749 aux.symtab = NULL;
74e1a04b 9750 free (aux.strtab);
28d13567 9751 aux.strtab = NULL;
74e1a04b 9752 }
28d13567
AM
9753 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9754 &aux.strtab, &aux.strtab_size))
9755 return FALSE;
0b6ae522 9756 }
fa197c1c 9757 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9758 unwsec = sec;
9759 }
9760
1b31d05e 9761 if (unwsec == NULL)
0b6ae522 9762 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9763 else
dda8d76d 9764 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9765 {
9766 if (sec->sh_type == sec_type)
9767 {
d3a49aa8
AM
9768 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9769 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9770 "contains %lu entry:\n",
9771 "\nUnwind section '%s' at offset 0x%lx "
9772 "contains %lu entries:\n",
9773 num_unwind),
dda8d76d 9774 printable_section_name (filedata, sec),
1b31d05e 9775 (unsigned long) sec->sh_offset,
d3a49aa8 9776 num_unwind);
0b6ae522 9777
dda8d76d 9778 if (! dump_arm_unwind (filedata, &aux, sec))
32ec8896 9779 res = FALSE;
1b31d05e
NC
9780 }
9781 }
0b6ae522 9782
9db70fc3
AM
9783 free (aux.symtab);
9784 free ((char *) aux.strtab);
32ec8896
NC
9785
9786 return res;
0b6ae522
DJ
9787}
9788
32ec8896 9789static bfd_boolean
dda8d76d 9790process_unwind (Filedata * filedata)
57346661 9791{
2cf0635d
NC
9792 struct unwind_handler
9793 {
32ec8896 9794 unsigned int machtype;
dda8d76d 9795 bfd_boolean (* handler)(Filedata *);
2cf0635d
NC
9796 } handlers[] =
9797 {
0b6ae522 9798 { EM_ARM, arm_process_unwind },
57346661
AM
9799 { EM_IA_64, ia64_process_unwind },
9800 { EM_PARISC, hppa_process_unwind },
fa197c1c 9801 { EM_TI_C6000, arm_process_unwind },
32ec8896 9802 { 0, NULL }
57346661
AM
9803 };
9804 int i;
9805
9806 if (!do_unwind)
32ec8896 9807 return TRUE;
57346661
AM
9808
9809 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9810 if (filedata->file_header.e_machine == handlers[i].machtype)
9811 return handlers[i].handler (filedata);
57346661 9812
1b31d05e 9813 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9814 get_machine_name (filedata->file_header.e_machine));
32ec8896 9815 return TRUE;
57346661
AM
9816}
9817
37c18eed
SD
9818static void
9819dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
9820{
9821 switch (entry->d_tag)
9822 {
9823 case DT_AARCH64_BTI_PLT:
1dbade74 9824 case DT_AARCH64_PAC_PLT:
37c18eed
SD
9825 break;
9826 default:
9827 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9828 break;
9829 }
9830 putchar ('\n');
9831}
9832
252b5132 9833static void
978c4450 9834dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
9835{
9836 switch (entry->d_tag)
9837 {
9838 case DT_MIPS_FLAGS:
9839 if (entry->d_un.d_val == 0)
4b68bca3 9840 printf (_("NONE"));
252b5132
RH
9841 else
9842 {
9843 static const char * opts[] =
9844 {
9845 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9846 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9847 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9848 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9849 "RLD_ORDER_SAFE"
9850 };
9851 unsigned int cnt;
32ec8896 9852 bfd_boolean first = TRUE;
2b692964 9853
60bca95a 9854 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9855 if (entry->d_un.d_val & (1 << cnt))
9856 {
9857 printf ("%s%s", first ? "" : " ", opts[cnt]);
32ec8896 9858 first = FALSE;
252b5132 9859 }
252b5132
RH
9860 }
9861 break;
103f02d3 9862
252b5132 9863 case DT_MIPS_IVERSION:
978c4450
AM
9864 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
9865 printf (_("Interface Version: %s"),
9866 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 9867 else
76ca31c0
NC
9868 {
9869 char buf[40];
9870 sprintf_vma (buf, entry->d_un.d_ptr);
9871 /* Note: coded this way so that there is a single string for translation. */
9872 printf (_("<corrupt: %s>"), buf);
9873 }
252b5132 9874 break;
103f02d3 9875
252b5132
RH
9876 case DT_MIPS_TIME_STAMP:
9877 {
d5b07ef4 9878 char timebuf[128];
2cf0635d 9879 struct tm * tmp;
91d6fa6a 9880 time_t atime = entry->d_un.d_val;
82b1b41b 9881
91d6fa6a 9882 tmp = gmtime (&atime);
82b1b41b
NC
9883 /* PR 17531: file: 6accc532. */
9884 if (tmp == NULL)
9885 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9886 else
9887 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9888 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9889 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9890 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9891 }
9892 break;
103f02d3 9893
252b5132
RH
9894 case DT_MIPS_RLD_VERSION:
9895 case DT_MIPS_LOCAL_GOTNO:
9896 case DT_MIPS_CONFLICTNO:
9897 case DT_MIPS_LIBLISTNO:
9898 case DT_MIPS_SYMTABNO:
9899 case DT_MIPS_UNREFEXTNO:
9900 case DT_MIPS_HIPAGENO:
9901 case DT_MIPS_DELTA_CLASS_NO:
9902 case DT_MIPS_DELTA_INSTANCE_NO:
9903 case DT_MIPS_DELTA_RELOC_NO:
9904 case DT_MIPS_DELTA_SYM_NO:
9905 case DT_MIPS_DELTA_CLASSSYM_NO:
9906 case DT_MIPS_COMPACT_SIZE:
c69075ac 9907 print_vma (entry->d_un.d_val, DEC);
252b5132 9908 break;
103f02d3 9909
f16a9783 9910 case DT_MIPS_XHASH:
978c4450
AM
9911 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
9912 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
9913 /* Falls through. */
9914
103f02d3 9915 default:
4b68bca3 9916 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9917 }
4b68bca3 9918 putchar ('\n');
103f02d3
UD
9919}
9920
103f02d3 9921static void
2cf0635d 9922dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9923{
9924 switch (entry->d_tag)
9925 {
9926 case DT_HP_DLD_FLAGS:
9927 {
9928 static struct
9929 {
9930 long int bit;
2cf0635d 9931 const char * str;
5e220199
NC
9932 }
9933 flags[] =
9934 {
9935 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9936 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9937 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9938 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9939 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9940 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9941 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9942 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9943 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9944 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9945 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9946 { DT_HP_GST, "HP_GST" },
9947 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
9948 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
9949 { DT_HP_NODELETE, "HP_NODELETE" },
9950 { DT_HP_GROUP, "HP_GROUP" },
9951 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 9952 };
32ec8896 9953 bfd_boolean first = TRUE;
5e220199 9954 size_t cnt;
f7a99963 9955 bfd_vma val = entry->d_un.d_val;
103f02d3 9956
60bca95a 9957 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 9958 if (val & flags[cnt].bit)
30800947
NC
9959 {
9960 if (! first)
9961 putchar (' ');
9962 fputs (flags[cnt].str, stdout);
32ec8896 9963 first = FALSE;
30800947
NC
9964 val ^= flags[cnt].bit;
9965 }
76da6bbe 9966
103f02d3 9967 if (val != 0 || first)
f7a99963
NC
9968 {
9969 if (! first)
9970 putchar (' ');
9971 print_vma (val, HEX);
9972 }
103f02d3
UD
9973 }
9974 break;
76da6bbe 9975
252b5132 9976 default:
f7a99963
NC
9977 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9978 break;
252b5132 9979 }
35b1837e 9980 putchar ('\n');
252b5132
RH
9981}
9982
28f997cf
TG
9983#ifdef BFD64
9984
9985/* VMS vs Unix time offset and factor. */
9986
9987#define VMS_EPOCH_OFFSET 35067168000000000LL
9988#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
9989#ifndef INT64_MIN
9990#define INT64_MIN (-9223372036854775807LL - 1)
9991#endif
28f997cf
TG
9992
9993/* Display a VMS time in a human readable format. */
9994
9995static void
9996print_vms_time (bfd_int64_t vmstime)
9997{
dccc31de 9998 struct tm *tm = NULL;
28f997cf
TG
9999 time_t unxtime;
10000
dccc31de
AM
10001 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10002 {
10003 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10004 unxtime = vmstime;
10005 if (unxtime == vmstime)
10006 tm = gmtime (&unxtime);
10007 }
10008 if (tm != NULL)
10009 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10010 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10011 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
10012}
10013#endif /* BFD64 */
10014
ecc51f48 10015static void
2cf0635d 10016dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10017{
10018 switch (entry->d_tag)
10019 {
0de14b54 10020 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10021 /* First 3 slots reserved. */
ecc51f48
NC
10022 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10023 printf (" -- ");
10024 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10025 break;
10026
28f997cf
TG
10027 case DT_IA_64_VMS_LINKTIME:
10028#ifdef BFD64
10029 print_vms_time (entry->d_un.d_val);
10030#endif
10031 break;
10032
10033 case DT_IA_64_VMS_LNKFLAGS:
10034 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10035 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10036 printf (" CALL_DEBUG");
10037 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10038 printf (" NOP0BUFS");
10039 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10040 printf (" P0IMAGE");
10041 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10042 printf (" MKTHREADS");
10043 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10044 printf (" UPCALLS");
10045 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10046 printf (" IMGSTA");
10047 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10048 printf (" INITIALIZE");
10049 if (entry->d_un.d_val & VMS_LF_MAIN)
10050 printf (" MAIN");
10051 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10052 printf (" EXE_INIT");
10053 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10054 printf (" TBK_IN_IMG");
10055 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10056 printf (" DBG_IN_IMG");
10057 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10058 printf (" TBK_IN_DSF");
10059 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10060 printf (" DBG_IN_DSF");
10061 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10062 printf (" SIGNATURES");
10063 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10064 printf (" REL_SEG_OFF");
10065 break;
10066
bdf4d63a
JJ
10067 default:
10068 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10069 break;
ecc51f48 10070 }
bdf4d63a 10071 putchar ('\n');
ecc51f48
NC
10072}
10073
32ec8896 10074static bfd_boolean
dda8d76d 10075get_32bit_dynamic_section (Filedata * filedata)
252b5132 10076{
2cf0635d
NC
10077 Elf32_External_Dyn * edyn;
10078 Elf32_External_Dyn * ext;
10079 Elf_Internal_Dyn * entry;
103f02d3 10080
978c4450
AM
10081 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10082 filedata->dynamic_addr, 1,
10083 filedata->dynamic_size,
10084 _("dynamic section"));
a6e9f9df 10085 if (!edyn)
32ec8896 10086 return FALSE;
103f02d3 10087
071436c6
NC
10088 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10089 might not have the luxury of section headers. Look for the DT_NULL
10090 terminator to determine the number of entries. */
978c4450
AM
10091 for (ext = edyn, filedata->dynamic_nent = 0;
10092 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10093 ext++)
10094 {
978c4450 10095 filedata->dynamic_nent++;
ba2685cc
AM
10096 if (BYTE_GET (ext->d_tag) == DT_NULL)
10097 break;
10098 }
252b5132 10099
978c4450
AM
10100 filedata->dynamic_section
10101 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10102 if (filedata->dynamic_section == NULL)
252b5132 10103 {
8b73c356 10104 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10105 (unsigned long) filedata->dynamic_nent);
9ea033b2 10106 free (edyn);
32ec8896 10107 return FALSE;
9ea033b2 10108 }
252b5132 10109
978c4450
AM
10110 for (ext = edyn, entry = filedata->dynamic_section;
10111 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10112 ext++, entry++)
9ea033b2 10113 {
fb514b26
AM
10114 entry->d_tag = BYTE_GET (ext->d_tag);
10115 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10116 }
10117
9ea033b2
NC
10118 free (edyn);
10119
32ec8896 10120 return TRUE;
9ea033b2
NC
10121}
10122
32ec8896 10123static bfd_boolean
dda8d76d 10124get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10125{
2cf0635d
NC
10126 Elf64_External_Dyn * edyn;
10127 Elf64_External_Dyn * ext;
10128 Elf_Internal_Dyn * entry;
103f02d3 10129
071436c6 10130 /* Read in the data. */
978c4450
AM
10131 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10132 filedata->dynamic_addr, 1,
10133 filedata->dynamic_size,
10134 _("dynamic section"));
a6e9f9df 10135 if (!edyn)
32ec8896 10136 return FALSE;
103f02d3 10137
071436c6
NC
10138 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10139 might not have the luxury of section headers. Look for the DT_NULL
10140 terminator to determine the number of entries. */
978c4450 10141 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10142 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10143 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10144 ext++)
10145 {
978c4450 10146 filedata->dynamic_nent++;
66543521 10147 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10148 break;
10149 }
252b5132 10150
978c4450
AM
10151 filedata->dynamic_section
10152 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10153 if (filedata->dynamic_section == NULL)
252b5132 10154 {
8b73c356 10155 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10156 (unsigned long) filedata->dynamic_nent);
252b5132 10157 free (edyn);
32ec8896 10158 return FALSE;
252b5132
RH
10159 }
10160
071436c6 10161 /* Convert from external to internal formats. */
978c4450
AM
10162 for (ext = edyn, entry = filedata->dynamic_section;
10163 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10164 ext++, entry++)
252b5132 10165 {
66543521
AM
10166 entry->d_tag = BYTE_GET (ext->d_tag);
10167 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10168 }
10169
10170 free (edyn);
10171
32ec8896 10172 return TRUE;
9ea033b2
NC
10173}
10174
e9e44622
JJ
10175static void
10176print_dynamic_flags (bfd_vma flags)
d1133906 10177{
32ec8896 10178 bfd_boolean first = TRUE;
13ae64f3 10179
d1133906
NC
10180 while (flags)
10181 {
10182 bfd_vma flag;
10183
10184 flag = flags & - flags;
10185 flags &= ~ flag;
10186
e9e44622 10187 if (first)
32ec8896 10188 first = FALSE;
e9e44622
JJ
10189 else
10190 putc (' ', stdout);
13ae64f3 10191
d1133906
NC
10192 switch (flag)
10193 {
e9e44622
JJ
10194 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10195 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10196 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10197 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10198 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10199 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10200 }
10201 }
e9e44622 10202 puts ("");
d1133906
NC
10203}
10204
10ca4b04
L
10205static bfd_vma *
10206get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10207{
10208 unsigned char * e_data;
10209 bfd_vma * i_data;
10210
10211 /* If the size_t type is smaller than the bfd_size_type, eg because
10212 you are building a 32-bit tool on a 64-bit host, then make sure
10213 that when (number) is cast to (size_t) no information is lost. */
10214 if (sizeof (size_t) < sizeof (bfd_size_type)
10215 && (bfd_size_type) ((size_t) number) != number)
10216 {
10217 error (_("Size truncation prevents reading %s elements of size %u\n"),
10218 bfd_vmatoa ("u", number), ent_size);
10219 return NULL;
10220 }
10221
10222 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10223 attempting to allocate memory when the read is bound to fail. */
10224 if (ent_size * number > filedata->file_size)
10225 {
10226 error (_("Invalid number of dynamic entries: %s\n"),
10227 bfd_vmatoa ("u", number));
10228 return NULL;
10229 }
10230
10231 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10232 if (e_data == NULL)
10233 {
10234 error (_("Out of memory reading %s dynamic entries\n"),
10235 bfd_vmatoa ("u", number));
10236 return NULL;
10237 }
10238
10239 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10240 {
10241 error (_("Unable to read in %s bytes of dynamic data\n"),
10242 bfd_vmatoa ("u", number * ent_size));
10243 free (e_data);
10244 return NULL;
10245 }
10246
10247 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10248 if (i_data == NULL)
10249 {
10250 error (_("Out of memory allocating space for %s dynamic entries\n"),
10251 bfd_vmatoa ("u", number));
10252 free (e_data);
10253 return NULL;
10254 }
10255
10256 while (number--)
10257 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10258
10259 free (e_data);
10260
10261 return i_data;
10262}
10263
10264static unsigned long
10265get_num_dynamic_syms (Filedata * filedata)
10266{
10267 unsigned long num_of_syms = 0;
10268
10269 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10270 return num_of_syms;
10271
978c4450 10272 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10273 {
10274 unsigned char nb[8];
10275 unsigned char nc[8];
10276 unsigned int hash_ent_size = 4;
10277
10278 if ((filedata->file_header.e_machine == EM_ALPHA
10279 || filedata->file_header.e_machine == EM_S390
10280 || filedata->file_header.e_machine == EM_S390_OLD)
10281 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10282 hash_ent_size = 8;
10283
10284 if (fseek (filedata->handle,
978c4450
AM
10285 (filedata->archive_file_offset
10286 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10287 sizeof nb + sizeof nc)),
10288 SEEK_SET))
10289 {
10290 error (_("Unable to seek to start of dynamic information\n"));
10291 goto no_hash;
10292 }
10293
10294 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10295 {
10296 error (_("Failed to read in number of buckets\n"));
10297 goto no_hash;
10298 }
10299
10300 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10301 {
10302 error (_("Failed to read in number of chains\n"));
10303 goto no_hash;
10304 }
10305
978c4450
AM
10306 filedata->nbuckets = byte_get (nb, hash_ent_size);
10307 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10308
2482f306
AM
10309 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10310 {
10311 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10312 hash_ent_size);
10313 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10314 hash_ent_size);
001890e1 10315
2482f306
AM
10316 if (filedata->buckets != NULL && filedata->chains != NULL)
10317 num_of_syms = filedata->nchains;
10318 }
ceb9bf11 10319 no_hash:
10ca4b04
L
10320 if (num_of_syms == 0)
10321 {
9db70fc3
AM
10322 free (filedata->buckets);
10323 filedata->buckets = NULL;
10324 free (filedata->chains);
10325 filedata->chains = NULL;
978c4450 10326 filedata->nbuckets = 0;
10ca4b04
L
10327 }
10328 }
10329
978c4450 10330 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10331 {
10332 unsigned char nb[16];
10333 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10334 bfd_vma buckets_vma;
10335 unsigned long hn;
10ca4b04
L
10336
10337 if (fseek (filedata->handle,
978c4450
AM
10338 (filedata->archive_file_offset
10339 + offset_from_vma (filedata,
10340 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10341 sizeof nb)),
10342 SEEK_SET))
10343 {
10344 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10345 goto no_gnu_hash;
10346 }
10347
10348 if (fread (nb, 16, 1, filedata->handle) != 1)
10349 {
10350 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10351 goto no_gnu_hash;
10352 }
10353
978c4450
AM
10354 filedata->ngnubuckets = byte_get (nb, 4);
10355 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10356 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10357 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10358 if (is_32bit_elf)
10359 buckets_vma += bitmaskwords * 4;
10360 else
10361 buckets_vma += bitmaskwords * 8;
10362
10363 if (fseek (filedata->handle,
978c4450 10364 (filedata->archive_file_offset
10ca4b04
L
10365 + offset_from_vma (filedata, buckets_vma, 4)),
10366 SEEK_SET))
10367 {
10368 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10369 goto no_gnu_hash;
10370 }
10371
978c4450
AM
10372 filedata->gnubuckets
10373 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10374
978c4450 10375 if (filedata->gnubuckets == NULL)
90837ea7 10376 goto no_gnu_hash;
10ca4b04 10377
978c4450
AM
10378 for (i = 0; i < filedata->ngnubuckets; i++)
10379 if (filedata->gnubuckets[i] != 0)
10ca4b04 10380 {
978c4450 10381 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10382 goto no_gnu_hash;
10ca4b04 10383
978c4450
AM
10384 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10385 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10386 }
10387
10388 if (maxchain == 0xffffffff)
90837ea7 10389 goto no_gnu_hash;
10ca4b04 10390
978c4450 10391 maxchain -= filedata->gnusymidx;
10ca4b04
L
10392
10393 if (fseek (filedata->handle,
978c4450
AM
10394 (filedata->archive_file_offset
10395 + offset_from_vma (filedata,
10396 buckets_vma + 4 * (filedata->ngnubuckets
10397 + maxchain),
10398 4)),
10ca4b04
L
10399 SEEK_SET))
10400 {
10401 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10402 goto no_gnu_hash;
10403 }
10404
10405 do
10406 {
10407 if (fread (nb, 4, 1, filedata->handle) != 1)
10408 {
10409 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10410 goto no_gnu_hash;
10411 }
10412
10413 if (maxchain + 1 == 0)
90837ea7 10414 goto no_gnu_hash;
10ca4b04
L
10415
10416 ++maxchain;
10417 }
10418 while ((byte_get (nb, 4) & 1) == 0);
10419
10420 if (fseek (filedata->handle,
978c4450
AM
10421 (filedata->archive_file_offset
10422 + offset_from_vma (filedata, (buckets_vma
10423 + 4 * filedata->ngnubuckets),
10424 4)),
10ca4b04
L
10425 SEEK_SET))
10426 {
10427 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10428 goto no_gnu_hash;
10429 }
10430
978c4450
AM
10431 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10432 filedata->ngnuchains = maxchain;
10ca4b04 10433
978c4450 10434 if (filedata->gnuchains == NULL)
90837ea7 10435 goto no_gnu_hash;
10ca4b04 10436
978c4450 10437 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10438 {
10439 if (fseek (filedata->handle,
978c4450 10440 (filedata->archive_file_offset
10ca4b04 10441 + offset_from_vma (filedata, (buckets_vma
978c4450 10442 + 4 * (filedata->ngnubuckets
10ca4b04
L
10443 + maxchain)), 4)),
10444 SEEK_SET))
10445 {
10446 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10447 goto no_gnu_hash;
10448 }
10449
978c4450 10450 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10451 if (filedata->mipsxlat == NULL)
10452 goto no_gnu_hash;
10ca4b04
L
10453 }
10454
978c4450
AM
10455 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10456 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10457 {
978c4450
AM
10458 bfd_vma si = filedata->gnubuckets[hn];
10459 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10460
10461 do
10462 {
978c4450 10463 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 10464 {
c31ab5a0
AM
10465 if (off < filedata->ngnuchains
10466 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 10467 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
10468 }
10469 else
10470 {
10471 if (si >= num_of_syms)
10472 num_of_syms = si + 1;
10473 }
10474 si++;
10475 }
978c4450
AM
10476 while (off < filedata->ngnuchains
10477 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
10478 }
10479
90837ea7 10480 if (num_of_syms == 0)
10ca4b04 10481 {
90837ea7 10482 no_gnu_hash:
9db70fc3
AM
10483 free (filedata->mipsxlat);
10484 filedata->mipsxlat = NULL;
10485 free (filedata->gnuchains);
10486 filedata->gnuchains = NULL;
10487 free (filedata->gnubuckets);
10488 filedata->gnubuckets = NULL;
978c4450
AM
10489 filedata->ngnubuckets = 0;
10490 filedata->ngnuchains = 0;
10ca4b04
L
10491 }
10492 }
10493
10494 return num_of_syms;
10495}
10496
b2d38a17
NC
10497/* Parse and display the contents of the dynamic section. */
10498
32ec8896 10499static bfd_boolean
dda8d76d 10500process_dynamic_section (Filedata * filedata)
9ea033b2 10501{
2cf0635d 10502 Elf_Internal_Dyn * entry;
9ea033b2 10503
978c4450 10504 if (filedata->dynamic_size == 0)
9ea033b2
NC
10505 {
10506 if (do_dynamic)
ca0e11aa
NC
10507 {
10508 if (filedata->is_separate)
10509 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
10510 filedata->file_name);
10511 else
10512 printf (_("\nThere is no dynamic section in this file.\n"));
10513 }
9ea033b2 10514
32ec8896 10515 return TRUE;
9ea033b2
NC
10516 }
10517
10518 if (is_32bit_elf)
10519 {
dda8d76d 10520 if (! get_32bit_dynamic_section (filedata))
32ec8896
NC
10521 return FALSE;
10522 }
10523 else
10524 {
dda8d76d 10525 if (! get_64bit_dynamic_section (filedata))
32ec8896 10526 return FALSE;
9ea033b2 10527 }
9ea033b2 10528
252b5132 10529 /* Find the appropriate symbol table. */
978c4450 10530 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 10531 {
2482f306
AM
10532 unsigned long num_of_syms;
10533
978c4450
AM
10534 for (entry = filedata->dynamic_section;
10535 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10536 ++entry)
10ca4b04 10537 if (entry->d_tag == DT_SYMTAB)
978c4450 10538 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 10539 else if (entry->d_tag == DT_SYMENT)
978c4450 10540 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 10541 else if (entry->d_tag == DT_HASH)
978c4450 10542 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 10543 else if (entry->d_tag == DT_GNU_HASH)
978c4450 10544 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
10545 else if ((filedata->file_header.e_machine == EM_MIPS
10546 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10547 && entry->d_tag == DT_MIPS_XHASH)
10548 {
978c4450
AM
10549 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10550 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 10551 }
252b5132 10552
2482f306
AM
10553 num_of_syms = get_num_dynamic_syms (filedata);
10554
10555 if (num_of_syms != 0
10556 && filedata->dynamic_symbols == NULL
10557 && filedata->dynamic_info[DT_SYMTAB]
978c4450 10558 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
10559 {
10560 Elf_Internal_Phdr *seg;
2482f306 10561 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 10562
2482f306
AM
10563 if (! get_program_headers (filedata))
10564 {
10565 error (_("Cannot interpret virtual addresses "
10566 "without program headers.\n"));
10567 return FALSE;
10568 }
252b5132 10569
2482f306
AM
10570 for (seg = filedata->program_headers;
10571 seg < filedata->program_headers + filedata->file_header.e_phnum;
10572 ++seg)
10573 {
10574 if (seg->p_type != PT_LOAD)
10575 continue;
252b5132 10576
2482f306
AM
10577 if (seg->p_offset + seg->p_filesz > filedata->file_size)
10578 {
10579 /* See PR 21379 for a reproducer. */
10580 error (_("Invalid PT_LOAD entry\n"));
10581 return FALSE;
10582 }
252b5132 10583
2482f306
AM
10584 if (vma >= (seg->p_vaddr & -seg->p_align)
10585 && vma < seg->p_vaddr + seg->p_filesz)
10586 {
10587 /* Since we do not know how big the symbol table is,
10588 we default to reading in up to the end of PT_LOAD
10589 segment and processing that. This is overkill, I
10590 know, but it should work. */
10591 Elf_Internal_Shdr section;
10592 section.sh_offset = (vma - seg->p_vaddr
10593 + seg->p_offset);
10594 section.sh_size = (num_of_syms
10595 * filedata->dynamic_info[DT_SYMENT]);
10596 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
10597
10598 if (do_checks
10599 && filedata->dynamic_symtab_section != NULL
10600 && ((filedata->dynamic_symtab_section->sh_offset
10601 != section.sh_offset)
10602 || (filedata->dynamic_symtab_section->sh_size
10603 != section.sh_size)
10604 || (filedata->dynamic_symtab_section->sh_entsize
10605 != section.sh_entsize)))
10606 warn (_("\
10607the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
10608
2482f306
AM
10609 section.sh_name = filedata->string_table_length;
10610 filedata->dynamic_symbols
10611 = GET_ELF_SYMBOLS (filedata, &section,
10612 &filedata->num_dynamic_syms);
10613 if (filedata->dynamic_symbols == NULL
10614 || filedata->num_dynamic_syms != num_of_syms)
10615 {
10616 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
10617 return FALSE;
10618 }
10619 break;
10620 }
10621 }
10622 }
10623 }
252b5132
RH
10624
10625 /* Similarly find a string table. */
978c4450
AM
10626 if (filedata->dynamic_strings == NULL)
10627 for (entry = filedata->dynamic_section;
10628 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
10629 ++entry)
10630 {
10631 if (entry->d_tag == DT_STRTAB)
978c4450 10632 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 10633
10ca4b04 10634 if (entry->d_tag == DT_STRSZ)
978c4450 10635 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10636
978c4450
AM
10637 if (filedata->dynamic_info[DT_STRTAB]
10638 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
10639 {
10640 unsigned long offset;
978c4450 10641 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
10642
10643 offset = offset_from_vma (filedata,
978c4450 10644 filedata->dynamic_info[DT_STRTAB],
10ca4b04 10645 str_tab_len);
8ac10c5b
L
10646 if (do_checks
10647 && filedata->dynamic_strtab_section
10648 && ((filedata->dynamic_strtab_section->sh_offset
10649 != (file_ptr) offset)
10650 || (filedata->dynamic_strtab_section->sh_size
10651 != str_tab_len)))
10652 warn (_("\
10653the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
10654
978c4450
AM
10655 filedata->dynamic_strings
10656 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
10657 _("dynamic string table"));
10658 if (filedata->dynamic_strings == NULL)
10ca4b04
L
10659 {
10660 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10661 break;
10662 }
e3d39609 10663
978c4450 10664 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
10665 break;
10666 }
10667 }
252b5132
RH
10668
10669 /* And find the syminfo section if available. */
978c4450 10670 if (filedata->dynamic_syminfo == NULL)
252b5132 10671 {
3e8bba36 10672 unsigned long syminsz = 0;
252b5132 10673
978c4450
AM
10674 for (entry = filedata->dynamic_section;
10675 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10676 ++entry)
252b5132
RH
10677 {
10678 if (entry->d_tag == DT_SYMINENT)
10679 {
10680 /* Note: these braces are necessary to avoid a syntax
10681 error from the SunOS4 C compiler. */
049b0c3a
NC
10682 /* PR binutils/17531: A corrupt file can trigger this test.
10683 So do not use an assert, instead generate an error message. */
10684 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10685 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10686 (int) entry->d_un.d_val);
252b5132
RH
10687 }
10688 else if (entry->d_tag == DT_SYMINSZ)
10689 syminsz = entry->d_un.d_val;
10690 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
10691 filedata->dynamic_syminfo_offset
10692 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
10693 }
10694
978c4450 10695 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 10696 {
2cf0635d
NC
10697 Elf_External_Syminfo * extsyminfo;
10698 Elf_External_Syminfo * extsym;
10699 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10700
10701 /* There is a syminfo section. Read the data. */
3f5e193b 10702 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
10703 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
10704 1, syminsz, _("symbol information"));
a6e9f9df 10705 if (!extsyminfo)
32ec8896 10706 return FALSE;
252b5132 10707
978c4450 10708 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
10709 {
10710 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 10711 free (filedata->dynamic_syminfo);
e3d39609 10712 }
978c4450
AM
10713 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
10714 if (filedata->dynamic_syminfo == NULL)
252b5132 10715 {
2482f306
AM
10716 error (_("Out of memory allocating %lu bytes "
10717 "for dynamic symbol info\n"),
8b73c356 10718 (unsigned long) syminsz);
32ec8896 10719 return FALSE;
252b5132
RH
10720 }
10721
2482f306
AM
10722 filedata->dynamic_syminfo_nent
10723 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 10724 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
10725 syminfo < (filedata->dynamic_syminfo
10726 + filedata->dynamic_syminfo_nent);
86dba8ee 10727 ++syminfo, ++extsym)
252b5132 10728 {
86dba8ee
AM
10729 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10730 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10731 }
10732
10733 free (extsyminfo);
10734 }
10735 }
10736
978c4450 10737 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa
NC
10738 {
10739 if (filedata->dynamic_nent == 1)
10740 {
10741 if (filedata->is_separate)
10742 printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains 1 entry:\n"),
10743 filedata->file_name,
10744 filedata->dynamic_addr);
10745 else
10746 printf (_("\nDynamic section at offset 0x%lx contains 1 entry:\n"),
10747 filedata->dynamic_addr);
10748 }
10749 else
10750 {
10751 if (filedata->is_separate)
10752 printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n"),
10753 filedata->file_name,
10754 filedata->dynamic_addr,
10755 (unsigned long) filedata->dynamic_nent);
10756 else
10757 printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
10758 filedata->dynamic_addr,
10759 (unsigned long) filedata->dynamic_nent);
10760 }
10761 }
252b5132
RH
10762 if (do_dynamic)
10763 printf (_(" Tag Type Name/Value\n"));
10764
978c4450
AM
10765 for (entry = filedata->dynamic_section;
10766 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10767 entry++)
252b5132
RH
10768 {
10769 if (do_dynamic)
f7a99963 10770 {
2cf0635d 10771 const char * dtype;
e699b9ff 10772
f7a99963
NC
10773 putchar (' ');
10774 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10775 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10776 printf (" (%s)%*s", dtype,
32ec8896 10777 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10778 }
252b5132
RH
10779
10780 switch (entry->d_tag)
10781 {
d1133906
NC
10782 case DT_FLAGS:
10783 if (do_dynamic)
e9e44622 10784 print_dynamic_flags (entry->d_un.d_val);
d1133906 10785 break;
76da6bbe 10786
252b5132
RH
10787 case DT_AUXILIARY:
10788 case DT_FILTER:
019148e4
L
10789 case DT_CONFIG:
10790 case DT_DEPAUDIT:
10791 case DT_AUDIT:
252b5132
RH
10792 if (do_dynamic)
10793 {
019148e4 10794 switch (entry->d_tag)
b34976b6 10795 {
019148e4
L
10796 case DT_AUXILIARY:
10797 printf (_("Auxiliary library"));
10798 break;
10799
10800 case DT_FILTER:
10801 printf (_("Filter library"));
10802 break;
10803
b34976b6 10804 case DT_CONFIG:
019148e4
L
10805 printf (_("Configuration file"));
10806 break;
10807
10808 case DT_DEPAUDIT:
10809 printf (_("Dependency audit library"));
10810 break;
10811
10812 case DT_AUDIT:
10813 printf (_("Audit library"));
10814 break;
10815 }
252b5132 10816
978c4450
AM
10817 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10818 printf (": [%s]\n",
10819 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 10820 else
f7a99963
NC
10821 {
10822 printf (": ");
10823 print_vma (entry->d_un.d_val, PREFIX_HEX);
10824 putchar ('\n');
10825 }
252b5132
RH
10826 }
10827 break;
10828
dcefbbbd 10829 case DT_FEATURE:
252b5132
RH
10830 if (do_dynamic)
10831 {
10832 printf (_("Flags:"));
86f55779 10833
252b5132
RH
10834 if (entry->d_un.d_val == 0)
10835 printf (_(" None\n"));
10836 else
10837 {
10838 unsigned long int val = entry->d_un.d_val;
86f55779 10839
252b5132
RH
10840 if (val & DTF_1_PARINIT)
10841 {
10842 printf (" PARINIT");
10843 val ^= DTF_1_PARINIT;
10844 }
dcefbbbd
L
10845 if (val & DTF_1_CONFEXP)
10846 {
10847 printf (" CONFEXP");
10848 val ^= DTF_1_CONFEXP;
10849 }
252b5132
RH
10850 if (val != 0)
10851 printf (" %lx", val);
10852 puts ("");
10853 }
10854 }
10855 break;
10856
10857 case DT_POSFLAG_1:
10858 if (do_dynamic)
10859 {
10860 printf (_("Flags:"));
86f55779 10861
252b5132
RH
10862 if (entry->d_un.d_val == 0)
10863 printf (_(" None\n"));
10864 else
10865 {
10866 unsigned long int val = entry->d_un.d_val;
86f55779 10867
252b5132
RH
10868 if (val & DF_P1_LAZYLOAD)
10869 {
10870 printf (" LAZYLOAD");
10871 val ^= DF_P1_LAZYLOAD;
10872 }
10873 if (val & DF_P1_GROUPPERM)
10874 {
10875 printf (" GROUPPERM");
10876 val ^= DF_P1_GROUPPERM;
10877 }
10878 if (val != 0)
10879 printf (" %lx", val);
10880 puts ("");
10881 }
10882 }
10883 break;
10884
10885 case DT_FLAGS_1:
10886 if (do_dynamic)
10887 {
10888 printf (_("Flags:"));
10889 if (entry->d_un.d_val == 0)
10890 printf (_(" None\n"));
10891 else
10892 {
10893 unsigned long int val = entry->d_un.d_val;
86f55779 10894
252b5132
RH
10895 if (val & DF_1_NOW)
10896 {
10897 printf (" NOW");
10898 val ^= DF_1_NOW;
10899 }
10900 if (val & DF_1_GLOBAL)
10901 {
10902 printf (" GLOBAL");
10903 val ^= DF_1_GLOBAL;
10904 }
10905 if (val & DF_1_GROUP)
10906 {
10907 printf (" GROUP");
10908 val ^= DF_1_GROUP;
10909 }
10910 if (val & DF_1_NODELETE)
10911 {
10912 printf (" NODELETE");
10913 val ^= DF_1_NODELETE;
10914 }
10915 if (val & DF_1_LOADFLTR)
10916 {
10917 printf (" LOADFLTR");
10918 val ^= DF_1_LOADFLTR;
10919 }
10920 if (val & DF_1_INITFIRST)
10921 {
10922 printf (" INITFIRST");
10923 val ^= DF_1_INITFIRST;
10924 }
10925 if (val & DF_1_NOOPEN)
10926 {
10927 printf (" NOOPEN");
10928 val ^= DF_1_NOOPEN;
10929 }
10930 if (val & DF_1_ORIGIN)
10931 {
10932 printf (" ORIGIN");
10933 val ^= DF_1_ORIGIN;
10934 }
10935 if (val & DF_1_DIRECT)
10936 {
10937 printf (" DIRECT");
10938 val ^= DF_1_DIRECT;
10939 }
10940 if (val & DF_1_TRANS)
10941 {
10942 printf (" TRANS");
10943 val ^= DF_1_TRANS;
10944 }
10945 if (val & DF_1_INTERPOSE)
10946 {
10947 printf (" INTERPOSE");
10948 val ^= DF_1_INTERPOSE;
10949 }
f7db6139 10950 if (val & DF_1_NODEFLIB)
dcefbbbd 10951 {
f7db6139
L
10952 printf (" NODEFLIB");
10953 val ^= DF_1_NODEFLIB;
dcefbbbd
L
10954 }
10955 if (val & DF_1_NODUMP)
10956 {
10957 printf (" NODUMP");
10958 val ^= DF_1_NODUMP;
10959 }
34b60028 10960 if (val & DF_1_CONFALT)
dcefbbbd 10961 {
34b60028
L
10962 printf (" CONFALT");
10963 val ^= DF_1_CONFALT;
10964 }
10965 if (val & DF_1_ENDFILTEE)
10966 {
10967 printf (" ENDFILTEE");
10968 val ^= DF_1_ENDFILTEE;
10969 }
10970 if (val & DF_1_DISPRELDNE)
10971 {
10972 printf (" DISPRELDNE");
10973 val ^= DF_1_DISPRELDNE;
10974 }
10975 if (val & DF_1_DISPRELPND)
10976 {
10977 printf (" DISPRELPND");
10978 val ^= DF_1_DISPRELPND;
10979 }
10980 if (val & DF_1_NODIRECT)
10981 {
10982 printf (" NODIRECT");
10983 val ^= DF_1_NODIRECT;
10984 }
10985 if (val & DF_1_IGNMULDEF)
10986 {
10987 printf (" IGNMULDEF");
10988 val ^= DF_1_IGNMULDEF;
10989 }
10990 if (val & DF_1_NOKSYMS)
10991 {
10992 printf (" NOKSYMS");
10993 val ^= DF_1_NOKSYMS;
10994 }
10995 if (val & DF_1_NOHDR)
10996 {
10997 printf (" NOHDR");
10998 val ^= DF_1_NOHDR;
10999 }
11000 if (val & DF_1_EDITED)
11001 {
11002 printf (" EDITED");
11003 val ^= DF_1_EDITED;
11004 }
11005 if (val & DF_1_NORELOC)
11006 {
11007 printf (" NORELOC");
11008 val ^= DF_1_NORELOC;
11009 }
11010 if (val & DF_1_SYMINTPOSE)
11011 {
11012 printf (" SYMINTPOSE");
11013 val ^= DF_1_SYMINTPOSE;
11014 }
11015 if (val & DF_1_GLOBAUDIT)
11016 {
11017 printf (" GLOBAUDIT");
11018 val ^= DF_1_GLOBAUDIT;
11019 }
11020 if (val & DF_1_SINGLETON)
11021 {
11022 printf (" SINGLETON");
11023 val ^= DF_1_SINGLETON;
dcefbbbd 11024 }
5c383f02
RO
11025 if (val & DF_1_STUB)
11026 {
11027 printf (" STUB");
11028 val ^= DF_1_STUB;
11029 }
11030 if (val & DF_1_PIE)
11031 {
11032 printf (" PIE");
11033 val ^= DF_1_PIE;
11034 }
b1202ffa
L
11035 if (val & DF_1_KMOD)
11036 {
11037 printf (" KMOD");
11038 val ^= DF_1_KMOD;
11039 }
11040 if (val & DF_1_WEAKFILTER)
11041 {
11042 printf (" WEAKFILTER");
11043 val ^= DF_1_WEAKFILTER;
11044 }
11045 if (val & DF_1_NOCOMMON)
11046 {
11047 printf (" NOCOMMON");
11048 val ^= DF_1_NOCOMMON;
11049 }
252b5132
RH
11050 if (val != 0)
11051 printf (" %lx", val);
11052 puts ("");
11053 }
11054 }
11055 break;
11056
11057 case DT_PLTREL:
978c4450 11058 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11059 if (do_dynamic)
dda8d76d 11060 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11061 break;
11062
11063 case DT_NULL :
11064 case DT_NEEDED :
11065 case DT_PLTGOT :
11066 case DT_HASH :
11067 case DT_STRTAB :
11068 case DT_SYMTAB :
11069 case DT_RELA :
11070 case DT_INIT :
11071 case DT_FINI :
11072 case DT_SONAME :
11073 case DT_RPATH :
11074 case DT_SYMBOLIC:
11075 case DT_REL :
11076 case DT_DEBUG :
11077 case DT_TEXTREL :
11078 case DT_JMPREL :
019148e4 11079 case DT_RUNPATH :
978c4450 11080 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11081
11082 if (do_dynamic)
11083 {
2cf0635d 11084 char * name;
252b5132 11085
978c4450
AM
11086 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
11087 name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11088 else
d79b3d50 11089 name = NULL;
252b5132
RH
11090
11091 if (name)
11092 {
11093 switch (entry->d_tag)
11094 {
11095 case DT_NEEDED:
11096 printf (_("Shared library: [%s]"), name);
11097
978c4450 11098 if (streq (name, filedata->program_interpreter))
f7a99963 11099 printf (_(" program interpreter"));
252b5132
RH
11100 break;
11101
11102 case DT_SONAME:
f7a99963 11103 printf (_("Library soname: [%s]"), name);
252b5132
RH
11104 break;
11105
11106 case DT_RPATH:
f7a99963 11107 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11108 break;
11109
019148e4
L
11110 case DT_RUNPATH:
11111 printf (_("Library runpath: [%s]"), name);
11112 break;
11113
252b5132 11114 default:
f7a99963
NC
11115 print_vma (entry->d_un.d_val, PREFIX_HEX);
11116 break;
252b5132
RH
11117 }
11118 }
11119 else
f7a99963
NC
11120 print_vma (entry->d_un.d_val, PREFIX_HEX);
11121
11122 putchar ('\n');
252b5132
RH
11123 }
11124 break;
11125
11126 case DT_PLTRELSZ:
11127 case DT_RELASZ :
11128 case DT_STRSZ :
11129 case DT_RELSZ :
11130 case DT_RELAENT :
11131 case DT_SYMENT :
11132 case DT_RELENT :
978c4450 11133 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11134 /* Fall through. */
252b5132
RH
11135 case DT_PLTPADSZ:
11136 case DT_MOVEENT :
11137 case DT_MOVESZ :
11138 case DT_INIT_ARRAYSZ:
11139 case DT_FINI_ARRAYSZ:
047b2264
JJ
11140 case DT_GNU_CONFLICTSZ:
11141 case DT_GNU_LIBLISTSZ:
252b5132 11142 if (do_dynamic)
f7a99963
NC
11143 {
11144 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11145 printf (_(" (bytes)\n"));
f7a99963 11146 }
252b5132
RH
11147 break;
11148
11149 case DT_VERDEFNUM:
11150 case DT_VERNEEDNUM:
11151 case DT_RELACOUNT:
11152 case DT_RELCOUNT:
11153 if (do_dynamic)
f7a99963
NC
11154 {
11155 print_vma (entry->d_un.d_val, UNSIGNED);
11156 putchar ('\n');
11157 }
252b5132
RH
11158 break;
11159
11160 case DT_SYMINSZ:
11161 case DT_SYMINENT:
11162 case DT_SYMINFO:
11163 case DT_USED:
11164 case DT_INIT_ARRAY:
11165 case DT_FINI_ARRAY:
11166 if (do_dynamic)
11167 {
d79b3d50 11168 if (entry->d_tag == DT_USED
978c4450 11169 && VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
252b5132 11170 {
978c4450 11171 char * name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11172
b34976b6 11173 if (*name)
252b5132
RH
11174 {
11175 printf (_("Not needed object: [%s]\n"), name);
11176 break;
11177 }
11178 }
103f02d3 11179
f7a99963
NC
11180 print_vma (entry->d_un.d_val, PREFIX_HEX);
11181 putchar ('\n');
252b5132
RH
11182 }
11183 break;
11184
11185 case DT_BIND_NOW:
11186 /* The value of this entry is ignored. */
35b1837e
AM
11187 if (do_dynamic)
11188 putchar ('\n');
252b5132 11189 break;
103f02d3 11190
047b2264
JJ
11191 case DT_GNU_PRELINKED:
11192 if (do_dynamic)
11193 {
2cf0635d 11194 struct tm * tmp;
91d6fa6a 11195 time_t atime = entry->d_un.d_val;
047b2264 11196
91d6fa6a 11197 tmp = gmtime (&atime);
071436c6
NC
11198 /* PR 17533 file: 041-1244816-0.004. */
11199 if (tmp == NULL)
5a2cbcf4
L
11200 printf (_("<corrupt time val: %lx"),
11201 (unsigned long) atime);
071436c6
NC
11202 else
11203 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11204 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11205 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11206
11207 }
11208 break;
11209
fdc90cb4 11210 case DT_GNU_HASH:
978c4450 11211 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11212 if (do_dynamic)
11213 {
11214 print_vma (entry->d_un.d_val, PREFIX_HEX);
11215 putchar ('\n');
11216 }
11217 break;
11218
a5da3dee
VDM
11219 case DT_GNU_FLAGS_1:
11220 if (do_dynamic)
11221 {
11222 printf (_("Flags:"));
11223 if (entry->d_un.d_val == 0)
11224 printf (_(" None\n"));
11225 else
11226 {
11227 unsigned long int val = entry->d_un.d_val;
11228
11229 if (val & DF_GNU_1_UNIQUE)
11230 {
11231 printf (" UNIQUE");
11232 val ^= DF_GNU_1_UNIQUE;
11233 }
11234 if (val != 0)
11235 printf (" %lx", val);
11236 puts ("");
11237 }
11238 }
11239 break;
11240
252b5132
RH
11241 default:
11242 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11243 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11244 = entry->d_un.d_val;
252b5132
RH
11245
11246 if (do_dynamic)
11247 {
dda8d76d 11248 switch (filedata->file_header.e_machine)
252b5132 11249 {
37c18eed
SD
11250 case EM_AARCH64:
11251 dynamic_section_aarch64_val (entry);
11252 break;
252b5132 11253 case EM_MIPS:
4fe85591 11254 case EM_MIPS_RS3_LE:
978c4450 11255 dynamic_section_mips_val (filedata, entry);
252b5132 11256 break;
103f02d3 11257 case EM_PARISC:
b2d38a17 11258 dynamic_section_parisc_val (entry);
103f02d3 11259 break;
ecc51f48 11260 case EM_IA_64:
b2d38a17 11261 dynamic_section_ia64_val (entry);
ecc51f48 11262 break;
252b5132 11263 default:
f7a99963
NC
11264 print_vma (entry->d_un.d_val, PREFIX_HEX);
11265 putchar ('\n');
252b5132
RH
11266 }
11267 }
11268 break;
11269 }
11270 }
11271
32ec8896 11272 return TRUE;
252b5132
RH
11273}
11274
11275static char *
d3ba0551 11276get_ver_flags (unsigned int flags)
252b5132 11277{
6d4f21f6 11278 static char buff[128];
252b5132
RH
11279
11280 buff[0] = 0;
11281
11282 if (flags == 0)
11283 return _("none");
11284
11285 if (flags & VER_FLG_BASE)
7bb1ad17 11286 strcat (buff, "BASE");
252b5132
RH
11287
11288 if (flags & VER_FLG_WEAK)
11289 {
11290 if (flags & VER_FLG_BASE)
7bb1ad17 11291 strcat (buff, " | ");
252b5132 11292
7bb1ad17 11293 strcat (buff, "WEAK");
252b5132
RH
11294 }
11295
44ec90b9
RO
11296 if (flags & VER_FLG_INFO)
11297 {
11298 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11299 strcat (buff, " | ");
44ec90b9 11300
7bb1ad17 11301 strcat (buff, "INFO");
44ec90b9
RO
11302 }
11303
11304 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11305 {
11306 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11307 strcat (buff, " | ");
11308
11309 strcat (buff, _("<unknown>"));
11310 }
252b5132
RH
11311
11312 return buff;
11313}
11314
11315/* Display the contents of the version sections. */
98fb390a 11316
32ec8896 11317static bfd_boolean
dda8d76d 11318process_version_sections (Filedata * filedata)
252b5132 11319{
2cf0635d 11320 Elf_Internal_Shdr * section;
b34976b6 11321 unsigned i;
32ec8896 11322 bfd_boolean found = FALSE;
252b5132
RH
11323
11324 if (! do_version)
32ec8896 11325 return TRUE;
252b5132 11326
dda8d76d
NC
11327 for (i = 0, section = filedata->section_headers;
11328 i < filedata->file_header.e_shnum;
b34976b6 11329 i++, section++)
252b5132
RH
11330 {
11331 switch (section->sh_type)
11332 {
11333 case SHT_GNU_verdef:
11334 {
2cf0635d 11335 Elf_External_Verdef * edefs;
452bf675
AM
11336 unsigned long idx;
11337 unsigned long cnt;
2cf0635d 11338 char * endbuf;
252b5132 11339
32ec8896 11340 found = TRUE;
252b5132 11341
ca0e11aa
NC
11342 if (filedata->is_separate)
11343 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
11344 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
11345 section->sh_info),
11346 filedata->file_name,
11347 printable_section_name (filedata, section),
11348 section->sh_info);
11349 else
11350 printf (ngettext ("\nVersion definition section '%s' "
11351 "contains %u entry:\n",
11352 "\nVersion definition section '%s' "
11353 "contains %u entries:\n",
11354 section->sh_info),
11355 printable_section_name (filedata, section),
11356 section->sh_info);
11357
ae9ac79e 11358 printf (_(" Addr: 0x"));
252b5132 11359 printf_vma (section->sh_addr);
233f82cf 11360 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11361 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11362 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11363
3f5e193b 11364 edefs = (Elf_External_Verdef *)
dda8d76d 11365 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11366 _("version definition section"));
a6e9f9df
AM
11367 if (!edefs)
11368 break;
59245841 11369 endbuf = (char *) edefs + section->sh_size;
252b5132 11370
1445030f 11371 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11372 {
2cf0635d
NC
11373 char * vstart;
11374 Elf_External_Verdef * edef;
b34976b6 11375 Elf_Internal_Verdef ent;
2cf0635d 11376 Elf_External_Verdaux * eaux;
b34976b6 11377 Elf_Internal_Verdaux aux;
452bf675 11378 unsigned long isum;
b34976b6 11379 int j;
103f02d3 11380
252b5132 11381 vstart = ((char *) edefs) + idx;
54806181
AM
11382 if (vstart + sizeof (*edef) > endbuf)
11383 break;
252b5132
RH
11384
11385 edef = (Elf_External_Verdef *) vstart;
11386
11387 ent.vd_version = BYTE_GET (edef->vd_version);
11388 ent.vd_flags = BYTE_GET (edef->vd_flags);
11389 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11390 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11391 ent.vd_hash = BYTE_GET (edef->vd_hash);
11392 ent.vd_aux = BYTE_GET (edef->vd_aux);
11393 ent.vd_next = BYTE_GET (edef->vd_next);
11394
452bf675 11395 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11396 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11397
11398 printf (_(" Index: %d Cnt: %d "),
11399 ent.vd_ndx, ent.vd_cnt);
11400
452bf675 11401 /* Check for overflow. */
1445030f 11402 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11403 break;
11404
252b5132
RH
11405 vstart += ent.vd_aux;
11406
1445030f
AM
11407 if (vstart + sizeof (*eaux) > endbuf)
11408 break;
252b5132
RH
11409 eaux = (Elf_External_Verdaux *) vstart;
11410
11411 aux.vda_name = BYTE_GET (eaux->vda_name);
11412 aux.vda_next = BYTE_GET (eaux->vda_next);
11413
978c4450
AM
11414 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
11415 printf (_("Name: %s\n"),
11416 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132
RH
11417 else
11418 printf (_("Name index: %ld\n"), aux.vda_name);
11419
11420 isum = idx + ent.vd_aux;
11421
b34976b6 11422 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11423 {
1445030f
AM
11424 if (aux.vda_next < sizeof (*eaux)
11425 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11426 {
11427 warn (_("Invalid vda_next field of %lx\n"),
11428 aux.vda_next);
11429 j = ent.vd_cnt;
11430 break;
11431 }
dd24e3da 11432 /* Check for overflow. */
7e26601c 11433 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11434 break;
11435
252b5132
RH
11436 isum += aux.vda_next;
11437 vstart += aux.vda_next;
11438
54806181
AM
11439 if (vstart + sizeof (*eaux) > endbuf)
11440 break;
1445030f 11441 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11442
11443 aux.vda_name = BYTE_GET (eaux->vda_name);
11444 aux.vda_next = BYTE_GET (eaux->vda_next);
11445
978c4450 11446 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
452bf675 11447 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450
AM
11448 isum, j,
11449 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132 11450 else
452bf675 11451 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11452 isum, j, aux.vda_name);
11453 }
dd24e3da 11454
54806181
AM
11455 if (j < ent.vd_cnt)
11456 printf (_(" Version def aux past end of section\n"));
252b5132 11457
c9f02c3e
MR
11458 /* PR 17531:
11459 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11460 if (ent.vd_next < sizeof (*edef)
11461 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11462 {
11463 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11464 cnt = section->sh_info;
11465 break;
11466 }
452bf675 11467 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11468 break;
11469
252b5132
RH
11470 idx += ent.vd_next;
11471 }
dd24e3da 11472
54806181
AM
11473 if (cnt < section->sh_info)
11474 printf (_(" Version definition past end of section\n"));
252b5132
RH
11475
11476 free (edefs);
11477 }
11478 break;
103f02d3 11479
252b5132
RH
11480 case SHT_GNU_verneed:
11481 {
2cf0635d 11482 Elf_External_Verneed * eneed;
452bf675
AM
11483 unsigned long idx;
11484 unsigned long cnt;
2cf0635d 11485 char * endbuf;
252b5132 11486
32ec8896 11487 found = TRUE;
252b5132 11488
ca0e11aa
NC
11489 if (filedata->is_separate)
11490 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
11491 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
11492 section->sh_info),
11493 filedata->file_name,
11494 printable_section_name (filedata, section),
11495 section->sh_info);
11496 else
11497 printf (ngettext ("\nVersion needs section '%s' "
11498 "contains %u entry:\n",
11499 "\nVersion needs section '%s' "
11500 "contains %u entries:\n",
11501 section->sh_info),
11502 printable_section_name (filedata, section),
11503 section->sh_info);
11504
252b5132
RH
11505 printf (_(" Addr: 0x"));
11506 printf_vma (section->sh_addr);
72de5009 11507 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11508 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11509 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11510
dda8d76d 11511 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11512 section->sh_offset, 1,
11513 section->sh_size,
9cf03b7e 11514 _("Version Needs section"));
a6e9f9df
AM
11515 if (!eneed)
11516 break;
59245841 11517 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11518
11519 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11520 {
2cf0635d 11521 Elf_External_Verneed * entry;
b34976b6 11522 Elf_Internal_Verneed ent;
452bf675 11523 unsigned long isum;
b34976b6 11524 int j;
2cf0635d 11525 char * vstart;
252b5132
RH
11526
11527 vstart = ((char *) eneed) + idx;
54806181
AM
11528 if (vstart + sizeof (*entry) > endbuf)
11529 break;
252b5132
RH
11530
11531 entry = (Elf_External_Verneed *) vstart;
11532
11533 ent.vn_version = BYTE_GET (entry->vn_version);
11534 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11535 ent.vn_file = BYTE_GET (entry->vn_file);
11536 ent.vn_aux = BYTE_GET (entry->vn_aux);
11537 ent.vn_next = BYTE_GET (entry->vn_next);
11538
452bf675 11539 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11540
978c4450
AM
11541 if (VALID_DYNAMIC_NAME (filedata, ent.vn_file))
11542 printf (_(" File: %s"),
11543 GET_DYNAMIC_NAME (filedata, ent.vn_file));
252b5132
RH
11544 else
11545 printf (_(" File: %lx"), ent.vn_file);
11546
11547 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11548
dd24e3da 11549 /* Check for overflow. */
7e26601c 11550 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11551 break;
252b5132
RH
11552 vstart += ent.vn_aux;
11553
11554 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11555 {
2cf0635d 11556 Elf_External_Vernaux * eaux;
b34976b6 11557 Elf_Internal_Vernaux aux;
252b5132 11558
54806181
AM
11559 if (vstart + sizeof (*eaux) > endbuf)
11560 break;
252b5132
RH
11561 eaux = (Elf_External_Vernaux *) vstart;
11562
11563 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11564 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11565 aux.vna_other = BYTE_GET (eaux->vna_other);
11566 aux.vna_name = BYTE_GET (eaux->vna_name);
11567 aux.vna_next = BYTE_GET (eaux->vna_next);
11568
978c4450 11569 if (VALID_DYNAMIC_NAME (filedata, aux.vna_name))
452bf675 11570 printf (_(" %#06lx: Name: %s"),
978c4450 11571 isum, GET_DYNAMIC_NAME (filedata, aux.vna_name));
252b5132 11572 else
452bf675 11573 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11574 isum, aux.vna_name);
11575
11576 printf (_(" Flags: %s Version: %d\n"),
11577 get_ver_flags (aux.vna_flags), aux.vna_other);
11578
1445030f
AM
11579 if (aux.vna_next < sizeof (*eaux)
11580 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11581 {
11582 warn (_("Invalid vna_next field of %lx\n"),
11583 aux.vna_next);
11584 j = ent.vn_cnt;
11585 break;
11586 }
1445030f
AM
11587 /* Check for overflow. */
11588 if (aux.vna_next > (size_t) (endbuf - vstart))
11589 break;
252b5132
RH
11590 isum += aux.vna_next;
11591 vstart += aux.vna_next;
11592 }
9cf03b7e 11593
54806181 11594 if (j < ent.vn_cnt)
f9a6a8f0 11595 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 11596
1445030f
AM
11597 if (ent.vn_next < sizeof (*entry)
11598 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11599 {
452bf675 11600 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11601 cnt = section->sh_info;
11602 break;
11603 }
1445030f
AM
11604 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11605 break;
252b5132
RH
11606 idx += ent.vn_next;
11607 }
9cf03b7e 11608
54806181 11609 if (cnt < section->sh_info)
9cf03b7e 11610 warn (_("Missing Version Needs information\n"));
103f02d3 11611
252b5132
RH
11612 free (eneed);
11613 }
11614 break;
11615
11616 case SHT_GNU_versym:
11617 {
2cf0635d 11618 Elf_Internal_Shdr * link_section;
8b73c356
NC
11619 size_t total;
11620 unsigned int cnt;
2cf0635d
NC
11621 unsigned char * edata;
11622 unsigned short * data;
11623 char * strtab;
11624 Elf_Internal_Sym * symbols;
11625 Elf_Internal_Shdr * string_sec;
ba5cdace 11626 unsigned long num_syms;
d3ba0551 11627 long off;
252b5132 11628
dda8d76d 11629 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11630 break;
11631
dda8d76d 11632 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11633 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11634
dda8d76d 11635 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11636 break;
11637
32ec8896 11638 found = TRUE;
252b5132 11639
dda8d76d 11640 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
11641 if (symbols == NULL)
11642 break;
252b5132 11643
dda8d76d 11644 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11645
dda8d76d 11646 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11647 string_sec->sh_size,
11648 _("version string table"));
a6e9f9df 11649 if (!strtab)
0429c154
MS
11650 {
11651 free (symbols);
11652 break;
11653 }
252b5132 11654
ca0e11aa
NC
11655 if (filedata->is_separate)
11656 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
11657 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
11658 total),
11659 filedata->file_name,
11660 printable_section_name (filedata, section),
11661 (unsigned long) total);
11662 else
11663 printf (ngettext ("\nVersion symbols section '%s' "
11664 "contains %lu entry:\n",
11665 "\nVersion symbols section '%s' "
11666 "contains %lu entries:\n",
11667 total),
11668 printable_section_name (filedata, section),
11669 (unsigned long) total);
252b5132 11670
ae9ac79e 11671 printf (_(" Addr: 0x"));
252b5132 11672 printf_vma (section->sh_addr);
72de5009 11673 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11674 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11675 printable_section_name (filedata, link_section));
252b5132 11676
dda8d76d 11677 off = offset_from_vma (filedata,
978c4450 11678 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11679 total * sizeof (short));
95099889
AM
11680 edata = (unsigned char *) get_data (NULL, filedata, off,
11681 sizeof (short), total,
11682 _("version symbol data"));
a6e9f9df
AM
11683 if (!edata)
11684 {
11685 free (strtab);
0429c154 11686 free (symbols);
a6e9f9df
AM
11687 break;
11688 }
252b5132 11689
3f5e193b 11690 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11691
11692 for (cnt = total; cnt --;)
b34976b6
AM
11693 data[cnt] = byte_get (edata + cnt * sizeof (short),
11694 sizeof (short));
252b5132
RH
11695
11696 free (edata);
11697
11698 for (cnt = 0; cnt < total; cnt += 4)
11699 {
11700 int j, nn;
ab273396
AM
11701 char *name;
11702 char *invalid = _("*invalid*");
252b5132
RH
11703
11704 printf (" %03x:", cnt);
11705
11706 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11707 switch (data[cnt + j])
252b5132
RH
11708 {
11709 case 0:
11710 fputs (_(" 0 (*local*) "), stdout);
11711 break;
11712
11713 case 1:
11714 fputs (_(" 1 (*global*) "), stdout);
11715 break;
11716
11717 default:
c244d050
NC
11718 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11719 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11720
dd24e3da 11721 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11722 array, break to avoid an out-of-bounds read. */
11723 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11724 {
11725 warn (_("invalid index into symbol array\n"));
11726 break;
11727 }
11728
ab273396 11729 name = NULL;
978c4450 11730 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11731 {
b34976b6
AM
11732 Elf_Internal_Verneed ivn;
11733 unsigned long offset;
252b5132 11734
d93f0186 11735 offset = offset_from_vma
978c4450
AM
11736 (filedata,
11737 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11738 sizeof (Elf_External_Verneed));
252b5132 11739
b34976b6 11740 do
252b5132 11741 {
b34976b6
AM
11742 Elf_Internal_Vernaux ivna;
11743 Elf_External_Verneed evn;
11744 Elf_External_Vernaux evna;
11745 unsigned long a_off;
252b5132 11746
dda8d76d 11747 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11748 _("version need")) == NULL)
11749 break;
0b4362b0 11750
252b5132
RH
11751 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11752 ivn.vn_next = BYTE_GET (evn.vn_next);
11753
11754 a_off = offset + ivn.vn_aux;
11755
11756 do
11757 {
dda8d76d 11758 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11759 1, _("version need aux (2)")) == NULL)
11760 {
11761 ivna.vna_next = 0;
11762 ivna.vna_other = 0;
11763 }
11764 else
11765 {
11766 ivna.vna_next = BYTE_GET (evna.vna_next);
11767 ivna.vna_other = BYTE_GET (evna.vna_other);
11768 }
252b5132
RH
11769
11770 a_off += ivna.vna_next;
11771 }
b34976b6 11772 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11773 && ivna.vna_next != 0);
11774
b34976b6 11775 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11776 {
11777 ivna.vna_name = BYTE_GET (evna.vna_name);
11778
54806181 11779 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11780 name = invalid;
54806181
AM
11781 else
11782 name = strtab + ivna.vna_name;
252b5132
RH
11783 break;
11784 }
11785
11786 offset += ivn.vn_next;
11787 }
11788 while (ivn.vn_next);
11789 }
00d93f34 11790
ab273396 11791 if (data[cnt + j] != 0x8001
978c4450 11792 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 11793 {
b34976b6
AM
11794 Elf_Internal_Verdef ivd;
11795 Elf_External_Verdef evd;
11796 unsigned long offset;
252b5132 11797
d93f0186 11798 offset = offset_from_vma
978c4450
AM
11799 (filedata,
11800 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 11801 sizeof evd);
252b5132
RH
11802
11803 do
11804 {
dda8d76d 11805 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
11806 _("version def")) == NULL)
11807 {
11808 ivd.vd_next = 0;
948f632f 11809 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
11810 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
11811 break;
59245841
NC
11812 }
11813 else
11814 {
11815 ivd.vd_next = BYTE_GET (evd.vd_next);
11816 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11817 }
252b5132
RH
11818
11819 offset += ivd.vd_next;
11820 }
c244d050 11821 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
11822 && ivd.vd_next != 0);
11823
c244d050 11824 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 11825 {
b34976b6
AM
11826 Elf_External_Verdaux evda;
11827 Elf_Internal_Verdaux ivda;
252b5132
RH
11828
11829 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11830
dda8d76d 11831 if (get_data (&evda, filedata,
59245841
NC
11832 offset - ivd.vd_next + ivd.vd_aux,
11833 sizeof (evda), 1,
11834 _("version def aux")) == NULL)
11835 break;
252b5132
RH
11836
11837 ivda.vda_name = BYTE_GET (evda.vda_name);
11838
54806181 11839 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
11840 name = invalid;
11841 else if (name != NULL && name != invalid)
11842 name = _("*both*");
54806181
AM
11843 else
11844 name = strtab + ivda.vda_name;
252b5132
RH
11845 }
11846 }
ab273396
AM
11847 if (name != NULL)
11848 nn += printf ("(%s%-*s",
11849 name,
11850 12 - (int) strlen (name),
11851 ")");
252b5132
RH
11852
11853 if (nn < 18)
11854 printf ("%*c", 18 - nn, ' ');
11855 }
11856
11857 putchar ('\n');
11858 }
11859
11860 free (data);
11861 free (strtab);
11862 free (symbols);
11863 }
11864 break;
103f02d3 11865
252b5132
RH
11866 default:
11867 break;
11868 }
11869 }
11870
11871 if (! found)
ca0e11aa
NC
11872 {
11873 if (filedata->is_separate)
11874 printf (_("\nNo version information found in linked file '%s'.\n"),
11875 filedata->file_name);
11876 else
11877 printf (_("\nNo version information found in this file.\n"));
11878 }
252b5132 11879
32ec8896 11880 return TRUE;
252b5132
RH
11881}
11882
d1133906 11883static const char *
dda8d76d 11884get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 11885{
89246a0e 11886 static char buff[64];
252b5132
RH
11887
11888 switch (binding)
11889 {
b34976b6
AM
11890 case STB_LOCAL: return "LOCAL";
11891 case STB_GLOBAL: return "GLOBAL";
11892 case STB_WEAK: return "WEAK";
252b5132
RH
11893 default:
11894 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
11895 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
11896 binding);
252b5132 11897 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
11898 {
11899 if (binding == STB_GNU_UNIQUE
df3a023b 11900 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
11901 return "UNIQUE";
11902 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
11903 }
252b5132 11904 else
e9e44622 11905 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
11906 return buff;
11907 }
11908}
11909
d1133906 11910static const char *
dda8d76d 11911get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 11912{
89246a0e 11913 static char buff[64];
252b5132
RH
11914
11915 switch (type)
11916 {
b34976b6
AM
11917 case STT_NOTYPE: return "NOTYPE";
11918 case STT_OBJECT: return "OBJECT";
11919 case STT_FUNC: return "FUNC";
11920 case STT_SECTION: return "SECTION";
11921 case STT_FILE: return "FILE";
11922 case STT_COMMON: return "COMMON";
11923 case STT_TLS: return "TLS";
15ab5209
DB
11924 case STT_RELC: return "RELC";
11925 case STT_SRELC: return "SRELC";
252b5132
RH
11926 default:
11927 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 11928 {
dda8d76d 11929 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 11930 return "THUMB_FUNC";
103f02d3 11931
dda8d76d 11932 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
11933 return "REGISTER";
11934
dda8d76d 11935 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
11936 return "PARISC_MILLI";
11937
e9e44622 11938 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 11939 }
252b5132 11940 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 11941 {
dda8d76d 11942 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
11943 {
11944 if (type == STT_HP_OPAQUE)
11945 return "HP_OPAQUE";
11946 if (type == STT_HP_STUB)
11947 return "HP_STUB";
11948 }
11949
d8045f23 11950 if (type == STT_GNU_IFUNC
dda8d76d 11951 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 11952 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
11953 return "IFUNC";
11954
e9e44622 11955 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 11956 }
252b5132 11957 else
e9e44622 11958 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
11959 return buff;
11960 }
11961}
11962
d1133906 11963static const char *
d3ba0551 11964get_symbol_visibility (unsigned int visibility)
d1133906
NC
11965{
11966 switch (visibility)
11967 {
b34976b6
AM
11968 case STV_DEFAULT: return "DEFAULT";
11969 case STV_INTERNAL: return "INTERNAL";
11970 case STV_HIDDEN: return "HIDDEN";
d1133906 11971 case STV_PROTECTED: return "PROTECTED";
bee0ee85 11972 default:
27a45f42 11973 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 11974 return _("<unknown>");
d1133906
NC
11975 }
11976}
11977
2057d69d
CZ
11978static const char *
11979get_alpha_symbol_other (unsigned int other)
9abca702 11980{
2057d69d
CZ
11981 switch (other)
11982 {
11983 case STO_ALPHA_NOPV: return "NOPV";
11984 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
11985 default:
27a45f42 11986 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 11987 return _("<unknown>");
9abca702 11988 }
2057d69d
CZ
11989}
11990
fd85a6a1
NC
11991static const char *
11992get_solaris_symbol_visibility (unsigned int visibility)
11993{
11994 switch (visibility)
11995 {
11996 case 4: return "EXPORTED";
11997 case 5: return "SINGLETON";
11998 case 6: return "ELIMINATE";
11999 default: return get_symbol_visibility (visibility);
12000 }
12001}
12002
2301ed1c
SN
12003static const char *
12004get_aarch64_symbol_other (unsigned int other)
12005{
12006 static char buf[32];
12007
12008 if (other & STO_AARCH64_VARIANT_PCS)
12009 {
12010 other &= ~STO_AARCH64_VARIANT_PCS;
12011 if (other == 0)
12012 return "VARIANT_PCS";
12013 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12014 return buf;
12015 }
12016 return NULL;
12017}
12018
5e2b0d47
NC
12019static const char *
12020get_mips_symbol_other (unsigned int other)
12021{
12022 switch (other)
12023 {
32ec8896
NC
12024 case STO_OPTIONAL: return "OPTIONAL";
12025 case STO_MIPS_PLT: return "MIPS PLT";
12026 case STO_MIPS_PIC: return "MIPS PIC";
12027 case STO_MICROMIPS: return "MICROMIPS";
12028 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12029 case STO_MIPS16: return "MIPS16";
12030 default: return NULL;
5e2b0d47
NC
12031 }
12032}
12033
28f997cf 12034static const char *
dda8d76d 12035get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12036{
dda8d76d 12037 if (is_ia64_vms (filedata))
28f997cf
TG
12038 {
12039 static char res[32];
12040
12041 res[0] = 0;
12042
12043 /* Function types is for images and .STB files only. */
dda8d76d 12044 switch (filedata->file_header.e_type)
28f997cf
TG
12045 {
12046 case ET_DYN:
12047 case ET_EXEC:
12048 switch (VMS_ST_FUNC_TYPE (other))
12049 {
12050 case VMS_SFT_CODE_ADDR:
12051 strcat (res, " CA");
12052 break;
12053 case VMS_SFT_SYMV_IDX:
12054 strcat (res, " VEC");
12055 break;
12056 case VMS_SFT_FD:
12057 strcat (res, " FD");
12058 break;
12059 case VMS_SFT_RESERVE:
12060 strcat (res, " RSV");
12061 break;
12062 default:
bee0ee85
NC
12063 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12064 VMS_ST_FUNC_TYPE (other));
12065 strcat (res, " <unknown>");
12066 break;
28f997cf
TG
12067 }
12068 break;
12069 default:
12070 break;
12071 }
12072 switch (VMS_ST_LINKAGE (other))
12073 {
12074 case VMS_STL_IGNORE:
12075 strcat (res, " IGN");
12076 break;
12077 case VMS_STL_RESERVE:
12078 strcat (res, " RSV");
12079 break;
12080 case VMS_STL_STD:
12081 strcat (res, " STD");
12082 break;
12083 case VMS_STL_LNK:
12084 strcat (res, " LNK");
12085 break;
12086 default:
bee0ee85
NC
12087 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12088 VMS_ST_LINKAGE (other));
12089 strcat (res, " <unknown>");
12090 break;
28f997cf
TG
12091 }
12092
12093 if (res[0] != 0)
12094 return res + 1;
12095 else
12096 return res;
12097 }
12098 return NULL;
12099}
12100
6911b7dc
AM
12101static const char *
12102get_ppc64_symbol_other (unsigned int other)
12103{
14732552
AM
12104 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12105 return NULL;
12106
12107 other >>= STO_PPC64_LOCAL_BIT;
12108 if (other <= 6)
6911b7dc 12109 {
89246a0e 12110 static char buf[64];
14732552
AM
12111 if (other >= 2)
12112 other = ppc64_decode_local_entry (other);
12113 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12114 return buf;
12115 }
12116 return NULL;
12117}
12118
5e2b0d47 12119static const char *
dda8d76d 12120get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12121{
12122 const char * result = NULL;
89246a0e 12123 static char buff [64];
5e2b0d47
NC
12124
12125 if (other == 0)
12126 return "";
12127
dda8d76d 12128 switch (filedata->file_header.e_machine)
5e2b0d47 12129 {
2057d69d
CZ
12130 case EM_ALPHA:
12131 result = get_alpha_symbol_other (other);
12132 break;
2301ed1c
SN
12133 case EM_AARCH64:
12134 result = get_aarch64_symbol_other (other);
12135 break;
5e2b0d47
NC
12136 case EM_MIPS:
12137 result = get_mips_symbol_other (other);
28f997cf
TG
12138 break;
12139 case EM_IA_64:
dda8d76d 12140 result = get_ia64_symbol_other (filedata, other);
28f997cf 12141 break;
6911b7dc
AM
12142 case EM_PPC64:
12143 result = get_ppc64_symbol_other (other);
12144 break;
5e2b0d47 12145 default:
fd85a6a1 12146 result = NULL;
5e2b0d47
NC
12147 break;
12148 }
12149
12150 if (result)
12151 return result;
12152
12153 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12154 return buff;
12155}
12156
d1133906 12157static const char *
dda8d76d 12158get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12159{
b34976b6 12160 static char buff[32];
5cf1065c 12161
252b5132
RH
12162 switch (type)
12163 {
b34976b6
AM
12164 case SHN_UNDEF: return "UND";
12165 case SHN_ABS: return "ABS";
12166 case SHN_COMMON: return "COM";
252b5132 12167 default:
9ce701e2 12168 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12169 && filedata->file_header.e_machine == EM_IA_64
12170 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12171 return "ANSI_COM";
12172 else if ((filedata->file_header.e_machine == EM_X86_64
12173 || filedata->file_header.e_machine == EM_L1OM
12174 || filedata->file_header.e_machine == EM_K1OM)
12175 && type == SHN_X86_64_LCOMMON)
12176 return "LARGE_COM";
12177 else if ((type == SHN_MIPS_SCOMMON
12178 && filedata->file_header.e_machine == EM_MIPS)
12179 || (type == SHN_TIC6X_SCOMMON
12180 && filedata->file_header.e_machine == EM_TI_C6000))
12181 return "SCOM";
12182 else if (type == SHN_MIPS_SUNDEFINED
12183 && filedata->file_header.e_machine == EM_MIPS)
12184 return "SUND";
12185 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12186 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12187 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12188 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12189 else if (type >= SHN_LORESERVE)
12190 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12191 else if (filedata->file_header.e_shnum != 0
12192 && type >= filedata->file_header.e_shnum)
12193 sprintf (buff, _("bad section index[%3d]"), type);
12194 else
12195 sprintf (buff, "%3d", type);
12196 break;
fd85a6a1
NC
12197 }
12198
10ca4b04 12199 return buff;
6bd1a22c
L
12200}
12201
bb4d2ac2 12202static const char *
dda8d76d 12203get_symbol_version_string (Filedata * filedata,
1449284b
NC
12204 bfd_boolean is_dynsym,
12205 const char * strtab,
12206 unsigned long int strtab_size,
12207 unsigned int si,
12208 Elf_Internal_Sym * psym,
12209 enum versioned_symbol_info * sym_info,
12210 unsigned short * vna_other)
bb4d2ac2 12211{
ab273396
AM
12212 unsigned char data[2];
12213 unsigned short vers_data;
12214 unsigned long offset;
7a815dd5 12215 unsigned short max_vd_ndx;
bb4d2ac2 12216
ab273396 12217 if (!is_dynsym
978c4450 12218 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12219 return NULL;
bb4d2ac2 12220
978c4450
AM
12221 offset = offset_from_vma (filedata,
12222 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12223 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12224
dda8d76d 12225 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12226 sizeof (data), 1, _("version data")) == NULL)
12227 return NULL;
12228
12229 vers_data = byte_get (data, 2);
bb4d2ac2 12230
1f6f5dba 12231 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12232 return NULL;
bb4d2ac2 12233
0b8b7609 12234 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12235 max_vd_ndx = 0;
12236
ab273396
AM
12237 /* Usually we'd only see verdef for defined symbols, and verneed for
12238 undefined symbols. However, symbols defined by the linker in
12239 .dynbss for variables copied from a shared library in order to
12240 avoid text relocations are defined yet have verneed. We could
12241 use a heuristic to detect the special case, for example, check
12242 for verneed first on symbols defined in SHT_NOBITS sections, but
12243 it is simpler and more reliable to just look for both verdef and
12244 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12245
ab273396
AM
12246 if (psym->st_shndx != SHN_UNDEF
12247 && vers_data != 0x8001
978c4450 12248 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12249 {
12250 Elf_Internal_Verdef ivd;
12251 Elf_Internal_Verdaux ivda;
12252 Elf_External_Verdaux evda;
12253 unsigned long off;
bb4d2ac2 12254
dda8d76d 12255 off = offset_from_vma (filedata,
978c4450 12256 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12257 sizeof (Elf_External_Verdef));
12258
12259 do
bb4d2ac2 12260 {
ab273396
AM
12261 Elf_External_Verdef evd;
12262
dda8d76d 12263 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12264 _("version def")) == NULL)
12265 {
12266 ivd.vd_ndx = 0;
12267 ivd.vd_aux = 0;
12268 ivd.vd_next = 0;
1f6f5dba 12269 ivd.vd_flags = 0;
ab273396
AM
12270 }
12271 else
bb4d2ac2 12272 {
ab273396
AM
12273 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12274 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12275 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12276 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12277 }
bb4d2ac2 12278
7a815dd5
L
12279 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12280 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12281
ab273396
AM
12282 off += ivd.vd_next;
12283 }
12284 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12285
ab273396
AM
12286 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12287 {
9abca702 12288 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12289 return NULL;
12290
ab273396
AM
12291 off -= ivd.vd_next;
12292 off += ivd.vd_aux;
bb4d2ac2 12293
dda8d76d 12294 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12295 _("version def aux")) != NULL)
12296 {
12297 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12298
ab273396 12299 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12300 return (ivda.vda_name < strtab_size
12301 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12302 }
12303 }
12304 }
bb4d2ac2 12305
978c4450 12306 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12307 {
12308 Elf_External_Verneed evn;
12309 Elf_Internal_Verneed ivn;
12310 Elf_Internal_Vernaux ivna;
bb4d2ac2 12311
dda8d76d 12312 offset = offset_from_vma (filedata,
978c4450 12313 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12314 sizeof evn);
12315 do
12316 {
12317 unsigned long vna_off;
bb4d2ac2 12318
dda8d76d 12319 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12320 _("version need")) == NULL)
12321 {
12322 ivna.vna_next = 0;
12323 ivna.vna_other = 0;
12324 ivna.vna_name = 0;
12325 break;
12326 }
bb4d2ac2 12327
ab273396
AM
12328 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12329 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12330
ab273396 12331 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12332
ab273396
AM
12333 do
12334 {
12335 Elf_External_Vernaux evna;
bb4d2ac2 12336
dda8d76d 12337 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12338 _("version need aux (3)")) == NULL)
bb4d2ac2 12339 {
ab273396
AM
12340 ivna.vna_next = 0;
12341 ivna.vna_other = 0;
12342 ivna.vna_name = 0;
bb4d2ac2 12343 }
bb4d2ac2 12344 else
bb4d2ac2 12345 {
ab273396
AM
12346 ivna.vna_other = BYTE_GET (evna.vna_other);
12347 ivna.vna_next = BYTE_GET (evna.vna_next);
12348 ivna.vna_name = BYTE_GET (evna.vna_name);
12349 }
bb4d2ac2 12350
ab273396
AM
12351 vna_off += ivna.vna_next;
12352 }
12353 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12354
ab273396
AM
12355 if (ivna.vna_other == vers_data)
12356 break;
bb4d2ac2 12357
ab273396
AM
12358 offset += ivn.vn_next;
12359 }
12360 while (ivn.vn_next != 0);
bb4d2ac2 12361
ab273396
AM
12362 if (ivna.vna_other == vers_data)
12363 {
12364 *sym_info = symbol_undefined;
12365 *vna_other = ivna.vna_other;
12366 return (ivna.vna_name < strtab_size
12367 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12368 }
7a815dd5
L
12369 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12370 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12371 return _("<corrupt>");
bb4d2ac2 12372 }
ab273396 12373 return NULL;
bb4d2ac2
L
12374}
12375
10ca4b04
L
12376static void
12377print_dynamic_symbol (Filedata *filedata, unsigned long si,
12378 Elf_Internal_Sym *symtab,
12379 Elf_Internal_Shdr *section,
12380 char *strtab, size_t strtab_size)
252b5132 12381{
10ca4b04
L
12382 const char *version_string;
12383 enum versioned_symbol_info sym_info;
12384 unsigned short vna_other;
12385 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 12386
10ca4b04
L
12387 printf ("%6ld: ", si);
12388 print_vma (psym->st_value, LONG_HEX);
12389 putchar (' ');
12390 print_vma (psym->st_size, DEC_5);
12391 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12392 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12393 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12394 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12395 else
252b5132 12396 {
10ca4b04 12397 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12398
10ca4b04
L
12399 printf (" %-7s", get_symbol_visibility (vis));
12400 /* Check to see if any other bits in the st_other field are set.
12401 Note - displaying this information disrupts the layout of the
12402 table being generated, but for the moment this case is very rare. */
12403 if (psym->st_other ^ vis)
12404 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12405 }
10ca4b04 12406 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab
NC
12407
12408 bfd_boolean is_valid = VALID_SYMBOL_NAME (strtab, strtab_size,
12409 psym->st_name);
12410 const char * sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
10ca4b04
L
12411
12412 version_string
12413 = get_symbol_version_string (filedata,
12414 (section == NULL
12415 || section->sh_type == SHT_DYNSYM),
12416 strtab, strtab_size, si,
12417 psym, &sym_info, &vna_other);
b9e920ec 12418
0942c7ab
NC
12419 int len_avail = 21;
12420 if (! do_wide && version_string != NULL)
12421 {
ddb43bab 12422 char buffer[16];
0942c7ab 12423
ddb43bab 12424 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
12425
12426 if (sym_info == symbol_undefined)
12427 len_avail -= sprintf (buffer," (%d)", vna_other);
12428 else if (sym_info != symbol_hidden)
12429 len_avail -= 1;
12430 }
12431
12432 print_symbol (len_avail, sstr);
b9e920ec 12433
10ca4b04
L
12434 if (version_string)
12435 {
12436 if (sym_info == symbol_undefined)
12437 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12438 else
10ca4b04
L
12439 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12440 version_string);
12441 }
6bd1a22c 12442
10ca4b04 12443 putchar ('\n');
6bd1a22c 12444
10ca4b04
L
12445 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12446 && section != NULL
12447 && si >= section->sh_info
12448 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12449 && filedata->file_header.e_machine != EM_MIPS
12450 /* Solaris binaries have been found to violate this requirement as
12451 well. Not sure if this is a bug or an ABI requirement. */
12452 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12453 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12454 si, printable_section_name (filedata, section), section->sh_info);
12455}
f16a9783 12456
0f03783c
NC
12457static const char *
12458get_lto_kind (unsigned int kind)
12459{
12460 switch (kind)
12461 {
12462 case 0: return "DEF";
12463 case 1: return "WEAKDEF";
12464 case 2: return "UNDEF";
12465 case 3: return "WEAKUNDEF";
12466 case 4: return "COMMON";
12467 default:
12468 break;
12469 }
12470
12471 static char buffer[30];
12472 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
12473 sprintf (buffer, "<unknown: %u>", kind);
12474 return buffer;
12475}
12476
12477static const char *
12478get_lto_visibility (unsigned int visibility)
12479{
12480 switch (visibility)
12481 {
12482 case 0: return "DEFAULT";
12483 case 1: return "PROTECTED";
12484 case 2: return "INTERNAL";
12485 case 3: return "HIDDEN";
12486 default:
12487 break;
12488 }
12489
12490 static char buffer[30];
12491 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
12492 sprintf (buffer, "<unknown: %u>", visibility);
12493 return buffer;
12494}
12495
12496static const char *
12497get_lto_sym_type (unsigned int sym_type)
12498{
12499 switch (sym_type)
12500 {
12501 case 0: return "UNKNOWN";
12502 case 1: return "FUNCTION";
12503 case 2: return "VARIABLE";
12504 default:
12505 break;
12506 }
12507
12508 static char buffer[30];
12509 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
12510 sprintf (buffer, "<unknown: %u>", sym_type);
12511 return buffer;
12512}
12513
12514/* Display an LTO format symbol table.
12515 FIXME: The format of LTO symbol tables is not formalized.
12516 So this code could need changing in the future. */
12517
12518static bfd_boolean
12519display_lto_symtab (Filedata * filedata,
12520 Elf_Internal_Shdr * section)
12521{
12522 if (section->sh_size == 0)
12523 {
ca0e11aa
NC
12524 if (filedata->is_separate)
12525 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
12526 printable_section_name (filedata, section),
12527 filedata->file_name);
12528 else
12529 printf (_("\nLTO Symbol table '%s' is empty!\n"),
12530 printable_section_name (filedata, section));
12531
0f03783c
NC
12532 return TRUE;
12533 }
12534
12535 if (section->sh_size > filedata->file_size)
12536 {
12537 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
12538 printable_section_name (filedata, section),
12539 (unsigned long) section->sh_size);
12540 return FALSE;
12541 }
12542
12543 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
12544 section->sh_size, 1, _("LTO symbols"));
12545 if (alloced_data == NULL)
12546 return FALSE;
12547
12548 /* Look for extended data for the symbol table. */
12549 Elf_Internal_Shdr * ext;
12550 void * ext_data_orig = NULL;
12551 char * ext_data = NULL;
12552 char * ext_data_end = NULL;
12553 char * ext_name = NULL;
12554
12555 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
b9e920ec 12556 SECTION_NAME (section) + sizeof (".gnu.lto_.symtab.") - 1) > 0
0f03783c
NC
12557 && ext_name != NULL /* Paranoia. */
12558 && (ext = find_section (filedata, ext_name)) != NULL)
12559 {
12560 if (ext->sh_size < 3)
12561 error (_("LTO Symbol extension table '%s' is empty!\n"),
12562 printable_section_name (filedata, ext));
12563 else
12564 {
12565 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
12566 ext->sh_size, 1,
12567 _("LTO ext symbol data"));
12568 if (ext_data != NULL)
12569 {
12570 ext_data_end = ext_data + ext->sh_size;
12571 if (* ext_data++ != 1)
12572 error (_("Unexpected version number in symbol extension table\n"));
12573 }
12574 }
12575 }
b9e920ec 12576
0f03783c
NC
12577 const unsigned char * data = (const unsigned char *) alloced_data;
12578 const unsigned char * end = data + section->sh_size;
12579
ca0e11aa
NC
12580 if (filedata->is_separate)
12581 printf (_("\nIn linked file '%s': "), filedata->file_name);
12582 else
12583 printf ("\n");
12584
0f03783c
NC
12585 if (ext_data_orig != NULL)
12586 {
12587 if (do_wide)
ca0e11aa 12588 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
12589 printable_section_name (filedata, section),
12590 printable_section_name (filedata, ext));
12591 else
12592 {
ca0e11aa 12593 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
12594 printable_section_name (filedata, section));
12595 printf (_(" and extension table '%s' contain:\n"),
12596 printable_section_name (filedata, ext));
12597 }
12598 }
12599 else
ca0e11aa 12600 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 12601 printable_section_name (filedata, section));
b9e920ec 12602
0f03783c 12603 /* FIXME: Add a wide version. */
b9e920ec 12604 if (ext_data_orig != NULL)
0f03783c
NC
12605 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
12606 else
12607 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
12608
12609 /* FIXME: We do not handle style prefixes. */
12610
12611 while (data < end)
12612 {
12613 const unsigned char * sym_name = data;
12614 data += strnlen ((const char *) sym_name, end - data) + 1;
12615 if (data >= end)
12616 goto fail;
12617
12618 const unsigned char * comdat_key = data;
12619 data += strnlen ((const char *) comdat_key, end - data) + 1;
12620 if (data >= end)
12621 goto fail;
12622
12623 if (data + 2 + 8 + 4 > end)
12624 goto fail;
12625
12626 unsigned int kind = *data++;
12627 unsigned int visibility = *data++;
12628
12629 elf_vma size = byte_get (data, 8);
12630 data += 8;
12631
12632 elf_vma slot = byte_get (data, 4);
12633 data += 4;
12634
12635 if (ext_data != NULL)
12636 {
12637 if (ext_data < (ext_data_end - 1))
12638 {
12639 unsigned int sym_type = * ext_data ++;
12640 unsigned int sec_kind = * ext_data ++;
12641
12642 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
12643 * comdat_key == 0 ? "-" : (char *) comdat_key,
12644 get_lto_kind (kind),
12645 get_lto_visibility (visibility),
12646 (long) size,
12647 (long) slot,
12648 get_lto_sym_type (sym_type),
12649 (long) sec_kind);
12650 print_symbol (6, (const char *) sym_name);
12651 }
12652 else
12653 {
12654 error (_("Ran out of LTO symbol extension data\n"));
12655 ext_data = NULL;
12656 /* FIXME: return FAIL result ? */
12657 }
12658 }
12659 else
12660 {
12661 printf (" %10s %10s %11s %08lx %08lx _",
12662 * comdat_key == 0 ? "-" : (char *) comdat_key,
12663 get_lto_kind (kind),
12664 get_lto_visibility (visibility),
12665 (long) size,
12666 (long) slot);
12667 print_symbol (21, (const char *) sym_name);
12668 }
12669 putchar ('\n');
12670 }
12671
12672 if (ext_data != NULL && ext_data < ext_data_end)
12673 {
12674 error (_("Data remains in the LTO symbol extension table\n"));
12675 goto fail;
12676 }
12677
12678 free (alloced_data);
12679 free (ext_data_orig);
12680 free (ext_name);
12681 return TRUE;
b9e920ec 12682
0f03783c
NC
12683 fail:
12684 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
12685 free (alloced_data);
12686 free (ext_data_orig);
12687 free (ext_name);
12688 return FALSE;
12689}
12690
12691/* Display LTO symbol tables. */
12692
12693static bfd_boolean
12694process_lto_symbol_tables (Filedata * filedata)
12695{
12696 Elf_Internal_Shdr * section;
12697 unsigned int i;
12698 bfd_boolean res = TRUE;
12699
12700 if (!do_lto_syms)
12701 return TRUE;
12702
12703 if (filedata->section_headers == NULL)
12704 return TRUE;
12705
12706 for (i = 0, section = filedata->section_headers;
12707 i < filedata->file_header.e_shnum;
12708 i++, section++)
b9e920ec
AM
12709 if (SECTION_NAME_VALID (section)
12710 && CONST_STRNEQ (SECTION_NAME (section), ".gnu.lto_.symtab."))
0f03783c
NC
12711 res &= display_lto_symtab (filedata, section);
12712
b9e920ec 12713 return res;
0f03783c
NC
12714}
12715
10ca4b04 12716/* Dump the symbol table. */
0f03783c 12717
10ca4b04
L
12718static bfd_boolean
12719process_symbol_table (Filedata * filedata)
12720{
12721 Elf_Internal_Shdr * section;
f16a9783 12722
10ca4b04
L
12723 if (!do_syms && !do_dyn_syms && !do_histogram)
12724 return TRUE;
6bd1a22c 12725
978c4450 12726 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
12727 && do_syms
12728 && do_using_dynamic
978c4450
AM
12729 && filedata->dynamic_strings != NULL
12730 && filedata->dynamic_symbols != NULL)
6bd1a22c 12731 {
10ca4b04 12732 unsigned long si;
6bd1a22c 12733
ca0e11aa
NC
12734 if (filedata->is_separate)
12735 {
12736 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
12737 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
12738 filedata->num_dynamic_syms),
12739 filedata->file_name,
12740 filedata->num_dynamic_syms);
12741 }
12742 else
12743 {
12744 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12745 "\nSymbol table for image contains %lu entries:\n",
12746 filedata->num_dynamic_syms),
12747 filedata->num_dynamic_syms);
12748 }
10ca4b04
L
12749 if (is_32bit_elf)
12750 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12751 else
12752 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12753
978c4450
AM
12754 for (si = 0; si < filedata->num_dynamic_syms; si++)
12755 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
12756 filedata->dynamic_strings,
12757 filedata->dynamic_strings_length);
252b5132 12758 }
8b73c356 12759 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 12760 && filedata->section_headers != NULL)
252b5132 12761 {
b34976b6 12762 unsigned int i;
252b5132 12763
dda8d76d
NC
12764 for (i = 0, section = filedata->section_headers;
12765 i < filedata->file_header.e_shnum;
252b5132
RH
12766 i++, section++)
12767 {
2cf0635d 12768 char * strtab = NULL;
c256ffe7 12769 unsigned long int strtab_size = 0;
2cf0635d 12770 Elf_Internal_Sym * symtab;
ef3df110 12771 unsigned long si, num_syms;
252b5132 12772
2c610e4b
L
12773 if ((section->sh_type != SHT_SYMTAB
12774 && section->sh_type != SHT_DYNSYM)
12775 || (!do_syms
12776 && section->sh_type == SHT_SYMTAB))
252b5132
RH
12777 continue;
12778
dd24e3da
NC
12779 if (section->sh_entsize == 0)
12780 {
12781 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 12782 printable_section_name (filedata, section));
dd24e3da
NC
12783 continue;
12784 }
12785
d3a49aa8 12786 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
12787
12788 if (filedata->is_separate)
12789 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
12790 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
12791 num_syms),
12792 filedata->file_name,
12793 printable_section_name (filedata, section),
12794 num_syms);
12795 else
12796 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
12797 "\nSymbol table '%s' contains %lu entries:\n",
12798 num_syms),
12799 printable_section_name (filedata, section),
12800 num_syms);
dd24e3da 12801
f7a99963 12802 if (is_32bit_elf)
ca47b30c 12803 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 12804 else
ca47b30c 12805 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 12806
dda8d76d 12807 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
12808 if (symtab == NULL)
12809 continue;
12810
dda8d76d 12811 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 12812 {
dda8d76d
NC
12813 strtab = filedata->string_table;
12814 strtab_size = filedata->string_table_length;
c256ffe7 12815 }
dda8d76d 12816 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 12817 {
2cf0635d 12818 Elf_Internal_Shdr * string_sec;
252b5132 12819
dda8d76d 12820 string_sec = filedata->section_headers + section->sh_link;
252b5132 12821
dda8d76d 12822 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
12823 1, string_sec->sh_size,
12824 _("string table"));
c256ffe7 12825 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
12826 }
12827
10ca4b04
L
12828 for (si = 0; si < num_syms; si++)
12829 print_dynamic_symbol (filedata, si, symtab, section,
12830 strtab, strtab_size);
252b5132
RH
12831
12832 free (symtab);
dda8d76d 12833 if (strtab != filedata->string_table)
252b5132
RH
12834 free (strtab);
12835 }
12836 }
12837 else if (do_syms)
12838 printf
12839 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
12840
978c4450 12841 if (do_histogram && filedata->buckets != NULL)
252b5132 12842 {
2cf0635d
NC
12843 unsigned long * lengths;
12844 unsigned long * counts;
66543521
AM
12845 unsigned long hn;
12846 bfd_vma si;
12847 unsigned long maxlength = 0;
12848 unsigned long nzero_counts = 0;
12849 unsigned long nsyms = 0;
6bd6a03d 12850 char *visited;
252b5132 12851
d3a49aa8
AM
12852 printf (ngettext ("\nHistogram for bucket list length "
12853 "(total of %lu bucket):\n",
12854 "\nHistogram for bucket list length "
12855 "(total of %lu buckets):\n",
978c4450
AM
12856 (unsigned long) filedata->nbuckets),
12857 (unsigned long) filedata->nbuckets);
252b5132 12858
978c4450
AM
12859 lengths = (unsigned long *) calloc (filedata->nbuckets,
12860 sizeof (*lengths));
252b5132
RH
12861 if (lengths == NULL)
12862 {
8b73c356 12863 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 12864 goto err_out;
252b5132 12865 }
978c4450
AM
12866 visited = xcmalloc (filedata->nchains, 1);
12867 memset (visited, 0, filedata->nchains);
8b73c356
NC
12868
12869 printf (_(" Length Number %% of total Coverage\n"));
978c4450 12870 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 12871 {
978c4450 12872 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 12873 {
b34976b6 12874 ++nsyms;
252b5132 12875 if (maxlength < ++lengths[hn])
b34976b6 12876 ++maxlength;
978c4450 12877 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
12878 {
12879 error (_("histogram chain is corrupt\n"));
12880 break;
12881 }
12882 visited[si] = 1;
252b5132
RH
12883 }
12884 }
6bd6a03d 12885 free (visited);
252b5132 12886
3f5e193b 12887 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
12888 if (counts == NULL)
12889 {
b2e951ec 12890 free (lengths);
8b73c356 12891 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 12892 goto err_out;
252b5132
RH
12893 }
12894
978c4450 12895 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 12896 ++counts[lengths[hn]];
252b5132 12897
978c4450 12898 if (filedata->nbuckets > 0)
252b5132 12899 {
66543521
AM
12900 unsigned long i;
12901 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12902 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 12903 for (i = 1; i <= maxlength; ++i)
103f02d3 12904 {
66543521
AM
12905 nzero_counts += counts[i] * i;
12906 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12907 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
12908 (nzero_counts * 100.0) / nsyms);
12909 }
252b5132
RH
12910 }
12911
12912 free (counts);
12913 free (lengths);
12914 }
12915
978c4450
AM
12916 free (filedata->buckets);
12917 filedata->buckets = NULL;
12918 filedata->nbuckets = 0;
12919 free (filedata->chains);
12920 filedata->chains = NULL;
252b5132 12921
978c4450 12922 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 12923 {
2cf0635d
NC
12924 unsigned long * lengths;
12925 unsigned long * counts;
fdc90cb4
JJ
12926 unsigned long hn;
12927 unsigned long maxlength = 0;
12928 unsigned long nzero_counts = 0;
12929 unsigned long nsyms = 0;
fdc90cb4 12930
f16a9783 12931 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 12932 "(total of %lu bucket):\n",
f16a9783 12933 "\nHistogram for `%s' bucket list length "
d3a49aa8 12934 "(total of %lu buckets):\n",
978c4450
AM
12935 (unsigned long) filedata->ngnubuckets),
12936 GNU_HASH_SECTION_NAME (filedata),
12937 (unsigned long) filedata->ngnubuckets);
8b73c356 12938
978c4450
AM
12939 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
12940 sizeof (*lengths));
fdc90cb4
JJ
12941 if (lengths == NULL)
12942 {
8b73c356 12943 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 12944 goto err_out;
fdc90cb4
JJ
12945 }
12946
fdc90cb4
JJ
12947 printf (_(" Length Number %% of total Coverage\n"));
12948
978c4450
AM
12949 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
12950 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
12951 {
12952 bfd_vma off, length = 1;
12953
978c4450 12954 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 12955 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
12956 off < filedata->ngnuchains
12957 && (filedata->gnuchains[off] & 1) == 0;
071436c6 12958 ++off)
fdc90cb4
JJ
12959 ++length;
12960 lengths[hn] = length;
12961 if (length > maxlength)
12962 maxlength = length;
12963 nsyms += length;
12964 }
12965
3f5e193b 12966 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
12967 if (counts == NULL)
12968 {
b2e951ec 12969 free (lengths);
8b73c356 12970 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 12971 goto err_out;
fdc90cb4
JJ
12972 }
12973
978c4450 12974 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
12975 ++counts[lengths[hn]];
12976
978c4450 12977 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
12978 {
12979 unsigned long j;
12980 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12981 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
12982 for (j = 1; j <= maxlength; ++j)
12983 {
12984 nzero_counts += counts[j] * j;
12985 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12986 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
12987 (nzero_counts * 100.0) / nsyms);
12988 }
12989 }
12990
12991 free (counts);
12992 free (lengths);
fdc90cb4 12993 }
978c4450
AM
12994 free (filedata->gnubuckets);
12995 filedata->gnubuckets = NULL;
12996 filedata->ngnubuckets = 0;
12997 free (filedata->gnuchains);
12998 filedata->gnuchains = NULL;
12999 filedata->ngnuchains = 0;
13000 free (filedata->mipsxlat);
13001 filedata->mipsxlat = NULL;
32ec8896 13002 return TRUE;
fd486f32
AM
13003
13004 err_out:
978c4450
AM
13005 free (filedata->gnubuckets);
13006 filedata->gnubuckets = NULL;
13007 filedata->ngnubuckets = 0;
13008 free (filedata->gnuchains);
13009 filedata->gnuchains = NULL;
13010 filedata->ngnuchains = 0;
13011 free (filedata->mipsxlat);
13012 filedata->mipsxlat = NULL;
13013 free (filedata->buckets);
13014 filedata->buckets = NULL;
13015 filedata->nbuckets = 0;
13016 free (filedata->chains);
13017 filedata->chains = NULL;
fd486f32 13018 return FALSE;
252b5132
RH
13019}
13020
32ec8896 13021static bfd_boolean
ca0e11aa 13022process_syminfo (Filedata * filedata)
252b5132 13023{
b4c96d0d 13024 unsigned int i;
252b5132 13025
978c4450 13026 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13027 || !do_dynamic)
13028 /* No syminfo, this is ok. */
32ec8896 13029 return TRUE;
252b5132
RH
13030
13031 /* There better should be a dynamic symbol section. */
978c4450 13032 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
32ec8896 13033 return FALSE;
252b5132 13034
ca0e11aa
NC
13035 if (filedata->is_separate)
13036 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13037 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13038 filedata->dynamic_syminfo_nent),
13039 filedata->file_name,
13040 filedata->dynamic_syminfo_offset,
13041 filedata->dynamic_syminfo_nent);
13042 else
d3a49aa8
AM
13043 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13044 "contains %d entry:\n",
13045 "\nDynamic info segment at offset 0x%lx "
13046 "contains %d entries:\n",
978c4450 13047 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13048 filedata->dynamic_syminfo_offset,
13049 filedata->dynamic_syminfo_nent);
252b5132
RH
13050
13051 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13052 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13053 {
978c4450 13054 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13055
31104126 13056 printf ("%4d: ", i);
978c4450 13057 if (i >= filedata->num_dynamic_syms)
4082ef84 13058 printf (_("<corrupt index>"));
978c4450
AM
13059 else if (VALID_DYNAMIC_NAME (filedata, filedata->dynamic_symbols[i].st_name))
13060 print_symbol (30, GET_DYNAMIC_NAME (filedata,
13061 filedata->dynamic_symbols[i].st_name));
d79b3d50 13062 else
978c4450 13063 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13064 putchar (' ');
252b5132 13065
978c4450 13066 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13067 {
13068 case SYMINFO_BT_SELF:
13069 fputs ("SELF ", stdout);
13070 break;
13071 case SYMINFO_BT_PARENT:
13072 fputs ("PARENT ", stdout);
13073 break;
13074 default:
978c4450
AM
13075 if (filedata->dynamic_syminfo[i].si_boundto > 0
13076 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
13077 && VALID_DYNAMIC_NAME (filedata,
13078 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13079 {
978c4450
AM
13080 print_symbol (10, GET_DYNAMIC_NAME (filedata,
13081 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13082 putchar (' ' );
13083 }
252b5132 13084 else
978c4450 13085 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13086 break;
13087 }
13088
13089 if (flags & SYMINFO_FLG_DIRECT)
13090 printf (" DIRECT");
13091 if (flags & SYMINFO_FLG_PASSTHRU)
13092 printf (" PASSTHRU");
13093 if (flags & SYMINFO_FLG_COPY)
13094 printf (" COPY");
13095 if (flags & SYMINFO_FLG_LAZYLOAD)
13096 printf (" LAZYLOAD");
13097
13098 puts ("");
13099 }
13100
32ec8896 13101 return TRUE;
252b5132
RH
13102}
13103
75802ccb
CE
13104/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13105 is contained by the region START .. END. The types of ADDR, START
13106 and END should all be the same. Note both ADDR + NELEM and END
13107 point to just beyond the end of the regions that are being tested. */
13108#define IN_RANGE(START,END,ADDR,NELEM) \
13109 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13110
cf13d699
NC
13111/* Check to see if the given reloc needs to be handled in a target specific
13112 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13113 FALSE.
13114
13115 If called with reloc == NULL, then this is a signal that reloc processing
13116 for the current section has finished, and any saved state should be
13117 discarded. */
09c11c86 13118
cf13d699 13119static bfd_boolean
dda8d76d
NC
13120target_specific_reloc_handling (Filedata * filedata,
13121 Elf_Internal_Rela * reloc,
13122 unsigned char * start,
13123 unsigned char * end,
13124 Elf_Internal_Sym * symtab,
13125 unsigned long num_syms)
252b5132 13126{
f84ce13b
NC
13127 unsigned int reloc_type = 0;
13128 unsigned long sym_index = 0;
13129
13130 if (reloc)
13131 {
dda8d76d 13132 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13133 sym_index = get_reloc_symindex (reloc->r_info);
13134 }
252b5132 13135
dda8d76d 13136 switch (filedata->file_header.e_machine)
252b5132 13137 {
13761a11
NC
13138 case EM_MSP430:
13139 case EM_MSP430_OLD:
13140 {
13141 static Elf_Internal_Sym * saved_sym = NULL;
13142
f84ce13b
NC
13143 if (reloc == NULL)
13144 {
13145 saved_sym = NULL;
13146 return TRUE;
13147 }
13148
13761a11
NC
13149 switch (reloc_type)
13150 {
13151 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13152 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13153 if (uses_msp430x_relocs (filedata))
13761a11 13154 break;
1a0670f3 13155 /* Fall through. */
13761a11 13156 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13157 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13158 /* PR 21139. */
13159 if (sym_index >= num_syms)
13160 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13161 sym_index);
13162 else
13163 saved_sym = symtab + sym_index;
13761a11
NC
13164 return TRUE;
13165
13166 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13167 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13168 goto handle_sym_diff;
0b4362b0 13169
13761a11
NC
13170 case 5: /* R_MSP430_16_BYTE */
13171 case 9: /* R_MSP430_8 */
7d81bc93 13172 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13173 if (uses_msp430x_relocs (filedata))
13761a11
NC
13174 break;
13175 goto handle_sym_diff;
13176
13177 case 2: /* R_MSP430_ABS16 */
13178 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13179 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13180 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13181 break;
13182 goto handle_sym_diff;
0b4362b0 13183
13761a11
NC
13184 handle_sym_diff:
13185 if (saved_sym != NULL)
13186 {
13187 bfd_vma value;
5a805384 13188 unsigned int reloc_size = 0;
7d81bc93
JL
13189 int leb_ret = 0;
13190 switch (reloc_type)
13191 {
13192 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13193 reloc_size = 4;
13194 break;
13195 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13196 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384
AM
13197 if (reloc->r_offset < (size_t) (end - start))
13198 read_leb128 (start + reloc->r_offset, end, FALSE,
13199 &reloc_size, &leb_ret);
7d81bc93
JL
13200 break;
13201 default:
13202 reloc_size = 2;
13203 break;
13204 }
13761a11 13205
5a805384 13206 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13207 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13208 "ULEB128 value\n"),
13209 (long) reloc->r_offset);
13210 else if (sym_index >= num_syms)
f84ce13b
NC
13211 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13212 sym_index);
03f7786e 13213 else
f84ce13b
NC
13214 {
13215 value = reloc->r_addend + (symtab[sym_index].st_value
13216 - saved_sym->st_value);
13217
b32e566b 13218 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13219 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13220 else
13221 /* PR 21137 */
13222 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13223 (long) reloc->r_offset);
f84ce13b 13224 }
13761a11
NC
13225
13226 saved_sym = NULL;
13227 return TRUE;
13228 }
13229 break;
13230
13231 default:
13232 if (saved_sym != NULL)
071436c6 13233 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
13234 break;
13235 }
13236 break;
13237 }
13238
cf13d699
NC
13239 case EM_MN10300:
13240 case EM_CYGNUS_MN10300:
13241 {
13242 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 13243
f84ce13b
NC
13244 if (reloc == NULL)
13245 {
13246 saved_sym = NULL;
13247 return TRUE;
13248 }
13249
cf13d699
NC
13250 switch (reloc_type)
13251 {
13252 case 34: /* R_MN10300_ALIGN */
13253 return TRUE;
13254 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
13255 if (sym_index >= num_syms)
13256 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
13257 sym_index);
13258 else
13259 saved_sym = symtab + sym_index;
cf13d699 13260 return TRUE;
f84ce13b 13261
cf13d699
NC
13262 case 1: /* R_MN10300_32 */
13263 case 2: /* R_MN10300_16 */
13264 if (saved_sym != NULL)
13265 {
03f7786e 13266 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 13267 bfd_vma value;
252b5132 13268
f84ce13b
NC
13269 if (sym_index >= num_syms)
13270 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
13271 sym_index);
03f7786e 13272 else
f84ce13b
NC
13273 {
13274 value = reloc->r_addend + (symtab[sym_index].st_value
13275 - saved_sym->st_value);
13276
b32e566b 13277 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13278 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13279 else
13280 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
13281 (long) reloc->r_offset);
f84ce13b 13282 }
252b5132 13283
cf13d699
NC
13284 saved_sym = NULL;
13285 return TRUE;
13286 }
13287 break;
13288 default:
13289 if (saved_sym != NULL)
071436c6 13290 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
13291 break;
13292 }
13293 break;
13294 }
6ff71e76
NC
13295
13296 case EM_RL78:
13297 {
13298 static bfd_vma saved_sym1 = 0;
13299 static bfd_vma saved_sym2 = 0;
13300 static bfd_vma value;
13301
f84ce13b
NC
13302 if (reloc == NULL)
13303 {
13304 saved_sym1 = saved_sym2 = 0;
13305 return TRUE;
13306 }
13307
6ff71e76
NC
13308 switch (reloc_type)
13309 {
13310 case 0x80: /* R_RL78_SYM. */
13311 saved_sym1 = saved_sym2;
f84ce13b
NC
13312 if (sym_index >= num_syms)
13313 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
13314 sym_index);
13315 else
13316 {
13317 saved_sym2 = symtab[sym_index].st_value;
13318 saved_sym2 += reloc->r_addend;
13319 }
6ff71e76
NC
13320 return TRUE;
13321
13322 case 0x83: /* R_RL78_OPsub. */
13323 value = saved_sym1 - saved_sym2;
13324 saved_sym2 = saved_sym1 = 0;
13325 return TRUE;
13326 break;
13327
13328 case 0x41: /* R_RL78_ABS32. */
b32e566b 13329 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 13330 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
13331 else
13332 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13333 (long) reloc->r_offset);
6ff71e76
NC
13334 value = 0;
13335 return TRUE;
13336
13337 case 0x43: /* R_RL78_ABS16. */
b32e566b 13338 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 13339 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
13340 else
13341 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13342 (long) reloc->r_offset);
6ff71e76
NC
13343 value = 0;
13344 return TRUE;
13345
13346 default:
13347 break;
13348 }
13349 break;
13350 }
252b5132
RH
13351 }
13352
cf13d699 13353 return FALSE;
252b5132
RH
13354}
13355
aca88567
NC
13356/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
13357 DWARF debug sections. This is a target specific test. Note - we do not
13358 go through the whole including-target-headers-multiple-times route, (as
13359 we have already done with <elf/h8.h>) because this would become very
13360 messy and even then this function would have to contain target specific
13361 information (the names of the relocs instead of their numeric values).
13362 FIXME: This is not the correct way to solve this problem. The proper way
13363 is to have target specific reloc sizing and typing functions created by
13364 the reloc-macros.h header, in the same way that it already creates the
13365 reloc naming functions. */
13366
13367static bfd_boolean
dda8d76d 13368is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13369{
d347c9df 13370 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13371 switch (filedata->file_header.e_machine)
aca88567 13372 {
41e92641 13373 case EM_386:
22abe556 13374 case EM_IAMCU:
41e92641 13375 return reloc_type == 1; /* R_386_32. */
aca88567
NC
13376 case EM_68K:
13377 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
13378 case EM_860:
13379 return reloc_type == 1; /* R_860_32. */
13380 case EM_960:
13381 return reloc_type == 2; /* R_960_32. */
a06ea964 13382 case EM_AARCH64:
9282b95a
JW
13383 return (reloc_type == 258
13384 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
13385 case EM_BPF:
13386 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
13387 case EM_ADAPTEVA_EPIPHANY:
13388 return reloc_type == 3;
aca88567 13389 case EM_ALPHA:
137b6b5f 13390 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
13391 case EM_ARC:
13392 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
13393 case EM_ARC_COMPACT:
13394 case EM_ARC_COMPACT2:
13395 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
13396 case EM_ARM:
13397 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 13398 case EM_AVR_OLD:
aca88567
NC
13399 case EM_AVR:
13400 return reloc_type == 1;
13401 case EM_BLACKFIN:
13402 return reloc_type == 0x12; /* R_byte4_data. */
13403 case EM_CRIS:
13404 return reloc_type == 3; /* R_CRIS_32. */
13405 case EM_CR16:
13406 return reloc_type == 3; /* R_CR16_NUM32. */
13407 case EM_CRX:
13408 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
13409 case EM_CSKY:
13410 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
13411 case EM_CYGNUS_FRV:
13412 return reloc_type == 1;
41e92641
NC
13413 case EM_CYGNUS_D10V:
13414 case EM_D10V:
13415 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
13416 case EM_CYGNUS_D30V:
13417 case EM_D30V:
13418 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
13419 case EM_DLX:
13420 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
13421 case EM_CYGNUS_FR30:
13422 case EM_FR30:
13423 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
13424 case EM_FT32:
13425 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
13426 case EM_H8S:
13427 case EM_H8_300:
13428 case EM_H8_300H:
13429 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 13430 case EM_IA_64:
262cdac7
AM
13431 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
13432 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
13433 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
13434 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
13435 case EM_IP2K_OLD:
13436 case EM_IP2K:
13437 return reloc_type == 2; /* R_IP2K_32. */
13438 case EM_IQ2000:
13439 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
13440 case EM_LATTICEMICO32:
13441 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 13442 case EM_M32C_OLD:
aca88567
NC
13443 case EM_M32C:
13444 return reloc_type == 3; /* R_M32C_32. */
13445 case EM_M32R:
13446 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
13447 case EM_68HC11:
13448 case EM_68HC12:
13449 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 13450 case EM_S12Z:
2849d19f
JD
13451 return reloc_type == 7 || /* R_S12Z_EXT32 */
13452 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
13453 case EM_MCORE:
13454 return reloc_type == 1; /* R_MCORE_ADDR32. */
13455 case EM_CYGNUS_MEP:
13456 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
13457 case EM_METAG:
13458 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
13459 case EM_MICROBLAZE:
13460 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
13461 case EM_MIPS:
13462 return reloc_type == 2; /* R_MIPS_32. */
13463 case EM_MMIX:
13464 return reloc_type == 4; /* R_MMIX_32. */
13465 case EM_CYGNUS_MN10200:
13466 case EM_MN10200:
13467 return reloc_type == 1; /* R_MN10200_32. */
13468 case EM_CYGNUS_MN10300:
13469 case EM_MN10300:
13470 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
13471 case EM_MOXIE:
13472 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
13473 case EM_MSP430_OLD:
13474 case EM_MSP430:
13761a11 13475 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
13476 case EM_MT:
13477 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
13478 case EM_NDS32:
13479 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 13480 case EM_ALTERA_NIOS2:
36591ba1 13481 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
13482 case EM_NIOS32:
13483 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
13484 case EM_OR1K:
13485 return reloc_type == 1; /* R_OR1K_32. */
aca88567 13486 case EM_PARISC:
9abca702 13487 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 13488 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 13489 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
13490 case EM_PJ:
13491 case EM_PJ_OLD:
13492 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
13493 case EM_PPC64:
13494 return reloc_type == 1; /* R_PPC64_ADDR32. */
13495 case EM_PPC:
13496 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
13497 case EM_TI_PRU:
13498 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
13499 case EM_RISCV:
13500 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
13501 case EM_RL78:
13502 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
13503 case EM_RX:
13504 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
13505 case EM_S370:
13506 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
13507 case EM_S390_OLD:
13508 case EM_S390:
13509 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
13510 case EM_SCORE:
13511 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
13512 case EM_SH:
13513 return reloc_type == 1; /* R_SH_DIR32. */
13514 case EM_SPARC32PLUS:
13515 case EM_SPARCV9:
13516 case EM_SPARC:
13517 return reloc_type == 3 /* R_SPARC_32. */
13518 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
13519 case EM_SPU:
13520 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
13521 case EM_TI_C6000:
13522 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
13523 case EM_TILEGX:
13524 return reloc_type == 2; /* R_TILEGX_32. */
13525 case EM_TILEPRO:
13526 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
13527 case EM_CYGNUS_V850:
13528 case EM_V850:
13529 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
13530 case EM_V800:
13531 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
13532 case EM_VAX:
13533 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
13534 case EM_VISIUM:
13535 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
13536 case EM_WEBASSEMBLY:
13537 return reloc_type == 1; /* R_WASM32_32. */
aca88567 13538 case EM_X86_64:
8a9036a4 13539 case EM_L1OM:
7a9068fe 13540 case EM_K1OM:
aca88567 13541 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
13542 case EM_XC16X:
13543 case EM_C166:
13544 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
13545 case EM_XGATE:
13546 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
13547 case EM_XSTORMY16:
13548 return reloc_type == 1; /* R_XSTROMY16_32. */
13549 case EM_XTENSA_OLD:
13550 case EM_XTENSA:
13551 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
13552 case EM_Z80:
13553 return reloc_type == 6; /* R_Z80_32. */
aca88567 13554 default:
bee0ee85
NC
13555 {
13556 static unsigned int prev_warn = 0;
13557
13558 /* Avoid repeating the same warning multiple times. */
dda8d76d 13559 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 13560 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
13561 filedata->file_header.e_machine);
13562 prev_warn = filedata->file_header.e_machine;
bee0ee85
NC
13563 return FALSE;
13564 }
aca88567
NC
13565 }
13566}
13567
13568/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13569 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
13570
13571static bfd_boolean
dda8d76d 13572is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13573{
dda8d76d 13574 switch (filedata->file_header.e_machine)
d347c9df 13575 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 13576 {
41e92641 13577 case EM_386:
22abe556 13578 case EM_IAMCU:
3e0873ac 13579 return reloc_type == 2; /* R_386_PC32. */
aca88567 13580 case EM_68K:
3e0873ac 13581 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
13582 case EM_AARCH64:
13583 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
13584 case EM_ADAPTEVA_EPIPHANY:
13585 return reloc_type == 6;
aca88567
NC
13586 case EM_ALPHA:
13587 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
13588 case EM_ARC_COMPACT:
13589 case EM_ARC_COMPACT2:
13590 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 13591 case EM_ARM:
3e0873ac 13592 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
13593 case EM_AVR_OLD:
13594 case EM_AVR:
13595 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
13596 case EM_MICROBLAZE:
13597 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
13598 case EM_OR1K:
13599 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 13600 case EM_PARISC:
85acf597 13601 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
13602 case EM_PPC:
13603 return reloc_type == 26; /* R_PPC_REL32. */
13604 case EM_PPC64:
3e0873ac 13605 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
13606 case EM_RISCV:
13607 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
13608 case EM_S390_OLD:
13609 case EM_S390:
3e0873ac 13610 return reloc_type == 5; /* R_390_PC32. */
aca88567 13611 case EM_SH:
3e0873ac 13612 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
13613 case EM_SPARC32PLUS:
13614 case EM_SPARCV9:
13615 case EM_SPARC:
3e0873ac 13616 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
13617 case EM_SPU:
13618 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
13619 case EM_TILEGX:
13620 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
13621 case EM_TILEPRO:
13622 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
13623 case EM_VISIUM:
13624 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 13625 case EM_X86_64:
8a9036a4 13626 case EM_L1OM:
7a9068fe 13627 case EM_K1OM:
3e0873ac 13628 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
13629 case EM_VAX:
13630 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
13631 case EM_XTENSA_OLD:
13632 case EM_XTENSA:
13633 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
13634 default:
13635 /* Do not abort or issue an error message here. Not all targets use
13636 pc-relative 32-bit relocs in their DWARF debug information and we
13637 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
13638 more helpful warning message will be generated by apply_relocations
13639 anyway, so just return. */
aca88567
NC
13640 return FALSE;
13641 }
13642}
13643
13644/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13645 a 64-bit absolute RELA relocation used in DWARF debug sections. */
13646
13647static bfd_boolean
dda8d76d 13648is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13649{
dda8d76d 13650 switch (filedata->file_header.e_machine)
aca88567 13651 {
a06ea964
NC
13652 case EM_AARCH64:
13653 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
13654 case EM_ALPHA:
13655 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 13656 case EM_IA_64:
262cdac7
AM
13657 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
13658 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
13659 case EM_PARISC:
13660 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
13661 case EM_PPC64:
13662 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
13663 case EM_RISCV:
13664 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
13665 case EM_SPARC32PLUS:
13666 case EM_SPARCV9:
13667 case EM_SPARC:
714da62f
NC
13668 return reloc_type == 32 /* R_SPARC_64. */
13669 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 13670 case EM_X86_64:
8a9036a4 13671 case EM_L1OM:
7a9068fe 13672 case EM_K1OM:
aca88567 13673 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
13674 case EM_S390_OLD:
13675 case EM_S390:
aa137e4d
NC
13676 return reloc_type == 22; /* R_S390_64. */
13677 case EM_TILEGX:
13678 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 13679 case EM_MIPS:
aa137e4d 13680 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
13681 default:
13682 return FALSE;
13683 }
13684}
13685
85acf597
RH
13686/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
13687 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
13688
13689static bfd_boolean
dda8d76d 13690is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 13691{
dda8d76d 13692 switch (filedata->file_header.e_machine)
85acf597 13693 {
a06ea964
NC
13694 case EM_AARCH64:
13695 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 13696 case EM_ALPHA:
aa137e4d 13697 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 13698 case EM_IA_64:
262cdac7
AM
13699 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
13700 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 13701 case EM_PARISC:
aa137e4d 13702 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 13703 case EM_PPC64:
aa137e4d 13704 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
13705 case EM_SPARC32PLUS:
13706 case EM_SPARCV9:
13707 case EM_SPARC:
aa137e4d 13708 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 13709 case EM_X86_64:
8a9036a4 13710 case EM_L1OM:
7a9068fe 13711 case EM_K1OM:
aa137e4d 13712 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
13713 case EM_S390_OLD:
13714 case EM_S390:
aa137e4d
NC
13715 return reloc_type == 23; /* R_S390_PC64. */
13716 case EM_TILEGX:
13717 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
13718 default:
13719 return FALSE;
13720 }
13721}
13722
4dc3c23d
AM
13723/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13724 a 24-bit absolute RELA relocation used in DWARF debug sections. */
13725
13726static bfd_boolean
dda8d76d 13727is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 13728{
dda8d76d 13729 switch (filedata->file_header.e_machine)
4dc3c23d
AM
13730 {
13731 case EM_CYGNUS_MN10200:
13732 case EM_MN10200:
13733 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
13734 case EM_FT32:
13735 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
13736 case EM_Z80:
13737 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d
AM
13738 default:
13739 return FALSE;
13740 }
13741}
13742
aca88567
NC
13743/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13744 a 16-bit absolute RELA relocation used in DWARF debug sections. */
13745
13746static bfd_boolean
dda8d76d 13747is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 13748{
d347c9df 13749 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13750 switch (filedata->file_header.e_machine)
4b78141a 13751 {
886a2506
NC
13752 case EM_ARC:
13753 case EM_ARC_COMPACT:
13754 case EM_ARC_COMPACT2:
13755 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
13756 case EM_ADAPTEVA_EPIPHANY:
13757 return reloc_type == 5;
aca88567
NC
13758 case EM_AVR_OLD:
13759 case EM_AVR:
13760 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
13761 case EM_CYGNUS_D10V:
13762 case EM_D10V:
13763 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
13764 case EM_FT32:
13765 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
13766 case EM_H8S:
13767 case EM_H8_300:
13768 case EM_H8_300H:
aca88567
NC
13769 return reloc_type == R_H8_DIR16;
13770 case EM_IP2K_OLD:
13771 case EM_IP2K:
13772 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 13773 case EM_M32C_OLD:
f4236fe4
DD
13774 case EM_M32C:
13775 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
13776 case EM_CYGNUS_MN10200:
13777 case EM_MN10200:
13778 return reloc_type == 2; /* R_MN10200_16. */
13779 case EM_CYGNUS_MN10300:
13780 case EM_MN10300:
13781 return reloc_type == 2; /* R_MN10300_16. */
aca88567 13782 case EM_MSP430:
dda8d76d 13783 if (uses_msp430x_relocs (filedata))
13761a11 13784 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 13785 /* Fall through. */
78c8d46c 13786 case EM_MSP430_OLD:
aca88567 13787 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
13788 case EM_NDS32:
13789 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 13790 case EM_ALTERA_NIOS2:
36591ba1 13791 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
13792 case EM_NIOS32:
13793 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
13794 case EM_OR1K:
13795 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
13796 case EM_RISCV:
13797 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
13798 case EM_TI_PRU:
13799 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
13800 case EM_TI_C6000:
13801 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
13802 case EM_VISIUM:
13803 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
13804 case EM_XC16X:
13805 case EM_C166:
13806 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
13807 case EM_XGATE:
13808 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
13809 case EM_Z80:
13810 return reloc_type == 4; /* R_Z80_16. */
4b78141a 13811 default:
aca88567 13812 return FALSE;
4b78141a
NC
13813 }
13814}
13815
39e07931
AS
13816/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13817 a 8-bit absolute RELA relocation used in DWARF debug sections. */
13818
13819static bfd_boolean
13820is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13821{
13822 switch (filedata->file_header.e_machine)
13823 {
13824 case EM_RISCV:
13825 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
13826 case EM_Z80:
13827 return reloc_type == 1; /* R_Z80_8. */
39e07931
AS
13828 default:
13829 return FALSE;
13830 }
13831}
13832
13833/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13834 a 6-bit absolute RELA relocation used in DWARF debug sections. */
13835
13836static bfd_boolean
13837is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13838{
13839 switch (filedata->file_header.e_machine)
13840 {
13841 case EM_RISCV:
13842 return reloc_type == 53; /* R_RISCV_SET6. */
13843 default:
13844 return FALSE;
13845 }
13846}
13847
03336641
JW
13848/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13849 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
13850
13851static bfd_boolean
13852is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13853{
13854 /* Please keep this table alpha-sorted for ease of visual lookup. */
13855 switch (filedata->file_header.e_machine)
13856 {
13857 case EM_RISCV:
13858 return reloc_type == 35; /* R_RISCV_ADD32. */
13859 default:
13860 return FALSE;
13861 }
13862}
13863
13864/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13865 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
13866
13867static bfd_boolean
13868is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13869{
13870 /* Please keep this table alpha-sorted for ease of visual lookup. */
13871 switch (filedata->file_header.e_machine)
13872 {
13873 case EM_RISCV:
13874 return reloc_type == 39; /* R_RISCV_SUB32. */
13875 default:
13876 return FALSE;
13877 }
13878}
13879
13880/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13881 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
13882
13883static bfd_boolean
13884is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13885{
13886 /* Please keep this table alpha-sorted for ease of visual lookup. */
13887 switch (filedata->file_header.e_machine)
13888 {
13889 case EM_RISCV:
13890 return reloc_type == 36; /* R_RISCV_ADD64. */
13891 default:
13892 return FALSE;
13893 }
13894}
13895
13896/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13897 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
13898
13899static bfd_boolean
13900is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13901{
13902 /* Please keep this table alpha-sorted for ease of visual lookup. */
13903 switch (filedata->file_header.e_machine)
13904 {
13905 case EM_RISCV:
13906 return reloc_type == 40; /* R_RISCV_SUB64. */
13907 default:
13908 return FALSE;
13909 }
13910}
13911
13912/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13913 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
13914
13915static bfd_boolean
13916is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13917{
13918 /* Please keep this table alpha-sorted for ease of visual lookup. */
13919 switch (filedata->file_header.e_machine)
13920 {
13921 case EM_RISCV:
13922 return reloc_type == 34; /* R_RISCV_ADD16. */
13923 default:
13924 return FALSE;
13925 }
13926}
13927
13928/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13929 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
13930
13931static bfd_boolean
13932is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13933{
13934 /* Please keep this table alpha-sorted for ease of visual lookup. */
13935 switch (filedata->file_header.e_machine)
13936 {
13937 case EM_RISCV:
13938 return reloc_type == 38; /* R_RISCV_SUB16. */
13939 default:
13940 return FALSE;
13941 }
13942}
13943
13944/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13945 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
13946
13947static bfd_boolean
13948is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13949{
13950 /* Please keep this table alpha-sorted for ease of visual lookup. */
13951 switch (filedata->file_header.e_machine)
13952 {
13953 case EM_RISCV:
13954 return reloc_type == 33; /* R_RISCV_ADD8. */
13955 default:
13956 return FALSE;
13957 }
13958}
13959
13960/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13961 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
13962
13963static bfd_boolean
13964is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13965{
13966 /* Please keep this table alpha-sorted for ease of visual lookup. */
13967 switch (filedata->file_header.e_machine)
13968 {
13969 case EM_RISCV:
13970 return reloc_type == 37; /* R_RISCV_SUB8. */
13971 default:
13972 return FALSE;
13973 }
13974}
13975
39e07931
AS
13976/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13977 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
13978
13979static bfd_boolean
13980is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13981{
13982 switch (filedata->file_header.e_machine)
13983 {
13984 case EM_RISCV:
13985 return reloc_type == 52; /* R_RISCV_SUB6. */
13986 default:
13987 return FALSE;
13988 }
13989}
13990
2a7b2e88
JK
13991/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
13992 relocation entries (possibly formerly used for SHT_GROUP sections). */
13993
13994static bfd_boolean
dda8d76d 13995is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 13996{
dda8d76d 13997 switch (filedata->file_header.e_machine)
2a7b2e88 13998 {
cb8f3167 13999 case EM_386: /* R_386_NONE. */
d347c9df 14000 case EM_68K: /* R_68K_NONE. */
cfb8c092 14001 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14002 case EM_ALPHA: /* R_ALPHA_NONE. */
14003 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14004 case EM_ARC: /* R_ARC_NONE. */
886a2506 14005 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14006 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14007 case EM_ARM: /* R_ARM_NONE. */
d347c9df 14008 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 14009 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14010 case EM_FT32: /* R_FT32_NONE. */
14011 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14012 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14013 case EM_L1OM: /* R_X86_64_NONE. */
14014 case EM_M32R: /* R_M32R_NONE. */
14015 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14016 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14017 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14018 case EM_NIOS32: /* R_NIOS_NONE. */
14019 case EM_OR1K: /* R_OR1K_NONE. */
14020 case EM_PARISC: /* R_PARISC_NONE. */
14021 case EM_PPC64: /* R_PPC64_NONE. */
14022 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14023 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14024 case EM_S390: /* R_390_NONE. */
14025 case EM_S390_OLD:
14026 case EM_SH: /* R_SH_NONE. */
14027 case EM_SPARC32PLUS:
14028 case EM_SPARC: /* R_SPARC_NONE. */
14029 case EM_SPARCV9:
aa137e4d
NC
14030 case EM_TILEGX: /* R_TILEGX_NONE. */
14031 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14032 case EM_TI_C6000:/* R_C6000_NONE. */
14033 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 14034 case EM_XC16X:
6655dba2 14035 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14036 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14037 return reloc_type == 0;
d347c9df 14038
a06ea964
NC
14039 case EM_AARCH64:
14040 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14041 case EM_AVR_OLD:
14042 case EM_AVR:
14043 return (reloc_type == 0 /* R_AVR_NONE. */
14044 || reloc_type == 30 /* R_AVR_DIFF8. */
14045 || reloc_type == 31 /* R_AVR_DIFF16. */
14046 || reloc_type == 32 /* R_AVR_DIFF32. */);
14047 case EM_METAG:
14048 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
14049 case EM_NDS32:
14050 return (reloc_type == 0 /* R_XTENSA_NONE. */
14051 || reloc_type == 204 /* R_NDS32_DIFF8. */
14052 || reloc_type == 205 /* R_NDS32_DIFF16. */
14053 || reloc_type == 206 /* R_NDS32_DIFF32. */
14054 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
14055 case EM_TI_PRU:
14056 return (reloc_type == 0 /* R_PRU_NONE. */
14057 || reloc_type == 65 /* R_PRU_DIFF8. */
14058 || reloc_type == 66 /* R_PRU_DIFF16. */
14059 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14060 case EM_XTENSA_OLD:
14061 case EM_XTENSA:
4dc3c23d
AM
14062 return (reloc_type == 0 /* R_XTENSA_NONE. */
14063 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14064 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14065 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14066 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14067 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14068 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14069 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14070 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14071 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88
JK
14072 }
14073 return FALSE;
14074}
14075
d1c4b12b
NC
14076/* Returns TRUE if there is a relocation against
14077 section NAME at OFFSET bytes. */
14078
14079bfd_boolean
14080reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14081{
14082 Elf_Internal_Rela * relocs;
14083 Elf_Internal_Rela * rp;
14084
14085 if (dsec == NULL || dsec->reloc_info == NULL)
14086 return FALSE;
14087
14088 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14089
14090 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14091 if (rp->r_offset == offset)
14092 return TRUE;
14093
14094 return FALSE;
14095}
14096
cf13d699 14097/* Apply relocations to a section.
32ec8896
NC
14098 Returns TRUE upon success, FALSE otherwise.
14099 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14100 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14101 will be set to the number of relocs loaded.
14102
cf13d699 14103 Note: So far support has been added only for those relocations
32ec8896
NC
14104 which can be found in debug sections. FIXME: Add support for
14105 more relocations ? */
1b315056 14106
32ec8896 14107static bfd_boolean
dda8d76d 14108apply_relocations (Filedata * filedata,
d1c4b12b
NC
14109 const Elf_Internal_Shdr * section,
14110 unsigned char * start,
14111 bfd_size_type size,
1449284b 14112 void ** relocs_return,
d1c4b12b 14113 unsigned long * num_relocs_return)
1b315056 14114{
cf13d699 14115 Elf_Internal_Shdr * relsec;
0d2a7a93 14116 unsigned char * end = start + size;
cb8f3167 14117
d1c4b12b
NC
14118 if (relocs_return != NULL)
14119 {
14120 * (Elf_Internal_Rela **) relocs_return = NULL;
14121 * num_relocs_return = 0;
14122 }
14123
dda8d76d 14124 if (filedata->file_header.e_type != ET_REL)
32ec8896
NC
14125 /* No relocs to apply. */
14126 return TRUE;
1b315056 14127
cf13d699 14128 /* Find the reloc section associated with the section. */
dda8d76d
NC
14129 for (relsec = filedata->section_headers;
14130 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14131 ++relsec)
252b5132 14132 {
41e92641
NC
14133 bfd_boolean is_rela;
14134 unsigned long num_relocs;
2cf0635d
NC
14135 Elf_Internal_Rela * relocs;
14136 Elf_Internal_Rela * rp;
14137 Elf_Internal_Shdr * symsec;
14138 Elf_Internal_Sym * symtab;
ba5cdace 14139 unsigned long num_syms;
2cf0635d 14140 Elf_Internal_Sym * sym;
252b5132 14141
41e92641 14142 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14143 || relsec->sh_info >= filedata->file_header.e_shnum
14144 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14145 || relsec->sh_size == 0
dda8d76d 14146 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14147 continue;
428409d5 14148
a788aedd
AM
14149 symsec = filedata->section_headers + relsec->sh_link;
14150 if (symsec->sh_type != SHT_SYMTAB
14151 && symsec->sh_type != SHT_DYNSYM)
14152 return FALSE;
14153
41e92641
NC
14154 is_rela = relsec->sh_type == SHT_RELA;
14155
14156 if (is_rela)
14157 {
dda8d76d 14158 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14159 relsec->sh_size, & relocs, & num_relocs))
32ec8896 14160 return FALSE;
41e92641
NC
14161 }
14162 else
14163 {
dda8d76d 14164 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14165 relsec->sh_size, & relocs, & num_relocs))
32ec8896 14166 return FALSE;
41e92641
NC
14167 }
14168
14169 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14170 if (filedata->file_header.e_machine == EM_SH)
41e92641 14171 is_rela = FALSE;
428409d5 14172
dda8d76d 14173 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 14174
41e92641 14175 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14176 {
41e92641
NC
14177 bfd_vma addend;
14178 unsigned int reloc_type;
14179 unsigned int reloc_size;
03336641
JW
14180 bfd_boolean reloc_inplace = FALSE;
14181 bfd_boolean reloc_subtract = FALSE;
91d6fa6a 14182 unsigned char * rloc;
ba5cdace 14183 unsigned long sym_index;
4b78141a 14184
dda8d76d 14185 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14186
dda8d76d 14187 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14188 continue;
dda8d76d 14189 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14190 continue;
dda8d76d
NC
14191 else if (is_32bit_abs_reloc (filedata, reloc_type)
14192 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14193 reloc_size = 4;
dda8d76d
NC
14194 else if (is_64bit_abs_reloc (filedata, reloc_type)
14195 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14196 reloc_size = 8;
dda8d76d 14197 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14198 reloc_size = 3;
dda8d76d 14199 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14200 reloc_size = 2;
39e07931
AS
14201 else if (is_8bit_abs_reloc (filedata, reloc_type)
14202 || is_6bit_abs_reloc (filedata, reloc_type))
14203 reloc_size = 1;
03336641
JW
14204 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14205 reloc_type))
14206 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14207 {
14208 reloc_size = 4;
14209 reloc_inplace = TRUE;
14210 }
14211 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14212 reloc_type))
14213 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14214 {
14215 reloc_size = 8;
14216 reloc_inplace = TRUE;
14217 }
14218 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14219 reloc_type))
14220 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14221 {
14222 reloc_size = 2;
14223 reloc_inplace = TRUE;
14224 }
14225 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14226 reloc_type))
14227 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14228 {
14229 reloc_size = 1;
14230 reloc_inplace = TRUE;
14231 }
39e07931
AS
14232 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
14233 reloc_type)))
14234 {
14235 reloc_size = 1;
14236 reloc_inplace = TRUE;
14237 }
aca88567 14238 else
4b78141a 14239 {
bee0ee85 14240 static unsigned int prev_reloc = 0;
dda8d76d 14241
bee0ee85
NC
14242 if (reloc_type != prev_reloc)
14243 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 14244 reloc_type, printable_section_name (filedata, section));
bee0ee85 14245 prev_reloc = reloc_type;
4b78141a
NC
14246 continue;
14247 }
103f02d3 14248
91d6fa6a 14249 rloc = start + rp->r_offset;
75802ccb 14250 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
14251 {
14252 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
14253 (unsigned long) rp->r_offset,
dda8d76d 14254 printable_section_name (filedata, section));
700dd8b7
L
14255 continue;
14256 }
103f02d3 14257
ba5cdace
NC
14258 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
14259 if (sym_index >= num_syms)
14260 {
14261 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 14262 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
14263 continue;
14264 }
14265 sym = symtab + sym_index;
41e92641
NC
14266
14267 /* If the reloc has a symbol associated with it,
55f25fc3
L
14268 make sure that it is of an appropriate type.
14269
14270 Relocations against symbols without type can happen.
14271 Gcc -feliminate-dwarf2-dups may generate symbols
14272 without type for debug info.
14273
14274 Icc generates relocations against function symbols
14275 instead of local labels.
14276
14277 Relocations against object symbols can happen, eg when
14278 referencing a global array. For an example of this see
14279 the _clz.o binary in libgcc.a. */
aca88567 14280 if (sym != symtab
b8871f35 14281 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 14282 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 14283 {
d3a49aa8 14284 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
14285 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
14286 printable_section_name (filedata, relsec),
d3a49aa8 14287 (long int)(rp - relocs));
aca88567 14288 continue;
5b18a4bc 14289 }
252b5132 14290
4dc3c23d
AM
14291 addend = 0;
14292 if (is_rela)
14293 addend += rp->r_addend;
c47320c3
AM
14294 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
14295 partial_inplace. */
4dc3c23d 14296 if (!is_rela
dda8d76d 14297 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 14298 && reloc_type == 1)
dda8d76d
NC
14299 || ((filedata->file_header.e_machine == EM_PJ
14300 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 14301 && reloc_type == 1)
dda8d76d
NC
14302 || ((filedata->file_header.e_machine == EM_D30V
14303 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
14304 && reloc_type == 12)
14305 || reloc_inplace)
39e07931
AS
14306 {
14307 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
14308 addend += byte_get (rloc, reloc_size) & 0x3f;
14309 else
14310 addend += byte_get (rloc, reloc_size);
14311 }
cb8f3167 14312
dda8d76d
NC
14313 if (is_32bit_pcrel_reloc (filedata, reloc_type)
14314 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
14315 {
14316 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 14317 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 14318 addend -= 8;
91d6fa6a 14319 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
14320 reloc_size);
14321 }
39e07931
AS
14322 else if (is_6bit_abs_reloc (filedata, reloc_type)
14323 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
14324 {
14325 if (reloc_subtract)
14326 addend -= sym->st_value;
14327 else
14328 addend += sym->st_value;
14329 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
14330 byte_put (rloc, addend, reloc_size);
14331 }
03336641
JW
14332 else if (reloc_subtract)
14333 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 14334 else
91d6fa6a 14335 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 14336 }
252b5132 14337
5b18a4bc 14338 free (symtab);
f84ce13b
NC
14339 /* Let the target specific reloc processing code know that
14340 we have finished with these relocs. */
dda8d76d 14341 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
14342
14343 if (relocs_return)
14344 {
14345 * (Elf_Internal_Rela **) relocs_return = relocs;
14346 * num_relocs_return = num_relocs;
14347 }
14348 else
14349 free (relocs);
14350
5b18a4bc
NC
14351 break;
14352 }
32ec8896 14353
dfc616fa 14354 return TRUE;
5b18a4bc 14355}
103f02d3 14356
cf13d699 14357#ifdef SUPPORT_DISASSEMBLY
32ec8896 14358static bfd_boolean
dda8d76d 14359disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14360{
dda8d76d 14361 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 14362
74e1a04b 14363 /* FIXME: XXX -- to be done --- XXX */
cf13d699 14364
32ec8896 14365 return TRUE;
cf13d699
NC
14366}
14367#endif
14368
14369/* Reads in the contents of SECTION from FILE, returning a pointer
14370 to a malloc'ed buffer or NULL if something went wrong. */
14371
14372static char *
dda8d76d 14373get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14374{
dda8d76d 14375 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
14376
14377 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
14378 {
c6b78c96 14379 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 14380 printable_section_name (filedata, section));
cf13d699
NC
14381 return NULL;
14382 }
14383
dda8d76d 14384 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 14385 _("section contents"));
cf13d699
NC
14386}
14387
0e602686
NC
14388/* Uncompresses a section that was compressed using zlib, in place. */
14389
14390static bfd_boolean
dda8d76d
NC
14391uncompress_section_contents (unsigned char ** buffer,
14392 dwarf_size_type uncompressed_size,
14393 dwarf_size_type * size)
0e602686
NC
14394{
14395 dwarf_size_type compressed_size = *size;
14396 unsigned char * compressed_buffer = *buffer;
14397 unsigned char * uncompressed_buffer;
14398 z_stream strm;
14399 int rc;
14400
14401 /* It is possible the section consists of several compressed
14402 buffers concatenated together, so we uncompress in a loop. */
14403 /* PR 18313: The state field in the z_stream structure is supposed
14404 to be invisible to the user (ie us), but some compilers will
14405 still complain about it being used without initialisation. So
14406 we first zero the entire z_stream structure and then set the fields
14407 that we need. */
14408 memset (& strm, 0, sizeof strm);
14409 strm.avail_in = compressed_size;
14410 strm.next_in = (Bytef *) compressed_buffer;
14411 strm.avail_out = uncompressed_size;
14412 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
14413
14414 rc = inflateInit (& strm);
14415 while (strm.avail_in > 0)
14416 {
14417 if (rc != Z_OK)
3624a6c1 14418 break;
0e602686
NC
14419 strm.next_out = ((Bytef *) uncompressed_buffer
14420 + (uncompressed_size - strm.avail_out));
14421 rc = inflate (&strm, Z_FINISH);
14422 if (rc != Z_STREAM_END)
3624a6c1 14423 break;
0e602686
NC
14424 rc = inflateReset (& strm);
14425 }
ad92f33d
AM
14426 if (inflateEnd (& strm) != Z_OK
14427 || rc != Z_OK
0e602686
NC
14428 || strm.avail_out != 0)
14429 goto fail;
14430
14431 *buffer = uncompressed_buffer;
14432 *size = uncompressed_size;
14433 return TRUE;
14434
14435 fail:
14436 free (uncompressed_buffer);
14437 /* Indicate decompression failure. */
14438 *buffer = NULL;
14439 return FALSE;
14440}
dd24e3da 14441
32ec8896 14442static bfd_boolean
dda8d76d 14443dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14444{
0e602686
NC
14445 Elf_Internal_Shdr * relsec;
14446 bfd_size_type num_bytes;
fd8008d8
L
14447 unsigned char * data;
14448 unsigned char * end;
14449 unsigned char * real_start;
14450 unsigned char * start;
0e602686 14451 bfd_boolean some_strings_shown;
cf13d699 14452
dda8d76d 14453 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14454 if (start == NULL)
c6b78c96
NC
14455 /* PR 21820: Do not fail if the section was empty. */
14456 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
14457
0e602686 14458 num_bytes = section->sh_size;
cf13d699 14459
dda8d76d 14460 printf (_("\nString dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 14461
0e602686
NC
14462 if (decompress_dumps)
14463 {
14464 dwarf_size_type new_size = num_bytes;
14465 dwarf_size_type uncompressed_size = 0;
14466
14467 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14468 {
14469 Elf_Internal_Chdr chdr;
14470 unsigned int compression_header_size
ebdf1ebf
NC
14471 = get_compression_header (& chdr, (unsigned char *) start,
14472 num_bytes);
5844b465
NC
14473 if (compression_header_size == 0)
14474 /* An error message will have already been generated
14475 by get_compression_header. */
14476 goto error_out;
0e602686 14477
813dabb9 14478 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14479 {
813dabb9 14480 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14481 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14482 goto error_out;
813dabb9 14483 }
813dabb9
L
14484 uncompressed_size = chdr.ch_size;
14485 start += compression_header_size;
14486 new_size -= compression_header_size;
0e602686
NC
14487 }
14488 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14489 {
14490 /* Read the zlib header. In this case, it should be "ZLIB"
14491 followed by the uncompressed section size, 8 bytes in
14492 big-endian order. */
14493 uncompressed_size = start[4]; uncompressed_size <<= 8;
14494 uncompressed_size += start[5]; uncompressed_size <<= 8;
14495 uncompressed_size += start[6]; uncompressed_size <<= 8;
14496 uncompressed_size += start[7]; uncompressed_size <<= 8;
14497 uncompressed_size += start[8]; uncompressed_size <<= 8;
14498 uncompressed_size += start[9]; uncompressed_size <<= 8;
14499 uncompressed_size += start[10]; uncompressed_size <<= 8;
14500 uncompressed_size += start[11];
14501 start += 12;
14502 new_size -= 12;
14503 }
14504
1835f746
NC
14505 if (uncompressed_size)
14506 {
14507 if (uncompress_section_contents (& start,
14508 uncompressed_size, & new_size))
14509 num_bytes = new_size;
14510 else
14511 {
14512 error (_("Unable to decompress section %s\n"),
dda8d76d 14513 printable_section_name (filedata, section));
f761cb13 14514 goto error_out;
1835f746
NC
14515 }
14516 }
bc303e5d
NC
14517 else
14518 start = real_start;
0e602686 14519 }
fd8008d8 14520
cf13d699
NC
14521 /* If the section being dumped has relocations against it the user might
14522 be expecting these relocations to have been applied. Check for this
14523 case and issue a warning message in order to avoid confusion.
14524 FIXME: Maybe we ought to have an option that dumps a section with
14525 relocs applied ? */
dda8d76d
NC
14526 for (relsec = filedata->section_headers;
14527 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14528 ++relsec)
14529 {
14530 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14531 || relsec->sh_info >= filedata->file_header.e_shnum
14532 || filedata->section_headers + relsec->sh_info != section
cf13d699 14533 || relsec->sh_size == 0
dda8d76d 14534 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14535 continue;
14536
14537 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14538 break;
14539 }
14540
cf13d699
NC
14541 data = start;
14542 end = start + num_bytes;
14543 some_strings_shown = FALSE;
14544
ba3265d0
NC
14545#ifdef HAVE_MBSTATE_T
14546 mbstate_t state;
14547 /* Initialise the multibyte conversion state. */
14548 memset (& state, 0, sizeof (state));
14549#endif
14550
14551 bfd_boolean continuing = FALSE;
14552
cf13d699
NC
14553 while (data < end)
14554 {
14555 while (!ISPRINT (* data))
14556 if (++ data >= end)
14557 break;
14558
14559 if (data < end)
14560 {
071436c6
NC
14561 size_t maxlen = end - data;
14562
ba3265d0
NC
14563 if (continuing)
14564 {
14565 printf (" ");
14566 continuing = FALSE;
14567 }
14568 else
14569 {
d1ce973e 14570 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
14571 }
14572
4082ef84
NC
14573 if (maxlen > 0)
14574 {
f3da8a96 14575 char c = 0;
ba3265d0
NC
14576
14577 while (maxlen)
14578 {
14579 c = *data++;
14580
14581 if (c == 0)
14582 break;
14583
14584 /* PR 25543: Treat new-lines as string-ending characters. */
14585 if (c == '\n')
14586 {
14587 printf ("\\n\n");
14588 if (*data != 0)
14589 continuing = TRUE;
14590 break;
14591 }
14592
14593 /* Do not print control characters directly as they can affect terminal
14594 settings. Such characters usually appear in the names generated
14595 by the assembler for local labels. */
14596 if (ISCNTRL (c))
14597 {
14598 printf ("^%c", c + 0x40);
14599 }
14600 else if (ISPRINT (c))
14601 {
14602 putchar (c);
14603 }
14604 else
14605 {
14606 size_t n;
14607#ifdef HAVE_MBSTATE_T
14608 wchar_t w;
14609#endif
14610 /* Let printf do the hard work of displaying multibyte characters. */
14611 printf ("%.1s", data - 1);
14612#ifdef HAVE_MBSTATE_T
14613 /* Try to find out how many bytes made up the character that was
14614 just printed. Advance the symbol pointer past the bytes that
14615 were displayed. */
14616 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
14617#else
14618 n = 1;
14619#endif
14620 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
14621 data += (n - 1);
14622 }
14623 }
14624
14625 if (c != '\n')
14626 putchar ('\n');
4082ef84
NC
14627 }
14628 else
14629 {
14630 printf (_("<corrupt>\n"));
14631 data = end;
14632 }
cf13d699
NC
14633 some_strings_shown = TRUE;
14634 }
14635 }
14636
14637 if (! some_strings_shown)
14638 printf (_(" No strings found in this section."));
14639
0e602686 14640 free (real_start);
cf13d699
NC
14641
14642 putchar ('\n');
32ec8896 14643 return TRUE;
f761cb13
AM
14644
14645error_out:
14646 free (real_start);
14647 return FALSE;
cf13d699
NC
14648}
14649
32ec8896 14650static bfd_boolean
dda8d76d
NC
14651dump_section_as_bytes (Elf_Internal_Shdr * section,
14652 Filedata * filedata,
14653 bfd_boolean relocate)
cf13d699
NC
14654{
14655 Elf_Internal_Shdr * relsec;
0e602686
NC
14656 bfd_size_type bytes;
14657 bfd_size_type section_size;
14658 bfd_vma addr;
14659 unsigned char * data;
14660 unsigned char * real_start;
14661 unsigned char * start;
14662
dda8d76d 14663 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14664 if (start == NULL)
c6b78c96
NC
14665 /* PR 21820: Do not fail if the section was empty. */
14666 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
32ec8896 14667
0e602686 14668 section_size = section->sh_size;
cf13d699 14669
dda8d76d 14670 printf (_("\nHex dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 14671
0e602686
NC
14672 if (decompress_dumps)
14673 {
14674 dwarf_size_type new_size = section_size;
14675 dwarf_size_type uncompressed_size = 0;
14676
14677 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14678 {
14679 Elf_Internal_Chdr chdr;
14680 unsigned int compression_header_size
ebdf1ebf 14681 = get_compression_header (& chdr, start, section_size);
0e602686 14682
5844b465
NC
14683 if (compression_header_size == 0)
14684 /* An error message will have already been generated
14685 by get_compression_header. */
14686 goto error_out;
14687
813dabb9 14688 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14689 {
813dabb9 14690 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14691 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14692 goto error_out;
0e602686 14693 }
813dabb9
L
14694 uncompressed_size = chdr.ch_size;
14695 start += compression_header_size;
14696 new_size -= compression_header_size;
0e602686
NC
14697 }
14698 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14699 {
14700 /* Read the zlib header. In this case, it should be "ZLIB"
14701 followed by the uncompressed section size, 8 bytes in
14702 big-endian order. */
14703 uncompressed_size = start[4]; uncompressed_size <<= 8;
14704 uncompressed_size += start[5]; uncompressed_size <<= 8;
14705 uncompressed_size += start[6]; uncompressed_size <<= 8;
14706 uncompressed_size += start[7]; uncompressed_size <<= 8;
14707 uncompressed_size += start[8]; uncompressed_size <<= 8;
14708 uncompressed_size += start[9]; uncompressed_size <<= 8;
14709 uncompressed_size += start[10]; uncompressed_size <<= 8;
14710 uncompressed_size += start[11];
14711 start += 12;
14712 new_size -= 12;
14713 }
14714
f055032e
NC
14715 if (uncompressed_size)
14716 {
14717 if (uncompress_section_contents (& start, uncompressed_size,
14718 & new_size))
bc303e5d
NC
14719 {
14720 section_size = new_size;
14721 }
f055032e
NC
14722 else
14723 {
14724 error (_("Unable to decompress section %s\n"),
dda8d76d 14725 printable_section_name (filedata, section));
bc303e5d 14726 /* FIXME: Print the section anyway ? */
f761cb13 14727 goto error_out;
f055032e
NC
14728 }
14729 }
bc303e5d
NC
14730 else
14731 start = real_start;
0e602686 14732 }
14ae95f2 14733
cf13d699
NC
14734 if (relocate)
14735 {
dda8d76d 14736 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 14737 goto error_out;
cf13d699
NC
14738 }
14739 else
14740 {
14741 /* If the section being dumped has relocations against it the user might
14742 be expecting these relocations to have been applied. Check for this
14743 case and issue a warning message in order to avoid confusion.
14744 FIXME: Maybe we ought to have an option that dumps a section with
14745 relocs applied ? */
dda8d76d
NC
14746 for (relsec = filedata->section_headers;
14747 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14748 ++relsec)
14749 {
14750 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14751 || relsec->sh_info >= filedata->file_header.e_shnum
14752 || filedata->section_headers + relsec->sh_info != section
cf13d699 14753 || relsec->sh_size == 0
dda8d76d 14754 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14755 continue;
14756
14757 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14758 break;
14759 }
14760 }
14761
14762 addr = section->sh_addr;
0e602686 14763 bytes = section_size;
cf13d699
NC
14764 data = start;
14765
14766 while (bytes)
14767 {
14768 int j;
14769 int k;
14770 int lbytes;
14771
14772 lbytes = (bytes > 16 ? 16 : bytes);
14773
14774 printf (" 0x%8.8lx ", (unsigned long) addr);
14775
14776 for (j = 0; j < 16; j++)
14777 {
14778 if (j < lbytes)
14779 printf ("%2.2x", data[j]);
14780 else
14781 printf (" ");
14782
14783 if ((j & 3) == 3)
14784 printf (" ");
14785 }
14786
14787 for (j = 0; j < lbytes; j++)
14788 {
14789 k = data[j];
14790 if (k >= ' ' && k < 0x7f)
14791 printf ("%c", k);
14792 else
14793 printf (".");
14794 }
14795
14796 putchar ('\n');
14797
14798 data += lbytes;
14799 addr += lbytes;
14800 bytes -= lbytes;
14801 }
14802
0e602686 14803 free (real_start);
cf13d699
NC
14804
14805 putchar ('\n');
32ec8896 14806 return TRUE;
f761cb13
AM
14807
14808 error_out:
14809 free (real_start);
14810 return FALSE;
cf13d699
NC
14811}
14812
094e34f2 14813#ifdef ENABLE_LIBCTF
7d9813f1
NA
14814static ctf_sect_t *
14815shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
14816{
b9e920ec 14817 buf->cts_name = SECTION_NAME_PRINT (shdr);
7d9813f1
NA
14818 buf->cts_size = shdr->sh_size;
14819 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
14820
14821 return buf;
14822}
14823
14824/* Formatting callback function passed to ctf_dump. Returns either the pointer
14825 it is passed, or a pointer to newly-allocated storage, in which case
14826 dump_ctf() will free it when it no longer needs it. */
14827
2f6ecaed
NA
14828static char *
14829dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14830 char *s, void *arg)
7d9813f1 14831{
3e50a591 14832 const char *blanks = arg;
7d9813f1
NA
14833 char *new_s;
14834
3e50a591 14835 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
14836 return s;
14837 return new_s;
14838}
14839
926c9e76
NA
14840/* Dump CTF errors/warnings. */
14841static void
139633c3 14842dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
14843{
14844 ctf_next_t *it = NULL;
14845 char *errtext;
14846 int is_warning;
14847 int err;
14848
14849 /* Dump accumulated errors and warnings. */
14850 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
14851 {
5e9b84f7 14852 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
14853 errtext);
14854 free (errtext);
14855 }
14856 if (err != ECTF_NEXT_END)
14857 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
14858}
14859
2f6ecaed
NA
14860/* Dump one CTF archive member. */
14861
14862static int
139633c3 14863dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
2f6ecaed 14864{
139633c3 14865 ctf_dict_t *parent = (ctf_dict_t *) arg;
2f6ecaed
NA
14866 const char *things[] = {"Header", "Labels", "Data objects",
14867 "Function objects", "Variables", "Types", "Strings",
14868 ""};
14869 const char **thing;
14870 size_t i;
8b37e7b6 14871 int err = 0;
2f6ecaed
NA
14872
14873 /* Only print out the name of non-default-named archive members.
14874 The name .ctf appears everywhere, even for things that aren't
14875 really archives, so printing it out is liable to be confusing.
14876
14877 The parent, if there is one, is the default-owned archive member:
14878 avoid importing it into itself. (This does no harm, but looks
14879 confusing.) */
14880
14881 if (strcmp (name, ".ctf") != 0)
14882 {
14883 printf (_("\nCTF archive member: %s:\n"), name);
14884 ctf_import (ctf, parent);
14885 }
14886
14887 for (i = 0, thing = things; *thing[0]; thing++, i++)
14888 {
14889 ctf_dump_state_t *s = NULL;
14890 char *item;
14891
14892 printf ("\n %s:\n", *thing);
14893 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
14894 (void *) " ")) != NULL)
14895 {
14896 printf ("%s\n", item);
14897 free (item);
14898 }
14899
14900 if (ctf_errno (ctf))
14901 {
14902 error (_("Iteration failed: %s, %s\n"), *thing,
14903 ctf_errmsg (ctf_errno (ctf)));
8b37e7b6
NA
14904 err = 1;
14905 goto out;
2f6ecaed
NA
14906 }
14907 }
8b37e7b6
NA
14908
14909 out:
926c9e76 14910 dump_ctf_errs (ctf);
8b37e7b6 14911 return err;
2f6ecaed
NA
14912}
14913
7d9813f1
NA
14914static bfd_boolean
14915dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
14916{
14917 Elf_Internal_Shdr * parent_sec = NULL;
14918 Elf_Internal_Shdr * symtab_sec = NULL;
14919 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
14920 void * data = NULL;
14921 void * symdata = NULL;
14922 void * strdata = NULL;
14923 void * parentdata = NULL;
14924 ctf_sect_t ctfsect, symsect, strsect, parentsect;
14925 ctf_sect_t * symsectp = NULL;
14926 ctf_sect_t * strsectp = NULL;
2f6ecaed
NA
14927 ctf_archive_t * ctfa = NULL;
14928 ctf_archive_t * parenta = NULL, *lookparent;
139633c3 14929 ctf_dict_t * parent = NULL;
7d9813f1 14930
7d9813f1
NA
14931 int err;
14932 bfd_boolean ret = FALSE;
7d9813f1
NA
14933
14934 shdr_to_ctf_sect (&ctfsect, section, filedata);
14935 data = get_section_contents (section, filedata);
14936 ctfsect.cts_data = data;
14937
616febde 14938 if (!dump_ctf_symtab_name)
3d16b64e 14939 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
14940
14941 if (!dump_ctf_strtab_name)
3d16b64e 14942 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
14943
14944 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
14945 {
14946 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
14947 {
14948 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
14949 goto fail;
14950 }
14951 if ((symdata = (void *) get_data (NULL, filedata,
14952 symtab_sec->sh_offset, 1,
14953 symtab_sec->sh_size,
14954 _("symbols"))) == NULL)
14955 goto fail;
14956 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
14957 symsect.cts_data = symdata;
14958 }
df16e041 14959 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
14960 {
14961 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
14962 {
14963 error (_("No string table section named %s\n"),
14964 dump_ctf_strtab_name);
14965 goto fail;
14966 }
14967 if ((strdata = (void *) get_data (NULL, filedata,
14968 strtab_sec->sh_offset, 1,
14969 strtab_sec->sh_size,
14970 _("strings"))) == NULL)
14971 goto fail;
14972 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
14973 strsect.cts_data = strdata;
14974 }
14975 if (dump_ctf_parent_name)
14976 {
14977 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
14978 {
14979 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
14980 goto fail;
14981 }
14982 if ((parentdata = (void *) get_data (NULL, filedata,
14983 parent_sec->sh_offset, 1,
14984 parent_sec->sh_size,
14985 _("CTF parent"))) == NULL)
14986 goto fail;
14987 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
14988 parentsect.cts_data = parentdata;
14989 }
14990
2f6ecaed
NA
14991 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
14992 libctf papers over the difference, so we can pretend it is always an
14993 archive. Possibly open the parent as well, if one was specified. */
7d9813f1 14994
2f6ecaed 14995 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 14996 {
926c9e76 14997 dump_ctf_errs (NULL);
7d9813f1
NA
14998 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14999 goto fail;
15000 }
15001
96c61be5
NA
15002 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15003 != ELFDATA2MSB);
15004
7d9813f1
NA
15005 if (parentdata)
15006 {
2f6ecaed
NA
15007 if ((parenta = ctf_arc_bufopen (&parentsect, symsectp, strsectp,
15008 &err)) == NULL)
7d9813f1 15009 {
926c9e76 15010 dump_ctf_errs (NULL);
7d9813f1
NA
15011 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15012 goto fail;
15013 }
2f6ecaed
NA
15014 lookparent = parenta;
15015 }
15016 else
15017 lookparent = ctfa;
7d9813f1 15018
2f6ecaed
NA
15019 /* Assume that the applicable parent archive member is the default one.
15020 (This is what all known implementations are expected to do, if they
15021 put CTFs and their parents in archives together.) */
ae41200b 15022 if ((parent = ctf_dict_open (lookparent, NULL, &err)) == NULL)
2f6ecaed 15023 {
926c9e76 15024 dump_ctf_errs (NULL);
2f6ecaed
NA
15025 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15026 goto fail;
7d9813f1
NA
15027 }
15028
15029 ret = TRUE;
15030
15031 printf (_("\nDump of CTF section '%s':\n"),
15032 printable_section_name (filedata, section));
15033
83d59285
NA
15034 if ((err = ctf_archive_iter (ctfa, dump_ctf_archive_member, parent)) != 0)
15035 {
15036 dump_ctf_errs (NULL);
15037 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
15038 ret = FALSE;
15039 }
7d9813f1
NA
15040
15041 fail:
139633c3 15042 ctf_dict_close (parent);
2f6ecaed
NA
15043 ctf_close (ctfa);
15044 ctf_close (parenta);
7d9813f1
NA
15045 free (parentdata);
15046 free (data);
15047 free (symdata);
15048 free (strdata);
15049 return ret;
15050}
094e34f2 15051#endif
7d9813f1 15052
32ec8896 15053static bfd_boolean
dda8d76d
NC
15054load_specific_debug_section (enum dwarf_section_display_enum debug,
15055 const Elf_Internal_Shdr * sec,
15056 void * data)
1007acb3 15057{
2cf0635d 15058 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15059 char buf [64];
dda8d76d 15060 Filedata * filedata = (Filedata *) data;
9abca702 15061
19e6b90e 15062 if (section->start != NULL)
dda8d76d
NC
15063 {
15064 /* If it is already loaded, do nothing. */
15065 if (streq (section->filename, filedata->file_name))
15066 return TRUE;
15067 free (section->start);
15068 }
1007acb3 15069
19e6b90e
L
15070 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15071 section->address = sec->sh_addr;
dda8d76d
NC
15072 section->filename = filedata->file_name;
15073 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15074 sec->sh_offset, 1,
15075 sec->sh_size, buf);
59245841
NC
15076 if (section->start == NULL)
15077 section->size = 0;
15078 else
15079 {
77115a4a
L
15080 unsigned char *start = section->start;
15081 dwarf_size_type size = sec->sh_size;
dab394de 15082 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15083
15084 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15085 {
15086 Elf_Internal_Chdr chdr;
d8024a91
NC
15087 unsigned int compression_header_size;
15088
f53be977
L
15089 if (size < (is_32bit_elf
15090 ? sizeof (Elf32_External_Chdr)
15091 : sizeof (Elf64_External_Chdr)))
d8024a91 15092 {
55be8fd0 15093 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15094 section->name);
32ec8896 15095 return FALSE;
d8024a91
NC
15096 }
15097
ebdf1ebf 15098 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15099 if (compression_header_size == 0)
15100 /* An error message will have already been generated
15101 by get_compression_header. */
15102 return FALSE;
d8024a91 15103
813dabb9
L
15104 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15105 {
15106 warn (_("section '%s' has unsupported compress type: %d\n"),
15107 section->name, chdr.ch_type);
32ec8896 15108 return FALSE;
813dabb9 15109 }
dab394de 15110 uncompressed_size = chdr.ch_size;
77115a4a
L
15111 start += compression_header_size;
15112 size -= compression_header_size;
15113 }
dab394de
L
15114 else if (size > 12 && streq ((char *) start, "ZLIB"))
15115 {
15116 /* Read the zlib header. In this case, it should be "ZLIB"
15117 followed by the uncompressed section size, 8 bytes in
15118 big-endian order. */
15119 uncompressed_size = start[4]; uncompressed_size <<= 8;
15120 uncompressed_size += start[5]; uncompressed_size <<= 8;
15121 uncompressed_size += start[6]; uncompressed_size <<= 8;
15122 uncompressed_size += start[7]; uncompressed_size <<= 8;
15123 uncompressed_size += start[8]; uncompressed_size <<= 8;
15124 uncompressed_size += start[9]; uncompressed_size <<= 8;
15125 uncompressed_size += start[10]; uncompressed_size <<= 8;
15126 uncompressed_size += start[11];
15127 start += 12;
15128 size -= 12;
15129 }
15130
1835f746 15131 if (uncompressed_size)
77115a4a 15132 {
1835f746
NC
15133 if (uncompress_section_contents (&start, uncompressed_size,
15134 &size))
15135 {
15136 /* Free the compressed buffer, update the section buffer
15137 and the section size if uncompress is successful. */
15138 free (section->start);
15139 section->start = start;
15140 }
15141 else
15142 {
15143 error (_("Unable to decompress section %s\n"),
dda8d76d 15144 printable_section_name (filedata, sec));
32ec8896 15145 return FALSE;
1835f746 15146 }
77115a4a 15147 }
bc303e5d 15148
77115a4a 15149 section->size = size;
59245841 15150 }
4a114e3e 15151
1b315056 15152 if (section->start == NULL)
32ec8896 15153 return FALSE;
1b315056 15154
19e6b90e 15155 if (debug_displays [debug].relocate)
32ec8896 15156 {
dda8d76d 15157 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896
NC
15158 & section->reloc_info, & section->num_relocs))
15159 return FALSE;
15160 }
d1c4b12b
NC
15161 else
15162 {
15163 section->reloc_info = NULL;
15164 section->num_relocs = 0;
15165 }
1007acb3 15166
32ec8896 15167 return TRUE;
1007acb3
L
15168}
15169
301a9420
AM
15170#if HAVE_LIBDEBUGINFOD
15171/* Return a hex string representation of the build-id. */
15172unsigned char *
15173get_build_id (void * data)
15174{
ca0e11aa 15175 Filedata * filedata = (Filedata *) data;
301a9420
AM
15176 Elf_Internal_Shdr * shdr;
15177 unsigned long i;
15178
55be8fd0
NC
15179 /* Iterate through notes to find note.gnu.build-id.
15180 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15181 for (i = 0, shdr = filedata->section_headers;
15182 i < filedata->file_header.e_shnum && shdr != NULL;
15183 i++, shdr++)
15184 {
15185 if (shdr->sh_type != SHT_NOTE)
15186 continue;
15187
15188 char * next;
15189 char * end;
15190 size_t data_remaining;
15191 size_t min_notesz;
15192 Elf_External_Note * enote;
15193 Elf_Internal_Note inote;
15194
15195 bfd_vma offset = shdr->sh_offset;
15196 bfd_vma align = shdr->sh_addralign;
15197 bfd_vma length = shdr->sh_size;
15198
15199 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15200 if (enote == NULL)
15201 continue;
15202
15203 if (align < 4)
15204 align = 4;
15205 else if (align != 4 && align != 8)
f761cb13
AM
15206 {
15207 free (enote);
15208 continue;
15209 }
301a9420
AM
15210
15211 end = (char *) enote + length;
15212 data_remaining = end - (char *) enote;
15213
15214 if (!is_ia64_vms (filedata))
15215 {
15216 min_notesz = offsetof (Elf_External_Note, name);
15217 if (data_remaining < min_notesz)
15218 {
55be8fd0
NC
15219 warn (_("\
15220malformed note encountered in section %s whilst scanning for build-id note\n"),
15221 printable_section_name (filedata, shdr));
f761cb13 15222 free (enote);
55be8fd0 15223 continue;
301a9420
AM
15224 }
15225 data_remaining -= min_notesz;
15226
15227 inote.type = BYTE_GET (enote->type);
15228 inote.namesz = BYTE_GET (enote->namesz);
15229 inote.namedata = enote->name;
15230 inote.descsz = BYTE_GET (enote->descsz);
15231 inote.descdata = ((char *) enote
15232 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15233 inote.descpos = offset + (inote.descdata - (char *) enote);
15234 next = ((char *) enote
15235 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15236 }
15237 else
15238 {
15239 Elf64_External_VMS_Note *vms_enote;
15240
15241 /* PR binutils/15191
15242 Make sure that there is enough data to read. */
15243 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15244 if (data_remaining < min_notesz)
15245 {
55be8fd0
NC
15246 warn (_("\
15247malformed note encountered in section %s whilst scanning for build-id note\n"),
15248 printable_section_name (filedata, shdr));
f761cb13 15249 free (enote);
55be8fd0 15250 continue;
301a9420
AM
15251 }
15252 data_remaining -= min_notesz;
15253
15254 vms_enote = (Elf64_External_VMS_Note *) enote;
15255 inote.type = BYTE_GET (vms_enote->type);
15256 inote.namesz = BYTE_GET (vms_enote->namesz);
15257 inote.namedata = vms_enote->name;
15258 inote.descsz = BYTE_GET (vms_enote->descsz);
15259 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15260 inote.descpos = offset + (inote.descdata - (char *) enote);
15261 next = inote.descdata + align_power (inote.descsz, 3);
15262 }
15263
15264 /* Skip malformed notes. */
15265 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
15266 || (size_t) (inote.descdata - inote.namedata) > data_remaining
15267 || (size_t) (next - inote.descdata) < inote.descsz
15268 || ((size_t) (next - inote.descdata)
15269 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
15270 {
55be8fd0
NC
15271 warn (_("\
15272malformed note encountered in section %s whilst scanning for build-id note\n"),
15273 printable_section_name (filedata, shdr));
f761cb13 15274 free (enote);
301a9420
AM
15275 continue;
15276 }
15277
15278 /* Check if this is the build-id note. If so then convert the build-id
15279 bytes to a hex string. */
15280 if (inote.namesz > 0
15281 && const_strneq (inote.namedata, "GNU")
15282 && inote.type == NT_GNU_BUILD_ID)
15283 {
15284 unsigned long j;
15285 char * build_id;
15286
15287 build_id = malloc (inote.descsz * 2 + 1);
15288 if (build_id == NULL)
f761cb13
AM
15289 {
15290 free (enote);
15291 return NULL;
15292 }
301a9420
AM
15293
15294 for (j = 0; j < inote.descsz; ++j)
15295 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
15296 build_id[inote.descsz * 2] = '\0';
f761cb13 15297 free (enote);
301a9420 15298
55be8fd0 15299 return (unsigned char *) build_id;
301a9420 15300 }
f761cb13 15301 free (enote);
301a9420
AM
15302 }
15303
15304 return NULL;
15305}
15306#endif /* HAVE_LIBDEBUGINFOD */
15307
657d0d47
CC
15308/* If this is not NULL, load_debug_section will only look for sections
15309 within the list of sections given here. */
32ec8896 15310static unsigned int * section_subset = NULL;
657d0d47 15311
32ec8896 15312bfd_boolean
dda8d76d 15313load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 15314{
2cf0635d
NC
15315 struct dwarf_section * section = &debug_displays [debug].section;
15316 Elf_Internal_Shdr * sec;
dda8d76d
NC
15317 Filedata * filedata = (Filedata *) data;
15318
f425ec66
NC
15319 /* Without section headers we cannot find any sections. */
15320 if (filedata->section_headers == NULL)
15321 return FALSE;
15322
9c1ce108
AM
15323 if (filedata->string_table == NULL
15324 && filedata->file_header.e_shstrndx != SHN_UNDEF
15325 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
15326 {
15327 Elf_Internal_Shdr * strs;
15328
15329 /* Read in the string table, so that we have section names to scan. */
15330 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
15331
4dff97b2 15332 if (strs != NULL && strs->sh_size != 0)
dda8d76d 15333 {
9c1ce108
AM
15334 filedata->string_table
15335 = (char *) get_data (NULL, filedata, strs->sh_offset,
15336 1, strs->sh_size, _("string table"));
dda8d76d 15337
9c1ce108
AM
15338 filedata->string_table_length
15339 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
15340 }
15341 }
d966045b
DJ
15342
15343 /* Locate the debug section. */
dda8d76d 15344 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
15345 if (sec != NULL)
15346 section->name = section->uncompressed_name;
15347 else
15348 {
dda8d76d 15349 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
15350 if (sec != NULL)
15351 section->name = section->compressed_name;
15352 }
15353 if (sec == NULL)
32ec8896 15354 return FALSE;
d966045b 15355
657d0d47
CC
15356 /* If we're loading from a subset of sections, and we've loaded
15357 a section matching this name before, it's likely that it's a
15358 different one. */
15359 if (section_subset != NULL)
15360 free_debug_section (debug);
15361
dda8d76d 15362 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
15363}
15364
19e6b90e
L
15365void
15366free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 15367{
2cf0635d 15368 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 15369
19e6b90e
L
15370 if (section->start == NULL)
15371 return;
1007acb3 15372
19e6b90e
L
15373 free ((char *) section->start);
15374 section->start = NULL;
15375 section->address = 0;
15376 section->size = 0;
a788aedd 15377
9db70fc3
AM
15378 free (section->reloc_info);
15379 section->reloc_info = NULL;
15380 section->num_relocs = 0;
1007acb3
L
15381}
15382
32ec8896 15383static bfd_boolean
dda8d76d 15384display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 15385{
b9e920ec 15386 char * name = SECTION_NAME_VALID (section) ? SECTION_NAME (section) : "";
dda8d76d 15387 const char * print_name = printable_section_name (filedata, section);
19e6b90e 15388 bfd_size_type length;
32ec8896 15389 bfd_boolean result = TRUE;
3f5e193b 15390 int i;
1007acb3 15391
19e6b90e
L
15392 length = section->sh_size;
15393 if (length == 0)
1007acb3 15394 {
74e1a04b 15395 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
32ec8896 15396 return TRUE;
1007acb3 15397 }
5dff79d8
NC
15398 if (section->sh_type == SHT_NOBITS)
15399 {
15400 /* There is no point in dumping the contents of a debugging section
15401 which has the NOBITS type - the bits in the file will be random.
15402 This can happen when a file containing a .eh_frame section is
15403 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
15404 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
15405 print_name);
32ec8896 15406 return FALSE;
5dff79d8 15407 }
1007acb3 15408
0112cd26 15409 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 15410 name = ".debug_info";
1007acb3 15411
19e6b90e
L
15412 /* See if we know how to display the contents of this section. */
15413 for (i = 0; i < max; i++)
d85bf2ba
NC
15414 {
15415 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
15416 struct dwarf_section_display * display = debug_displays + i;
15417 struct dwarf_section * sec = & display->section;
d966045b 15418
d85bf2ba
NC
15419 if (streq (sec->uncompressed_name, name)
15420 || (id == line && const_strneq (name, ".debug_line."))
15421 || streq (sec->compressed_name, name))
15422 {
15423 bfd_boolean secondary = (section != find_section (filedata, name));
1007acb3 15424
d85bf2ba
NC
15425 if (secondary)
15426 free_debug_section (id);
dda8d76d 15427
d85bf2ba
NC
15428 if (i == line && const_strneq (name, ".debug_line."))
15429 sec->name = name;
15430 else if (streq (sec->uncompressed_name, name))
15431 sec->name = sec->uncompressed_name;
15432 else
15433 sec->name = sec->compressed_name;
657d0d47 15434
d85bf2ba
NC
15435 if (load_specific_debug_section (id, section, filedata))
15436 {
15437 /* If this debug section is part of a CU/TU set in a .dwp file,
15438 restrict load_debug_section to the sections in that set. */
15439 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 15440
d85bf2ba 15441 result &= display->display (sec, filedata);
657d0d47 15442
d85bf2ba 15443 section_subset = NULL;
1007acb3 15444
d85bf2ba
NC
15445 if (secondary || (id != info && id != abbrev))
15446 free_debug_section (id);
15447 }
15448 break;
15449 }
15450 }
1007acb3 15451
19e6b90e 15452 if (i == max)
1007acb3 15453 {
74e1a04b 15454 printf (_("Unrecognized debug section: %s\n"), print_name);
32ec8896 15455 result = FALSE;
1007acb3
L
15456 }
15457
19e6b90e 15458 return result;
5b18a4bc 15459}
103f02d3 15460
aef1f6d0
DJ
15461/* Set DUMP_SECTS for all sections where dumps were requested
15462 based on section name. */
15463
15464static void
dda8d76d 15465initialise_dumps_byname (Filedata * filedata)
aef1f6d0 15466{
2cf0635d 15467 struct dump_list_entry * cur;
aef1f6d0
DJ
15468
15469 for (cur = dump_sects_byname; cur; cur = cur->next)
15470 {
15471 unsigned int i;
32ec8896 15472 bfd_boolean any = FALSE;
aef1f6d0 15473
dda8d76d 15474 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
15475 if (SECTION_NAME_VALID (filedata->section_headers + i)
15476 && streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 15477 {
6431e409 15478 request_dump_bynumber (&filedata->dump, i, cur->type);
32ec8896 15479 any = TRUE;
aef1f6d0
DJ
15480 }
15481
15482 if (!any)
ca0e11aa
NC
15483 {
15484 if (filedata->is_separate)
15485 warn (_("Section '%s' in linked file '%s' was not dumped because it does not exist\n"),
15486 cur->name, filedata->file_name);
15487 else
15488 warn (_("Section '%s' was not dumped because it does not exist\n"),
15489 cur->name);
15490 }
aef1f6d0
DJ
15491 }
15492}
15493
32ec8896 15494static bfd_boolean
dda8d76d 15495process_section_contents (Filedata * filedata)
5b18a4bc 15496{
2cf0635d 15497 Elf_Internal_Shdr * section;
19e6b90e 15498 unsigned int i;
32ec8896 15499 bfd_boolean res = TRUE;
103f02d3 15500
19e6b90e 15501 if (! do_dump)
32ec8896 15502 return TRUE;
103f02d3 15503
dda8d76d 15504 initialise_dumps_byname (filedata);
aef1f6d0 15505
dda8d76d 15506 for (i = 0, section = filedata->section_headers;
6431e409 15507 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
15508 i++, section++)
15509 {
6431e409 15510 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 15511
19e6b90e 15512#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
15513 if (dump & DISASS_DUMP)
15514 {
15515 if (! disassemble_section (section, filedata))
15516 res = FALSE;
15517 }
19e6b90e 15518#endif
dda8d76d 15519 if (dump & HEX_DUMP)
32ec8896 15520 {
dda8d76d 15521 if (! dump_section_as_bytes (section, filedata, FALSE))
32ec8896
NC
15522 res = FALSE;
15523 }
103f02d3 15524
dda8d76d 15525 if (dump & RELOC_DUMP)
32ec8896 15526 {
dda8d76d 15527 if (! dump_section_as_bytes (section, filedata, TRUE))
32ec8896
NC
15528 res = FALSE;
15529 }
09c11c86 15530
dda8d76d 15531 if (dump & STRING_DUMP)
32ec8896 15532 {
dda8d76d 15533 if (! dump_section_as_strings (section, filedata))
32ec8896
NC
15534 res = FALSE;
15535 }
cf13d699 15536
dda8d76d 15537 if (dump & DEBUG_DUMP)
32ec8896 15538 {
dda8d76d 15539 if (! display_debug_section (i, section, filedata))
32ec8896
NC
15540 res = FALSE;
15541 }
7d9813f1 15542
094e34f2 15543#ifdef ENABLE_LIBCTF
7d9813f1
NA
15544 if (dump & CTF_DUMP)
15545 {
15546 if (! dump_section_as_ctf (section, filedata))
15547 res = FALSE;
15548 }
094e34f2 15549#endif
5b18a4bc 15550 }
103f02d3 15551
19e6b90e
L
15552 /* Check to see if the user requested a
15553 dump of a section that does not exist. */
6431e409 15554 while (i < filedata->dump.num_dump_sects)
0ee3043f 15555 {
6431e409 15556 if (filedata->dump.dump_sects[i])
32ec8896 15557 {
ca0e11aa
NC
15558 if (filedata->is_separate)
15559 warn (_("Section %d in linked file '%s' was not dumped because it does not exist!\n"),
15560 i, filedata->file_name);
15561 else
15562 warn (_("Section %d was not dumped because it does not exist!\n"), i);
32ec8896
NC
15563 res = FALSE;
15564 }
0ee3043f
NC
15565 i++;
15566 }
32ec8896
NC
15567
15568 return res;
5b18a4bc 15569}
103f02d3 15570
5b18a4bc 15571static void
19e6b90e 15572process_mips_fpe_exception (int mask)
5b18a4bc 15573{
19e6b90e
L
15574 if (mask)
15575 {
32ec8896
NC
15576 bfd_boolean first = TRUE;
15577
19e6b90e 15578 if (mask & OEX_FPU_INEX)
32ec8896 15579 fputs ("INEX", stdout), first = FALSE;
19e6b90e 15580 if (mask & OEX_FPU_UFLO)
32ec8896 15581 printf ("%sUFLO", first ? "" : "|"), first = FALSE;
19e6b90e 15582 if (mask & OEX_FPU_OFLO)
32ec8896 15583 printf ("%sOFLO", first ? "" : "|"), first = FALSE;
19e6b90e 15584 if (mask & OEX_FPU_DIV0)
32ec8896 15585 printf ("%sDIV0", first ? "" : "|"), first = FALSE;
19e6b90e
L
15586 if (mask & OEX_FPU_INVAL)
15587 printf ("%sINVAL", first ? "" : "|");
15588 }
5b18a4bc 15589 else
19e6b90e 15590 fputs ("0", stdout);
5b18a4bc 15591}
103f02d3 15592
f6f0e17b
NC
15593/* Display's the value of TAG at location P. If TAG is
15594 greater than 0 it is assumed to be an unknown tag, and
15595 a message is printed to this effect. Otherwise it is
15596 assumed that a message has already been printed.
15597
15598 If the bottom bit of TAG is set it assumed to have a
15599 string value, otherwise it is assumed to have an integer
15600 value.
15601
15602 Returns an updated P pointing to the first unread byte
15603 beyond the end of TAG's value.
15604
15605 Reads at or beyond END will not be made. */
15606
15607static unsigned char *
60abdbed 15608display_tag_value (signed int tag,
f6f0e17b
NC
15609 unsigned char * p,
15610 const unsigned char * const end)
15611{
15612 unsigned long val;
15613
15614 if (tag > 0)
15615 printf (" Tag_unknown_%d: ", tag);
15616
15617 if (p >= end)
15618 {
4082ef84 15619 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
15620 }
15621 else if (tag & 1)
15622 {
071436c6
NC
15623 /* PR 17531 file: 027-19978-0.004. */
15624 size_t maxlen = (end - p) - 1;
15625
15626 putchar ('"');
4082ef84
NC
15627 if (maxlen > 0)
15628 {
15629 print_symbol ((int) maxlen, (const char *) p);
15630 p += strnlen ((char *) p, maxlen) + 1;
15631 }
15632 else
15633 {
15634 printf (_("<corrupt string tag>"));
15635 p = (unsigned char *) end;
15636 }
071436c6 15637 printf ("\"\n");
f6f0e17b
NC
15638 }
15639 else
15640 {
cd30bcef 15641 READ_ULEB (val, p, end);
f6f0e17b
NC
15642 printf ("%ld (0x%lx)\n", val, val);
15643 }
15644
4082ef84 15645 assert (p <= end);
f6f0e17b
NC
15646 return p;
15647}
15648
53a346d8
CZ
15649/* ARC ABI attributes section. */
15650
15651static unsigned char *
15652display_arc_attribute (unsigned char * p,
15653 const unsigned char * const end)
15654{
15655 unsigned int tag;
53a346d8
CZ
15656 unsigned int val;
15657
cd30bcef 15658 READ_ULEB (tag, p, end);
53a346d8
CZ
15659
15660 switch (tag)
15661 {
15662 case Tag_ARC_PCS_config:
cd30bcef 15663 READ_ULEB (val, p, end);
53a346d8
CZ
15664 printf (" Tag_ARC_PCS_config: ");
15665 switch (val)
15666 {
15667 case 0:
15668 printf (_("Absent/Non standard\n"));
15669 break;
15670 case 1:
15671 printf (_("Bare metal/mwdt\n"));
15672 break;
15673 case 2:
15674 printf (_("Bare metal/newlib\n"));
15675 break;
15676 case 3:
15677 printf (_("Linux/uclibc\n"));
15678 break;
15679 case 4:
15680 printf (_("Linux/glibc\n"));
15681 break;
15682 default:
15683 printf (_("Unknown\n"));
15684 break;
15685 }
15686 break;
15687
15688 case Tag_ARC_CPU_base:
cd30bcef 15689 READ_ULEB (val, p, end);
53a346d8
CZ
15690 printf (" Tag_ARC_CPU_base: ");
15691 switch (val)
15692 {
15693 default:
15694 case TAG_CPU_NONE:
15695 printf (_("Absent\n"));
15696 break;
15697 case TAG_CPU_ARC6xx:
15698 printf ("ARC6xx\n");
15699 break;
15700 case TAG_CPU_ARC7xx:
15701 printf ("ARC7xx\n");
15702 break;
15703 case TAG_CPU_ARCEM:
15704 printf ("ARCEM\n");
15705 break;
15706 case TAG_CPU_ARCHS:
15707 printf ("ARCHS\n");
15708 break;
15709 }
15710 break;
15711
15712 case Tag_ARC_CPU_variation:
cd30bcef 15713 READ_ULEB (val, p, end);
53a346d8
CZ
15714 printf (" Tag_ARC_CPU_variation: ");
15715 switch (val)
15716 {
15717 default:
15718 if (val > 0 && val < 16)
53a346d8 15719 printf ("Core%d\n", val);
d8cbc93b
JL
15720 else
15721 printf ("Unknown\n");
15722 break;
15723
53a346d8
CZ
15724 case 0:
15725 printf (_("Absent\n"));
15726 break;
15727 }
15728 break;
15729
15730 case Tag_ARC_CPU_name:
15731 printf (" Tag_ARC_CPU_name: ");
15732 p = display_tag_value (-1, p, end);
15733 break;
15734
15735 case Tag_ARC_ABI_rf16:
cd30bcef 15736 READ_ULEB (val, p, end);
53a346d8
CZ
15737 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
15738 break;
15739
15740 case Tag_ARC_ABI_osver:
cd30bcef 15741 READ_ULEB (val, p, end);
53a346d8
CZ
15742 printf (" Tag_ARC_ABI_osver: v%d\n", val);
15743 break;
15744
15745 case Tag_ARC_ABI_pic:
15746 case Tag_ARC_ABI_sda:
cd30bcef 15747 READ_ULEB (val, p, end);
53a346d8
CZ
15748 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
15749 : " Tag_ARC_ABI_pic: ");
15750 switch (val)
15751 {
15752 case 0:
15753 printf (_("Absent\n"));
15754 break;
15755 case 1:
15756 printf ("MWDT\n");
15757 break;
15758 case 2:
15759 printf ("GNU\n");
15760 break;
15761 default:
15762 printf (_("Unknown\n"));
15763 break;
15764 }
15765 break;
15766
15767 case Tag_ARC_ABI_tls:
cd30bcef 15768 READ_ULEB (val, p, end);
53a346d8
CZ
15769 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
15770 break;
15771
15772 case Tag_ARC_ABI_enumsize:
cd30bcef 15773 READ_ULEB (val, p, end);
53a346d8
CZ
15774 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
15775 _("smallest"));
15776 break;
15777
15778 case Tag_ARC_ABI_exceptions:
cd30bcef 15779 READ_ULEB (val, p, end);
53a346d8
CZ
15780 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
15781 : _("default"));
15782 break;
15783
15784 case Tag_ARC_ABI_double_size:
cd30bcef 15785 READ_ULEB (val, p, end);
53a346d8
CZ
15786 printf (" Tag_ARC_ABI_double_size: %d\n", val);
15787 break;
15788
15789 case Tag_ARC_ISA_config:
15790 printf (" Tag_ARC_ISA_config: ");
15791 p = display_tag_value (-1, p, end);
15792 break;
15793
15794 case Tag_ARC_ISA_apex:
15795 printf (" Tag_ARC_ISA_apex: ");
15796 p = display_tag_value (-1, p, end);
15797 break;
15798
15799 case Tag_ARC_ISA_mpy_option:
cd30bcef 15800 READ_ULEB (val, p, end);
53a346d8
CZ
15801 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
15802 break;
15803
db1e1b45 15804 case Tag_ARC_ATR_version:
cd30bcef 15805 READ_ULEB (val, p, end);
db1e1b45 15806 printf (" Tag_ARC_ATR_version: %d\n", val);
15807 break;
15808
53a346d8
CZ
15809 default:
15810 return display_tag_value (tag & 1, p, end);
15811 }
15812
15813 return p;
15814}
15815
11c1ff18
PB
15816/* ARM EABI attributes section. */
15817typedef struct
15818{
70e99720 15819 unsigned int tag;
2cf0635d 15820 const char * name;
11c1ff18 15821 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 15822 unsigned int type;
288f0ba2 15823 const char *const *table;
11c1ff18
PB
15824} arm_attr_public_tag;
15825
288f0ba2 15826static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 15827 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 15828 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 15829 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
288f0ba2
AM
15830static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
15831static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 15832 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 15833static const char *const arm_attr_tag_FP_arch[] =
bca38921 15834 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 15835 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
15836static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
15837static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
15838 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
15839 "NEON for ARMv8.1"};
288f0ba2 15840static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
15841 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
15842 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 15843static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 15844 {"V6", "SB", "TLS", "Unused"};
288f0ba2 15845static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 15846 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 15847static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 15848 {"Absolute", "PC-relative", "None"};
288f0ba2 15849static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 15850 {"None", "direct", "GOT-indirect"};
288f0ba2 15851static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 15852 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
15853static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
15854static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 15855 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
15856static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
15857static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
15858static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 15859 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 15860static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 15861 {"Unused", "small", "int", "forced to int"};
288f0ba2 15862static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 15863 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 15864static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 15865 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 15866static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 15867 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 15868static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
15869 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15870 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 15871static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
15872 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15873 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
15874static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
15875static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 15876 {"Not Allowed", "Allowed"};
288f0ba2 15877static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 15878 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 15879static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 15880 {"Follow architecture", "Allowed"};
288f0ba2 15881static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 15882 {"Not Allowed", "Allowed"};
288f0ba2 15883static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 15884 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 15885 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
15886static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
15887static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 15888 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 15889 "TrustZone and Virtualization Extensions"};
288f0ba2 15890static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 15891 {"Not Allowed", "Allowed"};
11c1ff18 15892
288f0ba2 15893static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
15894 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
15895
11c1ff18
PB
15896#define LOOKUP(id, name) \
15897 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 15898static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
15899{
15900 {4, "CPU_raw_name", 1, NULL},
15901 {5, "CPU_name", 1, NULL},
15902 LOOKUP(6, CPU_arch),
15903 {7, "CPU_arch_profile", 0, NULL},
15904 LOOKUP(8, ARM_ISA_use),
15905 LOOKUP(9, THUMB_ISA_use),
75375b3e 15906 LOOKUP(10, FP_arch),
11c1ff18 15907 LOOKUP(11, WMMX_arch),
f5f53991
AS
15908 LOOKUP(12, Advanced_SIMD_arch),
15909 LOOKUP(13, PCS_config),
11c1ff18
PB
15910 LOOKUP(14, ABI_PCS_R9_use),
15911 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 15912 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
15913 LOOKUP(17, ABI_PCS_GOT_use),
15914 LOOKUP(18, ABI_PCS_wchar_t),
15915 LOOKUP(19, ABI_FP_rounding),
15916 LOOKUP(20, ABI_FP_denormal),
15917 LOOKUP(21, ABI_FP_exceptions),
15918 LOOKUP(22, ABI_FP_user_exceptions),
15919 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
15920 {24, "ABI_align_needed", 0, NULL},
15921 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
15922 LOOKUP(26, ABI_enum_size),
15923 LOOKUP(27, ABI_HardFP_use),
15924 LOOKUP(28, ABI_VFP_args),
15925 LOOKUP(29, ABI_WMMX_args),
15926 LOOKUP(30, ABI_optimization_goals),
15927 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 15928 {32, "compatibility", 0, NULL},
f5f53991 15929 LOOKUP(34, CPU_unaligned_access),
75375b3e 15930 LOOKUP(36, FP_HP_extension),
8e79c3df 15931 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
15932 LOOKUP(42, MPextension_use),
15933 LOOKUP(44, DIV_use),
15afaa63 15934 LOOKUP(46, DSP_extension),
a7ad558c 15935 LOOKUP(48, MVE_arch),
f5f53991
AS
15936 {64, "nodefaults", 0, NULL},
15937 {65, "also_compatible_with", 0, NULL},
15938 LOOKUP(66, T2EE_use),
15939 {67, "conformance", 1, NULL},
15940 LOOKUP(68, Virtualization_use),
cd21e546 15941 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
15942};
15943#undef LOOKUP
15944
11c1ff18 15945static unsigned char *
f6f0e17b
NC
15946display_arm_attribute (unsigned char * p,
15947 const unsigned char * const end)
11c1ff18 15948{
70e99720 15949 unsigned int tag;
70e99720 15950 unsigned int val;
2cf0635d 15951 arm_attr_public_tag * attr;
11c1ff18 15952 unsigned i;
70e99720 15953 unsigned int type;
11c1ff18 15954
cd30bcef 15955 READ_ULEB (tag, p, end);
11c1ff18 15956 attr = NULL;
2cf0635d 15957 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
15958 {
15959 if (arm_attr_public_tags[i].tag == tag)
15960 {
15961 attr = &arm_attr_public_tags[i];
15962 break;
15963 }
15964 }
15965
15966 if (attr)
15967 {
15968 printf (" Tag_%s: ", attr->name);
15969 switch (attr->type)
15970 {
15971 case 0:
15972 switch (tag)
15973 {
15974 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 15975 READ_ULEB (val, p, end);
11c1ff18
PB
15976 switch (val)
15977 {
2b692964
NC
15978 case 0: printf (_("None\n")); break;
15979 case 'A': printf (_("Application\n")); break;
15980 case 'R': printf (_("Realtime\n")); break;
15981 case 'M': printf (_("Microcontroller\n")); break;
15982 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
15983 default: printf ("??? (%d)\n", val); break;
15984 }
15985 break;
15986
75375b3e 15987 case 24: /* Tag_align_needed. */
cd30bcef 15988 READ_ULEB (val, p, end);
75375b3e
MGD
15989 switch (val)
15990 {
2b692964
NC
15991 case 0: printf (_("None\n")); break;
15992 case 1: printf (_("8-byte\n")); break;
15993 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
15994 case 3: printf ("??? 3\n"); break;
15995 default:
15996 if (val <= 12)
dd24e3da 15997 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15998 1 << val);
15999 else
16000 printf ("??? (%d)\n", val);
16001 break;
16002 }
16003 break;
16004
16005 case 25: /* Tag_align_preserved. */
cd30bcef 16006 READ_ULEB (val, p, end);
75375b3e
MGD
16007 switch (val)
16008 {
2b692964
NC
16009 case 0: printf (_("None\n")); break;
16010 case 1: printf (_("8-byte, except leaf SP\n")); break;
16011 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16012 case 3: printf ("??? 3\n"); break;
16013 default:
16014 if (val <= 12)
dd24e3da 16015 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16016 1 << val);
16017 else
16018 printf ("??? (%d)\n", val);
16019 break;
16020 }
16021 break;
16022
11c1ff18 16023 case 32: /* Tag_compatibility. */
071436c6 16024 {
cd30bcef 16025 READ_ULEB (val, p, end);
071436c6 16026 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16027 if (p < end - 1)
16028 {
16029 size_t maxlen = (end - p) - 1;
16030
16031 print_symbol ((int) maxlen, (const char *) p);
16032 p += strnlen ((char *) p, maxlen) + 1;
16033 }
16034 else
16035 {
16036 printf (_("<corrupt>"));
16037 p = (unsigned char *) end;
16038 }
071436c6 16039 putchar ('\n');
071436c6 16040 }
11c1ff18
PB
16041 break;
16042
f5f53991 16043 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16044 /* PR 17531: file: 001-505008-0.01. */
16045 if (p < end)
16046 p++;
2b692964 16047 printf (_("True\n"));
f5f53991
AS
16048 break;
16049
16050 case 65: /* Tag_also_compatible_with. */
cd30bcef 16051 READ_ULEB (val, p, end);
f5f53991
AS
16052 if (val == 6 /* Tag_CPU_arch. */)
16053 {
cd30bcef 16054 READ_ULEB (val, p, end);
071436c6 16055 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16056 printf ("??? (%d)\n", val);
16057 else
16058 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16059 }
16060 else
16061 printf ("???\n");
071436c6
NC
16062 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16063 ;
f5f53991
AS
16064 break;
16065
11c1ff18 16066 default:
bee0ee85
NC
16067 printf (_("<unknown: %d>\n"), tag);
16068 break;
11c1ff18
PB
16069 }
16070 return p;
16071
16072 case 1:
f6f0e17b 16073 return display_tag_value (-1, p, end);
11c1ff18 16074 case 2:
f6f0e17b 16075 return display_tag_value (0, p, end);
11c1ff18
PB
16076
16077 default:
16078 assert (attr->type & 0x80);
cd30bcef 16079 READ_ULEB (val, p, end);
11c1ff18
PB
16080 type = attr->type & 0x7f;
16081 if (val >= type)
16082 printf ("??? (%d)\n", val);
16083 else
16084 printf ("%s\n", attr->table[val]);
16085 return p;
16086 }
16087 }
11c1ff18 16088
f6f0e17b 16089 return display_tag_value (tag, p, end);
11c1ff18
PB
16090}
16091
104d59d1 16092static unsigned char *
60bca95a 16093display_gnu_attribute (unsigned char * p,
60abdbed 16094 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16095 const unsigned char * const end)
104d59d1 16096{
cd30bcef 16097 unsigned int tag;
60abdbed 16098 unsigned int val;
104d59d1 16099
cd30bcef 16100 READ_ULEB (tag, p, end);
104d59d1
JM
16101
16102 /* Tag_compatibility is the only generic GNU attribute defined at
16103 present. */
16104 if (tag == 32)
16105 {
cd30bcef 16106 READ_ULEB (val, p, end);
071436c6
NC
16107
16108 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16109 if (p == end)
16110 {
071436c6 16111 printf (_("<corrupt>\n"));
f6f0e17b
NC
16112 warn (_("corrupt vendor attribute\n"));
16113 }
16114 else
16115 {
4082ef84
NC
16116 if (p < end - 1)
16117 {
16118 size_t maxlen = (end - p) - 1;
071436c6 16119
4082ef84
NC
16120 print_symbol ((int) maxlen, (const char *) p);
16121 p += strnlen ((char *) p, maxlen) + 1;
16122 }
16123 else
16124 {
16125 printf (_("<corrupt>"));
16126 p = (unsigned char *) end;
16127 }
071436c6 16128 putchar ('\n');
f6f0e17b 16129 }
104d59d1
JM
16130 return p;
16131 }
16132
16133 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16134 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16135
f6f0e17b 16136 return display_tag_value (tag, p, end);
104d59d1
JM
16137}
16138
85f7484a
PB
16139static unsigned char *
16140display_m68k_gnu_attribute (unsigned char * p,
16141 unsigned int tag,
16142 const unsigned char * const end)
16143{
16144 unsigned int val;
16145
16146 if (tag == Tag_GNU_M68K_ABI_FP)
16147 {
16148 printf (" Tag_GNU_M68K_ABI_FP: ");
16149 if (p == end)
16150 {
16151 printf (_("<corrupt>\n"));
16152 return p;
16153 }
16154 READ_ULEB (val, p, end);
16155
16156 if (val > 3)
16157 printf ("(%#x), ", val);
16158
16159 switch (val & 3)
16160 {
16161 case 0:
16162 printf (_("unspecified hard/soft float\n"));
16163 break;
16164 case 1:
16165 printf (_("hard float\n"));
16166 break;
16167 case 2:
16168 printf (_("soft float\n"));
16169 break;
16170 }
16171 return p;
16172 }
16173
16174 return display_tag_value (tag & 1, p, end);
16175}
16176
34c8bcba 16177static unsigned char *
f6f0e17b 16178display_power_gnu_attribute (unsigned char * p,
60abdbed 16179 unsigned int tag,
f6f0e17b 16180 const unsigned char * const end)
34c8bcba 16181{
005d79fd 16182 unsigned int val;
34c8bcba
JM
16183
16184 if (tag == Tag_GNU_Power_ABI_FP)
16185 {
34c8bcba 16186 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16187 if (p == end)
005d79fd
AM
16188 {
16189 printf (_("<corrupt>\n"));
16190 return p;
16191 }
cd30bcef 16192 READ_ULEB (val, p, end);
60bca95a 16193
005d79fd
AM
16194 if (val > 15)
16195 printf ("(%#x), ", val);
16196
16197 switch (val & 3)
34c8bcba
JM
16198 {
16199 case 0:
005d79fd 16200 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16201 break;
16202 case 1:
005d79fd 16203 printf (_("hard float, "));
34c8bcba
JM
16204 break;
16205 case 2:
005d79fd 16206 printf (_("soft float, "));
34c8bcba 16207 break;
3c7b9897 16208 case 3:
005d79fd 16209 printf (_("single-precision hard float, "));
3c7b9897 16210 break;
005d79fd
AM
16211 }
16212
16213 switch (val & 0xC)
16214 {
16215 case 0:
16216 printf (_("unspecified long double\n"));
16217 break;
16218 case 4:
16219 printf (_("128-bit IBM long double\n"));
16220 break;
16221 case 8:
16222 printf (_("64-bit long double\n"));
16223 break;
16224 case 12:
16225 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16226 break;
16227 }
16228 return p;
005d79fd 16229 }
34c8bcba 16230
c6e65352
DJ
16231 if (tag == Tag_GNU_Power_ABI_Vector)
16232 {
c6e65352 16233 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 16234 if (p == end)
005d79fd
AM
16235 {
16236 printf (_("<corrupt>\n"));
16237 return p;
16238 }
cd30bcef 16239 READ_ULEB (val, p, end);
005d79fd
AM
16240
16241 if (val > 3)
16242 printf ("(%#x), ", val);
16243
16244 switch (val & 3)
c6e65352
DJ
16245 {
16246 case 0:
005d79fd 16247 printf (_("unspecified\n"));
c6e65352
DJ
16248 break;
16249 case 1:
005d79fd 16250 printf (_("generic\n"));
c6e65352
DJ
16251 break;
16252 case 2:
16253 printf ("AltiVec\n");
16254 break;
16255 case 3:
16256 printf ("SPE\n");
16257 break;
c6e65352
DJ
16258 }
16259 return p;
005d79fd 16260 }
c6e65352 16261
f82e0623
NF
16262 if (tag == Tag_GNU_Power_ABI_Struct_Return)
16263 {
005d79fd 16264 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 16265 if (p == end)
f6f0e17b 16266 {
005d79fd 16267 printf (_("<corrupt>\n"));
f6f0e17b
NC
16268 return p;
16269 }
cd30bcef 16270 READ_ULEB (val, p, end);
0b4362b0 16271
005d79fd
AM
16272 if (val > 2)
16273 printf ("(%#x), ", val);
16274
16275 switch (val & 3)
16276 {
16277 case 0:
16278 printf (_("unspecified\n"));
16279 break;
16280 case 1:
16281 printf ("r3/r4\n");
16282 break;
16283 case 2:
16284 printf (_("memory\n"));
16285 break;
16286 case 3:
16287 printf ("???\n");
16288 break;
16289 }
f82e0623
NF
16290 return p;
16291 }
16292
f6f0e17b 16293 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
16294}
16295
643f7afb
AK
16296static unsigned char *
16297display_s390_gnu_attribute (unsigned char * p,
60abdbed 16298 unsigned int tag,
643f7afb
AK
16299 const unsigned char * const end)
16300{
cd30bcef 16301 unsigned int val;
643f7afb
AK
16302
16303 if (tag == Tag_GNU_S390_ABI_Vector)
16304 {
643f7afb 16305 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 16306 READ_ULEB (val, p, end);
643f7afb
AK
16307
16308 switch (val)
16309 {
16310 case 0:
16311 printf (_("any\n"));
16312 break;
16313 case 1:
16314 printf (_("software\n"));
16315 break;
16316 case 2:
16317 printf (_("hardware\n"));
16318 break;
16319 default:
16320 printf ("??? (%d)\n", val);
16321 break;
16322 }
16323 return p;
16324 }
16325
16326 return display_tag_value (tag & 1, p, end);
16327}
16328
9e8c70f9 16329static void
60abdbed 16330display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
16331{
16332 if (mask)
16333 {
32ec8896 16334 bfd_boolean first = TRUE;
071436c6 16335
9e8c70f9 16336 if (mask & ELF_SPARC_HWCAP_MUL32)
32ec8896 16337 fputs ("mul32", stdout), first = FALSE;
9e8c70f9 16338 if (mask & ELF_SPARC_HWCAP_DIV32)
32ec8896 16339 printf ("%sdiv32", first ? "" : "|"), first = FALSE;
9e8c70f9 16340 if (mask & ELF_SPARC_HWCAP_FSMULD)
32ec8896 16341 printf ("%sfsmuld", first ? "" : "|"), first = FALSE;
9e8c70f9 16342 if (mask & ELF_SPARC_HWCAP_V8PLUS)
32ec8896 16343 printf ("%sv8plus", first ? "" : "|"), first = FALSE;
9e8c70f9 16344 if (mask & ELF_SPARC_HWCAP_POPC)
32ec8896 16345 printf ("%spopc", first ? "" : "|"), first = FALSE;
9e8c70f9 16346 if (mask & ELF_SPARC_HWCAP_VIS)
32ec8896 16347 printf ("%svis", first ? "" : "|"), first = FALSE;
9e8c70f9 16348 if (mask & ELF_SPARC_HWCAP_VIS2)
32ec8896 16349 printf ("%svis2", first ? "" : "|"), first = FALSE;
9e8c70f9 16350 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
32ec8896 16351 printf ("%sASIBlkInit", first ? "" : "|"), first = FALSE;
9e8c70f9 16352 if (mask & ELF_SPARC_HWCAP_FMAF)
32ec8896 16353 printf ("%sfmaf", first ? "" : "|"), first = FALSE;
9e8c70f9 16354 if (mask & ELF_SPARC_HWCAP_VIS3)
32ec8896 16355 printf ("%svis3", first ? "" : "|"), first = FALSE;
9e8c70f9 16356 if (mask & ELF_SPARC_HWCAP_HPC)
32ec8896 16357 printf ("%shpc", first ? "" : "|"), first = FALSE;
9e8c70f9 16358 if (mask & ELF_SPARC_HWCAP_RANDOM)
32ec8896 16359 printf ("%srandom", first ? "" : "|"), first = FALSE;
9e8c70f9 16360 if (mask & ELF_SPARC_HWCAP_TRANS)
32ec8896 16361 printf ("%strans", first ? "" : "|"), first = FALSE;
9e8c70f9 16362 if (mask & ELF_SPARC_HWCAP_FJFMAU)
32ec8896 16363 printf ("%sfjfmau", first ? "" : "|"), first = FALSE;
9e8c70f9 16364 if (mask & ELF_SPARC_HWCAP_IMA)
32ec8896 16365 printf ("%sima", first ? "" : "|"), first = FALSE;
9e8c70f9 16366 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
32ec8896 16367 printf ("%scspare", first ? "" : "|"), first = FALSE;
9e8c70f9
DM
16368 }
16369 else
071436c6
NC
16370 fputc ('0', stdout);
16371 fputc ('\n', stdout);
9e8c70f9
DM
16372}
16373
3d68f91c 16374static void
60abdbed 16375display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
16376{
16377 if (mask)
16378 {
32ec8896 16379 bfd_boolean first = TRUE;
071436c6 16380
3d68f91c 16381 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
32ec8896 16382 fputs ("fjathplus", stdout), first = FALSE;
3d68f91c 16383 if (mask & ELF_SPARC_HWCAP2_VIS3B)
32ec8896 16384 printf ("%svis3b", first ? "" : "|"), first = FALSE;
3d68f91c 16385 if (mask & ELF_SPARC_HWCAP2_ADP)
32ec8896 16386 printf ("%sadp", first ? "" : "|"), first = FALSE;
3d68f91c 16387 if (mask & ELF_SPARC_HWCAP2_SPARC5)
32ec8896 16388 printf ("%ssparc5", first ? "" : "|"), first = FALSE;
3d68f91c 16389 if (mask & ELF_SPARC_HWCAP2_MWAIT)
32ec8896 16390 printf ("%smwait", first ? "" : "|"), first = FALSE;
3d68f91c 16391 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
32ec8896 16392 printf ("%sxmpmul", first ? "" : "|"), first = FALSE;
3d68f91c 16393 if (mask & ELF_SPARC_HWCAP2_XMONT)
32ec8896 16394 printf ("%sxmont2", first ? "" : "|"), first = FALSE;
3d68f91c 16395 if (mask & ELF_SPARC_HWCAP2_NSEC)
32ec8896 16396 printf ("%snsec", first ? "" : "|"), first = FALSE;
3d68f91c 16397 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
32ec8896 16398 printf ("%sfjathhpc", first ? "" : "|"), first = FALSE;
3d68f91c 16399 if (mask & ELF_SPARC_HWCAP2_FJDES)
32ec8896 16400 printf ("%sfjdes", first ? "" : "|"), first = FALSE;
3d68f91c 16401 if (mask & ELF_SPARC_HWCAP2_FJAES)
32ec8896 16402 printf ("%sfjaes", first ? "" : "|"), first = FALSE;
3d68f91c
JM
16403 }
16404 else
071436c6
NC
16405 fputc ('0', stdout);
16406 fputc ('\n', stdout);
3d68f91c
JM
16407}
16408
9e8c70f9 16409static unsigned char *
f6f0e17b 16410display_sparc_gnu_attribute (unsigned char * p,
60abdbed 16411 unsigned int tag,
f6f0e17b 16412 const unsigned char * const end)
9e8c70f9 16413{
cd30bcef 16414 unsigned int val;
3d68f91c 16415
9e8c70f9
DM
16416 if (tag == Tag_GNU_Sparc_HWCAPS)
16417 {
cd30bcef 16418 READ_ULEB (val, p, end);
9e8c70f9 16419 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
16420 display_sparc_hwcaps (val);
16421 return p;
3d68f91c
JM
16422 }
16423 if (tag == Tag_GNU_Sparc_HWCAPS2)
16424 {
cd30bcef 16425 READ_ULEB (val, p, end);
3d68f91c
JM
16426 printf (" Tag_GNU_Sparc_HWCAPS2: ");
16427 display_sparc_hwcaps2 (val);
16428 return p;
16429 }
9e8c70f9 16430
f6f0e17b 16431 return display_tag_value (tag, p, end);
9e8c70f9
DM
16432}
16433
351cdf24 16434static void
32ec8896 16435print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
16436{
16437 switch (val)
16438 {
16439 case Val_GNU_MIPS_ABI_FP_ANY:
16440 printf (_("Hard or soft float\n"));
16441 break;
16442 case Val_GNU_MIPS_ABI_FP_DOUBLE:
16443 printf (_("Hard float (double precision)\n"));
16444 break;
16445 case Val_GNU_MIPS_ABI_FP_SINGLE:
16446 printf (_("Hard float (single precision)\n"));
16447 break;
16448 case Val_GNU_MIPS_ABI_FP_SOFT:
16449 printf (_("Soft float\n"));
16450 break;
16451 case Val_GNU_MIPS_ABI_FP_OLD_64:
16452 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
16453 break;
16454 case Val_GNU_MIPS_ABI_FP_XX:
16455 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
16456 break;
16457 case Val_GNU_MIPS_ABI_FP_64:
16458 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
16459 break;
16460 case Val_GNU_MIPS_ABI_FP_64A:
16461 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
16462 break;
3350cc01
CM
16463 case Val_GNU_MIPS_ABI_FP_NAN2008:
16464 printf (_("NaN 2008 compatibility\n"));
16465 break;
351cdf24
MF
16466 default:
16467 printf ("??? (%d)\n", val);
16468 break;
16469 }
16470}
16471
2cf19d5c 16472static unsigned char *
f6f0e17b 16473display_mips_gnu_attribute (unsigned char * p,
60abdbed 16474 unsigned int tag,
f6f0e17b 16475 const unsigned char * const end)
2cf19d5c 16476{
2cf19d5c
JM
16477 if (tag == Tag_GNU_MIPS_ABI_FP)
16478 {
32ec8896 16479 unsigned int val;
f6f0e17b 16480
2cf19d5c 16481 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 16482 READ_ULEB (val, p, end);
351cdf24 16483 print_mips_fp_abi_value (val);
2cf19d5c
JM
16484 return p;
16485 }
16486
a9f58168
CF
16487 if (tag == Tag_GNU_MIPS_ABI_MSA)
16488 {
32ec8896 16489 unsigned int val;
a9f58168 16490
a9f58168 16491 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 16492 READ_ULEB (val, p, end);
a9f58168
CF
16493
16494 switch (val)
16495 {
16496 case Val_GNU_MIPS_ABI_MSA_ANY:
16497 printf (_("Any MSA or not\n"));
16498 break;
16499 case Val_GNU_MIPS_ABI_MSA_128:
16500 printf (_("128-bit MSA\n"));
16501 break;
16502 default:
16503 printf ("??? (%d)\n", val);
16504 break;
16505 }
16506 return p;
16507 }
16508
f6f0e17b 16509 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
16510}
16511
59e6276b 16512static unsigned char *
f6f0e17b
NC
16513display_tic6x_attribute (unsigned char * p,
16514 const unsigned char * const end)
59e6276b 16515{
60abdbed 16516 unsigned int tag;
cd30bcef 16517 unsigned int val;
59e6276b 16518
cd30bcef 16519 READ_ULEB (tag, p, end);
59e6276b
JM
16520
16521 switch (tag)
16522 {
75fa6dc1 16523 case Tag_ISA:
75fa6dc1 16524 printf (" Tag_ISA: ");
cd30bcef 16525 READ_ULEB (val, p, end);
59e6276b
JM
16526
16527 switch (val)
16528 {
75fa6dc1 16529 case C6XABI_Tag_ISA_none:
59e6276b
JM
16530 printf (_("None\n"));
16531 break;
75fa6dc1 16532 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
16533 printf ("C62x\n");
16534 break;
75fa6dc1 16535 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
16536 printf ("C67x\n");
16537 break;
75fa6dc1 16538 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
16539 printf ("C67x+\n");
16540 break;
75fa6dc1 16541 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
16542 printf ("C64x\n");
16543 break;
75fa6dc1 16544 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
16545 printf ("C64x+\n");
16546 break;
75fa6dc1 16547 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
16548 printf ("C674x\n");
16549 break;
16550 default:
16551 printf ("??? (%d)\n", val);
16552 break;
16553 }
16554 return p;
16555
87779176 16556 case Tag_ABI_wchar_t:
87779176 16557 printf (" Tag_ABI_wchar_t: ");
cd30bcef 16558 READ_ULEB (val, p, end);
87779176
JM
16559 switch (val)
16560 {
16561 case 0:
16562 printf (_("Not used\n"));
16563 break;
16564 case 1:
16565 printf (_("2 bytes\n"));
16566 break;
16567 case 2:
16568 printf (_("4 bytes\n"));
16569 break;
16570 default:
16571 printf ("??? (%d)\n", val);
16572 break;
16573 }
16574 return p;
16575
16576 case Tag_ABI_stack_align_needed:
87779176 16577 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 16578 READ_ULEB (val, p, end);
87779176
JM
16579 switch (val)
16580 {
16581 case 0:
16582 printf (_("8-byte\n"));
16583 break;
16584 case 1:
16585 printf (_("16-byte\n"));
16586 break;
16587 default:
16588 printf ("??? (%d)\n", val);
16589 break;
16590 }
16591 return p;
16592
16593 case Tag_ABI_stack_align_preserved:
cd30bcef 16594 READ_ULEB (val, p, end);
87779176
JM
16595 printf (" Tag_ABI_stack_align_preserved: ");
16596 switch (val)
16597 {
16598 case 0:
16599 printf (_("8-byte\n"));
16600 break;
16601 case 1:
16602 printf (_("16-byte\n"));
16603 break;
16604 default:
16605 printf ("??? (%d)\n", val);
16606 break;
16607 }
16608 return p;
16609
b5593623 16610 case Tag_ABI_DSBT:
cd30bcef 16611 READ_ULEB (val, p, end);
b5593623
JM
16612 printf (" Tag_ABI_DSBT: ");
16613 switch (val)
16614 {
16615 case 0:
16616 printf (_("DSBT addressing not used\n"));
16617 break;
16618 case 1:
16619 printf (_("DSBT addressing used\n"));
16620 break;
16621 default:
16622 printf ("??? (%d)\n", val);
16623 break;
16624 }
16625 return p;
16626
87779176 16627 case Tag_ABI_PID:
cd30bcef 16628 READ_ULEB (val, p, end);
87779176
JM
16629 printf (" Tag_ABI_PID: ");
16630 switch (val)
16631 {
16632 case 0:
16633 printf (_("Data addressing position-dependent\n"));
16634 break;
16635 case 1:
16636 printf (_("Data addressing position-independent, GOT near DP\n"));
16637 break;
16638 case 2:
16639 printf (_("Data addressing position-independent, GOT far from DP\n"));
16640 break;
16641 default:
16642 printf ("??? (%d)\n", val);
16643 break;
16644 }
16645 return p;
16646
16647 case Tag_ABI_PIC:
cd30bcef 16648 READ_ULEB (val, p, end);
87779176
JM
16649 printf (" Tag_ABI_PIC: ");
16650 switch (val)
16651 {
16652 case 0:
16653 printf (_("Code addressing position-dependent\n"));
16654 break;
16655 case 1:
16656 printf (_("Code addressing position-independent\n"));
16657 break;
16658 default:
16659 printf ("??? (%d)\n", val);
16660 break;
16661 }
16662 return p;
16663
16664 case Tag_ABI_array_object_alignment:
cd30bcef 16665 READ_ULEB (val, p, end);
87779176
JM
16666 printf (" Tag_ABI_array_object_alignment: ");
16667 switch (val)
16668 {
16669 case 0:
16670 printf (_("8-byte\n"));
16671 break;
16672 case 1:
16673 printf (_("4-byte\n"));
16674 break;
16675 case 2:
16676 printf (_("16-byte\n"));
16677 break;
16678 default:
16679 printf ("??? (%d)\n", val);
16680 break;
16681 }
16682 return p;
16683
16684 case Tag_ABI_array_object_align_expected:
cd30bcef 16685 READ_ULEB (val, p, end);
87779176
JM
16686 printf (" Tag_ABI_array_object_align_expected: ");
16687 switch (val)
16688 {
16689 case 0:
16690 printf (_("8-byte\n"));
16691 break;
16692 case 1:
16693 printf (_("4-byte\n"));
16694 break;
16695 case 2:
16696 printf (_("16-byte\n"));
16697 break;
16698 default:
16699 printf ("??? (%d)\n", val);
16700 break;
16701 }
16702 return p;
16703
3cbd1c06 16704 case Tag_ABI_compatibility:
071436c6 16705 {
cd30bcef 16706 READ_ULEB (val, p, end);
071436c6 16707 printf (" Tag_ABI_compatibility: ");
071436c6 16708 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16709 if (p < end - 1)
16710 {
16711 size_t maxlen = (end - p) - 1;
16712
16713 print_symbol ((int) maxlen, (const char *) p);
16714 p += strnlen ((char *) p, maxlen) + 1;
16715 }
16716 else
16717 {
16718 printf (_("<corrupt>"));
16719 p = (unsigned char *) end;
16720 }
071436c6 16721 putchar ('\n');
071436c6
NC
16722 return p;
16723 }
87779176
JM
16724
16725 case Tag_ABI_conformance:
071436c6 16726 {
4082ef84
NC
16727 printf (" Tag_ABI_conformance: \"");
16728 if (p < end - 1)
16729 {
16730 size_t maxlen = (end - p) - 1;
071436c6 16731
4082ef84
NC
16732 print_symbol ((int) maxlen, (const char *) p);
16733 p += strnlen ((char *) p, maxlen) + 1;
16734 }
16735 else
16736 {
16737 printf (_("<corrupt>"));
16738 p = (unsigned char *) end;
16739 }
071436c6 16740 printf ("\"\n");
071436c6
NC
16741 return p;
16742 }
59e6276b
JM
16743 }
16744
f6f0e17b
NC
16745 return display_tag_value (tag, p, end);
16746}
59e6276b 16747
f6f0e17b 16748static void
60abdbed 16749display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
16750{
16751 unsigned long addr = 0;
16752 size_t bytes = end - p;
16753
feceaa59 16754 assert (end >= p);
f6f0e17b 16755 while (bytes)
87779176 16756 {
f6f0e17b
NC
16757 int j;
16758 int k;
16759 int lbytes = (bytes > 16 ? 16 : bytes);
16760
16761 printf (" 0x%8.8lx ", addr);
16762
16763 for (j = 0; j < 16; j++)
16764 {
16765 if (j < lbytes)
16766 printf ("%2.2x", p[j]);
16767 else
16768 printf (" ");
16769
16770 if ((j & 3) == 3)
16771 printf (" ");
16772 }
16773
16774 for (j = 0; j < lbytes; j++)
16775 {
16776 k = p[j];
16777 if (k >= ' ' && k < 0x7f)
16778 printf ("%c", k);
16779 else
16780 printf (".");
16781 }
16782
16783 putchar ('\n');
16784
16785 p += lbytes;
16786 bytes -= lbytes;
16787 addr += lbytes;
87779176 16788 }
59e6276b 16789
f6f0e17b 16790 putchar ('\n');
59e6276b
JM
16791}
16792
13761a11 16793static unsigned char *
b0191216 16794display_msp430_attribute (unsigned char * p,
13761a11
NC
16795 const unsigned char * const end)
16796{
60abdbed
NC
16797 unsigned int val;
16798 unsigned int tag;
13761a11 16799
cd30bcef 16800 READ_ULEB (tag, p, end);
0b4362b0 16801
13761a11
NC
16802 switch (tag)
16803 {
16804 case OFBA_MSPABI_Tag_ISA:
13761a11 16805 printf (" Tag_ISA: ");
cd30bcef 16806 READ_ULEB (val, p, end);
13761a11
NC
16807 switch (val)
16808 {
16809 case 0: printf (_("None\n")); break;
16810 case 1: printf (_("MSP430\n")); break;
16811 case 2: printf (_("MSP430X\n")); break;
16812 default: printf ("??? (%d)\n", val); break;
16813 }
16814 break;
16815
16816 case OFBA_MSPABI_Tag_Code_Model:
13761a11 16817 printf (" Tag_Code_Model: ");
cd30bcef 16818 READ_ULEB (val, p, end);
13761a11
NC
16819 switch (val)
16820 {
16821 case 0: printf (_("None\n")); break;
16822 case 1: printf (_("Small\n")); break;
16823 case 2: printf (_("Large\n")); break;
16824 default: printf ("??? (%d)\n", val); break;
16825 }
16826 break;
16827
16828 case OFBA_MSPABI_Tag_Data_Model:
13761a11 16829 printf (" Tag_Data_Model: ");
cd30bcef 16830 READ_ULEB (val, p, end);
13761a11
NC
16831 switch (val)
16832 {
16833 case 0: printf (_("None\n")); break;
16834 case 1: printf (_("Small\n")); break;
16835 case 2: printf (_("Large\n")); break;
16836 case 3: printf (_("Restricted Large\n")); break;
16837 default: printf ("??? (%d)\n", val); break;
16838 }
16839 break;
16840
16841 default:
16842 printf (_(" <unknown tag %d>: "), tag);
16843
16844 if (tag & 1)
16845 {
071436c6 16846 putchar ('"');
4082ef84
NC
16847 if (p < end - 1)
16848 {
16849 size_t maxlen = (end - p) - 1;
16850
16851 print_symbol ((int) maxlen, (const char *) p);
16852 p += strnlen ((char *) p, maxlen) + 1;
16853 }
16854 else
16855 {
16856 printf (_("<corrupt>"));
16857 p = (unsigned char *) end;
16858 }
071436c6 16859 printf ("\"\n");
13761a11
NC
16860 }
16861 else
16862 {
cd30bcef 16863 READ_ULEB (val, p, end);
13761a11
NC
16864 printf ("%d (0x%x)\n", val, val);
16865 }
16866 break;
16867 }
16868
4082ef84 16869 assert (p <= end);
13761a11
NC
16870 return p;
16871}
16872
c0ea7c52
JL
16873static unsigned char *
16874display_msp430_gnu_attribute (unsigned char * p,
16875 unsigned int tag,
16876 const unsigned char * const end)
16877{
16878 if (tag == Tag_GNU_MSP430_Data_Region)
16879 {
cd30bcef 16880 unsigned int val;
c0ea7c52 16881
c0ea7c52 16882 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 16883 READ_ULEB (val, p, end);
c0ea7c52
JL
16884
16885 switch (val)
16886 {
16887 case Val_GNU_MSP430_Data_Region_Any:
16888 printf (_("Any Region\n"));
16889 break;
16890 case Val_GNU_MSP430_Data_Region_Lower:
16891 printf (_("Lower Region Only\n"));
16892 break;
16893 default:
cd30bcef 16894 printf ("??? (%u)\n", val);
c0ea7c52
JL
16895 }
16896 return p;
16897 }
16898 return display_tag_value (tag & 1, p, end);
16899}
16900
2dc8dd17
JW
16901struct riscv_attr_tag_t {
16902 const char *name;
cd30bcef 16903 unsigned int tag;
2dc8dd17
JW
16904};
16905
16906static struct riscv_attr_tag_t riscv_attr_tag[] =
16907{
16908#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
16909 T(arch),
16910 T(priv_spec),
16911 T(priv_spec_minor),
16912 T(priv_spec_revision),
16913 T(unaligned_access),
16914 T(stack_align),
16915#undef T
16916};
16917
16918static unsigned char *
16919display_riscv_attribute (unsigned char *p,
16920 const unsigned char * const end)
16921{
cd30bcef
AM
16922 unsigned int val;
16923 unsigned int tag;
2dc8dd17
JW
16924 struct riscv_attr_tag_t *attr = NULL;
16925 unsigned i;
16926
cd30bcef 16927 READ_ULEB (tag, p, end);
2dc8dd17
JW
16928
16929 /* Find the name of attribute. */
16930 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
16931 {
16932 if (riscv_attr_tag[i].tag == tag)
16933 {
16934 attr = &riscv_attr_tag[i];
16935 break;
16936 }
16937 }
16938
16939 if (attr)
16940 printf (" %s: ", attr->name);
16941 else
16942 return display_tag_value (tag, p, end);
16943
16944 switch (tag)
16945 {
16946 case Tag_RISCV_priv_spec:
16947 case Tag_RISCV_priv_spec_minor:
16948 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
16949 READ_ULEB (val, p, end);
16950 printf (_("%u\n"), val);
2dc8dd17
JW
16951 break;
16952 case Tag_RISCV_unaligned_access:
cd30bcef 16953 READ_ULEB (val, p, end);
2dc8dd17
JW
16954 switch (val)
16955 {
16956 case 0:
16957 printf (_("No unaligned access\n"));
16958 break;
16959 case 1:
16960 printf (_("Unaligned access\n"));
16961 break;
16962 }
16963 break;
16964 case Tag_RISCV_stack_align:
cd30bcef
AM
16965 READ_ULEB (val, p, end);
16966 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
16967 break;
16968 case Tag_RISCV_arch:
16969 p = display_tag_value (-1, p, end);
16970 break;
16971 default:
16972 return display_tag_value (tag, p, end);
16973 }
16974
16975 return p;
16976}
16977
0861f561
CQ
16978static unsigned char *
16979display_csky_attribute (unsigned char * p,
16980 const unsigned char * const end)
16981{
16982 unsigned int tag;
16983 unsigned int val;
16984 READ_ULEB (tag, p, end);
16985
16986 if (tag >= Tag_CSKY_MAX)
16987 {
16988 return display_tag_value (-1, p, end);
16989 }
16990
16991 switch (tag)
16992 {
16993 case Tag_CSKY_ARCH_NAME:
16994 printf (" Tag_CSKY_ARCH_NAME:\t\t");
16995 return display_tag_value (-1, p, end);
16996 case Tag_CSKY_CPU_NAME:
16997 printf (" Tag_CSKY_CPU_NAME:\t\t");
16998 return display_tag_value (-1, p, end);
16999
17000 case Tag_CSKY_ISA_FLAGS:
17001 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17002 return display_tag_value (0, p, end);
17003 case Tag_CSKY_ISA_EXT_FLAGS:
17004 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17005 return display_tag_value (0, p, end);
17006
17007 case Tag_CSKY_DSP_VERSION:
17008 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17009 READ_ULEB (val, p, end);
17010 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17011 printf ("DSP Extension\n");
17012 else if (val == VAL_CSKY_DSP_VERSION_2)
17013 printf ("DSP 2.0\n");
17014 break;
17015
17016 case Tag_CSKY_VDSP_VERSION:
17017 printf (" Tag_CSKY_VDSP_VERSION:\t");
17018 READ_ULEB (val, p, end);
17019 printf ("VDSP Version %d\n", val);
17020 break;
17021
17022 case Tag_CSKY_FPU_VERSION:
17023 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17024 READ_ULEB (val, p, end);
17025 if (val == VAL_CSKY_FPU_VERSION_1)
17026 printf ("ABIV1 FPU Version 1\n");
17027 else if (val == VAL_CSKY_FPU_VERSION_2)
17028 printf ("FPU Version 2\n");
17029 break;
17030
17031 case Tag_CSKY_FPU_ABI:
17032 printf (" Tag_CSKY_FPU_ABI:\t\t");
17033 READ_ULEB (val, p, end);
17034 if (val == VAL_CSKY_FPU_ABI_HARD)
17035 printf ("Hard\n");
17036 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17037 printf ("SoftFP\n");
17038 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17039 printf ("Soft\n");
17040 break;
17041 case Tag_CSKY_FPU_ROUNDING:
17042 READ_ULEB (val, p, end);
17043 if (val == 1) {
17044 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17045 printf ("Needed\n");
17046 }
17047 break;
17048 case Tag_CSKY_FPU_DENORMAL:
17049 READ_ULEB (val, p, end);
17050 if (val == 1) {
17051 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17052 printf ("Needed\n");
17053 }
17054 break;
17055 case Tag_CSKY_FPU_Exception:
17056 READ_ULEB (val, p, end);
17057 if (val == 1) {
17058 printf (" Tag_CSKY_FPU_Exception:\t");
17059 printf ("Needed\n");
17060 }
17061 break;
17062 case Tag_CSKY_FPU_NUMBER_MODULE:
17063 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17064 return display_tag_value (-1, p, end);
17065 case Tag_CSKY_FPU_HARDFP:
17066 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17067 READ_ULEB (val, p, end);
17068 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17069 printf (" Half");
17070 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17071 printf (" Single");
17072 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17073 printf (" Double");
17074 printf ("\n");
17075 break;
17076 default:
17077 return display_tag_value (tag, p, end);
17078 }
17079 return p;
17080}
17081
32ec8896 17082static bfd_boolean
dda8d76d 17083process_attributes (Filedata * filedata,
60bca95a 17084 const char * public_name,
104d59d1 17085 unsigned int proc_type,
f6f0e17b 17086 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17087 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17088{
2cf0635d 17089 Elf_Internal_Shdr * sect;
11c1ff18 17090 unsigned i;
32ec8896 17091 bfd_boolean res = TRUE;
11c1ff18
PB
17092
17093 /* Find the section header so that we get the size. */
dda8d76d
NC
17094 for (i = 0, sect = filedata->section_headers;
17095 i < filedata->file_header.e_shnum;
11c1ff18
PB
17096 i++, sect++)
17097 {
071436c6
NC
17098 unsigned char * contents;
17099 unsigned char * p;
17100
104d59d1 17101 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17102 continue;
17103
dda8d76d 17104 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17105 sect->sh_size, _("attributes"));
60bca95a 17106 if (contents == NULL)
32ec8896
NC
17107 {
17108 res = FALSE;
17109 continue;
17110 }
60bca95a 17111
11c1ff18 17112 p = contents;
60abdbed
NC
17113 /* The first character is the version of the attributes.
17114 Currently only version 1, (aka 'A') is recognised here. */
17115 if (*p != 'A')
32ec8896
NC
17116 {
17117 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
17118 res = FALSE;
17119 }
60abdbed 17120 else
11c1ff18 17121 {
071436c6
NC
17122 bfd_vma section_len;
17123
17124 section_len = sect->sh_size - 1;
11c1ff18 17125 p++;
60bca95a 17126
071436c6 17127 while (section_len > 0)
11c1ff18 17128 {
071436c6 17129 bfd_vma attr_len;
e9847026 17130 unsigned int namelen;
11c1ff18 17131 bfd_boolean public_section;
104d59d1 17132 bfd_boolean gnu_section;
11c1ff18 17133
071436c6 17134 if (section_len <= 4)
e0a31db1
NC
17135 {
17136 error (_("Tag section ends prematurely\n"));
32ec8896 17137 res = FALSE;
e0a31db1
NC
17138 break;
17139 }
071436c6 17140 attr_len = byte_get (p, 4);
11c1ff18 17141 p += 4;
60bca95a 17142
071436c6 17143 if (attr_len > section_len)
11c1ff18 17144 {
071436c6
NC
17145 error (_("Bad attribute length (%u > %u)\n"),
17146 (unsigned) attr_len, (unsigned) section_len);
17147 attr_len = section_len;
32ec8896 17148 res = FALSE;
11c1ff18 17149 }
74e1a04b 17150 /* PR 17531: file: 001-101425-0.004 */
071436c6 17151 else if (attr_len < 5)
74e1a04b 17152 {
071436c6 17153 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
32ec8896 17154 res = FALSE;
74e1a04b
NC
17155 break;
17156 }
e9847026 17157
071436c6
NC
17158 section_len -= attr_len;
17159 attr_len -= 4;
17160
17161 namelen = strnlen ((char *) p, attr_len) + 1;
17162 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17163 {
17164 error (_("Corrupt attribute section name\n"));
32ec8896 17165 res = FALSE;
e9847026
NC
17166 break;
17167 }
17168
071436c6
NC
17169 printf (_("Attribute Section: "));
17170 print_symbol (INT_MAX, (const char *) p);
17171 putchar ('\n');
60bca95a
NC
17172
17173 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
17174 public_section = TRUE;
17175 else
17176 public_section = FALSE;
60bca95a
NC
17177
17178 if (streq ((char *) p, "gnu"))
104d59d1
JM
17179 gnu_section = TRUE;
17180 else
17181 gnu_section = FALSE;
60bca95a 17182
11c1ff18 17183 p += namelen;
071436c6 17184 attr_len -= namelen;
e0a31db1 17185
071436c6 17186 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17187 {
e0a31db1 17188 int tag;
cd30bcef 17189 unsigned int val;
11c1ff18 17190 bfd_vma size;
071436c6 17191 unsigned char * end;
60bca95a 17192
e0a31db1 17193 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17194 if (attr_len < 6)
e0a31db1
NC
17195 {
17196 error (_("Unused bytes at end of section\n"));
32ec8896 17197 res = FALSE;
e0a31db1
NC
17198 section_len = 0;
17199 break;
17200 }
17201
17202 tag = *(p++);
11c1ff18 17203 size = byte_get (p, 4);
071436c6 17204 if (size > attr_len)
11c1ff18 17205 {
e9847026 17206 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17207 (unsigned) size, (unsigned) attr_len);
32ec8896 17208 res = FALSE;
071436c6 17209 size = attr_len;
11c1ff18 17210 }
e0a31db1
NC
17211 /* PR binutils/17531: Safe handling of corrupt files. */
17212 if (size < 6)
17213 {
17214 error (_("Bad subsection length (%u < 6)\n"),
17215 (unsigned) size);
32ec8896 17216 res = FALSE;
e0a31db1
NC
17217 section_len = 0;
17218 break;
17219 }
60bca95a 17220
071436c6 17221 attr_len -= size;
11c1ff18 17222 end = p + size - 1;
071436c6 17223 assert (end <= contents + sect->sh_size);
11c1ff18 17224 p += 4;
60bca95a 17225
11c1ff18
PB
17226 switch (tag)
17227 {
17228 case 1:
2b692964 17229 printf (_("File Attributes\n"));
11c1ff18
PB
17230 break;
17231 case 2:
2b692964 17232 printf (_("Section Attributes:"));
11c1ff18
PB
17233 goto do_numlist;
17234 case 3:
2b692964 17235 printf (_("Symbol Attributes:"));
1a0670f3 17236 /* Fall through. */
11c1ff18
PB
17237 do_numlist:
17238 for (;;)
17239 {
cd30bcef 17240 READ_ULEB (val, p, end);
11c1ff18
PB
17241 if (val == 0)
17242 break;
17243 printf (" %d", val);
17244 }
17245 printf ("\n");
17246 break;
17247 default:
2b692964 17248 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
17249 public_section = FALSE;
17250 break;
17251 }
60bca95a 17252
071436c6 17253 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
17254 {
17255 while (p < end)
f6f0e17b 17256 p = display_pub_attribute (p, end);
60abdbed 17257 assert (p == end);
104d59d1 17258 }
071436c6 17259 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
17260 {
17261 while (p < end)
17262 p = display_gnu_attribute (p,
f6f0e17b
NC
17263 display_proc_gnu_attribute,
17264 end);
60abdbed 17265 assert (p == end);
11c1ff18 17266 }
071436c6 17267 else if (p < end)
11c1ff18 17268 {
071436c6 17269 printf (_(" Unknown attribute:\n"));
f6f0e17b 17270 display_raw_attribute (p, end);
11c1ff18
PB
17271 p = end;
17272 }
071436c6
NC
17273 else
17274 attr_len = 0;
11c1ff18
PB
17275 }
17276 }
17277 }
d70c5fc7 17278
60bca95a 17279 free (contents);
11c1ff18 17280 }
32ec8896
NC
17281
17282 return res;
11c1ff18
PB
17283}
17284
ccb4c951
RS
17285/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
17286 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
17287 and return the VMA of the next entry, or -1 if there was a problem.
17288 Does not read from DATA_END or beyond. */
ccb4c951
RS
17289
17290static bfd_vma
82b1b41b
NC
17291print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
17292 unsigned char * data_end)
ccb4c951
RS
17293{
17294 printf (" ");
17295 print_vma (addr, LONG_HEX);
17296 printf (" ");
17297 if (addr < pltgot + 0xfff0)
17298 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
17299 else
17300 printf ("%10s", "");
17301 printf (" ");
17302 if (data == NULL)
2b692964 17303 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
17304 else
17305 {
17306 bfd_vma entry;
82b1b41b 17307 unsigned char * from = data + addr - pltgot;
ccb4c951 17308
82b1b41b
NC
17309 if (from + (is_32bit_elf ? 4 : 8) > data_end)
17310 {
17311 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
17312 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
17313 return (bfd_vma) -1;
17314 }
17315 else
17316 {
17317 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17318 print_vma (entry, LONG_HEX);
17319 }
ccb4c951
RS
17320 }
17321 return addr + (is_32bit_elf ? 4 : 8);
17322}
17323
861fb55a
DJ
17324/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
17325 PLTGOT. Print the Address and Initial fields of an entry at VMA
17326 ADDR and return the VMA of the next entry. */
17327
17328static bfd_vma
2cf0635d 17329print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
17330{
17331 printf (" ");
17332 print_vma (addr, LONG_HEX);
17333 printf (" ");
17334 if (data == NULL)
2b692964 17335 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
17336 else
17337 {
17338 bfd_vma entry;
17339
17340 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17341 print_vma (entry, LONG_HEX);
17342 }
17343 return addr + (is_32bit_elf ? 4 : 8);
17344}
17345
351cdf24
MF
17346static void
17347print_mips_ases (unsigned int mask)
17348{
17349 if (mask & AFL_ASE_DSP)
17350 fputs ("\n\tDSP ASE", stdout);
17351 if (mask & AFL_ASE_DSPR2)
17352 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
17353 if (mask & AFL_ASE_DSPR3)
17354 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
17355 if (mask & AFL_ASE_EVA)
17356 fputs ("\n\tEnhanced VA Scheme", stdout);
17357 if (mask & AFL_ASE_MCU)
17358 fputs ("\n\tMCU (MicroController) ASE", stdout);
17359 if (mask & AFL_ASE_MDMX)
17360 fputs ("\n\tMDMX ASE", stdout);
17361 if (mask & AFL_ASE_MIPS3D)
17362 fputs ("\n\tMIPS-3D ASE", stdout);
17363 if (mask & AFL_ASE_MT)
17364 fputs ("\n\tMT ASE", stdout);
17365 if (mask & AFL_ASE_SMARTMIPS)
17366 fputs ("\n\tSmartMIPS ASE", stdout);
17367 if (mask & AFL_ASE_VIRT)
17368 fputs ("\n\tVZ ASE", stdout);
17369 if (mask & AFL_ASE_MSA)
17370 fputs ("\n\tMSA ASE", stdout);
17371 if (mask & AFL_ASE_MIPS16)
17372 fputs ("\n\tMIPS16 ASE", stdout);
17373 if (mask & AFL_ASE_MICROMIPS)
17374 fputs ("\n\tMICROMIPS ASE", stdout);
17375 if (mask & AFL_ASE_XPA)
17376 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
17377 if (mask & AFL_ASE_MIPS16E2)
17378 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
17379 if (mask & AFL_ASE_CRC)
17380 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
17381 if (mask & AFL_ASE_GINV)
17382 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
17383 if (mask & AFL_ASE_LOONGSON_MMI)
17384 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
17385 if (mask & AFL_ASE_LOONGSON_CAM)
17386 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
17387 if (mask & AFL_ASE_LOONGSON_EXT)
17388 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
17389 if (mask & AFL_ASE_LOONGSON_EXT2)
17390 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
17391 if (mask == 0)
17392 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
17393 else if ((mask & ~AFL_ASE_MASK) != 0)
17394 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
17395}
17396
17397static void
17398print_mips_isa_ext (unsigned int isa_ext)
17399{
17400 switch (isa_ext)
17401 {
17402 case 0:
17403 fputs (_("None"), stdout);
17404 break;
17405 case AFL_EXT_XLR:
17406 fputs ("RMI XLR", stdout);
17407 break;
2c629856
N
17408 case AFL_EXT_OCTEON3:
17409 fputs ("Cavium Networks Octeon3", stdout);
17410 break;
351cdf24
MF
17411 case AFL_EXT_OCTEON2:
17412 fputs ("Cavium Networks Octeon2", stdout);
17413 break;
17414 case AFL_EXT_OCTEONP:
17415 fputs ("Cavium Networks OcteonP", stdout);
17416 break;
351cdf24
MF
17417 case AFL_EXT_OCTEON:
17418 fputs ("Cavium Networks Octeon", stdout);
17419 break;
17420 case AFL_EXT_5900:
17421 fputs ("Toshiba R5900", stdout);
17422 break;
17423 case AFL_EXT_4650:
17424 fputs ("MIPS R4650", stdout);
17425 break;
17426 case AFL_EXT_4010:
17427 fputs ("LSI R4010", stdout);
17428 break;
17429 case AFL_EXT_4100:
17430 fputs ("NEC VR4100", stdout);
17431 break;
17432 case AFL_EXT_3900:
17433 fputs ("Toshiba R3900", stdout);
17434 break;
17435 case AFL_EXT_10000:
17436 fputs ("MIPS R10000", stdout);
17437 break;
17438 case AFL_EXT_SB1:
17439 fputs ("Broadcom SB-1", stdout);
17440 break;
17441 case AFL_EXT_4111:
17442 fputs ("NEC VR4111/VR4181", stdout);
17443 break;
17444 case AFL_EXT_4120:
17445 fputs ("NEC VR4120", stdout);
17446 break;
17447 case AFL_EXT_5400:
17448 fputs ("NEC VR5400", stdout);
17449 break;
17450 case AFL_EXT_5500:
17451 fputs ("NEC VR5500", stdout);
17452 break;
17453 case AFL_EXT_LOONGSON_2E:
17454 fputs ("ST Microelectronics Loongson 2E", stdout);
17455 break;
17456 case AFL_EXT_LOONGSON_2F:
17457 fputs ("ST Microelectronics Loongson 2F", stdout);
17458 break;
38bf472a
MR
17459 case AFL_EXT_INTERAPTIV_MR2:
17460 fputs ("Imagination interAptiv MR2", stdout);
17461 break;
351cdf24 17462 default:
00ac7aa0 17463 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
17464 }
17465}
17466
32ec8896 17467static signed int
351cdf24
MF
17468get_mips_reg_size (int reg_size)
17469{
17470 return (reg_size == AFL_REG_NONE) ? 0
17471 : (reg_size == AFL_REG_32) ? 32
17472 : (reg_size == AFL_REG_64) ? 64
17473 : (reg_size == AFL_REG_128) ? 128
17474 : -1;
17475}
17476
32ec8896 17477static bfd_boolean
dda8d76d 17478process_mips_specific (Filedata * filedata)
5b18a4bc 17479{
2cf0635d 17480 Elf_Internal_Dyn * entry;
351cdf24 17481 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
17482 size_t liblist_offset = 0;
17483 size_t liblistno = 0;
17484 size_t conflictsno = 0;
17485 size_t options_offset = 0;
17486 size_t conflicts_offset = 0;
861fb55a
DJ
17487 size_t pltrelsz = 0;
17488 size_t pltrel = 0;
ccb4c951 17489 bfd_vma pltgot = 0;
861fb55a
DJ
17490 bfd_vma mips_pltgot = 0;
17491 bfd_vma jmprel = 0;
ccb4c951
RS
17492 bfd_vma local_gotno = 0;
17493 bfd_vma gotsym = 0;
17494 bfd_vma symtabno = 0;
32ec8896 17495 bfd_boolean res = TRUE;
103f02d3 17496
dda8d76d 17497 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896
NC
17498 display_mips_gnu_attribute))
17499 res = FALSE;
2cf19d5c 17500
dda8d76d 17501 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
17502
17503 if (sect != NULL)
17504 {
17505 Elf_External_ABIFlags_v0 *abiflags_ext;
17506 Elf_Internal_ABIFlags_v0 abiflags_in;
17507
17508 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
17509 {
17510 error (_("Corrupt MIPS ABI Flags section.\n"));
17511 res = FALSE;
17512 }
351cdf24
MF
17513 else
17514 {
dda8d76d 17515 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
17516 sect->sh_size, _("MIPS ABI Flags section"));
17517 if (abiflags_ext)
17518 {
17519 abiflags_in.version = BYTE_GET (abiflags_ext->version);
17520 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
17521 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
17522 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
17523 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
17524 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
17525 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
17526 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
17527 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
17528 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
17529 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
17530
17531 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
17532 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
17533 if (abiflags_in.isa_rev > 1)
17534 printf ("r%d", abiflags_in.isa_rev);
17535 printf ("\nGPR size: %d",
17536 get_mips_reg_size (abiflags_in.gpr_size));
17537 printf ("\nCPR1 size: %d",
17538 get_mips_reg_size (abiflags_in.cpr1_size));
17539 printf ("\nCPR2 size: %d",
17540 get_mips_reg_size (abiflags_in.cpr2_size));
17541 fputs ("\nFP ABI: ", stdout);
17542 print_mips_fp_abi_value (abiflags_in.fp_abi);
17543 fputs ("ISA Extension: ", stdout);
17544 print_mips_isa_ext (abiflags_in.isa_ext);
17545 fputs ("\nASEs:", stdout);
17546 print_mips_ases (abiflags_in.ases);
17547 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
17548 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
17549 fputc ('\n', stdout);
17550 free (abiflags_ext);
17551 }
17552 }
17553 }
17554
19e6b90e 17555 /* We have a lot of special sections. Thanks SGI! */
978c4450 17556 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
17557 {
17558 /* No dynamic information available. See if there is static GOT. */
dda8d76d 17559 sect = find_section (filedata, ".got");
bbdd9a68
MR
17560 if (sect != NULL)
17561 {
17562 unsigned char *data_end;
17563 unsigned char *data;
17564 bfd_vma ent, end;
17565 int addr_size;
17566
17567 pltgot = sect->sh_addr;
17568
17569 ent = pltgot;
17570 addr_size = (is_32bit_elf ? 4 : 8);
17571 end = pltgot + sect->sh_size;
17572
dda8d76d 17573 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
17574 end - pltgot, 1,
17575 _("Global Offset Table data"));
17576 /* PR 12855: Null data is handled gracefully throughout. */
17577 data_end = data + (end - pltgot);
17578
17579 printf (_("\nStatic GOT:\n"));
17580 printf (_(" Canonical gp value: "));
17581 print_vma (ent + 0x7ff0, LONG_HEX);
17582 printf ("\n\n");
17583
17584 /* In a dynamic binary GOT[0] is reserved for the dynamic
17585 loader to store the lazy resolver pointer, however in
17586 a static binary it may well have been omitted and GOT
17587 reduced to a table of addresses.
17588 PR 21344: Check for the entry being fully available
17589 before fetching it. */
17590 if (data
17591 && data + ent - pltgot + addr_size <= data_end
17592 && byte_get (data + ent - pltgot, addr_size) == 0)
17593 {
17594 printf (_(" Reserved entries:\n"));
17595 printf (_(" %*s %10s %*s\n"),
17596 addr_size * 2, _("Address"), _("Access"),
17597 addr_size * 2, _("Value"));
17598 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17599 printf ("\n");
17600 if (ent == (bfd_vma) -1)
17601 goto sgot_print_fail;
17602
17603 /* Check for the MSB of GOT[1] being set, identifying a
17604 GNU object. This entry will be used by some runtime
17605 loaders, to store the module pointer. Otherwise this
17606 is an ordinary local entry.
17607 PR 21344: Check for the entry being fully available
17608 before fetching it. */
17609 if (data
17610 && data + ent - pltgot + addr_size <= data_end
17611 && (byte_get (data + ent - pltgot, addr_size)
17612 >> (addr_size * 8 - 1)) != 0)
17613 {
17614 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17615 printf ("\n");
17616 if (ent == (bfd_vma) -1)
17617 goto sgot_print_fail;
17618 }
17619 printf ("\n");
17620 }
17621
f17e9d8a 17622 if (data != NULL && ent < end)
bbdd9a68
MR
17623 {
17624 printf (_(" Local entries:\n"));
17625 printf (" %*s %10s %*s\n",
17626 addr_size * 2, _("Address"), _("Access"),
17627 addr_size * 2, _("Value"));
17628 while (ent < end)
17629 {
17630 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17631 printf ("\n");
17632 if (ent == (bfd_vma) -1)
17633 goto sgot_print_fail;
17634 }
17635 printf ("\n");
17636 }
17637
17638 sgot_print_fail:
9db70fc3 17639 free (data);
bbdd9a68
MR
17640 }
17641 return res;
17642 }
252b5132 17643
978c4450 17644 for (entry = filedata->dynamic_section;
071436c6 17645 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
17646 (entry < filedata->dynamic_section + filedata->dynamic_nent
17647 && entry->d_tag != DT_NULL);
071436c6 17648 ++entry)
252b5132
RH
17649 switch (entry->d_tag)
17650 {
17651 case DT_MIPS_LIBLIST:
d93f0186 17652 liblist_offset
dda8d76d 17653 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17654 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
17655 break;
17656 case DT_MIPS_LIBLISTNO:
17657 liblistno = entry->d_un.d_val;
17658 break;
17659 case DT_MIPS_OPTIONS:
dda8d76d 17660 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
17661 break;
17662 case DT_MIPS_CONFLICT:
d93f0186 17663 conflicts_offset
dda8d76d 17664 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17665 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
17666 break;
17667 case DT_MIPS_CONFLICTNO:
17668 conflictsno = entry->d_un.d_val;
17669 break;
ccb4c951 17670 case DT_PLTGOT:
861fb55a
DJ
17671 pltgot = entry->d_un.d_ptr;
17672 break;
ccb4c951
RS
17673 case DT_MIPS_LOCAL_GOTNO:
17674 local_gotno = entry->d_un.d_val;
17675 break;
17676 case DT_MIPS_GOTSYM:
17677 gotsym = entry->d_un.d_val;
17678 break;
17679 case DT_MIPS_SYMTABNO:
17680 symtabno = entry->d_un.d_val;
17681 break;
861fb55a
DJ
17682 case DT_MIPS_PLTGOT:
17683 mips_pltgot = entry->d_un.d_ptr;
17684 break;
17685 case DT_PLTREL:
17686 pltrel = entry->d_un.d_val;
17687 break;
17688 case DT_PLTRELSZ:
17689 pltrelsz = entry->d_un.d_val;
17690 break;
17691 case DT_JMPREL:
17692 jmprel = entry->d_un.d_ptr;
17693 break;
252b5132
RH
17694 default:
17695 break;
17696 }
17697
17698 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
17699 {
2cf0635d 17700 Elf32_External_Lib * elib;
252b5132
RH
17701 size_t cnt;
17702
dda8d76d 17703 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
17704 sizeof (Elf32_External_Lib),
17705 liblistno,
17706 _("liblist section data"));
a6e9f9df 17707 if (elib)
252b5132 17708 {
d3a49aa8
AM
17709 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
17710 "\nSection '.liblist' contains %lu entries:\n",
17711 (unsigned long) liblistno),
a6e9f9df 17712 (unsigned long) liblistno);
2b692964 17713 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
17714 stdout);
17715
17716 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 17717 {
a6e9f9df 17718 Elf32_Lib liblist;
91d6fa6a 17719 time_t atime;
d5b07ef4 17720 char timebuf[128];
2cf0635d 17721 struct tm * tmp;
a6e9f9df
AM
17722
17723 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17724 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
17725 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17726 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17727 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17728
91d6fa6a 17729 tmp = gmtime (&atime);
e9e44622
JJ
17730 snprintf (timebuf, sizeof (timebuf),
17731 "%04u-%02u-%02uT%02u:%02u:%02u",
17732 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17733 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 17734
31104126 17735 printf ("%3lu: ", (unsigned long) cnt);
978c4450
AM
17736 if (VALID_DYNAMIC_NAME (filedata, liblist.l_name))
17737 print_symbol (20, GET_DYNAMIC_NAME (filedata, liblist.l_name));
d79b3d50 17738 else
2b692964 17739 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
17740 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
17741 liblist.l_version);
a6e9f9df
AM
17742
17743 if (liblist.l_flags == 0)
2b692964 17744 puts (_(" NONE"));
a6e9f9df
AM
17745 else
17746 {
17747 static const struct
252b5132 17748 {
2cf0635d 17749 const char * name;
a6e9f9df 17750 int bit;
252b5132 17751 }
a6e9f9df
AM
17752 l_flags_vals[] =
17753 {
17754 { " EXACT_MATCH", LL_EXACT_MATCH },
17755 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
17756 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
17757 { " EXPORTS", LL_EXPORTS },
17758 { " DELAY_LOAD", LL_DELAY_LOAD },
17759 { " DELTA", LL_DELTA }
17760 };
17761 int flags = liblist.l_flags;
17762 size_t fcnt;
17763
60bca95a 17764 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
17765 if ((flags & l_flags_vals[fcnt].bit) != 0)
17766 {
17767 fputs (l_flags_vals[fcnt].name, stdout);
17768 flags ^= l_flags_vals[fcnt].bit;
17769 }
17770 if (flags != 0)
17771 printf (" %#x", (unsigned int) flags);
252b5132 17772
a6e9f9df
AM
17773 puts ("");
17774 }
252b5132 17775 }
252b5132 17776
a6e9f9df
AM
17777 free (elib);
17778 }
32ec8896
NC
17779 else
17780 res = FALSE;
252b5132
RH
17781 }
17782
17783 if (options_offset != 0)
17784 {
2cf0635d 17785 Elf_External_Options * eopt;
252b5132
RH
17786 size_t offset;
17787 int cnt;
dda8d76d 17788 sect = filedata->section_headers;
252b5132
RH
17789
17790 /* Find the section header so that we get the size. */
dda8d76d 17791 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 17792 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
17793 if (sect == NULL)
17794 {
17795 error (_("No MIPS_OPTIONS header found\n"));
32ec8896 17796 return FALSE;
071436c6 17797 }
7fc0c668
NC
17798 /* PR 24243 */
17799 if (sect->sh_size < sizeof (* eopt))
17800 {
17801 error (_("The MIPS options section is too small.\n"));
17802 return FALSE;
17803 }
252b5132 17804
dda8d76d 17805 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 17806 sect->sh_size, _("options"));
a6e9f9df 17807 if (eopt)
252b5132 17808 {
fd17d1e6 17809 Elf_Internal_Options option;
76da6bbe 17810
a6e9f9df 17811 offset = cnt = 0;
82b1b41b 17812 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 17813 {
2cf0635d 17814 Elf_External_Options * eoption;
fd17d1e6 17815 unsigned int optsize;
252b5132 17816
a6e9f9df 17817 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 17818
fd17d1e6 17819 optsize = BYTE_GET (eoption->size);
76da6bbe 17820
82b1b41b 17821 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
17822 if (optsize < sizeof (* eopt)
17823 || optsize > sect->sh_size - offset)
82b1b41b 17824 {
645f43a8 17825 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 17826 optsize);
645f43a8 17827 free (eopt);
32ec8896 17828 return FALSE;
82b1b41b 17829 }
fd17d1e6 17830 offset += optsize;
a6e9f9df
AM
17831 ++cnt;
17832 }
252b5132 17833
d3a49aa8
AM
17834 printf (ngettext ("\nSection '%s' contains %d entry:\n",
17835 "\nSection '%s' contains %d entries:\n",
17836 cnt),
dda8d76d 17837 printable_section_name (filedata, sect), cnt);
76da6bbe 17838
82b1b41b 17839 offset = 0;
a6e9f9df 17840 while (cnt-- > 0)
252b5132 17841 {
a6e9f9df 17842 size_t len;
fd17d1e6
AM
17843 Elf_External_Options * eoption;
17844
17845 eoption = (Elf_External_Options *) ((char *) eopt + offset);
17846
17847 option.kind = BYTE_GET (eoption->kind);
17848 option.size = BYTE_GET (eoption->size);
17849 option.section = BYTE_GET (eoption->section);
17850 option.info = BYTE_GET (eoption->info);
a6e9f9df 17851
fd17d1e6 17852 switch (option.kind)
252b5132 17853 {
a6e9f9df
AM
17854 case ODK_NULL:
17855 /* This shouldn't happen. */
d0c4e780 17856 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 17857 option.section, option.info);
a6e9f9df 17858 break;
2e6be59c 17859
a6e9f9df
AM
17860 case ODK_REGINFO:
17861 printf (" REGINFO ");
dda8d76d 17862 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 17863 {
2cf0635d 17864 Elf32_External_RegInfo * ereg;
b34976b6 17865 Elf32_RegInfo reginfo;
a6e9f9df 17866
2e6be59c 17867 /* 32bit form. */
fd17d1e6
AM
17868 if (option.size < (sizeof (Elf_External_Options)
17869 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
17870 {
17871 printf (_("<corrupt>\n"));
17872 error (_("Truncated MIPS REGINFO option\n"));
17873 cnt = 0;
17874 break;
17875 }
17876
fd17d1e6 17877 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 17878
a6e9f9df
AM
17879 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17880 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17881 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17882 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17883 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
17884 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
17885
d0c4e780
AM
17886 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
17887 reginfo.ri_gprmask, reginfo.ri_gp_value);
17888 printf (" "
17889 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
17890 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
17891 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17892 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17893 }
17894 else
17895 {
17896 /* 64 bit form. */
2cf0635d 17897 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
17898 Elf64_Internal_RegInfo reginfo;
17899
fd17d1e6
AM
17900 if (option.size < (sizeof (Elf_External_Options)
17901 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
17902 {
17903 printf (_("<corrupt>\n"));
17904 error (_("Truncated MIPS REGINFO option\n"));
17905 cnt = 0;
17906 break;
17907 }
17908
fd17d1e6 17909 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
17910 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17911 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17912 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17913 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17914 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 17915 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 17916
d0c4e780
AM
17917 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
17918 reginfo.ri_gprmask, reginfo.ri_gp_value);
17919 printf (" "
17920 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
17921 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
17922 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17923 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17924 }
fd17d1e6 17925 offset += option.size;
a6e9f9df 17926 continue;
2e6be59c 17927
a6e9f9df
AM
17928 case ODK_EXCEPTIONS:
17929 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 17930 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 17931 fputs (") fpe_max(", stdout);
fd17d1e6 17932 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
17933 fputs (")", stdout);
17934
fd17d1e6 17935 if (option.info & OEX_PAGE0)
a6e9f9df 17936 fputs (" PAGE0", stdout);
fd17d1e6 17937 if (option.info & OEX_SMM)
a6e9f9df 17938 fputs (" SMM", stdout);
fd17d1e6 17939 if (option.info & OEX_FPDBUG)
a6e9f9df 17940 fputs (" FPDBUG", stdout);
fd17d1e6 17941 if (option.info & OEX_DISMISS)
a6e9f9df
AM
17942 fputs (" DISMISS", stdout);
17943 break;
2e6be59c 17944
a6e9f9df
AM
17945 case ODK_PAD:
17946 fputs (" PAD ", stdout);
fd17d1e6 17947 if (option.info & OPAD_PREFIX)
a6e9f9df 17948 fputs (" PREFIX", stdout);
fd17d1e6 17949 if (option.info & OPAD_POSTFIX)
a6e9f9df 17950 fputs (" POSTFIX", stdout);
fd17d1e6 17951 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
17952 fputs (" SYMBOL", stdout);
17953 break;
2e6be59c 17954
a6e9f9df
AM
17955 case ODK_HWPATCH:
17956 fputs (" HWPATCH ", stdout);
fd17d1e6 17957 if (option.info & OHW_R4KEOP)
a6e9f9df 17958 fputs (" R4KEOP", stdout);
fd17d1e6 17959 if (option.info & OHW_R8KPFETCH)
a6e9f9df 17960 fputs (" R8KPFETCH", stdout);
fd17d1e6 17961 if (option.info & OHW_R5KEOP)
a6e9f9df 17962 fputs (" R5KEOP", stdout);
fd17d1e6 17963 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
17964 fputs (" R5KCVTL", stdout);
17965 break;
2e6be59c 17966
a6e9f9df
AM
17967 case ODK_FILL:
17968 fputs (" FILL ", stdout);
17969 /* XXX Print content of info word? */
17970 break;
2e6be59c 17971
a6e9f9df
AM
17972 case ODK_TAGS:
17973 fputs (" TAGS ", stdout);
17974 /* XXX Print content of info word? */
17975 break;
2e6be59c 17976
a6e9f9df
AM
17977 case ODK_HWAND:
17978 fputs (" HWAND ", stdout);
fd17d1e6 17979 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 17980 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 17981 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
17982 fputs (" R4KEOP_CLEAN", stdout);
17983 break;
2e6be59c 17984
a6e9f9df
AM
17985 case ODK_HWOR:
17986 fputs (" HWOR ", stdout);
fd17d1e6 17987 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 17988 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 17989 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
17990 fputs (" R4KEOP_CLEAN", stdout);
17991 break;
2e6be59c 17992
a6e9f9df 17993 case ODK_GP_GROUP:
d0c4e780 17994 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
17995 option.info & OGP_GROUP,
17996 (option.info & OGP_SELF) >> 16);
a6e9f9df 17997 break;
2e6be59c 17998
a6e9f9df 17999 case ODK_IDENT:
d0c4e780 18000 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18001 option.info & OGP_GROUP,
18002 (option.info & OGP_SELF) >> 16);
a6e9f9df 18003 break;
2e6be59c 18004
a6e9f9df
AM
18005 default:
18006 /* This shouldn't happen. */
d0c4e780 18007 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18008 option.kind, option.section, option.info);
a6e9f9df 18009 break;
252b5132 18010 }
a6e9f9df 18011
2cf0635d 18012 len = sizeof (* eopt);
fd17d1e6 18013 while (len < option.size)
82b1b41b 18014 {
fd17d1e6 18015 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18016
82b1b41b
NC
18017 if (ISPRINT (datum))
18018 printf ("%c", datum);
18019 else
18020 printf ("\\%03o", datum);
18021 len ++;
18022 }
a6e9f9df 18023 fputs ("\n", stdout);
82b1b41b 18024
fd17d1e6 18025 offset += option.size;
252b5132 18026 }
a6e9f9df 18027 free (eopt);
252b5132 18028 }
32ec8896
NC
18029 else
18030 res = FALSE;
252b5132
RH
18031 }
18032
18033 if (conflicts_offset != 0 && conflictsno != 0)
18034 {
2cf0635d 18035 Elf32_Conflict * iconf;
252b5132
RH
18036 size_t cnt;
18037
978c4450 18038 if (filedata->dynamic_symbols == NULL)
252b5132 18039 {
591a748a 18040 error (_("conflict list found without a dynamic symbol table\n"));
32ec8896 18041 return FALSE;
252b5132
RH
18042 }
18043
7296a62a
NC
18044 /* PR 21345 - print a slightly more helpful error message
18045 if we are sure that the cmalloc will fail. */
645f43a8 18046 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18047 {
18048 error (_("Overlarge number of conflicts detected: %lx\n"),
18049 (long) conflictsno);
18050 return FALSE;
18051 }
18052
3f5e193b 18053 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18054 if (iconf == NULL)
18055 {
8b73c356 18056 error (_("Out of memory allocating space for dynamic conflicts\n"));
32ec8896 18057 return FALSE;
252b5132
RH
18058 }
18059
9ea033b2 18060 if (is_32bit_elf)
252b5132 18061 {
2cf0635d 18062 Elf32_External_Conflict * econf32;
a6e9f9df 18063
3f5e193b 18064 econf32 = (Elf32_External_Conflict *)
95099889
AM
18065 get_data (NULL, filedata, conflicts_offset,
18066 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18067 if (!econf32)
5a814d6d
AM
18068 {
18069 free (iconf);
18070 return FALSE;
18071 }
252b5132
RH
18072
18073 for (cnt = 0; cnt < conflictsno; ++cnt)
18074 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18075
18076 free (econf32);
252b5132
RH
18077 }
18078 else
18079 {
2cf0635d 18080 Elf64_External_Conflict * econf64;
a6e9f9df 18081
3f5e193b 18082 econf64 = (Elf64_External_Conflict *)
95099889
AM
18083 get_data (NULL, filedata, conflicts_offset,
18084 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18085 if (!econf64)
5a814d6d
AM
18086 {
18087 free (iconf);
18088 return FALSE;
18089 }
252b5132
RH
18090
18091 for (cnt = 0; cnt < conflictsno; ++cnt)
18092 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18093
18094 free (econf64);
252b5132
RH
18095 }
18096
d3a49aa8
AM
18097 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18098 "\nSection '.conflict' contains %lu entries:\n",
18099 (unsigned long) conflictsno),
c7e7ca54 18100 (unsigned long) conflictsno);
252b5132
RH
18101 puts (_(" Num: Index Value Name"));
18102
18103 for (cnt = 0; cnt < conflictsno; ++cnt)
18104 {
b34976b6 18105 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18106
978c4450 18107 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18108 printf (_("<corrupt symbol index>"));
d79b3d50 18109 else
e0a31db1
NC
18110 {
18111 Elf_Internal_Sym * psym;
18112
978c4450 18113 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18114 print_vma (psym->st_value, FULL_HEX);
18115 putchar (' ');
978c4450
AM
18116 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18117 print_symbol (25, GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18118 else
18119 printf (_("<corrupt: %14ld>"), psym->st_name);
18120 }
31104126 18121 putchar ('\n');
252b5132
RH
18122 }
18123
252b5132
RH
18124 free (iconf);
18125 }
18126
ccb4c951
RS
18127 if (pltgot != 0 && local_gotno != 0)
18128 {
91d6fa6a 18129 bfd_vma ent, local_end, global_end;
bbeee7ea 18130 size_t i, offset;
2cf0635d 18131 unsigned char * data;
82b1b41b 18132 unsigned char * data_end;
bbeee7ea 18133 int addr_size;
ccb4c951 18134
91d6fa6a 18135 ent = pltgot;
ccb4c951
RS
18136 addr_size = (is_32bit_elf ? 4 : 8);
18137 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18138
74e1a04b
NC
18139 /* PR binutils/17533 file: 012-111227-0.004 */
18140 if (symtabno < gotsym)
18141 {
18142 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18143 (unsigned long) gotsym, (unsigned long) symtabno);
32ec8896 18144 return FALSE;
74e1a04b 18145 }
82b1b41b 18146
74e1a04b 18147 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18148 /* PR 17531: file: 54c91a34. */
18149 if (global_end < local_end)
18150 {
18151 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
32ec8896 18152 return FALSE;
82b1b41b 18153 }
948f632f 18154
dda8d76d
NC
18155 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18156 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18157 global_end - pltgot, 1,
18158 _("Global Offset Table data"));
919383ac 18159 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18160 data_end = data + (global_end - pltgot);
59245841 18161
ccb4c951
RS
18162 printf (_("\nPrimary GOT:\n"));
18163 printf (_(" Canonical gp value: "));
18164 print_vma (pltgot + 0x7ff0, LONG_HEX);
18165 printf ("\n\n");
18166
18167 printf (_(" Reserved entries:\n"));
18168 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18169 addr_size * 2, _("Address"), _("Access"),
18170 addr_size * 2, _("Initial"));
82b1b41b 18171 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18172 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18173 if (ent == (bfd_vma) -1)
18174 goto got_print_fail;
75ec1fdb 18175
c4ab9505
MR
18176 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18177 This entry will be used by some runtime loaders, to store the
18178 module pointer. Otherwise this is an ordinary local entry.
18179 PR 21344: Check for the entry being fully available before
18180 fetching it. */
18181 if (data
18182 && data + ent - pltgot + addr_size <= data_end
18183 && (byte_get (data + ent - pltgot, addr_size)
18184 >> (addr_size * 8 - 1)) != 0)
18185 {
18186 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18187 printf (_(" Module pointer (GNU extension)\n"));
18188 if (ent == (bfd_vma) -1)
18189 goto got_print_fail;
ccb4c951
RS
18190 }
18191 printf ("\n");
18192
f17e9d8a 18193 if (data != NULL && ent < local_end)
ccb4c951
RS
18194 {
18195 printf (_(" Local entries:\n"));
cc5914eb 18196 printf (" %*s %10s %*s\n",
2b692964
NC
18197 addr_size * 2, _("Address"), _("Access"),
18198 addr_size * 2, _("Initial"));
91d6fa6a 18199 while (ent < local_end)
ccb4c951 18200 {
82b1b41b 18201 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18202 printf ("\n");
82b1b41b
NC
18203 if (ent == (bfd_vma) -1)
18204 goto got_print_fail;
ccb4c951
RS
18205 }
18206 printf ("\n");
18207 }
18208
f17e9d8a 18209 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18210 {
18211 int sym_width;
18212
18213 printf (_(" Global entries:\n"));
cc5914eb 18214 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18215 addr_size * 2, _("Address"),
18216 _("Access"),
2b692964 18217 addr_size * 2, _("Initial"),
9cf03b7e
NC
18218 addr_size * 2, _("Sym.Val."),
18219 _("Type"),
18220 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18221 _("Ndx"), _("Name"));
0b4362b0 18222
ccb4c951 18223 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18224
ccb4c951
RS
18225 for (i = gotsym; i < symtabno; i++)
18226 {
82b1b41b 18227 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18228 printf (" ");
e0a31db1 18229
978c4450 18230 if (filedata->dynamic_symbols == NULL)
e0a31db1 18231 printf (_("<no dynamic symbols>"));
978c4450 18232 else if (i < filedata->num_dynamic_syms)
e0a31db1 18233 {
978c4450 18234 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
18235
18236 print_vma (psym->st_value, LONG_HEX);
18237 printf (" %-7s %3s ",
dda8d76d
NC
18238 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18239 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 18240
978c4450
AM
18241 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18242 print_symbol (sym_width,
18243 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18244 else
18245 printf (_("<corrupt: %14ld>"), psym->st_name);
18246 }
ccb4c951 18247 else
7fc5ac57
JBG
18248 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
18249 (unsigned long) i);
e0a31db1 18250
ccb4c951 18251 printf ("\n");
82b1b41b
NC
18252 if (ent == (bfd_vma) -1)
18253 break;
ccb4c951
RS
18254 }
18255 printf ("\n");
18256 }
18257
82b1b41b 18258 got_print_fail:
9db70fc3 18259 free (data);
ccb4c951
RS
18260 }
18261
861fb55a
DJ
18262 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
18263 {
91d6fa6a 18264 bfd_vma ent, end;
861fb55a
DJ
18265 size_t offset, rel_offset;
18266 unsigned long count, i;
2cf0635d 18267 unsigned char * data;
861fb55a 18268 int addr_size, sym_width;
2cf0635d 18269 Elf_Internal_Rela * rels;
861fb55a 18270
dda8d76d 18271 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
18272 if (pltrel == DT_RELA)
18273 {
dda8d76d 18274 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 18275 return FALSE;
861fb55a
DJ
18276 }
18277 else
18278 {
dda8d76d 18279 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 18280 return FALSE;
861fb55a
DJ
18281 }
18282
91d6fa6a 18283 ent = mips_pltgot;
861fb55a
DJ
18284 addr_size = (is_32bit_elf ? 4 : 8);
18285 end = mips_pltgot + (2 + count) * addr_size;
18286
dda8d76d
NC
18287 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
18288 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 18289 1, _("Procedure Linkage Table data"));
59245841 18290 if (data == NULL)
288f0ba2
AM
18291 {
18292 free (rels);
18293 return FALSE;
18294 }
59245841 18295
9cf03b7e 18296 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
18297 printf (_(" Reserved entries:\n"));
18298 printf (_(" %*s %*s Purpose\n"),
2b692964 18299 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 18300 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18301 printf (_(" PLT lazy resolver\n"));
91d6fa6a 18302 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18303 printf (_(" Module pointer\n"));
861fb55a
DJ
18304 printf ("\n");
18305
18306 printf (_(" Entries:\n"));
cc5914eb 18307 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
18308 addr_size * 2, _("Address"),
18309 addr_size * 2, _("Initial"),
18310 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
18311 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
18312 for (i = 0; i < count; i++)
18313 {
df97ab2a 18314 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 18315
91d6fa6a 18316 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 18317 printf (" ");
e0a31db1 18318
978c4450 18319 if (idx >= filedata->num_dynamic_syms)
df97ab2a 18320 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 18321 else
e0a31db1 18322 {
978c4450 18323 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
18324
18325 print_vma (psym->st_value, LONG_HEX);
18326 printf (" %-7s %3s ",
dda8d76d
NC
18327 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18328 get_symbol_index_type (filedata, psym->st_shndx));
978c4450
AM
18329 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18330 print_symbol (sym_width,
18331 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18332 else
18333 printf (_("<corrupt: %14ld>"), psym->st_name);
18334 }
861fb55a
DJ
18335 printf ("\n");
18336 }
18337 printf ("\n");
18338
9db70fc3 18339 free (data);
861fb55a
DJ
18340 free (rels);
18341 }
18342
32ec8896 18343 return res;
252b5132
RH
18344}
18345
32ec8896 18346static bfd_boolean
dda8d76d 18347process_nds32_specific (Filedata * filedata)
35c08157
KLC
18348{
18349 Elf_Internal_Shdr *sect = NULL;
18350
dda8d76d 18351 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 18352 if (sect != NULL && sect->sh_size >= 4)
35c08157 18353 {
9c7b8e9b
AM
18354 unsigned char *buf;
18355 unsigned int flag;
35c08157
KLC
18356
18357 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
18358 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
18359 _("NDS32 elf flags section"));
35c08157 18360
9c7b8e9b 18361 if (buf == NULL)
32ec8896
NC
18362 return FALSE;
18363
9c7b8e9b
AM
18364 flag = byte_get (buf, 4);
18365 free (buf);
18366 switch (flag & 0x3)
35c08157
KLC
18367 {
18368 case 0:
18369 printf ("(VEC_SIZE):\tNo entry.\n");
18370 break;
18371 case 1:
18372 printf ("(VEC_SIZE):\t4 bytes\n");
18373 break;
18374 case 2:
18375 printf ("(VEC_SIZE):\t16 bytes\n");
18376 break;
18377 case 3:
18378 printf ("(VEC_SIZE):\treserved\n");
18379 break;
18380 }
18381 }
18382
18383 return TRUE;
18384}
18385
32ec8896 18386static bfd_boolean
dda8d76d 18387process_gnu_liblist (Filedata * filedata)
047b2264 18388{
2cf0635d
NC
18389 Elf_Internal_Shdr * section;
18390 Elf_Internal_Shdr * string_sec;
18391 Elf32_External_Lib * elib;
18392 char * strtab;
c256ffe7 18393 size_t strtab_size;
047b2264 18394 size_t cnt;
d3a49aa8 18395 unsigned long num_liblist;
047b2264 18396 unsigned i;
32ec8896 18397 bfd_boolean res = TRUE;
047b2264
JJ
18398
18399 if (! do_arch)
32ec8896 18400 return TRUE;
047b2264 18401
dda8d76d
NC
18402 for (i = 0, section = filedata->section_headers;
18403 i < filedata->file_header.e_shnum;
b34976b6 18404 i++, section++)
047b2264
JJ
18405 {
18406 switch (section->sh_type)
18407 {
18408 case SHT_GNU_LIBLIST:
dda8d76d 18409 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
18410 break;
18411
3f5e193b 18412 elib = (Elf32_External_Lib *)
dda8d76d 18413 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 18414 _("liblist section data"));
047b2264
JJ
18415
18416 if (elib == NULL)
32ec8896
NC
18417 {
18418 res = FALSE;
18419 break;
18420 }
047b2264 18421
dda8d76d
NC
18422 string_sec = filedata->section_headers + section->sh_link;
18423 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
18424 string_sec->sh_size,
18425 _("liblist string table"));
047b2264
JJ
18426 if (strtab == NULL
18427 || section->sh_entsize != sizeof (Elf32_External_Lib))
18428 {
18429 free (elib);
2842702f 18430 free (strtab);
32ec8896 18431 res = FALSE;
047b2264
JJ
18432 break;
18433 }
59245841 18434 strtab_size = string_sec->sh_size;
047b2264 18435
d3a49aa8
AM
18436 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
18437 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
18438 "\nLibrary list section '%s' contains %lu entries:\n",
18439 num_liblist),
dda8d76d 18440 printable_section_name (filedata, section),
d3a49aa8 18441 num_liblist);
047b2264 18442
2b692964 18443 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
18444
18445 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
18446 ++cnt)
18447 {
18448 Elf32_Lib liblist;
91d6fa6a 18449 time_t atime;
d5b07ef4 18450 char timebuf[128];
2cf0635d 18451 struct tm * tmp;
047b2264
JJ
18452
18453 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18454 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
18455 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18456 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18457 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18458
91d6fa6a 18459 tmp = gmtime (&atime);
e9e44622
JJ
18460 snprintf (timebuf, sizeof (timebuf),
18461 "%04u-%02u-%02uT%02u:%02u:%02u",
18462 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18463 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
18464
18465 printf ("%3lu: ", (unsigned long) cnt);
18466 if (do_wide)
c256ffe7 18467 printf ("%-20s", liblist.l_name < strtab_size
2b692964 18468 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 18469 else
c256ffe7 18470 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 18471 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
18472 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
18473 liblist.l_version, liblist.l_flags);
18474 }
18475
18476 free (elib);
2842702f 18477 free (strtab);
047b2264
JJ
18478 }
18479 }
18480
32ec8896 18481 return res;
047b2264
JJ
18482}
18483
9437c45b 18484static const char *
dda8d76d 18485get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
18486{
18487 static char buff[64];
103f02d3 18488
dda8d76d 18489 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
18490 switch (e_type)
18491 {
57346661 18492 case NT_AUXV:
1ec5cd37 18493 return _("NT_AUXV (auxiliary vector)");
57346661 18494 case NT_PRSTATUS:
1ec5cd37 18495 return _("NT_PRSTATUS (prstatus structure)");
57346661 18496 case NT_FPREGSET:
1ec5cd37 18497 return _("NT_FPREGSET (floating point registers)");
57346661 18498 case NT_PRPSINFO:
1ec5cd37 18499 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 18500 case NT_TASKSTRUCT:
1ec5cd37 18501 return _("NT_TASKSTRUCT (task structure)");
57346661 18502 case NT_PRXFPREG:
1ec5cd37 18503 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
18504 case NT_PPC_VMX:
18505 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
18506 case NT_PPC_VSX:
18507 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
18508 case NT_PPC_TAR:
18509 return _("NT_PPC_TAR (ppc TAR register)");
18510 case NT_PPC_PPR:
18511 return _("NT_PPC_PPR (ppc PPR register)");
18512 case NT_PPC_DSCR:
18513 return _("NT_PPC_DSCR (ppc DSCR register)");
18514 case NT_PPC_EBB:
18515 return _("NT_PPC_EBB (ppc EBB registers)");
18516 case NT_PPC_PMU:
18517 return _("NT_PPC_PMU (ppc PMU registers)");
18518 case NT_PPC_TM_CGPR:
18519 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
18520 case NT_PPC_TM_CFPR:
18521 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
18522 case NT_PPC_TM_CVMX:
18523 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
18524 case NT_PPC_TM_CVSX:
3fd21718 18525 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
18526 case NT_PPC_TM_SPR:
18527 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
18528 case NT_PPC_TM_CTAR:
18529 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
18530 case NT_PPC_TM_CPPR:
18531 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
18532 case NT_PPC_TM_CDSCR:
18533 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
18534 case NT_386_TLS:
18535 return _("NT_386_TLS (x86 TLS information)");
18536 case NT_386_IOPERM:
18537 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
18538 case NT_X86_XSTATE:
18539 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
18540 case NT_X86_CET:
18541 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
18542 case NT_S390_HIGH_GPRS:
18543 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
18544 case NT_S390_TIMER:
18545 return _("NT_S390_TIMER (s390 timer register)");
18546 case NT_S390_TODCMP:
18547 return _("NT_S390_TODCMP (s390 TOD comparator register)");
18548 case NT_S390_TODPREG:
18549 return _("NT_S390_TODPREG (s390 TOD programmable register)");
18550 case NT_S390_CTRS:
18551 return _("NT_S390_CTRS (s390 control registers)");
18552 case NT_S390_PREFIX:
18553 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
18554 case NT_S390_LAST_BREAK:
18555 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
18556 case NT_S390_SYSTEM_CALL:
18557 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
18558 case NT_S390_TDB:
18559 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
18560 case NT_S390_VXRS_LOW:
18561 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
18562 case NT_S390_VXRS_HIGH:
18563 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
18564 case NT_S390_GS_CB:
18565 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
18566 case NT_S390_GS_BC:
18567 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
18568 case NT_ARM_VFP:
18569 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
18570 case NT_ARM_TLS:
18571 return _("NT_ARM_TLS (AArch TLS registers)");
18572 case NT_ARM_HW_BREAK:
18573 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
18574 case NT_ARM_HW_WATCH:
18575 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
27456742
AK
18576 case NT_ARC_V2:
18577 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
57346661 18578 case NT_PSTATUS:
1ec5cd37 18579 return _("NT_PSTATUS (pstatus structure)");
57346661 18580 case NT_FPREGS:
1ec5cd37 18581 return _("NT_FPREGS (floating point registers)");
57346661 18582 case NT_PSINFO:
1ec5cd37 18583 return _("NT_PSINFO (psinfo structure)");
57346661 18584 case NT_LWPSTATUS:
1ec5cd37 18585 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 18586 case NT_LWPSINFO:
1ec5cd37 18587 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 18588 case NT_WIN32PSTATUS:
1ec5cd37 18589 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
18590 case NT_SIGINFO:
18591 return _("NT_SIGINFO (siginfo_t data)");
18592 case NT_FILE:
18593 return _("NT_FILE (mapped files)");
1ec5cd37
NC
18594 default:
18595 break;
18596 }
18597 else
18598 switch (e_type)
18599 {
18600 case NT_VERSION:
18601 return _("NT_VERSION (version)");
18602 case NT_ARCH:
18603 return _("NT_ARCH (architecture)");
9ef920e9 18604 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 18605 return _("OPEN");
9ef920e9 18606 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 18607 return _("func");
1ec5cd37
NC
18608 default:
18609 break;
18610 }
18611
e9e44622 18612 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 18613 return buff;
779fe533
NC
18614}
18615
32ec8896 18616static bfd_boolean
9ece1fa9
TT
18617print_core_note (Elf_Internal_Note *pnote)
18618{
18619 unsigned int addr_size = is_32bit_elf ? 4 : 8;
18620 bfd_vma count, page_size;
18621 unsigned char *descdata, *filenames, *descend;
18622
18623 if (pnote->type != NT_FILE)
04ac15ab
AS
18624 {
18625 if (do_wide)
18626 printf ("\n");
18627 return TRUE;
18628 }
9ece1fa9
TT
18629
18630#ifndef BFD64
18631 if (!is_32bit_elf)
18632 {
18633 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
18634 /* Still "successful". */
32ec8896 18635 return TRUE;
9ece1fa9
TT
18636 }
18637#endif
18638
18639 if (pnote->descsz < 2 * addr_size)
18640 {
32ec8896
NC
18641 error (_(" Malformed note - too short for header\n"));
18642 return FALSE;
9ece1fa9
TT
18643 }
18644
18645 descdata = (unsigned char *) pnote->descdata;
18646 descend = descdata + pnote->descsz;
18647
18648 if (descdata[pnote->descsz - 1] != '\0')
18649 {
32ec8896
NC
18650 error (_(" Malformed note - does not end with \\0\n"));
18651 return FALSE;
9ece1fa9
TT
18652 }
18653
18654 count = byte_get (descdata, addr_size);
18655 descdata += addr_size;
18656
18657 page_size = byte_get (descdata, addr_size);
18658 descdata += addr_size;
18659
5396a86e
AM
18660 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
18661 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 18662 {
32ec8896
NC
18663 error (_(" Malformed note - too short for supplied file count\n"));
18664 return FALSE;
9ece1fa9
TT
18665 }
18666
18667 printf (_(" Page size: "));
18668 print_vma (page_size, DEC);
18669 printf ("\n");
18670
18671 printf (_(" %*s%*s%*s\n"),
18672 (int) (2 + 2 * addr_size), _("Start"),
18673 (int) (4 + 2 * addr_size), _("End"),
18674 (int) (4 + 2 * addr_size), _("Page Offset"));
18675 filenames = descdata + count * 3 * addr_size;
595712bb 18676 while (count-- > 0)
9ece1fa9
TT
18677 {
18678 bfd_vma start, end, file_ofs;
18679
18680 if (filenames == descend)
18681 {
32ec8896
NC
18682 error (_(" Malformed note - filenames end too early\n"));
18683 return FALSE;
9ece1fa9
TT
18684 }
18685
18686 start = byte_get (descdata, addr_size);
18687 descdata += addr_size;
18688 end = byte_get (descdata, addr_size);
18689 descdata += addr_size;
18690 file_ofs = byte_get (descdata, addr_size);
18691 descdata += addr_size;
18692
18693 printf (" ");
18694 print_vma (start, FULL_HEX);
18695 printf (" ");
18696 print_vma (end, FULL_HEX);
18697 printf (" ");
18698 print_vma (file_ofs, FULL_HEX);
18699 printf ("\n %s\n", filenames);
18700
18701 filenames += 1 + strlen ((char *) filenames);
18702 }
18703
32ec8896 18704 return TRUE;
9ece1fa9
TT
18705}
18706
1118d252
RM
18707static const char *
18708get_gnu_elf_note_type (unsigned e_type)
18709{
1449284b 18710 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
18711 switch (e_type)
18712 {
18713 case NT_GNU_ABI_TAG:
18714 return _("NT_GNU_ABI_TAG (ABI version tag)");
18715 case NT_GNU_HWCAP:
18716 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
18717 case NT_GNU_BUILD_ID:
18718 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
18719 case NT_GNU_GOLD_VERSION:
18720 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
18721 case NT_GNU_PROPERTY_TYPE_0:
18722 return _("NT_GNU_PROPERTY_TYPE_0");
18723 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
18724 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
18725 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
18726 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 18727 default:
1449284b
NC
18728 {
18729 static char buff[64];
1118d252 18730
1449284b
NC
18731 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18732 return buff;
18733 }
18734 }
1118d252
RM
18735}
18736
a9eafb08
L
18737static void
18738decode_x86_compat_isa (unsigned int bitmask)
18739{
18740 while (bitmask)
18741 {
18742 unsigned int bit = bitmask & (- bitmask);
18743
18744 bitmask &= ~ bit;
18745 switch (bit)
18746 {
18747 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
18748 printf ("i486");
18749 break;
18750 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
18751 printf ("586");
18752 break;
18753 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
18754 printf ("686");
18755 break;
18756 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
18757 printf ("SSE");
18758 break;
18759 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
18760 printf ("SSE2");
18761 break;
18762 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
18763 printf ("SSE3");
18764 break;
18765 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
18766 printf ("SSSE3");
18767 break;
18768 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
18769 printf ("SSE4_1");
18770 break;
18771 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
18772 printf ("SSE4_2");
18773 break;
18774 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
18775 printf ("AVX");
18776 break;
18777 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
18778 printf ("AVX2");
18779 break;
18780 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
18781 printf ("AVX512F");
18782 break;
18783 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
18784 printf ("AVX512CD");
18785 break;
18786 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
18787 printf ("AVX512ER");
18788 break;
18789 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
18790 printf ("AVX512PF");
18791 break;
18792 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
18793 printf ("AVX512VL");
18794 break;
18795 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
18796 printf ("AVX512DQ");
18797 break;
18798 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
18799 printf ("AVX512BW");
18800 break;
65b3d26e
L
18801 default:
18802 printf (_("<unknown: %x>"), bit);
18803 break;
a9eafb08
L
18804 }
18805 if (bitmask)
18806 printf (", ");
18807 }
18808}
18809
9ef920e9 18810static void
32930e4e 18811decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 18812{
0a59decb 18813 if (!bitmask)
90c745dc
L
18814 {
18815 printf (_("<None>"));
18816 return;
18817 }
90c745dc 18818
9ef920e9
NC
18819 while (bitmask)
18820 {
1fc87489 18821 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
18822
18823 bitmask &= ~ bit;
18824 switch (bit)
18825 {
32930e4e 18826 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
18827 printf ("CMOV");
18828 break;
32930e4e 18829 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
18830 printf ("SSE");
18831 break;
32930e4e 18832 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
18833 printf ("SSE2");
18834 break;
32930e4e 18835 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
18836 printf ("SSE3");
18837 break;
32930e4e 18838 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
18839 printf ("SSSE3");
18840 break;
32930e4e 18841 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
18842 printf ("SSE4_1");
18843 break;
32930e4e 18844 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
18845 printf ("SSE4_2");
18846 break;
32930e4e 18847 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
18848 printf ("AVX");
18849 break;
32930e4e 18850 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
18851 printf ("AVX2");
18852 break;
32930e4e 18853 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
18854 printf ("FMA");
18855 break;
32930e4e 18856 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
18857 printf ("AVX512F");
18858 break;
32930e4e 18859 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
18860 printf ("AVX512CD");
18861 break;
32930e4e 18862 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
18863 printf ("AVX512ER");
18864 break;
32930e4e 18865 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
18866 printf ("AVX512PF");
18867 break;
32930e4e 18868 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
18869 printf ("AVX512VL");
18870 break;
32930e4e 18871 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
18872 printf ("AVX512DQ");
18873 break;
32930e4e 18874 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
18875 printf ("AVX512BW");
18876 break;
32930e4e 18877 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
18878 printf ("AVX512_4FMAPS");
18879 break;
32930e4e 18880 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
18881 printf ("AVX512_4VNNIW");
18882 break;
32930e4e 18883 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
18884 printf ("AVX512_BITALG");
18885 break;
32930e4e 18886 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
18887 printf ("AVX512_IFMA");
18888 break;
32930e4e 18889 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
18890 printf ("AVX512_VBMI");
18891 break;
32930e4e 18892 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
18893 printf ("AVX512_VBMI2");
18894 break;
32930e4e 18895 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
18896 printf ("AVX512_VNNI");
18897 break;
32930e4e 18898 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
18899 printf ("AVX512_BF16");
18900 break;
65b3d26e
L
18901 default:
18902 printf (_("<unknown: %x>"), bit);
18903 break;
9ef920e9
NC
18904 }
18905 if (bitmask)
18906 printf (", ");
18907 }
18908}
18909
32930e4e
L
18910static void
18911decode_x86_isa (unsigned int bitmask)
18912{
32930e4e
L
18913 while (bitmask)
18914 {
18915 unsigned int bit = bitmask & (- bitmask);
18916
18917 bitmask &= ~ bit;
18918 switch (bit)
18919 {
b0ab0693
L
18920 case GNU_PROPERTY_X86_ISA_1_BASELINE:
18921 printf ("x86-64-baseline");
18922 break;
32930e4e
L
18923 case GNU_PROPERTY_X86_ISA_1_V2:
18924 printf ("x86-64-v2");
18925 break;
18926 case GNU_PROPERTY_X86_ISA_1_V3:
18927 printf ("x86-64-v3");
18928 break;
18929 case GNU_PROPERTY_X86_ISA_1_V4:
18930 printf ("x86-64-v4");
18931 break;
18932 default:
18933 printf (_("<unknown: %x>"), bit);
18934 break;
18935 }
18936 if (bitmask)
18937 printf (", ");
18938 }
18939}
18940
ee2fdd6f 18941static void
a9eafb08 18942decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 18943{
0a59decb 18944 if (!bitmask)
90c745dc
L
18945 {
18946 printf (_("<None>"));
18947 return;
18948 }
90c745dc 18949
ee2fdd6f
L
18950 while (bitmask)
18951 {
18952 unsigned int bit = bitmask & (- bitmask);
18953
18954 bitmask &= ~ bit;
18955 switch (bit)
18956 {
18957 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 18958 printf ("IBT");
ee2fdd6f 18959 break;
48580982 18960 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 18961 printf ("SHSTK");
48580982 18962 break;
279d901e
L
18963 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
18964 printf ("LAM_U48");
18965 break;
18966 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
18967 printf ("LAM_U57");
18968 break;
ee2fdd6f
L
18969 default:
18970 printf (_("<unknown: %x>"), bit);
18971 break;
18972 }
18973 if (bitmask)
18974 printf (", ");
18975 }
18976}
18977
a9eafb08
L
18978static void
18979decode_x86_feature_2 (unsigned int bitmask)
18980{
0a59decb 18981 if (!bitmask)
90c745dc
L
18982 {
18983 printf (_("<None>"));
18984 return;
18985 }
90c745dc 18986
a9eafb08
L
18987 while (bitmask)
18988 {
18989 unsigned int bit = bitmask & (- bitmask);
18990
18991 bitmask &= ~ bit;
18992 switch (bit)
18993 {
18994 case GNU_PROPERTY_X86_FEATURE_2_X86:
18995 printf ("x86");
18996 break;
18997 case GNU_PROPERTY_X86_FEATURE_2_X87:
18998 printf ("x87");
18999 break;
19000 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19001 printf ("MMX");
19002 break;
19003 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19004 printf ("XMM");
19005 break;
19006 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19007 printf ("YMM");
19008 break;
19009 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19010 printf ("ZMM");
19011 break;
a308b89d
L
19012 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19013 printf ("TMM");
19014 break;
32930e4e
L
19015 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19016 printf ("MASK");
19017 break;
a9eafb08
L
19018 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19019 printf ("FXSR");
19020 break;
19021 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19022 printf ("XSAVE");
19023 break;
19024 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19025 printf ("XSAVEOPT");
19026 break;
19027 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19028 printf ("XSAVEC");
19029 break;
65b3d26e
L
19030 default:
19031 printf (_("<unknown: %x>"), bit);
19032 break;
a9eafb08
L
19033 }
19034 if (bitmask)
19035 printf (", ");
19036 }
19037}
19038
cd702818
SD
19039static void
19040decode_aarch64_feature_1_and (unsigned int bitmask)
19041{
19042 while (bitmask)
19043 {
19044 unsigned int bit = bitmask & (- bitmask);
19045
19046 bitmask &= ~ bit;
19047 switch (bit)
19048 {
19049 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19050 printf ("BTI");
19051 break;
19052
19053 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19054 printf ("PAC");
19055 break;
19056
19057 default:
19058 printf (_("<unknown: %x>"), bit);
19059 break;
19060 }
19061 if (bitmask)
19062 printf (", ");
19063 }
19064}
19065
9ef920e9 19066static void
dda8d76d 19067print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19068{
19069 unsigned char * ptr = (unsigned char *) pnote->descdata;
19070 unsigned char * ptr_end = ptr + pnote->descsz;
19071 unsigned int size = is_32bit_elf ? 4 : 8;
19072
19073 printf (_(" Properties: "));
19074
1fc87489 19075 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19076 {
19077 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19078 return;
19079 }
19080
6ab2c4ed 19081 while (ptr < ptr_end)
9ef920e9 19082 {
1fc87489 19083 unsigned int j;
6ab2c4ed
MC
19084 unsigned int type;
19085 unsigned int datasz;
19086
19087 if ((size_t) (ptr_end - ptr) < 8)
19088 {
19089 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19090 break;
19091 }
19092
19093 type = byte_get (ptr, 4);
19094 datasz = byte_get (ptr + 4, 4);
9ef920e9 19095
1fc87489 19096 ptr += 8;
9ef920e9 19097
6ab2c4ed 19098 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19099 {
1fc87489
L
19100 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19101 type, datasz);
9ef920e9 19102 break;
1fc87489 19103 }
9ef920e9 19104
1fc87489
L
19105 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19106 {
dda8d76d
NC
19107 if (filedata->file_header.e_machine == EM_X86_64
19108 || filedata->file_header.e_machine == EM_IAMCU
19109 || filedata->file_header.e_machine == EM_386)
1fc87489 19110 {
aa7bca9b
L
19111 unsigned int bitmask;
19112
19113 if (datasz == 4)
0a59decb 19114 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19115 else
19116 bitmask = 0;
19117
1fc87489
L
19118 switch (type)
19119 {
19120 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19121 if (datasz != 4)
aa7bca9b
L
19122 printf (_("x86 ISA used: <corrupt length: %#x> "),
19123 datasz);
1fc87489 19124 else
aa7bca9b
L
19125 {
19126 printf ("x86 ISA used: ");
19127 decode_x86_isa (bitmask);
19128 }
1fc87489 19129 goto next;
9ef920e9 19130
1fc87489 19131 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19132 if (datasz != 4)
aa7bca9b
L
19133 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19134 datasz);
1fc87489 19135 else
aa7bca9b
L
19136 {
19137 printf ("x86 ISA needed: ");
19138 decode_x86_isa (bitmask);
19139 }
1fc87489 19140 goto next;
9ef920e9 19141
ee2fdd6f 19142 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19143 if (datasz != 4)
aa7bca9b
L
19144 printf (_("x86 feature: <corrupt length: %#x> "),
19145 datasz);
ee2fdd6f 19146 else
aa7bca9b
L
19147 {
19148 printf ("x86 feature: ");
a9eafb08
L
19149 decode_x86_feature_1 (bitmask);
19150 }
19151 goto next;
19152
19153 case GNU_PROPERTY_X86_FEATURE_2_USED:
19154 if (datasz != 4)
19155 printf (_("x86 feature used: <corrupt length: %#x> "),
19156 datasz);
19157 else
19158 {
19159 printf ("x86 feature used: ");
19160 decode_x86_feature_2 (bitmask);
19161 }
19162 goto next;
19163
19164 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
19165 if (datasz != 4)
19166 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
19167 else
19168 {
19169 printf ("x86 feature needed: ");
19170 decode_x86_feature_2 (bitmask);
19171 }
19172 goto next;
19173
19174 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
19175 if (datasz != 4)
19176 printf (_("x86 ISA used: <corrupt length: %#x> "),
19177 datasz);
19178 else
19179 {
19180 printf ("x86 ISA used: ");
19181 decode_x86_compat_isa (bitmask);
19182 }
19183 goto next;
19184
19185 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
19186 if (datasz != 4)
19187 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19188 datasz);
19189 else
19190 {
19191 printf ("x86 ISA needed: ");
19192 decode_x86_compat_isa (bitmask);
aa7bca9b 19193 }
ee2fdd6f
L
19194 goto next;
19195
32930e4e
L
19196 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
19197 if (datasz != 4)
19198 printf (_("x86 ISA used: <corrupt length: %#x> "),
19199 datasz);
19200 else
19201 {
19202 printf ("x86 ISA used: ");
19203 decode_x86_compat_2_isa (bitmask);
19204 }
19205 goto next;
19206
19207 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
19208 if (datasz != 4)
19209 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19210 datasz);
19211 else
19212 {
19213 printf ("x86 ISA needed: ");
19214 decode_x86_compat_2_isa (bitmask);
19215 }
19216 goto next;
19217
1fc87489
L
19218 default:
19219 break;
19220 }
19221 }
cd702818
SD
19222 else if (filedata->file_header.e_machine == EM_AARCH64)
19223 {
19224 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
19225 {
19226 printf ("AArch64 feature: ");
19227 if (datasz != 4)
19228 printf (_("<corrupt length: %#x> "), datasz);
19229 else
19230 decode_aarch64_feature_1_and (byte_get (ptr, 4));
19231 goto next;
19232 }
19233 }
1fc87489
L
19234 }
19235 else
19236 {
19237 switch (type)
9ef920e9 19238 {
1fc87489
L
19239 case GNU_PROPERTY_STACK_SIZE:
19240 printf (_("stack size: "));
19241 if (datasz != size)
19242 printf (_("<corrupt length: %#x> "), datasz);
19243 else
19244 printf ("%#lx", (unsigned long) byte_get (ptr, size));
19245 goto next;
19246
19247 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
19248 printf ("no copy on protected ");
19249 if (datasz)
19250 printf (_("<corrupt length: %#x> "), datasz);
19251 goto next;
19252
19253 default:
9ef920e9
NC
19254 break;
19255 }
9ef920e9
NC
19256 }
19257
1fc87489
L
19258 if (type < GNU_PROPERTY_LOPROC)
19259 printf (_("<unknown type %#x data: "), type);
19260 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 19261 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
19262 else
19263 printf (_("<application-specific type %#x data: "), type);
19264 for (j = 0; j < datasz; ++j)
19265 printf ("%02x ", ptr[j] & 0xff);
19266 printf (">");
19267
dc1e8a47 19268 next:
9ef920e9 19269 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
19270 if (ptr == ptr_end)
19271 break;
1fc87489 19272
6ab2c4ed
MC
19273 if (do_wide)
19274 printf (", ");
19275 else
19276 printf ("\n\t");
9ef920e9
NC
19277 }
19278
19279 printf ("\n");
19280}
19281
32ec8896 19282static bfd_boolean
dda8d76d 19283print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 19284{
1449284b 19285 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
19286 switch (pnote->type)
19287 {
19288 case NT_GNU_BUILD_ID:
19289 {
19290 unsigned long i;
19291
19292 printf (_(" Build ID: "));
19293 for (i = 0; i < pnote->descsz; ++i)
19294 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 19295 printf ("\n");
664f90a3
TT
19296 }
19297 break;
19298
19299 case NT_GNU_ABI_TAG:
19300 {
19301 unsigned long os, major, minor, subminor;
19302 const char *osname;
19303
3102e897
NC
19304 /* PR 17531: file: 030-599401-0.004. */
19305 if (pnote->descsz < 16)
19306 {
19307 printf (_(" <corrupt GNU_ABI_TAG>\n"));
19308 break;
19309 }
19310
664f90a3
TT
19311 os = byte_get ((unsigned char *) pnote->descdata, 4);
19312 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19313 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
19314 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
19315
19316 switch (os)
19317 {
19318 case GNU_ABI_TAG_LINUX:
19319 osname = "Linux";
19320 break;
19321 case GNU_ABI_TAG_HURD:
19322 osname = "Hurd";
19323 break;
19324 case GNU_ABI_TAG_SOLARIS:
19325 osname = "Solaris";
19326 break;
19327 case GNU_ABI_TAG_FREEBSD:
19328 osname = "FreeBSD";
19329 break;
19330 case GNU_ABI_TAG_NETBSD:
19331 osname = "NetBSD";
19332 break;
14ae95f2
RM
19333 case GNU_ABI_TAG_SYLLABLE:
19334 osname = "Syllable";
19335 break;
19336 case GNU_ABI_TAG_NACL:
19337 osname = "NaCl";
19338 break;
664f90a3
TT
19339 default:
19340 osname = "Unknown";
19341 break;
19342 }
19343
19344 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
19345 major, minor, subminor);
19346 }
19347 break;
926c5385
CC
19348
19349 case NT_GNU_GOLD_VERSION:
19350 {
19351 unsigned long i;
19352
19353 printf (_(" Version: "));
19354 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
19355 printf ("%c", pnote->descdata[i]);
19356 printf ("\n");
19357 }
19358 break;
1449284b
NC
19359
19360 case NT_GNU_HWCAP:
19361 {
19362 unsigned long num_entries, mask;
19363
19364 /* Hardware capabilities information. Word 0 is the number of entries.
19365 Word 1 is a bitmask of enabled entries. The rest of the descriptor
19366 is a series of entries, where each entry is a single byte followed
19367 by a nul terminated string. The byte gives the bit number to test
19368 if enabled in the bitmask. */
19369 printf (_(" Hardware Capabilities: "));
19370 if (pnote->descsz < 8)
19371 {
32ec8896
NC
19372 error (_("<corrupt GNU_HWCAP>\n"));
19373 return FALSE;
1449284b
NC
19374 }
19375 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
19376 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19377 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
19378 /* FIXME: Add code to display the entries... */
19379 }
19380 break;
19381
9ef920e9 19382 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 19383 print_gnu_property_note (filedata, pnote);
9ef920e9 19384 break;
9abca702 19385
1449284b
NC
19386 default:
19387 /* Handle unrecognised types. An error message should have already been
19388 created by get_gnu_elf_note_type(), so all that we need to do is to
19389 display the data. */
19390 {
19391 unsigned long i;
19392
19393 printf (_(" Description data: "));
19394 for (i = 0; i < pnote->descsz; ++i)
19395 printf ("%02x ", pnote->descdata[i] & 0xff);
19396 printf ("\n");
19397 }
19398 break;
664f90a3
TT
19399 }
19400
32ec8896 19401 return TRUE;
664f90a3
TT
19402}
19403
685080f2
NC
19404static const char *
19405get_v850_elf_note_type (enum v850_notes n_type)
19406{
19407 static char buff[64];
19408
19409 switch (n_type)
19410 {
19411 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
19412 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
19413 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
19414 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
19415 case V850_NOTE_CACHE_INFO: return _("Use of cache");
19416 case V850_NOTE_MMU_INFO: return _("Use of MMU");
19417 default:
19418 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
19419 return buff;
19420 }
19421}
19422
32ec8896 19423static bfd_boolean
685080f2
NC
19424print_v850_note (Elf_Internal_Note * pnote)
19425{
19426 unsigned int val;
19427
19428 if (pnote->descsz != 4)
32ec8896
NC
19429 return FALSE;
19430
685080f2
NC
19431 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
19432
19433 if (val == 0)
19434 {
19435 printf (_("not set\n"));
32ec8896 19436 return TRUE;
685080f2
NC
19437 }
19438
19439 switch (pnote->type)
19440 {
19441 case V850_NOTE_ALIGNMENT:
19442 switch (val)
19443 {
32ec8896
NC
19444 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return TRUE;
19445 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return TRUE;
685080f2
NC
19446 }
19447 break;
14ae95f2 19448
685080f2
NC
19449 case V850_NOTE_DATA_SIZE:
19450 switch (val)
19451 {
32ec8896
NC
19452 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return TRUE;
19453 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return TRUE;
685080f2
NC
19454 }
19455 break;
14ae95f2 19456
685080f2
NC
19457 case V850_NOTE_FPU_INFO:
19458 switch (val)
19459 {
32ec8896
NC
19460 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return TRUE;
19461 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return TRUE;
685080f2
NC
19462 }
19463 break;
14ae95f2 19464
685080f2
NC
19465 case V850_NOTE_MMU_INFO:
19466 case V850_NOTE_CACHE_INFO:
19467 case V850_NOTE_SIMD_INFO:
19468 if (val == EF_RH850_SIMD)
19469 {
19470 printf (_("yes\n"));
32ec8896 19471 return TRUE;
685080f2
NC
19472 }
19473 break;
19474
19475 default:
19476 /* An 'unknown note type' message will already have been displayed. */
19477 break;
19478 }
19479
19480 printf (_("unknown value: %x\n"), val);
32ec8896 19481 return FALSE;
685080f2
NC
19482}
19483
32ec8896 19484static bfd_boolean
c6056a74
SF
19485process_netbsd_elf_note (Elf_Internal_Note * pnote)
19486{
19487 unsigned int version;
19488
19489 switch (pnote->type)
19490 {
19491 case NT_NETBSD_IDENT:
b966f55f
AM
19492 if (pnote->descsz < 1)
19493 break;
c6056a74
SF
19494 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19495 if ((version / 10000) % 100)
b966f55f 19496 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
19497 version, version / 100000000, (version / 1000000) % 100,
19498 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 19499 'A' + (version / 10000) % 26);
c6056a74
SF
19500 else
19501 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 19502 version, version / 100000000, (version / 1000000) % 100,
15f205b1 19503 (version / 100) % 100);
32ec8896 19504 return TRUE;
c6056a74
SF
19505
19506 case NT_NETBSD_MARCH:
9abca702 19507 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 19508 pnote->descdata);
32ec8896 19509 return TRUE;
c6056a74 19510
9abca702
CZ
19511#ifdef NT_NETBSD_PAX
19512 case NT_NETBSD_PAX:
b966f55f
AM
19513 if (pnote->descsz < 1)
19514 break;
9abca702
CZ
19515 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19516 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
19517 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
19518 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
19519 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
19520 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
19521 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
19522 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
19523 return TRUE;
19524#endif
c6056a74 19525 }
b966f55f
AM
19526
19527 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
19528 pnote->descsz, pnote->type);
19529 return FALSE;
c6056a74
SF
19530}
19531
f4ddf30f 19532static const char *
dda8d76d 19533get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 19534{
f4ddf30f
JB
19535 switch (e_type)
19536 {
19537 case NT_FREEBSD_THRMISC:
19538 return _("NT_THRMISC (thrmisc structure)");
19539 case NT_FREEBSD_PROCSTAT_PROC:
19540 return _("NT_PROCSTAT_PROC (proc data)");
19541 case NT_FREEBSD_PROCSTAT_FILES:
19542 return _("NT_PROCSTAT_FILES (files data)");
19543 case NT_FREEBSD_PROCSTAT_VMMAP:
19544 return _("NT_PROCSTAT_VMMAP (vmmap data)");
19545 case NT_FREEBSD_PROCSTAT_GROUPS:
19546 return _("NT_PROCSTAT_GROUPS (groups data)");
19547 case NT_FREEBSD_PROCSTAT_UMASK:
19548 return _("NT_PROCSTAT_UMASK (umask data)");
19549 case NT_FREEBSD_PROCSTAT_RLIMIT:
19550 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
19551 case NT_FREEBSD_PROCSTAT_OSREL:
19552 return _("NT_PROCSTAT_OSREL (osreldate data)");
19553 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
19554 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
19555 case NT_FREEBSD_PROCSTAT_AUXV:
19556 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
19557 case NT_FREEBSD_PTLWPINFO:
19558 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 19559 }
dda8d76d 19560 return get_note_type (filedata, e_type);
f4ddf30f
JB
19561}
19562
9437c45b 19563static const char *
dda8d76d 19564get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
19565{
19566 static char buff[64];
19567
540e6170
CZ
19568 switch (e_type)
19569 {
19570 case NT_NETBSDCORE_PROCINFO:
19571 /* NetBSD core "procinfo" structure. */
19572 return _("NetBSD procinfo structure");
9437c45b 19573
540e6170
CZ
19574#ifdef NT_NETBSDCORE_AUXV
19575 case NT_NETBSDCORE_AUXV:
19576 return _("NetBSD ELF auxiliary vector data");
19577#endif
9437c45b 19578
06d949ec
KR
19579#ifdef NT_NETBSDCORE_LWPSTATUS
19580 case NT_NETBSDCORE_LWPSTATUS:
19581 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
19582#endif
19583
540e6170 19584 default:
06d949ec 19585 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
19586 defined for NetBSD core files. If the note type is less
19587 than the start of the machine-dependent note types, we don't
19588 understand it. */
19589
19590 if (e_type < NT_NETBSDCORE_FIRSTMACH)
19591 {
19592 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19593 return buff;
19594 }
19595 break;
9437c45b
JT
19596 }
19597
dda8d76d 19598 switch (filedata->file_header.e_machine)
9437c45b
JT
19599 {
19600 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
19601 and PT_GETFPREGS == mach+2. */
19602
19603 case EM_OLD_ALPHA:
19604 case EM_ALPHA:
19605 case EM_SPARC:
19606 case EM_SPARC32PLUS:
19607 case EM_SPARCV9:
19608 switch (e_type)
19609 {
2b692964 19610 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 19611 return _("PT_GETREGS (reg structure)");
2b692964 19612 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 19613 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19614 default:
19615 break;
19616 }
19617 break;
19618
c0d38b0e
CZ
19619 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
19620 There's also old PT___GETREGS40 == mach + 1 for old reg
19621 structure which lacks GBR. */
19622 case EM_SH:
19623 switch (e_type)
19624 {
19625 case NT_NETBSDCORE_FIRSTMACH + 1:
19626 return _("PT___GETREGS40 (old reg structure)");
19627 case NT_NETBSDCORE_FIRSTMACH + 3:
19628 return _("PT_GETREGS (reg structure)");
19629 case NT_NETBSDCORE_FIRSTMACH + 5:
19630 return _("PT_GETFPREGS (fpreg structure)");
19631 default:
19632 break;
19633 }
19634 break;
19635
9437c45b
JT
19636 /* On all other arch's, PT_GETREGS == mach+1 and
19637 PT_GETFPREGS == mach+3. */
19638 default:
19639 switch (e_type)
19640 {
2b692964 19641 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 19642 return _("PT_GETREGS (reg structure)");
2b692964 19643 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 19644 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19645 default:
19646 break;
19647 }
19648 }
19649
9cf03b7e 19650 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 19651 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
19652 return buff;
19653}
19654
70616151
TT
19655static const char *
19656get_stapsdt_note_type (unsigned e_type)
19657{
19658 static char buff[64];
19659
19660 switch (e_type)
19661 {
19662 case NT_STAPSDT:
19663 return _("NT_STAPSDT (SystemTap probe descriptors)");
19664
19665 default:
19666 break;
19667 }
19668
19669 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19670 return buff;
19671}
19672
32ec8896 19673static bfd_boolean
c6a9fc58
TT
19674print_stapsdt_note (Elf_Internal_Note *pnote)
19675{
3ca60c57
NC
19676 size_t len, maxlen;
19677 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
19678 char *data = pnote->descdata;
19679 char *data_end = pnote->descdata + pnote->descsz;
19680 bfd_vma pc, base_addr, semaphore;
19681 char *provider, *probe, *arg_fmt;
19682
3ca60c57
NC
19683 if (pnote->descsz < (addr_size * 3))
19684 goto stapdt_note_too_small;
19685
c6a9fc58
TT
19686 pc = byte_get ((unsigned char *) data, addr_size);
19687 data += addr_size;
3ca60c57 19688
c6a9fc58
TT
19689 base_addr = byte_get ((unsigned char *) data, addr_size);
19690 data += addr_size;
3ca60c57 19691
c6a9fc58
TT
19692 semaphore = byte_get ((unsigned char *) data, addr_size);
19693 data += addr_size;
19694
3ca60c57
NC
19695 if (data >= data_end)
19696 goto stapdt_note_too_small;
19697 maxlen = data_end - data;
19698 len = strnlen (data, maxlen);
19699 if (len < maxlen)
19700 {
19701 provider = data;
19702 data += len + 1;
19703 }
19704 else
19705 goto stapdt_note_too_small;
19706
19707 if (data >= data_end)
19708 goto stapdt_note_too_small;
19709 maxlen = data_end - data;
19710 len = strnlen (data, maxlen);
19711 if (len < maxlen)
19712 {
19713 probe = data;
19714 data += len + 1;
19715 }
19716 else
19717 goto stapdt_note_too_small;
9abca702 19718
3ca60c57
NC
19719 if (data >= data_end)
19720 goto stapdt_note_too_small;
19721 maxlen = data_end - data;
19722 len = strnlen (data, maxlen);
19723 if (len < maxlen)
19724 {
19725 arg_fmt = data;
19726 data += len + 1;
19727 }
19728 else
19729 goto stapdt_note_too_small;
c6a9fc58
TT
19730
19731 printf (_(" Provider: %s\n"), provider);
19732 printf (_(" Name: %s\n"), probe);
19733 printf (_(" Location: "));
19734 print_vma (pc, FULL_HEX);
19735 printf (_(", Base: "));
19736 print_vma (base_addr, FULL_HEX);
19737 printf (_(", Semaphore: "));
19738 print_vma (semaphore, FULL_HEX);
9cf03b7e 19739 printf ("\n");
c6a9fc58
TT
19740 printf (_(" Arguments: %s\n"), arg_fmt);
19741
19742 return data == data_end;
3ca60c57
NC
19743
19744 stapdt_note_too_small:
19745 printf (_(" <corrupt - note is too small>\n"));
19746 error (_("corrupt stapdt note - the data size is too small\n"));
19747 return FALSE;
c6a9fc58
TT
19748}
19749
00e98fc7
TG
19750static const char *
19751get_ia64_vms_note_type (unsigned e_type)
19752{
19753 static char buff[64];
19754
19755 switch (e_type)
19756 {
19757 case NT_VMS_MHD:
19758 return _("NT_VMS_MHD (module header)");
19759 case NT_VMS_LNM:
19760 return _("NT_VMS_LNM (language name)");
19761 case NT_VMS_SRC:
19762 return _("NT_VMS_SRC (source files)");
19763 case NT_VMS_TITLE:
9cf03b7e 19764 return "NT_VMS_TITLE";
00e98fc7
TG
19765 case NT_VMS_EIDC:
19766 return _("NT_VMS_EIDC (consistency check)");
19767 case NT_VMS_FPMODE:
19768 return _("NT_VMS_FPMODE (FP mode)");
19769 case NT_VMS_LINKTIME:
9cf03b7e 19770 return "NT_VMS_LINKTIME";
00e98fc7
TG
19771 case NT_VMS_IMGNAM:
19772 return _("NT_VMS_IMGNAM (image name)");
19773 case NT_VMS_IMGID:
19774 return _("NT_VMS_IMGID (image id)");
19775 case NT_VMS_LINKID:
19776 return _("NT_VMS_LINKID (link id)");
19777 case NT_VMS_IMGBID:
19778 return _("NT_VMS_IMGBID (build id)");
19779 case NT_VMS_GSTNAM:
19780 return _("NT_VMS_GSTNAM (sym table name)");
19781 case NT_VMS_ORIG_DYN:
9cf03b7e 19782 return "NT_VMS_ORIG_DYN";
00e98fc7 19783 case NT_VMS_PATCHTIME:
9cf03b7e 19784 return "NT_VMS_PATCHTIME";
00e98fc7
TG
19785 default:
19786 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19787 return buff;
19788 }
19789}
19790
32ec8896 19791static bfd_boolean
00e98fc7
TG
19792print_ia64_vms_note (Elf_Internal_Note * pnote)
19793{
8d18bf79
NC
19794 int maxlen = pnote->descsz;
19795
19796 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
19797 goto desc_size_fail;
19798
00e98fc7
TG
19799 switch (pnote->type)
19800 {
19801 case NT_VMS_MHD:
8d18bf79
NC
19802 if (maxlen <= 36)
19803 goto desc_size_fail;
19804
19805 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
19806
19807 printf (_(" Creation date : %.17s\n"), pnote->descdata);
19808 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
19809 if (l + 34 < maxlen)
19810 {
19811 printf (_(" Module name : %s\n"), pnote->descdata + 34);
19812 if (l + 35 < maxlen)
19813 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
19814 else
19815 printf (_(" Module version : <missing>\n"));
19816 }
00e98fc7 19817 else
8d18bf79
NC
19818 {
19819 printf (_(" Module name : <missing>\n"));
19820 printf (_(" Module version : <missing>\n"));
19821 }
00e98fc7 19822 break;
8d18bf79 19823
00e98fc7 19824 case NT_VMS_LNM:
8d18bf79 19825 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19826 break;
8d18bf79 19827
00e98fc7
TG
19828#ifdef BFD64
19829 case NT_VMS_FPMODE:
9cf03b7e 19830 printf (_(" Floating Point mode: "));
8d18bf79
NC
19831 if (maxlen < 8)
19832 goto desc_size_fail;
19833 /* FIXME: Generate an error if descsz > 8 ? */
19834
4a5cb34f 19835 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 19836 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 19837 break;
8d18bf79 19838
00e98fc7
TG
19839 case NT_VMS_LINKTIME:
19840 printf (_(" Link time: "));
8d18bf79
NC
19841 if (maxlen < 8)
19842 goto desc_size_fail;
19843 /* FIXME: Generate an error if descsz > 8 ? */
19844
00e98fc7 19845 print_vms_time
8d18bf79 19846 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19847 printf ("\n");
19848 break;
8d18bf79 19849
00e98fc7
TG
19850 case NT_VMS_PATCHTIME:
19851 printf (_(" Patch time: "));
8d18bf79
NC
19852 if (maxlen < 8)
19853 goto desc_size_fail;
19854 /* FIXME: Generate an error if descsz > 8 ? */
19855
00e98fc7 19856 print_vms_time
8d18bf79 19857 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19858 printf ("\n");
19859 break;
8d18bf79 19860
00e98fc7 19861 case NT_VMS_ORIG_DYN:
8d18bf79
NC
19862 if (maxlen < 34)
19863 goto desc_size_fail;
19864
00e98fc7
TG
19865 printf (_(" Major id: %u, minor id: %u\n"),
19866 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
19867 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 19868 printf (_(" Last modified : "));
00e98fc7
TG
19869 print_vms_time
19870 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 19871 printf (_("\n Link flags : "));
4a5cb34f 19872 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 19873 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 19874 printf (_(" Header flags: 0x%08x\n"),
948f632f 19875 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 19876 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
19877 break;
19878#endif
8d18bf79 19879
00e98fc7 19880 case NT_VMS_IMGNAM:
8d18bf79 19881 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19882 break;
8d18bf79 19883
00e98fc7 19884 case NT_VMS_GSTNAM:
8d18bf79 19885 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19886 break;
8d18bf79 19887
00e98fc7 19888 case NT_VMS_IMGID:
8d18bf79 19889 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19890 break;
8d18bf79 19891
00e98fc7 19892 case NT_VMS_LINKID:
8d18bf79 19893 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19894 break;
8d18bf79 19895
00e98fc7 19896 default:
32ec8896 19897 return FALSE;
00e98fc7 19898 }
8d18bf79 19899
32ec8896 19900 return TRUE;
8d18bf79
NC
19901
19902 desc_size_fail:
19903 printf (_(" <corrupt - data size is too small>\n"));
19904 error (_("corrupt IA64 note: data size is too small\n"));
19905 return FALSE;
00e98fc7
TG
19906}
19907
fd486f32
AM
19908struct build_attr_cache {
19909 Filedata *filedata;
19910 char *strtab;
19911 unsigned long strtablen;
19912 Elf_Internal_Sym *symtab;
19913 unsigned long nsyms;
19914} ba_cache;
19915
6f156d7a
NC
19916/* Find the symbol associated with a build attribute that is attached
19917 to address OFFSET. If PNAME is non-NULL then store the name of
19918 the symbol (if found) in the provided pointer, Returns NULL if a
19919 symbol could not be found. */
c799a79d 19920
6f156d7a
NC
19921static Elf_Internal_Sym *
19922get_symbol_for_build_attribute (Filedata * filedata,
19923 unsigned long offset,
19924 bfd_boolean is_open_attr,
19925 const char ** pname)
9ef920e9 19926{
fd486f32
AM
19927 Elf_Internal_Sym *saved_sym = NULL;
19928 Elf_Internal_Sym *sym;
9ef920e9 19929
dda8d76d 19930 if (filedata->section_headers != NULL
fd486f32 19931 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 19932 {
c799a79d 19933 Elf_Internal_Shdr * symsec;
9ef920e9 19934
fd486f32
AM
19935 free (ba_cache.strtab);
19936 ba_cache.strtab = NULL;
19937 free (ba_cache.symtab);
19938 ba_cache.symtab = NULL;
19939
c799a79d 19940 /* Load the symbol and string sections. */
dda8d76d
NC
19941 for (symsec = filedata->section_headers;
19942 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 19943 symsec ++)
9ef920e9 19944 {
28d13567
AM
19945 if (symsec->sh_type == SHT_SYMTAB
19946 && get_symtab (filedata, symsec,
19947 &ba_cache.symtab, &ba_cache.nsyms,
19948 &ba_cache.strtab, &ba_cache.strtablen))
19949 break;
9ef920e9 19950 }
fd486f32 19951 ba_cache.filedata = filedata;
9ef920e9
NC
19952 }
19953
fd486f32 19954 if (ba_cache.symtab == NULL)
6f156d7a 19955 return NULL;
9ef920e9 19956
c799a79d 19957 /* Find a symbol whose value matches offset. */
fd486f32 19958 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
19959 if (sym->st_value == offset)
19960 {
fd486f32 19961 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
19962 /* Huh ? This should not happen. */
19963 continue;
9ef920e9 19964
fd486f32 19965 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 19966 continue;
9ef920e9 19967
8fd75781
NC
19968 /* The AArch64 and ARM architectures define mapping symbols
19969 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
19970 if (ba_cache.strtab[sym->st_name] == '$'
19971 && ba_cache.strtab[sym->st_name + 1] != 0
19972 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
19973 continue;
19974
c799a79d
NC
19975 if (is_open_attr)
19976 {
19977 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
19978 and FILE or OBJECT symbols over NOTYPE symbols. We skip
19979 FUNC symbols entirely. */
19980 switch (ELF_ST_TYPE (sym->st_info))
19981 {
c799a79d 19982 case STT_OBJECT:
6f156d7a 19983 case STT_FILE:
c799a79d 19984 saved_sym = sym;
6f156d7a
NC
19985 if (sym->st_size)
19986 {
19987 /* If the symbol has a size associated
19988 with it then we can stop searching. */
fd486f32 19989 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 19990 }
c799a79d 19991 continue;
9ef920e9 19992
c799a79d
NC
19993 case STT_FUNC:
19994 /* Ignore function symbols. */
19995 continue;
19996
19997 default:
19998 break;
19999 }
20000
20001 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20002 {
c799a79d
NC
20003 case STB_GLOBAL:
20004 if (saved_sym == NULL
20005 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20006 saved_sym = sym;
20007 break;
c871dade 20008
c799a79d
NC
20009 case STB_LOCAL:
20010 if (saved_sym == NULL)
20011 saved_sym = sym;
20012 break;
20013
20014 default:
9ef920e9
NC
20015 break;
20016 }
20017 }
c799a79d
NC
20018 else
20019 {
20020 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20021 continue;
20022
20023 saved_sym = sym;
20024 break;
20025 }
20026 }
20027
6f156d7a 20028 if (saved_sym && pname)
fd486f32 20029 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20030
20031 return saved_sym;
c799a79d
NC
20032}
20033
d20e98ab
NC
20034/* Returns true iff addr1 and addr2 are in the same section. */
20035
20036static bfd_boolean
20037same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20038{
20039 Elf_Internal_Shdr * a1;
20040 Elf_Internal_Shdr * a2;
20041
20042 a1 = find_section_by_address (filedata, addr1);
20043 a2 = find_section_by_address (filedata, addr2);
9abca702 20044
d20e98ab
NC
20045 return a1 == a2 && a1 != NULL;
20046}
20047
c799a79d 20048static bfd_boolean
dda8d76d
NC
20049print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20050 Filedata * filedata)
c799a79d 20051{
6f156d7a
NC
20052 static unsigned long global_offset = 0;
20053 static unsigned long global_end = 0;
20054 static unsigned long func_offset = 0;
20055 static unsigned long func_end = 0;
c871dade 20056
6f156d7a
NC
20057 Elf_Internal_Sym * sym;
20058 const char * name;
20059 unsigned long start;
20060 unsigned long end;
20061 bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
20062
20063 switch (pnote->descsz)
c799a79d 20064 {
6f156d7a
NC
20065 case 0:
20066 /* A zero-length description means that the range of
20067 the previous note of the same type should be used. */
c799a79d 20068 if (is_open_attr)
c871dade 20069 {
6f156d7a
NC
20070 if (global_end > global_offset)
20071 printf (_(" Applies to region from %#lx to %#lx\n"),
20072 global_offset, global_end);
20073 else
20074 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20075 }
20076 else
20077 {
6f156d7a
NC
20078 if (func_end > func_offset)
20079 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20080 else
20081 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20082 }
6f156d7a 20083 return TRUE;
9ef920e9 20084
6f156d7a
NC
20085 case 4:
20086 start = byte_get ((unsigned char *) pnote->descdata, 4);
20087 end = 0;
20088 break;
20089
20090 case 8:
c74147bb
NC
20091 start = byte_get ((unsigned char *) pnote->descdata, 4);
20092 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20093 break;
20094
20095 case 16:
20096 start = byte_get ((unsigned char *) pnote->descdata, 8);
20097 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20098 break;
9abca702 20099
6f156d7a 20100 default:
c799a79d
NC
20101 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
20102 printf (_(" <invalid descsz>"));
20103 return FALSE;
20104 }
20105
6f156d7a
NC
20106 name = NULL;
20107 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
20108 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
20109 in order to avoid them being confused with the start address of the
20110 first function in the file... */
20111 if (sym == NULL && is_open_attr)
20112 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
20113 & name);
6f156d7a
NC
20114
20115 if (end == 0 && sym != NULL && sym->st_size > 0)
20116 end = start + sym->st_size;
c799a79d
NC
20117
20118 if (is_open_attr)
20119 {
d20e98ab
NC
20120 /* FIXME: Need to properly allow for section alignment.
20121 16 is just the alignment used on x86_64. */
20122 if (global_end > 0
20123 && start > BFD_ALIGN (global_end, 16)
20124 /* Build notes are not guaranteed to be organised in order of
20125 increasing address, but we should find the all of the notes
20126 for one section in the same place. */
20127 && same_section (filedata, start, global_end))
6f156d7a
NC
20128 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
20129 global_end + 1, start - 1);
20130
20131 printf (_(" Applies to region from %#lx"), start);
20132 global_offset = start;
20133
20134 if (end)
20135 {
20136 printf (_(" to %#lx"), end);
20137 global_end = end;
20138 }
c799a79d
NC
20139 }
20140 else
20141 {
6f156d7a
NC
20142 printf (_(" Applies to region from %#lx"), start);
20143 func_offset = start;
20144
20145 if (end)
20146 {
20147 printf (_(" to %#lx"), end);
20148 func_end = end;
20149 }
c799a79d
NC
20150 }
20151
6f156d7a
NC
20152 if (sym && name)
20153 printf (_(" (%s)"), name);
20154
20155 printf ("\n");
20156 return TRUE;
9ef920e9
NC
20157}
20158
20159static bfd_boolean
20160print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
20161{
1d15e434
NC
20162 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
20163 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
20164 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
20165 char name_type;
20166 char name_attribute;
1d15e434 20167 const char * expected_types;
9ef920e9
NC
20168 const char * name = pnote->namedata;
20169 const char * text;
88305e1b 20170 signed int left;
9ef920e9
NC
20171
20172 if (name == NULL || pnote->namesz < 2)
20173 {
20174 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 20175 print_symbol (-20, _(" <corrupt name>"));
9ef920e9
NC
20176 return FALSE;
20177 }
20178
6f156d7a
NC
20179 if (do_wide)
20180 left = 28;
20181 else
20182 left = 20;
88305e1b
NC
20183
20184 /* Version 2 of the spec adds a "GA" prefix to the name field. */
20185 if (name[0] == 'G' && name[1] == 'A')
20186 {
6f156d7a
NC
20187 if (pnote->namesz < 4)
20188 {
20189 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
20190 print_symbol (-20, _(" <corrupt name>"));
20191 return FALSE;
20192 }
20193
88305e1b
NC
20194 printf ("GA");
20195 name += 2;
20196 left -= 2;
20197 }
20198
9ef920e9
NC
20199 switch ((name_type = * name))
20200 {
20201 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20202 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20203 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20204 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20205 printf ("%c", * name);
88305e1b 20206 left --;
9ef920e9
NC
20207 break;
20208 default:
20209 error (_("unrecognised attribute type in name field: %d\n"), name_type);
20210 print_symbol (-20, _("<unknown name type>"));
20211 return FALSE;
20212 }
20213
9ef920e9
NC
20214 ++ name;
20215 text = NULL;
20216
20217 switch ((name_attribute = * name))
20218 {
20219 case GNU_BUILD_ATTRIBUTE_VERSION:
20220 text = _("<version>");
1d15e434 20221 expected_types = string_expected;
9ef920e9
NC
20222 ++ name;
20223 break;
20224 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20225 text = _("<stack prot>");
75d7d298 20226 expected_types = "!+*";
9ef920e9
NC
20227 ++ name;
20228 break;
20229 case GNU_BUILD_ATTRIBUTE_RELRO:
20230 text = _("<relro>");
1d15e434 20231 expected_types = bool_expected;
9ef920e9
NC
20232 ++ name;
20233 break;
20234 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
20235 text = _("<stack size>");
1d15e434 20236 expected_types = number_expected;
9ef920e9
NC
20237 ++ name;
20238 break;
20239 case GNU_BUILD_ATTRIBUTE_TOOL:
20240 text = _("<tool>");
1d15e434 20241 expected_types = string_expected;
9ef920e9
NC
20242 ++ name;
20243 break;
20244 case GNU_BUILD_ATTRIBUTE_ABI:
20245 text = _("<ABI>");
20246 expected_types = "$*";
20247 ++ name;
20248 break;
20249 case GNU_BUILD_ATTRIBUTE_PIC:
20250 text = _("<PIC>");
1d15e434 20251 expected_types = number_expected;
9ef920e9
NC
20252 ++ name;
20253 break;
a8be5506
NC
20254 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
20255 text = _("<short enum>");
1d15e434 20256 expected_types = bool_expected;
a8be5506
NC
20257 ++ name;
20258 break;
9ef920e9
NC
20259 default:
20260 if (ISPRINT (* name))
20261 {
20262 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
20263
20264 if (len > left && ! do_wide)
20265 len = left;
75d7d298 20266 printf ("%.*s:", len, name);
9ef920e9 20267 left -= len;
0dd6ae21 20268 name += len;
9ef920e9
NC
20269 }
20270 else
20271 {
3e6b6445 20272 static char tmpbuf [128];
88305e1b 20273
3e6b6445
NC
20274 error (_("unrecognised byte in name field: %d\n"), * name);
20275 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
20276 text = tmpbuf;
20277 name ++;
9ef920e9
NC
20278 }
20279 expected_types = "*$!+";
20280 break;
20281 }
20282
20283 if (text)
88305e1b 20284 left -= printf ("%s", text);
9ef920e9
NC
20285
20286 if (strchr (expected_types, name_type) == NULL)
75d7d298 20287 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
20288
20289 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
20290 {
20291 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
20292 (unsigned long) pnote->namesz,
20293 (long) (name - pnote->namedata));
20294 return FALSE;
20295 }
20296
20297 if (left < 1 && ! do_wide)
20298 return TRUE;
20299
20300 switch (name_type)
20301 {
20302 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20303 {
b06b2c92 20304 unsigned int bytes;
ddef72cd
NC
20305 unsigned long long val = 0;
20306 unsigned int shift = 0;
20307 char * decoded = NULL;
20308
b06b2c92
NC
20309 bytes = pnote->namesz - (name - pnote->namedata);
20310 if (bytes > 0)
20311 /* The -1 is because the name field is always 0 terminated, and we
20312 want to be able to ensure that the shift in the while loop below
20313 will not overflow. */
20314 -- bytes;
20315
ddef72cd
NC
20316 if (bytes > sizeof (val))
20317 {
3e6b6445
NC
20318 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
20319 bytes);
20320 bytes = sizeof (val);
ddef72cd 20321 }
3e6b6445
NC
20322 /* We do not bother to warn if bytes == 0 as this can
20323 happen with some early versions of the gcc plugin. */
9ef920e9
NC
20324
20325 while (bytes --)
20326 {
54b8331d 20327 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
20328
20329 val |= byte << shift;
9ef920e9
NC
20330 shift += 8;
20331 }
20332
75d7d298 20333 switch (name_attribute)
9ef920e9 20334 {
75d7d298 20335 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
20336 switch (val)
20337 {
75d7d298
NC
20338 case 0: decoded = "static"; break;
20339 case 1: decoded = "pic"; break;
20340 case 2: decoded = "PIC"; break;
20341 case 3: decoded = "pie"; break;
20342 case 4: decoded = "PIE"; break;
20343 default: break;
9ef920e9 20344 }
75d7d298
NC
20345 break;
20346 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20347 switch (val)
9ef920e9 20348 {
75d7d298
NC
20349 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
20350 case 0: decoded = "off"; break;
20351 case 1: decoded = "on"; break;
20352 case 2: decoded = "all"; break;
20353 case 3: decoded = "strong"; break;
20354 case 4: decoded = "explicit"; break;
20355 default: break;
9ef920e9 20356 }
75d7d298
NC
20357 break;
20358 default:
20359 break;
9ef920e9
NC
20360 }
20361
75d7d298 20362 if (decoded != NULL)
3e6b6445
NC
20363 {
20364 print_symbol (-left, decoded);
20365 left = 0;
20366 }
20367 else if (val == 0)
20368 {
20369 printf ("0x0");
20370 left -= 3;
20371 }
9ef920e9 20372 else
75d7d298
NC
20373 {
20374 if (do_wide)
ddef72cd 20375 left -= printf ("0x%llx", val);
75d7d298 20376 else
ddef72cd 20377 left -= printf ("0x%-.*llx", left, val);
75d7d298 20378 }
9ef920e9
NC
20379 }
20380 break;
20381 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20382 left -= print_symbol (- left, name);
20383 break;
20384 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20385 left -= print_symbol (- left, "true");
20386 break;
20387 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20388 left -= print_symbol (- left, "false");
20389 break;
20390 }
20391
20392 if (do_wide && left > 0)
20393 printf ("%-*s", left, " ");
9abca702 20394
9ef920e9
NC
20395 return TRUE;
20396}
20397
6d118b09
NC
20398/* Note that by the ELF standard, the name field is already null byte
20399 terminated, and namesz includes the terminating null byte.
20400 I.E. the value of namesz for the name "FSF" is 4.
20401
e3c8793a 20402 If the value of namesz is zero, there is no name present. */
9ef920e9 20403
32ec8896 20404static bfd_boolean
9ef920e9 20405process_note (Elf_Internal_Note * pnote,
dda8d76d 20406 Filedata * filedata)
779fe533 20407{
2cf0635d
NC
20408 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
20409 const char * nt;
9437c45b
JT
20410
20411 if (pnote->namesz == 0)
1ec5cd37
NC
20412 /* If there is no note name, then use the default set of
20413 note type strings. */
dda8d76d 20414 nt = get_note_type (filedata, pnote->type);
1ec5cd37 20415
1118d252
RM
20416 else if (const_strneq (pnote->namedata, "GNU"))
20417 /* GNU-specific object file notes. */
20418 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
20419
20420 else if (const_strneq (pnote->namedata, "FreeBSD"))
20421 /* FreeBSD-specific core file notes. */
dda8d76d 20422 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 20423
0112cd26 20424 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 20425 /* NetBSD-specific core file notes. */
dda8d76d 20426 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 20427
c6056a74
SF
20428 else if (const_strneq (pnote->namedata, "NetBSD"))
20429 /* NetBSD-specific core file notes. */
20430 return process_netbsd_elf_note (pnote);
20431
9abca702
CZ
20432 else if (const_strneq (pnote->namedata, "PaX"))
20433 /* NetBSD-specific core file notes. */
20434 return process_netbsd_elf_note (pnote);
20435
b15fa79e
AM
20436 else if (strneq (pnote->namedata, "SPU/", 4))
20437 {
20438 /* SPU-specific core file notes. */
20439 nt = pnote->namedata + 4;
20440 name = "SPU";
20441 }
20442
00e98fc7
TG
20443 else if (const_strneq (pnote->namedata, "IPF/VMS"))
20444 /* VMS/ia64-specific file notes. */
20445 nt = get_ia64_vms_note_type (pnote->type);
20446
70616151
TT
20447 else if (const_strneq (pnote->namedata, "stapsdt"))
20448 nt = get_stapsdt_note_type (pnote->type);
20449
9437c45b 20450 else
1ec5cd37
NC
20451 /* Don't recognize this note name; just use the default set of
20452 note type strings. */
dda8d76d 20453 nt = get_note_type (filedata, pnote->type);
9437c45b 20454
1449284b 20455 printf (" ");
9ef920e9 20456
483767a3
AM
20457 if (((const_strneq (pnote->namedata, "GA")
20458 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20459 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20460 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20461 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
20462 print_gnu_build_attribute_name (pnote);
20463 else
20464 print_symbol (-20, name);
20465
20466 if (do_wide)
20467 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
20468 else
20469 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7
TG
20470
20471 if (const_strneq (pnote->namedata, "IPF/VMS"))
20472 return print_ia64_vms_note (pnote);
664f90a3 20473 else if (const_strneq (pnote->namedata, "GNU"))
dda8d76d 20474 return print_gnu_note (filedata, pnote);
c6a9fc58
TT
20475 else if (const_strneq (pnote->namedata, "stapsdt"))
20476 return print_stapsdt_note (pnote);
9ece1fa9
TT
20477 else if (const_strneq (pnote->namedata, "CORE"))
20478 return print_core_note (pnote);
483767a3
AM
20479 else if (((const_strneq (pnote->namedata, "GA")
20480 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20481 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20482 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20483 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 20484 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 20485
9ef920e9 20486 if (pnote->descsz)
1449284b
NC
20487 {
20488 unsigned long i;
20489
20490 printf (_(" description data: "));
20491 for (i = 0; i < pnote->descsz; i++)
178d8719 20492 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
20493 if (!do_wide)
20494 printf ("\n");
1449284b
NC
20495 }
20496
9ef920e9
NC
20497 if (do_wide)
20498 printf ("\n");
20499
32ec8896 20500 return TRUE;
1449284b 20501}
6d118b09 20502
32ec8896 20503static bfd_boolean
dda8d76d
NC
20504process_notes_at (Filedata * filedata,
20505 Elf_Internal_Shdr * section,
20506 bfd_vma offset,
82ed9683
L
20507 bfd_vma length,
20508 bfd_vma align)
779fe533 20509{
2cf0635d
NC
20510 Elf_External_Note * pnotes;
20511 Elf_External_Note * external;
4dff97b2
NC
20512 char * end;
20513 bfd_boolean res = TRUE;
103f02d3 20514
779fe533 20515 if (length <= 0)
32ec8896 20516 return FALSE;
103f02d3 20517
1449284b
NC
20518 if (section)
20519 {
dda8d76d 20520 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 20521 if (pnotes)
32ec8896 20522 {
dda8d76d 20523 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
20524 {
20525 free (pnotes);
20526 return FALSE;
20527 }
32ec8896 20528 }
1449284b
NC
20529 }
20530 else
82ed9683 20531 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 20532 _("notes"));
4dff97b2 20533
dd24e3da 20534 if (pnotes == NULL)
32ec8896 20535 return FALSE;
779fe533 20536
103f02d3 20537 external = pnotes;
103f02d3 20538
ca0e11aa
NC
20539 if (filedata->is_separate)
20540 printf (_("In linked file '%s': "), filedata->file_name);
20541 else
20542 printf ("\n");
1449284b 20543 if (section)
ca0e11aa 20544 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 20545 else
ca0e11aa 20546 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
20547 (unsigned long) offset, (unsigned long) length);
20548
82ed9683
L
20549 /* NB: Some note sections may have alignment value of 0 or 1. gABI
20550 specifies that notes should be aligned to 4 bytes in 32-bit
20551 objects and to 8 bytes in 64-bit objects. As a Linux extension,
20552 we also support 4 byte alignment in 64-bit objects. If section
20553 alignment is less than 4, we treate alignment as 4 bytes. */
20554 if (align < 4)
20555 align = 4;
20556 else if (align != 4 && align != 8)
20557 {
20558 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
20559 (long) align);
a788aedd 20560 free (pnotes);
82ed9683
L
20561 return FALSE;
20562 }
20563
dbe15e4e 20564 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 20565
c8071705
NC
20566 end = (char *) pnotes + length;
20567 while ((char *) external < end)
779fe533 20568 {
b34976b6 20569 Elf_Internal_Note inote;
15b42fb0 20570 size_t min_notesz;
4dff97b2 20571 char * next;
2cf0635d 20572 char * temp = NULL;
c8071705 20573 size_t data_remaining = end - (char *) external;
6d118b09 20574
dda8d76d 20575 if (!is_ia64_vms (filedata))
15b42fb0 20576 {
9dd3a467
NC
20577 /* PR binutils/15191
20578 Make sure that there is enough data to read. */
15b42fb0
AM
20579 min_notesz = offsetof (Elf_External_Note, name);
20580 if (data_remaining < min_notesz)
9dd3a467 20581 {
d3a49aa8
AM
20582 warn (ngettext ("Corrupt note: only %ld byte remains, "
20583 "not enough for a full note\n",
20584 "Corrupt note: only %ld bytes remain, "
20585 "not enough for a full note\n",
20586 data_remaining),
20587 (long) data_remaining);
9dd3a467
NC
20588 break;
20589 }
5396a86e
AM
20590 data_remaining -= min_notesz;
20591
15b42fb0
AM
20592 inote.type = BYTE_GET (external->type);
20593 inote.namesz = BYTE_GET (external->namesz);
20594 inote.namedata = external->name;
20595 inote.descsz = BYTE_GET (external->descsz);
276da9b3 20596 inote.descdata = ((char *) external
4dff97b2 20597 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 20598 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 20599 next = ((char *) external
4dff97b2 20600 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 20601 }
00e98fc7 20602 else
15b42fb0
AM
20603 {
20604 Elf64_External_VMS_Note *vms_external;
00e98fc7 20605
9dd3a467
NC
20606 /* PR binutils/15191
20607 Make sure that there is enough data to read. */
15b42fb0
AM
20608 min_notesz = offsetof (Elf64_External_VMS_Note, name);
20609 if (data_remaining < min_notesz)
9dd3a467 20610 {
d3a49aa8
AM
20611 warn (ngettext ("Corrupt note: only %ld byte remains, "
20612 "not enough for a full note\n",
20613 "Corrupt note: only %ld bytes remain, "
20614 "not enough for a full note\n",
20615 data_remaining),
20616 (long) data_remaining);
9dd3a467
NC
20617 break;
20618 }
5396a86e 20619 data_remaining -= min_notesz;
3e55a963 20620
15b42fb0
AM
20621 vms_external = (Elf64_External_VMS_Note *) external;
20622 inote.type = BYTE_GET (vms_external->type);
20623 inote.namesz = BYTE_GET (vms_external->namesz);
20624 inote.namedata = vms_external->name;
20625 inote.descsz = BYTE_GET (vms_external->descsz);
20626 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
20627 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20628 next = inote.descdata + align_power (inote.descsz, 3);
20629 }
20630
5396a86e
AM
20631 /* PR 17531: file: 3443835e. */
20632 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
20633 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
20634 || (size_t) (inote.descdata - inote.namedata) > data_remaining
20635 || (size_t) (next - inote.descdata) < inote.descsz
20636 || ((size_t) (next - inote.descdata)
20637 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 20638 {
15b42fb0 20639 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 20640 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
20641 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
20642 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
20643 break;
20644 }
20645
15b42fb0 20646 external = (Elf_External_Note *) next;
dd24e3da 20647
6d118b09
NC
20648 /* Verify that name is null terminated. It appears that at least
20649 one version of Linux (RedHat 6.0) generates corefiles that don't
20650 comply with the ELF spec by failing to include the null byte in
20651 namesz. */
18344509 20652 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 20653 {
5396a86e 20654 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 20655 {
5396a86e
AM
20656 temp = (char *) malloc (inote.namesz + 1);
20657 if (temp == NULL)
20658 {
20659 error (_("Out of memory allocating space for inote name\n"));
20660 res = FALSE;
20661 break;
20662 }
76da6bbe 20663
5396a86e
AM
20664 memcpy (temp, inote.namedata, inote.namesz);
20665 inote.namedata = temp;
20666 }
20667 inote.namedata[inote.namesz] = 0;
6d118b09
NC
20668 }
20669
dda8d76d 20670 if (! process_note (& inote, filedata))
6b4bf3bc 20671 res = FALSE;
103f02d3 20672
9db70fc3
AM
20673 free (temp);
20674 temp = NULL;
779fe533
NC
20675 }
20676
20677 free (pnotes);
103f02d3 20678
779fe533
NC
20679 return res;
20680}
20681
32ec8896 20682static bfd_boolean
dda8d76d 20683process_corefile_note_segments (Filedata * filedata)
779fe533 20684{
2cf0635d 20685 Elf_Internal_Phdr * segment;
b34976b6 20686 unsigned int i;
32ec8896 20687 bfd_boolean res = TRUE;
103f02d3 20688
dda8d76d 20689 if (! get_program_headers (filedata))
6b4bf3bc 20690 return TRUE;
103f02d3 20691
dda8d76d
NC
20692 for (i = 0, segment = filedata->program_headers;
20693 i < filedata->file_header.e_phnum;
b34976b6 20694 i++, segment++)
779fe533
NC
20695 {
20696 if (segment->p_type == PT_NOTE)
dda8d76d 20697 if (! process_notes_at (filedata, NULL,
32ec8896 20698 (bfd_vma) segment->p_offset,
82ed9683
L
20699 (bfd_vma) segment->p_filesz,
20700 (bfd_vma) segment->p_align))
32ec8896 20701 res = FALSE;
779fe533 20702 }
103f02d3 20703
779fe533
NC
20704 return res;
20705}
20706
32ec8896 20707static bfd_boolean
dda8d76d 20708process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
20709{
20710 Elf_External_Note * pnotes;
20711 Elf_External_Note * external;
c8071705 20712 char * end;
32ec8896 20713 bfd_boolean res = TRUE;
685080f2
NC
20714
20715 if (length <= 0)
32ec8896 20716 return FALSE;
685080f2 20717
dda8d76d 20718 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
20719 _("v850 notes"));
20720 if (pnotes == NULL)
32ec8896 20721 return FALSE;
685080f2
NC
20722
20723 external = pnotes;
c8071705 20724 end = (char*) pnotes + length;
685080f2
NC
20725
20726 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
20727 (unsigned long) offset, (unsigned long) length);
20728
c8071705 20729 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
20730 {
20731 Elf_External_Note * next;
20732 Elf_Internal_Note inote;
20733
20734 inote.type = BYTE_GET (external->type);
20735 inote.namesz = BYTE_GET (external->namesz);
20736 inote.namedata = external->name;
20737 inote.descsz = BYTE_GET (external->descsz);
20738 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
20739 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20740
c8071705
NC
20741 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
20742 {
20743 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
20744 inote.descdata = inote.namedata;
20745 inote.namesz = 0;
20746 }
20747
685080f2
NC
20748 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
20749
c8071705 20750 if ( ((char *) next > end)
685080f2
NC
20751 || ((char *) next < (char *) pnotes))
20752 {
20753 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
20754 (unsigned long) ((char *) external - (char *) pnotes));
20755 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20756 inote.type, inote.namesz, inote.descsz);
20757 break;
20758 }
20759
20760 external = next;
20761
20762 /* Prevent out-of-bounds indexing. */
c8071705 20763 if ( inote.namedata + inote.namesz > end
685080f2
NC
20764 || inote.namedata + inote.namesz < inote.namedata)
20765 {
20766 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
20767 (unsigned long) ((char *) external - (char *) pnotes));
20768 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20769 inote.type, inote.namesz, inote.descsz);
20770 break;
20771 }
20772
20773 printf (" %s: ", get_v850_elf_note_type (inote.type));
20774
20775 if (! print_v850_note (& inote))
20776 {
32ec8896 20777 res = FALSE;
685080f2
NC
20778 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
20779 inote.namesz, inote.descsz);
20780 }
20781 }
20782
20783 free (pnotes);
20784
20785 return res;
20786}
20787
32ec8896 20788static bfd_boolean
dda8d76d 20789process_note_sections (Filedata * filedata)
1ec5cd37 20790{
2cf0635d 20791 Elf_Internal_Shdr * section;
1ec5cd37 20792 unsigned long i;
32ec8896
NC
20793 unsigned int n = 0;
20794 bfd_boolean res = TRUE;
1ec5cd37 20795
dda8d76d
NC
20796 for (i = 0, section = filedata->section_headers;
20797 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 20798 i++, section++)
685080f2
NC
20799 {
20800 if (section->sh_type == SHT_NOTE)
20801 {
dda8d76d 20802 if (! process_notes_at (filedata, section,
32ec8896 20803 (bfd_vma) section->sh_offset,
82ed9683
L
20804 (bfd_vma) section->sh_size,
20805 (bfd_vma) section->sh_addralign))
32ec8896 20806 res = FALSE;
685080f2
NC
20807 n++;
20808 }
20809
dda8d76d
NC
20810 if (( filedata->file_header.e_machine == EM_V800
20811 || filedata->file_header.e_machine == EM_V850
20812 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
20813 && section->sh_type == SHT_RENESAS_INFO)
20814 {
dda8d76d 20815 if (! process_v850_notes (filedata,
32ec8896
NC
20816 (bfd_vma) section->sh_offset,
20817 (bfd_vma) section->sh_size))
20818 res = FALSE;
685080f2
NC
20819 n++;
20820 }
20821 }
df565f32
NC
20822
20823 if (n == 0)
20824 /* Try processing NOTE segments instead. */
dda8d76d 20825 return process_corefile_note_segments (filedata);
1ec5cd37
NC
20826
20827 return res;
20828}
20829
32ec8896 20830static bfd_boolean
dda8d76d 20831process_notes (Filedata * filedata)
779fe533
NC
20832{
20833 /* If we have not been asked to display the notes then do nothing. */
20834 if (! do_notes)
32ec8896 20835 return TRUE;
103f02d3 20836
dda8d76d
NC
20837 if (filedata->file_header.e_type != ET_CORE)
20838 return process_note_sections (filedata);
103f02d3 20839
779fe533 20840 /* No program headers means no NOTE segment. */
dda8d76d
NC
20841 if (filedata->file_header.e_phnum > 0)
20842 return process_corefile_note_segments (filedata);
779fe533 20843
ca0e11aa
NC
20844 if (filedata->is_separate)
20845 printf (_("No notes found in linked file '%s'.\n"),
20846 filedata->file_name);
20847 else
20848 printf (_("No notes found file.\n"));
20849
32ec8896 20850 return TRUE;
779fe533
NC
20851}
20852
60abdbed
NC
20853static unsigned char *
20854display_public_gnu_attributes (unsigned char * start,
20855 const unsigned char * const end)
20856{
20857 printf (_(" Unknown GNU attribute: %s\n"), start);
20858
20859 start += strnlen ((char *) start, end - start);
20860 display_raw_attribute (start, end);
20861
20862 return (unsigned char *) end;
20863}
20864
20865static unsigned char *
20866display_generic_attribute (unsigned char * start,
20867 unsigned int tag,
20868 const unsigned char * const end)
20869{
20870 if (tag == 0)
20871 return (unsigned char *) end;
20872
20873 return display_tag_value (tag, start, end);
20874}
20875
32ec8896 20876static bfd_boolean
dda8d76d 20877process_arch_specific (Filedata * filedata)
252b5132 20878{
a952a375 20879 if (! do_arch)
32ec8896 20880 return TRUE;
a952a375 20881
dda8d76d 20882 switch (filedata->file_header.e_machine)
252b5132 20883 {
53a346d8
CZ
20884 case EM_ARC:
20885 case EM_ARC_COMPACT:
20886 case EM_ARC_COMPACT2:
dda8d76d 20887 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
20888 display_arc_attribute,
20889 display_generic_attribute);
11c1ff18 20890 case EM_ARM:
dda8d76d 20891 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
20892 display_arm_attribute,
20893 display_generic_attribute);
20894
252b5132 20895 case EM_MIPS:
4fe85591 20896 case EM_MIPS_RS3_LE:
dda8d76d 20897 return process_mips_specific (filedata);
60abdbed
NC
20898
20899 case EM_MSP430:
dda8d76d 20900 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 20901 display_msp430_attribute,
c0ea7c52 20902 display_msp430_gnu_attribute);
60abdbed 20903
2dc8dd17
JW
20904 case EM_RISCV:
20905 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
20906 display_riscv_attribute,
20907 display_generic_attribute);
20908
35c08157 20909 case EM_NDS32:
dda8d76d 20910 return process_nds32_specific (filedata);
60abdbed 20911
85f7484a
PB
20912 case EM_68K:
20913 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
20914 display_m68k_gnu_attribute);
20915
34c8bcba 20916 case EM_PPC:
b82317dd 20917 case EM_PPC64:
dda8d76d 20918 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20919 display_power_gnu_attribute);
20920
643f7afb
AK
20921 case EM_S390:
20922 case EM_S390_OLD:
dda8d76d 20923 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20924 display_s390_gnu_attribute);
20925
9e8c70f9
DM
20926 case EM_SPARC:
20927 case EM_SPARC32PLUS:
20928 case EM_SPARCV9:
dda8d76d 20929 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20930 display_sparc_gnu_attribute);
20931
59e6276b 20932 case EM_TI_C6000:
dda8d76d 20933 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
20934 display_tic6x_attribute,
20935 display_generic_attribute);
20936
0861f561
CQ
20937 case EM_CSKY:
20938 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
20939 display_csky_attribute, NULL);
20940
252b5132 20941 default:
dda8d76d 20942 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
20943 display_public_gnu_attributes,
20944 display_generic_attribute);
252b5132 20945 }
252b5132
RH
20946}
20947
32ec8896 20948static bfd_boolean
dda8d76d 20949get_file_header (Filedata * filedata)
252b5132 20950{
9ea033b2 20951 /* Read in the identity array. */
dda8d76d 20952 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20953 return FALSE;
252b5132 20954
9ea033b2 20955 /* Determine how to read the rest of the header. */
dda8d76d 20956 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 20957 {
1a0670f3
AM
20958 default:
20959 case ELFDATANONE:
adab8cdc
AO
20960 case ELFDATA2LSB:
20961 byte_get = byte_get_little_endian;
20962 byte_put = byte_put_little_endian;
20963 break;
20964 case ELFDATA2MSB:
20965 byte_get = byte_get_big_endian;
20966 byte_put = byte_put_big_endian;
20967 break;
9ea033b2
NC
20968 }
20969
20970 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 20971 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
20972
20973 /* Read in the rest of the header. */
20974 if (is_32bit_elf)
20975 {
20976 Elf32_External_Ehdr ehdr32;
252b5132 20977
dda8d76d 20978 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20979 return FALSE;
103f02d3 20980
dda8d76d
NC
20981 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
20982 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
20983 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
20984 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
20985 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
20986 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
20987 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
20988 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
20989 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
20990 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
20991 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
20992 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
20993 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 20994 }
252b5132 20995 else
9ea033b2
NC
20996 {
20997 Elf64_External_Ehdr ehdr64;
a952a375
NC
20998
20999 /* If we have been compiled with sizeof (bfd_vma) == 4, then
21000 we will not be able to cope with the 64bit data found in
21001 64 ELF files. Detect this now and abort before we start
50c2245b 21002 overwriting things. */
a952a375
NC
21003 if (sizeof (bfd_vma) < 8)
21004 {
e3c8793a
NC
21005 error (_("This instance of readelf has been built without support for a\n\
2100664 bit data type and so it cannot read 64 bit ELF files.\n"));
32ec8896 21007 return FALSE;
a952a375 21008 }
103f02d3 21009
dda8d76d 21010 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 21011 return FALSE;
103f02d3 21012
dda8d76d
NC
21013 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
21014 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
21015 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
21016 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
21017 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
21018 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
21019 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
21020 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
21021 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
21022 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
21023 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
21024 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
21025 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 21026 }
252b5132 21027
dda8d76d 21028 if (filedata->file_header.e_shoff)
7ece0d85
JJ
21029 {
21030 /* There may be some extensions in the first section header. Don't
21031 bomb if we can't read it. */
21032 if (is_32bit_elf)
dda8d76d 21033 get_32bit_section_headers (filedata, TRUE);
7ece0d85 21034 else
dda8d76d 21035 get_64bit_section_headers (filedata, TRUE);
7ece0d85 21036 }
560f3c1c 21037
32ec8896 21038 return TRUE;
252b5132
RH
21039}
21040
dda8d76d
NC
21041static void
21042close_file (Filedata * filedata)
21043{
21044 if (filedata)
21045 {
21046 if (filedata->handle)
21047 fclose (filedata->handle);
21048 free (filedata);
21049 }
21050}
21051
21052void
21053close_debug_file (void * data)
21054{
21055 close_file ((Filedata *) data);
21056}
21057
21058static Filedata *
ca0e11aa 21059open_file (const char * pathname, bfd_boolean is_separate)
dda8d76d
NC
21060{
21061 struct stat statbuf;
21062 Filedata * filedata = NULL;
21063
21064 if (stat (pathname, & statbuf) < 0
21065 || ! S_ISREG (statbuf.st_mode))
21066 goto fail;
21067
21068 filedata = calloc (1, sizeof * filedata);
21069 if (filedata == NULL)
21070 goto fail;
21071
21072 filedata->handle = fopen (pathname, "rb");
21073 if (filedata->handle == NULL)
21074 goto fail;
21075
21076 filedata->file_size = (bfd_size_type) statbuf.st_size;
21077 filedata->file_name = pathname;
ca0e11aa 21078 filedata->is_separate = is_separate;
dda8d76d
NC
21079
21080 if (! get_file_header (filedata))
21081 goto fail;
21082
21083 if (filedata->file_header.e_shoff)
21084 {
21085 bfd_boolean res;
21086
21087 /* Read the section headers again, this time for real. */
21088 if (is_32bit_elf)
21089 res = get_32bit_section_headers (filedata, FALSE);
21090 else
21091 res = get_64bit_section_headers (filedata, FALSE);
21092
21093 if (!res)
21094 goto fail;
21095 }
21096
21097 return filedata;
21098
21099 fail:
21100 if (filedata)
21101 {
21102 if (filedata->handle)
21103 fclose (filedata->handle);
21104 free (filedata);
21105 }
21106 return NULL;
21107}
21108
21109void *
21110open_debug_file (const char * pathname)
21111{
ca0e11aa 21112 return open_file (pathname, TRUE);
dda8d76d
NC
21113}
21114
fb52b2f4
NC
21115/* Process one ELF object file according to the command line options.
21116 This file may actually be stored in an archive. The file is
32ec8896
NC
21117 positioned at the start of the ELF object. Returns TRUE if no
21118 problems were encountered, FALSE otherwise. */
fb52b2f4 21119
32ec8896 21120static bfd_boolean
dda8d76d 21121process_object (Filedata * filedata)
252b5132 21122{
24841daa 21123 bfd_boolean have_separate_files;
252b5132 21124 unsigned int i;
2482f306 21125 bfd_boolean res;
252b5132 21126
dda8d76d 21127 if (! get_file_header (filedata))
252b5132 21128 {
dda8d76d 21129 error (_("%s: Failed to read file header\n"), filedata->file_name);
32ec8896 21130 return FALSE;
252b5132
RH
21131 }
21132
21133 /* Initialise per file variables. */
978c4450
AM
21134 for (i = ARRAY_SIZE (filedata->version_info); i--;)
21135 filedata->version_info[i] = 0;
252b5132 21136
978c4450
AM
21137 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
21138 filedata->dynamic_info[i] = 0;
21139 filedata->dynamic_info_DT_GNU_HASH = 0;
21140 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
21141
21142 /* Process the file. */
21143 if (show_name)
dda8d76d 21144 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 21145
18bd398b
NC
21146 /* Initialise the dump_sects array from the cmdline_dump_sects array.
21147 Note we do this even if cmdline_dump_sects is empty because we
21148 must make sure that the dump_sets array is zeroed out before each
21149 object file is processed. */
6431e409
AM
21150 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
21151 memset (filedata->dump.dump_sects, 0,
21152 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 21153
dda8d76d 21154 if (cmdline.num_dump_sects > 0)
18bd398b 21155 {
6431e409 21156 if (filedata->dump.num_dump_sects == 0)
18bd398b 21157 /* A sneaky way of allocating the dump_sects array. */
6431e409 21158 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
18bd398b 21159
6431e409
AM
21160 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
21161 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
21162 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 21163 }
d70c5fc7 21164
dda8d76d 21165 if (! process_file_header (filedata))
32ec8896 21166 return FALSE;
252b5132 21167
dda8d76d 21168 if (! process_section_headers (filedata))
2f62977e 21169 {
32ec8896
NC
21170 /* Without loaded section headers we cannot process lots of things. */
21171 do_unwind = do_version = do_dump = do_arch = FALSE;
252b5132 21172
2f62977e 21173 if (! do_using_dynamic)
32ec8896 21174 do_syms = do_dyn_syms = do_reloc = FALSE;
2f62977e 21175 }
252b5132 21176
dda8d76d 21177 if (! process_section_groups (filedata))
32ec8896
NC
21178 /* Without loaded section groups we cannot process unwind. */
21179 do_unwind = FALSE;
d1f5c6e3 21180
2482f306
AM
21181 res = process_program_headers (filedata);
21182 if (res)
21183 res = process_dynamic_section (filedata);
252b5132 21184
dda8d76d 21185 if (! process_relocs (filedata))
32ec8896 21186 res = FALSE;
252b5132 21187
dda8d76d 21188 if (! process_unwind (filedata))
32ec8896 21189 res = FALSE;
4d6ed7c8 21190
dda8d76d 21191 if (! process_symbol_table (filedata))
32ec8896 21192 res = FALSE;
252b5132 21193
0f03783c
NC
21194 if (! process_lto_symbol_tables (filedata))
21195 res = FALSE;
b9e920ec 21196
dda8d76d 21197 if (! process_syminfo (filedata))
32ec8896 21198 res = FALSE;
252b5132 21199
dda8d76d 21200 if (! process_version_sections (filedata))
32ec8896 21201 res = FALSE;
252b5132 21202
82ed9683 21203 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 21204 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 21205 else
24841daa 21206 have_separate_files = FALSE;
dda8d76d
NC
21207
21208 if (! process_section_contents (filedata))
32ec8896 21209 res = FALSE;
f5842774 21210
24841daa 21211 if (have_separate_files)
dda8d76d 21212 {
24841daa
NC
21213 separate_info * d;
21214
21215 for (d = first_separate_info; d != NULL; d = d->next)
21216 {
ca0e11aa 21217 if (process_links && ! process_file_header (d->handle))
24841daa 21218 res = FALSE;
ca0e11aa 21219 else if (! process_section_headers (d->handle))
24841daa 21220 res = FALSE;
ca0e11aa
NC
21221 else if (process_links)
21222 {
21223 if (! process_section_contents (d->handle))
21224 res = FALSE;
21225 if (! process_section_groups (d->handle))
21226 res = FALSE;
21227 if (! process_program_headers (d->handle))
21228 res = FALSE;
21229 if (! process_dynamic_section (d->handle))
21230 res = FALSE;
21231 if (! process_relocs (d->handle))
21232 res = FALSE;
21233 if (! process_unwind (d->handle))
21234 res = FALSE;
21235 if (! process_symbol_table (d->handle))
21236 res = FALSE;
21237 if (! process_lto_symbol_tables (d->handle))
21238 res = FALSE;
21239 if (! process_syminfo (d->handle))
21240 res = FALSE;
21241 if (! process_version_sections (d->handle))
21242 res = FALSE;
21243 if (! process_notes (d->handle))
21244 res = FALSE;
21245 }
24841daa
NC
21246 }
21247
21248 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
21249 }
21250
21251 if (! process_notes (filedata))
32ec8896 21252 res = FALSE;
103f02d3 21253
dda8d76d 21254 if (! process_gnu_liblist (filedata))
32ec8896 21255 res = FALSE;
047b2264 21256
dda8d76d 21257 if (! process_arch_specific (filedata))
32ec8896 21258 res = FALSE;
252b5132 21259
dda8d76d
NC
21260 free (filedata->program_headers);
21261 filedata->program_headers = NULL;
d93f0186 21262
dda8d76d
NC
21263 free (filedata->section_headers);
21264 filedata->section_headers = NULL;
252b5132 21265
dda8d76d
NC
21266 free (filedata->string_table);
21267 filedata->string_table = NULL;
21268 filedata->string_table_length = 0;
252b5132 21269
9db70fc3
AM
21270 free (filedata->dump.dump_sects);
21271 filedata->dump.dump_sects = NULL;
21272 filedata->dump.num_dump_sects = 0;
a788aedd 21273
9db70fc3
AM
21274 free (filedata->dynamic_strings);
21275 filedata->dynamic_strings = NULL;
21276 filedata->dynamic_strings_length = 0;
252b5132 21277
9db70fc3
AM
21278 free (filedata->dynamic_symbols);
21279 filedata->dynamic_symbols = NULL;
21280 filedata->num_dynamic_syms = 0;
252b5132 21281
9db70fc3
AM
21282 free (filedata->dynamic_syminfo);
21283 filedata->dynamic_syminfo = NULL;
ff78d6d6 21284
9db70fc3
AM
21285 free (filedata->dynamic_section);
21286 filedata->dynamic_section = NULL;
293c573e 21287
978c4450 21288 while (filedata->symtab_shndx_list != NULL)
8fb879cd 21289 {
978c4450
AM
21290 elf_section_list *next = filedata->symtab_shndx_list->next;
21291 free (filedata->symtab_shndx_list);
21292 filedata->symtab_shndx_list = next;
8fb879cd
AM
21293 }
21294
9db70fc3
AM
21295 free (filedata->section_headers_groups);
21296 filedata->section_headers_groups = NULL;
e4b17d5c 21297
978c4450 21298 if (filedata->section_groups)
e4b17d5c 21299 {
2cf0635d
NC
21300 struct group_list * g;
21301 struct group_list * next;
e4b17d5c 21302
978c4450 21303 for (i = 0; i < filedata->group_count; i++)
e4b17d5c 21304 {
978c4450 21305 for (g = filedata->section_groups [i].root; g != NULL; g = next)
e4b17d5c
L
21306 {
21307 next = g->next;
21308 free (g);
21309 }
21310 }
21311
978c4450
AM
21312 free (filedata->section_groups);
21313 filedata->section_groups = NULL;
e4b17d5c
L
21314 }
21315
19e6b90e 21316 free_debug_memory ();
18bd398b 21317
32ec8896 21318 return res;
252b5132
RH
21319}
21320
2cf0635d 21321/* Process an ELF archive.
32ec8896
NC
21322 On entry the file is positioned just after the ARMAG string.
21323 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 21324
32ec8896 21325static bfd_boolean
dda8d76d 21326process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
2cf0635d
NC
21327{
21328 struct archive_info arch;
21329 struct archive_info nested_arch;
21330 size_t got;
32ec8896 21331 bfd_boolean ret = TRUE;
2cf0635d 21332
32ec8896 21333 show_name = TRUE;
2cf0635d
NC
21334
21335 /* The ARCH structure is used to hold information about this archive. */
21336 arch.file_name = NULL;
21337 arch.file = NULL;
21338 arch.index_array = NULL;
21339 arch.sym_table = NULL;
21340 arch.longnames = NULL;
21341
21342 /* The NESTED_ARCH structure is used as a single-item cache of information
21343 about a nested archive (when members of a thin archive reside within
21344 another regular archive file). */
21345 nested_arch.file_name = NULL;
21346 nested_arch.file = NULL;
21347 nested_arch.index_array = NULL;
21348 nested_arch.sym_table = NULL;
21349 nested_arch.longnames = NULL;
21350
dda8d76d 21351 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
21352 filedata->file_size, is_thin_archive,
21353 do_archive_index) != 0)
2cf0635d 21354 {
32ec8896 21355 ret = FALSE;
2cf0635d 21356 goto out;
4145f1d5 21357 }
fb52b2f4 21358
4145f1d5
NC
21359 if (do_archive_index)
21360 {
2cf0635d 21361 if (arch.sym_table == NULL)
1cb7d8b1
AM
21362 error (_("%s: unable to dump the index as none was found\n"),
21363 filedata->file_name);
4145f1d5
NC
21364 else
21365 {
591f7597 21366 unsigned long i, l;
4145f1d5
NC
21367 unsigned long current_pos;
21368
1cb7d8b1
AM
21369 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
21370 "in the symbol table)\n"),
21371 filedata->file_name, (unsigned long) arch.index_num,
21372 arch.sym_size);
dda8d76d
NC
21373
21374 current_pos = ftell (filedata->handle);
4145f1d5 21375
2cf0635d 21376 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 21377 {
1cb7d8b1
AM
21378 if (i == 0
21379 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
21380 {
21381 char * member_name
21382 = get_archive_member_name_at (&arch, arch.index_array[i],
21383 &nested_arch);
2cf0635d 21384
1cb7d8b1
AM
21385 if (member_name != NULL)
21386 {
21387 char * qualified_name
21388 = make_qualified_name (&arch, &nested_arch,
21389 member_name);
2cf0635d 21390
1cb7d8b1
AM
21391 if (qualified_name != NULL)
21392 {
21393 printf (_("Contents of binary %s at offset "),
21394 qualified_name);
c2a7d3f5
NC
21395 (void) print_vma (arch.index_array[i], PREFIX_HEX);
21396 putchar ('\n');
1cb7d8b1
AM
21397 free (qualified_name);
21398 }
fd486f32 21399 free (member_name);
4145f1d5
NC
21400 }
21401 }
2cf0635d
NC
21402
21403 if (l >= arch.sym_size)
4145f1d5 21404 {
1cb7d8b1
AM
21405 error (_("%s: end of the symbol table reached "
21406 "before the end of the index\n"),
dda8d76d 21407 filedata->file_name);
32ec8896 21408 ret = FALSE;
cb8f3167 21409 break;
4145f1d5 21410 }
591f7597 21411 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
21412 printf ("\t%.*s\n",
21413 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 21414 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
21415 }
21416
67ce483b 21417 if (arch.uses_64bit_indices)
c2a7d3f5
NC
21418 l = (l + 7) & ~ 7;
21419 else
21420 l += l & 1;
21421
2cf0635d 21422 if (l < arch.sym_size)
32ec8896 21423 {
d3a49aa8
AM
21424 error (ngettext ("%s: %ld byte remains in the symbol table, "
21425 "but without corresponding entries in "
21426 "the index table\n",
21427 "%s: %ld bytes remain in the symbol table, "
21428 "but without corresponding entries in "
21429 "the index table\n",
21430 arch.sym_size - l),
dda8d76d 21431 filedata->file_name, arch.sym_size - l);
32ec8896
NC
21432 ret = FALSE;
21433 }
4145f1d5 21434
dda8d76d 21435 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 21436 {
1cb7d8b1
AM
21437 error (_("%s: failed to seek back to start of object files "
21438 "in the archive\n"),
dda8d76d 21439 filedata->file_name);
32ec8896 21440 ret = FALSE;
2cf0635d 21441 goto out;
4145f1d5 21442 }
fb52b2f4 21443 }
4145f1d5
NC
21444
21445 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
21446 && !do_segments && !do_header && !do_dump && !do_version
21447 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 21448 && !do_section_groups && !do_dyn_syms)
2cf0635d 21449 {
32ec8896 21450 ret = TRUE; /* Archive index only. */
2cf0635d
NC
21451 goto out;
21452 }
fb52b2f4
NC
21453 }
21454
fb52b2f4
NC
21455 while (1)
21456 {
2cf0635d
NC
21457 char * name;
21458 size_t namelen;
21459 char * qualified_name;
21460
21461 /* Read the next archive header. */
dda8d76d 21462 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
21463 {
21464 error (_("%s: failed to seek to next archive header\n"),
21465 arch.file_name);
21466 ret = FALSE;
21467 break;
21468 }
dda8d76d 21469 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 21470 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
21471 {
21472 if (got == 0)
2cf0635d 21473 break;
28e817cc
NC
21474 /* PR 24049 - we cannot use filedata->file_name as this will
21475 have already been freed. */
21476 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 21477
1cb7d8b1
AM
21478 ret = FALSE;
21479 break;
21480 }
2cf0635d 21481 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
21482 {
21483 error (_("%s: did not find a valid archive header\n"),
21484 arch.file_name);
21485 ret = FALSE;
21486 break;
21487 }
2cf0635d
NC
21488
21489 arch.next_arhdr_offset += sizeof arch.arhdr;
21490
978c4450
AM
21491 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
21492 if (filedata->archive_file_size & 01)
21493 ++filedata->archive_file_size;
2cf0635d
NC
21494
21495 name = get_archive_member_name (&arch, &nested_arch);
21496 if (name == NULL)
fb52b2f4 21497 {
28e817cc 21498 error (_("%s: bad archive file name\n"), arch.file_name);
32ec8896 21499 ret = FALSE;
d989285c 21500 break;
fb52b2f4 21501 }
2cf0635d 21502 namelen = strlen (name);
fb52b2f4 21503
2cf0635d
NC
21504 qualified_name = make_qualified_name (&arch, &nested_arch, name);
21505 if (qualified_name == NULL)
fb52b2f4 21506 {
28e817cc 21507 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 21508 free (name);
32ec8896 21509 ret = FALSE;
d989285c 21510 break;
fb52b2f4
NC
21511 }
21512
2cf0635d 21513 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
21514 {
21515 /* This is a proxy for an external member of a thin archive. */
21516 Filedata * member_filedata;
21517 char * member_file_name = adjust_relative_path
dda8d76d 21518 (filedata->file_name, name, namelen);
32ec8896 21519
fd486f32 21520 free (name);
1cb7d8b1
AM
21521 if (member_file_name == NULL)
21522 {
fd486f32 21523 free (qualified_name);
1cb7d8b1
AM
21524 ret = FALSE;
21525 break;
21526 }
2cf0635d 21527
ca0e11aa 21528 member_filedata = open_file (member_file_name, FALSE);
1cb7d8b1
AM
21529 if (member_filedata == NULL)
21530 {
21531 error (_("Input file '%s' is not readable.\n"), member_file_name);
21532 free (member_file_name);
fd486f32 21533 free (qualified_name);
1cb7d8b1
AM
21534 ret = FALSE;
21535 break;
21536 }
2cf0635d 21537
978c4450 21538 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 21539 member_filedata->file_name = qualified_name;
2cf0635d 21540
1cb7d8b1 21541 if (! process_object (member_filedata))
32ec8896 21542 ret = FALSE;
2cf0635d 21543
1cb7d8b1
AM
21544 close_file (member_filedata);
21545 free (member_file_name);
1cb7d8b1 21546 }
2cf0635d 21547 else if (is_thin_archive)
1cb7d8b1
AM
21548 {
21549 Filedata thin_filedata;
eb02c04d 21550
1cb7d8b1 21551 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 21552
a043396b
NC
21553 /* PR 15140: Allow for corrupt thin archives. */
21554 if (nested_arch.file == NULL)
21555 {
21556 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 21557 qualified_name, name);
fd486f32
AM
21558 free (qualified_name);
21559 free (name);
32ec8896 21560 ret = FALSE;
a043396b
NC
21561 break;
21562 }
fd486f32 21563 free (name);
a043396b 21564
1cb7d8b1 21565 /* This is a proxy for a member of a nested archive. */
978c4450
AM
21566 filedata->archive_file_offset
21567 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 21568
1cb7d8b1
AM
21569 /* The nested archive file will have been opened and setup by
21570 get_archive_member_name. */
978c4450
AM
21571 if (fseek (nested_arch.file, filedata->archive_file_offset,
21572 SEEK_SET) != 0)
1cb7d8b1
AM
21573 {
21574 error (_("%s: failed to seek to archive member.\n"),
21575 nested_arch.file_name);
fd486f32 21576 free (qualified_name);
1cb7d8b1
AM
21577 ret = FALSE;
21578 break;
21579 }
2cf0635d 21580
dda8d76d
NC
21581 thin_filedata.handle = nested_arch.file;
21582 thin_filedata.file_name = qualified_name;
9abca702 21583
1cb7d8b1 21584 if (! process_object (& thin_filedata))
32ec8896 21585 ret = FALSE;
1cb7d8b1 21586 }
2cf0635d 21587 else
1cb7d8b1 21588 {
fd486f32 21589 free (name);
978c4450 21590 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 21591 filedata->file_name = qualified_name;
1cb7d8b1 21592 if (! process_object (filedata))
32ec8896 21593 ret = FALSE;
978c4450 21594 arch.next_arhdr_offset += filedata->archive_file_size;
4c836627 21595 /* Stop looping with "negative" archive_file_size. */
978c4450 21596 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 21597 arch.next_arhdr_offset = -1ul;
1cb7d8b1 21598 }
fb52b2f4 21599
2cf0635d 21600 free (qualified_name);
fb52b2f4
NC
21601 }
21602
4145f1d5 21603 out:
2cf0635d
NC
21604 if (nested_arch.file != NULL)
21605 fclose (nested_arch.file);
21606 release_archive (&nested_arch);
21607 release_archive (&arch);
fb52b2f4 21608
d989285c 21609 return ret;
fb52b2f4
NC
21610}
21611
32ec8896 21612static bfd_boolean
2cf0635d 21613process_file (char * file_name)
fb52b2f4 21614{
dda8d76d 21615 Filedata * filedata = NULL;
fb52b2f4
NC
21616 struct stat statbuf;
21617 char armag[SARMAG];
32ec8896 21618 bfd_boolean ret = TRUE;
fb52b2f4
NC
21619
21620 if (stat (file_name, &statbuf) < 0)
21621 {
f24ddbdd
NC
21622 if (errno == ENOENT)
21623 error (_("'%s': No such file\n"), file_name);
21624 else
21625 error (_("Could not locate '%s'. System error message: %s\n"),
21626 file_name, strerror (errno));
32ec8896 21627 return FALSE;
f24ddbdd
NC
21628 }
21629
21630 if (! S_ISREG (statbuf.st_mode))
21631 {
21632 error (_("'%s' is not an ordinary file\n"), file_name);
32ec8896 21633 return FALSE;
fb52b2f4
NC
21634 }
21635
dda8d76d
NC
21636 filedata = calloc (1, sizeof * filedata);
21637 if (filedata == NULL)
21638 {
21639 error (_("Out of memory allocating file data structure\n"));
21640 return FALSE;
21641 }
21642
21643 filedata->file_name = file_name;
21644 filedata->handle = fopen (file_name, "rb");
21645 if (filedata->handle == NULL)
fb52b2f4 21646 {
f24ddbdd 21647 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 21648 free (filedata);
32ec8896 21649 return FALSE;
fb52b2f4
NC
21650 }
21651
dda8d76d 21652 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 21653 {
4145f1d5 21654 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
21655 fclose (filedata->handle);
21656 free (filedata);
32ec8896 21657 return FALSE;
fb52b2f4
NC
21658 }
21659
dda8d76d 21660 filedata->file_size = (bfd_size_type) statbuf.st_size;
ca0e11aa 21661 filedata->is_separate = FALSE;
f54498b4 21662
fb52b2f4 21663 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 21664 {
dda8d76d 21665 if (! process_archive (filedata, FALSE))
32ec8896
NC
21666 ret = FALSE;
21667 }
2cf0635d 21668 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 21669 {
dda8d76d 21670 if ( ! process_archive (filedata, TRUE))
32ec8896
NC
21671 ret = FALSE;
21672 }
fb52b2f4
NC
21673 else
21674 {
1b513401 21675 if (do_archive_index && !check_all)
4145f1d5
NC
21676 error (_("File %s is not an archive so its index cannot be displayed.\n"),
21677 file_name);
21678
dda8d76d 21679 rewind (filedata->handle);
978c4450 21680 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 21681
dda8d76d 21682 if (! process_object (filedata))
32ec8896 21683 ret = FALSE;
fb52b2f4
NC
21684 }
21685
dda8d76d 21686 fclose (filedata->handle);
8fb879cd
AM
21687 free (filedata->section_headers);
21688 free (filedata->program_headers);
21689 free (filedata->string_table);
6431e409 21690 free (filedata->dump.dump_sects);
dda8d76d 21691 free (filedata);
32ec8896 21692
fd486f32 21693 free (ba_cache.strtab);
1bd6175a 21694 ba_cache.strtab = NULL;
fd486f32 21695 free (ba_cache.symtab);
1bd6175a 21696 ba_cache.symtab = NULL;
fd486f32
AM
21697 ba_cache.filedata = NULL;
21698
fb52b2f4
NC
21699 return ret;
21700}
21701
252b5132
RH
21702#ifdef SUPPORT_DISASSEMBLY
21703/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 21704 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 21705 symbols. */
252b5132
RH
21706
21707void
2cf0635d 21708print_address (unsigned int addr, FILE * outfile)
252b5132
RH
21709{
21710 fprintf (outfile,"0x%8.8x", addr);
21711}
21712
e3c8793a 21713/* Needed by the i386 disassembler. */
dda8d76d 21714
252b5132
RH
21715void
21716db_task_printsym (unsigned int addr)
21717{
21718 print_address (addr, stderr);
21719}
21720#endif
21721
21722int
2cf0635d 21723main (int argc, char ** argv)
252b5132 21724{
ff78d6d6
L
21725 int err;
21726
252b5132
RH
21727#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
21728 setlocale (LC_MESSAGES, "");
3882b010
L
21729#endif
21730#if defined (HAVE_SETLOCALE)
21731 setlocale (LC_CTYPE, "");
252b5132
RH
21732#endif
21733 bindtextdomain (PACKAGE, LOCALEDIR);
21734 textdomain (PACKAGE);
21735
869b9d07
MM
21736 expandargv (&argc, &argv);
21737
dda8d76d 21738 parse_args (& cmdline, argc, argv);
59f14fc0 21739
18bd398b 21740 if (optind < (argc - 1))
1b513401
NC
21741 /* When displaying information for more than one file,
21742 prefix the information with the file name. */
32ec8896 21743 show_name = TRUE;
5656ba2c
L
21744 else if (optind >= argc)
21745 {
1b513401
NC
21746 /* Ensure that the warning is always displayed. */
21747 do_checks = TRUE;
21748
5656ba2c
L
21749 warn (_("Nothing to do.\n"));
21750 usage (stderr);
21751 }
18bd398b 21752
32ec8896 21753 err = FALSE;
252b5132 21754 while (optind < argc)
32ec8896
NC
21755 if (! process_file (argv[optind++]))
21756 err = TRUE;
252b5132 21757
9db70fc3 21758 free (cmdline.dump_sects);
252b5132 21759
7d9813f1
NA
21760 free (dump_ctf_symtab_name);
21761 free (dump_ctf_strtab_name);
21762 free (dump_ctf_parent_name);
21763
32ec8896 21764 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 21765}