MIPS/binutils/testsuite: Fix XPA and Virtualization ASE cases
[deliverable/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>
7bfd842d 47#include <wchar.h>
252b5132 48
a952a375 49#if __GNUC__ >= 2
19936277 50/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 51 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 52 Only do this if we believe that the compiler can support a 64 bit
a952a375 53 data type. For now we only rely on GCC being able to do this. */
19936277 54#define BFD64
a952a375
NC
55#endif
56
3db64b00
AM
57#include "bfd.h"
58#include "bucomm.h"
3284fe0c 59#include "elfcomm.h"
19e6b90e 60#include "dwarf.h"
7d9813f1 61#include "ctf-api.h"
79bc120c 62#include "demangle.h"
252b5132
RH
63
64#include "elf/common.h"
65#include "elf/external.h"
66#include "elf/internal.h"
252b5132 67
4b78141a
NC
68
69/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
70 we can obtain the H8 reloc numbers. We need these for the
71 get_reloc_size() function. We include h8.h again after defining
72 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
73
74#include "elf/h8.h"
75#undef _ELF_H8_H
76
77/* Undo the effects of #including reloc-macros.h. */
78
79#undef START_RELOC_NUMBERS
80#undef RELOC_NUMBER
81#undef FAKE_RELOC
82#undef EMPTY_RELOC
83#undef END_RELOC_NUMBERS
84#undef _RELOC_MACROS_H
85
252b5132
RH
86/* The following headers use the elf/reloc-macros.h file to
87 automatically generate relocation recognition functions
88 such as elf_mips_reloc_type() */
89
90#define RELOC_MACROS_GEN_FUNC
91
a06ea964 92#include "elf/aarch64.h"
252b5132 93#include "elf/alpha.h"
3b16e843 94#include "elf/arc.h"
252b5132 95#include "elf/arm.h"
3b16e843 96#include "elf/avr.h"
1d65ded4 97#include "elf/bfin.h"
60bca95a 98#include "elf/cr16.h"
3b16e843 99#include "elf/cris.h"
1c0d3aa6 100#include "elf/crx.h"
b8891f8d 101#include "elf/csky.h"
252b5132
RH
102#include "elf/d10v.h"
103#include "elf/d30v.h"
d172d4ba 104#include "elf/dlx.h"
aca4efc7 105#include "elf/bpf.h"
cfb8c092 106#include "elf/epiphany.h"
252b5132 107#include "elf/fr30.h"
5c70f934 108#include "elf/frv.h"
3f8107ab 109#include "elf/ft32.h"
3b16e843
NC
110#include "elf/h8.h"
111#include "elf/hppa.h"
112#include "elf/i386.h"
f954747f
AM
113#include "elf/i370.h"
114#include "elf/i860.h"
115#include "elf/i960.h"
3b16e843 116#include "elf/ia64.h"
1e4cf259 117#include "elf/ip2k.h"
84e94c90 118#include "elf/lm32.h"
1c0d3aa6 119#include "elf/iq2000.h"
49f58d10 120#include "elf/m32c.h"
3b16e843
NC
121#include "elf/m32r.h"
122#include "elf/m68k.h"
75751cd9 123#include "elf/m68hc11.h"
7b4ae824 124#include "elf/s12z.h"
252b5132 125#include "elf/mcore.h"
15ab5209 126#include "elf/mep.h"
a3c62988 127#include "elf/metag.h"
7ba29e2a 128#include "elf/microblaze.h"
3b16e843 129#include "elf/mips.h"
3c3bdf30 130#include "elf/mmix.h"
3b16e843
NC
131#include "elf/mn10200.h"
132#include "elf/mn10300.h"
5506d11a 133#include "elf/moxie.h"
4970f871 134#include "elf/mt.h"
2469cfa2 135#include "elf/msp430.h"
35c08157 136#include "elf/nds32.h"
fe944acf 137#include "elf/nfp.h"
13761a11 138#include "elf/nios2.h"
73589c9d 139#include "elf/or1k.h"
7d466069 140#include "elf/pj.h"
3b16e843 141#include "elf/ppc.h"
c833c019 142#include "elf/ppc64.h"
2b100bb5 143#include "elf/pru.h"
03336641 144#include "elf/riscv.h"
99c513f6 145#include "elf/rl78.h"
c7927a3c 146#include "elf/rx.h"
a85d7ed0 147#include "elf/s390.h"
1c0d3aa6 148#include "elf/score.h"
3b16e843
NC
149#include "elf/sh.h"
150#include "elf/sparc.h"
e9f53129 151#include "elf/spu.h"
40b36596 152#include "elf/tic6x.h"
aa137e4d
NC
153#include "elf/tilegx.h"
154#include "elf/tilepro.h"
3b16e843 155#include "elf/v850.h"
179d3252 156#include "elf/vax.h"
619ed720 157#include "elf/visium.h"
f96bd6c2 158#include "elf/wasm32.h"
3b16e843 159#include "elf/x86-64.h"
c29aca4a 160#include "elf/xc16x.h"
f6c1a2d5 161#include "elf/xgate.h"
93fbbb04 162#include "elf/xstormy16.h"
88da6820 163#include "elf/xtensa.h"
6655dba2 164#include "elf/z80.h"
252b5132 165
252b5132 166#include "getopt.h"
566b0d53 167#include "libiberty.h"
09c11c86 168#include "safe-ctype.h"
2cf0635d 169#include "filenames.h"
252b5132 170
15b42fb0
AM
171#ifndef offsetof
172#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
173#endif
174
6a40cf0c
NC
175typedef struct elf_section_list
176{
dda8d76d
NC
177 Elf_Internal_Shdr * hdr;
178 struct elf_section_list * next;
6a40cf0c
NC
179} elf_section_list;
180
dda8d76d
NC
181/* Flag bits indicating particular types of dump. */
182#define HEX_DUMP (1 << 0) /* The -x command line switch. */
183#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
184#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
185#define STRING_DUMP (1 << 3) /* The -p command line switch. */
186#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 187#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
188
189typedef unsigned char dump_type;
190
191/* A linked list of the section names for which dumps were requested. */
192struct dump_list_entry
193{
194 char * name;
195 dump_type type;
196 struct dump_list_entry * next;
197};
198
6431e409
AM
199/* A dynamic array of flags indicating for which sections a dump
200 has been requested via command line switches. */
1b513401
NC
201struct dump_data
202{
6431e409
AM
203 dump_type * dump_sects;
204 unsigned int num_dump_sects;
205};
206
207static struct dump_data cmdline;
208
209static struct dump_list_entry * dump_sects_byname;
210
2cf0635d 211char * program_name = "readelf";
dda8d76d 212
015dc7e1
AM
213static bool show_name = false;
214static bool do_dynamic = false;
215static bool do_syms = false;
216static bool do_dyn_syms = false;
217static bool do_lto_syms = false;
218static bool do_reloc = false;
219static bool do_sections = false;
220static bool do_section_groups = false;
221static bool do_section_details = false;
222static bool do_segments = false;
223static bool do_unwind = false;
224static bool do_using_dynamic = false;
225static bool do_header = false;
226static bool do_dump = false;
227static bool do_version = false;
228static bool do_histogram = false;
229static bool do_debugging = false;
230static bool do_ctf = false;
231static bool do_arch = false;
232static bool do_notes = false;
233static bool do_archive_index = false;
234static bool check_all = false;
235static bool is_32bit_elf = false;
236static bool decompress_dumps = false;
237static bool do_not_show_symbol_truncation = false;
238static bool do_demangle = false; /* Pretty print C++ symbol names. */
239static bool process_links = false;
79bc120c 240static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 241static int sym_base = 0;
252b5132 242
7d9813f1
NA
243static char *dump_ctf_parent_name;
244static char *dump_ctf_symtab_name;
245static char *dump_ctf_strtab_name;
246
e4b17d5c
L
247struct group_list
248{
dda8d76d
NC
249 struct group_list * next;
250 unsigned int section_index;
e4b17d5c
L
251};
252
253struct group
254{
dda8d76d
NC
255 struct group_list * root;
256 unsigned int group_index;
e4b17d5c
L
257};
258
978c4450
AM
259typedef struct filedata
260{
261 const char * file_name;
015dc7e1 262 bool is_separate;
978c4450
AM
263 FILE * handle;
264 bfd_size_type file_size;
265 Elf_Internal_Ehdr file_header;
266 Elf_Internal_Shdr * section_headers;
267 Elf_Internal_Phdr * program_headers;
268 char * string_table;
269 unsigned long string_table_length;
270 unsigned long archive_file_offset;
271 unsigned long archive_file_size;
272 unsigned long dynamic_addr;
273 bfd_size_type dynamic_size;
274 size_t dynamic_nent;
275 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 276 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450
AM
277 char * dynamic_strings;
278 unsigned long dynamic_strings_length;
8ac10c5b 279 Elf_Internal_Shdr * dynamic_symtab_section;
978c4450
AM
280 unsigned long num_dynamic_syms;
281 Elf_Internal_Sym * dynamic_symbols;
282 bfd_vma version_info[16];
283 unsigned int dynamic_syminfo_nent;
284 Elf_Internal_Syminfo * dynamic_syminfo;
285 unsigned long dynamic_syminfo_offset;
286 bfd_size_type nbuckets;
287 bfd_size_type nchains;
288 bfd_vma * buckets;
289 bfd_vma * chains;
290 bfd_size_type ngnubuckets;
291 bfd_size_type ngnuchains;
292 bfd_vma * gnubuckets;
293 bfd_vma * gnuchains;
294 bfd_vma * mipsxlat;
295 bfd_vma gnusymidx;
13acb58d 296 char * program_interpreter;
978c4450
AM
297 bfd_vma dynamic_info[DT_ENCODING];
298 bfd_vma dynamic_info_DT_GNU_HASH;
299 bfd_vma dynamic_info_DT_MIPS_XHASH;
300 elf_section_list * symtab_shndx_list;
301 size_t group_count;
302 struct group * section_groups;
303 struct group ** section_headers_groups;
304 /* A dynamic array of flags indicating for which sections a dump of
305 some kind has been requested. It is reset on a per-object file
306 basis and then initialised from the cmdline_dump_sects array,
307 the results of interpreting the -w switch, and the
308 dump_sects_byname list. */
309 struct dump_data dump;
310} Filedata;
aef1f6d0 311
c256ffe7 312/* How to print a vma value. */
843dd992
NC
313typedef enum print_mode
314{
315 HEX,
047c3dbf 316 HEX_5,
843dd992
NC
317 DEC,
318 DEC_5,
319 UNSIGNED,
047c3dbf 320 UNSIGNED_5,
843dd992 321 PREFIX_HEX,
047c3dbf 322 PREFIX_HEX_5,
843dd992 323 FULL_HEX,
047c3dbf
NL
324 LONG_HEX,
325 OCTAL,
326 OCTAL_5
843dd992
NC
327}
328print_mode;
329
bb4d2ac2
L
330/* Versioned symbol info. */
331enum versioned_symbol_info
332{
333 symbol_undefined,
334 symbol_hidden,
335 symbol_public
336};
337
32ec8896 338static const char * get_symbol_version_string
015dc7e1 339 (Filedata *, bool, const char *, unsigned long, unsigned,
32ec8896 340 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 341
9c19a809
NC
342#define UNKNOWN -1
343
b9e920ec
AM
344#define SECTION_NAME(X) \
345 (filedata->string_table + (X)->sh_name)
346
347#define SECTION_NAME_VALID(X) \
348 ((X) != NULL \
349 && filedata->string_table != NULL \
350 && (X)->sh_name < filedata->string_table_length)
351
352#define SECTION_NAME_PRINT(X) \
353 ((X) == NULL ? _("<none>") \
354 : filedata->string_table == NULL ? _("<no-strings>") \
355 : (X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
356 : filedata->string_table + (X)->sh_name)
252b5132 357
ee42cf8c 358#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 359
ba5cdace
NC
360#define GET_ELF_SYMBOLS(file, section, sym_count) \
361 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
362 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 363
10ca4b04
L
364#define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
365 (strtab != NULL && offset < strtab_size)
978c4450
AM
366#define VALID_DYNAMIC_NAME(filedata, offset) \
367 VALID_SYMBOL_NAME (filedata->dynamic_strings, \
368 filedata->dynamic_strings_length, offset)
d79b3d50
NC
369/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
370 already been called and verified that the string exists. */
978c4450
AM
371#define GET_DYNAMIC_NAME(filedata, offset) \
372 (filedata->dynamic_strings + offset)
18bd398b 373
61865e30
NC
374#define REMOVE_ARCH_BITS(ADDR) \
375 do \
376 { \
dda8d76d 377 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
378 (ADDR) &= ~1; \
379 } \
380 while (0)
f16a9783
MS
381
382/* Get the correct GNU hash section name. */
978c4450
AM
383#define GNU_HASH_SECTION_NAME(filedata) \
384 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 385\f
66cfc0fd
AM
386/* Print a BFD_VMA to an internal buffer, for use in error messages.
387 BFD_FMA_FMT can't be used in translated strings. */
388
389static const char *
390bfd_vmatoa (char *fmtch, bfd_vma value)
391{
392 /* bfd_vmatoa is used more then once in a printf call for output.
393 Cycle through an array of buffers. */
394 static int buf_pos = 0;
395 static struct bfd_vmatoa_buf
396 {
397 char place[64];
398 } buf[4];
399 char *ret;
400 char fmt[32];
401
402 ret = buf[buf_pos++].place;
403 buf_pos %= ARRAY_SIZE (buf);
404
405 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
406 snprintf (ret, sizeof (buf[0].place), fmt, value);
407 return ret;
408}
409
dda8d76d
NC
410/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
411 OFFSET + the offset of the current archive member, if we are examining an
412 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
413 allocate a buffer using malloc and fill that. In either case return the
414 pointer to the start of the retrieved data or NULL if something went wrong.
415 If something does go wrong and REASON is not NULL then emit an error
416 message using REASON as part of the context. */
59245841 417
c256ffe7 418static void *
dda8d76d
NC
419get_data (void * var,
420 Filedata * filedata,
421 unsigned long offset,
422 bfd_size_type size,
423 bfd_size_type nmemb,
424 const char * reason)
a6e9f9df 425{
2cf0635d 426 void * mvar;
57028622 427 bfd_size_type amt = size * nmemb;
a6e9f9df 428
c256ffe7 429 if (size == 0 || nmemb == 0)
a6e9f9df
AM
430 return NULL;
431
57028622
NC
432 /* If the size_t type is smaller than the bfd_size_type, eg because
433 you are building a 32-bit tool on a 64-bit host, then make sure
434 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
435 if ((size_t) size != size
436 || (size_t) nmemb != nmemb
437 || (size_t) amt != amt)
57028622
NC
438 {
439 if (reason)
66cfc0fd
AM
440 error (_("Size truncation prevents reading %s"
441 " elements of size %s for %s\n"),
442 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
443 return NULL;
444 }
445
446 /* Check for size overflow. */
7c1c1904 447 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
448 {
449 if (reason)
66cfc0fd
AM
450 error (_("Size overflow prevents reading %s"
451 " elements of size %s for %s\n"),
452 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
453 return NULL;
454 }
455
c22b42ce 456 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 457 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
458 if (filedata->archive_file_offset > filedata->file_size
459 || offset > filedata->file_size - filedata->archive_file_offset
460 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 461 {
049b0c3a 462 if (reason)
66cfc0fd
AM
463 error (_("Reading %s bytes extends past end of file for %s\n"),
464 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
465 return NULL;
466 }
467
978c4450
AM
468 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
469 SEEK_SET))
071436c6
NC
470 {
471 if (reason)
c9c1d674 472 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 473 filedata->archive_file_offset + offset, reason);
071436c6
NC
474 return NULL;
475 }
476
a6e9f9df
AM
477 mvar = var;
478 if (mvar == NULL)
479 {
7c1c1904
AM
480 /* + 1 so that we can '\0' terminate invalid string table sections. */
481 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
482
483 if (mvar == NULL)
484 {
049b0c3a 485 if (reason)
66cfc0fd
AM
486 error (_("Out of memory allocating %s bytes for %s\n"),
487 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
488 return NULL;
489 }
c256ffe7 490
c9c1d674 491 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
492 }
493
dda8d76d 494 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 495 {
049b0c3a 496 if (reason)
66cfc0fd
AM
497 error (_("Unable to read in %s bytes of %s\n"),
498 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
499 if (mvar != var)
500 free (mvar);
501 return NULL;
502 }
503
504 return mvar;
505}
506
32ec8896
NC
507/* Print a VMA value in the MODE specified.
508 Returns the number of characters displayed. */
cb8f3167 509
32ec8896 510static unsigned int
14a91970 511print_vma (bfd_vma vma, print_mode mode)
66543521 512{
32ec8896 513 unsigned int nc = 0;
66543521 514
14a91970 515 switch (mode)
66543521 516 {
14a91970
AM
517 case FULL_HEX:
518 nc = printf ("0x");
1a0670f3 519 /* Fall through. */
14a91970 520 case LONG_HEX:
f7a99963 521#ifdef BFD64
14a91970 522 if (is_32bit_elf)
437c2fb7 523 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 524#endif
14a91970
AM
525 printf_vma (vma);
526 return nc + 16;
b19aac67 527
14a91970
AM
528 case DEC_5:
529 if (vma <= 99999)
530 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 531 /* Fall through. */
14a91970
AM
532 case PREFIX_HEX:
533 nc = printf ("0x");
1a0670f3 534 /* Fall through. */
14a91970
AM
535 case HEX:
536 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 537
047c3dbf
NL
538 case PREFIX_HEX_5:
539 nc = printf ("0x");
540 /* Fall through. */
541 case HEX_5:
542 return nc + printf ("%05" BFD_VMA_FMT "x", vma);
543
14a91970
AM
544 case DEC:
545 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 546
14a91970
AM
547 case UNSIGNED:
548 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896 549
047c3dbf
NL
550 case UNSIGNED_5:
551 return printf ("%5" BFD_VMA_FMT "u", vma);
552
553 case OCTAL:
554 return printf ("%" BFD_VMA_FMT "o", vma);
555
556 case OCTAL_5:
557 return printf ("%5" BFD_VMA_FMT "o", vma);
558
32ec8896
NC
559 default:
560 /* FIXME: Report unrecognised mode ? */
561 return 0;
f7a99963 562 }
f7a99963
NC
563}
564
047c3dbf 565
7bfd842d 566/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 567 multibye characters (assuming the host environment supports them).
31104126 568
7bfd842d
NC
569 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
570
0942c7ab
NC
571 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
572 abs(WIDTH) - 5 characters followed by "[...]".
573
7bfd842d
NC
574 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
575 padding as necessary.
171191ba
NC
576
577 Returns the number of emitted characters. */
578
579static unsigned int
0942c7ab 580print_symbol (signed int width, const char * symbol)
31104126 581{
015dc7e1
AM
582 bool extra_padding = false;
583 bool do_dots = false;
32ec8896 584 signed int num_printed = 0;
3bfcb652 585#ifdef HAVE_MBSTATE_T
7bfd842d 586 mbstate_t state;
3bfcb652 587#endif
32ec8896 588 unsigned int width_remaining;
79bc120c 589 const void * alloced_symbol = NULL;
961c521f 590
7bfd842d 591 if (width < 0)
961c521f 592 {
88305e1b 593 /* Keep the width positive. This helps the code below. */
961c521f 594 width = - width;
015dc7e1 595 extra_padding = true;
0b4362b0 596 }
56d8f8a9
NC
597 else if (width == 0)
598 return 0;
961c521f 599
7bfd842d
NC
600 if (do_wide)
601 /* Set the remaining width to a very large value.
602 This simplifies the code below. */
603 width_remaining = INT_MAX;
604 else
0942c7ab
NC
605 {
606 width_remaining = width;
607 if (! do_not_show_symbol_truncation
608 && (int) strlen (symbol) > width)
609 {
610 width_remaining -= 5;
611 if ((int) width_remaining < 0)
612 width_remaining = 0;
015dc7e1 613 do_dots = true;
0942c7ab
NC
614 }
615 }
cb8f3167 616
3bfcb652 617#ifdef HAVE_MBSTATE_T
7bfd842d
NC
618 /* Initialise the multibyte conversion state. */
619 memset (& state, 0, sizeof (state));
3bfcb652 620#endif
961c521f 621
79bc120c
NC
622 if (do_demangle && *symbol)
623 {
624 const char * res = cplus_demangle (symbol, demangle_flags);
625
626 if (res != NULL)
627 alloced_symbol = symbol = res;
628 }
629
7bfd842d
NC
630 while (width_remaining)
631 {
632 size_t n;
7bfd842d 633 const char c = *symbol++;
961c521f 634
7bfd842d 635 if (c == 0)
961c521f
NC
636 break;
637
7bfd842d
NC
638 /* Do not print control characters directly as they can affect terminal
639 settings. Such characters usually appear in the names generated
640 by the assembler for local labels. */
641 if (ISCNTRL (c))
961c521f 642 {
7bfd842d 643 if (width_remaining < 2)
961c521f
NC
644 break;
645
7bfd842d
NC
646 printf ("^%c", c + 0x40);
647 width_remaining -= 2;
171191ba 648 num_printed += 2;
961c521f 649 }
7bfd842d
NC
650 else if (ISPRINT (c))
651 {
652 putchar (c);
653 width_remaining --;
654 num_printed ++;
655 }
961c521f
NC
656 else
657 {
3bfcb652
NC
658#ifdef HAVE_MBSTATE_T
659 wchar_t w;
660#endif
7bfd842d
NC
661 /* Let printf do the hard work of displaying multibyte characters. */
662 printf ("%.1s", symbol - 1);
663 width_remaining --;
664 num_printed ++;
665
3bfcb652 666#ifdef HAVE_MBSTATE_T
7bfd842d
NC
667 /* Try to find out how many bytes made up the character that was
668 just printed. Advance the symbol pointer past the bytes that
669 were displayed. */
670 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
671#else
672 n = 1;
673#endif
7bfd842d
NC
674 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
675 symbol += (n - 1);
961c521f 676 }
961c521f 677 }
171191ba 678
0942c7ab
NC
679 if (do_dots)
680 num_printed += printf ("[...]");
681
7bfd842d 682 if (extra_padding && num_printed < width)
171191ba
NC
683 {
684 /* Fill in the remaining spaces. */
7bfd842d
NC
685 printf ("%-*s", width - num_printed, " ");
686 num_printed = width;
171191ba
NC
687 }
688
79bc120c 689 free ((void *) alloced_symbol);
171191ba 690 return num_printed;
31104126
NC
691}
692
1449284b 693/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
694 the given section's name. Like print_symbol, except that it does not try
695 to print multibyte characters, it just interprets them as hex values. */
696
697static const char *
dda8d76d 698printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 699{
ca0e11aa 700#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 701 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
b9e920ec 702 const char * name = SECTION_NAME_PRINT (sec);
74e1a04b
NC
703 char * buf = sec_name_buf;
704 char c;
705 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
706
707 while ((c = * name ++) != 0)
708 {
709 if (ISCNTRL (c))
710 {
711 if (remaining < 2)
712 break;
948f632f 713
74e1a04b
NC
714 * buf ++ = '^';
715 * buf ++ = c + 0x40;
716 remaining -= 2;
717 }
718 else if (ISPRINT (c))
719 {
720 * buf ++ = c;
721 remaining -= 1;
722 }
723 else
724 {
725 static char hex[17] = "0123456789ABCDEF";
726
727 if (remaining < 4)
728 break;
729 * buf ++ = '<';
730 * buf ++ = hex[(c & 0xf0) >> 4];
731 * buf ++ = hex[c & 0x0f];
732 * buf ++ = '>';
733 remaining -= 4;
734 }
735
736 if (remaining == 0)
737 break;
738 }
739
740 * buf = 0;
741 return sec_name_buf;
742}
743
744static const char *
dda8d76d 745printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 746{
dda8d76d 747 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
748 return _("<corrupt>");
749
dda8d76d 750 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
751}
752
89fac5e3
RS
753/* Return a pointer to section NAME, or NULL if no such section exists. */
754
755static Elf_Internal_Shdr *
dda8d76d 756find_section (Filedata * filedata, const char * name)
89fac5e3
RS
757{
758 unsigned int i;
759
68807c3c
NC
760 if (filedata->section_headers == NULL)
761 return NULL;
dda8d76d
NC
762
763 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
764 if (SECTION_NAME_VALID (filedata->section_headers + i)
765 && streq (SECTION_NAME (filedata->section_headers + i), name))
dda8d76d 766 return filedata->section_headers + i;
89fac5e3
RS
767
768 return NULL;
769}
770
0b6ae522
DJ
771/* Return a pointer to a section containing ADDR, or NULL if no such
772 section exists. */
773
774static Elf_Internal_Shdr *
dda8d76d 775find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
776{
777 unsigned int i;
778
68807c3c
NC
779 if (filedata->section_headers == NULL)
780 return NULL;
781
dda8d76d 782 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 783 {
dda8d76d
NC
784 Elf_Internal_Shdr *sec = filedata->section_headers + i;
785
0b6ae522
DJ
786 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
787 return sec;
788 }
789
790 return NULL;
791}
792
071436c6 793static Elf_Internal_Shdr *
dda8d76d 794find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
795{
796 unsigned int i;
797
68807c3c
NC
798 if (filedata->section_headers == NULL)
799 return NULL;
800
dda8d76d 801 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 802 {
dda8d76d
NC
803 Elf_Internal_Shdr *sec = filedata->section_headers + i;
804
071436c6
NC
805 if (sec->sh_type == type)
806 return sec;
807 }
808
809 return NULL;
810}
811
657d0d47
CC
812/* Return a pointer to section NAME, or NULL if no such section exists,
813 restricted to the list of sections given in SET. */
814
815static Elf_Internal_Shdr *
dda8d76d 816find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
817{
818 unsigned int i;
819
68807c3c
NC
820 if (filedata->section_headers == NULL)
821 return NULL;
822
657d0d47
CC
823 if (set != NULL)
824 {
825 while ((i = *set++) > 0)
b814a36d
NC
826 {
827 /* See PR 21156 for a reproducer. */
dda8d76d 828 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
829 continue; /* FIXME: Should we issue an error message ? */
830
b9e920ec
AM
831 if (SECTION_NAME_VALID (filedata->section_headers + i)
832 && streq (SECTION_NAME (filedata->section_headers + i), name))
dda8d76d 833 return filedata->section_headers + i;
b814a36d 834 }
657d0d47
CC
835 }
836
dda8d76d 837 return find_section (filedata, name);
657d0d47
CC
838}
839
32ec8896 840/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
841 This OS has so many departures from the ELF standard that we test it at
842 many places. */
843
015dc7e1 844static inline bool
dda8d76d 845is_ia64_vms (Filedata * filedata)
28f997cf 846{
dda8d76d
NC
847 return filedata->file_header.e_machine == EM_IA_64
848 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
849}
850
bcedfee6 851/* Guess the relocation size commonly used by the specific machines. */
252b5132 852
015dc7e1 853static bool
2dc4cec1 854guess_is_rela (unsigned int e_machine)
252b5132 855{
9c19a809 856 switch (e_machine)
252b5132
RH
857 {
858 /* Targets that use REL relocations. */
252b5132 859 case EM_386:
22abe556 860 case EM_IAMCU:
f954747f 861 case EM_960:
e9f53129 862 case EM_ARM:
2b0337b0 863 case EM_D10V:
252b5132 864 case EM_CYGNUS_D10V:
e9f53129 865 case EM_DLX:
252b5132 866 case EM_MIPS:
4fe85591 867 case EM_MIPS_RS3_LE:
e9f53129 868 case EM_CYGNUS_M32R:
1c0d3aa6 869 case EM_SCORE:
f6c1a2d5 870 case EM_XGATE:
fe944acf 871 case EM_NFP:
aca4efc7 872 case EM_BPF:
015dc7e1 873 return false;
103f02d3 874
252b5132
RH
875 /* Targets that use RELA relocations. */
876 case EM_68K:
f954747f 877 case EM_860:
a06ea964 878 case EM_AARCH64:
cfb8c092 879 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
880 case EM_ALPHA:
881 case EM_ALTERA_NIOS2:
886a2506
NC
882 case EM_ARC:
883 case EM_ARC_COMPACT:
884 case EM_ARC_COMPACT2:
e9f53129
AM
885 case EM_AVR:
886 case EM_AVR_OLD:
887 case EM_BLACKFIN:
60bca95a 888 case EM_CR16:
e9f53129
AM
889 case EM_CRIS:
890 case EM_CRX:
b8891f8d 891 case EM_CSKY:
2b0337b0 892 case EM_D30V:
252b5132 893 case EM_CYGNUS_D30V:
2b0337b0 894 case EM_FR30:
3f8107ab 895 case EM_FT32:
252b5132 896 case EM_CYGNUS_FR30:
5c70f934 897 case EM_CYGNUS_FRV:
e9f53129
AM
898 case EM_H8S:
899 case EM_H8_300:
900 case EM_H8_300H:
800eeca4 901 case EM_IA_64:
1e4cf259
NC
902 case EM_IP2K:
903 case EM_IP2K_OLD:
3b36097d 904 case EM_IQ2000:
84e94c90 905 case EM_LATTICEMICO32:
ff7eeb89 906 case EM_M32C_OLD:
49f58d10 907 case EM_M32C:
e9f53129
AM
908 case EM_M32R:
909 case EM_MCORE:
15ab5209 910 case EM_CYGNUS_MEP:
a3c62988 911 case EM_METAG:
e9f53129
AM
912 case EM_MMIX:
913 case EM_MN10200:
914 case EM_CYGNUS_MN10200:
915 case EM_MN10300:
916 case EM_CYGNUS_MN10300:
5506d11a 917 case EM_MOXIE:
e9f53129
AM
918 case EM_MSP430:
919 case EM_MSP430_OLD:
d031aafb 920 case EM_MT:
35c08157 921 case EM_NDS32:
64fd6348 922 case EM_NIOS32:
73589c9d 923 case EM_OR1K:
e9f53129
AM
924 case EM_PPC64:
925 case EM_PPC:
2b100bb5 926 case EM_TI_PRU:
e23eba97 927 case EM_RISCV:
99c513f6 928 case EM_RL78:
c7927a3c 929 case EM_RX:
e9f53129
AM
930 case EM_S390:
931 case EM_S390_OLD:
932 case EM_SH:
933 case EM_SPARC:
934 case EM_SPARC32PLUS:
935 case EM_SPARCV9:
936 case EM_SPU:
40b36596 937 case EM_TI_C6000:
aa137e4d
NC
938 case EM_TILEGX:
939 case EM_TILEPRO:
708e2187 940 case EM_V800:
e9f53129
AM
941 case EM_V850:
942 case EM_CYGNUS_V850:
943 case EM_VAX:
619ed720 944 case EM_VISIUM:
e9f53129 945 case EM_X86_64:
8a9036a4 946 case EM_L1OM:
7a9068fe 947 case EM_K1OM:
e9f53129
AM
948 case EM_XSTORMY16:
949 case EM_XTENSA:
950 case EM_XTENSA_OLD:
7ba29e2a
NC
951 case EM_MICROBLAZE:
952 case EM_MICROBLAZE_OLD:
f96bd6c2 953 case EM_WEBASSEMBLY:
015dc7e1 954 return true;
103f02d3 955
e9f53129
AM
956 case EM_68HC05:
957 case EM_68HC08:
958 case EM_68HC11:
959 case EM_68HC16:
960 case EM_FX66:
961 case EM_ME16:
d1133906 962 case EM_MMA:
d1133906
NC
963 case EM_NCPU:
964 case EM_NDR1:
e9f53129 965 case EM_PCP:
d1133906 966 case EM_ST100:
e9f53129 967 case EM_ST19:
d1133906 968 case EM_ST7:
e9f53129
AM
969 case EM_ST9PLUS:
970 case EM_STARCORE:
d1133906 971 case EM_SVX:
e9f53129 972 case EM_TINYJ:
9c19a809
NC
973 default:
974 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 975 return false;
9c19a809
NC
976 }
977}
252b5132 978
dda8d76d 979/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
980 Returns TRUE upon success, FALSE otherwise. If successful then a
981 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
982 and the number of relocs loaded is placed in *NRELASP. It is the caller's
983 responsibility to free the allocated buffer. */
984
015dc7e1 985static bool
dda8d76d
NC
986slurp_rela_relocs (Filedata * filedata,
987 unsigned long rel_offset,
988 unsigned long rel_size,
989 Elf_Internal_Rela ** relasp,
990 unsigned long * nrelasp)
9c19a809 991{
2cf0635d 992 Elf_Internal_Rela * relas;
8b73c356 993 size_t nrelas;
4d6ed7c8 994 unsigned int i;
252b5132 995
4d6ed7c8
NC
996 if (is_32bit_elf)
997 {
2cf0635d 998 Elf32_External_Rela * erelas;
103f02d3 999
dda8d76d 1000 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1001 rel_size, _("32-bit relocation data"));
a6e9f9df 1002 if (!erelas)
015dc7e1 1003 return false;
252b5132 1004
4d6ed7c8 1005 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1006
3f5e193b
NC
1007 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1008 sizeof (Elf_Internal_Rela));
103f02d3 1009
4d6ed7c8
NC
1010 if (relas == NULL)
1011 {
c256ffe7 1012 free (erelas);
591a748a 1013 error (_("out of memory parsing relocs\n"));
015dc7e1 1014 return false;
4d6ed7c8 1015 }
103f02d3 1016
4d6ed7c8
NC
1017 for (i = 0; i < nrelas; i++)
1018 {
1019 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1020 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1021 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1022 }
103f02d3 1023
4d6ed7c8
NC
1024 free (erelas);
1025 }
1026 else
1027 {
2cf0635d 1028 Elf64_External_Rela * erelas;
103f02d3 1029
dda8d76d 1030 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1031 rel_size, _("64-bit relocation data"));
a6e9f9df 1032 if (!erelas)
015dc7e1 1033 return false;
4d6ed7c8
NC
1034
1035 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1036
3f5e193b
NC
1037 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1038 sizeof (Elf_Internal_Rela));
103f02d3 1039
4d6ed7c8
NC
1040 if (relas == NULL)
1041 {
c256ffe7 1042 free (erelas);
591a748a 1043 error (_("out of memory parsing relocs\n"));
015dc7e1 1044 return false;
9c19a809 1045 }
4d6ed7c8
NC
1046
1047 for (i = 0; i < nrelas; i++)
9c19a809 1048 {
66543521
AM
1049 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1050 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1051 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1052
1053 /* The #ifdef BFD64 below is to prevent a compile time
1054 warning. We know that if we do not have a 64 bit data
1055 type that we will never execute this code anyway. */
1056#ifdef BFD64
dda8d76d
NC
1057 if (filedata->file_header.e_machine == EM_MIPS
1058 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1059 {
1060 /* In little-endian objects, r_info isn't really a
1061 64-bit little-endian value: it has a 32-bit
1062 little-endian symbol index followed by four
1063 individual byte fields. Reorder INFO
1064 accordingly. */
91d6fa6a
NC
1065 bfd_vma inf = relas[i].r_info;
1066 inf = (((inf & 0xffffffff) << 32)
1067 | ((inf >> 56) & 0xff)
1068 | ((inf >> 40) & 0xff00)
1069 | ((inf >> 24) & 0xff0000)
1070 | ((inf >> 8) & 0xff000000));
1071 relas[i].r_info = inf;
861fb55a
DJ
1072 }
1073#endif /* BFD64 */
4d6ed7c8 1074 }
103f02d3 1075
4d6ed7c8
NC
1076 free (erelas);
1077 }
32ec8896 1078
4d6ed7c8
NC
1079 *relasp = relas;
1080 *nrelasp = nrelas;
015dc7e1 1081 return true;
4d6ed7c8 1082}
103f02d3 1083
dda8d76d 1084/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1085 Returns TRUE upon success, FALSE otherwise. If successful then a
1086 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1087 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1088 responsibility to free the allocated buffer. */
1089
015dc7e1 1090static bool
dda8d76d
NC
1091slurp_rel_relocs (Filedata * filedata,
1092 unsigned long rel_offset,
1093 unsigned long rel_size,
1094 Elf_Internal_Rela ** relsp,
1095 unsigned long * nrelsp)
4d6ed7c8 1096{
2cf0635d 1097 Elf_Internal_Rela * rels;
8b73c356 1098 size_t nrels;
4d6ed7c8 1099 unsigned int i;
103f02d3 1100
4d6ed7c8
NC
1101 if (is_32bit_elf)
1102 {
2cf0635d 1103 Elf32_External_Rel * erels;
103f02d3 1104
dda8d76d 1105 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1106 rel_size, _("32-bit relocation data"));
a6e9f9df 1107 if (!erels)
015dc7e1 1108 return false;
103f02d3 1109
4d6ed7c8 1110 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1111
3f5e193b 1112 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1113
4d6ed7c8
NC
1114 if (rels == NULL)
1115 {
c256ffe7 1116 free (erels);
591a748a 1117 error (_("out of memory parsing relocs\n"));
015dc7e1 1118 return false;
4d6ed7c8
NC
1119 }
1120
1121 for (i = 0; i < nrels; i++)
1122 {
1123 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1124 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1125 rels[i].r_addend = 0;
9ea033b2 1126 }
4d6ed7c8
NC
1127
1128 free (erels);
9c19a809
NC
1129 }
1130 else
1131 {
2cf0635d 1132 Elf64_External_Rel * erels;
9ea033b2 1133
dda8d76d 1134 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1135 rel_size, _("64-bit relocation data"));
a6e9f9df 1136 if (!erels)
015dc7e1 1137 return false;
103f02d3 1138
4d6ed7c8 1139 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1140
3f5e193b 1141 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1142
4d6ed7c8 1143 if (rels == NULL)
9c19a809 1144 {
c256ffe7 1145 free (erels);
591a748a 1146 error (_("out of memory parsing relocs\n"));
015dc7e1 1147 return false;
4d6ed7c8 1148 }
103f02d3 1149
4d6ed7c8
NC
1150 for (i = 0; i < nrels; i++)
1151 {
66543521
AM
1152 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1153 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1154 rels[i].r_addend = 0;
861fb55a
DJ
1155
1156 /* The #ifdef BFD64 below is to prevent a compile time
1157 warning. We know that if we do not have a 64 bit data
1158 type that we will never execute this code anyway. */
1159#ifdef BFD64
dda8d76d
NC
1160 if (filedata->file_header.e_machine == EM_MIPS
1161 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1162 {
1163 /* In little-endian objects, r_info isn't really a
1164 64-bit little-endian value: it has a 32-bit
1165 little-endian symbol index followed by four
1166 individual byte fields. Reorder INFO
1167 accordingly. */
91d6fa6a
NC
1168 bfd_vma inf = rels[i].r_info;
1169 inf = (((inf & 0xffffffff) << 32)
1170 | ((inf >> 56) & 0xff)
1171 | ((inf >> 40) & 0xff00)
1172 | ((inf >> 24) & 0xff0000)
1173 | ((inf >> 8) & 0xff000000));
1174 rels[i].r_info = inf;
861fb55a
DJ
1175 }
1176#endif /* BFD64 */
4d6ed7c8 1177 }
103f02d3 1178
4d6ed7c8
NC
1179 free (erels);
1180 }
32ec8896 1181
4d6ed7c8
NC
1182 *relsp = rels;
1183 *nrelsp = nrels;
015dc7e1 1184 return true;
4d6ed7c8 1185}
103f02d3 1186
aca88567
NC
1187/* Returns the reloc type extracted from the reloc info field. */
1188
1189static unsigned int
dda8d76d 1190get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1191{
1192 if (is_32bit_elf)
1193 return ELF32_R_TYPE (reloc_info);
1194
dda8d76d 1195 switch (filedata->file_header.e_machine)
aca88567
NC
1196 {
1197 case EM_MIPS:
1198 /* Note: We assume that reloc_info has already been adjusted for us. */
1199 return ELF64_MIPS_R_TYPE (reloc_info);
1200
1201 case EM_SPARCV9:
1202 return ELF64_R_TYPE_ID (reloc_info);
1203
1204 default:
1205 return ELF64_R_TYPE (reloc_info);
1206 }
1207}
1208
1209/* Return the symbol index extracted from the reloc info field. */
1210
1211static bfd_vma
1212get_reloc_symindex (bfd_vma reloc_info)
1213{
1214 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1215}
1216
015dc7e1 1217static inline bool
dda8d76d 1218uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1219{
1220 return
dda8d76d 1221 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1222 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1223 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1224 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1225 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1226}
1227
d3ba0551
AM
1228/* Display the contents of the relocation data found at the specified
1229 offset. */
ee42cf8c 1230
015dc7e1 1231static bool
dda8d76d
NC
1232dump_relocations (Filedata * filedata,
1233 unsigned long rel_offset,
1234 unsigned long rel_size,
1235 Elf_Internal_Sym * symtab,
1236 unsigned long nsyms,
1237 char * strtab,
1238 unsigned long strtablen,
1239 int is_rela,
015dc7e1 1240 bool is_dynsym)
4d6ed7c8 1241{
32ec8896 1242 unsigned long i;
2cf0635d 1243 Elf_Internal_Rela * rels;
015dc7e1 1244 bool res = true;
103f02d3 1245
4d6ed7c8 1246 if (is_rela == UNKNOWN)
dda8d76d 1247 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1248
4d6ed7c8
NC
1249 if (is_rela)
1250 {
dda8d76d 1251 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1252 return false;
4d6ed7c8
NC
1253 }
1254 else
1255 {
dda8d76d 1256 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1257 return false;
252b5132
RH
1258 }
1259
410f7a12
L
1260 if (is_32bit_elf)
1261 {
1262 if (is_rela)
2c71103e
NC
1263 {
1264 if (do_wide)
1265 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1266 else
1267 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1268 }
410f7a12 1269 else
2c71103e
NC
1270 {
1271 if (do_wide)
1272 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1273 else
1274 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1275 }
410f7a12 1276 }
252b5132 1277 else
410f7a12
L
1278 {
1279 if (is_rela)
2c71103e
NC
1280 {
1281 if (do_wide)
8beeaeb7 1282 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1283 else
1284 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1285 }
410f7a12 1286 else
2c71103e
NC
1287 {
1288 if (do_wide)
8beeaeb7 1289 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1290 else
1291 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1292 }
410f7a12 1293 }
252b5132
RH
1294
1295 for (i = 0; i < rel_size; i++)
1296 {
2cf0635d 1297 const char * rtype;
b34976b6 1298 bfd_vma offset;
91d6fa6a 1299 bfd_vma inf;
b34976b6
AM
1300 bfd_vma symtab_index;
1301 bfd_vma type;
103f02d3 1302
b34976b6 1303 offset = rels[i].r_offset;
91d6fa6a 1304 inf = rels[i].r_info;
103f02d3 1305
dda8d76d 1306 type = get_reloc_type (filedata, inf);
91d6fa6a 1307 symtab_index = get_reloc_symindex (inf);
252b5132 1308
410f7a12
L
1309 if (is_32bit_elf)
1310 {
39dbeff8
AM
1311 printf ("%8.8lx %8.8lx ",
1312 (unsigned long) offset & 0xffffffff,
91d6fa6a 1313 (unsigned long) inf & 0xffffffff);
410f7a12
L
1314 }
1315 else
1316 {
39dbeff8 1317 printf (do_wide
d1ce973e
AM
1318 ? "%16.16" BFD_VMA_FMT "x %16.16" BFD_VMA_FMT "x "
1319 : "%12.12" BFD_VMA_FMT "x %12.12" BFD_VMA_FMT "x ",
91d6fa6a 1320 offset, inf);
410f7a12 1321 }
103f02d3 1322
dda8d76d 1323 switch (filedata->file_header.e_machine)
252b5132
RH
1324 {
1325 default:
1326 rtype = NULL;
1327 break;
1328
a06ea964
NC
1329 case EM_AARCH64:
1330 rtype = elf_aarch64_reloc_type (type);
1331 break;
1332
2b0337b0 1333 case EM_M32R:
252b5132 1334 case EM_CYGNUS_M32R:
9ea033b2 1335 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1336 break;
1337
1338 case EM_386:
22abe556 1339 case EM_IAMCU:
9ea033b2 1340 rtype = elf_i386_reloc_type (type);
252b5132
RH
1341 break;
1342
ba2685cc
AM
1343 case EM_68HC11:
1344 case EM_68HC12:
1345 rtype = elf_m68hc11_reloc_type (type);
1346 break;
75751cd9 1347
7b4ae824
JD
1348 case EM_S12Z:
1349 rtype = elf_s12z_reloc_type (type);
1350 break;
1351
252b5132 1352 case EM_68K:
9ea033b2 1353 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1354 break;
1355
f954747f
AM
1356 case EM_960:
1357 rtype = elf_i960_reloc_type (type);
1358 break;
1359
adde6300 1360 case EM_AVR:
2b0337b0 1361 case EM_AVR_OLD:
adde6300
AM
1362 rtype = elf_avr_reloc_type (type);
1363 break;
1364
9ea033b2
NC
1365 case EM_OLD_SPARCV9:
1366 case EM_SPARC32PLUS:
1367 case EM_SPARCV9:
252b5132 1368 case EM_SPARC:
9ea033b2 1369 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1370 break;
1371
e9f53129
AM
1372 case EM_SPU:
1373 rtype = elf_spu_reloc_type (type);
1374 break;
1375
708e2187
NC
1376 case EM_V800:
1377 rtype = v800_reloc_type (type);
1378 break;
2b0337b0 1379 case EM_V850:
252b5132 1380 case EM_CYGNUS_V850:
9ea033b2 1381 rtype = v850_reloc_type (type);
252b5132
RH
1382 break;
1383
2b0337b0 1384 case EM_D10V:
252b5132 1385 case EM_CYGNUS_D10V:
9ea033b2 1386 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1387 break;
1388
2b0337b0 1389 case EM_D30V:
252b5132 1390 case EM_CYGNUS_D30V:
9ea033b2 1391 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1392 break;
1393
d172d4ba
NC
1394 case EM_DLX:
1395 rtype = elf_dlx_reloc_type (type);
1396 break;
1397
252b5132 1398 case EM_SH:
9ea033b2 1399 rtype = elf_sh_reloc_type (type);
252b5132
RH
1400 break;
1401
2b0337b0 1402 case EM_MN10300:
252b5132 1403 case EM_CYGNUS_MN10300:
9ea033b2 1404 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1405 break;
1406
2b0337b0 1407 case EM_MN10200:
252b5132 1408 case EM_CYGNUS_MN10200:
9ea033b2 1409 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1410 break;
1411
2b0337b0 1412 case EM_FR30:
252b5132 1413 case EM_CYGNUS_FR30:
9ea033b2 1414 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1415 break;
1416
ba2685cc
AM
1417 case EM_CYGNUS_FRV:
1418 rtype = elf_frv_reloc_type (type);
1419 break;
5c70f934 1420
b8891f8d
AJ
1421 case EM_CSKY:
1422 rtype = elf_csky_reloc_type (type);
1423 break;
1424
3f8107ab
AM
1425 case EM_FT32:
1426 rtype = elf_ft32_reloc_type (type);
1427 break;
1428
252b5132 1429 case EM_MCORE:
9ea033b2 1430 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1431 break;
1432
3c3bdf30
NC
1433 case EM_MMIX:
1434 rtype = elf_mmix_reloc_type (type);
1435 break;
1436
5506d11a
AM
1437 case EM_MOXIE:
1438 rtype = elf_moxie_reloc_type (type);
1439 break;
1440
2469cfa2 1441 case EM_MSP430:
dda8d76d 1442 if (uses_msp430x_relocs (filedata))
13761a11
NC
1443 {
1444 rtype = elf_msp430x_reloc_type (type);
1445 break;
1446 }
1a0670f3 1447 /* Fall through. */
2469cfa2
NC
1448 case EM_MSP430_OLD:
1449 rtype = elf_msp430_reloc_type (type);
1450 break;
1451
35c08157
KLC
1452 case EM_NDS32:
1453 rtype = elf_nds32_reloc_type (type);
1454 break;
1455
252b5132 1456 case EM_PPC:
9ea033b2 1457 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1458 break;
1459
c833c019
AM
1460 case EM_PPC64:
1461 rtype = elf_ppc64_reloc_type (type);
1462 break;
1463
252b5132 1464 case EM_MIPS:
4fe85591 1465 case EM_MIPS_RS3_LE:
9ea033b2 1466 rtype = elf_mips_reloc_type (type);
252b5132
RH
1467 break;
1468
e23eba97
NC
1469 case EM_RISCV:
1470 rtype = elf_riscv_reloc_type (type);
1471 break;
1472
252b5132 1473 case EM_ALPHA:
9ea033b2 1474 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1475 break;
1476
1477 case EM_ARM:
9ea033b2 1478 rtype = elf_arm_reloc_type (type);
252b5132
RH
1479 break;
1480
584da044 1481 case EM_ARC:
886a2506
NC
1482 case EM_ARC_COMPACT:
1483 case EM_ARC_COMPACT2:
9ea033b2 1484 rtype = elf_arc_reloc_type (type);
252b5132
RH
1485 break;
1486
1487 case EM_PARISC:
69e617ca 1488 rtype = elf_hppa_reloc_type (type);
252b5132 1489 break;
7d466069 1490
b8720f9d
JL
1491 case EM_H8_300:
1492 case EM_H8_300H:
1493 case EM_H8S:
1494 rtype = elf_h8_reloc_type (type);
1495 break;
1496
73589c9d
CS
1497 case EM_OR1K:
1498 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1499 break;
1500
7d466069 1501 case EM_PJ:
2b0337b0 1502 case EM_PJ_OLD:
7d466069
ILT
1503 rtype = elf_pj_reloc_type (type);
1504 break;
800eeca4
JW
1505 case EM_IA_64:
1506 rtype = elf_ia64_reloc_type (type);
1507 break;
1b61cf92
HPN
1508
1509 case EM_CRIS:
1510 rtype = elf_cris_reloc_type (type);
1511 break;
535c37ff 1512
f954747f
AM
1513 case EM_860:
1514 rtype = elf_i860_reloc_type (type);
1515 break;
1516
bcedfee6 1517 case EM_X86_64:
8a9036a4 1518 case EM_L1OM:
7a9068fe 1519 case EM_K1OM:
bcedfee6
NC
1520 rtype = elf_x86_64_reloc_type (type);
1521 break;
a85d7ed0 1522
f954747f
AM
1523 case EM_S370:
1524 rtype = i370_reloc_type (type);
1525 break;
1526
53c7db4b
KH
1527 case EM_S390_OLD:
1528 case EM_S390:
1529 rtype = elf_s390_reloc_type (type);
1530 break;
93fbbb04 1531
1c0d3aa6
NC
1532 case EM_SCORE:
1533 rtype = elf_score_reloc_type (type);
1534 break;
1535
93fbbb04
GK
1536 case EM_XSTORMY16:
1537 rtype = elf_xstormy16_reloc_type (type);
1538 break;
179d3252 1539
1fe1f39c
NC
1540 case EM_CRX:
1541 rtype = elf_crx_reloc_type (type);
1542 break;
1543
179d3252
JT
1544 case EM_VAX:
1545 rtype = elf_vax_reloc_type (type);
1546 break;
1e4cf259 1547
619ed720
EB
1548 case EM_VISIUM:
1549 rtype = elf_visium_reloc_type (type);
1550 break;
1551
aca4efc7
JM
1552 case EM_BPF:
1553 rtype = elf_bpf_reloc_type (type);
1554 break;
1555
cfb8c092
NC
1556 case EM_ADAPTEVA_EPIPHANY:
1557 rtype = elf_epiphany_reloc_type (type);
1558 break;
1559
1e4cf259
NC
1560 case EM_IP2K:
1561 case EM_IP2K_OLD:
1562 rtype = elf_ip2k_reloc_type (type);
1563 break;
3b36097d
SC
1564
1565 case EM_IQ2000:
1566 rtype = elf_iq2000_reloc_type (type);
1567 break;
88da6820
NC
1568
1569 case EM_XTENSA_OLD:
1570 case EM_XTENSA:
1571 rtype = elf_xtensa_reloc_type (type);
1572 break;
a34e3ecb 1573
84e94c90
NC
1574 case EM_LATTICEMICO32:
1575 rtype = elf_lm32_reloc_type (type);
1576 break;
1577
ff7eeb89 1578 case EM_M32C_OLD:
49f58d10
JB
1579 case EM_M32C:
1580 rtype = elf_m32c_reloc_type (type);
1581 break;
1582
d031aafb
NS
1583 case EM_MT:
1584 rtype = elf_mt_reloc_type (type);
a34e3ecb 1585 break;
1d65ded4
CM
1586
1587 case EM_BLACKFIN:
1588 rtype = elf_bfin_reloc_type (type);
1589 break;
15ab5209
DB
1590
1591 case EM_CYGNUS_MEP:
1592 rtype = elf_mep_reloc_type (type);
1593 break;
60bca95a
NC
1594
1595 case EM_CR16:
1596 rtype = elf_cr16_reloc_type (type);
1597 break;
dd24e3da 1598
7ba29e2a
NC
1599 case EM_MICROBLAZE:
1600 case EM_MICROBLAZE_OLD:
1601 rtype = elf_microblaze_reloc_type (type);
1602 break;
c7927a3c 1603
99c513f6
DD
1604 case EM_RL78:
1605 rtype = elf_rl78_reloc_type (type);
1606 break;
1607
c7927a3c
NC
1608 case EM_RX:
1609 rtype = elf_rx_reloc_type (type);
1610 break;
c29aca4a 1611
a3c62988
NC
1612 case EM_METAG:
1613 rtype = elf_metag_reloc_type (type);
1614 break;
1615
c29aca4a
NC
1616 case EM_XC16X:
1617 case EM_C166:
1618 rtype = elf_xc16x_reloc_type (type);
1619 break;
40b36596
JM
1620
1621 case EM_TI_C6000:
1622 rtype = elf_tic6x_reloc_type (type);
1623 break;
aa137e4d
NC
1624
1625 case EM_TILEGX:
1626 rtype = elf_tilegx_reloc_type (type);
1627 break;
1628
1629 case EM_TILEPRO:
1630 rtype = elf_tilepro_reloc_type (type);
1631 break;
f6c1a2d5 1632
f96bd6c2
PC
1633 case EM_WEBASSEMBLY:
1634 rtype = elf_wasm32_reloc_type (type);
1635 break;
1636
f6c1a2d5
NC
1637 case EM_XGATE:
1638 rtype = elf_xgate_reloc_type (type);
1639 break;
36591ba1
SL
1640
1641 case EM_ALTERA_NIOS2:
1642 rtype = elf_nios2_reloc_type (type);
1643 break;
2b100bb5
DD
1644
1645 case EM_TI_PRU:
1646 rtype = elf_pru_reloc_type (type);
1647 break;
fe944acf
FT
1648
1649 case EM_NFP:
1650 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1651 rtype = elf_nfp3200_reloc_type (type);
1652 else
1653 rtype = elf_nfp_reloc_type (type);
1654 break;
6655dba2
SB
1655
1656 case EM_Z80:
1657 rtype = elf_z80_reloc_type (type);
1658 break;
252b5132
RH
1659 }
1660
1661 if (rtype == NULL)
39dbeff8 1662 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1663 else
5c144731 1664 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1665
dda8d76d 1666 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1667 && rtype != NULL
7ace3541
RH
1668 && streq (rtype, "R_ALPHA_LITUSE")
1669 && is_rela)
1670 {
1671 switch (rels[i].r_addend)
1672 {
1673 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1674 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1675 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1676 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1677 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1678 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1679 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1680 default: rtype = NULL;
1681 }
32ec8896 1682
7ace3541
RH
1683 if (rtype)
1684 printf (" (%s)", rtype);
1685 else
1686 {
1687 putchar (' ');
1688 printf (_("<unknown addend: %lx>"),
1689 (unsigned long) rels[i].r_addend);
015dc7e1 1690 res = false;
7ace3541
RH
1691 }
1692 }
1693 else if (symtab_index)
252b5132 1694 {
af3fc3bc 1695 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1696 {
27a45f42
AS
1697 error (_(" bad symbol index: %08lx in reloc\n"),
1698 (unsigned long) symtab_index);
015dc7e1 1699 res = false;
32ec8896 1700 }
af3fc3bc 1701 else
19936277 1702 {
2cf0635d 1703 Elf_Internal_Sym * psym;
bb4d2ac2
L
1704 const char * version_string;
1705 enum versioned_symbol_info sym_info;
1706 unsigned short vna_other;
19936277 1707
af3fc3bc 1708 psym = symtab + symtab_index;
103f02d3 1709
bb4d2ac2 1710 version_string
dda8d76d 1711 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1712 strtab, strtablen,
1713 symtab_index,
1714 psym,
1715 &sym_info,
1716 &vna_other);
1717
af3fc3bc 1718 printf (" ");
171191ba 1719
d8045f23
NC
1720 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1721 {
1722 const char * name;
1723 unsigned int len;
1724 unsigned int width = is_32bit_elf ? 8 : 14;
1725
1726 /* Relocations against GNU_IFUNC symbols do not use the value
1727 of the symbol as the address to relocate against. Instead
1728 they invoke the function named by the symbol and use its
1729 result as the address for relocation.
1730
1731 To indicate this to the user, do not display the value of
1732 the symbol in the "Symbols's Value" field. Instead show
1733 its name followed by () as a hint that the symbol is
1734 invoked. */
1735
1736 if (strtab == NULL
1737 || psym->st_name == 0
1738 || psym->st_name >= strtablen)
1739 name = "??";
1740 else
1741 name = strtab + psym->st_name;
1742
1743 len = print_symbol (width, name);
bb4d2ac2
L
1744 if (version_string)
1745 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1746 version_string);
d8045f23
NC
1747 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1748 }
1749 else
1750 {
1751 print_vma (psym->st_value, LONG_HEX);
171191ba 1752
d8045f23
NC
1753 printf (is_32bit_elf ? " " : " ");
1754 }
103f02d3 1755
af3fc3bc 1756 if (psym->st_name == 0)
f1ef08cb 1757 {
2cf0635d 1758 const char * sec_name = "<null>";
f1ef08cb
AM
1759 char name_buf[40];
1760
1761 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1762 {
dda8d76d 1763 if (psym->st_shndx < filedata->file_header.e_shnum)
b9e920ec
AM
1764 sec_name = SECTION_NAME_PRINT (filedata->section_headers
1765 + psym->st_shndx);
f1ef08cb
AM
1766 else if (psym->st_shndx == SHN_ABS)
1767 sec_name = "ABS";
1768 else if (psym->st_shndx == SHN_COMMON)
1769 sec_name = "COMMON";
dda8d76d 1770 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1771 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1772 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1773 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1774 sec_name = "SCOMMON";
dda8d76d 1775 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1776 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1777 sec_name = "SUNDEF";
dda8d76d
NC
1778 else if ((filedata->file_header.e_machine == EM_X86_64
1779 || filedata->file_header.e_machine == EM_L1OM
1780 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1781 && psym->st_shndx == SHN_X86_64_LCOMMON)
1782 sec_name = "LARGE_COMMON";
dda8d76d
NC
1783 else if (filedata->file_header.e_machine == EM_IA_64
1784 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1785 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1786 sec_name = "ANSI_COM";
dda8d76d 1787 else if (is_ia64_vms (filedata)
148b93f2
NC
1788 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1789 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1790 else
1791 {
1792 sprintf (name_buf, "<section 0x%x>",
1793 (unsigned int) psym->st_shndx);
1794 sec_name = name_buf;
1795 }
1796 }
1797 print_symbol (22, sec_name);
1798 }
af3fc3bc 1799 else if (strtab == NULL)
d79b3d50 1800 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1801 else if (psym->st_name >= strtablen)
32ec8896 1802 {
27a45f42
AS
1803 error (_("<corrupt string table index: %3ld>\n"),
1804 psym->st_name);
015dc7e1 1805 res = false;
32ec8896 1806 }
af3fc3bc 1807 else
bb4d2ac2
L
1808 {
1809 print_symbol (22, strtab + psym->st_name);
1810 if (version_string)
1811 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1812 version_string);
1813 }
103f02d3 1814
af3fc3bc 1815 if (is_rela)
171191ba 1816 {
7360e63f 1817 bfd_vma off = rels[i].r_addend;
171191ba 1818
7360e63f 1819 if ((bfd_signed_vma) off < 0)
598aaa76 1820 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1821 else
598aaa76 1822 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1823 }
19936277 1824 }
252b5132 1825 }
1b228002 1826 else if (is_rela)
f7a99963 1827 {
7360e63f 1828 bfd_vma off = rels[i].r_addend;
e04d7088
L
1829
1830 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1831 if ((bfd_signed_vma) off < 0)
e04d7088
L
1832 printf ("-%" BFD_VMA_FMT "x", - off);
1833 else
1834 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1835 }
252b5132 1836
dda8d76d 1837 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1838 && rtype != NULL
1839 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1840 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1841
252b5132 1842 putchar ('\n');
2c71103e 1843
aca88567 1844#ifdef BFD64
dda8d76d 1845 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1846 {
91d6fa6a
NC
1847 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1848 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1849 const char * rtype2 = elf_mips_reloc_type (type2);
1850 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1851
2c71103e
NC
1852 printf (" Type2: ");
1853
1854 if (rtype2 == NULL)
39dbeff8
AM
1855 printf (_("unrecognized: %-7lx"),
1856 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1857 else
1858 printf ("%-17.17s", rtype2);
1859
18bd398b 1860 printf ("\n Type3: ");
2c71103e
NC
1861
1862 if (rtype3 == NULL)
39dbeff8
AM
1863 printf (_("unrecognized: %-7lx"),
1864 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1865 else
1866 printf ("%-17.17s", rtype3);
1867
53c7db4b 1868 putchar ('\n');
2c71103e 1869 }
aca88567 1870#endif /* BFD64 */
252b5132
RH
1871 }
1872
c8286bd1 1873 free (rels);
32ec8896
NC
1874
1875 return res;
252b5132
RH
1876}
1877
37c18eed
SD
1878static const char *
1879get_aarch64_dynamic_type (unsigned long type)
1880{
1881 switch (type)
1882 {
1883 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 1884 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 1885 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
1886 default:
1887 return NULL;
1888 }
1889}
1890
252b5132 1891static const char *
d3ba0551 1892get_mips_dynamic_type (unsigned long type)
252b5132
RH
1893{
1894 switch (type)
1895 {
1896 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1897 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1898 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1899 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1900 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1901 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1902 case DT_MIPS_MSYM: return "MIPS_MSYM";
1903 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1904 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1905 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1906 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1907 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1908 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1909 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1910 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1911 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1912 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1913 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1914 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1915 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1916 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1917 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1918 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1919 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1920 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1921 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1922 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1923 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1924 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1925 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1926 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1927 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1928 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1929 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1930 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1931 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1932 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1933 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1934 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1935 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1936 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1937 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1938 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1939 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1940 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1941 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 1942 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
1943 default:
1944 return NULL;
1945 }
1946}
1947
9a097730 1948static const char *
d3ba0551 1949get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1950{
1951 switch (type)
1952 {
1953 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1954 default:
1955 return NULL;
1956 }
103f02d3
UD
1957}
1958
7490d522
AM
1959static const char *
1960get_ppc_dynamic_type (unsigned long type)
1961{
1962 switch (type)
1963 {
a7f2871e 1964 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1965 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1966 default:
1967 return NULL;
1968 }
1969}
1970
f1cb7e17 1971static const char *
d3ba0551 1972get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1973{
1974 switch (type)
1975 {
a7f2871e
AM
1976 case DT_PPC64_GLINK: return "PPC64_GLINK";
1977 case DT_PPC64_OPD: return "PPC64_OPD";
1978 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1979 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1980 default:
1981 return NULL;
1982 }
1983}
1984
103f02d3 1985static const char *
d3ba0551 1986get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1987{
1988 switch (type)
1989 {
1990 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1991 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1992 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1993 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1994 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1995 case DT_HP_PREINIT: return "HP_PREINIT";
1996 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1997 case DT_HP_NEEDED: return "HP_NEEDED";
1998 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1999 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2000 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2001 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2002 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2003 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2004 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2005 case DT_HP_FILTERED: return "HP_FILTERED";
2006 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2007 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2008 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2009 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2010 case DT_PLT: return "PLT";
2011 case DT_PLT_SIZE: return "PLT_SIZE";
2012 case DT_DLT: return "DLT";
2013 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2014 default:
2015 return NULL;
2016 }
2017}
9a097730 2018
ecc51f48 2019static const char *
d3ba0551 2020get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2021{
2022 switch (type)
2023 {
148b93f2
NC
2024 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2025 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2026 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2027 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2028 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2029 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2030 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2031 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2032 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2033 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2034 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2035 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2036 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2037 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2038 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2039 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2040 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2041 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2042 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2043 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2044 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2045 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2046 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2047 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2048 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2049 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2050 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2051 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2052 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2053 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2054 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2055 default:
2056 return NULL;
2057 }
2058}
2059
fd85a6a1
NC
2060static const char *
2061get_solaris_section_type (unsigned long type)
2062{
2063 switch (type)
2064 {
2065 case 0x6fffffee: return "SUNW_ancillary";
2066 case 0x6fffffef: return "SUNW_capchain";
2067 case 0x6ffffff0: return "SUNW_capinfo";
2068 case 0x6ffffff1: return "SUNW_symsort";
2069 case 0x6ffffff2: return "SUNW_tlssort";
2070 case 0x6ffffff3: return "SUNW_LDYNSYM";
2071 case 0x6ffffff4: return "SUNW_dof";
2072 case 0x6ffffff5: return "SUNW_cap";
2073 case 0x6ffffff6: return "SUNW_SIGNATURE";
2074 case 0x6ffffff7: return "SUNW_ANNOTATE";
2075 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2076 case 0x6ffffff9: return "SUNW_DEBUG";
2077 case 0x6ffffffa: return "SUNW_move";
2078 case 0x6ffffffb: return "SUNW_COMDAT";
2079 case 0x6ffffffc: return "SUNW_syminfo";
2080 case 0x6ffffffd: return "SUNW_verdef";
2081 case 0x6ffffffe: return "SUNW_verneed";
2082 case 0x6fffffff: return "SUNW_versym";
2083 case 0x70000000: return "SPARC_GOTDATA";
2084 default: return NULL;
2085 }
2086}
2087
fabcb361
RH
2088static const char *
2089get_alpha_dynamic_type (unsigned long type)
2090{
2091 switch (type)
2092 {
2093 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2094 default: return NULL;
fabcb361
RH
2095 }
2096}
2097
1c0d3aa6
NC
2098static const char *
2099get_score_dynamic_type (unsigned long type)
2100{
2101 switch (type)
2102 {
2103 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2104 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2105 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2106 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2107 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2108 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2109 default: return NULL;
1c0d3aa6
NC
2110 }
2111}
2112
40b36596
JM
2113static const char *
2114get_tic6x_dynamic_type (unsigned long type)
2115{
2116 switch (type)
2117 {
2118 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2119 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2120 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2121 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2122 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2123 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2124 default: return NULL;
40b36596
JM
2125 }
2126}
1c0d3aa6 2127
36591ba1
SL
2128static const char *
2129get_nios2_dynamic_type (unsigned long type)
2130{
2131 switch (type)
2132 {
2133 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2134 default: return NULL;
36591ba1
SL
2135 }
2136}
2137
fd85a6a1
NC
2138static const char *
2139get_solaris_dynamic_type (unsigned long type)
2140{
2141 switch (type)
2142 {
2143 case 0x6000000d: return "SUNW_AUXILIARY";
2144 case 0x6000000e: return "SUNW_RTLDINF";
2145 case 0x6000000f: return "SUNW_FILTER";
2146 case 0x60000010: return "SUNW_CAP";
2147 case 0x60000011: return "SUNW_SYMTAB";
2148 case 0x60000012: return "SUNW_SYMSZ";
2149 case 0x60000013: return "SUNW_SORTENT";
2150 case 0x60000014: return "SUNW_SYMSORT";
2151 case 0x60000015: return "SUNW_SYMSORTSZ";
2152 case 0x60000016: return "SUNW_TLSSORT";
2153 case 0x60000017: return "SUNW_TLSSORTSZ";
2154 case 0x60000018: return "SUNW_CAPINFO";
2155 case 0x60000019: return "SUNW_STRPAD";
2156 case 0x6000001a: return "SUNW_CAPCHAIN";
2157 case 0x6000001b: return "SUNW_LDMACH";
2158 case 0x6000001d: return "SUNW_CAPCHAINENT";
2159 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2160 case 0x60000021: return "SUNW_PARENT";
2161 case 0x60000023: return "SUNW_ASLR";
2162 case 0x60000025: return "SUNW_RELAX";
2163 case 0x60000029: return "SUNW_NXHEAP";
2164 case 0x6000002b: return "SUNW_NXSTACK";
2165
2166 case 0x70000001: return "SPARC_REGISTER";
2167 case 0x7ffffffd: return "AUXILIARY";
2168 case 0x7ffffffe: return "USED";
2169 case 0x7fffffff: return "FILTER";
2170
15f205b1 2171 default: return NULL;
fd85a6a1
NC
2172 }
2173}
2174
252b5132 2175static const char *
dda8d76d 2176get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2177{
e9e44622 2178 static char buff[64];
252b5132
RH
2179
2180 switch (type)
2181 {
2182 case DT_NULL: return "NULL";
2183 case DT_NEEDED: return "NEEDED";
2184 case DT_PLTRELSZ: return "PLTRELSZ";
2185 case DT_PLTGOT: return "PLTGOT";
2186 case DT_HASH: return "HASH";
2187 case DT_STRTAB: return "STRTAB";
2188 case DT_SYMTAB: return "SYMTAB";
2189 case DT_RELA: return "RELA";
2190 case DT_RELASZ: return "RELASZ";
2191 case DT_RELAENT: return "RELAENT";
2192 case DT_STRSZ: return "STRSZ";
2193 case DT_SYMENT: return "SYMENT";
2194 case DT_INIT: return "INIT";
2195 case DT_FINI: return "FINI";
2196 case DT_SONAME: return "SONAME";
2197 case DT_RPATH: return "RPATH";
2198 case DT_SYMBOLIC: return "SYMBOLIC";
2199 case DT_REL: return "REL";
2200 case DT_RELSZ: return "RELSZ";
2201 case DT_RELENT: return "RELENT";
2202 case DT_PLTREL: return "PLTREL";
2203 case DT_DEBUG: return "DEBUG";
2204 case DT_TEXTREL: return "TEXTREL";
2205 case DT_JMPREL: return "JMPREL";
2206 case DT_BIND_NOW: return "BIND_NOW";
2207 case DT_INIT_ARRAY: return "INIT_ARRAY";
2208 case DT_FINI_ARRAY: return "FINI_ARRAY";
2209 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2210 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2211 case DT_RUNPATH: return "RUNPATH";
2212 case DT_FLAGS: return "FLAGS";
2d0e6f43 2213
d1133906
NC
2214 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2215 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2216 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2217
05107a46 2218 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2219 case DT_PLTPADSZ: return "PLTPADSZ";
2220 case DT_MOVEENT: return "MOVEENT";
2221 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2222 case DT_FEATURE: return "FEATURE";
252b5132
RH
2223 case DT_POSFLAG_1: return "POSFLAG_1";
2224 case DT_SYMINSZ: return "SYMINSZ";
2225 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2226
252b5132 2227 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2228 case DT_CONFIG: return "CONFIG";
2229 case DT_DEPAUDIT: return "DEPAUDIT";
2230 case DT_AUDIT: return "AUDIT";
2231 case DT_PLTPAD: return "PLTPAD";
2232 case DT_MOVETAB: return "MOVETAB";
252b5132 2233 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2234
252b5132 2235 case DT_VERSYM: return "VERSYM";
103f02d3 2236
67a4f2b7
AO
2237 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2238 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2239 case DT_RELACOUNT: return "RELACOUNT";
2240 case DT_RELCOUNT: return "RELCOUNT";
2241 case DT_FLAGS_1: return "FLAGS_1";
2242 case DT_VERDEF: return "VERDEF";
2243 case DT_VERDEFNUM: return "VERDEFNUM";
2244 case DT_VERNEED: return "VERNEED";
2245 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2246
019148e4 2247 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2248 case DT_USED: return "USED";
2249 case DT_FILTER: return "FILTER";
103f02d3 2250
047b2264
JJ
2251 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2252 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2253 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2254 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2255 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2256 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2257 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2258
252b5132
RH
2259 default:
2260 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2261 {
2cf0635d 2262 const char * result;
103f02d3 2263
dda8d76d 2264 switch (filedata->file_header.e_machine)
252b5132 2265 {
37c18eed
SD
2266 case EM_AARCH64:
2267 result = get_aarch64_dynamic_type (type);
2268 break;
252b5132 2269 case EM_MIPS:
4fe85591 2270 case EM_MIPS_RS3_LE:
252b5132
RH
2271 result = get_mips_dynamic_type (type);
2272 break;
9a097730
RH
2273 case EM_SPARCV9:
2274 result = get_sparc64_dynamic_type (type);
2275 break;
7490d522
AM
2276 case EM_PPC:
2277 result = get_ppc_dynamic_type (type);
2278 break;
f1cb7e17
AM
2279 case EM_PPC64:
2280 result = get_ppc64_dynamic_type (type);
2281 break;
ecc51f48
NC
2282 case EM_IA_64:
2283 result = get_ia64_dynamic_type (type);
2284 break;
fabcb361
RH
2285 case EM_ALPHA:
2286 result = get_alpha_dynamic_type (type);
2287 break;
1c0d3aa6
NC
2288 case EM_SCORE:
2289 result = get_score_dynamic_type (type);
2290 break;
40b36596
JM
2291 case EM_TI_C6000:
2292 result = get_tic6x_dynamic_type (type);
2293 break;
36591ba1
SL
2294 case EM_ALTERA_NIOS2:
2295 result = get_nios2_dynamic_type (type);
2296 break;
252b5132 2297 default:
dda8d76d 2298 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2299 result = get_solaris_dynamic_type (type);
2300 else
2301 result = NULL;
252b5132
RH
2302 break;
2303 }
2304
2305 if (result != NULL)
2306 return result;
2307
e9e44622 2308 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2309 }
eec8f817 2310 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2311 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2312 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2313 {
2cf0635d 2314 const char * result;
103f02d3 2315
dda8d76d 2316 switch (filedata->file_header.e_machine)
103f02d3
UD
2317 {
2318 case EM_PARISC:
2319 result = get_parisc_dynamic_type (type);
2320 break;
148b93f2
NC
2321 case EM_IA_64:
2322 result = get_ia64_dynamic_type (type);
2323 break;
103f02d3 2324 default:
dda8d76d 2325 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2326 result = get_solaris_dynamic_type (type);
2327 else
2328 result = NULL;
103f02d3
UD
2329 break;
2330 }
2331
2332 if (result != NULL)
2333 return result;
2334
e9e44622
JJ
2335 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2336 type);
103f02d3 2337 }
252b5132 2338 else
e9e44622 2339 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2340
252b5132
RH
2341 return buff;
2342 }
2343}
2344
2345static char *
d3ba0551 2346get_file_type (unsigned e_type)
252b5132 2347{
89246a0e 2348 static char buff[64];
252b5132
RH
2349
2350 switch (e_type)
2351 {
32ec8896
NC
2352 case ET_NONE: return _("NONE (None)");
2353 case ET_REL: return _("REL (Relocatable file)");
2354 case ET_EXEC: return _("EXEC (Executable file)");
2355 case ET_DYN: return _("DYN (Shared object file)");
2356 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2357
2358 default:
2359 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2360 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2361 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2362 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2363 else
e9e44622 2364 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2365 return buff;
2366 }
2367}
2368
2369static char *
d3ba0551 2370get_machine_name (unsigned e_machine)
252b5132 2371{
b34976b6 2372 static char buff[64]; /* XXX */
252b5132
RH
2373
2374 switch (e_machine)
2375 {
55e22ca8
NC
2376 /* Please keep this switch table sorted by increasing EM_ value. */
2377 /* 0 */
c45021f2
NC
2378 case EM_NONE: return _("None");
2379 case EM_M32: return "WE32100";
2380 case EM_SPARC: return "Sparc";
2381 case EM_386: return "Intel 80386";
2382 case EM_68K: return "MC68000";
2383 case EM_88K: return "MC88000";
22abe556 2384 case EM_IAMCU: return "Intel MCU";
fb70ec17 2385 case EM_860: return "Intel 80860";
c45021f2
NC
2386 case EM_MIPS: return "MIPS R3000";
2387 case EM_S370: return "IBM System/370";
55e22ca8 2388 /* 10 */
7036c0e1 2389 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2390 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2391 case EM_PARISC: return "HPPA";
55e22ca8 2392 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2393 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2394 case EM_960: return "Intel 80960";
c45021f2 2395 case EM_PPC: return "PowerPC";
55e22ca8 2396 /* 20 */
285d1771 2397 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2398 case EM_S390_OLD:
2399 case EM_S390: return "IBM S/390";
2400 case EM_SPU: return "SPU";
2401 /* 30 */
2402 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2403 case EM_FR20: return "Fujitsu FR20";
2404 case EM_RH32: return "TRW RH32";
b34976b6 2405 case EM_MCORE: return "MCORE";
55e22ca8 2406 /* 40 */
7036c0e1
AJ
2407 case EM_ARM: return "ARM";
2408 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2409 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2410 case EM_SPARCV9: return "Sparc v9";
2411 case EM_TRICORE: return "Siemens Tricore";
584da044 2412 case EM_ARC: return "ARC";
c2dcd04e
NC
2413 case EM_H8_300: return "Renesas H8/300";
2414 case EM_H8_300H: return "Renesas H8/300H";
2415 case EM_H8S: return "Renesas H8S";
2416 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2417 /* 50 */
30800947 2418 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2419 case EM_MIPS_X: return "Stanford MIPS-X";
2420 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2421 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2422 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2423 case EM_PCP: return "Siemens PCP";
2424 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2425 case EM_NDR1: return "Denso NDR1 microprocesspr";
2426 case EM_STARCORE: return "Motorola Star*Core processor";
2427 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2428 /* 60 */
7036c0e1
AJ
2429 case EM_ST100: return "STMicroelectronics ST100 processor";
2430 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2431 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2432 case EM_PDSP: return "Sony DSP processor";
2433 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2434 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2435 case EM_FX66: return "Siemens FX66 microcontroller";
2436 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2437 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2438 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2439 /* 70 */
7036c0e1
AJ
2440 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2441 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2442 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2443 case EM_SVX: return "Silicon Graphics SVx";
2444 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2445 case EM_VAX: return "Digital VAX";
1b61cf92 2446 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2447 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2448 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2449 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2450 /* 80 */
b34976b6 2451 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2452 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2453 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2454 case EM_AVR_OLD:
2455 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2456 case EM_CYGNUS_FR30:
2457 case EM_FR30: return "Fujitsu FR30";
2458 case EM_CYGNUS_D10V:
2459 case EM_D10V: return "d10v";
2460 case EM_CYGNUS_D30V:
2461 case EM_D30V: return "d30v";
2462 case EM_CYGNUS_V850:
2463 case EM_V850: return "Renesas V850";
2464 case EM_CYGNUS_M32R:
2465 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2466 case EM_CYGNUS_MN10300:
2467 case EM_MN10300: return "mn10300";
2468 /* 90 */
2469 case EM_CYGNUS_MN10200:
2470 case EM_MN10200: return "mn10200";
2471 case EM_PJ: return "picoJava";
73589c9d 2472 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2473 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2474 case EM_XTENSA_OLD:
2475 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2476 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2477 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2478 case EM_NS32K: return "National Semiconductor 32000 series";
2479 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2480 case EM_SNP1K: return "Trebia SNP 1000 processor";
2481 /* 100 */
9abca702 2482 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2483 case EM_IP2K_OLD:
2484 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2485 case EM_MAX: return "MAX Processor";
2486 case EM_CR: return "National Semiconductor CompactRISC";
2487 case EM_F2MC16: return "Fujitsu F2MC16";
2488 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2489 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2490 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2491 case EM_SEP: return "Sharp embedded microprocessor";
2492 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2493 /* 110 */
11636f9e
JM
2494 case EM_UNICORE: return "Unicore";
2495 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2496 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2497 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2498 case EM_CRX: return "National Semiconductor CRX microprocessor";
2499 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2500 case EM_C166:
d70c5fc7 2501 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2502 case EM_M16C: return "Renesas M16C series microprocessors";
2503 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2504 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2505 /* 120 */
2506 case EM_M32C: return "Renesas M32c";
2507 /* 130 */
11636f9e
JM
2508 case EM_TSK3000: return "Altium TSK3000 core";
2509 case EM_RS08: return "Freescale RS08 embedded processor";
2510 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2511 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2512 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2513 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2514 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2515 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2516 /* 140 */
11636f9e
JM
2517 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2518 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2519 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2520 case EM_TI_PRU: return "TI PRU I/O processor";
2521 /* 160 */
11636f9e
JM
2522 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2523 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2524 case EM_R32C: return "Renesas R32C series microprocessors";
2525 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2526 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2527 case EM_8051: return "Intel 8051 and variants";
2528 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2529 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2530 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2531 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2532 /* 170 */
11636f9e
JM
2533 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2534 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2535 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2536 case EM_RX: return "Renesas RX";
a3c62988 2537 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2538 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2539 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2540 case EM_CR16:
2541 case EM_MICROBLAZE:
2542 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2543 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2544 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2545 /* 180 */
2546 case EM_L1OM: return "Intel L1OM";
2547 case EM_K1OM: return "Intel K1OM";
2548 case EM_INTEL182: return "Intel (reserved)";
2549 case EM_AARCH64: return "AArch64";
2550 case EM_ARM184: return "ARM (reserved)";
2551 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2552 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2553 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2554 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2555 /* 190 */
11636f9e 2556 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2557 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2558 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2559 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2560 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2561 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2562 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2563 case EM_RL78: return "Renesas RL78";
6d913794 2564 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2565 case EM_78K0R: return "Renesas 78K0R";
2566 /* 200 */
6d913794 2567 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2568 case EM_BA1: return "Beyond BA1 CPU architecture";
2569 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2570 case EM_XCORE: return "XMOS xCORE processor family";
2571 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2572 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2573 /* 210 */
6d913794
NC
2574 case EM_KM32: return "KM211 KM32 32-bit processor";
2575 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2576 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2577 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2578 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2579 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2580 case EM_COGE: return "Cognitive Smart Memory Processor";
2581 case EM_COOL: return "Bluechip Systems CoolEngine";
2582 case EM_NORC: return "Nanoradio Optimized RISC";
2583 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2584 /* 220 */
15f205b1 2585 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2586 case EM_VISIUM: return "CDS VISIUMcore processor";
2587 case EM_FT32: return "FTDI Chip FT32";
2588 case EM_MOXIE: return "Moxie";
2589 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2590 /* 230 (all reserved) */
2591 /* 240 */
55e22ca8
NC
2592 case EM_RISCV: return "RISC-V";
2593 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2594 case EM_CEVA: return "CEVA Processor Architecture Family";
2595 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2596 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2597 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2598 case EM_IMG1: return "Imagination Technologies";
2599 /* 250 */
fe944acf 2600 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2601 case EM_VE: return "NEC Vector Engine";
2602 case EM_CSKY: return "C-SKY";
2603 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2604 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2605 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2606 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2607 case EM_65816: return "WDC 65816/65C816";
01a8c731 2608 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2609 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2610
2611 /* Large numbers... */
2612 case EM_MT: return "Morpho Techologies MT processor";
2613 case EM_ALPHA: return "Alpha";
2614 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2615 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2616 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2617 case EM_IQ2000: return "Vitesse IQ2000";
2618 case EM_M32C_OLD:
2619 case EM_NIOS32: return "Altera Nios";
2620 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2621 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2622 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2623 case EM_S12Z: return "Freescale S12Z";
55e22ca8 2624
252b5132 2625 default:
35d9dd2f 2626 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2627 return buff;
2628 }
2629}
2630
a9522a21
AB
2631static void
2632decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2633{
2634 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 2635 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
2636 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2637 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2638 architectures.
2639
2640 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2641 but also sets a specific architecture type in the e_flags field.
2642
2643 However, when decoding the flags we don't worry if we see an
2644 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2645 ARCEM architecture type. */
2646
2647 switch (e_flags & EF_ARC_MACH_MSK)
2648 {
2649 /* We only expect these to occur for EM_ARC_COMPACT2. */
2650 case EF_ARC_CPU_ARCV2EM:
2651 strcat (buf, ", ARC EM");
2652 break;
2653 case EF_ARC_CPU_ARCV2HS:
2654 strcat (buf, ", ARC HS");
2655 break;
2656
2657 /* We only expect these to occur for EM_ARC_COMPACT. */
2658 case E_ARC_MACH_ARC600:
2659 strcat (buf, ", ARC600");
2660 break;
2661 case E_ARC_MACH_ARC601:
2662 strcat (buf, ", ARC601");
2663 break;
2664 case E_ARC_MACH_ARC700:
2665 strcat (buf, ", ARC700");
2666 break;
2667
2668 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2669 new ELF with new architecture being read by an old version of
2670 readelf, or (c) An ELF built with non-GNU compiler that does not
2671 set the architecture in the e_flags. */
2672 default:
2673 if (e_machine == EM_ARC_COMPACT)
2674 strcat (buf, ", Unknown ARCompact");
2675 else
2676 strcat (buf, ", Unknown ARC");
2677 break;
2678 }
2679
2680 switch (e_flags & EF_ARC_OSABI_MSK)
2681 {
2682 case E_ARC_OSABI_ORIG:
2683 strcat (buf, ", (ABI:legacy)");
2684 break;
2685 case E_ARC_OSABI_V2:
2686 strcat (buf, ", (ABI:v2)");
2687 break;
2688 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2689 case E_ARC_OSABI_V3:
2690 strcat (buf, ", v3 no-legacy-syscalls ABI");
2691 break;
53a346d8
CZ
2692 case E_ARC_OSABI_V4:
2693 strcat (buf, ", v4 ABI");
2694 break;
a9522a21
AB
2695 default:
2696 strcat (buf, ", unrecognised ARC OSABI flag");
2697 break;
2698 }
2699}
2700
f3485b74 2701static void
d3ba0551 2702decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2703{
2704 unsigned eabi;
015dc7e1 2705 bool unknown = false;
f3485b74
NC
2706
2707 eabi = EF_ARM_EABI_VERSION (e_flags);
2708 e_flags &= ~ EF_ARM_EABIMASK;
2709
2710 /* Handle "generic" ARM flags. */
2711 if (e_flags & EF_ARM_RELEXEC)
2712 {
2713 strcat (buf, ", relocatable executable");
2714 e_flags &= ~ EF_ARM_RELEXEC;
2715 }
76da6bbe 2716
18a20338
CL
2717 if (e_flags & EF_ARM_PIC)
2718 {
2719 strcat (buf, ", position independent");
2720 e_flags &= ~ EF_ARM_PIC;
2721 }
2722
f3485b74
NC
2723 /* Now handle EABI specific flags. */
2724 switch (eabi)
2725 {
2726 default:
2c71103e 2727 strcat (buf, ", <unrecognized EABI>");
f3485b74 2728 if (e_flags)
015dc7e1 2729 unknown = true;
f3485b74
NC
2730 break;
2731
2732 case EF_ARM_EABI_VER1:
a5bcd848 2733 strcat (buf, ", Version1 EABI");
f3485b74
NC
2734 while (e_flags)
2735 {
2736 unsigned flag;
76da6bbe 2737
f3485b74
NC
2738 /* Process flags one bit at a time. */
2739 flag = e_flags & - e_flags;
2740 e_flags &= ~ flag;
76da6bbe 2741
f3485b74
NC
2742 switch (flag)
2743 {
a5bcd848 2744 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2745 strcat (buf, ", sorted symbol tables");
2746 break;
76da6bbe 2747
f3485b74 2748 default:
015dc7e1 2749 unknown = true;
f3485b74
NC
2750 break;
2751 }
2752 }
2753 break;
76da6bbe 2754
a5bcd848
PB
2755 case EF_ARM_EABI_VER2:
2756 strcat (buf, ", Version2 EABI");
2757 while (e_flags)
2758 {
2759 unsigned flag;
2760
2761 /* Process flags one bit at a time. */
2762 flag = e_flags & - e_flags;
2763 e_flags &= ~ flag;
2764
2765 switch (flag)
2766 {
2767 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2768 strcat (buf, ", sorted symbol tables");
2769 break;
2770
2771 case EF_ARM_DYNSYMSUSESEGIDX:
2772 strcat (buf, ", dynamic symbols use segment index");
2773 break;
2774
2775 case EF_ARM_MAPSYMSFIRST:
2776 strcat (buf, ", mapping symbols precede others");
2777 break;
2778
2779 default:
015dc7e1 2780 unknown = true;
a5bcd848
PB
2781 break;
2782 }
2783 }
2784 break;
2785
d507cf36
PB
2786 case EF_ARM_EABI_VER3:
2787 strcat (buf, ", Version3 EABI");
8cb51566
PB
2788 break;
2789
2790 case EF_ARM_EABI_VER4:
2791 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2792 while (e_flags)
2793 {
2794 unsigned flag;
2795
2796 /* Process flags one bit at a time. */
2797 flag = e_flags & - e_flags;
2798 e_flags &= ~ flag;
2799
2800 switch (flag)
2801 {
2802 case EF_ARM_BE8:
2803 strcat (buf, ", BE8");
2804 break;
2805
2806 case EF_ARM_LE8:
2807 strcat (buf, ", LE8");
2808 break;
2809
2810 default:
015dc7e1 2811 unknown = true;
3bfcb652
NC
2812 break;
2813 }
3bfcb652
NC
2814 }
2815 break;
3a4a14e9
PB
2816
2817 case EF_ARM_EABI_VER5:
2818 strcat (buf, ", Version5 EABI");
d507cf36
PB
2819 while (e_flags)
2820 {
2821 unsigned flag;
2822
2823 /* Process flags one bit at a time. */
2824 flag = e_flags & - e_flags;
2825 e_flags &= ~ flag;
2826
2827 switch (flag)
2828 {
2829 case EF_ARM_BE8:
2830 strcat (buf, ", BE8");
2831 break;
2832
2833 case EF_ARM_LE8:
2834 strcat (buf, ", LE8");
2835 break;
2836
3bfcb652
NC
2837 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2838 strcat (buf, ", soft-float ABI");
2839 break;
2840
2841 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2842 strcat (buf, ", hard-float ABI");
2843 break;
2844
d507cf36 2845 default:
015dc7e1 2846 unknown = true;
d507cf36
PB
2847 break;
2848 }
2849 }
2850 break;
2851
f3485b74 2852 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2853 strcat (buf, ", GNU EABI");
f3485b74
NC
2854 while (e_flags)
2855 {
2856 unsigned flag;
76da6bbe 2857
f3485b74
NC
2858 /* Process flags one bit at a time. */
2859 flag = e_flags & - e_flags;
2860 e_flags &= ~ flag;
76da6bbe 2861
f3485b74
NC
2862 switch (flag)
2863 {
a5bcd848 2864 case EF_ARM_INTERWORK:
f3485b74
NC
2865 strcat (buf, ", interworking enabled");
2866 break;
76da6bbe 2867
a5bcd848 2868 case EF_ARM_APCS_26:
f3485b74
NC
2869 strcat (buf, ", uses APCS/26");
2870 break;
76da6bbe 2871
a5bcd848 2872 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2873 strcat (buf, ", uses APCS/float");
2874 break;
76da6bbe 2875
a5bcd848 2876 case EF_ARM_PIC:
f3485b74
NC
2877 strcat (buf, ", position independent");
2878 break;
76da6bbe 2879
a5bcd848 2880 case EF_ARM_ALIGN8:
f3485b74
NC
2881 strcat (buf, ", 8 bit structure alignment");
2882 break;
76da6bbe 2883
a5bcd848 2884 case EF_ARM_NEW_ABI:
f3485b74
NC
2885 strcat (buf, ", uses new ABI");
2886 break;
76da6bbe 2887
a5bcd848 2888 case EF_ARM_OLD_ABI:
f3485b74
NC
2889 strcat (buf, ", uses old ABI");
2890 break;
76da6bbe 2891
a5bcd848 2892 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2893 strcat (buf, ", software FP");
2894 break;
76da6bbe 2895
90e01f86
ILT
2896 case EF_ARM_VFP_FLOAT:
2897 strcat (buf, ", VFP");
2898 break;
2899
fde78edd
NC
2900 case EF_ARM_MAVERICK_FLOAT:
2901 strcat (buf, ", Maverick FP");
2902 break;
2903
f3485b74 2904 default:
015dc7e1 2905 unknown = true;
f3485b74
NC
2906 break;
2907 }
2908 }
2909 }
f3485b74
NC
2910
2911 if (unknown)
2b692964 2912 strcat (buf,_(", <unknown>"));
f3485b74
NC
2913}
2914
343433df
AB
2915static void
2916decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2917{
2918 --size; /* Leave space for null terminator. */
2919
2920 switch (e_flags & EF_AVR_MACH)
2921 {
2922 case E_AVR_MACH_AVR1:
2923 strncat (buf, ", avr:1", size);
2924 break;
2925 case E_AVR_MACH_AVR2:
2926 strncat (buf, ", avr:2", size);
2927 break;
2928 case E_AVR_MACH_AVR25:
2929 strncat (buf, ", avr:25", size);
2930 break;
2931 case E_AVR_MACH_AVR3:
2932 strncat (buf, ", avr:3", size);
2933 break;
2934 case E_AVR_MACH_AVR31:
2935 strncat (buf, ", avr:31", size);
2936 break;
2937 case E_AVR_MACH_AVR35:
2938 strncat (buf, ", avr:35", size);
2939 break;
2940 case E_AVR_MACH_AVR4:
2941 strncat (buf, ", avr:4", size);
2942 break;
2943 case E_AVR_MACH_AVR5:
2944 strncat (buf, ", avr:5", size);
2945 break;
2946 case E_AVR_MACH_AVR51:
2947 strncat (buf, ", avr:51", size);
2948 break;
2949 case E_AVR_MACH_AVR6:
2950 strncat (buf, ", avr:6", size);
2951 break;
2952 case E_AVR_MACH_AVRTINY:
2953 strncat (buf, ", avr:100", size);
2954 break;
2955 case E_AVR_MACH_XMEGA1:
2956 strncat (buf, ", avr:101", size);
2957 break;
2958 case E_AVR_MACH_XMEGA2:
2959 strncat (buf, ", avr:102", size);
2960 break;
2961 case E_AVR_MACH_XMEGA3:
2962 strncat (buf, ", avr:103", size);
2963 break;
2964 case E_AVR_MACH_XMEGA4:
2965 strncat (buf, ", avr:104", size);
2966 break;
2967 case E_AVR_MACH_XMEGA5:
2968 strncat (buf, ", avr:105", size);
2969 break;
2970 case E_AVR_MACH_XMEGA6:
2971 strncat (buf, ", avr:106", size);
2972 break;
2973 case E_AVR_MACH_XMEGA7:
2974 strncat (buf, ", avr:107", size);
2975 break;
2976 default:
2977 strncat (buf, ", avr:<unknown>", size);
2978 break;
2979 }
2980
2981 size -= strlen (buf);
2982 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2983 strncat (buf, ", link-relax", size);
2984}
2985
35c08157
KLC
2986static void
2987decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2988{
2989 unsigned abi;
2990 unsigned arch;
2991 unsigned config;
2992 unsigned version;
015dc7e1 2993 bool has_fpu = false;
32ec8896 2994 unsigned int r = 0;
35c08157
KLC
2995
2996 static const char *ABI_STRINGS[] =
2997 {
2998 "ABI v0", /* use r5 as return register; only used in N1213HC */
2999 "ABI v1", /* use r0 as return register */
3000 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3001 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3002 "AABI",
3003 "ABI2 FP+"
35c08157
KLC
3004 };
3005 static const char *VER_STRINGS[] =
3006 {
3007 "Andes ELF V1.3 or older",
3008 "Andes ELF V1.3.1",
3009 "Andes ELF V1.4"
3010 };
3011 static const char *ARCH_STRINGS[] =
3012 {
3013 "",
3014 "Andes Star v1.0",
3015 "Andes Star v2.0",
3016 "Andes Star v3.0",
3017 "Andes Star v3.0m"
3018 };
3019
3020 abi = EF_NDS_ABI & e_flags;
3021 arch = EF_NDS_ARCH & e_flags;
3022 config = EF_NDS_INST & e_flags;
3023 version = EF_NDS32_ELF_VERSION & e_flags;
3024
3025 memset (buf, 0, size);
3026
3027 switch (abi)
3028 {
3029 case E_NDS_ABI_V0:
3030 case E_NDS_ABI_V1:
3031 case E_NDS_ABI_V2:
3032 case E_NDS_ABI_V2FP:
3033 case E_NDS_ABI_AABI:
40c7a7cb 3034 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3035 /* In case there are holes in the array. */
3036 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3037 break;
3038
3039 default:
3040 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3041 break;
3042 }
3043
3044 switch (version)
3045 {
3046 case E_NDS32_ELF_VER_1_2:
3047 case E_NDS32_ELF_VER_1_3:
3048 case E_NDS32_ELF_VER_1_4:
3049 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3050 break;
3051
3052 default:
3053 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3054 break;
3055 }
3056
3057 if (E_NDS_ABI_V0 == abi)
3058 {
3059 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3060 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3061 if (arch == E_NDS_ARCH_STAR_V1_0)
3062 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3063 return;
3064 }
3065
3066 switch (arch)
3067 {
3068 case E_NDS_ARCH_STAR_V1_0:
3069 case E_NDS_ARCH_STAR_V2_0:
3070 case E_NDS_ARCH_STAR_V3_0:
3071 case E_NDS_ARCH_STAR_V3_M:
3072 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3073 break;
3074
3075 default:
3076 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3077 /* ARCH version determines how the e_flags are interpreted.
3078 If it is unknown, we cannot proceed. */
3079 return;
3080 }
3081
3082 /* Newer ABI; Now handle architecture specific flags. */
3083 if (arch == E_NDS_ARCH_STAR_V1_0)
3084 {
3085 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3086 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3087
3088 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3089 r += snprintf (buf + r, size -r, ", MAC");
3090
3091 if (config & E_NDS32_HAS_DIV_INST)
3092 r += snprintf (buf + r, size -r, ", DIV");
3093
3094 if (config & E_NDS32_HAS_16BIT_INST)
3095 r += snprintf (buf + r, size -r, ", 16b");
3096 }
3097 else
3098 {
3099 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3100 {
3101 if (version <= E_NDS32_ELF_VER_1_3)
3102 r += snprintf (buf + r, size -r, ", [B8]");
3103 else
3104 r += snprintf (buf + r, size -r, ", EX9");
3105 }
3106
3107 if (config & E_NDS32_HAS_MAC_DX_INST)
3108 r += snprintf (buf + r, size -r, ", MAC_DX");
3109
3110 if (config & E_NDS32_HAS_DIV_DX_INST)
3111 r += snprintf (buf + r, size -r, ", DIV_DX");
3112
3113 if (config & E_NDS32_HAS_16BIT_INST)
3114 {
3115 if (version <= E_NDS32_ELF_VER_1_3)
3116 r += snprintf (buf + r, size -r, ", 16b");
3117 else
3118 r += snprintf (buf + r, size -r, ", IFC");
3119 }
3120 }
3121
3122 if (config & E_NDS32_HAS_EXT_INST)
3123 r += snprintf (buf + r, size -r, ", PERF1");
3124
3125 if (config & E_NDS32_HAS_EXT2_INST)
3126 r += snprintf (buf + r, size -r, ", PERF2");
3127
3128 if (config & E_NDS32_HAS_FPU_INST)
3129 {
015dc7e1 3130 has_fpu = true;
35c08157
KLC
3131 r += snprintf (buf + r, size -r, ", FPU_SP");
3132 }
3133
3134 if (config & E_NDS32_HAS_FPU_DP_INST)
3135 {
015dc7e1 3136 has_fpu = true;
35c08157
KLC
3137 r += snprintf (buf + r, size -r, ", FPU_DP");
3138 }
3139
3140 if (config & E_NDS32_HAS_FPU_MAC_INST)
3141 {
015dc7e1 3142 has_fpu = true;
35c08157
KLC
3143 r += snprintf (buf + r, size -r, ", FPU_MAC");
3144 }
3145
3146 if (has_fpu)
3147 {
3148 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3149 {
3150 case E_NDS32_FPU_REG_8SP_4DP:
3151 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3152 break;
3153 case E_NDS32_FPU_REG_16SP_8DP:
3154 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3155 break;
3156 case E_NDS32_FPU_REG_32SP_16DP:
3157 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3158 break;
3159 case E_NDS32_FPU_REG_32SP_32DP:
3160 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3161 break;
3162 }
3163 }
3164
3165 if (config & E_NDS32_HAS_AUDIO_INST)
3166 r += snprintf (buf + r, size -r, ", AUDIO");
3167
3168 if (config & E_NDS32_HAS_STRING_INST)
3169 r += snprintf (buf + r, size -r, ", STR");
3170
3171 if (config & E_NDS32_HAS_REDUCED_REGS)
3172 r += snprintf (buf + r, size -r, ", 16REG");
3173
3174 if (config & E_NDS32_HAS_VIDEO_INST)
3175 {
3176 if (version <= E_NDS32_ELF_VER_1_3)
3177 r += snprintf (buf + r, size -r, ", VIDEO");
3178 else
3179 r += snprintf (buf + r, size -r, ", SATURATION");
3180 }
3181
3182 if (config & E_NDS32_HAS_ENCRIPT_INST)
3183 r += snprintf (buf + r, size -r, ", ENCRP");
3184
3185 if (config & E_NDS32_HAS_L2C_INST)
3186 r += snprintf (buf + r, size -r, ", L2C");
3187}
3188
252b5132 3189static char *
dda8d76d 3190get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3191{
b34976b6 3192 static char buf[1024];
252b5132
RH
3193
3194 buf[0] = '\0';
76da6bbe 3195
252b5132
RH
3196 if (e_flags)
3197 {
3198 switch (e_machine)
3199 {
3200 default:
3201 break;
3202
886a2506 3203 case EM_ARC_COMPACT2:
886a2506 3204 case EM_ARC_COMPACT:
a9522a21
AB
3205 decode_ARC_machine_flags (e_flags, e_machine, buf);
3206 break;
886a2506 3207
f3485b74
NC
3208 case EM_ARM:
3209 decode_ARM_machine_flags (e_flags, buf);
3210 break;
76da6bbe 3211
343433df
AB
3212 case EM_AVR:
3213 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3214 break;
3215
781303ce
MF
3216 case EM_BLACKFIN:
3217 if (e_flags & EF_BFIN_PIC)
3218 strcat (buf, ", PIC");
3219
3220 if (e_flags & EF_BFIN_FDPIC)
3221 strcat (buf, ", FDPIC");
3222
3223 if (e_flags & EF_BFIN_CODE_IN_L1)
3224 strcat (buf, ", code in L1");
3225
3226 if (e_flags & EF_BFIN_DATA_IN_L1)
3227 strcat (buf, ", data in L1");
3228
3229 break;
3230
ec2dfb42
AO
3231 case EM_CYGNUS_FRV:
3232 switch (e_flags & EF_FRV_CPU_MASK)
3233 {
3234 case EF_FRV_CPU_GENERIC:
3235 break;
3236
3237 default:
3238 strcat (buf, ", fr???");
3239 break;
57346661 3240
ec2dfb42
AO
3241 case EF_FRV_CPU_FR300:
3242 strcat (buf, ", fr300");
3243 break;
3244
3245 case EF_FRV_CPU_FR400:
3246 strcat (buf, ", fr400");
3247 break;
3248 case EF_FRV_CPU_FR405:
3249 strcat (buf, ", fr405");
3250 break;
3251
3252 case EF_FRV_CPU_FR450:
3253 strcat (buf, ", fr450");
3254 break;
3255
3256 case EF_FRV_CPU_FR500:
3257 strcat (buf, ", fr500");
3258 break;
3259 case EF_FRV_CPU_FR550:
3260 strcat (buf, ", fr550");
3261 break;
3262
3263 case EF_FRV_CPU_SIMPLE:
3264 strcat (buf, ", simple");
3265 break;
3266 case EF_FRV_CPU_TOMCAT:
3267 strcat (buf, ", tomcat");
3268 break;
3269 }
1c877e87 3270 break;
ec2dfb42 3271
53c7db4b 3272 case EM_68K:
425c6cb0 3273 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3274 strcat (buf, ", m68000");
425c6cb0 3275 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3276 strcat (buf, ", cpu32");
3277 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3278 strcat (buf, ", fido_a");
425c6cb0 3279 else
266abb8f 3280 {
2cf0635d
NC
3281 char const * isa = _("unknown");
3282 char const * mac = _("unknown mac");
3283 char const * additional = NULL;
0112cd26 3284
c694fd50 3285 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3286 {
c694fd50 3287 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3288 isa = "A";
3289 additional = ", nodiv";
3290 break;
c694fd50 3291 case EF_M68K_CF_ISA_A:
266abb8f
NS
3292 isa = "A";
3293 break;
c694fd50 3294 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3295 isa = "A+";
3296 break;
c694fd50 3297 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3298 isa = "B";
3299 additional = ", nousp";
3300 break;
c694fd50 3301 case EF_M68K_CF_ISA_B:
266abb8f
NS
3302 isa = "B";
3303 break;
f608cd77
NS
3304 case EF_M68K_CF_ISA_C:
3305 isa = "C";
3306 break;
3307 case EF_M68K_CF_ISA_C_NODIV:
3308 isa = "C";
3309 additional = ", nodiv";
3310 break;
266abb8f
NS
3311 }
3312 strcat (buf, ", cf, isa ");
3313 strcat (buf, isa);
0b2e31dc
NS
3314 if (additional)
3315 strcat (buf, additional);
c694fd50 3316 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3317 strcat (buf, ", float");
c694fd50 3318 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3319 {
3320 case 0:
3321 mac = NULL;
3322 break;
c694fd50 3323 case EF_M68K_CF_MAC:
266abb8f
NS
3324 mac = "mac";
3325 break;
c694fd50 3326 case EF_M68K_CF_EMAC:
266abb8f
NS
3327 mac = "emac";
3328 break;
f608cd77
NS
3329 case EF_M68K_CF_EMAC_B:
3330 mac = "emac_b";
3331 break;
266abb8f
NS
3332 }
3333 if (mac)
3334 {
3335 strcat (buf, ", ");
3336 strcat (buf, mac);
3337 }
266abb8f 3338 }
53c7db4b 3339 break;
33c63f9d 3340
153a2776
NC
3341 case EM_CYGNUS_MEP:
3342 switch (e_flags & EF_MEP_CPU_MASK)
3343 {
3344 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3345 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3346 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3347 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3348 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3349 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3350 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3351 }
3352
3353 switch (e_flags & EF_MEP_COP_MASK)
3354 {
3355 case EF_MEP_COP_NONE: break;
3356 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3357 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3358 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3359 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3360 default: strcat (buf, _("<unknown MeP copro type>")); break;
3361 }
3362
3363 if (e_flags & EF_MEP_LIBRARY)
3364 strcat (buf, ", Built for Library");
3365
3366 if (e_flags & EF_MEP_INDEX_MASK)
3367 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3368 e_flags & EF_MEP_INDEX_MASK);
3369
3370 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3371 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3372 e_flags & ~ EF_MEP_ALL_FLAGS);
3373 break;
3374
252b5132
RH
3375 case EM_PPC:
3376 if (e_flags & EF_PPC_EMB)
3377 strcat (buf, ", emb");
3378
3379 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3380 strcat (buf, _(", relocatable"));
252b5132
RH
3381
3382 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3383 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3384 break;
3385
ee67d69a
AM
3386 case EM_PPC64:
3387 if (e_flags & EF_PPC64_ABI)
3388 {
3389 char abi[] = ", abiv0";
3390
3391 abi[6] += e_flags & EF_PPC64_ABI;
3392 strcat (buf, abi);
3393 }
3394 break;
3395
708e2187
NC
3396 case EM_V800:
3397 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3398 strcat (buf, ", RH850 ABI");
0b4362b0 3399
708e2187
NC
3400 if (e_flags & EF_V800_850E3)
3401 strcat (buf, ", V3 architecture");
3402
3403 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3404 strcat (buf, ", FPU not used");
3405
3406 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3407 strcat (buf, ", regmode: COMMON");
3408
3409 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3410 strcat (buf, ", r4 not used");
3411
3412 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3413 strcat (buf, ", r30 not used");
3414
3415 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3416 strcat (buf, ", r5 not used");
3417
3418 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3419 strcat (buf, ", r2 not used");
3420
3421 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3422 {
3423 switch (e_flags & - e_flags)
3424 {
3425 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3426 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3427 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3428 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3429 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3430 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3431 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3432 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3433 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3434 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3435 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3436 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3437 default: break;
3438 }
3439 }
3440 break;
3441
2b0337b0 3442 case EM_V850:
252b5132
RH
3443 case EM_CYGNUS_V850:
3444 switch (e_flags & EF_V850_ARCH)
3445 {
78c8d46c
NC
3446 case E_V850E3V5_ARCH:
3447 strcat (buf, ", v850e3v5");
3448 break;
1cd986c5
NC
3449 case E_V850E2V3_ARCH:
3450 strcat (buf, ", v850e2v3");
3451 break;
3452 case E_V850E2_ARCH:
3453 strcat (buf, ", v850e2");
3454 break;
3455 case E_V850E1_ARCH:
3456 strcat (buf, ", v850e1");
8ad30312 3457 break;
252b5132
RH
3458 case E_V850E_ARCH:
3459 strcat (buf, ", v850e");
3460 break;
252b5132
RH
3461 case E_V850_ARCH:
3462 strcat (buf, ", v850");
3463 break;
3464 default:
2b692964 3465 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3466 break;
3467 }
3468 break;
3469
2b0337b0 3470 case EM_M32R:
252b5132
RH
3471 case EM_CYGNUS_M32R:
3472 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3473 strcat (buf, ", m32r");
252b5132
RH
3474 break;
3475
3476 case EM_MIPS:
4fe85591 3477 case EM_MIPS_RS3_LE:
252b5132
RH
3478 if (e_flags & EF_MIPS_NOREORDER)
3479 strcat (buf, ", noreorder");
3480
3481 if (e_flags & EF_MIPS_PIC)
3482 strcat (buf, ", pic");
3483
3484 if (e_flags & EF_MIPS_CPIC)
3485 strcat (buf, ", cpic");
3486
d1bdd336
TS
3487 if (e_flags & EF_MIPS_UCODE)
3488 strcat (buf, ", ugen_reserved");
3489
252b5132
RH
3490 if (e_flags & EF_MIPS_ABI2)
3491 strcat (buf, ", abi2");
3492
43521d43
TS
3493 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3494 strcat (buf, ", odk first");
3495
a5d22d2a
TS
3496 if (e_flags & EF_MIPS_32BITMODE)
3497 strcat (buf, ", 32bitmode");
3498
ba92f887
MR
3499 if (e_flags & EF_MIPS_NAN2008)
3500 strcat (buf, ", nan2008");
3501
fef1b0b3
SE
3502 if (e_flags & EF_MIPS_FP64)
3503 strcat (buf, ", fp64");
3504
156c2f8b
NC
3505 switch ((e_flags & EF_MIPS_MACH))
3506 {
3507 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3508 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3509 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3510 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3511 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3512 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3513 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3514 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3515 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3516 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3517 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3518 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3519 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3520 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3521 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3522 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3523 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3524 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3525 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3526 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3527 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3528 case 0:
3529 /* We simply ignore the field in this case to avoid confusion:
3530 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3531 extension. */
3532 break;
2b692964 3533 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3534 }
43521d43
TS
3535
3536 switch ((e_flags & EF_MIPS_ABI))
3537 {
3538 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3539 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3540 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3541 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3542 case 0:
3543 /* We simply ignore the field in this case to avoid confusion:
3544 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3545 This means it is likely to be an o32 file, but not for
3546 sure. */
3547 break;
2b692964 3548 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3549 }
3550
3551 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3552 strcat (buf, ", mdmx");
3553
3554 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3555 strcat (buf, ", mips16");
3556
df58fc94
RS
3557 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3558 strcat (buf, ", micromips");
3559
43521d43
TS
3560 switch ((e_flags & EF_MIPS_ARCH))
3561 {
3562 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3563 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3564 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3565 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3566 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3567 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3568 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3569 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3570 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3571 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3572 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3573 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3574 }
252b5132 3575 break;
351b4b40 3576
35c08157
KLC
3577 case EM_NDS32:
3578 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3579 break;
3580
fe944acf
FT
3581 case EM_NFP:
3582 switch (EF_NFP_MACH (e_flags))
3583 {
3584 case E_NFP_MACH_3200:
3585 strcat (buf, ", NFP-32xx");
3586 break;
3587 case E_NFP_MACH_6000:
3588 strcat (buf, ", NFP-6xxx");
3589 break;
3590 }
3591 break;
3592
e23eba97
NC
3593 case EM_RISCV:
3594 if (e_flags & EF_RISCV_RVC)
3595 strcat (buf, ", RVC");
2922d21d 3596
7f999549
JW
3597 if (e_flags & EF_RISCV_RVE)
3598 strcat (buf, ", RVE");
3599
2922d21d
AW
3600 switch (e_flags & EF_RISCV_FLOAT_ABI)
3601 {
3602 case EF_RISCV_FLOAT_ABI_SOFT:
3603 strcat (buf, ", soft-float ABI");
3604 break;
3605
3606 case EF_RISCV_FLOAT_ABI_SINGLE:
3607 strcat (buf, ", single-float ABI");
3608 break;
3609
3610 case EF_RISCV_FLOAT_ABI_DOUBLE:
3611 strcat (buf, ", double-float ABI");
3612 break;
3613
3614 case EF_RISCV_FLOAT_ABI_QUAD:
3615 strcat (buf, ", quad-float ABI");
3616 break;
3617 }
e23eba97
NC
3618 break;
3619
ccde1100
AO
3620 case EM_SH:
3621 switch ((e_flags & EF_SH_MACH_MASK))
3622 {
3623 case EF_SH1: strcat (buf, ", sh1"); break;
3624 case EF_SH2: strcat (buf, ", sh2"); break;
3625 case EF_SH3: strcat (buf, ", sh3"); break;
3626 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3627 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3628 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3629 case EF_SH3E: strcat (buf, ", sh3e"); break;
3630 case EF_SH4: strcat (buf, ", sh4"); break;
3631 case EF_SH5: strcat (buf, ", sh5"); break;
3632 case EF_SH2E: strcat (buf, ", sh2e"); break;
3633 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3634 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3635 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3636 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3637 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3638 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3639 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3640 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3641 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3642 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3643 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3644 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3645 }
3646
cec6a5b8
MR
3647 if (e_flags & EF_SH_PIC)
3648 strcat (buf, ", pic");
3649
3650 if (e_flags & EF_SH_FDPIC)
3651 strcat (buf, ", fdpic");
ccde1100 3652 break;
948f632f 3653
73589c9d
CS
3654 case EM_OR1K:
3655 if (e_flags & EF_OR1K_NODELAY)
3656 strcat (buf, ", no delay");
3657 break;
57346661 3658
351b4b40
RH
3659 case EM_SPARCV9:
3660 if (e_flags & EF_SPARC_32PLUS)
3661 strcat (buf, ", v8+");
3662
3663 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3664 strcat (buf, ", ultrasparcI");
3665
3666 if (e_flags & EF_SPARC_SUN_US3)
3667 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3668
3669 if (e_flags & EF_SPARC_HAL_R1)
3670 strcat (buf, ", halr1");
3671
3672 if (e_flags & EF_SPARC_LEDATA)
3673 strcat (buf, ", ledata");
3674
3675 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3676 strcat (buf, ", tso");
3677
3678 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3679 strcat (buf, ", pso");
3680
3681 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3682 strcat (buf, ", rmo");
3683 break;
7d466069 3684
103f02d3
UD
3685 case EM_PARISC:
3686 switch (e_flags & EF_PARISC_ARCH)
3687 {
3688 case EFA_PARISC_1_0:
3689 strcpy (buf, ", PA-RISC 1.0");
3690 break;
3691 case EFA_PARISC_1_1:
3692 strcpy (buf, ", PA-RISC 1.1");
3693 break;
3694 case EFA_PARISC_2_0:
3695 strcpy (buf, ", PA-RISC 2.0");
3696 break;
3697 default:
3698 break;
3699 }
3700 if (e_flags & EF_PARISC_TRAPNIL)
3701 strcat (buf, ", trapnil");
3702 if (e_flags & EF_PARISC_EXT)
3703 strcat (buf, ", ext");
3704 if (e_flags & EF_PARISC_LSB)
3705 strcat (buf, ", lsb");
3706 if (e_flags & EF_PARISC_WIDE)
3707 strcat (buf, ", wide");
3708 if (e_flags & EF_PARISC_NO_KABP)
3709 strcat (buf, ", no kabp");
3710 if (e_flags & EF_PARISC_LAZYSWAP)
3711 strcat (buf, ", lazyswap");
30800947 3712 break;
76da6bbe 3713
7d466069 3714 case EM_PJ:
2b0337b0 3715 case EM_PJ_OLD:
7d466069
ILT
3716 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3717 strcat (buf, ", new calling convention");
3718
3719 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3720 strcat (buf, ", gnu calling convention");
3721 break;
4d6ed7c8
NC
3722
3723 case EM_IA_64:
3724 if ((e_flags & EF_IA_64_ABI64))
3725 strcat (buf, ", 64-bit");
3726 else
3727 strcat (buf, ", 32-bit");
3728 if ((e_flags & EF_IA_64_REDUCEDFP))
3729 strcat (buf, ", reduced fp model");
3730 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3731 strcat (buf, ", no function descriptors, constant gp");
3732 else if ((e_flags & EF_IA_64_CONS_GP))
3733 strcat (buf, ", constant gp");
3734 if ((e_flags & EF_IA_64_ABSOLUTE))
3735 strcat (buf, ", absolute");
dda8d76d 3736 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3737 {
3738 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3739 strcat (buf, ", vms_linkages");
3740 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3741 {
3742 case EF_IA_64_VMS_COMCOD_SUCCESS:
3743 break;
3744 case EF_IA_64_VMS_COMCOD_WARNING:
3745 strcat (buf, ", warning");
3746 break;
3747 case EF_IA_64_VMS_COMCOD_ERROR:
3748 strcat (buf, ", error");
3749 break;
3750 case EF_IA_64_VMS_COMCOD_ABORT:
3751 strcat (buf, ", abort");
3752 break;
3753 default:
bee0ee85
NC
3754 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3755 e_flags & EF_IA_64_VMS_COMCOD);
3756 strcat (buf, ", <unknown>");
28f997cf
TG
3757 }
3758 }
4d6ed7c8 3759 break;
179d3252
JT
3760
3761 case EM_VAX:
3762 if ((e_flags & EF_VAX_NONPIC))
3763 strcat (buf, ", non-PIC");
3764 if ((e_flags & EF_VAX_DFLOAT))
3765 strcat (buf, ", D-Float");
3766 if ((e_flags & EF_VAX_GFLOAT))
3767 strcat (buf, ", G-Float");
3768 break;
c7927a3c 3769
619ed720
EB
3770 case EM_VISIUM:
3771 if (e_flags & EF_VISIUM_ARCH_MCM)
3772 strcat (buf, ", mcm");
3773 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3774 strcat (buf, ", mcm24");
3775 if (e_flags & EF_VISIUM_ARCH_GR6)
3776 strcat (buf, ", gr6");
3777 break;
3778
4046d87a 3779 case EM_RL78:
1740ba0c
NC
3780 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3781 {
3782 case E_FLAG_RL78_ANY_CPU: break;
3783 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3784 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3785 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3786 }
856ea05c
KP
3787 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3788 strcat (buf, ", 64-bit doubles");
4046d87a 3789 break;
0b4362b0 3790
c7927a3c
NC
3791 case EM_RX:
3792 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3793 strcat (buf, ", 64-bit doubles");
3794 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3795 strcat (buf, ", dsp");
d4cb0ea0 3796 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3797 strcat (buf, ", pid");
708e2187
NC
3798 if (e_flags & E_FLAG_RX_ABI)
3799 strcat (buf, ", RX ABI");
3525236c
NC
3800 if (e_flags & E_FLAG_RX_SINSNS_SET)
3801 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3802 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3803 if (e_flags & E_FLAG_RX_V2)
3804 strcat (buf, ", V2");
f87673e0
YS
3805 if (e_flags & E_FLAG_RX_V3)
3806 strcat (buf, ", V3");
d4cb0ea0 3807 break;
55786da2
AK
3808
3809 case EM_S390:
3810 if (e_flags & EF_S390_HIGH_GPRS)
3811 strcat (buf, ", highgprs");
d4cb0ea0 3812 break;
40b36596
JM
3813
3814 case EM_TI_C6000:
3815 if ((e_flags & EF_C6000_REL))
3816 strcat (buf, ", relocatable module");
d4cb0ea0 3817 break;
13761a11
NC
3818
3819 case EM_MSP430:
3820 strcat (buf, _(": architecture variant: "));
3821 switch (e_flags & EF_MSP430_MACH)
3822 {
3823 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3824 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3825 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3826 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3827 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3828 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3829 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3830 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3831 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3832 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3833 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3834 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3835 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3836 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3837 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3838 default:
3839 strcat (buf, _(": unknown")); break;
3840 }
3841
3842 if (e_flags & ~ EF_MSP430_MACH)
3843 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
3844 break;
3845
3846 case EM_Z80:
3847 switch (e_flags & EF_Z80_MACH_MSK)
3848 {
3849 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
3850 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
3851 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
3852 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
3853 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
3854 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 3855 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
3856 default:
3857 strcat (buf, _(", unknown")); break;
3858 }
3859 break;
252b5132
RH
3860 }
3861 }
3862
3863 return buf;
3864}
3865
252b5132 3866static const char *
dda8d76d 3867get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3868{
3869 static char buff[32];
3870
3871 switch (osabi)
3872 {
3873 case ELFOSABI_NONE: return "UNIX - System V";
3874 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3875 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3876 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3877 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3878 case ELFOSABI_AIX: return "UNIX - AIX";
3879 case ELFOSABI_IRIX: return "UNIX - IRIX";
3880 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3881 case ELFOSABI_TRU64: return "UNIX - TRU64";
3882 case ELFOSABI_MODESTO: return "Novell - Modesto";
3883 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3884 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3885 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3886 case ELFOSABI_AROS: return "AROS";
11636f9e 3887 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3888 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3889 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3890 default:
40b36596 3891 if (osabi >= 64)
dda8d76d 3892 switch (filedata->file_header.e_machine)
40b36596
JM
3893 {
3894 case EM_ARM:
3895 switch (osabi)
3896 {
3897 case ELFOSABI_ARM: return "ARM";
18a20338 3898 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3899 default:
3900 break;
3901 }
3902 break;
3903
3904 case EM_MSP430:
3905 case EM_MSP430_OLD:
619ed720 3906 case EM_VISIUM:
40b36596
JM
3907 switch (osabi)
3908 {
3909 case ELFOSABI_STANDALONE: return _("Standalone App");
3910 default:
3911 break;
3912 }
3913 break;
3914
3915 case EM_TI_C6000:
3916 switch (osabi)
3917 {
3918 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3919 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3920 default:
3921 break;
3922 }
3923 break;
3924
3925 default:
3926 break;
3927 }
e9e44622 3928 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3929 return buff;
3930 }
3931}
3932
a06ea964
NC
3933static const char *
3934get_aarch64_segment_type (unsigned long type)
3935{
3936 switch (type)
3937 {
32ec8896
NC
3938 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3939 default: return NULL;
a06ea964 3940 }
a06ea964
NC
3941}
3942
b294bdf8
MM
3943static const char *
3944get_arm_segment_type (unsigned long type)
3945{
3946 switch (type)
3947 {
32ec8896
NC
3948 case PT_ARM_EXIDX: return "EXIDX";
3949 default: return NULL;
b294bdf8 3950 }
b294bdf8
MM
3951}
3952
b4cbbe8f
AK
3953static const char *
3954get_s390_segment_type (unsigned long type)
3955{
3956 switch (type)
3957 {
3958 case PT_S390_PGSTE: return "S390_PGSTE";
3959 default: return NULL;
3960 }
3961}
3962
d3ba0551
AM
3963static const char *
3964get_mips_segment_type (unsigned long type)
252b5132
RH
3965{
3966 switch (type)
3967 {
32ec8896
NC
3968 case PT_MIPS_REGINFO: return "REGINFO";
3969 case PT_MIPS_RTPROC: return "RTPROC";
3970 case PT_MIPS_OPTIONS: return "OPTIONS";
3971 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3972 default: return NULL;
252b5132 3973 }
252b5132
RH
3974}
3975
103f02d3 3976static const char *
d3ba0551 3977get_parisc_segment_type (unsigned long type)
103f02d3
UD
3978{
3979 switch (type)
3980 {
103f02d3
UD
3981 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3982 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3983 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3984 default: return NULL;
103f02d3 3985 }
103f02d3
UD
3986}
3987
4d6ed7c8 3988static const char *
d3ba0551 3989get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3990{
3991 switch (type)
3992 {
3993 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3994 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 3995 default: return NULL;
4d6ed7c8 3996 }
4d6ed7c8
NC
3997}
3998
40b36596
JM
3999static const char *
4000get_tic6x_segment_type (unsigned long type)
4001{
4002 switch (type)
4003 {
32ec8896
NC
4004 case PT_C6000_PHATTR: return "C6000_PHATTR";
4005 default: return NULL;
40b36596 4006 }
40b36596
JM
4007}
4008
df3a023b
AM
4009static const char *
4010get_hpux_segment_type (unsigned long type, unsigned e_machine)
4011{
4012 if (e_machine == EM_PARISC)
4013 switch (type)
4014 {
4015 case PT_HP_TLS: return "HP_TLS";
4016 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4017 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4018 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4019 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4020 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4021 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4022 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4023 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4024 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4025 case PT_HP_PARALLEL: return "HP_PARALLEL";
4026 case PT_HP_FASTBIND: return "HP_FASTBIND";
4027 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4028 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4029 case PT_HP_STACK: return "HP_STACK";
4030 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4031 default: return NULL;
4032 }
4033
4034 if (e_machine == EM_IA_64)
4035 switch (type)
4036 {
4037 case PT_HP_TLS: return "HP_TLS";
4038 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4039 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4040 case PT_IA_64_HP_STACK: return "HP_STACK";
4041 default: return NULL;
4042 }
4043
4044 return NULL;
4045}
4046
5522f910
NC
4047static const char *
4048get_solaris_segment_type (unsigned long type)
4049{
4050 switch (type)
4051 {
4052 case 0x6464e550: return "PT_SUNW_UNWIND";
4053 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4054 case 0x6ffffff7: return "PT_LOSUNW";
4055 case 0x6ffffffa: return "PT_SUNWBSS";
4056 case 0x6ffffffb: return "PT_SUNWSTACK";
4057 case 0x6ffffffc: return "PT_SUNWDTRACE";
4058 case 0x6ffffffd: return "PT_SUNWCAP";
4059 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4060 default: return NULL;
5522f910
NC
4061 }
4062}
4063
252b5132 4064static const char *
dda8d76d 4065get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4066{
b34976b6 4067 static char buff[32];
252b5132
RH
4068
4069 switch (p_type)
4070 {
b34976b6
AM
4071 case PT_NULL: return "NULL";
4072 case PT_LOAD: return "LOAD";
252b5132 4073 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4074 case PT_INTERP: return "INTERP";
4075 case PT_NOTE: return "NOTE";
4076 case PT_SHLIB: return "SHLIB";
4077 case PT_PHDR: return "PHDR";
13ae64f3 4078 case PT_TLS: return "TLS";
32ec8896 4079 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4080 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4081 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4082 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4083
3eba3ef3
NC
4084 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4085 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4086 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4087
252b5132 4088 default:
df3a023b 4089 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4090 {
2cf0635d 4091 const char * result;
103f02d3 4092
dda8d76d 4093 switch (filedata->file_header.e_machine)
252b5132 4094 {
a06ea964
NC
4095 case EM_AARCH64:
4096 result = get_aarch64_segment_type (p_type);
4097 break;
b294bdf8
MM
4098 case EM_ARM:
4099 result = get_arm_segment_type (p_type);
4100 break;
252b5132 4101 case EM_MIPS:
4fe85591 4102 case EM_MIPS_RS3_LE:
252b5132
RH
4103 result = get_mips_segment_type (p_type);
4104 break;
103f02d3
UD
4105 case EM_PARISC:
4106 result = get_parisc_segment_type (p_type);
4107 break;
4d6ed7c8
NC
4108 case EM_IA_64:
4109 result = get_ia64_segment_type (p_type);
4110 break;
40b36596
JM
4111 case EM_TI_C6000:
4112 result = get_tic6x_segment_type (p_type);
4113 break;
b4cbbe8f
AK
4114 case EM_S390:
4115 case EM_S390_OLD:
4116 result = get_s390_segment_type (p_type);
4117 break;
252b5132
RH
4118 default:
4119 result = NULL;
4120 break;
4121 }
103f02d3 4122
252b5132
RH
4123 if (result != NULL)
4124 return result;
103f02d3 4125
1a9ccd70 4126 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4127 }
4128 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4129 {
df3a023b 4130 const char * result = NULL;
103f02d3 4131
df3a023b 4132 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4133 {
df3a023b
AM
4134 case ELFOSABI_GNU:
4135 case ELFOSABI_FREEBSD:
4136 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4137 {
4138 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4139 result = buff;
4140 }
103f02d3 4141 break;
df3a023b
AM
4142 case ELFOSABI_HPUX:
4143 result = get_hpux_segment_type (p_type,
4144 filedata->file_header.e_machine);
4145 break;
4146 case ELFOSABI_SOLARIS:
4147 result = get_solaris_segment_type (p_type);
00428cca 4148 break;
103f02d3 4149 default:
103f02d3
UD
4150 break;
4151 }
103f02d3
UD
4152 if (result != NULL)
4153 return result;
4154
1a9ccd70 4155 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4156 }
252b5132 4157 else
e9e44622 4158 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4159
4160 return buff;
4161 }
4162}
4163
53a346d8
CZ
4164static const char *
4165get_arc_section_type_name (unsigned int sh_type)
4166{
4167 switch (sh_type)
4168 {
4169 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4170 default:
4171 break;
4172 }
4173 return NULL;
4174}
4175
252b5132 4176static const char *
d3ba0551 4177get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4178{
4179 switch (sh_type)
4180 {
b34976b6
AM
4181 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4182 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4183 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4184 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4185 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4186 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4187 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4188 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4189 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4190 case SHT_MIPS_RELD: return "MIPS_RELD";
4191 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4192 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4193 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4194 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4195 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4196 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4197 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4198 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4199 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4200 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4201 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4202 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4203 case SHT_MIPS_LINE: return "MIPS_LINE";
4204 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4205 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4206 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4207 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4208 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4209 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4210 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4211 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4212 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4213 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4214 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4215 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4216 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4217 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4218 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4219 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4220 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4221 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4222 default:
4223 break;
4224 }
4225 return NULL;
4226}
4227
103f02d3 4228static const char *
d3ba0551 4229get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4230{
4231 switch (sh_type)
4232 {
4233 case SHT_PARISC_EXT: return "PARISC_EXT";
4234 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4235 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4236 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4237 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4238 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4239 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4240 default: return NULL;
103f02d3 4241 }
103f02d3
UD
4242}
4243
4d6ed7c8 4244static const char *
dda8d76d 4245get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4246{
18bd398b 4247 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4248 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4249 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4250
4d6ed7c8
NC
4251 switch (sh_type)
4252 {
148b93f2
NC
4253 case SHT_IA_64_EXT: return "IA_64_EXT";
4254 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4255 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4256 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4257 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4258 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4259 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4260 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4261 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4262 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4263 default:
4264 break;
4265 }
4266 return NULL;
4267}
4268
d2b2c203
DJ
4269static const char *
4270get_x86_64_section_type_name (unsigned int sh_type)
4271{
4272 switch (sh_type)
4273 {
4274 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4275 default: return NULL;
d2b2c203 4276 }
d2b2c203
DJ
4277}
4278
a06ea964
NC
4279static const char *
4280get_aarch64_section_type_name (unsigned int sh_type)
4281{
4282 switch (sh_type)
4283 {
32ec8896
NC
4284 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4285 default: return NULL;
a06ea964 4286 }
a06ea964
NC
4287}
4288
40a18ebd
NC
4289static const char *
4290get_arm_section_type_name (unsigned int sh_type)
4291{
4292 switch (sh_type)
4293 {
7f6fed87
NC
4294 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4295 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4296 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4297 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4298 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4299 default: return NULL;
40a18ebd 4300 }
40a18ebd
NC
4301}
4302
40b36596
JM
4303static const char *
4304get_tic6x_section_type_name (unsigned int sh_type)
4305{
4306 switch (sh_type)
4307 {
32ec8896
NC
4308 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4309 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4310 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4311 case SHT_TI_ICODE: return "TI_ICODE";
4312 case SHT_TI_XREF: return "TI_XREF";
4313 case SHT_TI_HANDLER: return "TI_HANDLER";
4314 case SHT_TI_INITINFO: return "TI_INITINFO";
4315 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4316 default: return NULL;
40b36596 4317 }
40b36596
JM
4318}
4319
13761a11 4320static const char *
b0191216 4321get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4322{
4323 switch (sh_type)
4324 {
32ec8896
NC
4325 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4326 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4327 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4328 default: return NULL;
13761a11
NC
4329 }
4330}
4331
fe944acf
FT
4332static const char *
4333get_nfp_section_type_name (unsigned int sh_type)
4334{
4335 switch (sh_type)
4336 {
4337 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4338 case SHT_NFP_INITREG: return "NFP_INITREG";
4339 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4340 default: return NULL;
4341 }
4342}
4343
685080f2
NC
4344static const char *
4345get_v850_section_type_name (unsigned int sh_type)
4346{
4347 switch (sh_type)
4348 {
32ec8896
NC
4349 case SHT_V850_SCOMMON: return "V850 Small Common";
4350 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4351 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4352 case SHT_RENESAS_IOP: return "RENESAS IOP";
4353 case SHT_RENESAS_INFO: return "RENESAS INFO";
4354 default: return NULL;
685080f2
NC
4355 }
4356}
4357
2dc8dd17
JW
4358static const char *
4359get_riscv_section_type_name (unsigned int sh_type)
4360{
4361 switch (sh_type)
4362 {
4363 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4364 default: return NULL;
4365 }
4366}
4367
0861f561
CQ
4368static const char *
4369get_csky_section_type_name (unsigned int sh_type)
4370{
4371 switch (sh_type)
4372 {
4373 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4374 default: return NULL;
4375 }
4376}
4377
252b5132 4378static const char *
dda8d76d 4379get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4380{
b34976b6 4381 static char buff[32];
9fb71ee4 4382 const char * result;
252b5132
RH
4383
4384 switch (sh_type)
4385 {
4386 case SHT_NULL: return "NULL";
4387 case SHT_PROGBITS: return "PROGBITS";
4388 case SHT_SYMTAB: return "SYMTAB";
4389 case SHT_STRTAB: return "STRTAB";
4390 case SHT_RELA: return "RELA";
4391 case SHT_HASH: return "HASH";
4392 case SHT_DYNAMIC: return "DYNAMIC";
4393 case SHT_NOTE: return "NOTE";
4394 case SHT_NOBITS: return "NOBITS";
4395 case SHT_REL: return "REL";
4396 case SHT_SHLIB: return "SHLIB";
4397 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4398 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4399 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4400 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4401 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4402 case SHT_GROUP: return "GROUP";
67ce483b 4403 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4404 case SHT_GNU_verdef: return "VERDEF";
4405 case SHT_GNU_verneed: return "VERNEED";
4406 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4407 case 0x6ffffff0: return "VERSYM";
4408 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4409 case 0x7ffffffd: return "AUXILIARY";
4410 case 0x7fffffff: return "FILTER";
047b2264 4411 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4412
4413 default:
4414 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4415 {
dda8d76d 4416 switch (filedata->file_header.e_machine)
252b5132 4417 {
53a346d8
CZ
4418 case EM_ARC:
4419 case EM_ARC_COMPACT:
4420 case EM_ARC_COMPACT2:
4421 result = get_arc_section_type_name (sh_type);
4422 break;
252b5132 4423 case EM_MIPS:
4fe85591 4424 case EM_MIPS_RS3_LE:
252b5132
RH
4425 result = get_mips_section_type_name (sh_type);
4426 break;
103f02d3
UD
4427 case EM_PARISC:
4428 result = get_parisc_section_type_name (sh_type);
4429 break;
4d6ed7c8 4430 case EM_IA_64:
dda8d76d 4431 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4432 break;
d2b2c203 4433 case EM_X86_64:
8a9036a4 4434 case EM_L1OM:
7a9068fe 4435 case EM_K1OM:
d2b2c203
DJ
4436 result = get_x86_64_section_type_name (sh_type);
4437 break;
a06ea964
NC
4438 case EM_AARCH64:
4439 result = get_aarch64_section_type_name (sh_type);
4440 break;
40a18ebd
NC
4441 case EM_ARM:
4442 result = get_arm_section_type_name (sh_type);
4443 break;
40b36596
JM
4444 case EM_TI_C6000:
4445 result = get_tic6x_section_type_name (sh_type);
4446 break;
13761a11 4447 case EM_MSP430:
b0191216 4448 result = get_msp430_section_type_name (sh_type);
13761a11 4449 break;
fe944acf
FT
4450 case EM_NFP:
4451 result = get_nfp_section_type_name (sh_type);
4452 break;
685080f2
NC
4453 case EM_V800:
4454 case EM_V850:
4455 case EM_CYGNUS_V850:
4456 result = get_v850_section_type_name (sh_type);
4457 break;
2dc8dd17
JW
4458 case EM_RISCV:
4459 result = get_riscv_section_type_name (sh_type);
4460 break;
0861f561
CQ
4461 case EM_CSKY:
4462 result = get_csky_section_type_name (sh_type);
4463 break;
252b5132
RH
4464 default:
4465 result = NULL;
4466 break;
4467 }
4468
4469 if (result != NULL)
4470 return result;
4471
9fb71ee4 4472 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4473 }
4474 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4475 {
dda8d76d 4476 switch (filedata->file_header.e_machine)
148b93f2
NC
4477 {
4478 case EM_IA_64:
dda8d76d 4479 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4480 break;
4481 default:
dda8d76d 4482 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4483 result = get_solaris_section_type (sh_type);
4484 else
1b4b80bf
NC
4485 {
4486 switch (sh_type)
4487 {
4488 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4489 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4490 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4491 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4492 default:
4493 result = NULL;
4494 break;
4495 }
4496 }
148b93f2
NC
4497 break;
4498 }
4499
4500 if (result != NULL)
4501 return result;
4502
9fb71ee4 4503 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4504 }
252b5132 4505 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4506 {
dda8d76d 4507 switch (filedata->file_header.e_machine)
685080f2
NC
4508 {
4509 case EM_V800:
4510 case EM_V850:
4511 case EM_CYGNUS_V850:
9fb71ee4 4512 result = get_v850_section_type_name (sh_type);
a9fb83be 4513 break;
685080f2 4514 default:
9fb71ee4 4515 result = NULL;
685080f2
NC
4516 break;
4517 }
4518
9fb71ee4
NC
4519 if (result != NULL)
4520 return result;
4521
4522 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4523 }
252b5132 4524 else
a7dbfd1c
NC
4525 /* This message is probably going to be displayed in a 15
4526 character wide field, so put the hex value first. */
4527 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4528
252b5132
RH
4529 return buff;
4530 }
4531}
4532
79bc120c
NC
4533enum long_option_values
4534{
4535 OPTION_DEBUG_DUMP = 512,
4536 OPTION_DYN_SYMS,
0f03783c 4537 OPTION_LTO_SYMS,
79bc120c
NC
4538 OPTION_DWARF_DEPTH,
4539 OPTION_DWARF_START,
4540 OPTION_DWARF_CHECK,
4541 OPTION_CTF_DUMP,
4542 OPTION_CTF_PARENT,
4543 OPTION_CTF_SYMBOLS,
4544 OPTION_CTF_STRINGS,
4545 OPTION_WITH_SYMBOL_VERSIONS,
4546 OPTION_RECURSE_LIMIT,
4547 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
4548 OPTION_NO_DEMANGLING,
4549 OPTION_SYM_BASE
79bc120c 4550};
2979dc34 4551
85b1c36d 4552static struct option options[] =
252b5132 4553{
79bc120c
NC
4554 /* Note - This table is alpha-sorted on the 'val'
4555 field in order to make adding new options easier. */
4556 {"arch-specific", no_argument, 0, 'A'},
b34976b6 4557 {"all", no_argument, 0, 'a'},
79bc120c
NC
4558 {"demangle", optional_argument, 0, 'C'},
4559 {"archive-index", no_argument, 0, 'c'},
4560 {"use-dynamic", no_argument, 0, 'D'},
4561 {"dynamic", no_argument, 0, 'd'},
b34976b6 4562 {"headers", no_argument, 0, 'e'},
79bc120c
NC
4563 {"section-groups", no_argument, 0, 'g'},
4564 {"help", no_argument, 0, 'H'},
4565 {"file-header", no_argument, 0, 'h'},
b34976b6 4566 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
4567 {"lint", no_argument, 0, 'L'},
4568 {"enable-checks", no_argument, 0, 'L'},
4569 {"program-headers", no_argument, 0, 'l'},
b34976b6 4570 {"segments", no_argument, 0, 'l'},
595cf52e 4571 {"full-section-name",no_argument, 0, 'N'},
79bc120c 4572 {"notes", no_argument, 0, 'n'},
ca0e11aa 4573 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
4574 {"string-dump", required_argument, 0, 'p'},
4575 {"relocated-dump", required_argument, 0, 'R'},
4576 {"relocs", no_argument, 0, 'r'},
4577 {"section-headers", no_argument, 0, 'S'},
4578 {"sections", no_argument, 0, 'S'},
b34976b6
AM
4579 {"symbols", no_argument, 0, 's'},
4580 {"syms", no_argument, 0, 's'},
79bc120c
NC
4581 {"silent-truncation",no_argument, 0, 'T'},
4582 {"section-details", no_argument, 0, 't'},
09c11c86 4583 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
4584 {"version-info", no_argument, 0, 'V'},
4585 {"version", no_argument, 0, 'v'},
4586 {"wide", no_argument, 0, 'W'},
b34976b6 4587 {"hex-dump", required_argument, 0, 'x'},
0e602686 4588 {"decompress", no_argument, 0, 'z'},
252b5132 4589
79bc120c
NC
4590 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
4591 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
4592 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4593 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4594 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 4595 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 4596 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
4597 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4598 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4599 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 4600#ifdef ENABLE_LIBCTF
d344b407 4601 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
4602 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
4603 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
4604 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 4605#endif
047c3dbf 4606 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 4607
b34976b6 4608 {0, no_argument, 0, 0}
252b5132
RH
4609};
4610
4611static void
2cf0635d 4612usage (FILE * stream)
252b5132 4613{
92f01d61
JM
4614 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4615 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4616 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4617 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4618 -h --file-header Display the ELF file header\n\
4619 -l --program-headers Display the program headers\n\
4620 --segments An alias for --program-headers\n\
4621 -S --section-headers Display the sections' header\n\
4622 --sections An alias for --section-headers\n\
f5842774 4623 -g --section-groups Display the section groups\n\
5477e8a0 4624 -t --section-details Display the section details\n\
8b53311e
NC
4625 -e --headers Equivalent to: -h -l -S\n\
4626 -s --syms Display the symbol table\n\
3f08eb35 4627 --symbols An alias for --syms\n\
1b513401 4628 --dyn-syms Display the dynamic symbol table\n\
0f03783c 4629 --lto-syms Display LTO symbol tables\n\
047c3dbf
NL
4630 --sym-base=[0|8|10|16] \n\
4631 Force base for symbol sizes. The options are \n\
4632 mixed (the default), octal, decimal, hexadecimal.\n\
79bc120c
NC
4633 -C --demangle[=STYLE] Decode low-level symbol names into user-level names\n\
4634 The STYLE, if specified, can be `auto' (the default),\n\
4635 `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
4636 or `gnat'\n\
4637 --no-demangle Do not demangle low-level symbol names. (This is the default)\n\
4638 --recurse-limit Enable a demangling recursion limit. (This is the default)\n\
4639 --no-recurse-limit Disable a demangling recursion limit\n\
8b53311e
NC
4640 -n --notes Display the core notes (if present)\n\
4641 -r --relocs Display the relocations (if present)\n\
4642 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4643 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4644 -V --version-info Display the version sections (if present)\n\
1b31d05e 4645 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4646 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4647 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
1b513401 4648 -L --lint|--enable-checks Display warning messages for possible problems\n\
09c11c86
NC
4649 -x --hex-dump=<number|name>\n\
4650 Dump the contents of section <number|name> as bytes\n\
4651 -p --string-dump=<number|name>\n\
4652 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4653 -R --relocated-dump=<number|name>\n\
4654 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4655 -z --decompress Decompress section before dumping it\n\
6643bb00
AM
4656 -w[lLiaprmfFsOoRtgUuTAc] or\n\
4657 --debug-dump=[rawline,decodedline,info,abbrev,pubnames,aranges,macro,frames,\n\
4658 frames-interp,str,str-offsets,loc,Ranges,pubtypes,gdb_index,\n\
4659 trace_info,trace_abbrev,trace_aranges,addr,cu_index]\n\
ca0e11aa
NC
4660 Display the contents of DWARF debug sections\n\
4661 -wk,--debug-dump=links Display the contents of sections that link to separate debuginfo files\n\
4662 -P,--process-links Display the contents of non-debug sections in separate debuginfo files. (Implies -wK)\n"));
c46b7066
NC
4663#if DEFAULT_FOR_FOLLOW_LINKS
4664 fprintf (stream, _("\
4665 -wK,--debug-dump=follow-links Follow links to separate debug info files (default)\n\
4666 -wN,--debug-dump=no-follow-links Do not follow links to separate debug info files\n\
4667"));
4668#else
4669 fprintf (stream, _("\
4670 -wK,--debug-dump=follow-links Follow links to separate debug info files\n\
4671 -wN,--debug-dump=no-follow-links Do not follow links to separate debug info files (default)\n\
4672"));
4673#endif
fd2f0033
TT
4674 fprintf (stream, _("\
4675 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4676 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4677 or deeper\n"));
094e34f2 4678#ifdef ENABLE_LIBCTF
7d9813f1
NA
4679 fprintf (stream, _("\
4680 --ctf=<number|name> Display CTF info from section <number|name>\n\
4681 --ctf-parent=<number|name>\n\
4682 Use section <number|name> as the CTF parent\n\n\
4683 --ctf-symbols=<number|name>\n\
4684 Use section <number|name> as the CTF external symtab\n\n\
4685 --ctf-strings=<number|name>\n\
4686 Use section <number|name> as the CTF external strtab\n\n"));
094e34f2 4687#endif
7d9813f1 4688
252b5132 4689#ifdef SUPPORT_DISASSEMBLY
92f01d61 4690 fprintf (stream, _("\
09c11c86
NC
4691 -i --instruction-dump=<number|name>\n\
4692 Disassemble the contents of section <number|name>\n"));
252b5132 4693#endif
92f01d61 4694 fprintf (stream, _("\
8b53311e
NC
4695 -I --histogram Display histogram of bucket list lengths\n\
4696 -W --wide Allow output width to exceed 80 characters\n\
0942c7ab 4697 -T --silent-truncation If a symbol name is truncated, do not add a suffix [...]\n\
07012eee 4698 @<file> Read options from <file>\n\
8b53311e
NC
4699 -H --help Display this information\n\
4700 -v --version Display the version number of readelf\n"));
1118d252 4701
92f01d61
JM
4702 if (REPORT_BUGS_TO[0] && stream == stdout)
4703 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4704
92f01d61 4705 exit (stream == stdout ? 0 : 1);
252b5132
RH
4706}
4707
18bd398b
NC
4708/* Record the fact that the user wants the contents of section number
4709 SECTION to be displayed using the method(s) encoded as flags bits
4710 in TYPE. Note, TYPE can be zero if we are creating the array for
4711 the first time. */
4712
252b5132 4713static void
6431e409
AM
4714request_dump_bynumber (struct dump_data *dumpdata,
4715 unsigned int section, dump_type type)
252b5132 4716{
6431e409 4717 if (section >= dumpdata->num_dump_sects)
252b5132 4718 {
2cf0635d 4719 dump_type * new_dump_sects;
252b5132 4720
3f5e193b 4721 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4722 sizeof (* new_dump_sects));
252b5132
RH
4723
4724 if (new_dump_sects == NULL)
591a748a 4725 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4726 else
4727 {
6431e409 4728 if (dumpdata->dump_sects)
21b65bac
NC
4729 {
4730 /* Copy current flag settings. */
6431e409
AM
4731 memcpy (new_dump_sects, dumpdata->dump_sects,
4732 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4733
6431e409 4734 free (dumpdata->dump_sects);
21b65bac 4735 }
252b5132 4736
6431e409
AM
4737 dumpdata->dump_sects = new_dump_sects;
4738 dumpdata->num_dump_sects = section + 1;
252b5132
RH
4739 }
4740 }
4741
6431e409
AM
4742 if (dumpdata->dump_sects)
4743 dumpdata->dump_sects[section] |= type;
252b5132
RH
4744}
4745
aef1f6d0
DJ
4746/* Request a dump by section name. */
4747
4748static void
2cf0635d 4749request_dump_byname (const char * section, dump_type type)
aef1f6d0 4750{
2cf0635d 4751 struct dump_list_entry * new_request;
aef1f6d0 4752
3f5e193b
NC
4753 new_request = (struct dump_list_entry *)
4754 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4755 if (!new_request)
591a748a 4756 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4757
4758 new_request->name = strdup (section);
4759 if (!new_request->name)
591a748a 4760 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4761
4762 new_request->type = type;
4763
4764 new_request->next = dump_sects_byname;
4765 dump_sects_byname = new_request;
4766}
4767
cf13d699 4768static inline void
6431e409 4769request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
4770{
4771 int section;
4772 char * cp;
4773
015dc7e1 4774 do_dump = true;
cf13d699
NC
4775 section = strtoul (optarg, & cp, 0);
4776
4777 if (! *cp && section >= 0)
6431e409 4778 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
4779 else
4780 request_dump_byname (optarg, type);
4781}
4782
252b5132 4783static void
6431e409 4784parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
4785{
4786 int c;
4787
4788 if (argc < 2)
92f01d61 4789 usage (stderr);
252b5132
RH
4790
4791 while ((c = getopt_long
ca0e11aa 4792 (argc, argv, "ACDHILNPR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4793 {
252b5132
RH
4794 switch (c)
4795 {
4796 case 0:
4797 /* Long options. */
4798 break;
4799 case 'H':
92f01d61 4800 usage (stdout);
252b5132
RH
4801 break;
4802
4803 case 'a':
015dc7e1
AM
4804 do_syms = true;
4805 do_reloc = true;
4806 do_unwind = true;
4807 do_dynamic = true;
4808 do_header = true;
4809 do_sections = true;
4810 do_section_groups = true;
4811 do_segments = true;
4812 do_version = true;
4813 do_histogram = true;
4814 do_arch = true;
4815 do_notes = true;
252b5132 4816 break;
79bc120c 4817
f5842774 4818 case 'g':
015dc7e1 4819 do_section_groups = true;
f5842774 4820 break;
5477e8a0 4821 case 't':
595cf52e 4822 case 'N':
015dc7e1
AM
4823 do_sections = true;
4824 do_section_details = true;
595cf52e 4825 break;
252b5132 4826 case 'e':
015dc7e1
AM
4827 do_header = true;
4828 do_sections = true;
4829 do_segments = true;
252b5132 4830 break;
a952a375 4831 case 'A':
015dc7e1 4832 do_arch = true;
a952a375 4833 break;
252b5132 4834 case 'D':
015dc7e1 4835 do_using_dynamic = true;
252b5132
RH
4836 break;
4837 case 'r':
015dc7e1 4838 do_reloc = true;
252b5132 4839 break;
4d6ed7c8 4840 case 'u':
015dc7e1 4841 do_unwind = true;
4d6ed7c8 4842 break;
252b5132 4843 case 'h':
015dc7e1 4844 do_header = true;
252b5132
RH
4845 break;
4846 case 'l':
015dc7e1 4847 do_segments = true;
252b5132
RH
4848 break;
4849 case 's':
015dc7e1 4850 do_syms = true;
252b5132
RH
4851 break;
4852 case 'S':
015dc7e1 4853 do_sections = true;
252b5132
RH
4854 break;
4855 case 'd':
015dc7e1 4856 do_dynamic = true;
252b5132 4857 break;
a952a375 4858 case 'I':
015dc7e1 4859 do_histogram = true;
a952a375 4860 break;
779fe533 4861 case 'n':
015dc7e1 4862 do_notes = true;
779fe533 4863 break;
4145f1d5 4864 case 'c':
015dc7e1 4865 do_archive_index = true;
4145f1d5 4866 break;
1b513401 4867 case 'L':
015dc7e1 4868 do_checks = true;
1b513401 4869 break;
ca0e11aa 4870 case 'P':
015dc7e1
AM
4871 process_links = true;
4872 do_follow_links = true;
ca0e11aa 4873 break;
252b5132 4874 case 'x':
6431e409 4875 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 4876 break;
09c11c86 4877 case 'p':
6431e409 4878 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
4879 break;
4880 case 'R':
6431e409 4881 request_dump (dumpdata, RELOC_DUMP);
09c11c86 4882 break;
0e602686 4883 case 'z':
015dc7e1 4884 decompress_dumps = true;
0e602686 4885 break;
252b5132 4886 case 'w':
015dc7e1 4887 do_dump = true;
0f03783c 4888 if (optarg == NULL)
613ff48b 4889 {
015dc7e1 4890 do_debugging = true;
613ff48b
CC
4891 dwarf_select_sections_all ();
4892 }
252b5132
RH
4893 else
4894 {
015dc7e1 4895 do_debugging = false;
4cb93e3b 4896 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4897 }
4898 break;
2979dc34 4899 case OPTION_DEBUG_DUMP:
015dc7e1 4900 do_dump = true;
0f03783c 4901 if (optarg == NULL)
015dc7e1 4902 do_debugging = true;
2979dc34
JJ
4903 else
4904 {
015dc7e1 4905 do_debugging = false;
4cb93e3b 4906 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4907 }
4908 break;
fd2f0033
TT
4909 case OPTION_DWARF_DEPTH:
4910 {
4911 char *cp;
4912
4913 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4914 }
4915 break;
4916 case OPTION_DWARF_START:
4917 {
4918 char *cp;
4919
4920 dwarf_start_die = strtoul (optarg, & cp, 0);
4921 }
4922 break;
4723351a 4923 case OPTION_DWARF_CHECK:
015dc7e1 4924 dwarf_check = true;
4723351a 4925 break;
7d9813f1 4926 case OPTION_CTF_DUMP:
015dc7e1 4927 do_ctf = true;
6431e409 4928 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
4929 break;
4930 case OPTION_CTF_SYMBOLS:
df16e041 4931 free (dump_ctf_symtab_name);
7d9813f1
NA
4932 dump_ctf_symtab_name = strdup (optarg);
4933 break;
4934 case OPTION_CTF_STRINGS:
df16e041 4935 free (dump_ctf_strtab_name);
7d9813f1
NA
4936 dump_ctf_strtab_name = strdup (optarg);
4937 break;
4938 case OPTION_CTF_PARENT:
df16e041 4939 free (dump_ctf_parent_name);
7d9813f1
NA
4940 dump_ctf_parent_name = strdup (optarg);
4941 break;
2c610e4b 4942 case OPTION_DYN_SYMS:
015dc7e1 4943 do_dyn_syms = true;
2c610e4b 4944 break;
0f03783c 4945 case OPTION_LTO_SYMS:
015dc7e1 4946 do_lto_syms = true;
0f03783c 4947 break;
252b5132
RH
4948#ifdef SUPPORT_DISASSEMBLY
4949 case 'i':
6431e409 4950 request_dump (dumpdata, DISASS_DUMP);
cf13d699 4951 break;
252b5132
RH
4952#endif
4953 case 'v':
4954 print_version (program_name);
4955 break;
4956 case 'V':
015dc7e1 4957 do_version = true;
252b5132 4958 break;
d974e256 4959 case 'W':
015dc7e1 4960 do_wide = true;
d974e256 4961 break;
0942c7ab 4962 case 'T':
015dc7e1 4963 do_not_show_symbol_truncation = true;
0942c7ab 4964 break;
79bc120c 4965 case 'C':
015dc7e1 4966 do_demangle = true;
79bc120c
NC
4967 if (optarg != NULL)
4968 {
4969 enum demangling_styles style;
4970
4971 style = cplus_demangle_name_to_style (optarg);
4972 if (style == unknown_demangling)
4973 error (_("unknown demangling style `%s'"), optarg);
4974
4975 cplus_demangle_set_style (style);
4976 }
4977 break;
4978 case OPTION_NO_DEMANGLING:
015dc7e1 4979 do_demangle = false;
79bc120c
NC
4980 break;
4981 case OPTION_RECURSE_LIMIT:
4982 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
4983 break;
4984 case OPTION_NO_RECURSE_LIMIT:
4985 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
4986 break;
4987 case OPTION_WITH_SYMBOL_VERSIONS:
4988 /* Ignored for backward compatibility. */
4989 break;
b9e920ec 4990
047c3dbf
NL
4991 case OPTION_SYM_BASE:
4992 sym_base = 0;
4993 if (optarg != NULL)
4994 {
4995 sym_base = strtoul (optarg, NULL, 0);
4996 switch (sym_base)
4997 {
4998 case 0:
4999 case 8:
5000 case 10:
5001 case 16:
5002 break;
5003
5004 default:
5005 sym_base = 0;
5006 break;
5007 }
5008 }
5009 break;
5010
252b5132 5011 default:
252b5132
RH
5012 /* xgettext:c-format */
5013 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5014 /* Fall through. */
252b5132 5015 case '?':
92f01d61 5016 usage (stderr);
252b5132
RH
5017 }
5018 }
5019
4d6ed7c8 5020 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5021 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5022 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5023 && !do_section_groups && !do_archive_index
0f03783c 5024 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5025 {
5026 if (do_checks)
5027 {
015dc7e1
AM
5028 check_all = true;
5029 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5030 do_segments = do_header = do_dump = do_version = true;
5031 do_histogram = do_debugging = do_arch = do_notes = true;
5032 do_section_groups = do_archive_index = do_dyn_syms = true;
5033 do_lto_syms = true;
1b513401
NC
5034 }
5035 else
5036 usage (stderr);
5037 }
252b5132
RH
5038}
5039
5040static const char *
d3ba0551 5041get_elf_class (unsigned int elf_class)
252b5132 5042{
b34976b6 5043 static char buff[32];
103f02d3 5044
252b5132
RH
5045 switch (elf_class)
5046 {
5047 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5048 case ELFCLASS32: return "ELF32";
5049 case ELFCLASS64: return "ELF64";
ab5e7794 5050 default:
e9e44622 5051 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5052 return buff;
252b5132
RH
5053 }
5054}
5055
5056static const char *
d3ba0551 5057get_data_encoding (unsigned int encoding)
252b5132 5058{
b34976b6 5059 static char buff[32];
103f02d3 5060
252b5132
RH
5061 switch (encoding)
5062 {
5063 case ELFDATANONE: return _("none");
33c63f9d
CM
5064 case ELFDATA2LSB: return _("2's complement, little endian");
5065 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5066 default:
e9e44622 5067 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5068 return buff;
252b5132
RH
5069 }
5070}
5071
dda8d76d 5072/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5073
015dc7e1 5074static bool
dda8d76d 5075process_file_header (Filedata * filedata)
252b5132 5076{
dda8d76d
NC
5077 Elf_Internal_Ehdr * header = & filedata->file_header;
5078
5079 if ( header->e_ident[EI_MAG0] != ELFMAG0
5080 || header->e_ident[EI_MAG1] != ELFMAG1
5081 || header->e_ident[EI_MAG2] != ELFMAG2
5082 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5083 {
5084 error
5085 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
015dc7e1 5086 return false;
252b5132
RH
5087 }
5088
ca0e11aa
NC
5089 if (! filedata->is_separate)
5090 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5091
252b5132
RH
5092 if (do_header)
5093 {
32ec8896 5094 unsigned i;
252b5132 5095
ca0e11aa
NC
5096 if (filedata->is_separate)
5097 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5098 else
5099 printf (_("ELF Header:\n"));
252b5132 5100 printf (_(" Magic: "));
b34976b6 5101 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5102 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5103 printf ("\n");
5104 printf (_(" Class: %s\n"),
dda8d76d 5105 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5106 printf (_(" Data: %s\n"),
dda8d76d 5107 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5108 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5109 header->e_ident[EI_VERSION],
5110 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5111 ? _(" (current)")
dda8d76d 5112 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5113 ? _(" <unknown>")
789be9f7 5114 : "")));
252b5132 5115 printf (_(" OS/ABI: %s\n"),
dda8d76d 5116 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5117 printf (_(" ABI Version: %d\n"),
dda8d76d 5118 header->e_ident[EI_ABIVERSION]);
252b5132 5119 printf (_(" Type: %s\n"),
dda8d76d 5120 get_file_type (header->e_type));
252b5132 5121 printf (_(" Machine: %s\n"),
dda8d76d 5122 get_machine_name (header->e_machine));
252b5132 5123 printf (_(" Version: 0x%lx\n"),
e8a64888 5124 header->e_version);
76da6bbe 5125
f7a99963 5126 printf (_(" Entry point address: "));
e8a64888 5127 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5128 printf (_("\n Start of program headers: "));
e8a64888 5129 print_vma (header->e_phoff, DEC);
f7a99963 5130 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5131 print_vma (header->e_shoff, DEC);
f7a99963 5132 printf (_(" (bytes into file)\n"));
76da6bbe 5133
252b5132 5134 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5135 header->e_flags,
dda8d76d 5136 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5137 printf (_(" Size of this header: %u (bytes)\n"),
5138 header->e_ehsize);
5139 printf (_(" Size of program headers: %u (bytes)\n"),
5140 header->e_phentsize);
5141 printf (_(" Number of program headers: %u"),
5142 header->e_phnum);
dda8d76d
NC
5143 if (filedata->section_headers != NULL
5144 && header->e_phnum == PN_XNUM
5145 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
5146 {
5147 header->e_phnum = filedata->section_headers[0].sh_info;
5148 printf (" (%u)", header->e_phnum);
5149 }
2046a35d 5150 putc ('\n', stdout);
e8a64888
AM
5151 printf (_(" Size of section headers: %u (bytes)\n"),
5152 header->e_shentsize);
5153 printf (_(" Number of section headers: %u"),
5154 header->e_shnum);
dda8d76d 5155 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5156 {
5157 header->e_shnum = filedata->section_headers[0].sh_size;
5158 printf (" (%u)", header->e_shnum);
5159 }
560f3c1c 5160 putc ('\n', stdout);
e8a64888
AM
5161 printf (_(" Section header string table index: %u"),
5162 header->e_shstrndx);
dda8d76d
NC
5163 if (filedata->section_headers != NULL
5164 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5165 {
5166 header->e_shstrndx = filedata->section_headers[0].sh_link;
5167 printf (" (%u)", header->e_shstrndx);
5168 }
5169 if (header->e_shstrndx != SHN_UNDEF
5170 && header->e_shstrndx >= header->e_shnum)
5171 {
5172 header->e_shstrndx = SHN_UNDEF;
5173 printf (_(" <corrupt: out of range>"));
5174 }
560f3c1c
AM
5175 putc ('\n', stdout);
5176 }
5177
dda8d76d 5178 if (filedata->section_headers != NULL)
560f3c1c 5179 {
dda8d76d
NC
5180 if (header->e_phnum == PN_XNUM
5181 && filedata->section_headers[0].sh_info != 0)
5182 header->e_phnum = filedata->section_headers[0].sh_info;
5183 if (header->e_shnum == SHN_UNDEF)
5184 header->e_shnum = filedata->section_headers[0].sh_size;
5185 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5186 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5187 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
5188 header->e_shstrndx = SHN_UNDEF;
5189 free (filedata->section_headers);
5190 filedata->section_headers = NULL;
252b5132 5191 }
103f02d3 5192
015dc7e1 5193 return true;
9ea033b2
NC
5194}
5195
dda8d76d
NC
5196/* Read in the program headers from FILEDATA and store them in PHEADERS.
5197 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5198
015dc7e1 5199static bool
dda8d76d 5200get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5201{
2cf0635d
NC
5202 Elf32_External_Phdr * phdrs;
5203 Elf32_External_Phdr * external;
5204 Elf_Internal_Phdr * internal;
b34976b6 5205 unsigned int i;
dda8d76d
NC
5206 unsigned int size = filedata->file_header.e_phentsize;
5207 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5208
5209 /* PR binutils/17531: Cope with unexpected section header sizes. */
5210 if (size == 0 || num == 0)
015dc7e1 5211 return false;
e0a31db1
NC
5212 if (size < sizeof * phdrs)
5213 {
5214 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5215 return false;
e0a31db1
NC
5216 }
5217 if (size > sizeof * phdrs)
5218 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5219
dda8d76d 5220 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5221 size, num, _("program headers"));
5222 if (phdrs == NULL)
015dc7e1 5223 return false;
9ea033b2 5224
91d6fa6a 5225 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5226 i < filedata->file_header.e_phnum;
b34976b6 5227 i++, internal++, external++)
252b5132 5228 {
9ea033b2
NC
5229 internal->p_type = BYTE_GET (external->p_type);
5230 internal->p_offset = BYTE_GET (external->p_offset);
5231 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5232 internal->p_paddr = BYTE_GET (external->p_paddr);
5233 internal->p_filesz = BYTE_GET (external->p_filesz);
5234 internal->p_memsz = BYTE_GET (external->p_memsz);
5235 internal->p_flags = BYTE_GET (external->p_flags);
5236 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5237 }
5238
9ea033b2 5239 free (phdrs);
015dc7e1 5240 return true;
252b5132
RH
5241}
5242
dda8d76d
NC
5243/* Read in the program headers from FILEDATA and store them in PHEADERS.
5244 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5245
015dc7e1 5246static bool
dda8d76d 5247get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5248{
2cf0635d
NC
5249 Elf64_External_Phdr * phdrs;
5250 Elf64_External_Phdr * external;
5251 Elf_Internal_Phdr * internal;
b34976b6 5252 unsigned int i;
dda8d76d
NC
5253 unsigned int size = filedata->file_header.e_phentsize;
5254 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5255
5256 /* PR binutils/17531: Cope with unexpected section header sizes. */
5257 if (size == 0 || num == 0)
015dc7e1 5258 return false;
e0a31db1
NC
5259 if (size < sizeof * phdrs)
5260 {
5261 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5262 return false;
e0a31db1
NC
5263 }
5264 if (size > sizeof * phdrs)
5265 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5266
dda8d76d 5267 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5268 size, num, _("program headers"));
a6e9f9df 5269 if (!phdrs)
015dc7e1 5270 return false;
9ea033b2 5271
91d6fa6a 5272 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5273 i < filedata->file_header.e_phnum;
b34976b6 5274 i++, internal++, external++)
9ea033b2
NC
5275 {
5276 internal->p_type = BYTE_GET (external->p_type);
5277 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5278 internal->p_offset = BYTE_GET (external->p_offset);
5279 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5280 internal->p_paddr = BYTE_GET (external->p_paddr);
5281 internal->p_filesz = BYTE_GET (external->p_filesz);
5282 internal->p_memsz = BYTE_GET (external->p_memsz);
5283 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5284 }
5285
5286 free (phdrs);
015dc7e1 5287 return true;
9ea033b2 5288}
252b5132 5289
32ec8896 5290/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5291
015dc7e1 5292static bool
dda8d76d 5293get_program_headers (Filedata * filedata)
d93f0186 5294{
2cf0635d 5295 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5296
5297 /* Check cache of prior read. */
dda8d76d 5298 if (filedata->program_headers != NULL)
015dc7e1 5299 return true;
d93f0186 5300
82156ab7
NC
5301 /* Be kind to memory checkers by looking for
5302 e_phnum values which we know must be invalid. */
dda8d76d 5303 if (filedata->file_header.e_phnum
82156ab7 5304 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5305 >= filedata->file_size)
82156ab7
NC
5306 {
5307 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5308 filedata->file_header.e_phnum);
015dc7e1 5309 return false;
82156ab7 5310 }
d93f0186 5311
dda8d76d 5312 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5313 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5314 if (phdrs == NULL)
5315 {
8b73c356 5316 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5317 filedata->file_header.e_phnum);
015dc7e1 5318 return false;
d93f0186
NC
5319 }
5320
5321 if (is_32bit_elf
dda8d76d
NC
5322 ? get_32bit_program_headers (filedata, phdrs)
5323 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5324 {
dda8d76d 5325 filedata->program_headers = phdrs;
015dc7e1 5326 return true;
d93f0186
NC
5327 }
5328
5329 free (phdrs);
015dc7e1 5330 return false;
d93f0186
NC
5331}
5332
32ec8896 5333/* Returns TRUE if the program headers were loaded. */
2f62977e 5334
015dc7e1 5335static bool
dda8d76d 5336process_program_headers (Filedata * filedata)
252b5132 5337{
2cf0635d 5338 Elf_Internal_Phdr * segment;
b34976b6 5339 unsigned int i;
1a9ccd70 5340 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5341
978c4450
AM
5342 filedata->dynamic_addr = 0;
5343 filedata->dynamic_size = 0;
663f67df 5344
dda8d76d 5345 if (filedata->file_header.e_phnum == 0)
252b5132 5346 {
82f2dbf7 5347 /* PR binutils/12467. */
dda8d76d 5348 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5349 {
5350 warn (_("possibly corrupt ELF header - it has a non-zero program"
5351 " header offset, but no program headers\n"));
015dc7e1 5352 return false;
32ec8896 5353 }
82f2dbf7 5354 else if (do_segments)
ca0e11aa
NC
5355 {
5356 if (filedata->is_separate)
5357 printf (_("\nThere are no program headers in linked file '%s'.\n"),
5358 filedata->file_name);
5359 else
5360 printf (_("\nThere are no program headers in this file.\n"));
5361 }
015dc7e1 5362 return true;
252b5132
RH
5363 }
5364
5365 if (do_segments && !do_header)
5366 {
ca0e11aa
NC
5367 if (filedata->is_separate)
5368 printf ("\nIn linked file '%s' the ELF file type is %s\n",
5369 filedata->file_name,
5370 get_file_type (filedata->file_header.e_type));
5371 else
5372 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
dda8d76d 5373 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5374 printf (ngettext ("There is %d program header, starting at offset %s\n",
5375 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5376 filedata->file_header.e_phnum),
5377 filedata->file_header.e_phnum,
5378 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5379 }
5380
dda8d76d 5381 if (! get_program_headers (filedata))
015dc7e1 5382 return true;
103f02d3 5383
252b5132
RH
5384 if (do_segments)
5385 {
dda8d76d 5386 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5387 printf (_("\nProgram Headers:\n"));
5388 else
5389 printf (_("\nProgram Headers:\n"));
76da6bbe 5390
f7a99963
NC
5391 if (is_32bit_elf)
5392 printf
5393 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5394 else if (do_wide)
5395 printf
5396 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5397 else
5398 {
5399 printf
5400 (_(" Type Offset VirtAddr PhysAddr\n"));
5401 printf
5402 (_(" FileSiz MemSiz Flags Align\n"));
5403 }
252b5132
RH
5404 }
5405
dda8d76d
NC
5406 for (i = 0, segment = filedata->program_headers;
5407 i < filedata->file_header.e_phnum;
b34976b6 5408 i++, segment++)
252b5132
RH
5409 {
5410 if (do_segments)
5411 {
dda8d76d 5412 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5413
5414 if (is_32bit_elf)
5415 {
5416 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5417 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5418 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5419 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5420 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5421 printf ("%c%c%c ",
5422 (segment->p_flags & PF_R ? 'R' : ' '),
5423 (segment->p_flags & PF_W ? 'W' : ' '),
5424 (segment->p_flags & PF_X ? 'E' : ' '));
5425 printf ("%#lx", (unsigned long) segment->p_align);
5426 }
d974e256
JJ
5427 else if (do_wide)
5428 {
5429 if ((unsigned long) segment->p_offset == segment->p_offset)
5430 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5431 else
5432 {
5433 print_vma (segment->p_offset, FULL_HEX);
5434 putchar (' ');
5435 }
5436
5437 print_vma (segment->p_vaddr, FULL_HEX);
5438 putchar (' ');
5439 print_vma (segment->p_paddr, FULL_HEX);
5440 putchar (' ');
5441
5442 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5443 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5444 else
5445 {
5446 print_vma (segment->p_filesz, FULL_HEX);
5447 putchar (' ');
5448 }
5449
5450 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5451 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5452 else
5453 {
f48e6c45 5454 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5455 }
5456
5457 printf (" %c%c%c ",
5458 (segment->p_flags & PF_R ? 'R' : ' '),
5459 (segment->p_flags & PF_W ? 'W' : ' '),
5460 (segment->p_flags & PF_X ? 'E' : ' '));
5461
5462 if ((unsigned long) segment->p_align == segment->p_align)
5463 printf ("%#lx", (unsigned long) segment->p_align);
5464 else
5465 {
5466 print_vma (segment->p_align, PREFIX_HEX);
5467 }
5468 }
f7a99963
NC
5469 else
5470 {
5471 print_vma (segment->p_offset, FULL_HEX);
5472 putchar (' ');
5473 print_vma (segment->p_vaddr, FULL_HEX);
5474 putchar (' ');
5475 print_vma (segment->p_paddr, FULL_HEX);
5476 printf ("\n ");
5477 print_vma (segment->p_filesz, FULL_HEX);
5478 putchar (' ');
5479 print_vma (segment->p_memsz, FULL_HEX);
5480 printf (" %c%c%c ",
5481 (segment->p_flags & PF_R ? 'R' : ' '),
5482 (segment->p_flags & PF_W ? 'W' : ' '),
5483 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5484 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5485 }
252b5132 5486
1a9ccd70
NC
5487 putc ('\n', stdout);
5488 }
f54498b4 5489
252b5132
RH
5490 switch (segment->p_type)
5491 {
1a9ccd70 5492 case PT_LOAD:
502d895c
NC
5493#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5494 required by the ELF standard, several programs, including the Linux
5495 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5496 if (previous_load
5497 && previous_load->p_vaddr > segment->p_vaddr)
5498 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5499#endif
1a9ccd70
NC
5500 if (segment->p_memsz < segment->p_filesz)
5501 error (_("the segment's file size is larger than its memory size\n"));
5502 previous_load = segment;
5503 break;
5504
5505 case PT_PHDR:
5506 /* PR 20815 - Verify that the program header is loaded into memory. */
5507 if (i > 0 && previous_load != NULL)
5508 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5509 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5510 {
5511 unsigned int j;
5512
dda8d76d 5513 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5514 {
5515 Elf_Internal_Phdr *load = filedata->program_headers + j;
5516 if (load->p_type == PT_LOAD
5517 && load->p_offset <= segment->p_offset
5518 && (load->p_offset + load->p_filesz
5519 >= segment->p_offset + segment->p_filesz)
5520 && load->p_vaddr <= segment->p_vaddr
5521 && (load->p_vaddr + load->p_filesz
5522 >= segment->p_vaddr + segment->p_filesz))
5523 break;
5524 }
dda8d76d 5525 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5526 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5527 }
5528 break;
5529
252b5132 5530 case PT_DYNAMIC:
978c4450 5531 if (filedata->dynamic_addr)
252b5132
RH
5532 error (_("more than one dynamic segment\n"));
5533
20737c13
AM
5534 /* By default, assume that the .dynamic section is the first
5535 section in the DYNAMIC segment. */
978c4450
AM
5536 filedata->dynamic_addr = segment->p_offset;
5537 filedata->dynamic_size = segment->p_filesz;
20737c13 5538
b2d38a17
NC
5539 /* Try to locate the .dynamic section. If there is
5540 a section header table, we can easily locate it. */
dda8d76d 5541 if (filedata->section_headers != NULL)
b2d38a17 5542 {
2cf0635d 5543 Elf_Internal_Shdr * sec;
b2d38a17 5544
dda8d76d 5545 sec = find_section (filedata, ".dynamic");
89fac5e3 5546 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5547 {
28f997cf
TG
5548 /* A corresponding .dynamic section is expected, but on
5549 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5550 if (!is_ia64_vms (filedata))
28f997cf 5551 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5552 break;
5553 }
5554
42bb2e33 5555 if (sec->sh_type == SHT_NOBITS)
20737c13 5556 {
978c4450 5557 filedata->dynamic_size = 0;
20737c13
AM
5558 break;
5559 }
42bb2e33 5560
978c4450
AM
5561 filedata->dynamic_addr = sec->sh_offset;
5562 filedata->dynamic_size = sec->sh_size;
b2d38a17 5563
8ac10c5b
L
5564 /* The PT_DYNAMIC segment, which is used by the run-time
5565 loader, should exactly match the .dynamic section. */
5566 if (do_checks
5567 && (filedata->dynamic_addr != segment->p_offset
5568 || filedata->dynamic_size != segment->p_filesz))
5569 warn (_("\
5570the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 5571 }
39e224f6
MW
5572
5573 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5574 segment. Check this after matching against the section headers
5575 so we don't warn on debuginfo file (which have NOBITS .dynamic
5576 sections). */
978c4450
AM
5577 if (filedata->dynamic_addr > filedata->file_size
5578 || (filedata->dynamic_size
5579 > filedata->file_size - filedata->dynamic_addr))
39e224f6
MW
5580 {
5581 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
978c4450 5582 filedata->dynamic_addr = filedata->dynamic_size = 0;
39e224f6 5583 }
252b5132
RH
5584 break;
5585
5586 case PT_INTERP:
13acb58d
AM
5587 if (segment->p_offset >= filedata->file_size
5588 || segment->p_filesz > filedata->file_size - segment->p_offset
5589 || segment->p_filesz - 1 >= (size_t) -2
5590 || fseek (filedata->handle,
5591 filedata->archive_file_offset + (long) segment->p_offset,
5592 SEEK_SET))
252b5132
RH
5593 error (_("Unable to find program interpreter name\n"));
5594 else
5595 {
13acb58d
AM
5596 size_t len = segment->p_filesz;
5597 free (filedata->program_interpreter);
5598 filedata->program_interpreter = xmalloc (len + 1);
5599 len = fread (filedata->program_interpreter, 1, len,
5600 filedata->handle);
5601 filedata->program_interpreter[len] = 0;
252b5132
RH
5602
5603 if (do_segments)
f54498b4 5604 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 5605 filedata->program_interpreter);
252b5132
RH
5606 }
5607 break;
5608 }
252b5132
RH
5609 }
5610
dda8d76d
NC
5611 if (do_segments
5612 && filedata->section_headers != NULL
5613 && filedata->string_table != NULL)
252b5132
RH
5614 {
5615 printf (_("\n Section to Segment mapping:\n"));
5616 printf (_(" Segment Sections...\n"));
5617
dda8d76d 5618 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5619 {
9ad5cbcf 5620 unsigned int j;
2cf0635d 5621 Elf_Internal_Shdr * section;
252b5132 5622
dda8d76d
NC
5623 segment = filedata->program_headers + i;
5624 section = filedata->section_headers + 1;
252b5132
RH
5625
5626 printf (" %2.2d ", i);
5627
dda8d76d 5628 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5629 {
f4638467
AM
5630 if (!ELF_TBSS_SPECIAL (section, segment)
5631 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5632 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5633 }
5634
5635 putc ('\n',stdout);
5636 }
5637 }
5638
015dc7e1 5639 return true;
252b5132
RH
5640}
5641
5642
d93f0186
NC
5643/* Find the file offset corresponding to VMA by using the program headers. */
5644
5645static long
dda8d76d 5646offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5647{
2cf0635d 5648 Elf_Internal_Phdr * seg;
d93f0186 5649
dda8d76d 5650 if (! get_program_headers (filedata))
d93f0186
NC
5651 {
5652 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5653 return (long) vma;
5654 }
5655
dda8d76d
NC
5656 for (seg = filedata->program_headers;
5657 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5658 ++seg)
5659 {
5660 if (seg->p_type != PT_LOAD)
5661 continue;
5662
5663 if (vma >= (seg->p_vaddr & -seg->p_align)
5664 && vma + size <= seg->p_vaddr + seg->p_filesz)
5665 return vma - seg->p_vaddr + seg->p_offset;
5666 }
5667
5668 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5669 (unsigned long) vma);
d93f0186
NC
5670 return (long) vma;
5671}
5672
5673
dda8d76d
NC
5674/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5675 If PROBE is true, this is just a probe and we do not generate any error
5676 messages if the load fails. */
049b0c3a 5677
015dc7e1
AM
5678static bool
5679get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 5680{
2cf0635d
NC
5681 Elf32_External_Shdr * shdrs;
5682 Elf_Internal_Shdr * internal;
dda8d76d
NC
5683 unsigned int i;
5684 unsigned int size = filedata->file_header.e_shentsize;
5685 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5686
5687 /* PR binutils/17531: Cope with unexpected section header sizes. */
5688 if (size == 0 || num == 0)
015dc7e1 5689 return false;
049b0c3a
NC
5690 if (size < sizeof * shdrs)
5691 {
5692 if (! probe)
5693 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 5694 return false;
049b0c3a
NC
5695 }
5696 if (!probe && size > sizeof * shdrs)
5697 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5698
dda8d76d 5699 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5700 size, num,
5701 probe ? NULL : _("section headers"));
5702 if (shdrs == NULL)
015dc7e1 5703 return false;
252b5132 5704
dda8d76d
NC
5705 free (filedata->section_headers);
5706 filedata->section_headers = (Elf_Internal_Shdr *)
5707 cmalloc (num, sizeof (Elf_Internal_Shdr));
5708 if (filedata->section_headers == NULL)
252b5132 5709 {
049b0c3a 5710 if (!probe)
8b73c356 5711 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5712 free (shdrs);
015dc7e1 5713 return false;
252b5132
RH
5714 }
5715
dda8d76d 5716 for (i = 0, internal = filedata->section_headers;
560f3c1c 5717 i < num;
b34976b6 5718 i++, internal++)
252b5132
RH
5719 {
5720 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5721 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5722 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5723 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5724 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5725 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5726 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5727 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5728 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5729 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5730 if (!probe && internal->sh_link > num)
5731 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5732 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5733 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5734 }
5735
5736 free (shdrs);
015dc7e1 5737 return true;
252b5132
RH
5738}
5739
dda8d76d
NC
5740/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5741
015dc7e1
AM
5742static bool
5743get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 5744{
dda8d76d
NC
5745 Elf64_External_Shdr * shdrs;
5746 Elf_Internal_Shdr * internal;
5747 unsigned int i;
5748 unsigned int size = filedata->file_header.e_shentsize;
5749 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5750
5751 /* PR binutils/17531: Cope with unexpected section header sizes. */
5752 if (size == 0 || num == 0)
015dc7e1 5753 return false;
dda8d76d 5754
049b0c3a
NC
5755 if (size < sizeof * shdrs)
5756 {
5757 if (! probe)
5758 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 5759 return false;
049b0c3a 5760 }
dda8d76d 5761
049b0c3a
NC
5762 if (! probe && size > sizeof * shdrs)
5763 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5764
dda8d76d
NC
5765 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5766 filedata->file_header.e_shoff,
049b0c3a
NC
5767 size, num,
5768 probe ? NULL : _("section headers"));
5769 if (shdrs == NULL)
015dc7e1 5770 return false;
9ea033b2 5771
dda8d76d
NC
5772 free (filedata->section_headers);
5773 filedata->section_headers = (Elf_Internal_Shdr *)
5774 cmalloc (num, sizeof (Elf_Internal_Shdr));
5775 if (filedata->section_headers == NULL)
9ea033b2 5776 {
049b0c3a 5777 if (! probe)
8b73c356 5778 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5779 free (shdrs);
015dc7e1 5780 return false;
9ea033b2
NC
5781 }
5782
dda8d76d 5783 for (i = 0, internal = filedata->section_headers;
560f3c1c 5784 i < num;
b34976b6 5785 i++, internal++)
9ea033b2
NC
5786 {
5787 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5788 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5789 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5790 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5791 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5792 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5793 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5794 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5795 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5796 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5797 if (!probe && internal->sh_link > num)
5798 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5799 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5800 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5801 }
5802
5803 free (shdrs);
015dc7e1 5804 return true;
9ea033b2
NC
5805}
5806
252b5132 5807static Elf_Internal_Sym *
dda8d76d
NC
5808get_32bit_elf_symbols (Filedata * filedata,
5809 Elf_Internal_Shdr * section,
5810 unsigned long * num_syms_return)
252b5132 5811{
ba5cdace 5812 unsigned long number = 0;
dd24e3da 5813 Elf32_External_Sym * esyms = NULL;
ba5cdace 5814 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5815 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5816 Elf_Internal_Sym * psym;
b34976b6 5817 unsigned int j;
e3d39609 5818 elf_section_list * entry;
252b5132 5819
c9c1d674
EG
5820 if (section->sh_size == 0)
5821 {
5822 if (num_syms_return != NULL)
5823 * num_syms_return = 0;
5824 return NULL;
5825 }
5826
dd24e3da 5827 /* Run some sanity checks first. */
c9c1d674 5828 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5829 {
c9c1d674 5830 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5831 printable_section_name (filedata, section),
5832 (unsigned long) section->sh_entsize);
ba5cdace 5833 goto exit_point;
dd24e3da
NC
5834 }
5835
dda8d76d 5836 if (section->sh_size > filedata->file_size)
f54498b4
NC
5837 {
5838 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5839 printable_section_name (filedata, section),
5840 (unsigned long) section->sh_size);
f54498b4
NC
5841 goto exit_point;
5842 }
5843
dd24e3da
NC
5844 number = section->sh_size / section->sh_entsize;
5845
5846 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5847 {
c9c1d674 5848 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5849 (unsigned long) section->sh_size,
dda8d76d 5850 printable_section_name (filedata, section),
8066deb1 5851 (unsigned long) section->sh_entsize);
ba5cdace 5852 goto exit_point;
dd24e3da
NC
5853 }
5854
dda8d76d 5855 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5856 section->sh_size, _("symbols"));
dd24e3da 5857 if (esyms == NULL)
ba5cdace 5858 goto exit_point;
252b5132 5859
e3d39609 5860 shndx = NULL;
978c4450 5861 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5862 {
5863 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5864 continue;
5865
5866 if (shndx != NULL)
5867 {
5868 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5869 free (shndx);
5870 }
5871
5872 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5873 entry->hdr->sh_offset,
5874 1, entry->hdr->sh_size,
5875 _("symbol table section indices"));
5876 if (shndx == NULL)
5877 goto exit_point;
5878
5879 /* PR17531: file: heap-buffer-overflow */
5880 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5881 {
5882 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5883 printable_section_name (filedata, entry->hdr),
5884 (unsigned long) entry->hdr->sh_size,
5885 (unsigned long) section->sh_size);
5886 goto exit_point;
c9c1d674 5887 }
e3d39609 5888 }
9ad5cbcf 5889
3f5e193b 5890 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5891
5892 if (isyms == NULL)
5893 {
8b73c356
NC
5894 error (_("Out of memory reading %lu symbols\n"),
5895 (unsigned long) number);
dd24e3da 5896 goto exit_point;
252b5132
RH
5897 }
5898
dd24e3da 5899 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5900 {
5901 psym->st_name = BYTE_GET (esyms[j].st_name);
5902 psym->st_value = BYTE_GET (esyms[j].st_value);
5903 psym->st_size = BYTE_GET (esyms[j].st_size);
5904 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5905 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5906 psym->st_shndx
5907 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5908 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5909 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5910 psym->st_info = BYTE_GET (esyms[j].st_info);
5911 psym->st_other = BYTE_GET (esyms[j].st_other);
5912 }
5913
dd24e3da 5914 exit_point:
e3d39609
NC
5915 free (shndx);
5916 free (esyms);
252b5132 5917
ba5cdace
NC
5918 if (num_syms_return != NULL)
5919 * num_syms_return = isyms == NULL ? 0 : number;
5920
252b5132
RH
5921 return isyms;
5922}
5923
9ea033b2 5924static Elf_Internal_Sym *
dda8d76d
NC
5925get_64bit_elf_symbols (Filedata * filedata,
5926 Elf_Internal_Shdr * section,
5927 unsigned long * num_syms_return)
9ea033b2 5928{
ba5cdace
NC
5929 unsigned long number = 0;
5930 Elf64_External_Sym * esyms = NULL;
5931 Elf_External_Sym_Shndx * shndx = NULL;
5932 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5933 Elf_Internal_Sym * psym;
b34976b6 5934 unsigned int j;
e3d39609 5935 elf_section_list * entry;
9ea033b2 5936
c9c1d674
EG
5937 if (section->sh_size == 0)
5938 {
5939 if (num_syms_return != NULL)
5940 * num_syms_return = 0;
5941 return NULL;
5942 }
5943
dd24e3da 5944 /* Run some sanity checks first. */
c9c1d674 5945 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5946 {
c9c1d674 5947 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5948 printable_section_name (filedata, section),
8066deb1 5949 (unsigned long) section->sh_entsize);
ba5cdace 5950 goto exit_point;
dd24e3da
NC
5951 }
5952
dda8d76d 5953 if (section->sh_size > filedata->file_size)
f54498b4
NC
5954 {
5955 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5956 printable_section_name (filedata, section),
8066deb1 5957 (unsigned long) section->sh_size);
f54498b4
NC
5958 goto exit_point;
5959 }
5960
dd24e3da
NC
5961 number = section->sh_size / section->sh_entsize;
5962
5963 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5964 {
c9c1d674 5965 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5966 (unsigned long) section->sh_size,
dda8d76d 5967 printable_section_name (filedata, section),
8066deb1 5968 (unsigned long) section->sh_entsize);
ba5cdace 5969 goto exit_point;
dd24e3da
NC
5970 }
5971
dda8d76d 5972 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5973 section->sh_size, _("symbols"));
a6e9f9df 5974 if (!esyms)
ba5cdace 5975 goto exit_point;
9ea033b2 5976
e3d39609 5977 shndx = NULL;
978c4450 5978 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5979 {
5980 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5981 continue;
5982
5983 if (shndx != NULL)
5984 {
5985 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5986 free (shndx);
c9c1d674 5987 }
e3d39609
NC
5988
5989 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5990 entry->hdr->sh_offset,
5991 1, entry->hdr->sh_size,
5992 _("symbol table section indices"));
5993 if (shndx == NULL)
5994 goto exit_point;
5995
5996 /* PR17531: file: heap-buffer-overflow */
5997 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5998 {
5999 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6000 printable_section_name (filedata, entry->hdr),
6001 (unsigned long) entry->hdr->sh_size,
6002 (unsigned long) section->sh_size);
6003 goto exit_point;
6004 }
6005 }
9ad5cbcf 6006
3f5e193b 6007 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6008
6009 if (isyms == NULL)
6010 {
8b73c356
NC
6011 error (_("Out of memory reading %lu symbols\n"),
6012 (unsigned long) number);
ba5cdace 6013 goto exit_point;
9ea033b2
NC
6014 }
6015
ba5cdace 6016 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6017 {
6018 psym->st_name = BYTE_GET (esyms[j].st_name);
6019 psym->st_info = BYTE_GET (esyms[j].st_info);
6020 psym->st_other = BYTE_GET (esyms[j].st_other);
6021 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6022
4fbb74a6 6023 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6024 psym->st_shndx
6025 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6026 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6027 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6028
66543521
AM
6029 psym->st_value = BYTE_GET (esyms[j].st_value);
6030 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6031 }
6032
ba5cdace 6033 exit_point:
e3d39609
NC
6034 free (shndx);
6035 free (esyms);
ba5cdace
NC
6036
6037 if (num_syms_return != NULL)
6038 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6039
6040 return isyms;
6041}
6042
d1133906 6043static const char *
dda8d76d 6044get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 6045{
5477e8a0 6046 static char buff[1024];
2cf0635d 6047 char * p = buff;
32ec8896
NC
6048 unsigned int field_size = is_32bit_elf ? 8 : 16;
6049 signed int sindex;
6050 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
6051 bfd_vma os_flags = 0;
6052 bfd_vma proc_flags = 0;
6053 bfd_vma unknown_flags = 0;
148b93f2 6054 static const struct
5477e8a0 6055 {
2cf0635d 6056 const char * str;
32ec8896 6057 unsigned int len;
5477e8a0
L
6058 }
6059 flags [] =
6060 {
cfcac11d
NC
6061 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6062 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6063 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6064 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6065 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6066 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6067 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6068 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6069 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6070 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6071 /* IA-64 specific. */
6072 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6073 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6074 /* IA-64 OpenVMS specific. */
6075 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6076 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6077 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6078 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6079 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6080 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6081 /* Generic. */
cfcac11d 6082 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6083 /* SPARC specific. */
77115a4a 6084 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6085 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6086 /* ARM specific. */
6087 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6088 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6089 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6090 /* GNU specific. */
6091 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6092 /* VLE specific. */
6093 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6094 /* GNU specific. */
6095 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6096 };
6097
6098 if (do_section_details)
6099 {
8d5ff12c
L
6100 sprintf (buff, "[%*.*lx]: ",
6101 field_size, field_size, (unsigned long) sh_flags);
6102 p += field_size + 4;
5477e8a0 6103 }
76da6bbe 6104
d1133906
NC
6105 while (sh_flags)
6106 {
6107 bfd_vma flag;
6108
6109 flag = sh_flags & - sh_flags;
6110 sh_flags &= ~ flag;
76da6bbe 6111
5477e8a0 6112 if (do_section_details)
d1133906 6113 {
5477e8a0
L
6114 switch (flag)
6115 {
91d6fa6a
NC
6116 case SHF_WRITE: sindex = 0; break;
6117 case SHF_ALLOC: sindex = 1; break;
6118 case SHF_EXECINSTR: sindex = 2; break;
6119 case SHF_MERGE: sindex = 3; break;
6120 case SHF_STRINGS: sindex = 4; break;
6121 case SHF_INFO_LINK: sindex = 5; break;
6122 case SHF_LINK_ORDER: sindex = 6; break;
6123 case SHF_OS_NONCONFORMING: sindex = 7; break;
6124 case SHF_GROUP: sindex = 8; break;
6125 case SHF_TLS: sindex = 9; break;
18ae9cc1 6126 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6127 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6128
5477e8a0 6129 default:
91d6fa6a 6130 sindex = -1;
dda8d76d 6131 switch (filedata->file_header.e_machine)
148b93f2 6132 {
cfcac11d 6133 case EM_IA_64:
148b93f2 6134 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6135 sindex = 10;
148b93f2 6136 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6137 sindex = 11;
148b93f2 6138#ifdef BFD64
dda8d76d 6139 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6140 switch (flag)
6141 {
91d6fa6a
NC
6142 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6143 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6144 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6145 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6146 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6147 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6148 default: break;
6149 }
6150#endif
cfcac11d
NC
6151 break;
6152
caa83f8b 6153 case EM_386:
22abe556 6154 case EM_IAMCU:
caa83f8b 6155 case EM_X86_64:
7f502d6c 6156 case EM_L1OM:
7a9068fe 6157 case EM_K1OM:
cfcac11d
NC
6158 case EM_OLD_SPARCV9:
6159 case EM_SPARC32PLUS:
6160 case EM_SPARCV9:
6161 case EM_SPARC:
18ae9cc1 6162 if (flag == SHF_ORDERED)
91d6fa6a 6163 sindex = 19;
cfcac11d 6164 break;
ac4c9b04
MG
6165
6166 case EM_ARM:
6167 switch (flag)
6168 {
6169 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6170 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6171 case SHF_COMDEF: sindex = 23; break;
6172 default: break;
6173 }
6174 break;
83eef883
AFB
6175 case EM_PPC:
6176 if (flag == SHF_PPC_VLE)
6177 sindex = 25;
6178 break;
99fabbc9
JL
6179 default:
6180 break;
6181 }
ac4c9b04 6182
99fabbc9
JL
6183 switch (filedata->file_header.e_ident[EI_OSABI])
6184 {
6185 case ELFOSABI_GNU:
6186 case ELFOSABI_FREEBSD:
6187 if (flag == SHF_GNU_RETAIN)
6188 sindex = 26;
6189 /* Fall through */
6190 case ELFOSABI_NONE:
6191 if (flag == SHF_GNU_MBIND)
6192 /* We should not recognize SHF_GNU_MBIND for
6193 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6194 not set the EI_OSABI header byte. */
6195 sindex = 24;
6196 break;
cfcac11d
NC
6197 default:
6198 break;
148b93f2 6199 }
99fabbc9 6200 break;
5477e8a0
L
6201 }
6202
91d6fa6a 6203 if (sindex != -1)
5477e8a0 6204 {
8d5ff12c
L
6205 if (p != buff + field_size + 4)
6206 {
6207 if (size < (10 + 2))
bee0ee85
NC
6208 {
6209 warn (_("Internal error: not enough buffer room for section flag info"));
6210 return _("<unknown>");
6211 }
8d5ff12c
L
6212 size -= 2;
6213 *p++ = ',';
6214 *p++ = ' ';
6215 }
6216
91d6fa6a
NC
6217 size -= flags [sindex].len;
6218 p = stpcpy (p, flags [sindex].str);
5477e8a0 6219 }
3b22753a 6220 else if (flag & SHF_MASKOS)
8d5ff12c 6221 os_flags |= flag;
d1133906 6222 else if (flag & SHF_MASKPROC)
8d5ff12c 6223 proc_flags |= flag;
d1133906 6224 else
8d5ff12c 6225 unknown_flags |= flag;
5477e8a0
L
6226 }
6227 else
6228 {
6229 switch (flag)
6230 {
6231 case SHF_WRITE: *p = 'W'; break;
6232 case SHF_ALLOC: *p = 'A'; break;
6233 case SHF_EXECINSTR: *p = 'X'; break;
6234 case SHF_MERGE: *p = 'M'; break;
6235 case SHF_STRINGS: *p = 'S'; break;
6236 case SHF_INFO_LINK: *p = 'I'; break;
6237 case SHF_LINK_ORDER: *p = 'L'; break;
6238 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6239 case SHF_GROUP: *p = 'G'; break;
6240 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6241 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6242 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6243
6244 default:
dda8d76d
NC
6245 if ((filedata->file_header.e_machine == EM_X86_64
6246 || filedata->file_header.e_machine == EM_L1OM
6247 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6248 && flag == SHF_X86_64_LARGE)
6249 *p = 'l';
dda8d76d 6250 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6251 && flag == SHF_ARM_PURECODE)
99fabbc9 6252 *p = 'y';
dda8d76d 6253 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6254 && flag == SHF_PPC_VLE)
99fabbc9 6255 *p = 'v';
5477e8a0
L
6256 else if (flag & SHF_MASKOS)
6257 {
99fabbc9
JL
6258 switch (filedata->file_header.e_ident[EI_OSABI])
6259 {
6260 case ELFOSABI_GNU:
6261 case ELFOSABI_FREEBSD:
6262 if (flag == SHF_GNU_RETAIN)
6263 {
6264 *p = 'R';
6265 break;
6266 }
6267 /* Fall through */
6268 case ELFOSABI_NONE:
6269 if (flag == SHF_GNU_MBIND)
6270 {
6271 /* We should not recognize SHF_GNU_MBIND for
6272 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6273 not set the EI_OSABI header byte. */
6274 *p = 'D';
6275 break;
6276 }
6277 /* Fall through */
6278 default:
6279 *p = 'o';
6280 sh_flags &= ~SHF_MASKOS;
6281 break;
6282 }
5477e8a0
L
6283 }
6284 else if (flag & SHF_MASKPROC)
6285 {
6286 *p = 'p';
6287 sh_flags &= ~ SHF_MASKPROC;
6288 }
6289 else
6290 *p = 'x';
6291 break;
6292 }
6293 p++;
d1133906
NC
6294 }
6295 }
76da6bbe 6296
8d5ff12c
L
6297 if (do_section_details)
6298 {
6299 if (os_flags)
6300 {
6301 size -= 5 + field_size;
6302 if (p != buff + field_size + 4)
6303 {
6304 if (size < (2 + 1))
bee0ee85
NC
6305 {
6306 warn (_("Internal error: not enough buffer room for section flag info"));
6307 return _("<unknown>");
6308 }
8d5ff12c
L
6309 size -= 2;
6310 *p++ = ',';
6311 *p++ = ' ';
6312 }
6313 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6314 (unsigned long) os_flags);
6315 p += 5 + field_size;
6316 }
6317 if (proc_flags)
6318 {
6319 size -= 7 + field_size;
6320 if (p != buff + field_size + 4)
6321 {
6322 if (size < (2 + 1))
bee0ee85
NC
6323 {
6324 warn (_("Internal error: not enough buffer room for section flag info"));
6325 return _("<unknown>");
6326 }
8d5ff12c
L
6327 size -= 2;
6328 *p++ = ',';
6329 *p++ = ' ';
6330 }
6331 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6332 (unsigned long) proc_flags);
6333 p += 7 + field_size;
6334 }
6335 if (unknown_flags)
6336 {
6337 size -= 10 + field_size;
6338 if (p != buff + field_size + 4)
6339 {
6340 if (size < (2 + 1))
bee0ee85
NC
6341 {
6342 warn (_("Internal error: not enough buffer room for section flag info"));
6343 return _("<unknown>");
6344 }
8d5ff12c
L
6345 size -= 2;
6346 *p++ = ',';
6347 *p++ = ' ';
6348 }
2b692964 6349 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6350 (unsigned long) unknown_flags);
6351 p += 10 + field_size;
6352 }
6353 }
6354
e9e44622 6355 *p = '\0';
d1133906
NC
6356 return buff;
6357}
6358
5844b465 6359static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6360get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6361{
6362 if (is_32bit_elf)
6363 {
6364 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6365
ebdf1ebf
NC
6366 if (size < sizeof (* echdr))
6367 {
6368 error (_("Compressed section is too small even for a compression header\n"));
6369 return 0;
6370 }
6371
77115a4a
L
6372 chdr->ch_type = BYTE_GET (echdr->ch_type);
6373 chdr->ch_size = BYTE_GET (echdr->ch_size);
6374 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6375 return sizeof (*echdr);
6376 }
6377 else
6378 {
6379 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6380
ebdf1ebf
NC
6381 if (size < sizeof (* echdr))
6382 {
6383 error (_("Compressed section is too small even for a compression header\n"));
6384 return 0;
6385 }
6386
77115a4a
L
6387 chdr->ch_type = BYTE_GET (echdr->ch_type);
6388 chdr->ch_size = BYTE_GET (echdr->ch_size);
6389 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6390 return sizeof (*echdr);
6391 }
6392}
6393
015dc7e1 6394static bool
dda8d76d 6395process_section_headers (Filedata * filedata)
252b5132 6396{
2cf0635d 6397 Elf_Internal_Shdr * section;
b34976b6 6398 unsigned int i;
252b5132 6399
8fb879cd 6400 free (filedata->section_headers);
dda8d76d 6401 filedata->section_headers = NULL;
978c4450
AM
6402 free (filedata->dynamic_symbols);
6403 filedata->dynamic_symbols = NULL;
6404 filedata->num_dynamic_syms = 0;
6405 free (filedata->dynamic_strings);
6406 filedata->dynamic_strings = NULL;
6407 filedata->dynamic_strings_length = 0;
6408 free (filedata->dynamic_syminfo);
6409 filedata->dynamic_syminfo = NULL;
6410 while (filedata->symtab_shndx_list != NULL)
8ff66993 6411 {
978c4450
AM
6412 elf_section_list *next = filedata->symtab_shndx_list->next;
6413 free (filedata->symtab_shndx_list);
6414 filedata->symtab_shndx_list = next;
8ff66993 6415 }
252b5132 6416
dda8d76d 6417 if (filedata->file_header.e_shnum == 0)
252b5132 6418 {
82f2dbf7 6419 /* PR binutils/12467. */
dda8d76d 6420 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6421 {
6422 warn (_("possibly corrupt ELF file header - it has a non-zero"
6423 " section header offset, but no section headers\n"));
015dc7e1 6424 return false;
32ec8896 6425 }
82f2dbf7 6426 else if (do_sections)
252b5132
RH
6427 printf (_("\nThere are no sections in this file.\n"));
6428
015dc7e1 6429 return true;
252b5132
RH
6430 }
6431
6432 if (do_sections && !do_header)
ca0e11aa
NC
6433 {
6434 if (filedata->is_separate && process_links)
6435 printf (_("In linked file '%s': "), filedata->file_name);
6436 if (! filedata->is_separate || process_links)
6437 printf (ngettext ("There is %d section header, "
6438 "starting at offset 0x%lx:\n",
6439 "There are %d section headers, "
6440 "starting at offset 0x%lx:\n",
6441 filedata->file_header.e_shnum),
6442 filedata->file_header.e_shnum,
6443 (unsigned long) filedata->file_header.e_shoff);
6444 }
252b5132 6445
9ea033b2
NC
6446 if (is_32bit_elf)
6447 {
015dc7e1
AM
6448 if (! get_32bit_section_headers (filedata, false))
6449 return false;
32ec8896
NC
6450 }
6451 else
6452 {
015dc7e1
AM
6453 if (! get_64bit_section_headers (filedata, false))
6454 return false;
9ea033b2 6455 }
252b5132
RH
6456
6457 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6458 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6459 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6460 {
dda8d76d 6461 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6462
c256ffe7
JJ
6463 if (section->sh_size != 0)
6464 {
dda8d76d
NC
6465 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6466 1, section->sh_size,
6467 _("string table"));
0de14b54 6468
dda8d76d 6469 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6470 }
252b5132
RH
6471 }
6472
6473 /* Scan the sections for the dynamic symbol table
e3c8793a 6474 and dynamic string table and debug sections. */
89fac5e3 6475 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6476 switch (filedata->file_header.e_machine)
89fac5e3
RS
6477 {
6478 case EM_MIPS:
6479 case EM_MIPS_RS3_LE:
6480 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6481 FDE addresses. However, the ABI also has a semi-official ILP32
6482 variant for which the normal FDE address size rules apply.
6483
6484 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6485 section, where XX is the size of longs in bits. Unfortunately,
6486 earlier compilers provided no way of distinguishing ILP32 objects
6487 from LP64 objects, so if there's any doubt, we should assume that
6488 the official LP64 form is being used. */
dda8d76d
NC
6489 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6490 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6491 eh_addr_size = 8;
6492 break;
0f56a26a
DD
6493
6494 case EM_H8_300:
6495 case EM_H8_300H:
dda8d76d 6496 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6497 {
6498 case E_H8_MACH_H8300:
6499 case E_H8_MACH_H8300HN:
6500 case E_H8_MACH_H8300SN:
6501 case E_H8_MACH_H8300SXN:
6502 eh_addr_size = 2;
6503 break;
6504 case E_H8_MACH_H8300H:
6505 case E_H8_MACH_H8300S:
6506 case E_H8_MACH_H8300SX:
6507 eh_addr_size = 4;
6508 break;
6509 }
f4236fe4
DD
6510 break;
6511
ff7eeb89 6512 case EM_M32C_OLD:
f4236fe4 6513 case EM_M32C:
dda8d76d 6514 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6515 {
6516 case EF_M32C_CPU_M16C:
6517 eh_addr_size = 2;
6518 break;
6519 }
6520 break;
89fac5e3
RS
6521 }
6522
76ca31c0
NC
6523#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6524 do \
6525 { \
6526 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6527 if (section->sh_entsize != expected_entsize) \
9dd3a467 6528 { \
76ca31c0
NC
6529 char buf[40]; \
6530 sprintf_vma (buf, section->sh_entsize); \
6531 /* Note: coded this way so that there is a single string for \
6532 translation. */ \
6533 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6534 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6535 (unsigned) expected_entsize); \
9dd3a467 6536 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6537 } \
6538 } \
08d8fa11 6539 while (0)
9dd3a467
NC
6540
6541#define CHECK_ENTSIZE(section, i, type) \
1b513401 6542 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
6543 sizeof (Elf64_External_##type))
6544
dda8d76d
NC
6545 for (i = 0, section = filedata->section_headers;
6546 i < filedata->file_header.e_shnum;
b34976b6 6547 i++, section++)
252b5132 6548 {
b9e920ec 6549 char * name = SECTION_NAME_PRINT (section);
252b5132 6550
1b513401
NC
6551 /* Run some sanity checks on the headers and
6552 possibly fill in some file data as well. */
6553 switch (section->sh_type)
252b5132 6554 {
1b513401 6555 case SHT_DYNSYM:
978c4450 6556 if (filedata->dynamic_symbols != NULL)
252b5132
RH
6557 {
6558 error (_("File contains multiple dynamic symbol tables\n"));
6559 continue;
6560 }
6561
08d8fa11 6562 CHECK_ENTSIZE (section, i, Sym);
978c4450
AM
6563 filedata->dynamic_symbols
6564 = GET_ELF_SYMBOLS (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 6565 filedata->dynamic_symtab_section = section;
1b513401
NC
6566 break;
6567
6568 case SHT_STRTAB:
6569 if (streq (name, ".dynstr"))
252b5132 6570 {
1b513401
NC
6571 if (filedata->dynamic_strings != NULL)
6572 {
6573 error (_("File contains multiple dynamic string tables\n"));
6574 continue;
6575 }
6576
6577 filedata->dynamic_strings
6578 = (char *) get_data (NULL, filedata, section->sh_offset,
6579 1, section->sh_size, _("dynamic strings"));
6580 filedata->dynamic_strings_length
6581 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 6582 filedata->dynamic_strtab_section = section;
252b5132 6583 }
1b513401
NC
6584 break;
6585
6586 case SHT_SYMTAB_SHNDX:
6587 {
6588 elf_section_list * entry = xmalloc (sizeof * entry);
6589
6590 entry->hdr = section;
6591 entry->next = filedata->symtab_shndx_list;
6592 filedata->symtab_shndx_list = entry;
6593 }
6594 break;
6595
6596 case SHT_SYMTAB:
6597 CHECK_ENTSIZE (section, i, Sym);
6598 break;
6599
6600 case SHT_GROUP:
6601 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6602 break;
252b5132 6603
1b513401
NC
6604 case SHT_REL:
6605 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 6606 if (do_checks && section->sh_size == 0)
1b513401
NC
6607 warn (_("Section '%s': zero-sized relocation section\n"), name);
6608 break;
6609
6610 case SHT_RELA:
6611 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 6612 if (do_checks && section->sh_size == 0)
1b513401
NC
6613 warn (_("Section '%s': zero-sized relocation section\n"), name);
6614 break;
6615
6616 case SHT_NOTE:
6617 case SHT_PROGBITS:
546cb2d8
NC
6618 /* Having a zero sized section is not illegal according to the
6619 ELF standard, but it might be an indication that something
6620 is wrong. So issue a warning if we are running in lint mode. */
6621 if (do_checks && section->sh_size == 0)
1b513401
NC
6622 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
6623 break;
6624
6625 default:
6626 break;
6627 }
6628
6629 if ((do_debugging || do_debug_info || do_debug_abbrevs
6630 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
6631 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
6632 || do_debug_str || do_debug_str_offsets || do_debug_loc
6633 || do_debug_ranges
1b513401 6634 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
6635 && (startswith (name, ".debug_")
6636 || startswith (name, ".zdebug_")))
252b5132 6637 {
1b315056
CS
6638 if (name[1] == 'z')
6639 name += sizeof (".zdebug_") - 1;
6640 else
6641 name += sizeof (".debug_") - 1;
252b5132
RH
6642
6643 if (do_debugging
24d127aa
ML
6644 || (do_debug_info && startswith (name, "info"))
6645 || (do_debug_info && startswith (name, "types"))
6646 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 6647 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
6648 || (do_debug_lines && startswith (name, "line."))
6649 || (do_debug_pubnames && startswith (name, "pubnames"))
6650 || (do_debug_pubtypes && startswith (name, "pubtypes"))
6651 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
6652 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
6653 || (do_debug_aranges && startswith (name, "aranges"))
6654 || (do_debug_ranges && startswith (name, "ranges"))
6655 || (do_debug_ranges && startswith (name, "rnglists"))
6656 || (do_debug_frames && startswith (name, "frame"))
6657 || (do_debug_macinfo && startswith (name, "macinfo"))
6658 || (do_debug_macinfo && startswith (name, "macro"))
6659 || (do_debug_str && startswith (name, "str"))
6660 || (do_debug_links && startswith (name, "sup"))
6661 || (do_debug_str_offsets && startswith (name, "str_offsets"))
6662 || (do_debug_loc && startswith (name, "loc"))
6663 || (do_debug_loc && startswith (name, "loclists"))
6664 || (do_debug_addr && startswith (name, "addr"))
6665 || (do_debug_cu_index && startswith (name, "cu_index"))
6666 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 6667 )
6431e409 6668 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6669 }
a262ae96 6670 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6671 else if ((do_debugging || do_debug_info)
24d127aa 6672 && startswith (name, ".gnu.linkonce.wi."))
6431e409 6673 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6674 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6675 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6676 else if (do_gdb_index && (streq (name, ".gdb_index")
6677 || streq (name, ".debug_names")))
6431e409 6678 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6679 /* Trace sections for Itanium VMS. */
6680 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6681 || do_trace_aranges)
24d127aa 6682 && startswith (name, ".trace_"))
6f875884
TG
6683 {
6684 name += sizeof (".trace_") - 1;
6685
6686 if (do_debugging
6687 || (do_trace_info && streq (name, "info"))
6688 || (do_trace_abbrevs && streq (name, "abbrev"))
6689 || (do_trace_aranges && streq (name, "aranges"))
6690 )
6431e409 6691 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6692 }
dda8d76d 6693 else if ((do_debugging || do_debug_links)
24d127aa
ML
6694 && (startswith (name, ".gnu_debuglink")
6695 || startswith (name, ".gnu_debugaltlink")))
6431e409 6696 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6697 }
6698
6699 if (! do_sections)
015dc7e1 6700 return true;
252b5132 6701
ca0e11aa 6702 if (filedata->is_separate && ! process_links)
015dc7e1 6703 return true;
ca0e11aa
NC
6704
6705 if (filedata->is_separate)
6706 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
6707 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6708 printf (_("\nSection Headers:\n"));
6709 else
6710 printf (_("\nSection Header:\n"));
76da6bbe 6711
f7a99963 6712 if (is_32bit_elf)
595cf52e 6713 {
5477e8a0 6714 if (do_section_details)
595cf52e
L
6715 {
6716 printf (_(" [Nr] Name\n"));
5477e8a0 6717 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6718 }
6719 else
6720 printf
6721 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6722 }
d974e256 6723 else if (do_wide)
595cf52e 6724 {
5477e8a0 6725 if (do_section_details)
595cf52e
L
6726 {
6727 printf (_(" [Nr] Name\n"));
5477e8a0 6728 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6729 }
6730 else
6731 printf
6732 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6733 }
f7a99963
NC
6734 else
6735 {
5477e8a0 6736 if (do_section_details)
595cf52e
L
6737 {
6738 printf (_(" [Nr] Name\n"));
5477e8a0
L
6739 printf (_(" Type Address Offset Link\n"));
6740 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6741 }
6742 else
6743 {
6744 printf (_(" [Nr] Name Type Address Offset\n"));
6745 printf (_(" Size EntSize Flags Link Info Align\n"));
6746 }
f7a99963 6747 }
252b5132 6748
5477e8a0
L
6749 if (do_section_details)
6750 printf (_(" Flags\n"));
6751
dda8d76d
NC
6752 for (i = 0, section = filedata->section_headers;
6753 i < filedata->file_header.e_shnum;
b34976b6 6754 i++, section++)
252b5132 6755 {
dd905818
NC
6756 /* Run some sanity checks on the section header. */
6757
6758 /* Check the sh_link field. */
6759 switch (section->sh_type)
6760 {
285e3f99
AM
6761 case SHT_REL:
6762 case SHT_RELA:
6763 if (section->sh_link == 0
6764 && (filedata->file_header.e_type == ET_EXEC
6765 || filedata->file_header.e_type == ET_DYN))
6766 /* A dynamic relocation section where all entries use a
6767 zero symbol index need not specify a symtab section. */
6768 break;
6769 /* Fall through. */
dd905818
NC
6770 case SHT_SYMTAB_SHNDX:
6771 case SHT_GROUP:
6772 case SHT_HASH:
6773 case SHT_GNU_HASH:
6774 case SHT_GNU_versym:
285e3f99 6775 if (section->sh_link == 0
dda8d76d
NC
6776 || section->sh_link >= filedata->file_header.e_shnum
6777 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6778 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6779 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6780 i, section->sh_link);
6781 break;
6782
6783 case SHT_DYNAMIC:
6784 case SHT_SYMTAB:
6785 case SHT_DYNSYM:
6786 case SHT_GNU_verneed:
6787 case SHT_GNU_verdef:
6788 case SHT_GNU_LIBLIST:
285e3f99 6789 if (section->sh_link == 0
dda8d76d
NC
6790 || section->sh_link >= filedata->file_header.e_shnum
6791 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6792 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6793 i, section->sh_link);
6794 break;
6795
6796 case SHT_INIT_ARRAY:
6797 case SHT_FINI_ARRAY:
6798 case SHT_PREINIT_ARRAY:
6799 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6800 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6801 i, section->sh_link);
6802 break;
6803
6804 default:
6805 /* FIXME: Add support for target specific section types. */
6806#if 0 /* Currently we do not check other section types as there are too
6807 many special cases. Stab sections for example have a type
6808 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6809 section. */
6810 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6811 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6812 i, section->sh_link);
6813#endif
6814 break;
6815 }
6816
6817 /* Check the sh_info field. */
6818 switch (section->sh_type)
6819 {
6820 case SHT_REL:
6821 case SHT_RELA:
285e3f99
AM
6822 if (section->sh_info == 0
6823 && (filedata->file_header.e_type == ET_EXEC
6824 || filedata->file_header.e_type == ET_DYN))
6825 /* Dynamic relocations apply to segments, so they do not
6826 need to specify the section they relocate. */
6827 break;
6828 if (section->sh_info == 0
dda8d76d
NC
6829 || section->sh_info >= filedata->file_header.e_shnum
6830 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6831 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6832 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6833 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6834 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6835 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6836 /* FIXME: Are other section types valid ? */
dda8d76d 6837 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6838 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6839 i, section->sh_info);
dd905818
NC
6840 break;
6841
6842 case SHT_DYNAMIC:
6843 case SHT_HASH:
6844 case SHT_SYMTAB_SHNDX:
6845 case SHT_INIT_ARRAY:
6846 case SHT_FINI_ARRAY:
6847 case SHT_PREINIT_ARRAY:
6848 if (section->sh_info != 0)
6849 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6850 i, section->sh_info);
6851 break;
6852
6853 case SHT_GROUP:
6854 case SHT_SYMTAB:
6855 case SHT_DYNSYM:
6856 /* A symbol index - we assume that it is valid. */
6857 break;
6858
6859 default:
6860 /* FIXME: Add support for target specific section types. */
6861 if (section->sh_type == SHT_NOBITS)
6862 /* NOBITS section headers with non-zero sh_info fields can be
6863 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6864 information. The stripped sections have their headers
6865 preserved but their types set to SHT_NOBITS. So do not check
6866 this type of section. */
dd905818
NC
6867 ;
6868 else if (section->sh_flags & SHF_INFO_LINK)
6869 {
dda8d76d 6870 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6871 warn (_("[%2u]: Expected link to another section in info field"), i);
6872 }
a91e1603
L
6873 else if (section->sh_type < SHT_LOOS
6874 && (section->sh_flags & SHF_GNU_MBIND) == 0
6875 && section->sh_info != 0)
dd905818
NC
6876 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6877 i, section->sh_info);
6878 break;
6879 }
6880
3e6b6445 6881 /* Check the sh_size field. */
dda8d76d 6882 if (section->sh_size > filedata->file_size
3e6b6445
NC
6883 && section->sh_type != SHT_NOBITS
6884 && section->sh_type != SHT_NULL
6885 && section->sh_type < SHT_LOOS)
6886 warn (_("Size of section %u is larger than the entire file!\n"), i);
6887
7bfd842d 6888 printf (" [%2u] ", i);
5477e8a0 6889 if (do_section_details)
dda8d76d 6890 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6891 else
b9e920ec 6892 print_symbol (-17, SECTION_NAME_PRINT (section));
0b4362b0 6893
ea52a088 6894 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6895 get_section_type_name (filedata, section->sh_type));
0b4362b0 6896
f7a99963
NC
6897 if (is_32bit_elf)
6898 {
cfcac11d
NC
6899 const char * link_too_big = NULL;
6900
f7a99963 6901 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6902
f7a99963
NC
6903 printf ( " %6.6lx %6.6lx %2.2lx",
6904 (unsigned long) section->sh_offset,
6905 (unsigned long) section->sh_size,
6906 (unsigned long) section->sh_entsize);
d1133906 6907
5477e8a0
L
6908 if (do_section_details)
6909 fputs (" ", stdout);
6910 else
dda8d76d 6911 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6912
dda8d76d 6913 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6914 {
6915 link_too_big = "";
6916 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6917 an error but it can have special values in Solaris binaries. */
dda8d76d 6918 switch (filedata->file_header.e_machine)
cfcac11d 6919 {
caa83f8b 6920 case EM_386:
22abe556 6921 case EM_IAMCU:
caa83f8b 6922 case EM_X86_64:
7f502d6c 6923 case EM_L1OM:
7a9068fe 6924 case EM_K1OM:
cfcac11d
NC
6925 case EM_OLD_SPARCV9:
6926 case EM_SPARC32PLUS:
6927 case EM_SPARCV9:
6928 case EM_SPARC:
6929 if (section->sh_link == (SHN_BEFORE & 0xffff))
6930 link_too_big = "BEFORE";
6931 else if (section->sh_link == (SHN_AFTER & 0xffff))
6932 link_too_big = "AFTER";
6933 break;
6934 default:
6935 break;
6936 }
6937 }
6938
6939 if (do_section_details)
6940 {
6941 if (link_too_big != NULL && * link_too_big)
6942 printf ("<%s> ", link_too_big);
6943 else
6944 printf ("%2u ", section->sh_link);
6945 printf ("%3u %2lu\n", section->sh_info,
6946 (unsigned long) section->sh_addralign);
6947 }
6948 else
6949 printf ("%2u %3u %2lu\n",
6950 section->sh_link,
6951 section->sh_info,
6952 (unsigned long) section->sh_addralign);
6953
6954 if (link_too_big && ! * link_too_big)
6955 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6956 i, section->sh_link);
f7a99963 6957 }
d974e256
JJ
6958 else if (do_wide)
6959 {
6960 print_vma (section->sh_addr, LONG_HEX);
6961
6962 if ((long) section->sh_offset == section->sh_offset)
6963 printf (" %6.6lx", (unsigned long) section->sh_offset);
6964 else
6965 {
6966 putchar (' ');
6967 print_vma (section->sh_offset, LONG_HEX);
6968 }
6969
6970 if ((unsigned long) section->sh_size == section->sh_size)
6971 printf (" %6.6lx", (unsigned long) section->sh_size);
6972 else
6973 {
6974 putchar (' ');
6975 print_vma (section->sh_size, LONG_HEX);
6976 }
6977
6978 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6979 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6980 else
6981 {
6982 putchar (' ');
6983 print_vma (section->sh_entsize, LONG_HEX);
6984 }
6985
5477e8a0
L
6986 if (do_section_details)
6987 fputs (" ", stdout);
6988 else
dda8d76d 6989 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6990
72de5009 6991 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6992
6993 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6994 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6995 else
6996 {
6997 print_vma (section->sh_addralign, DEC);
6998 putchar ('\n');
6999 }
7000 }
5477e8a0 7001 else if (do_section_details)
595cf52e 7002 {
55cc53e9 7003 putchar (' ');
595cf52e
L
7004 print_vma (section->sh_addr, LONG_HEX);
7005 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7006 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7007 else
7008 {
7009 printf (" ");
7010 print_vma (section->sh_offset, LONG_HEX);
7011 }
72de5009 7012 printf (" %u\n ", section->sh_link);
595cf52e 7013 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7014 putchar (' ');
595cf52e
L
7015 print_vma (section->sh_entsize, LONG_HEX);
7016
72de5009
AM
7017 printf (" %-16u %lu\n",
7018 section->sh_info,
595cf52e
L
7019 (unsigned long) section->sh_addralign);
7020 }
f7a99963
NC
7021 else
7022 {
7023 putchar (' ');
7024 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7025 if ((long) section->sh_offset == section->sh_offset)
7026 printf (" %8.8lx", (unsigned long) section->sh_offset);
7027 else
7028 {
7029 printf (" ");
7030 print_vma (section->sh_offset, LONG_HEX);
7031 }
f7a99963
NC
7032 printf ("\n ");
7033 print_vma (section->sh_size, LONG_HEX);
7034 printf (" ");
7035 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7036
dda8d76d 7037 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7038
72de5009
AM
7039 printf (" %2u %3u %lu\n",
7040 section->sh_link,
7041 section->sh_info,
f7a99963
NC
7042 (unsigned long) section->sh_addralign);
7043 }
5477e8a0
L
7044
7045 if (do_section_details)
77115a4a 7046 {
dda8d76d 7047 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7048 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7049 {
7050 /* Minimum section size is 12 bytes for 32-bit compression
7051 header + 12 bytes for compressed data header. */
7052 unsigned char buf[24];
d8024a91 7053
77115a4a 7054 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7055 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7056 sizeof (buf), _("compression header")))
7057 {
7058 Elf_Internal_Chdr chdr;
d8024a91 7059
5844b465
NC
7060 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7061 printf (_(" [<corrupt>]\n"));
77115a4a 7062 else
5844b465
NC
7063 {
7064 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7065 printf (" ZLIB, ");
7066 else
7067 printf (_(" [<unknown>: 0x%x], "),
7068 chdr.ch_type);
7069 print_vma (chdr.ch_size, LONG_HEX);
7070 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7071 }
77115a4a
L
7072 }
7073 }
7074 }
252b5132
RH
7075 }
7076
5477e8a0 7077 if (!do_section_details)
3dbcc61d 7078 {
9fb71ee4
NC
7079 /* The ordering of the letters shown here matches the ordering of the
7080 corresponding SHF_xxx values, and hence the order in which these
7081 letters will be displayed to the user. */
7082 printf (_("Key to Flags:\n\
7083 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7084 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7085 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7086 switch (filedata->file_header.e_ident[EI_OSABI])
7087 {
7088 case ELFOSABI_GNU:
7089 case ELFOSABI_FREEBSD:
7090 printf (_("R (retain), "));
7091 /* Fall through */
7092 case ELFOSABI_NONE:
7093 printf (_("D (mbind), "));
7094 break;
7095 default:
7096 break;
7097 }
dda8d76d
NC
7098 if (filedata->file_header.e_machine == EM_X86_64
7099 || filedata->file_header.e_machine == EM_L1OM
7100 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7101 printf (_("l (large), "));
dda8d76d 7102 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7103 printf (_("y (purecode), "));
dda8d76d 7104 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7105 printf (_("v (VLE), "));
9fb71ee4 7106 printf ("p (processor specific)\n");
0b4362b0 7107 }
d1133906 7108
015dc7e1 7109 return true;
252b5132
RH
7110}
7111
015dc7e1 7112static bool
28d13567
AM
7113get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7114 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7115 char **strtab, unsigned long *strtablen)
7116{
7117 *strtab = NULL;
7118 *strtablen = 0;
7119 *symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms);
7120
7121 if (*symtab == NULL)
015dc7e1 7122 return false;
28d13567
AM
7123
7124 if (symsec->sh_link != 0)
7125 {
7126 Elf_Internal_Shdr *strsec;
7127
7128 if (symsec->sh_link >= filedata->file_header.e_shnum)
7129 {
7130 error (_("Bad sh_link in symbol table section\n"));
7131 free (*symtab);
7132 *symtab = NULL;
7133 *nsyms = 0;
015dc7e1 7134 return false;
28d13567
AM
7135 }
7136
7137 strsec = filedata->section_headers + symsec->sh_link;
7138
7139 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7140 1, strsec->sh_size, _("string table"));
7141 if (*strtab == NULL)
7142 {
7143 free (*symtab);
7144 *symtab = NULL;
7145 *nsyms = 0;
015dc7e1 7146 return false;
28d13567
AM
7147 }
7148 *strtablen = strsec->sh_size;
7149 }
015dc7e1 7150 return true;
28d13567
AM
7151}
7152
f5842774
L
7153static const char *
7154get_group_flags (unsigned int flags)
7155{
1449284b 7156 static char buff[128];
220453ec 7157
6d913794
NC
7158 if (flags == 0)
7159 return "";
7160 else if (flags == GRP_COMDAT)
7161 return "COMDAT ";
f5842774 7162
89246a0e
AM
7163 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7164 flags,
7165 flags & GRP_MASKOS ? _("<OS specific>") : "",
7166 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7167 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7168 ? _("<unknown>") : ""));
6d913794 7169
f5842774
L
7170 return buff;
7171}
7172
015dc7e1 7173static bool
dda8d76d 7174process_section_groups (Filedata * filedata)
f5842774 7175{
2cf0635d 7176 Elf_Internal_Shdr * section;
f5842774 7177 unsigned int i;
2cf0635d
NC
7178 struct group * group;
7179 Elf_Internal_Shdr * symtab_sec;
7180 Elf_Internal_Shdr * strtab_sec;
7181 Elf_Internal_Sym * symtab;
ba5cdace 7182 unsigned long num_syms;
2cf0635d 7183 char * strtab;
c256ffe7 7184 size_t strtab_size;
d1f5c6e3
L
7185
7186 /* Don't process section groups unless needed. */
7187 if (!do_unwind && !do_section_groups)
015dc7e1 7188 return true;
f5842774 7189
dda8d76d 7190 if (filedata->file_header.e_shnum == 0)
f5842774
L
7191 {
7192 if (do_section_groups)
ca0e11aa
NC
7193 {
7194 if (filedata->is_separate)
7195 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7196 filedata->file_name);
7197 else
7198 printf (_("\nThere are no section groups in this file.\n"));
7199 }
015dc7e1 7200 return true;
f5842774
L
7201 }
7202
dda8d76d 7203 if (filedata->section_headers == NULL)
f5842774
L
7204 {
7205 error (_("Section headers are not available!\n"));
fa1908fd 7206 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7207 return false;
f5842774
L
7208 }
7209
978c4450
AM
7210 filedata->section_headers_groups
7211 = (struct group **) calloc (filedata->file_header.e_shnum,
7212 sizeof (struct group *));
e4b17d5c 7213
978c4450 7214 if (filedata->section_headers_groups == NULL)
e4b17d5c 7215 {
8b73c356 7216 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7217 filedata->file_header.e_shnum);
015dc7e1 7218 return false;
e4b17d5c
L
7219 }
7220
f5842774 7221 /* Scan the sections for the group section. */
978c4450 7222 filedata->group_count = 0;
dda8d76d
NC
7223 for (i = 0, section = filedata->section_headers;
7224 i < filedata->file_header.e_shnum;
f5842774 7225 i++, section++)
e4b17d5c 7226 if (section->sh_type == SHT_GROUP)
978c4450 7227 filedata->group_count++;
e4b17d5c 7228
978c4450 7229 if (filedata->group_count == 0)
d1f5c6e3
L
7230 {
7231 if (do_section_groups)
ca0e11aa
NC
7232 {
7233 if (filedata->is_separate)
7234 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7235 filedata->file_name);
7236 else
7237 printf (_("\nThere are no section groups in this file.\n"));
7238 }
d1f5c6e3 7239
015dc7e1 7240 return true;
d1f5c6e3
L
7241 }
7242
978c4450
AM
7243 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7244 sizeof (struct group));
e4b17d5c 7245
978c4450 7246 if (filedata->section_groups == NULL)
e4b17d5c 7247 {
8b73c356 7248 error (_("Out of memory reading %lu groups\n"),
978c4450 7249 (unsigned long) filedata->group_count);
015dc7e1 7250 return false;
e4b17d5c
L
7251 }
7252
d1f5c6e3
L
7253 symtab_sec = NULL;
7254 strtab_sec = NULL;
7255 symtab = NULL;
ba5cdace 7256 num_syms = 0;
d1f5c6e3 7257 strtab = NULL;
c256ffe7 7258 strtab_size = 0;
ca0e11aa
NC
7259
7260 if (filedata->is_separate)
7261 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7262
978c4450 7263 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7264 i < filedata->file_header.e_shnum;
e4b17d5c 7265 i++, section++)
f5842774
L
7266 {
7267 if (section->sh_type == SHT_GROUP)
7268 {
dda8d76d 7269 const char * name = printable_section_name (filedata, section);
74e1a04b 7270 const char * group_name;
2cf0635d
NC
7271 unsigned char * start;
7272 unsigned char * indices;
f5842774 7273 unsigned int entry, j, size;
2cf0635d
NC
7274 Elf_Internal_Shdr * sec;
7275 Elf_Internal_Sym * sym;
f5842774
L
7276
7277 /* Get the symbol table. */
dda8d76d
NC
7278 if (section->sh_link >= filedata->file_header.e_shnum
7279 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7280 != SHT_SYMTAB))
f5842774
L
7281 {
7282 error (_("Bad sh_link in group section `%s'\n"), name);
7283 continue;
7284 }
d1f5c6e3
L
7285
7286 if (symtab_sec != sec)
7287 {
7288 symtab_sec = sec;
9db70fc3 7289 free (symtab);
dda8d76d 7290 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 7291 }
f5842774 7292
dd24e3da
NC
7293 if (symtab == NULL)
7294 {
7295 error (_("Corrupt header in group section `%s'\n"), name);
7296 continue;
7297 }
7298
ba5cdace
NC
7299 if (section->sh_info >= num_syms)
7300 {
7301 error (_("Bad sh_info in group section `%s'\n"), name);
7302 continue;
7303 }
7304
f5842774
L
7305 sym = symtab + section->sh_info;
7306
7307 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7308 {
4fbb74a6 7309 if (sym->st_shndx == 0
dda8d76d 7310 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7311 {
7312 error (_("Bad sh_info in group section `%s'\n"), name);
7313 continue;
7314 }
ba2685cc 7315
b9e920ec
AM
7316 group_name = SECTION_NAME_PRINT (filedata->section_headers
7317 + sym->st_shndx);
c256ffe7 7318 strtab_sec = NULL;
9db70fc3 7319 free (strtab);
f5842774 7320 strtab = NULL;
c256ffe7 7321 strtab_size = 0;
f5842774
L
7322 }
7323 else
7324 {
7325 /* Get the string table. */
dda8d76d 7326 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7327 {
7328 strtab_sec = NULL;
9db70fc3 7329 free (strtab);
c256ffe7
JJ
7330 strtab = NULL;
7331 strtab_size = 0;
7332 }
7333 else if (strtab_sec
dda8d76d 7334 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7335 {
7336 strtab_sec = sec;
9db70fc3 7337 free (strtab);
071436c6 7338
dda8d76d 7339 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7340 1, strtab_sec->sh_size,
7341 _("string table"));
c256ffe7 7342 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7343 }
c256ffe7 7344 group_name = sym->st_name < strtab_size
2b692964 7345 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7346 }
7347
c9c1d674
EG
7348 /* PR 17531: file: loop. */
7349 if (section->sh_entsize > section->sh_size)
7350 {
7351 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7352 printable_section_name (filedata, section),
8066deb1
AM
7353 (unsigned long) section->sh_entsize,
7354 (unsigned long) section->sh_size);
61dd8e19 7355 continue;
c9c1d674
EG
7356 }
7357
dda8d76d 7358 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7359 1, section->sh_size,
7360 _("section data"));
59245841
NC
7361 if (start == NULL)
7362 continue;
f5842774
L
7363
7364 indices = start;
7365 size = (section->sh_size / section->sh_entsize) - 1;
7366 entry = byte_get (indices, 4);
7367 indices += 4;
e4b17d5c
L
7368
7369 if (do_section_groups)
7370 {
2b692964 7371 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7372 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7373
e4b17d5c
L
7374 printf (_(" [Index] Name\n"));
7375 }
7376
7377 group->group_index = i;
7378
f5842774
L
7379 for (j = 0; j < size; j++)
7380 {
2cf0635d 7381 struct group_list * g;
e4b17d5c 7382
f5842774
L
7383 entry = byte_get (indices, 4);
7384 indices += 4;
7385
dda8d76d 7386 if (entry >= filedata->file_header.e_shnum)
391cb864 7387 {
57028622
NC
7388 static unsigned num_group_errors = 0;
7389
7390 if (num_group_errors ++ < 10)
7391 {
7392 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7393 entry, i, filedata->file_header.e_shnum - 1);
57028622 7394 if (num_group_errors == 10)
67ce483b 7395 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7396 }
391cb864
L
7397 continue;
7398 }
391cb864 7399
978c4450 7400 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7401 {
d1f5c6e3
L
7402 if (entry)
7403 {
57028622
NC
7404 static unsigned num_errs = 0;
7405
7406 if (num_errs ++ < 10)
7407 {
7408 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7409 entry, i,
978c4450 7410 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7411 if (num_errs == 10)
7412 warn (_("Further error messages about already contained group sections suppressed\n"));
7413 }
d1f5c6e3
L
7414 continue;
7415 }
7416 else
7417 {
7418 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7419 section group. We just warn it the first time
d1f5c6e3 7420 and ignore it afterwards. */
015dc7e1 7421 static bool warned = false;
d1f5c6e3
L
7422 if (!warned)
7423 {
7424 error (_("section 0 in group section [%5u]\n"),
978c4450 7425 filedata->section_headers_groups [entry]->group_index);
015dc7e1 7426 warned = true;
d1f5c6e3
L
7427 }
7428 }
e4b17d5c
L
7429 }
7430
978c4450 7431 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7432
7433 if (do_section_groups)
7434 {
dda8d76d
NC
7435 sec = filedata->section_headers + entry;
7436 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7437 }
7438
3f5e193b 7439 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7440 g->section_index = entry;
7441 g->next = group->root;
7442 group->root = g;
f5842774
L
7443 }
7444
9db70fc3 7445 free (start);
e4b17d5c
L
7446
7447 group++;
f5842774
L
7448 }
7449 }
7450
9db70fc3
AM
7451 free (symtab);
7452 free (strtab);
015dc7e1 7453 return true;
f5842774
L
7454}
7455
28f997cf
TG
7456/* Data used to display dynamic fixups. */
7457
7458struct ia64_vms_dynfixup
7459{
7460 bfd_vma needed_ident; /* Library ident number. */
7461 bfd_vma needed; /* Index in the dstrtab of the library name. */
7462 bfd_vma fixup_needed; /* Index of the library. */
7463 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7464 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7465};
7466
7467/* Data used to display dynamic relocations. */
7468
7469struct ia64_vms_dynimgrela
7470{
7471 bfd_vma img_rela_cnt; /* Number of relocations. */
7472 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7473};
7474
7475/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7476 library). */
7477
015dc7e1 7478static bool
dda8d76d
NC
7479dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7480 struct ia64_vms_dynfixup * fixup,
7481 const char * strtab,
7482 unsigned int strtab_sz)
28f997cf 7483{
32ec8896 7484 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7485 long i;
32ec8896 7486 const char * lib_name;
28f997cf 7487
978c4450
AM
7488 imfs = get_data (NULL, filedata,
7489 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7490 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7491 _("dynamic section image fixups"));
7492 if (!imfs)
015dc7e1 7493 return false;
28f997cf
TG
7494
7495 if (fixup->needed < strtab_sz)
7496 lib_name = strtab + fixup->needed;
7497 else
7498 {
32ec8896 7499 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7500 (unsigned long) fixup->needed);
28f997cf
TG
7501 lib_name = "???";
7502 }
736990c4 7503
28f997cf
TG
7504 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7505 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7506 printf
7507 (_("Seg Offset Type SymVec DataType\n"));
7508
7509 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7510 {
7511 unsigned int type;
7512 const char *rtype;
7513
7514 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7515 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7516 type = BYTE_GET (imfs [i].type);
7517 rtype = elf_ia64_reloc_type (type);
7518 if (rtype == NULL)
7519 printf (" 0x%08x ", type);
7520 else
7521 printf (" %-32s ", rtype);
7522 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7523 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7524 }
7525
7526 free (imfs);
015dc7e1 7527 return true;
28f997cf
TG
7528}
7529
7530/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7531
015dc7e1 7532static bool
dda8d76d 7533dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7534{
7535 Elf64_External_VMS_IMAGE_RELA *imrs;
7536 long i;
7537
978c4450
AM
7538 imrs = get_data (NULL, filedata,
7539 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 7540 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7541 _("dynamic section image relocations"));
28f997cf 7542 if (!imrs)
015dc7e1 7543 return false;
28f997cf
TG
7544
7545 printf (_("\nImage relocs\n"));
7546 printf
7547 (_("Seg Offset Type Addend Seg Sym Off\n"));
7548
7549 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7550 {
7551 unsigned int type;
7552 const char *rtype;
7553
7554 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7555 printf ("%08" BFD_VMA_FMT "x ",
7556 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7557 type = BYTE_GET (imrs [i].type);
7558 rtype = elf_ia64_reloc_type (type);
7559 if (rtype == NULL)
7560 printf ("0x%08x ", type);
7561 else
7562 printf ("%-31s ", rtype);
7563 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7564 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7565 printf ("%08" BFD_VMA_FMT "x\n",
7566 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7567 }
7568
7569 free (imrs);
015dc7e1 7570 return true;
28f997cf
TG
7571}
7572
7573/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7574
015dc7e1 7575static bool
dda8d76d 7576process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7577{
7578 struct ia64_vms_dynfixup fixup;
7579 struct ia64_vms_dynimgrela imgrela;
7580 Elf_Internal_Dyn *entry;
28f997cf
TG
7581 bfd_vma strtab_off = 0;
7582 bfd_vma strtab_sz = 0;
7583 char *strtab = NULL;
015dc7e1 7584 bool res = true;
28f997cf
TG
7585
7586 memset (&fixup, 0, sizeof (fixup));
7587 memset (&imgrela, 0, sizeof (imgrela));
7588
7589 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
7590 for (entry = filedata->dynamic_section;
7591 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
7592 entry++)
7593 {
7594 switch (entry->d_tag)
7595 {
7596 case DT_IA_64_VMS_STRTAB_OFFSET:
7597 strtab_off = entry->d_un.d_val;
7598 break;
7599 case DT_STRSZ:
7600 strtab_sz = entry->d_un.d_val;
7601 if (strtab == NULL)
978c4450
AM
7602 strtab = get_data (NULL, filedata,
7603 filedata->dynamic_addr + strtab_off,
28f997cf 7604 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7605 if (strtab == NULL)
7606 strtab_sz = 0;
28f997cf
TG
7607 break;
7608
7609 case DT_IA_64_VMS_NEEDED_IDENT:
7610 fixup.needed_ident = entry->d_un.d_val;
7611 break;
7612 case DT_NEEDED:
7613 fixup.needed = entry->d_un.d_val;
7614 break;
7615 case DT_IA_64_VMS_FIXUP_NEEDED:
7616 fixup.fixup_needed = entry->d_un.d_val;
7617 break;
7618 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7619 fixup.fixup_rela_cnt = entry->d_un.d_val;
7620 break;
7621 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7622 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7623 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 7624 res = false;
28f997cf 7625 break;
28f997cf
TG
7626 case DT_IA_64_VMS_IMG_RELA_CNT:
7627 imgrela.img_rela_cnt = entry->d_un.d_val;
7628 break;
7629 case DT_IA_64_VMS_IMG_RELA_OFF:
7630 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7631 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 7632 res = false;
28f997cf
TG
7633 break;
7634
7635 default:
7636 break;
7637 }
7638 }
7639
9db70fc3 7640 free (strtab);
28f997cf
TG
7641
7642 return res;
7643}
7644
85b1c36d 7645static struct
566b0d53 7646{
2cf0635d 7647 const char * name;
566b0d53
L
7648 int reloc;
7649 int size;
7650 int rela;
32ec8896
NC
7651}
7652 dynamic_relocations [] =
566b0d53 7653{
015dc7e1
AM
7654 { "REL", DT_REL, DT_RELSZ, false },
7655 { "RELA", DT_RELA, DT_RELASZ, true },
32ec8896 7656 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7657};
7658
252b5132 7659/* Process the reloc section. */
18bd398b 7660
015dc7e1 7661static bool
dda8d76d 7662process_relocs (Filedata * filedata)
252b5132 7663{
b34976b6
AM
7664 unsigned long rel_size;
7665 unsigned long rel_offset;
252b5132 7666
252b5132 7667 if (!do_reloc)
015dc7e1 7668 return true;
252b5132
RH
7669
7670 if (do_using_dynamic)
7671 {
32ec8896 7672 int is_rela;
2cf0635d 7673 const char * name;
015dc7e1 7674 bool has_dynamic_reloc;
566b0d53 7675 unsigned int i;
0de14b54 7676
015dc7e1 7677 has_dynamic_reloc = false;
252b5132 7678
566b0d53 7679 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7680 {
566b0d53
L
7681 is_rela = dynamic_relocations [i].rela;
7682 name = dynamic_relocations [i].name;
978c4450
AM
7683 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
7684 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 7685
32ec8896 7686 if (rel_size)
015dc7e1 7687 has_dynamic_reloc = true;
566b0d53
L
7688
7689 if (is_rela == UNKNOWN)
aa903cfb 7690 {
566b0d53 7691 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 7692 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
7693 {
7694 case DT_REL:
015dc7e1 7695 is_rela = false;
566b0d53
L
7696 break;
7697 case DT_RELA:
015dc7e1 7698 is_rela = true;
566b0d53
L
7699 break;
7700 }
aa903cfb 7701 }
252b5132 7702
566b0d53
L
7703 if (rel_size)
7704 {
ca0e11aa
NC
7705 if (filedata->is_separate)
7706 printf
7707 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
7708 filedata->file_name, name, rel_offset, rel_size);
7709 else
7710 printf
7711 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7712 name, rel_offset, rel_size);
252b5132 7713
dda8d76d
NC
7714 dump_relocations (filedata,
7715 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7716 rel_size,
978c4450
AM
7717 filedata->dynamic_symbols,
7718 filedata->num_dynamic_syms,
7719 filedata->dynamic_strings,
7720 filedata->dynamic_strings_length,
015dc7e1 7721 is_rela, true /* is_dynamic */);
566b0d53 7722 }
252b5132 7723 }
566b0d53 7724
dda8d76d
NC
7725 if (is_ia64_vms (filedata))
7726 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 7727 has_dynamic_reloc = true;
28f997cf 7728
566b0d53 7729 if (! has_dynamic_reloc)
ca0e11aa
NC
7730 {
7731 if (filedata->is_separate)
7732 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
7733 filedata->file_name);
7734 else
7735 printf (_("\nThere are no dynamic relocations in this file.\n"));
7736 }
252b5132
RH
7737 }
7738 else
7739 {
2cf0635d 7740 Elf_Internal_Shdr * section;
b34976b6 7741 unsigned long i;
015dc7e1 7742 bool found = false;
252b5132 7743
dda8d76d
NC
7744 for (i = 0, section = filedata->section_headers;
7745 i < filedata->file_header.e_shnum;
b34976b6 7746 i++, section++)
252b5132
RH
7747 {
7748 if ( section->sh_type != SHT_RELA
7749 && section->sh_type != SHT_REL)
7750 continue;
7751
7752 rel_offset = section->sh_offset;
7753 rel_size = section->sh_size;
7754
7755 if (rel_size)
7756 {
b34976b6 7757 int is_rela;
d3a49aa8 7758 unsigned long num_rela;
103f02d3 7759
ca0e11aa
NC
7760 if (filedata->is_separate)
7761 printf (_("\nIn linked file '%s' relocation section "),
7762 filedata->file_name);
7763 else
7764 printf (_("\nRelocation section "));
252b5132 7765
dda8d76d 7766 if (filedata->string_table == NULL)
19936277 7767 printf ("%d", section->sh_name);
252b5132 7768 else
dda8d76d 7769 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7770
d3a49aa8
AM
7771 num_rela = rel_size / section->sh_entsize;
7772 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7773 " at offset 0x%lx contains %lu entries:\n",
7774 num_rela),
7775 rel_offset, num_rela);
252b5132 7776
d79b3d50
NC
7777 is_rela = section->sh_type == SHT_RELA;
7778
4fbb74a6 7779 if (section->sh_link != 0
dda8d76d 7780 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7781 {
2cf0635d
NC
7782 Elf_Internal_Shdr * symsec;
7783 Elf_Internal_Sym * symtab;
d79b3d50 7784 unsigned long nsyms;
c256ffe7 7785 unsigned long strtablen = 0;
2cf0635d 7786 char * strtab = NULL;
57346661 7787
dda8d76d 7788 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7789 if (symsec->sh_type != SHT_SYMTAB
7790 && symsec->sh_type != SHT_DYNSYM)
7791 continue;
7792
28d13567
AM
7793 if (!get_symtab (filedata, symsec,
7794 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7795 continue;
252b5132 7796
dda8d76d 7797 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7798 symtab, nsyms, strtab, strtablen,
7799 is_rela,
7800 symsec->sh_type == SHT_DYNSYM);
9db70fc3 7801 free (strtab);
d79b3d50
NC
7802 free (symtab);
7803 }
7804 else
dda8d76d 7805 dump_relocations (filedata, rel_offset, rel_size,
32ec8896 7806 NULL, 0, NULL, 0, is_rela,
015dc7e1 7807 false /* is_dynamic */);
252b5132 7808
015dc7e1 7809 found = true;
252b5132
RH
7810 }
7811 }
7812
7813 if (! found)
45ac8f4f
NC
7814 {
7815 /* Users sometimes forget the -D option, so try to be helpful. */
7816 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7817 {
978c4450 7818 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 7819 {
ca0e11aa
NC
7820 if (filedata->is_separate)
7821 printf (_("\nThere are no static relocations in linked file '%s'."),
7822 filedata->file_name);
7823 else
7824 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
7825 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7826
7827 break;
7828 }
7829 }
7830 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
7831 {
7832 if (filedata->is_separate)
7833 printf (_("\nThere are no relocations in linked file '%s'.\n"),
7834 filedata->file_name);
7835 else
7836 printf (_("\nThere are no relocations in this file.\n"));
7837 }
45ac8f4f 7838 }
252b5132
RH
7839 }
7840
015dc7e1 7841 return true;
252b5132
RH
7842}
7843
4d6ed7c8
NC
7844/* An absolute address consists of a section and an offset. If the
7845 section is NULL, the offset itself is the address, otherwise, the
7846 address equals to LOAD_ADDRESS(section) + offset. */
7847
7848struct absaddr
948f632f
DA
7849{
7850 unsigned short section;
7851 bfd_vma offset;
7852};
4d6ed7c8 7853
948f632f
DA
7854/* Find the nearest symbol at or below ADDR. Returns the symbol
7855 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7856
4d6ed7c8 7857static void
dda8d76d
NC
7858find_symbol_for_address (Filedata * filedata,
7859 Elf_Internal_Sym * symtab,
7860 unsigned long nsyms,
7861 const char * strtab,
7862 unsigned long strtab_size,
7863 struct absaddr addr,
7864 const char ** symname,
7865 bfd_vma * offset)
4d6ed7c8 7866{
d3ba0551 7867 bfd_vma dist = 0x100000;
2cf0635d 7868 Elf_Internal_Sym * sym;
948f632f
DA
7869 Elf_Internal_Sym * beg;
7870 Elf_Internal_Sym * end;
2cf0635d 7871 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7872
0b6ae522 7873 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7874 beg = symtab;
7875 end = symtab + nsyms;
0b6ae522 7876
948f632f 7877 while (beg < end)
4d6ed7c8 7878 {
948f632f
DA
7879 bfd_vma value;
7880
7881 sym = beg + (end - beg) / 2;
0b6ae522 7882
948f632f 7883 value = sym->st_value;
0b6ae522
DJ
7884 REMOVE_ARCH_BITS (value);
7885
948f632f 7886 if (sym->st_name != 0
4d6ed7c8 7887 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7888 && addr.offset >= value
7889 && addr.offset - value < dist)
4d6ed7c8
NC
7890 {
7891 best = sym;
0b6ae522 7892 dist = addr.offset - value;
4d6ed7c8
NC
7893 if (!dist)
7894 break;
7895 }
948f632f
DA
7896
7897 if (addr.offset < value)
7898 end = sym;
7899 else
7900 beg = sym + 1;
4d6ed7c8 7901 }
1b31d05e 7902
4d6ed7c8
NC
7903 if (best)
7904 {
57346661 7905 *symname = (best->st_name >= strtab_size
2b692964 7906 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7907 *offset = dist;
7908 return;
7909 }
1b31d05e 7910
4d6ed7c8
NC
7911 *symname = NULL;
7912 *offset = addr.offset;
7913}
7914
32ec8896 7915static /* signed */ int
948f632f
DA
7916symcmp (const void *p, const void *q)
7917{
7918 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7919 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7920
7921 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7922}
7923
7924/* Process the unwind section. */
7925
7926#include "unwind-ia64.h"
7927
7928struct ia64_unw_table_entry
7929{
7930 struct absaddr start;
7931 struct absaddr end;
7932 struct absaddr info;
7933};
7934
7935struct ia64_unw_aux_info
7936{
32ec8896
NC
7937 struct ia64_unw_table_entry * table; /* Unwind table. */
7938 unsigned long table_len; /* Length of unwind table. */
7939 unsigned char * info; /* Unwind info. */
7940 unsigned long info_size; /* Size of unwind info. */
7941 bfd_vma info_addr; /* Starting address of unwind info. */
7942 bfd_vma seg_base; /* Starting address of segment. */
7943 Elf_Internal_Sym * symtab; /* The symbol table. */
7944 unsigned long nsyms; /* Number of symbols. */
7945 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7946 unsigned long nfuns; /* Number of entries in funtab. */
7947 char * strtab; /* The string table. */
7948 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7949};
7950
015dc7e1 7951static bool
dda8d76d 7952dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7953{
2cf0635d 7954 struct ia64_unw_table_entry * tp;
948f632f 7955 unsigned long j, nfuns;
4d6ed7c8 7956 int in_body;
015dc7e1 7957 bool res = true;
7036c0e1 7958
948f632f
DA
7959 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7960 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7961 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7962 aux->funtab[nfuns++] = aux->symtab[j];
7963 aux->nfuns = nfuns;
7964 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7965
4d6ed7c8
NC
7966 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7967 {
7968 bfd_vma stamp;
7969 bfd_vma offset;
2cf0635d
NC
7970 const unsigned char * dp;
7971 const unsigned char * head;
53774b7e 7972 const unsigned char * end;
2cf0635d 7973 const char * procname;
4d6ed7c8 7974
dda8d76d 7975 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7976 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7977
7978 fputs ("\n<", stdout);
7979
7980 if (procname)
7981 {
7982 fputs (procname, stdout);
7983
7984 if (offset)
7985 printf ("+%lx", (unsigned long) offset);
7986 }
7987
7988 fputs (">: [", stdout);
7989 print_vma (tp->start.offset, PREFIX_HEX);
7990 fputc ('-', stdout);
7991 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7992 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7993 (unsigned long) (tp->info.offset - aux->seg_base));
7994
53774b7e
NC
7995 /* PR 17531: file: 86232b32. */
7996 if (aux->info == NULL)
7997 continue;
7998
97c0a079
AM
7999 offset = tp->info.offset;
8000 if (tp->info.section)
8001 {
8002 if (tp->info.section >= filedata->file_header.e_shnum)
8003 {
8004 warn (_("Invalid section %u in table entry %ld\n"),
8005 tp->info.section, (long) (tp - aux->table));
015dc7e1 8006 res = false;
97c0a079
AM
8007 continue;
8008 }
8009 offset += filedata->section_headers[tp->info.section].sh_addr;
8010 }
8011 offset -= aux->info_addr;
53774b7e 8012 /* PR 17531: file: 0997b4d1. */
90679903
AM
8013 if (offset >= aux->info_size
8014 || aux->info_size - offset < 8)
53774b7e
NC
8015 {
8016 warn (_("Invalid offset %lx in table entry %ld\n"),
8017 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8018 res = false;
53774b7e
NC
8019 continue;
8020 }
8021
97c0a079 8022 head = aux->info + offset;
a4a00738 8023 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8024
86f55779 8025 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8026 (unsigned) UNW_VER (stamp),
8027 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8028 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8029 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8030 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8031
8032 if (UNW_VER (stamp) != 1)
8033 {
2b692964 8034 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8035 continue;
8036 }
8037
8038 in_body = 0;
53774b7e
NC
8039 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8040 /* PR 17531: file: 16ceda89. */
8041 if (end > aux->info + aux->info_size)
8042 end = aux->info + aux->info_size;
8043 for (dp = head + 8; dp < end;)
b4477bc8 8044 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8045 }
948f632f
DA
8046
8047 free (aux->funtab);
32ec8896
NC
8048
8049 return res;
4d6ed7c8
NC
8050}
8051
015dc7e1 8052static bool
dda8d76d
NC
8053slurp_ia64_unwind_table (Filedata * filedata,
8054 struct ia64_unw_aux_info * aux,
8055 Elf_Internal_Shdr * sec)
4d6ed7c8 8056{
89fac5e3 8057 unsigned long size, nrelas, i;
2cf0635d
NC
8058 Elf_Internal_Phdr * seg;
8059 struct ia64_unw_table_entry * tep;
8060 Elf_Internal_Shdr * relsec;
8061 Elf_Internal_Rela * rela;
8062 Elf_Internal_Rela * rp;
8063 unsigned char * table;
8064 unsigned char * tp;
8065 Elf_Internal_Sym * sym;
8066 const char * relname;
4d6ed7c8 8067
53774b7e
NC
8068 aux->table_len = 0;
8069
4d6ed7c8
NC
8070 /* First, find the starting address of the segment that includes
8071 this section: */
8072
dda8d76d 8073 if (filedata->file_header.e_phnum)
4d6ed7c8 8074 {
dda8d76d 8075 if (! get_program_headers (filedata))
015dc7e1 8076 return false;
4d6ed7c8 8077
dda8d76d
NC
8078 for (seg = filedata->program_headers;
8079 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8080 ++seg)
4d6ed7c8
NC
8081 {
8082 if (seg->p_type != PT_LOAD)
8083 continue;
8084
8085 if (sec->sh_addr >= seg->p_vaddr
8086 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8087 {
8088 aux->seg_base = seg->p_vaddr;
8089 break;
8090 }
8091 }
4d6ed7c8
NC
8092 }
8093
8094 /* Second, build the unwind table from the contents of the unwind section: */
8095 size = sec->sh_size;
dda8d76d 8096 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8097 _("unwind table"));
a6e9f9df 8098 if (!table)
015dc7e1 8099 return false;
4d6ed7c8 8100
53774b7e 8101 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8102 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8103 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8104 tep = aux->table;
53774b7e
NC
8105
8106 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8107 {
8108 tep->start.section = SHN_UNDEF;
8109 tep->end.section = SHN_UNDEF;
8110 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8111 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8112 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8113 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8114 tep->start.offset += aux->seg_base;
8115 tep->end.offset += aux->seg_base;
8116 tep->info.offset += aux->seg_base;
8117 }
8118 free (table);
8119
41e92641 8120 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8121 for (relsec = filedata->section_headers;
8122 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8123 ++relsec)
8124 {
8125 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8126 || relsec->sh_info >= filedata->file_header.e_shnum
8127 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8128 continue;
8129
dda8d76d 8130 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8131 & rela, & nrelas))
53774b7e
NC
8132 {
8133 free (aux->table);
8134 aux->table = NULL;
8135 aux->table_len = 0;
015dc7e1 8136 return false;
53774b7e 8137 }
4d6ed7c8
NC
8138
8139 for (rp = rela; rp < rela + nrelas; ++rp)
8140 {
4770fb94 8141 unsigned int sym_ndx;
726bd37d
AM
8142 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8143 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8144
82b1b41b
NC
8145 /* PR 17531: file: 9fa67536. */
8146 if (relname == NULL)
8147 {
726bd37d 8148 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8149 continue;
8150 }
948f632f 8151
24d127aa 8152 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8153 {
82b1b41b 8154 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8155 continue;
8156 }
8157
89fac5e3 8158 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8159
53774b7e
NC
8160 /* PR 17531: file: 5bc8d9bf. */
8161 if (i >= aux->table_len)
8162 {
8163 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8164 continue;
8165 }
8166
4770fb94
AM
8167 sym_ndx = get_reloc_symindex (rp->r_info);
8168 if (sym_ndx >= aux->nsyms)
8169 {
8170 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8171 sym_ndx);
8172 continue;
8173 }
8174 sym = aux->symtab + sym_ndx;
8175
53774b7e 8176 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8177 {
8178 case 0:
8179 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8180 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8181 break;
8182 case 1:
8183 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8184 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8185 break;
8186 case 2:
8187 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8188 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8189 break;
8190 default:
8191 break;
8192 }
8193 }
8194
8195 free (rela);
8196 }
8197
015dc7e1 8198 return true;
4d6ed7c8
NC
8199}
8200
015dc7e1 8201static bool
dda8d76d 8202ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8203{
2cf0635d
NC
8204 Elf_Internal_Shdr * sec;
8205 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8206 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8207 struct ia64_unw_aux_info aux;
015dc7e1 8208 bool res = true;
f1467e33 8209
4d6ed7c8
NC
8210 memset (& aux, 0, sizeof (aux));
8211
dda8d76d 8212 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8213 {
28d13567 8214 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8215 {
28d13567 8216 if (aux.symtab)
4082ef84 8217 {
28d13567
AM
8218 error (_("Multiple symbol tables encountered\n"));
8219 free (aux.symtab);
8220 aux.symtab = NULL;
4082ef84 8221 free (aux.strtab);
28d13567 8222 aux.strtab = NULL;
4082ef84 8223 }
28d13567
AM
8224 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8225 &aux.strtab, &aux.strtab_size))
015dc7e1 8226 return false;
4d6ed7c8
NC
8227 }
8228 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8229 unwcount++;
8230 }
8231
8232 if (!unwcount)
8233 printf (_("\nThere are no unwind sections in this file.\n"));
8234
8235 while (unwcount-- > 0)
8236 {
2cf0635d 8237 char * suffix;
579f31ac
JJ
8238 size_t len, len2;
8239
dda8d76d
NC
8240 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8241 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8242 if (sec->sh_type == SHT_IA_64_UNWIND)
8243 {
8244 unwsec = sec;
8245 break;
8246 }
4082ef84
NC
8247 /* We have already counted the number of SHT_IA64_UNWIND
8248 sections so the loop above should never fail. */
8249 assert (unwsec != NULL);
579f31ac
JJ
8250
8251 unwstart = i + 1;
8252 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8253
e4b17d5c
L
8254 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8255 {
8256 /* We need to find which section group it is in. */
4082ef84 8257 struct group_list * g;
e4b17d5c 8258
978c4450
AM
8259 if (filedata->section_headers_groups == NULL
8260 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8261 i = filedata->file_header.e_shnum;
4082ef84 8262 else
e4b17d5c 8263 {
978c4450 8264 g = filedata->section_headers_groups[i]->root;
18bd398b 8265
4082ef84
NC
8266 for (; g != NULL; g = g->next)
8267 {
dda8d76d 8268 sec = filedata->section_headers + g->section_index;
e4b17d5c 8269
b9e920ec
AM
8270 if (SECTION_NAME_VALID (sec)
8271 && streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
4082ef84
NC
8272 break;
8273 }
8274
8275 if (g == NULL)
dda8d76d 8276 i = filedata->file_header.e_shnum;
4082ef84 8277 }
e4b17d5c 8278 }
b9e920ec 8279 else if (SECTION_NAME_VALID (unwsec)
e9b095a5
ML
8280 && startswith (SECTION_NAME (unwsec),
8281 ELF_STRING_ia64_unwind_once))
579f31ac 8282 {
18bd398b 8283 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
8284 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
8285 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8286 for (i = 0, sec = filedata->section_headers;
8287 i < filedata->file_header.e_shnum;
579f31ac 8288 ++i, ++sec)
b9e920ec 8289 if (SECTION_NAME_VALID (sec)
e9b095a5
ML
8290 && startswith (SECTION_NAME (sec),
8291 ELF_STRING_ia64_unwind_info_once)
18bd398b 8292 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8293 break;
8294 }
8295 else
8296 {
8297 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8298 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8299 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8300 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8301 suffix = "";
b9e920ec 8302 if (SECTION_NAME_VALID (unwsec)
e9b095a5 8303 && startswith (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind))
579f31ac 8304 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8305 for (i = 0, sec = filedata->section_headers;
8306 i < filedata->file_header.e_shnum;
579f31ac 8307 ++i, ++sec)
b9e920ec 8308 if (SECTION_NAME_VALID (sec)
e9b095a5 8309 && startswith (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info)
18bd398b 8310 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8311 break;
8312 }
8313
dda8d76d 8314 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8315 {
8316 printf (_("\nCould not find unwind info section for "));
8317
dda8d76d 8318 if (filedata->string_table == NULL)
579f31ac
JJ
8319 printf ("%d", unwsec->sh_name);
8320 else
dda8d76d 8321 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8322 }
8323 else
4d6ed7c8 8324 {
4d6ed7c8 8325 aux.info_addr = sec->sh_addr;
dda8d76d 8326 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8327 sec->sh_size,
8328 _("unwind info"));
59245841 8329 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8330
579f31ac 8331 printf (_("\nUnwind section "));
4d6ed7c8 8332
dda8d76d 8333 if (filedata->string_table == NULL)
579f31ac
JJ
8334 printf ("%d", unwsec->sh_name);
8335 else
dda8d76d 8336 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8337
579f31ac 8338 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8339 (unsigned long) unwsec->sh_offset,
89fac5e3 8340 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8341
dda8d76d 8342 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8343 && aux.table_len > 0)
dda8d76d 8344 dump_ia64_unwind (filedata, & aux);
579f31ac 8345
9db70fc3
AM
8346 free ((char *) aux.table);
8347 free ((char *) aux.info);
579f31ac
JJ
8348 aux.table = NULL;
8349 aux.info = NULL;
8350 }
4d6ed7c8 8351 }
4d6ed7c8 8352
9db70fc3
AM
8353 free (aux.symtab);
8354 free ((char *) aux.strtab);
32ec8896
NC
8355
8356 return res;
4d6ed7c8
NC
8357}
8358
3f5e193b 8359struct hppa_unw_table_entry
32ec8896
NC
8360{
8361 struct absaddr start;
8362 struct absaddr end;
8363 unsigned int Cannot_unwind:1; /* 0 */
8364 unsigned int Millicode:1; /* 1 */
8365 unsigned int Millicode_save_sr0:1; /* 2 */
8366 unsigned int Region_description:2; /* 3..4 */
8367 unsigned int reserved1:1; /* 5 */
8368 unsigned int Entry_SR:1; /* 6 */
8369 unsigned int Entry_FR:4; /* Number saved 7..10 */
8370 unsigned int Entry_GR:5; /* Number saved 11..15 */
8371 unsigned int Args_stored:1; /* 16 */
8372 unsigned int Variable_Frame:1; /* 17 */
8373 unsigned int Separate_Package_Body:1; /* 18 */
8374 unsigned int Frame_Extension_Millicode:1; /* 19 */
8375 unsigned int Stack_Overflow_Check:1; /* 20 */
8376 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8377 unsigned int Ada_Region:1; /* 22 */
8378 unsigned int cxx_info:1; /* 23 */
8379 unsigned int cxx_try_catch:1; /* 24 */
8380 unsigned int sched_entry_seq:1; /* 25 */
8381 unsigned int reserved2:1; /* 26 */
8382 unsigned int Save_SP:1; /* 27 */
8383 unsigned int Save_RP:1; /* 28 */
8384 unsigned int Save_MRP_in_frame:1; /* 29 */
8385 unsigned int extn_ptr_defined:1; /* 30 */
8386 unsigned int Cleanup_defined:1; /* 31 */
8387
8388 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8389 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8390 unsigned int Large_frame:1; /* 2 */
8391 unsigned int Pseudo_SP_Set:1; /* 3 */
8392 unsigned int reserved4:1; /* 4 */
8393 unsigned int Total_frame_size:27; /* 5..31 */
8394};
3f5e193b 8395
57346661 8396struct hppa_unw_aux_info
948f632f 8397{
32ec8896
NC
8398 struct hppa_unw_table_entry * table; /* Unwind table. */
8399 unsigned long table_len; /* Length of unwind table. */
8400 bfd_vma seg_base; /* Starting address of segment. */
8401 Elf_Internal_Sym * symtab; /* The symbol table. */
8402 unsigned long nsyms; /* Number of symbols. */
8403 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8404 unsigned long nfuns; /* Number of entries in funtab. */
8405 char * strtab; /* The string table. */
8406 unsigned long strtab_size; /* Size of string table. */
948f632f 8407};
57346661 8408
015dc7e1 8409static bool
dda8d76d 8410dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8411{
2cf0635d 8412 struct hppa_unw_table_entry * tp;
948f632f 8413 unsigned long j, nfuns;
015dc7e1 8414 bool res = true;
948f632f
DA
8415
8416 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8417 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8418 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8419 aux->funtab[nfuns++] = aux->symtab[j];
8420 aux->nfuns = nfuns;
8421 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8422
57346661
AM
8423 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8424 {
8425 bfd_vma offset;
2cf0635d 8426 const char * procname;
57346661 8427
dda8d76d 8428 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8429 aux->strtab_size, tp->start, &procname,
8430 &offset);
8431
8432 fputs ("\n<", stdout);
8433
8434 if (procname)
8435 {
8436 fputs (procname, stdout);
8437
8438 if (offset)
8439 printf ("+%lx", (unsigned long) offset);
8440 }
8441
8442 fputs (">: [", stdout);
8443 print_vma (tp->start.offset, PREFIX_HEX);
8444 fputc ('-', stdout);
8445 print_vma (tp->end.offset, PREFIX_HEX);
8446 printf ("]\n\t");
8447
18bd398b
NC
8448#define PF(_m) if (tp->_m) printf (#_m " ");
8449#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8450 PF(Cannot_unwind);
8451 PF(Millicode);
8452 PF(Millicode_save_sr0);
18bd398b 8453 /* PV(Region_description); */
57346661
AM
8454 PF(Entry_SR);
8455 PV(Entry_FR);
8456 PV(Entry_GR);
8457 PF(Args_stored);
8458 PF(Variable_Frame);
8459 PF(Separate_Package_Body);
8460 PF(Frame_Extension_Millicode);
8461 PF(Stack_Overflow_Check);
8462 PF(Two_Instruction_SP_Increment);
8463 PF(Ada_Region);
8464 PF(cxx_info);
8465 PF(cxx_try_catch);
8466 PF(sched_entry_seq);
8467 PF(Save_SP);
8468 PF(Save_RP);
8469 PF(Save_MRP_in_frame);
8470 PF(extn_ptr_defined);
8471 PF(Cleanup_defined);
8472 PF(MPE_XL_interrupt_marker);
8473 PF(HP_UX_interrupt_marker);
8474 PF(Large_frame);
8475 PF(Pseudo_SP_Set);
8476 PV(Total_frame_size);
8477#undef PF
8478#undef PV
8479 }
8480
18bd398b 8481 printf ("\n");
948f632f
DA
8482
8483 free (aux->funtab);
32ec8896
NC
8484
8485 return res;
57346661
AM
8486}
8487
015dc7e1 8488static bool
dda8d76d
NC
8489slurp_hppa_unwind_table (Filedata * filedata,
8490 struct hppa_unw_aux_info * aux,
8491 Elf_Internal_Shdr * sec)
57346661 8492{
1c0751b2 8493 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8494 Elf_Internal_Phdr * seg;
8495 struct hppa_unw_table_entry * tep;
8496 Elf_Internal_Shdr * relsec;
8497 Elf_Internal_Rela * rela;
8498 Elf_Internal_Rela * rp;
8499 unsigned char * table;
8500 unsigned char * tp;
8501 Elf_Internal_Sym * sym;
8502 const char * relname;
57346661 8503
57346661
AM
8504 /* First, find the starting address of the segment that includes
8505 this section. */
dda8d76d 8506 if (filedata->file_header.e_phnum)
57346661 8507 {
dda8d76d 8508 if (! get_program_headers (filedata))
015dc7e1 8509 return false;
57346661 8510
dda8d76d
NC
8511 for (seg = filedata->program_headers;
8512 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8513 ++seg)
8514 {
8515 if (seg->p_type != PT_LOAD)
8516 continue;
8517
8518 if (sec->sh_addr >= seg->p_vaddr
8519 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8520 {
8521 aux->seg_base = seg->p_vaddr;
8522 break;
8523 }
8524 }
8525 }
8526
8527 /* Second, build the unwind table from the contents of the unwind
8528 section. */
8529 size = sec->sh_size;
dda8d76d 8530 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8531 _("unwind table"));
57346661 8532 if (!table)
015dc7e1 8533 return false;
57346661 8534
1c0751b2
DA
8535 unw_ent_size = 16;
8536 nentries = size / unw_ent_size;
8537 size = unw_ent_size * nentries;
57346661 8538
e3fdc001 8539 aux->table_len = nentries;
3f5e193b
NC
8540 tep = aux->table = (struct hppa_unw_table_entry *)
8541 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8542
1c0751b2 8543 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8544 {
8545 unsigned int tmp1, tmp2;
8546
8547 tep->start.section = SHN_UNDEF;
8548 tep->end.section = SHN_UNDEF;
8549
1c0751b2
DA
8550 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8551 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8552 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8553 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8554
8555 tep->start.offset += aux->seg_base;
8556 tep->end.offset += aux->seg_base;
57346661
AM
8557
8558 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8559 tep->Millicode = (tmp1 >> 30) & 0x1;
8560 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8561 tep->Region_description = (tmp1 >> 27) & 0x3;
8562 tep->reserved1 = (tmp1 >> 26) & 0x1;
8563 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8564 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8565 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8566 tep->Args_stored = (tmp1 >> 15) & 0x1;
8567 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8568 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8569 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8570 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8571 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8572 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8573 tep->cxx_info = (tmp1 >> 8) & 0x1;
8574 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8575 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8576 tep->reserved2 = (tmp1 >> 5) & 0x1;
8577 tep->Save_SP = (tmp1 >> 4) & 0x1;
8578 tep->Save_RP = (tmp1 >> 3) & 0x1;
8579 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8580 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8581 tep->Cleanup_defined = tmp1 & 0x1;
8582
8583 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8584 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8585 tep->Large_frame = (tmp2 >> 29) & 0x1;
8586 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8587 tep->reserved4 = (tmp2 >> 27) & 0x1;
8588 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8589 }
8590 free (table);
8591
8592 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8593 for (relsec = filedata->section_headers;
8594 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8595 ++relsec)
8596 {
8597 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8598 || relsec->sh_info >= filedata->file_header.e_shnum
8599 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8600 continue;
8601
dda8d76d 8602 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8603 & rela, & nrelas))
015dc7e1 8604 return false;
57346661
AM
8605
8606 for (rp = rela; rp < rela + nrelas; ++rp)
8607 {
4770fb94 8608 unsigned int sym_ndx;
726bd37d
AM
8609 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8610 relname = elf_hppa_reloc_type (r_type);
57346661 8611
726bd37d
AM
8612 if (relname == NULL)
8613 {
8614 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8615 continue;
8616 }
8617
57346661 8618 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 8619 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 8620 {
726bd37d 8621 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8622 continue;
8623 }
8624
8625 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8626 if (i >= aux->table_len)
8627 {
8628 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8629 continue;
8630 }
57346661 8631
4770fb94
AM
8632 sym_ndx = get_reloc_symindex (rp->r_info);
8633 if (sym_ndx >= aux->nsyms)
8634 {
8635 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8636 sym_ndx);
8637 continue;
8638 }
8639 sym = aux->symtab + sym_ndx;
8640
43f6cd05 8641 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8642 {
8643 case 0:
8644 aux->table[i].start.section = sym->st_shndx;
1e456d54 8645 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8646 break;
8647 case 1:
8648 aux->table[i].end.section = sym->st_shndx;
1e456d54 8649 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8650 break;
8651 default:
8652 break;
8653 }
8654 }
8655
8656 free (rela);
8657 }
8658
015dc7e1 8659 return true;
57346661
AM
8660}
8661
015dc7e1 8662static bool
dda8d76d 8663hppa_process_unwind (Filedata * filedata)
57346661 8664{
57346661 8665 struct hppa_unw_aux_info aux;
2cf0635d 8666 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8667 Elf_Internal_Shdr * sec;
18bd398b 8668 unsigned long i;
015dc7e1 8669 bool res = true;
57346661 8670
dda8d76d 8671 if (filedata->string_table == NULL)
015dc7e1 8672 return false;
1b31d05e
NC
8673
8674 memset (& aux, 0, sizeof (aux));
57346661 8675
dda8d76d 8676 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8677 {
28d13567 8678 if (sec->sh_type == SHT_SYMTAB)
57346661 8679 {
28d13567 8680 if (aux.symtab)
4082ef84 8681 {
28d13567
AM
8682 error (_("Multiple symbol tables encountered\n"));
8683 free (aux.symtab);
8684 aux.symtab = NULL;
4082ef84 8685 free (aux.strtab);
28d13567 8686 aux.strtab = NULL;
4082ef84 8687 }
28d13567
AM
8688 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8689 &aux.strtab, &aux.strtab_size))
015dc7e1 8690 return false;
57346661 8691 }
b9e920ec
AM
8692 else if (SECTION_NAME_VALID (sec)
8693 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8694 unwsec = sec;
8695 }
8696
8697 if (!unwsec)
8698 printf (_("\nThere are no unwind sections in this file.\n"));
8699
dda8d76d 8700 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8701 {
b9e920ec
AM
8702 if (SECTION_NAME_VALID (sec)
8703 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8704 {
43f6cd05 8705 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8706
d3a49aa8
AM
8707 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8708 "contains %lu entry:\n",
8709 "\nUnwind section '%s' at offset 0x%lx "
8710 "contains %lu entries:\n",
8711 num_unwind),
dda8d76d 8712 printable_section_name (filedata, sec),
57346661 8713 (unsigned long) sec->sh_offset,
d3a49aa8 8714 num_unwind);
57346661 8715
dda8d76d 8716 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 8717 res = false;
66b09c7e
S
8718
8719 if (res && aux.table_len > 0)
32ec8896 8720 {
dda8d76d 8721 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 8722 res = false;
32ec8896 8723 }
57346661 8724
9db70fc3 8725 free ((char *) aux.table);
57346661
AM
8726 aux.table = NULL;
8727 }
8728 }
8729
9db70fc3
AM
8730 free (aux.symtab);
8731 free ((char *) aux.strtab);
32ec8896
NC
8732
8733 return res;
57346661
AM
8734}
8735
0b6ae522
DJ
8736struct arm_section
8737{
a734115a
NC
8738 unsigned char * data; /* The unwind data. */
8739 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8740 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8741 unsigned long nrelas; /* The number of relocations. */
8742 unsigned int rel_type; /* REL or RELA ? */
8743 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8744};
8745
8746struct arm_unw_aux_info
8747{
dda8d76d 8748 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8749 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8750 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8751 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8752 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8753 char * strtab; /* The file's string table. */
8754 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8755};
8756
8757static const char *
dda8d76d
NC
8758arm_print_vma_and_name (Filedata * filedata,
8759 struct arm_unw_aux_info * aux,
8760 bfd_vma fn,
8761 struct absaddr addr)
0b6ae522
DJ
8762{
8763 const char *procname;
8764 bfd_vma sym_offset;
8765
8766 if (addr.section == SHN_UNDEF)
8767 addr.offset = fn;
8768
dda8d76d 8769 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8770 aux->strtab_size, addr, &procname,
8771 &sym_offset);
8772
8773 print_vma (fn, PREFIX_HEX);
8774
8775 if (procname)
8776 {
8777 fputs (" <", stdout);
8778 fputs (procname, stdout);
8779
8780 if (sym_offset)
8781 printf ("+0x%lx", (unsigned long) sym_offset);
8782 fputc ('>', stdout);
8783 }
8784
8785 return procname;
8786}
8787
8788static void
8789arm_free_section (struct arm_section *arm_sec)
8790{
9db70fc3
AM
8791 free (arm_sec->data);
8792 free (arm_sec->rela);
0b6ae522
DJ
8793}
8794
a734115a
NC
8795/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8796 cached section and install SEC instead.
8797 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8798 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8799 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8800 relocation's offset in ADDR.
1b31d05e
NC
8801 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8802 into the string table of the symbol associated with the reloc. If no
8803 reloc was applied store -1 there.
8804 5) Return TRUE upon success, FALSE otherwise. */
a734115a 8805
015dc7e1 8806static bool
dda8d76d
NC
8807get_unwind_section_word (Filedata * filedata,
8808 struct arm_unw_aux_info * aux,
1b31d05e
NC
8809 struct arm_section * arm_sec,
8810 Elf_Internal_Shdr * sec,
8811 bfd_vma word_offset,
8812 unsigned int * wordp,
8813 struct absaddr * addr,
8814 bfd_vma * sym_name)
0b6ae522
DJ
8815{
8816 Elf_Internal_Rela *rp;
8817 Elf_Internal_Sym *sym;
8818 const char * relname;
8819 unsigned int word;
015dc7e1 8820 bool wrapped;
0b6ae522 8821
e0a31db1 8822 if (sec == NULL || arm_sec == NULL)
015dc7e1 8823 return false;
e0a31db1 8824
0b6ae522
DJ
8825 addr->section = SHN_UNDEF;
8826 addr->offset = 0;
8827
1b31d05e
NC
8828 if (sym_name != NULL)
8829 *sym_name = (bfd_vma) -1;
8830
a734115a 8831 /* If necessary, update the section cache. */
0b6ae522
DJ
8832 if (sec != arm_sec->sec)
8833 {
8834 Elf_Internal_Shdr *relsec;
8835
8836 arm_free_section (arm_sec);
8837
8838 arm_sec->sec = sec;
dda8d76d 8839 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8840 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8841 arm_sec->rela = NULL;
8842 arm_sec->nrelas = 0;
8843
dda8d76d
NC
8844 for (relsec = filedata->section_headers;
8845 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8846 ++relsec)
8847 {
dda8d76d
NC
8848 if (relsec->sh_info >= filedata->file_header.e_shnum
8849 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8850 /* PR 15745: Check the section type as well. */
8851 || (relsec->sh_type != SHT_REL
8852 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8853 continue;
8854
a734115a 8855 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8856 if (relsec->sh_type == SHT_REL)
8857 {
dda8d76d 8858 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8859 relsec->sh_size,
8860 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 8861 return false;
0b6ae522 8862 }
1ae40aa4 8863 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8864 {
dda8d76d 8865 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8866 relsec->sh_size,
8867 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 8868 return false;
0b6ae522 8869 }
1ae40aa4 8870 break;
0b6ae522
DJ
8871 }
8872
8873 arm_sec->next_rela = arm_sec->rela;
8874 }
8875
a734115a 8876 /* If there is no unwind data we can do nothing. */
0b6ae522 8877 if (arm_sec->data == NULL)
015dc7e1 8878 return false;
0b6ae522 8879
e0a31db1 8880 /* If the offset is invalid then fail. */
f32ba729
NC
8881 if (/* PR 21343 *//* PR 18879 */
8882 sec->sh_size < 4
8883 || word_offset > (sec->sh_size - 4)
1a915552 8884 || ((bfd_signed_vma) word_offset) < 0)
015dc7e1 8885 return false;
e0a31db1 8886
a734115a 8887 /* Get the word at the required offset. */
0b6ae522
DJ
8888 word = byte_get (arm_sec->data + word_offset, 4);
8889
0eff7165
NC
8890 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8891 if (arm_sec->rela == NULL)
8892 {
8893 * wordp = word;
015dc7e1 8894 return true;
0eff7165
NC
8895 }
8896
a734115a 8897 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 8898 wrapped = false;
0b6ae522
DJ
8899 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8900 {
8901 bfd_vma prelval, offset;
8902
8903 if (rp->r_offset > word_offset && !wrapped)
8904 {
8905 rp = arm_sec->rela;
015dc7e1 8906 wrapped = true;
0b6ae522
DJ
8907 }
8908 if (rp->r_offset > word_offset)
8909 break;
8910
8911 if (rp->r_offset & 3)
8912 {
8913 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8914 (unsigned long) rp->r_offset);
8915 continue;
8916 }
8917
8918 if (rp->r_offset < word_offset)
8919 continue;
8920
74e1a04b
NC
8921 /* PR 17531: file: 027-161405-0.004 */
8922 if (aux->symtab == NULL)
8923 continue;
8924
0b6ae522
DJ
8925 if (arm_sec->rel_type == SHT_REL)
8926 {
8927 offset = word & 0x7fffffff;
8928 if (offset & 0x40000000)
8929 offset |= ~ (bfd_vma) 0x7fffffff;
8930 }
a734115a 8931 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8932 offset = rp->r_addend;
a734115a 8933 else
74e1a04b
NC
8934 {
8935 error (_("Unknown section relocation type %d encountered\n"),
8936 arm_sec->rel_type);
8937 break;
8938 }
0b6ae522 8939
071436c6
NC
8940 /* PR 17531 file: 027-1241568-0.004. */
8941 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8942 {
8943 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8944 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8945 break;
8946 }
8947
8948 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8949 offset += sym->st_value;
8950 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8951
a734115a 8952 /* Check that we are processing the expected reloc type. */
dda8d76d 8953 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8954 {
8955 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8956 if (relname == NULL)
8957 {
8958 warn (_("Skipping unknown ARM relocation type: %d\n"),
8959 (int) ELF32_R_TYPE (rp->r_info));
8960 continue;
8961 }
a734115a
NC
8962
8963 if (streq (relname, "R_ARM_NONE"))
8964 continue;
0b4362b0 8965
a734115a
NC
8966 if (! streq (relname, "R_ARM_PREL31"))
8967 {
071436c6 8968 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8969 continue;
8970 }
8971 }
dda8d76d 8972 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8973 {
8974 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8975 if (relname == NULL)
8976 {
8977 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8978 (int) ELF32_R_TYPE (rp->r_info));
8979 continue;
8980 }
0b4362b0 8981
a734115a
NC
8982 if (streq (relname, "R_C6000_NONE"))
8983 continue;
8984
8985 if (! streq (relname, "R_C6000_PREL31"))
8986 {
071436c6 8987 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8988 continue;
8989 }
8990
8991 prelval >>= 1;
8992 }
8993 else
74e1a04b
NC
8994 {
8995 /* This function currently only supports ARM and TI unwinders. */
8996 warn (_("Only TI and ARM unwinders are currently supported\n"));
8997 break;
8998 }
fa197c1c 8999
0b6ae522
DJ
9000 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
9001 addr->section = sym->st_shndx;
9002 addr->offset = offset;
74e1a04b 9003
1b31d05e
NC
9004 if (sym_name)
9005 * sym_name = sym->st_name;
0b6ae522
DJ
9006 break;
9007 }
9008
9009 *wordp = word;
9010 arm_sec->next_rela = rp;
9011
015dc7e1 9012 return true;
0b6ae522
DJ
9013}
9014
a734115a
NC
9015static const char *tic6x_unwind_regnames[16] =
9016{
0b4362b0
RM
9017 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9018 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9019 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9020};
fa197c1c 9021
0b6ae522 9022static void
fa197c1c 9023decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9024{
fa197c1c
PB
9025 int i;
9026
9027 for (i = 12; mask; mask >>= 1, i--)
9028 {
9029 if (mask & 1)
9030 {
9031 fputs (tic6x_unwind_regnames[i], stdout);
9032 if (mask > 1)
9033 fputs (", ", stdout);
9034 }
9035 }
9036}
0b6ae522
DJ
9037
9038#define ADVANCE \
9039 if (remaining == 0 && more_words) \
9040 { \
9041 data_offset += 4; \
dda8d76d 9042 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9043 data_offset, & word, & addr, NULL)) \
015dc7e1 9044 return false; \
0b6ae522
DJ
9045 remaining = 4; \
9046 more_words--; \
9047 } \
9048
9049#define GET_OP(OP) \
9050 ADVANCE; \
9051 if (remaining) \
9052 { \
9053 remaining--; \
9054 (OP) = word >> 24; \
9055 word <<= 8; \
9056 } \
9057 else \
9058 { \
2b692964 9059 printf (_("[Truncated opcode]\n")); \
015dc7e1 9060 return false; \
0b6ae522 9061 } \
cc5914eb 9062 printf ("0x%02x ", OP)
0b6ae522 9063
015dc7e1 9064static bool
dda8d76d
NC
9065decode_arm_unwind_bytecode (Filedata * filedata,
9066 struct arm_unw_aux_info * aux,
948f632f
DA
9067 unsigned int word,
9068 unsigned int remaining,
9069 unsigned int more_words,
9070 bfd_vma data_offset,
9071 Elf_Internal_Shdr * data_sec,
9072 struct arm_section * data_arm_sec)
fa197c1c
PB
9073{
9074 struct absaddr addr;
015dc7e1 9075 bool res = true;
0b6ae522
DJ
9076
9077 /* Decode the unwinding instructions. */
9078 while (1)
9079 {
9080 unsigned int op, op2;
9081
9082 ADVANCE;
9083 if (remaining == 0)
9084 break;
9085 remaining--;
9086 op = word >> 24;
9087 word <<= 8;
9088
cc5914eb 9089 printf (" 0x%02x ", op);
0b6ae522
DJ
9090
9091 if ((op & 0xc0) == 0x00)
9092 {
9093 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9094
cc5914eb 9095 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9096 }
9097 else if ((op & 0xc0) == 0x40)
9098 {
9099 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9100
cc5914eb 9101 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9102 }
9103 else if ((op & 0xf0) == 0x80)
9104 {
9105 GET_OP (op2);
9106 if (op == 0x80 && op2 == 0)
9107 printf (_("Refuse to unwind"));
9108 else
9109 {
9110 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9111 bool first = true;
0b6ae522 9112 int i;
2b692964 9113
0b6ae522
DJ
9114 printf ("pop {");
9115 for (i = 0; i < 12; i++)
9116 if (mask & (1 << i))
9117 {
9118 if (first)
015dc7e1 9119 first = false;
0b6ae522
DJ
9120 else
9121 printf (", ");
9122 printf ("r%d", 4 + i);
9123 }
9124 printf ("}");
9125 }
9126 }
9127 else if ((op & 0xf0) == 0x90)
9128 {
9129 if (op == 0x9d || op == 0x9f)
9130 printf (_(" [Reserved]"));
9131 else
cc5914eb 9132 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9133 }
9134 else if ((op & 0xf0) == 0xa0)
9135 {
9136 int end = 4 + (op & 0x07);
015dc7e1 9137 bool first = true;
0b6ae522 9138 int i;
61865e30 9139
0b6ae522
DJ
9140 printf (" pop {");
9141 for (i = 4; i <= end; i++)
9142 {
9143 if (first)
015dc7e1 9144 first = false;
0b6ae522
DJ
9145 else
9146 printf (", ");
9147 printf ("r%d", i);
9148 }
9149 if (op & 0x08)
9150 {
1b31d05e 9151 if (!first)
0b6ae522
DJ
9152 printf (", ");
9153 printf ("r14");
9154 }
9155 printf ("}");
9156 }
9157 else if (op == 0xb0)
9158 printf (_(" finish"));
9159 else if (op == 0xb1)
9160 {
9161 GET_OP (op2);
9162 if (op2 == 0 || (op2 & 0xf0) != 0)
9163 printf (_("[Spare]"));
9164 else
9165 {
9166 unsigned int mask = op2 & 0x0f;
015dc7e1 9167 bool first = true;
0b6ae522 9168 int i;
61865e30 9169
0b6ae522
DJ
9170 printf ("pop {");
9171 for (i = 0; i < 12; i++)
9172 if (mask & (1 << i))
9173 {
9174 if (first)
015dc7e1 9175 first = false;
0b6ae522
DJ
9176 else
9177 printf (", ");
9178 printf ("r%d", i);
9179 }
9180 printf ("}");
9181 }
9182 }
9183 else if (op == 0xb2)
9184 {
b115cf96 9185 unsigned char buf[9];
0b6ae522
DJ
9186 unsigned int i, len;
9187 unsigned long offset;
61865e30 9188
b115cf96 9189 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9190 {
9191 GET_OP (buf[i]);
9192 if ((buf[i] & 0x80) == 0)
9193 break;
9194 }
4082ef84 9195 if (i == sizeof (buf))
32ec8896 9196 {
27a45f42 9197 error (_("corrupt change to vsp\n"));
015dc7e1 9198 res = false;
32ec8896 9199 }
4082ef84
NC
9200 else
9201 {
015dc7e1 9202 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9203 assert (len == i + 1);
9204 offset = offset * 4 + 0x204;
9205 printf ("vsp = vsp + %ld", offset);
9206 }
0b6ae522 9207 }
61865e30 9208 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9209 {
61865e30
NC
9210 unsigned int first, last;
9211
9212 GET_OP (op2);
9213 first = op2 >> 4;
9214 last = op2 & 0x0f;
9215 if (op == 0xc8)
9216 first = first + 16;
9217 printf ("pop {D%d", first);
9218 if (last)
9219 printf ("-D%d", first + last);
9220 printf ("}");
9221 }
9222 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9223 {
9224 unsigned int count = op & 0x07;
9225
9226 printf ("pop {D8");
9227 if (count)
9228 printf ("-D%d", 8 + count);
9229 printf ("}");
9230 }
9231 else if (op >= 0xc0 && op <= 0xc5)
9232 {
9233 unsigned int count = op & 0x07;
9234
9235 printf (" pop {wR10");
9236 if (count)
9237 printf ("-wR%d", 10 + count);
9238 printf ("}");
9239 }
9240 else if (op == 0xc6)
9241 {
9242 unsigned int first, last;
9243
9244 GET_OP (op2);
9245 first = op2 >> 4;
9246 last = op2 & 0x0f;
9247 printf ("pop {wR%d", first);
9248 if (last)
9249 printf ("-wR%d", first + last);
9250 printf ("}");
9251 }
9252 else if (op == 0xc7)
9253 {
9254 GET_OP (op2);
9255 if (op2 == 0 || (op2 & 0xf0) != 0)
9256 printf (_("[Spare]"));
0b6ae522
DJ
9257 else
9258 {
61865e30 9259 unsigned int mask = op2 & 0x0f;
015dc7e1 9260 bool first = true;
61865e30
NC
9261 int i;
9262
9263 printf ("pop {");
9264 for (i = 0; i < 4; i++)
9265 if (mask & (1 << i))
9266 {
9267 if (first)
015dc7e1 9268 first = false;
61865e30
NC
9269 else
9270 printf (", ");
9271 printf ("wCGR%d", i);
9272 }
9273 printf ("}");
0b6ae522
DJ
9274 }
9275 }
61865e30 9276 else
32ec8896
NC
9277 {
9278 printf (_(" [unsupported opcode]"));
015dc7e1 9279 res = false;
32ec8896
NC
9280 }
9281
0b6ae522
DJ
9282 printf ("\n");
9283 }
32ec8896
NC
9284
9285 return res;
fa197c1c
PB
9286}
9287
015dc7e1 9288static bool
dda8d76d
NC
9289decode_tic6x_unwind_bytecode (Filedata * filedata,
9290 struct arm_unw_aux_info * aux,
948f632f
DA
9291 unsigned int word,
9292 unsigned int remaining,
9293 unsigned int more_words,
9294 bfd_vma data_offset,
9295 Elf_Internal_Shdr * data_sec,
9296 struct arm_section * data_arm_sec)
fa197c1c
PB
9297{
9298 struct absaddr addr;
9299
9300 /* Decode the unwinding instructions. */
9301 while (1)
9302 {
9303 unsigned int op, op2;
9304
9305 ADVANCE;
9306 if (remaining == 0)
9307 break;
9308 remaining--;
9309 op = word >> 24;
9310 word <<= 8;
9311
9cf03b7e 9312 printf (" 0x%02x ", op);
fa197c1c
PB
9313
9314 if ((op & 0xc0) == 0x00)
9315 {
9316 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9317 printf (" sp = sp + %d", offset);
fa197c1c
PB
9318 }
9319 else if ((op & 0xc0) == 0x80)
9320 {
9321 GET_OP (op2);
9322 if (op == 0x80 && op2 == 0)
9323 printf (_("Refuse to unwind"));
9324 else
9325 {
9326 unsigned int mask = ((op & 0x1f) << 8) | op2;
9327 if (op & 0x20)
9328 printf ("pop compact {");
9329 else
9330 printf ("pop {");
9331
9332 decode_tic6x_unwind_regmask (mask);
9333 printf("}");
9334 }
9335 }
9336 else if ((op & 0xf0) == 0xc0)
9337 {
9338 unsigned int reg;
9339 unsigned int nregs;
9340 unsigned int i;
9341 const char *name;
a734115a
NC
9342 struct
9343 {
32ec8896
NC
9344 unsigned int offset;
9345 unsigned int reg;
fa197c1c
PB
9346 } regpos[16];
9347
9348 /* Scan entire instruction first so that GET_OP output is not
9349 interleaved with disassembly. */
9350 nregs = 0;
9351 for (i = 0; nregs < (op & 0xf); i++)
9352 {
9353 GET_OP (op2);
9354 reg = op2 >> 4;
9355 if (reg != 0xf)
9356 {
9357 regpos[nregs].offset = i * 2;
9358 regpos[nregs].reg = reg;
9359 nregs++;
9360 }
9361
9362 reg = op2 & 0xf;
9363 if (reg != 0xf)
9364 {
9365 regpos[nregs].offset = i * 2 + 1;
9366 regpos[nregs].reg = reg;
9367 nregs++;
9368 }
9369 }
9370
9371 printf (_("pop frame {"));
18344509 9372 if (nregs == 0)
fa197c1c 9373 {
18344509
NC
9374 printf (_("*corrupt* - no registers specified"));
9375 }
9376 else
9377 {
9378 reg = nregs - 1;
9379 for (i = i * 2; i > 0; i--)
fa197c1c 9380 {
18344509
NC
9381 if (regpos[reg].offset == i - 1)
9382 {
9383 name = tic6x_unwind_regnames[regpos[reg].reg];
9384 if (reg > 0)
9385 reg--;
9386 }
9387 else
9388 name = _("[pad]");
fa197c1c 9389
18344509
NC
9390 fputs (name, stdout);
9391 if (i > 1)
9392 printf (", ");
9393 }
fa197c1c
PB
9394 }
9395
9396 printf ("}");
9397 }
9398 else if (op == 0xd0)
9399 printf (" MOV FP, SP");
9400 else if (op == 0xd1)
9401 printf (" __c6xabi_pop_rts");
9402 else if (op == 0xd2)
9403 {
9404 unsigned char buf[9];
9405 unsigned int i, len;
9406 unsigned long offset;
a734115a 9407
fa197c1c
PB
9408 for (i = 0; i < sizeof (buf); i++)
9409 {
9410 GET_OP (buf[i]);
9411 if ((buf[i] & 0x80) == 0)
9412 break;
9413 }
0eff7165
NC
9414 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9415 if (i == sizeof (buf))
9416 {
0eff7165 9417 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 9418 return false;
0eff7165 9419 }
948f632f 9420
015dc7e1 9421 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
9422 assert (len == i + 1);
9423 offset = offset * 8 + 0x408;
9424 printf (_("sp = sp + %ld"), offset);
9425 }
9426 else if ((op & 0xf0) == 0xe0)
9427 {
9428 if ((op & 0x0f) == 7)
9429 printf (" RETURN");
9430 else
9431 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9432 }
9433 else
9434 {
9435 printf (_(" [unsupported opcode]"));
9436 }
9437 putchar ('\n');
9438 }
32ec8896 9439
015dc7e1 9440 return true;
fa197c1c
PB
9441}
9442
9443static bfd_vma
dda8d76d 9444arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9445{
9446 bfd_vma offset;
9447
9448 offset = word & 0x7fffffff;
9449 if (offset & 0x40000000)
9450 offset |= ~ (bfd_vma) 0x7fffffff;
9451
dda8d76d 9452 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9453 offset <<= 1;
9454
9455 return offset + where;
9456}
9457
015dc7e1 9458static bool
dda8d76d
NC
9459decode_arm_unwind (Filedata * filedata,
9460 struct arm_unw_aux_info * aux,
1b31d05e
NC
9461 unsigned int word,
9462 unsigned int remaining,
9463 bfd_vma data_offset,
9464 Elf_Internal_Shdr * data_sec,
9465 struct arm_section * data_arm_sec)
fa197c1c
PB
9466{
9467 int per_index;
9468 unsigned int more_words = 0;
37e14bc3 9469 struct absaddr addr;
1b31d05e 9470 bfd_vma sym_name = (bfd_vma) -1;
015dc7e1 9471 bool res = true;
fa197c1c
PB
9472
9473 if (remaining == 0)
9474 {
1b31d05e
NC
9475 /* Fetch the first word.
9476 Note - when decoding an object file the address extracted
9477 here will always be 0. So we also pass in the sym_name
9478 parameter so that we can find the symbol associated with
9479 the personality routine. */
dda8d76d 9480 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9481 & word, & addr, & sym_name))
015dc7e1 9482 return false;
1b31d05e 9483
fa197c1c
PB
9484 remaining = 4;
9485 }
c93dbb25
CZ
9486 else
9487 {
9488 addr.section = SHN_UNDEF;
9489 addr.offset = 0;
9490 }
fa197c1c
PB
9491
9492 if ((word & 0x80000000) == 0)
9493 {
9494 /* Expand prel31 for personality routine. */
9495 bfd_vma fn;
9496 const char *procname;
9497
dda8d76d 9498 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9499 printf (_(" Personality routine: "));
1b31d05e
NC
9500 if (fn == 0
9501 && addr.section == SHN_UNDEF && addr.offset == 0
9502 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9503 {
9504 procname = aux->strtab + sym_name;
9505 print_vma (fn, PREFIX_HEX);
9506 if (procname)
9507 {
9508 fputs (" <", stdout);
9509 fputs (procname, stdout);
9510 fputc ('>', stdout);
9511 }
9512 }
9513 else
dda8d76d 9514 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9515 fputc ('\n', stdout);
9516
9517 /* The GCC personality routines use the standard compact
9518 encoding, starting with one byte giving the number of
9519 words. */
9520 if (procname != NULL
24d127aa
ML
9521 && (startswith (procname, "__gcc_personality_v0")
9522 || startswith (procname, "__gxx_personality_v0")
9523 || startswith (procname, "__gcj_personality_v0")
9524 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
9525 {
9526 remaining = 0;
9527 more_words = 1;
9528 ADVANCE;
9529 if (!remaining)
9530 {
9531 printf (_(" [Truncated data]\n"));
015dc7e1 9532 return false;
fa197c1c
PB
9533 }
9534 more_words = word >> 24;
9535 word <<= 8;
9536 remaining--;
9537 per_index = -1;
9538 }
9539 else
015dc7e1 9540 return true;
fa197c1c
PB
9541 }
9542 else
9543 {
1b31d05e 9544 /* ARM EHABI Section 6.3:
0b4362b0 9545
1b31d05e 9546 An exception-handling table entry for the compact model looks like:
0b4362b0 9547
1b31d05e
NC
9548 31 30-28 27-24 23-0
9549 -- ----- ----- ----
9550 1 0 index Data for personalityRoutine[index] */
9551
dda8d76d 9552 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9553 && (word & 0x70000000))
32ec8896
NC
9554 {
9555 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 9556 res = false;
32ec8896 9557 }
1b31d05e 9558
fa197c1c 9559 per_index = (word >> 24) & 0x7f;
1b31d05e 9560 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9561 if (per_index == 0)
9562 {
9563 more_words = 0;
9564 word <<= 8;
9565 remaining--;
9566 }
9567 else if (per_index < 3)
9568 {
9569 more_words = (word >> 16) & 0xff;
9570 word <<= 16;
9571 remaining -= 2;
9572 }
9573 }
9574
dda8d76d 9575 switch (filedata->file_header.e_machine)
fa197c1c
PB
9576 {
9577 case EM_ARM:
9578 if (per_index < 3)
9579 {
dda8d76d 9580 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 9581 data_offset, data_sec, data_arm_sec))
015dc7e1 9582 res = false;
fa197c1c
PB
9583 }
9584 else
1b31d05e
NC
9585 {
9586 warn (_("Unknown ARM compact model index encountered\n"));
9587 printf (_(" [reserved]\n"));
015dc7e1 9588 res = false;
1b31d05e 9589 }
fa197c1c
PB
9590 break;
9591
9592 case EM_TI_C6000:
9593 if (per_index < 3)
9594 {
dda8d76d 9595 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 9596 data_offset, data_sec, data_arm_sec))
015dc7e1 9597 res = false;
fa197c1c
PB
9598 }
9599 else if (per_index < 5)
9600 {
9601 if (((word >> 17) & 0x7f) == 0x7f)
9602 printf (_(" Restore stack from frame pointer\n"));
9603 else
9604 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9605 printf (_(" Registers restored: "));
9606 if (per_index == 4)
9607 printf (" (compact) ");
9608 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9609 putchar ('\n');
9610 printf (_(" Return register: %s\n"),
9611 tic6x_unwind_regnames[word & 0xf]);
9612 }
9613 else
1b31d05e 9614 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9615 break;
9616
9617 default:
74e1a04b 9618 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9619 filedata->file_header.e_machine);
015dc7e1 9620 res = false;
fa197c1c 9621 }
0b6ae522
DJ
9622
9623 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9624
9625 return res;
0b6ae522
DJ
9626}
9627
015dc7e1 9628static bool
dda8d76d
NC
9629dump_arm_unwind (Filedata * filedata,
9630 struct arm_unw_aux_info * aux,
9631 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9632{
9633 struct arm_section exidx_arm_sec, extab_arm_sec;
9634 unsigned int i, exidx_len;
948f632f 9635 unsigned long j, nfuns;
015dc7e1 9636 bool res = true;
0b6ae522
DJ
9637
9638 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9639 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9640 exidx_len = exidx_sec->sh_size / 8;
9641
948f632f
DA
9642 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9643 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9644 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9645 aux->funtab[nfuns++] = aux->symtab[j];
9646 aux->nfuns = nfuns;
9647 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9648
0b6ae522
DJ
9649 for (i = 0; i < exidx_len; i++)
9650 {
9651 unsigned int exidx_fn, exidx_entry;
9652 struct absaddr fn_addr, entry_addr;
9653 bfd_vma fn;
9654
9655 fputc ('\n', stdout);
9656
dda8d76d 9657 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9658 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9659 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9660 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9661 {
948f632f 9662 free (aux->funtab);
1b31d05e
NC
9663 arm_free_section (& exidx_arm_sec);
9664 arm_free_section (& extab_arm_sec);
015dc7e1 9665 return false;
0b6ae522
DJ
9666 }
9667
83c257ca
NC
9668 /* ARM EHABI, Section 5:
9669 An index table entry consists of 2 words.
9670 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9671 if (exidx_fn & 0x80000000)
32ec8896
NC
9672 {
9673 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 9674 res = false;
32ec8896 9675 }
83c257ca 9676
dda8d76d 9677 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9678
dda8d76d 9679 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9680 fputs (": ", stdout);
9681
9682 if (exidx_entry == 1)
9683 {
9684 print_vma (exidx_entry, PREFIX_HEX);
9685 fputs (" [cantunwind]\n", stdout);
9686 }
9687 else if (exidx_entry & 0x80000000)
9688 {
9689 print_vma (exidx_entry, PREFIX_HEX);
9690 fputc ('\n', stdout);
dda8d76d 9691 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9692 }
9693 else
9694 {
8f73510c 9695 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9696 Elf_Internal_Shdr *table_sec;
9697
9698 fputs ("@", stdout);
dda8d76d 9699 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9700 print_vma (table, PREFIX_HEX);
9701 printf ("\n");
9702
9703 /* Locate the matching .ARM.extab. */
9704 if (entry_addr.section != SHN_UNDEF
dda8d76d 9705 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9706 {
dda8d76d 9707 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9708 table_offset = entry_addr.offset;
1a915552
NC
9709 /* PR 18879 */
9710 if (table_offset > table_sec->sh_size
9711 || ((bfd_signed_vma) table_offset) < 0)
9712 {
9713 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9714 (unsigned long) table_offset,
dda8d76d 9715 printable_section_name (filedata, table_sec));
015dc7e1 9716 res = false;
1a915552
NC
9717 continue;
9718 }
0b6ae522
DJ
9719 }
9720 else
9721 {
dda8d76d 9722 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9723 if (table_sec != NULL)
9724 table_offset = table - table_sec->sh_addr;
9725 }
32ec8896 9726
0b6ae522
DJ
9727 if (table_sec == NULL)
9728 {
9729 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9730 (unsigned long) table);
015dc7e1 9731 res = false;
0b6ae522
DJ
9732 continue;
9733 }
32ec8896 9734
dda8d76d 9735 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 9736 &extab_arm_sec))
015dc7e1 9737 res = false;
0b6ae522
DJ
9738 }
9739 }
9740
9741 printf ("\n");
9742
948f632f 9743 free (aux->funtab);
0b6ae522
DJ
9744 arm_free_section (&exidx_arm_sec);
9745 arm_free_section (&extab_arm_sec);
32ec8896
NC
9746
9747 return res;
0b6ae522
DJ
9748}
9749
fa197c1c 9750/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9751
015dc7e1 9752static bool
dda8d76d 9753arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9754{
9755 struct arm_unw_aux_info aux;
9756 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9757 Elf_Internal_Shdr *sec;
9758 unsigned long i;
fa197c1c 9759 unsigned int sec_type;
015dc7e1 9760 bool res = true;
0b6ae522 9761
dda8d76d 9762 switch (filedata->file_header.e_machine)
fa197c1c
PB
9763 {
9764 case EM_ARM:
9765 sec_type = SHT_ARM_EXIDX;
9766 break;
9767
9768 case EM_TI_C6000:
9769 sec_type = SHT_C6000_UNWIND;
9770 break;
9771
0b4362b0 9772 default:
74e1a04b 9773 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9774 filedata->file_header.e_machine);
015dc7e1 9775 return false;
fa197c1c
PB
9776 }
9777
dda8d76d 9778 if (filedata->string_table == NULL)
015dc7e1 9779 return false;
1b31d05e
NC
9780
9781 memset (& aux, 0, sizeof (aux));
dda8d76d 9782 aux.filedata = filedata;
0b6ae522 9783
dda8d76d 9784 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9785 {
28d13567 9786 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9787 {
28d13567 9788 if (aux.symtab)
74e1a04b 9789 {
28d13567
AM
9790 error (_("Multiple symbol tables encountered\n"));
9791 free (aux.symtab);
9792 aux.symtab = NULL;
74e1a04b 9793 free (aux.strtab);
28d13567 9794 aux.strtab = NULL;
74e1a04b 9795 }
28d13567
AM
9796 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9797 &aux.strtab, &aux.strtab_size))
015dc7e1 9798 return false;
0b6ae522 9799 }
fa197c1c 9800 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9801 unwsec = sec;
9802 }
9803
1b31d05e 9804 if (unwsec == NULL)
0b6ae522 9805 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9806 else
dda8d76d 9807 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9808 {
9809 if (sec->sh_type == sec_type)
9810 {
d3a49aa8
AM
9811 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9812 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9813 "contains %lu entry:\n",
9814 "\nUnwind section '%s' at offset 0x%lx "
9815 "contains %lu entries:\n",
9816 num_unwind),
dda8d76d 9817 printable_section_name (filedata, sec),
1b31d05e 9818 (unsigned long) sec->sh_offset,
d3a49aa8 9819 num_unwind);
0b6ae522 9820
dda8d76d 9821 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 9822 res = false;
1b31d05e
NC
9823 }
9824 }
0b6ae522 9825
9db70fc3
AM
9826 free (aux.symtab);
9827 free ((char *) aux.strtab);
32ec8896
NC
9828
9829 return res;
0b6ae522
DJ
9830}
9831
3ecc00ec
NC
9832static bool
9833no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
9834{
9835 printf (_("No processor specific unwind information to decode\n"));
9836 return true;
9837}
9838
015dc7e1 9839static bool
dda8d76d 9840process_unwind (Filedata * filedata)
57346661 9841{
2cf0635d
NC
9842 struct unwind_handler
9843 {
32ec8896 9844 unsigned int machtype;
015dc7e1 9845 bool (* handler)(Filedata *);
2cf0635d
NC
9846 } handlers[] =
9847 {
0b6ae522 9848 { EM_ARM, arm_process_unwind },
57346661
AM
9849 { EM_IA_64, ia64_process_unwind },
9850 { EM_PARISC, hppa_process_unwind },
fa197c1c 9851 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
9852 { EM_386, no_processor_specific_unwind },
9853 { EM_X86_64, no_processor_specific_unwind },
32ec8896 9854 { 0, NULL }
57346661
AM
9855 };
9856 int i;
9857
9858 if (!do_unwind)
015dc7e1 9859 return true;
57346661
AM
9860
9861 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9862 if (filedata->file_header.e_machine == handlers[i].machtype)
9863 return handlers[i].handler (filedata);
57346661 9864
1b31d05e 9865 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9866 get_machine_name (filedata->file_header.e_machine));
015dc7e1 9867 return true;
57346661
AM
9868}
9869
37c18eed
SD
9870static void
9871dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
9872{
9873 switch (entry->d_tag)
9874 {
9875 case DT_AARCH64_BTI_PLT:
1dbade74 9876 case DT_AARCH64_PAC_PLT:
37c18eed
SD
9877 break;
9878 default:
9879 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9880 break;
9881 }
9882 putchar ('\n');
9883}
9884
252b5132 9885static void
978c4450 9886dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
9887{
9888 switch (entry->d_tag)
9889 {
9890 case DT_MIPS_FLAGS:
9891 if (entry->d_un.d_val == 0)
4b68bca3 9892 printf (_("NONE"));
252b5132
RH
9893 else
9894 {
9895 static const char * opts[] =
9896 {
9897 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9898 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9899 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9900 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9901 "RLD_ORDER_SAFE"
9902 };
9903 unsigned int cnt;
015dc7e1 9904 bool first = true;
2b692964 9905
60bca95a 9906 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9907 if (entry->d_un.d_val & (1 << cnt))
9908 {
9909 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 9910 first = false;
252b5132 9911 }
252b5132
RH
9912 }
9913 break;
103f02d3 9914
252b5132 9915 case DT_MIPS_IVERSION:
978c4450
AM
9916 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
9917 printf (_("Interface Version: %s"),
9918 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 9919 else
76ca31c0
NC
9920 {
9921 char buf[40];
9922 sprintf_vma (buf, entry->d_un.d_ptr);
9923 /* Note: coded this way so that there is a single string for translation. */
9924 printf (_("<corrupt: %s>"), buf);
9925 }
252b5132 9926 break;
103f02d3 9927
252b5132
RH
9928 case DT_MIPS_TIME_STAMP:
9929 {
d5b07ef4 9930 char timebuf[128];
2cf0635d 9931 struct tm * tmp;
91d6fa6a 9932 time_t atime = entry->d_un.d_val;
82b1b41b 9933
91d6fa6a 9934 tmp = gmtime (&atime);
82b1b41b
NC
9935 /* PR 17531: file: 6accc532. */
9936 if (tmp == NULL)
9937 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9938 else
9939 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9940 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9941 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9942 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9943 }
9944 break;
103f02d3 9945
252b5132
RH
9946 case DT_MIPS_RLD_VERSION:
9947 case DT_MIPS_LOCAL_GOTNO:
9948 case DT_MIPS_CONFLICTNO:
9949 case DT_MIPS_LIBLISTNO:
9950 case DT_MIPS_SYMTABNO:
9951 case DT_MIPS_UNREFEXTNO:
9952 case DT_MIPS_HIPAGENO:
9953 case DT_MIPS_DELTA_CLASS_NO:
9954 case DT_MIPS_DELTA_INSTANCE_NO:
9955 case DT_MIPS_DELTA_RELOC_NO:
9956 case DT_MIPS_DELTA_SYM_NO:
9957 case DT_MIPS_DELTA_CLASSSYM_NO:
9958 case DT_MIPS_COMPACT_SIZE:
c69075ac 9959 print_vma (entry->d_un.d_val, DEC);
252b5132 9960 break;
103f02d3 9961
f16a9783 9962 case DT_MIPS_XHASH:
978c4450
AM
9963 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
9964 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
9965 /* Falls through. */
9966
103f02d3 9967 default:
4b68bca3 9968 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9969 }
4b68bca3 9970 putchar ('\n');
103f02d3
UD
9971}
9972
103f02d3 9973static void
2cf0635d 9974dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9975{
9976 switch (entry->d_tag)
9977 {
9978 case DT_HP_DLD_FLAGS:
9979 {
9980 static struct
9981 {
9982 long int bit;
2cf0635d 9983 const char * str;
5e220199
NC
9984 }
9985 flags[] =
9986 {
9987 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9988 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9989 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9990 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9991 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9992 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9993 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9994 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9995 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9996 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9997 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9998 { DT_HP_GST, "HP_GST" },
9999 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10000 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10001 { DT_HP_NODELETE, "HP_NODELETE" },
10002 { DT_HP_GROUP, "HP_GROUP" },
10003 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10004 };
015dc7e1 10005 bool first = true;
5e220199 10006 size_t cnt;
f7a99963 10007 bfd_vma val = entry->d_un.d_val;
103f02d3 10008
60bca95a 10009 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10010 if (val & flags[cnt].bit)
30800947
NC
10011 {
10012 if (! first)
10013 putchar (' ');
10014 fputs (flags[cnt].str, stdout);
015dc7e1 10015 first = false;
30800947
NC
10016 val ^= flags[cnt].bit;
10017 }
76da6bbe 10018
103f02d3 10019 if (val != 0 || first)
f7a99963
NC
10020 {
10021 if (! first)
10022 putchar (' ');
10023 print_vma (val, HEX);
10024 }
103f02d3
UD
10025 }
10026 break;
76da6bbe 10027
252b5132 10028 default:
f7a99963
NC
10029 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10030 break;
252b5132 10031 }
35b1837e 10032 putchar ('\n');
252b5132
RH
10033}
10034
28f997cf
TG
10035#ifdef BFD64
10036
10037/* VMS vs Unix time offset and factor. */
10038
10039#define VMS_EPOCH_OFFSET 35067168000000000LL
10040#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10041#ifndef INT64_MIN
10042#define INT64_MIN (-9223372036854775807LL - 1)
10043#endif
28f997cf
TG
10044
10045/* Display a VMS time in a human readable format. */
10046
10047static void
10048print_vms_time (bfd_int64_t vmstime)
10049{
dccc31de 10050 struct tm *tm = NULL;
28f997cf
TG
10051 time_t unxtime;
10052
dccc31de
AM
10053 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10054 {
10055 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10056 unxtime = vmstime;
10057 if (unxtime == vmstime)
10058 tm = gmtime (&unxtime);
10059 }
10060 if (tm != NULL)
10061 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10062 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10063 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
10064}
10065#endif /* BFD64 */
10066
ecc51f48 10067static void
2cf0635d 10068dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10069{
10070 switch (entry->d_tag)
10071 {
0de14b54 10072 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10073 /* First 3 slots reserved. */
ecc51f48
NC
10074 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10075 printf (" -- ");
10076 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10077 break;
10078
28f997cf
TG
10079 case DT_IA_64_VMS_LINKTIME:
10080#ifdef BFD64
10081 print_vms_time (entry->d_un.d_val);
10082#endif
10083 break;
10084
10085 case DT_IA_64_VMS_LNKFLAGS:
10086 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10087 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10088 printf (" CALL_DEBUG");
10089 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10090 printf (" NOP0BUFS");
10091 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10092 printf (" P0IMAGE");
10093 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10094 printf (" MKTHREADS");
10095 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10096 printf (" UPCALLS");
10097 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10098 printf (" IMGSTA");
10099 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10100 printf (" INITIALIZE");
10101 if (entry->d_un.d_val & VMS_LF_MAIN)
10102 printf (" MAIN");
10103 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10104 printf (" EXE_INIT");
10105 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10106 printf (" TBK_IN_IMG");
10107 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10108 printf (" DBG_IN_IMG");
10109 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10110 printf (" TBK_IN_DSF");
10111 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10112 printf (" DBG_IN_DSF");
10113 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10114 printf (" SIGNATURES");
10115 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10116 printf (" REL_SEG_OFF");
10117 break;
10118
bdf4d63a
JJ
10119 default:
10120 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10121 break;
ecc51f48 10122 }
bdf4d63a 10123 putchar ('\n');
ecc51f48
NC
10124}
10125
015dc7e1 10126static bool
dda8d76d 10127get_32bit_dynamic_section (Filedata * filedata)
252b5132 10128{
2cf0635d
NC
10129 Elf32_External_Dyn * edyn;
10130 Elf32_External_Dyn * ext;
10131 Elf_Internal_Dyn * entry;
103f02d3 10132
978c4450
AM
10133 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10134 filedata->dynamic_addr, 1,
10135 filedata->dynamic_size,
10136 _("dynamic section"));
a6e9f9df 10137 if (!edyn)
015dc7e1 10138 return false;
103f02d3 10139
071436c6
NC
10140 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10141 might not have the luxury of section headers. Look for the DT_NULL
10142 terminator to determine the number of entries. */
978c4450
AM
10143 for (ext = edyn, filedata->dynamic_nent = 0;
10144 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10145 ext++)
10146 {
978c4450 10147 filedata->dynamic_nent++;
ba2685cc
AM
10148 if (BYTE_GET (ext->d_tag) == DT_NULL)
10149 break;
10150 }
252b5132 10151
978c4450
AM
10152 filedata->dynamic_section
10153 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10154 if (filedata->dynamic_section == NULL)
252b5132 10155 {
8b73c356 10156 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10157 (unsigned long) filedata->dynamic_nent);
9ea033b2 10158 free (edyn);
015dc7e1 10159 return false;
9ea033b2 10160 }
252b5132 10161
978c4450
AM
10162 for (ext = edyn, entry = filedata->dynamic_section;
10163 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10164 ext++, entry++)
9ea033b2 10165 {
fb514b26
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
9ea033b2
NC
10170 free (edyn);
10171
015dc7e1 10172 return true;
9ea033b2
NC
10173}
10174
015dc7e1 10175static bool
dda8d76d 10176get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10177{
2cf0635d
NC
10178 Elf64_External_Dyn * edyn;
10179 Elf64_External_Dyn * ext;
10180 Elf_Internal_Dyn * entry;
103f02d3 10181
071436c6 10182 /* Read in the data. */
978c4450
AM
10183 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10184 filedata->dynamic_addr, 1,
10185 filedata->dynamic_size,
10186 _("dynamic section"));
a6e9f9df 10187 if (!edyn)
015dc7e1 10188 return false;
103f02d3 10189
071436c6
NC
10190 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10191 might not have the luxury of section headers. Look for the DT_NULL
10192 terminator to determine the number of entries. */
978c4450 10193 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10194 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10195 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10196 ext++)
10197 {
978c4450 10198 filedata->dynamic_nent++;
66543521 10199 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10200 break;
10201 }
252b5132 10202
978c4450
AM
10203 filedata->dynamic_section
10204 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10205 if (filedata->dynamic_section == NULL)
252b5132 10206 {
8b73c356 10207 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10208 (unsigned long) filedata->dynamic_nent);
252b5132 10209 free (edyn);
015dc7e1 10210 return false;
252b5132
RH
10211 }
10212
071436c6 10213 /* Convert from external to internal formats. */
978c4450
AM
10214 for (ext = edyn, entry = filedata->dynamic_section;
10215 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10216 ext++, entry++)
252b5132 10217 {
66543521
AM
10218 entry->d_tag = BYTE_GET (ext->d_tag);
10219 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10220 }
10221
10222 free (edyn);
10223
015dc7e1 10224 return true;
9ea033b2
NC
10225}
10226
e9e44622
JJ
10227static void
10228print_dynamic_flags (bfd_vma flags)
d1133906 10229{
015dc7e1 10230 bool first = true;
13ae64f3 10231
d1133906
NC
10232 while (flags)
10233 {
10234 bfd_vma flag;
10235
10236 flag = flags & - flags;
10237 flags &= ~ flag;
10238
e9e44622 10239 if (first)
015dc7e1 10240 first = false;
e9e44622
JJ
10241 else
10242 putc (' ', stdout);
13ae64f3 10243
d1133906
NC
10244 switch (flag)
10245 {
e9e44622
JJ
10246 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10247 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10248 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10249 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10250 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10251 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10252 }
10253 }
e9e44622 10254 puts ("");
d1133906
NC
10255}
10256
10ca4b04
L
10257static bfd_vma *
10258get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10259{
10260 unsigned char * e_data;
10261 bfd_vma * i_data;
10262
10263 /* If the size_t type is smaller than the bfd_size_type, eg because
10264 you are building a 32-bit tool on a 64-bit host, then make sure
10265 that when (number) is cast to (size_t) no information is lost. */
10266 if (sizeof (size_t) < sizeof (bfd_size_type)
10267 && (bfd_size_type) ((size_t) number) != number)
10268 {
10269 error (_("Size truncation prevents reading %s elements of size %u\n"),
10270 bfd_vmatoa ("u", number), ent_size);
10271 return NULL;
10272 }
10273
10274 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10275 attempting to allocate memory when the read is bound to fail. */
10276 if (ent_size * number > filedata->file_size)
10277 {
10278 error (_("Invalid number of dynamic entries: %s\n"),
10279 bfd_vmatoa ("u", number));
10280 return NULL;
10281 }
10282
10283 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10284 if (e_data == NULL)
10285 {
10286 error (_("Out of memory reading %s dynamic entries\n"),
10287 bfd_vmatoa ("u", number));
10288 return NULL;
10289 }
10290
10291 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10292 {
10293 error (_("Unable to read in %s bytes of dynamic data\n"),
10294 bfd_vmatoa ("u", number * ent_size));
10295 free (e_data);
10296 return NULL;
10297 }
10298
10299 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10300 if (i_data == NULL)
10301 {
10302 error (_("Out of memory allocating space for %s dynamic entries\n"),
10303 bfd_vmatoa ("u", number));
10304 free (e_data);
10305 return NULL;
10306 }
10307
10308 while (number--)
10309 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10310
10311 free (e_data);
10312
10313 return i_data;
10314}
10315
10316static unsigned long
10317get_num_dynamic_syms (Filedata * filedata)
10318{
10319 unsigned long num_of_syms = 0;
10320
10321 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10322 return num_of_syms;
10323
978c4450 10324 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10325 {
10326 unsigned char nb[8];
10327 unsigned char nc[8];
10328 unsigned int hash_ent_size = 4;
10329
10330 if ((filedata->file_header.e_machine == EM_ALPHA
10331 || filedata->file_header.e_machine == EM_S390
10332 || filedata->file_header.e_machine == EM_S390_OLD)
10333 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10334 hash_ent_size = 8;
10335
10336 if (fseek (filedata->handle,
978c4450
AM
10337 (filedata->archive_file_offset
10338 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10339 sizeof nb + sizeof nc)),
10340 SEEK_SET))
10341 {
10342 error (_("Unable to seek to start of dynamic information\n"));
10343 goto no_hash;
10344 }
10345
10346 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10347 {
10348 error (_("Failed to read in number of buckets\n"));
10349 goto no_hash;
10350 }
10351
10352 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10353 {
10354 error (_("Failed to read in number of chains\n"));
10355 goto no_hash;
10356 }
10357
978c4450
AM
10358 filedata->nbuckets = byte_get (nb, hash_ent_size);
10359 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10360
2482f306
AM
10361 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10362 {
10363 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10364 hash_ent_size);
10365 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10366 hash_ent_size);
001890e1 10367
2482f306
AM
10368 if (filedata->buckets != NULL && filedata->chains != NULL)
10369 num_of_syms = filedata->nchains;
10370 }
ceb9bf11 10371 no_hash:
10ca4b04
L
10372 if (num_of_syms == 0)
10373 {
9db70fc3
AM
10374 free (filedata->buckets);
10375 filedata->buckets = NULL;
10376 free (filedata->chains);
10377 filedata->chains = NULL;
978c4450 10378 filedata->nbuckets = 0;
10ca4b04
L
10379 }
10380 }
10381
978c4450 10382 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10383 {
10384 unsigned char nb[16];
10385 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10386 bfd_vma buckets_vma;
10387 unsigned long hn;
10ca4b04
L
10388
10389 if (fseek (filedata->handle,
978c4450
AM
10390 (filedata->archive_file_offset
10391 + offset_from_vma (filedata,
10392 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10393 sizeof nb)),
10394 SEEK_SET))
10395 {
10396 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10397 goto no_gnu_hash;
10398 }
10399
10400 if (fread (nb, 16, 1, filedata->handle) != 1)
10401 {
10402 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10403 goto no_gnu_hash;
10404 }
10405
978c4450
AM
10406 filedata->ngnubuckets = byte_get (nb, 4);
10407 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10408 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10409 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10410 if (is_32bit_elf)
10411 buckets_vma += bitmaskwords * 4;
10412 else
10413 buckets_vma += bitmaskwords * 8;
10414
10415 if (fseek (filedata->handle,
978c4450 10416 (filedata->archive_file_offset
10ca4b04
L
10417 + offset_from_vma (filedata, buckets_vma, 4)),
10418 SEEK_SET))
10419 {
10420 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10421 goto no_gnu_hash;
10422 }
10423
978c4450
AM
10424 filedata->gnubuckets
10425 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10426
978c4450 10427 if (filedata->gnubuckets == NULL)
90837ea7 10428 goto no_gnu_hash;
10ca4b04 10429
978c4450
AM
10430 for (i = 0; i < filedata->ngnubuckets; i++)
10431 if (filedata->gnubuckets[i] != 0)
10ca4b04 10432 {
978c4450 10433 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10434 goto no_gnu_hash;
10ca4b04 10435
978c4450
AM
10436 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10437 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10438 }
10439
10440 if (maxchain == 0xffffffff)
90837ea7 10441 goto no_gnu_hash;
10ca4b04 10442
978c4450 10443 maxchain -= filedata->gnusymidx;
10ca4b04
L
10444
10445 if (fseek (filedata->handle,
978c4450
AM
10446 (filedata->archive_file_offset
10447 + offset_from_vma (filedata,
10448 buckets_vma + 4 * (filedata->ngnubuckets
10449 + maxchain),
10450 4)),
10ca4b04
L
10451 SEEK_SET))
10452 {
10453 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10454 goto no_gnu_hash;
10455 }
10456
10457 do
10458 {
10459 if (fread (nb, 4, 1, filedata->handle) != 1)
10460 {
10461 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10462 goto no_gnu_hash;
10463 }
10464
10465 if (maxchain + 1 == 0)
90837ea7 10466 goto no_gnu_hash;
10ca4b04
L
10467
10468 ++maxchain;
10469 }
10470 while ((byte_get (nb, 4) & 1) == 0);
10471
10472 if (fseek (filedata->handle,
978c4450
AM
10473 (filedata->archive_file_offset
10474 + offset_from_vma (filedata, (buckets_vma
10475 + 4 * filedata->ngnubuckets),
10476 4)),
10ca4b04
L
10477 SEEK_SET))
10478 {
10479 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10480 goto no_gnu_hash;
10481 }
10482
978c4450
AM
10483 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10484 filedata->ngnuchains = maxchain;
10ca4b04 10485
978c4450 10486 if (filedata->gnuchains == NULL)
90837ea7 10487 goto no_gnu_hash;
10ca4b04 10488
978c4450 10489 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10490 {
10491 if (fseek (filedata->handle,
978c4450 10492 (filedata->archive_file_offset
10ca4b04 10493 + offset_from_vma (filedata, (buckets_vma
978c4450 10494 + 4 * (filedata->ngnubuckets
10ca4b04
L
10495 + maxchain)), 4)),
10496 SEEK_SET))
10497 {
10498 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10499 goto no_gnu_hash;
10500 }
10501
978c4450 10502 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10503 if (filedata->mipsxlat == NULL)
10504 goto no_gnu_hash;
10ca4b04
L
10505 }
10506
978c4450
AM
10507 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10508 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10509 {
978c4450
AM
10510 bfd_vma si = filedata->gnubuckets[hn];
10511 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10512
10513 do
10514 {
978c4450 10515 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 10516 {
c31ab5a0
AM
10517 if (off < filedata->ngnuchains
10518 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 10519 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
10520 }
10521 else
10522 {
10523 if (si >= num_of_syms)
10524 num_of_syms = si + 1;
10525 }
10526 si++;
10527 }
978c4450
AM
10528 while (off < filedata->ngnuchains
10529 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
10530 }
10531
90837ea7 10532 if (num_of_syms == 0)
10ca4b04 10533 {
90837ea7 10534 no_gnu_hash:
9db70fc3
AM
10535 free (filedata->mipsxlat);
10536 filedata->mipsxlat = NULL;
10537 free (filedata->gnuchains);
10538 filedata->gnuchains = NULL;
10539 free (filedata->gnubuckets);
10540 filedata->gnubuckets = NULL;
978c4450
AM
10541 filedata->ngnubuckets = 0;
10542 filedata->ngnuchains = 0;
10ca4b04
L
10543 }
10544 }
10545
10546 return num_of_syms;
10547}
10548
b2d38a17
NC
10549/* Parse and display the contents of the dynamic section. */
10550
015dc7e1 10551static bool
dda8d76d 10552process_dynamic_section (Filedata * filedata)
9ea033b2 10553{
2cf0635d 10554 Elf_Internal_Dyn * entry;
9ea033b2 10555
978c4450 10556 if (filedata->dynamic_size == 0)
9ea033b2
NC
10557 {
10558 if (do_dynamic)
ca0e11aa
NC
10559 {
10560 if (filedata->is_separate)
10561 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
10562 filedata->file_name);
10563 else
10564 printf (_("\nThere is no dynamic section in this file.\n"));
10565 }
9ea033b2 10566
015dc7e1 10567 return true;
9ea033b2
NC
10568 }
10569
10570 if (is_32bit_elf)
10571 {
dda8d76d 10572 if (! get_32bit_dynamic_section (filedata))
015dc7e1 10573 return false;
32ec8896
NC
10574 }
10575 else
10576 {
dda8d76d 10577 if (! get_64bit_dynamic_section (filedata))
015dc7e1 10578 return false;
9ea033b2 10579 }
9ea033b2 10580
252b5132 10581 /* Find the appropriate symbol table. */
978c4450 10582 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 10583 {
2482f306
AM
10584 unsigned long num_of_syms;
10585
978c4450
AM
10586 for (entry = filedata->dynamic_section;
10587 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10588 ++entry)
10ca4b04 10589 if (entry->d_tag == DT_SYMTAB)
978c4450 10590 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 10591 else if (entry->d_tag == DT_SYMENT)
978c4450 10592 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 10593 else if (entry->d_tag == DT_HASH)
978c4450 10594 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 10595 else if (entry->d_tag == DT_GNU_HASH)
978c4450 10596 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
10597 else if ((filedata->file_header.e_machine == EM_MIPS
10598 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10599 && entry->d_tag == DT_MIPS_XHASH)
10600 {
978c4450
AM
10601 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10602 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 10603 }
252b5132 10604
2482f306
AM
10605 num_of_syms = get_num_dynamic_syms (filedata);
10606
10607 if (num_of_syms != 0
10608 && filedata->dynamic_symbols == NULL
10609 && filedata->dynamic_info[DT_SYMTAB]
978c4450 10610 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
10611 {
10612 Elf_Internal_Phdr *seg;
2482f306 10613 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 10614
2482f306
AM
10615 if (! get_program_headers (filedata))
10616 {
10617 error (_("Cannot interpret virtual addresses "
10618 "without program headers.\n"));
015dc7e1 10619 return false;
2482f306 10620 }
252b5132 10621
2482f306
AM
10622 for (seg = filedata->program_headers;
10623 seg < filedata->program_headers + filedata->file_header.e_phnum;
10624 ++seg)
10625 {
10626 if (seg->p_type != PT_LOAD)
10627 continue;
252b5132 10628
2482f306
AM
10629 if (seg->p_offset + seg->p_filesz > filedata->file_size)
10630 {
10631 /* See PR 21379 for a reproducer. */
10632 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 10633 return false;
2482f306 10634 }
252b5132 10635
2482f306
AM
10636 if (vma >= (seg->p_vaddr & -seg->p_align)
10637 && vma < seg->p_vaddr + seg->p_filesz)
10638 {
10639 /* Since we do not know how big the symbol table is,
10640 we default to reading in up to the end of PT_LOAD
10641 segment and processing that. This is overkill, I
10642 know, but it should work. */
10643 Elf_Internal_Shdr section;
10644 section.sh_offset = (vma - seg->p_vaddr
10645 + seg->p_offset);
10646 section.sh_size = (num_of_syms
10647 * filedata->dynamic_info[DT_SYMENT]);
10648 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
10649
10650 if (do_checks
10651 && filedata->dynamic_symtab_section != NULL
10652 && ((filedata->dynamic_symtab_section->sh_offset
10653 != section.sh_offset)
10654 || (filedata->dynamic_symtab_section->sh_size
10655 != section.sh_size)
10656 || (filedata->dynamic_symtab_section->sh_entsize
10657 != section.sh_entsize)))
10658 warn (_("\
10659the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
10660
2482f306
AM
10661 section.sh_name = filedata->string_table_length;
10662 filedata->dynamic_symbols
10663 = GET_ELF_SYMBOLS (filedata, &section,
10664 &filedata->num_dynamic_syms);
10665 if (filedata->dynamic_symbols == NULL
10666 || filedata->num_dynamic_syms != num_of_syms)
10667 {
10668 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 10669 return false;
2482f306
AM
10670 }
10671 break;
10672 }
10673 }
10674 }
10675 }
252b5132
RH
10676
10677 /* Similarly find a string table. */
978c4450
AM
10678 if (filedata->dynamic_strings == NULL)
10679 for (entry = filedata->dynamic_section;
10680 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
10681 ++entry)
10682 {
10683 if (entry->d_tag == DT_STRTAB)
978c4450 10684 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 10685
10ca4b04 10686 if (entry->d_tag == DT_STRSZ)
978c4450 10687 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10688
978c4450
AM
10689 if (filedata->dynamic_info[DT_STRTAB]
10690 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
10691 {
10692 unsigned long offset;
978c4450 10693 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
10694
10695 offset = offset_from_vma (filedata,
978c4450 10696 filedata->dynamic_info[DT_STRTAB],
10ca4b04 10697 str_tab_len);
8ac10c5b
L
10698 if (do_checks
10699 && filedata->dynamic_strtab_section
10700 && ((filedata->dynamic_strtab_section->sh_offset
10701 != (file_ptr) offset)
10702 || (filedata->dynamic_strtab_section->sh_size
10703 != str_tab_len)))
10704 warn (_("\
10705the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
10706
978c4450
AM
10707 filedata->dynamic_strings
10708 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
10709 _("dynamic string table"));
10710 if (filedata->dynamic_strings == NULL)
10ca4b04
L
10711 {
10712 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10713 break;
10714 }
e3d39609 10715
978c4450 10716 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
10717 break;
10718 }
10719 }
252b5132
RH
10720
10721 /* And find the syminfo section if available. */
978c4450 10722 if (filedata->dynamic_syminfo == NULL)
252b5132 10723 {
3e8bba36 10724 unsigned long syminsz = 0;
252b5132 10725
978c4450
AM
10726 for (entry = filedata->dynamic_section;
10727 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10728 ++entry)
252b5132
RH
10729 {
10730 if (entry->d_tag == DT_SYMINENT)
10731 {
10732 /* Note: these braces are necessary to avoid a syntax
10733 error from the SunOS4 C compiler. */
049b0c3a
NC
10734 /* PR binutils/17531: A corrupt file can trigger this test.
10735 So do not use an assert, instead generate an error message. */
10736 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10737 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10738 (int) entry->d_un.d_val);
252b5132
RH
10739 }
10740 else if (entry->d_tag == DT_SYMINSZ)
10741 syminsz = entry->d_un.d_val;
10742 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
10743 filedata->dynamic_syminfo_offset
10744 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
10745 }
10746
978c4450 10747 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 10748 {
2cf0635d
NC
10749 Elf_External_Syminfo * extsyminfo;
10750 Elf_External_Syminfo * extsym;
10751 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10752
10753 /* There is a syminfo section. Read the data. */
3f5e193b 10754 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
10755 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
10756 1, syminsz, _("symbol information"));
a6e9f9df 10757 if (!extsyminfo)
015dc7e1 10758 return false;
252b5132 10759
978c4450 10760 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
10761 {
10762 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 10763 free (filedata->dynamic_syminfo);
e3d39609 10764 }
978c4450
AM
10765 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
10766 if (filedata->dynamic_syminfo == NULL)
252b5132 10767 {
2482f306
AM
10768 error (_("Out of memory allocating %lu bytes "
10769 "for dynamic symbol info\n"),
8b73c356 10770 (unsigned long) syminsz);
015dc7e1 10771 return false;
252b5132
RH
10772 }
10773
2482f306
AM
10774 filedata->dynamic_syminfo_nent
10775 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 10776 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
10777 syminfo < (filedata->dynamic_syminfo
10778 + filedata->dynamic_syminfo_nent);
86dba8ee 10779 ++syminfo, ++extsym)
252b5132 10780 {
86dba8ee
AM
10781 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10782 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10783 }
10784
10785 free (extsyminfo);
10786 }
10787 }
10788
978c4450 10789 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa
NC
10790 {
10791 if (filedata->dynamic_nent == 1)
10792 {
10793 if (filedata->is_separate)
10794 printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains 1 entry:\n"),
10795 filedata->file_name,
10796 filedata->dynamic_addr);
10797 else
10798 printf (_("\nDynamic section at offset 0x%lx contains 1 entry:\n"),
10799 filedata->dynamic_addr);
10800 }
10801 else
10802 {
10803 if (filedata->is_separate)
10804 printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n"),
10805 filedata->file_name,
10806 filedata->dynamic_addr,
10807 (unsigned long) filedata->dynamic_nent);
10808 else
10809 printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
10810 filedata->dynamic_addr,
10811 (unsigned long) filedata->dynamic_nent);
10812 }
10813 }
252b5132
RH
10814 if (do_dynamic)
10815 printf (_(" Tag Type Name/Value\n"));
10816
978c4450
AM
10817 for (entry = filedata->dynamic_section;
10818 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10819 entry++)
252b5132
RH
10820 {
10821 if (do_dynamic)
f7a99963 10822 {
2cf0635d 10823 const char * dtype;
e699b9ff 10824
f7a99963
NC
10825 putchar (' ');
10826 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10827 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10828 printf (" (%s)%*s", dtype,
32ec8896 10829 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10830 }
252b5132
RH
10831
10832 switch (entry->d_tag)
10833 {
d1133906
NC
10834 case DT_FLAGS:
10835 if (do_dynamic)
e9e44622 10836 print_dynamic_flags (entry->d_un.d_val);
d1133906 10837 break;
76da6bbe 10838
252b5132
RH
10839 case DT_AUXILIARY:
10840 case DT_FILTER:
019148e4
L
10841 case DT_CONFIG:
10842 case DT_DEPAUDIT:
10843 case DT_AUDIT:
252b5132
RH
10844 if (do_dynamic)
10845 {
019148e4 10846 switch (entry->d_tag)
b34976b6 10847 {
019148e4
L
10848 case DT_AUXILIARY:
10849 printf (_("Auxiliary library"));
10850 break;
10851
10852 case DT_FILTER:
10853 printf (_("Filter library"));
10854 break;
10855
b34976b6 10856 case DT_CONFIG:
019148e4
L
10857 printf (_("Configuration file"));
10858 break;
10859
10860 case DT_DEPAUDIT:
10861 printf (_("Dependency audit library"));
10862 break;
10863
10864 case DT_AUDIT:
10865 printf (_("Audit library"));
10866 break;
10867 }
252b5132 10868
978c4450
AM
10869 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10870 printf (": [%s]\n",
10871 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 10872 else
f7a99963
NC
10873 {
10874 printf (": ");
10875 print_vma (entry->d_un.d_val, PREFIX_HEX);
10876 putchar ('\n');
10877 }
252b5132
RH
10878 }
10879 break;
10880
dcefbbbd 10881 case DT_FEATURE:
252b5132
RH
10882 if (do_dynamic)
10883 {
10884 printf (_("Flags:"));
86f55779 10885
252b5132
RH
10886 if (entry->d_un.d_val == 0)
10887 printf (_(" None\n"));
10888 else
10889 {
10890 unsigned long int val = entry->d_un.d_val;
86f55779 10891
252b5132
RH
10892 if (val & DTF_1_PARINIT)
10893 {
10894 printf (" PARINIT");
10895 val ^= DTF_1_PARINIT;
10896 }
dcefbbbd
L
10897 if (val & DTF_1_CONFEXP)
10898 {
10899 printf (" CONFEXP");
10900 val ^= DTF_1_CONFEXP;
10901 }
252b5132
RH
10902 if (val != 0)
10903 printf (" %lx", val);
10904 puts ("");
10905 }
10906 }
10907 break;
10908
10909 case DT_POSFLAG_1:
10910 if (do_dynamic)
10911 {
10912 printf (_("Flags:"));
86f55779 10913
252b5132
RH
10914 if (entry->d_un.d_val == 0)
10915 printf (_(" None\n"));
10916 else
10917 {
10918 unsigned long int val = entry->d_un.d_val;
86f55779 10919
252b5132
RH
10920 if (val & DF_P1_LAZYLOAD)
10921 {
10922 printf (" LAZYLOAD");
10923 val ^= DF_P1_LAZYLOAD;
10924 }
10925 if (val & DF_P1_GROUPPERM)
10926 {
10927 printf (" GROUPPERM");
10928 val ^= DF_P1_GROUPPERM;
10929 }
10930 if (val != 0)
10931 printf (" %lx", val);
10932 puts ("");
10933 }
10934 }
10935 break;
10936
10937 case DT_FLAGS_1:
10938 if (do_dynamic)
10939 {
10940 printf (_("Flags:"));
10941 if (entry->d_un.d_val == 0)
10942 printf (_(" None\n"));
10943 else
10944 {
10945 unsigned long int val = entry->d_un.d_val;
86f55779 10946
252b5132
RH
10947 if (val & DF_1_NOW)
10948 {
10949 printf (" NOW");
10950 val ^= DF_1_NOW;
10951 }
10952 if (val & DF_1_GLOBAL)
10953 {
10954 printf (" GLOBAL");
10955 val ^= DF_1_GLOBAL;
10956 }
10957 if (val & DF_1_GROUP)
10958 {
10959 printf (" GROUP");
10960 val ^= DF_1_GROUP;
10961 }
10962 if (val & DF_1_NODELETE)
10963 {
10964 printf (" NODELETE");
10965 val ^= DF_1_NODELETE;
10966 }
10967 if (val & DF_1_LOADFLTR)
10968 {
10969 printf (" LOADFLTR");
10970 val ^= DF_1_LOADFLTR;
10971 }
10972 if (val & DF_1_INITFIRST)
10973 {
10974 printf (" INITFIRST");
10975 val ^= DF_1_INITFIRST;
10976 }
10977 if (val & DF_1_NOOPEN)
10978 {
10979 printf (" NOOPEN");
10980 val ^= DF_1_NOOPEN;
10981 }
10982 if (val & DF_1_ORIGIN)
10983 {
10984 printf (" ORIGIN");
10985 val ^= DF_1_ORIGIN;
10986 }
10987 if (val & DF_1_DIRECT)
10988 {
10989 printf (" DIRECT");
10990 val ^= DF_1_DIRECT;
10991 }
10992 if (val & DF_1_TRANS)
10993 {
10994 printf (" TRANS");
10995 val ^= DF_1_TRANS;
10996 }
10997 if (val & DF_1_INTERPOSE)
10998 {
10999 printf (" INTERPOSE");
11000 val ^= DF_1_INTERPOSE;
11001 }
f7db6139 11002 if (val & DF_1_NODEFLIB)
dcefbbbd 11003 {
f7db6139
L
11004 printf (" NODEFLIB");
11005 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11006 }
11007 if (val & DF_1_NODUMP)
11008 {
11009 printf (" NODUMP");
11010 val ^= DF_1_NODUMP;
11011 }
34b60028 11012 if (val & DF_1_CONFALT)
dcefbbbd 11013 {
34b60028
L
11014 printf (" CONFALT");
11015 val ^= DF_1_CONFALT;
11016 }
11017 if (val & DF_1_ENDFILTEE)
11018 {
11019 printf (" ENDFILTEE");
11020 val ^= DF_1_ENDFILTEE;
11021 }
11022 if (val & DF_1_DISPRELDNE)
11023 {
11024 printf (" DISPRELDNE");
11025 val ^= DF_1_DISPRELDNE;
11026 }
11027 if (val & DF_1_DISPRELPND)
11028 {
11029 printf (" DISPRELPND");
11030 val ^= DF_1_DISPRELPND;
11031 }
11032 if (val & DF_1_NODIRECT)
11033 {
11034 printf (" NODIRECT");
11035 val ^= DF_1_NODIRECT;
11036 }
11037 if (val & DF_1_IGNMULDEF)
11038 {
11039 printf (" IGNMULDEF");
11040 val ^= DF_1_IGNMULDEF;
11041 }
11042 if (val & DF_1_NOKSYMS)
11043 {
11044 printf (" NOKSYMS");
11045 val ^= DF_1_NOKSYMS;
11046 }
11047 if (val & DF_1_NOHDR)
11048 {
11049 printf (" NOHDR");
11050 val ^= DF_1_NOHDR;
11051 }
11052 if (val & DF_1_EDITED)
11053 {
11054 printf (" EDITED");
11055 val ^= DF_1_EDITED;
11056 }
11057 if (val & DF_1_NORELOC)
11058 {
11059 printf (" NORELOC");
11060 val ^= DF_1_NORELOC;
11061 }
11062 if (val & DF_1_SYMINTPOSE)
11063 {
11064 printf (" SYMINTPOSE");
11065 val ^= DF_1_SYMINTPOSE;
11066 }
11067 if (val & DF_1_GLOBAUDIT)
11068 {
11069 printf (" GLOBAUDIT");
11070 val ^= DF_1_GLOBAUDIT;
11071 }
11072 if (val & DF_1_SINGLETON)
11073 {
11074 printf (" SINGLETON");
11075 val ^= DF_1_SINGLETON;
dcefbbbd 11076 }
5c383f02
RO
11077 if (val & DF_1_STUB)
11078 {
11079 printf (" STUB");
11080 val ^= DF_1_STUB;
11081 }
11082 if (val & DF_1_PIE)
11083 {
11084 printf (" PIE");
11085 val ^= DF_1_PIE;
11086 }
b1202ffa
L
11087 if (val & DF_1_KMOD)
11088 {
11089 printf (" KMOD");
11090 val ^= DF_1_KMOD;
11091 }
11092 if (val & DF_1_WEAKFILTER)
11093 {
11094 printf (" WEAKFILTER");
11095 val ^= DF_1_WEAKFILTER;
11096 }
11097 if (val & DF_1_NOCOMMON)
11098 {
11099 printf (" NOCOMMON");
11100 val ^= DF_1_NOCOMMON;
11101 }
252b5132
RH
11102 if (val != 0)
11103 printf (" %lx", val);
11104 puts ("");
11105 }
11106 }
11107 break;
11108
11109 case DT_PLTREL:
978c4450 11110 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11111 if (do_dynamic)
dda8d76d 11112 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11113 break;
11114
11115 case DT_NULL :
11116 case DT_NEEDED :
11117 case DT_PLTGOT :
11118 case DT_HASH :
11119 case DT_STRTAB :
11120 case DT_SYMTAB :
11121 case DT_RELA :
11122 case DT_INIT :
11123 case DT_FINI :
11124 case DT_SONAME :
11125 case DT_RPATH :
11126 case DT_SYMBOLIC:
11127 case DT_REL :
11128 case DT_DEBUG :
11129 case DT_TEXTREL :
11130 case DT_JMPREL :
019148e4 11131 case DT_RUNPATH :
978c4450 11132 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11133
11134 if (do_dynamic)
11135 {
2cf0635d 11136 char * name;
252b5132 11137
978c4450
AM
11138 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
11139 name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11140 else
d79b3d50 11141 name = NULL;
252b5132
RH
11142
11143 if (name)
11144 {
11145 switch (entry->d_tag)
11146 {
11147 case DT_NEEDED:
11148 printf (_("Shared library: [%s]"), name);
11149
13acb58d
AM
11150 if (filedata->program_interpreter
11151 && streq (name, filedata->program_interpreter))
f7a99963 11152 printf (_(" program interpreter"));
252b5132
RH
11153 break;
11154
11155 case DT_SONAME:
f7a99963 11156 printf (_("Library soname: [%s]"), name);
252b5132
RH
11157 break;
11158
11159 case DT_RPATH:
f7a99963 11160 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11161 break;
11162
019148e4
L
11163 case DT_RUNPATH:
11164 printf (_("Library runpath: [%s]"), name);
11165 break;
11166
252b5132 11167 default:
f7a99963
NC
11168 print_vma (entry->d_un.d_val, PREFIX_HEX);
11169 break;
252b5132
RH
11170 }
11171 }
11172 else
f7a99963
NC
11173 print_vma (entry->d_un.d_val, PREFIX_HEX);
11174
11175 putchar ('\n');
252b5132
RH
11176 }
11177 break;
11178
11179 case DT_PLTRELSZ:
11180 case DT_RELASZ :
11181 case DT_STRSZ :
11182 case DT_RELSZ :
11183 case DT_RELAENT :
11184 case DT_SYMENT :
11185 case DT_RELENT :
978c4450 11186 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11187 /* Fall through. */
252b5132
RH
11188 case DT_PLTPADSZ:
11189 case DT_MOVEENT :
11190 case DT_MOVESZ :
11191 case DT_INIT_ARRAYSZ:
11192 case DT_FINI_ARRAYSZ:
047b2264
JJ
11193 case DT_GNU_CONFLICTSZ:
11194 case DT_GNU_LIBLISTSZ:
252b5132 11195 if (do_dynamic)
f7a99963
NC
11196 {
11197 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11198 printf (_(" (bytes)\n"));
f7a99963 11199 }
252b5132
RH
11200 break;
11201
11202 case DT_VERDEFNUM:
11203 case DT_VERNEEDNUM:
11204 case DT_RELACOUNT:
11205 case DT_RELCOUNT:
11206 if (do_dynamic)
f7a99963
NC
11207 {
11208 print_vma (entry->d_un.d_val, UNSIGNED);
11209 putchar ('\n');
11210 }
252b5132
RH
11211 break;
11212
11213 case DT_SYMINSZ:
11214 case DT_SYMINENT:
11215 case DT_SYMINFO:
11216 case DT_USED:
11217 case DT_INIT_ARRAY:
11218 case DT_FINI_ARRAY:
11219 if (do_dynamic)
11220 {
d79b3d50 11221 if (entry->d_tag == DT_USED
978c4450 11222 && VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
252b5132 11223 {
978c4450 11224 char * name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11225
b34976b6 11226 if (*name)
252b5132
RH
11227 {
11228 printf (_("Not needed object: [%s]\n"), name);
11229 break;
11230 }
11231 }
103f02d3 11232
f7a99963
NC
11233 print_vma (entry->d_un.d_val, PREFIX_HEX);
11234 putchar ('\n');
252b5132
RH
11235 }
11236 break;
11237
11238 case DT_BIND_NOW:
11239 /* The value of this entry is ignored. */
35b1837e
AM
11240 if (do_dynamic)
11241 putchar ('\n');
252b5132 11242 break;
103f02d3 11243
047b2264
JJ
11244 case DT_GNU_PRELINKED:
11245 if (do_dynamic)
11246 {
2cf0635d 11247 struct tm * tmp;
91d6fa6a 11248 time_t atime = entry->d_un.d_val;
047b2264 11249
91d6fa6a 11250 tmp = gmtime (&atime);
071436c6
NC
11251 /* PR 17533 file: 041-1244816-0.004. */
11252 if (tmp == NULL)
5a2cbcf4
L
11253 printf (_("<corrupt time val: %lx"),
11254 (unsigned long) atime);
071436c6
NC
11255 else
11256 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11257 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11258 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11259
11260 }
11261 break;
11262
fdc90cb4 11263 case DT_GNU_HASH:
978c4450 11264 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11265 if (do_dynamic)
11266 {
11267 print_vma (entry->d_un.d_val, PREFIX_HEX);
11268 putchar ('\n');
11269 }
11270 break;
11271
a5da3dee
VDM
11272 case DT_GNU_FLAGS_1:
11273 if (do_dynamic)
11274 {
11275 printf (_("Flags:"));
11276 if (entry->d_un.d_val == 0)
11277 printf (_(" None\n"));
11278 else
11279 {
11280 unsigned long int val = entry->d_un.d_val;
11281
11282 if (val & DF_GNU_1_UNIQUE)
11283 {
11284 printf (" UNIQUE");
11285 val ^= DF_GNU_1_UNIQUE;
11286 }
11287 if (val != 0)
11288 printf (" %lx", val);
11289 puts ("");
11290 }
11291 }
11292 break;
11293
252b5132
RH
11294 default:
11295 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11296 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11297 = entry->d_un.d_val;
252b5132
RH
11298
11299 if (do_dynamic)
11300 {
dda8d76d 11301 switch (filedata->file_header.e_machine)
252b5132 11302 {
37c18eed
SD
11303 case EM_AARCH64:
11304 dynamic_section_aarch64_val (entry);
11305 break;
252b5132 11306 case EM_MIPS:
4fe85591 11307 case EM_MIPS_RS3_LE:
978c4450 11308 dynamic_section_mips_val (filedata, entry);
252b5132 11309 break;
103f02d3 11310 case EM_PARISC:
b2d38a17 11311 dynamic_section_parisc_val (entry);
103f02d3 11312 break;
ecc51f48 11313 case EM_IA_64:
b2d38a17 11314 dynamic_section_ia64_val (entry);
ecc51f48 11315 break;
252b5132 11316 default:
f7a99963
NC
11317 print_vma (entry->d_un.d_val, PREFIX_HEX);
11318 putchar ('\n');
252b5132
RH
11319 }
11320 }
11321 break;
11322 }
11323 }
11324
015dc7e1 11325 return true;
252b5132
RH
11326}
11327
11328static char *
d3ba0551 11329get_ver_flags (unsigned int flags)
252b5132 11330{
6d4f21f6 11331 static char buff[128];
252b5132
RH
11332
11333 buff[0] = 0;
11334
11335 if (flags == 0)
11336 return _("none");
11337
11338 if (flags & VER_FLG_BASE)
7bb1ad17 11339 strcat (buff, "BASE");
252b5132
RH
11340
11341 if (flags & VER_FLG_WEAK)
11342 {
11343 if (flags & VER_FLG_BASE)
7bb1ad17 11344 strcat (buff, " | ");
252b5132 11345
7bb1ad17 11346 strcat (buff, "WEAK");
252b5132
RH
11347 }
11348
44ec90b9
RO
11349 if (flags & VER_FLG_INFO)
11350 {
11351 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11352 strcat (buff, " | ");
44ec90b9 11353
7bb1ad17 11354 strcat (buff, "INFO");
44ec90b9
RO
11355 }
11356
11357 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11358 {
11359 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11360 strcat (buff, " | ");
11361
11362 strcat (buff, _("<unknown>"));
11363 }
252b5132
RH
11364
11365 return buff;
11366}
11367
11368/* Display the contents of the version sections. */
98fb390a 11369
015dc7e1 11370static bool
dda8d76d 11371process_version_sections (Filedata * filedata)
252b5132 11372{
2cf0635d 11373 Elf_Internal_Shdr * section;
b34976b6 11374 unsigned i;
015dc7e1 11375 bool found = false;
252b5132
RH
11376
11377 if (! do_version)
015dc7e1 11378 return true;
252b5132 11379
dda8d76d
NC
11380 for (i = 0, section = filedata->section_headers;
11381 i < filedata->file_header.e_shnum;
b34976b6 11382 i++, section++)
252b5132
RH
11383 {
11384 switch (section->sh_type)
11385 {
11386 case SHT_GNU_verdef:
11387 {
2cf0635d 11388 Elf_External_Verdef * edefs;
452bf675
AM
11389 unsigned long idx;
11390 unsigned long cnt;
2cf0635d 11391 char * endbuf;
252b5132 11392
015dc7e1 11393 found = true;
252b5132 11394
ca0e11aa
NC
11395 if (filedata->is_separate)
11396 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
11397 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
11398 section->sh_info),
11399 filedata->file_name,
11400 printable_section_name (filedata, section),
11401 section->sh_info);
11402 else
11403 printf (ngettext ("\nVersion definition section '%s' "
11404 "contains %u entry:\n",
11405 "\nVersion definition section '%s' "
11406 "contains %u entries:\n",
11407 section->sh_info),
11408 printable_section_name (filedata, section),
11409 section->sh_info);
047c3dbf 11410
ae9ac79e 11411 printf (_(" Addr: 0x"));
252b5132 11412 printf_vma (section->sh_addr);
233f82cf 11413 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11414 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11415 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11416
3f5e193b 11417 edefs = (Elf_External_Verdef *)
dda8d76d 11418 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11419 _("version definition section"));
a6e9f9df
AM
11420 if (!edefs)
11421 break;
59245841 11422 endbuf = (char *) edefs + section->sh_size;
252b5132 11423
1445030f 11424 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11425 {
2cf0635d
NC
11426 char * vstart;
11427 Elf_External_Verdef * edef;
b34976b6 11428 Elf_Internal_Verdef ent;
2cf0635d 11429 Elf_External_Verdaux * eaux;
b34976b6 11430 Elf_Internal_Verdaux aux;
452bf675 11431 unsigned long isum;
b34976b6 11432 int j;
103f02d3 11433
252b5132 11434 vstart = ((char *) edefs) + idx;
54806181
AM
11435 if (vstart + sizeof (*edef) > endbuf)
11436 break;
252b5132
RH
11437
11438 edef = (Elf_External_Verdef *) vstart;
11439
11440 ent.vd_version = BYTE_GET (edef->vd_version);
11441 ent.vd_flags = BYTE_GET (edef->vd_flags);
11442 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11443 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11444 ent.vd_hash = BYTE_GET (edef->vd_hash);
11445 ent.vd_aux = BYTE_GET (edef->vd_aux);
11446 ent.vd_next = BYTE_GET (edef->vd_next);
11447
452bf675 11448 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11449 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11450
11451 printf (_(" Index: %d Cnt: %d "),
11452 ent.vd_ndx, ent.vd_cnt);
11453
452bf675 11454 /* Check for overflow. */
1445030f 11455 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11456 break;
11457
252b5132
RH
11458 vstart += ent.vd_aux;
11459
1445030f
AM
11460 if (vstart + sizeof (*eaux) > endbuf)
11461 break;
252b5132
RH
11462 eaux = (Elf_External_Verdaux *) vstart;
11463
11464 aux.vda_name = BYTE_GET (eaux->vda_name);
11465 aux.vda_next = BYTE_GET (eaux->vda_next);
11466
978c4450
AM
11467 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
11468 printf (_("Name: %s\n"),
11469 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132
RH
11470 else
11471 printf (_("Name index: %ld\n"), aux.vda_name);
11472
11473 isum = idx + ent.vd_aux;
11474
b34976b6 11475 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11476 {
1445030f
AM
11477 if (aux.vda_next < sizeof (*eaux)
11478 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11479 {
11480 warn (_("Invalid vda_next field of %lx\n"),
11481 aux.vda_next);
11482 j = ent.vd_cnt;
11483 break;
11484 }
dd24e3da 11485 /* Check for overflow. */
7e26601c 11486 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11487 break;
11488
252b5132
RH
11489 isum += aux.vda_next;
11490 vstart += aux.vda_next;
11491
54806181
AM
11492 if (vstart + sizeof (*eaux) > endbuf)
11493 break;
1445030f 11494 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11495
11496 aux.vda_name = BYTE_GET (eaux->vda_name);
11497 aux.vda_next = BYTE_GET (eaux->vda_next);
11498
978c4450 11499 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
452bf675 11500 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450
AM
11501 isum, j,
11502 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132 11503 else
452bf675 11504 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11505 isum, j, aux.vda_name);
11506 }
dd24e3da 11507
54806181
AM
11508 if (j < ent.vd_cnt)
11509 printf (_(" Version def aux past end of section\n"));
252b5132 11510
c9f02c3e
MR
11511 /* PR 17531:
11512 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11513 if (ent.vd_next < sizeof (*edef)
11514 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11515 {
11516 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11517 cnt = section->sh_info;
11518 break;
11519 }
452bf675 11520 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11521 break;
11522
252b5132
RH
11523 idx += ent.vd_next;
11524 }
dd24e3da 11525
54806181
AM
11526 if (cnt < section->sh_info)
11527 printf (_(" Version definition past end of section\n"));
252b5132
RH
11528
11529 free (edefs);
11530 }
11531 break;
103f02d3 11532
252b5132
RH
11533 case SHT_GNU_verneed:
11534 {
2cf0635d 11535 Elf_External_Verneed * eneed;
452bf675
AM
11536 unsigned long idx;
11537 unsigned long cnt;
2cf0635d 11538 char * endbuf;
252b5132 11539
015dc7e1 11540 found = true;
252b5132 11541
ca0e11aa
NC
11542 if (filedata->is_separate)
11543 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
11544 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
11545 section->sh_info),
11546 filedata->file_name,
11547 printable_section_name (filedata, section),
11548 section->sh_info);
11549 else
11550 printf (ngettext ("\nVersion needs section '%s' "
11551 "contains %u entry:\n",
11552 "\nVersion needs section '%s' "
11553 "contains %u entries:\n",
11554 section->sh_info),
11555 printable_section_name (filedata, section),
11556 section->sh_info);
047c3dbf 11557
252b5132
RH
11558 printf (_(" Addr: 0x"));
11559 printf_vma (section->sh_addr);
72de5009 11560 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11561 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11562 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11563
dda8d76d 11564 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11565 section->sh_offset, 1,
11566 section->sh_size,
9cf03b7e 11567 _("Version Needs section"));
a6e9f9df
AM
11568 if (!eneed)
11569 break;
59245841 11570 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11571
11572 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11573 {
2cf0635d 11574 Elf_External_Verneed * entry;
b34976b6 11575 Elf_Internal_Verneed ent;
452bf675 11576 unsigned long isum;
b34976b6 11577 int j;
2cf0635d 11578 char * vstart;
252b5132
RH
11579
11580 vstart = ((char *) eneed) + idx;
54806181
AM
11581 if (vstart + sizeof (*entry) > endbuf)
11582 break;
252b5132
RH
11583
11584 entry = (Elf_External_Verneed *) vstart;
11585
11586 ent.vn_version = BYTE_GET (entry->vn_version);
11587 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11588 ent.vn_file = BYTE_GET (entry->vn_file);
11589 ent.vn_aux = BYTE_GET (entry->vn_aux);
11590 ent.vn_next = BYTE_GET (entry->vn_next);
11591
452bf675 11592 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11593
978c4450
AM
11594 if (VALID_DYNAMIC_NAME (filedata, ent.vn_file))
11595 printf (_(" File: %s"),
11596 GET_DYNAMIC_NAME (filedata, ent.vn_file));
252b5132
RH
11597 else
11598 printf (_(" File: %lx"), ent.vn_file);
11599
11600 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11601
dd24e3da 11602 /* Check for overflow. */
7e26601c 11603 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11604 break;
252b5132
RH
11605 vstart += ent.vn_aux;
11606
11607 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11608 {
2cf0635d 11609 Elf_External_Vernaux * eaux;
b34976b6 11610 Elf_Internal_Vernaux aux;
252b5132 11611
54806181
AM
11612 if (vstart + sizeof (*eaux) > endbuf)
11613 break;
252b5132
RH
11614 eaux = (Elf_External_Vernaux *) vstart;
11615
11616 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11617 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11618 aux.vna_other = BYTE_GET (eaux->vna_other);
11619 aux.vna_name = BYTE_GET (eaux->vna_name);
11620 aux.vna_next = BYTE_GET (eaux->vna_next);
11621
978c4450 11622 if (VALID_DYNAMIC_NAME (filedata, aux.vna_name))
452bf675 11623 printf (_(" %#06lx: Name: %s"),
978c4450 11624 isum, GET_DYNAMIC_NAME (filedata, aux.vna_name));
252b5132 11625 else
452bf675 11626 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11627 isum, aux.vna_name);
11628
11629 printf (_(" Flags: %s Version: %d\n"),
11630 get_ver_flags (aux.vna_flags), aux.vna_other);
11631
1445030f
AM
11632 if (aux.vna_next < sizeof (*eaux)
11633 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11634 {
11635 warn (_("Invalid vna_next field of %lx\n"),
11636 aux.vna_next);
11637 j = ent.vn_cnt;
11638 break;
11639 }
1445030f
AM
11640 /* Check for overflow. */
11641 if (aux.vna_next > (size_t) (endbuf - vstart))
11642 break;
252b5132
RH
11643 isum += aux.vna_next;
11644 vstart += aux.vna_next;
11645 }
9cf03b7e 11646
54806181 11647 if (j < ent.vn_cnt)
f9a6a8f0 11648 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 11649
1445030f
AM
11650 if (ent.vn_next < sizeof (*entry)
11651 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11652 {
452bf675 11653 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11654 cnt = section->sh_info;
11655 break;
11656 }
1445030f
AM
11657 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11658 break;
252b5132
RH
11659 idx += ent.vn_next;
11660 }
9cf03b7e 11661
54806181 11662 if (cnt < section->sh_info)
9cf03b7e 11663 warn (_("Missing Version Needs information\n"));
103f02d3 11664
252b5132
RH
11665 free (eneed);
11666 }
11667 break;
11668
11669 case SHT_GNU_versym:
11670 {
2cf0635d 11671 Elf_Internal_Shdr * link_section;
8b73c356
NC
11672 size_t total;
11673 unsigned int cnt;
2cf0635d
NC
11674 unsigned char * edata;
11675 unsigned short * data;
11676 char * strtab;
11677 Elf_Internal_Sym * symbols;
11678 Elf_Internal_Shdr * string_sec;
ba5cdace 11679 unsigned long num_syms;
d3ba0551 11680 long off;
252b5132 11681
dda8d76d 11682 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11683 break;
11684
dda8d76d 11685 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11686 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11687
dda8d76d 11688 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11689 break;
11690
015dc7e1 11691 found = true;
252b5132 11692
dda8d76d 11693 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
11694 if (symbols == NULL)
11695 break;
252b5132 11696
dda8d76d 11697 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11698
dda8d76d 11699 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11700 string_sec->sh_size,
11701 _("version string table"));
a6e9f9df 11702 if (!strtab)
0429c154
MS
11703 {
11704 free (symbols);
11705 break;
11706 }
252b5132 11707
ca0e11aa
NC
11708 if (filedata->is_separate)
11709 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
11710 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
11711 total),
11712 filedata->file_name,
11713 printable_section_name (filedata, section),
11714 (unsigned long) total);
11715 else
11716 printf (ngettext ("\nVersion symbols section '%s' "
11717 "contains %lu entry:\n",
11718 "\nVersion symbols section '%s' "
11719 "contains %lu entries:\n",
11720 total),
11721 printable_section_name (filedata, section),
11722 (unsigned long) total);
252b5132 11723
ae9ac79e 11724 printf (_(" Addr: 0x"));
252b5132 11725 printf_vma (section->sh_addr);
72de5009 11726 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11727 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11728 printable_section_name (filedata, link_section));
252b5132 11729
dda8d76d 11730 off = offset_from_vma (filedata,
978c4450 11731 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11732 total * sizeof (short));
95099889
AM
11733 edata = (unsigned char *) get_data (NULL, filedata, off,
11734 sizeof (short), total,
11735 _("version symbol data"));
a6e9f9df
AM
11736 if (!edata)
11737 {
11738 free (strtab);
0429c154 11739 free (symbols);
a6e9f9df
AM
11740 break;
11741 }
252b5132 11742
3f5e193b 11743 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11744
11745 for (cnt = total; cnt --;)
b34976b6
AM
11746 data[cnt] = byte_get (edata + cnt * sizeof (short),
11747 sizeof (short));
252b5132
RH
11748
11749 free (edata);
11750
11751 for (cnt = 0; cnt < total; cnt += 4)
11752 {
11753 int j, nn;
ab273396
AM
11754 char *name;
11755 char *invalid = _("*invalid*");
252b5132
RH
11756
11757 printf (" %03x:", cnt);
11758
11759 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11760 switch (data[cnt + j])
252b5132
RH
11761 {
11762 case 0:
11763 fputs (_(" 0 (*local*) "), stdout);
11764 break;
11765
11766 case 1:
11767 fputs (_(" 1 (*global*) "), stdout);
11768 break;
11769
11770 default:
c244d050
NC
11771 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11772 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11773
dd24e3da 11774 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11775 array, break to avoid an out-of-bounds read. */
11776 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11777 {
11778 warn (_("invalid index into symbol array\n"));
11779 break;
11780 }
11781
ab273396 11782 name = NULL;
978c4450 11783 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11784 {
b34976b6
AM
11785 Elf_Internal_Verneed ivn;
11786 unsigned long offset;
252b5132 11787
d93f0186 11788 offset = offset_from_vma
978c4450
AM
11789 (filedata,
11790 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11791 sizeof (Elf_External_Verneed));
252b5132 11792
b34976b6 11793 do
252b5132 11794 {
b34976b6
AM
11795 Elf_Internal_Vernaux ivna;
11796 Elf_External_Verneed evn;
11797 Elf_External_Vernaux evna;
11798 unsigned long a_off;
252b5132 11799
dda8d76d 11800 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11801 _("version need")) == NULL)
11802 break;
0b4362b0 11803
252b5132
RH
11804 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11805 ivn.vn_next = BYTE_GET (evn.vn_next);
11806
11807 a_off = offset + ivn.vn_aux;
11808
11809 do
11810 {
dda8d76d 11811 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11812 1, _("version need aux (2)")) == NULL)
11813 {
11814 ivna.vna_next = 0;
11815 ivna.vna_other = 0;
11816 }
11817 else
11818 {
11819 ivna.vna_next = BYTE_GET (evna.vna_next);
11820 ivna.vna_other = BYTE_GET (evna.vna_other);
11821 }
252b5132
RH
11822
11823 a_off += ivna.vna_next;
11824 }
b34976b6 11825 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11826 && ivna.vna_next != 0);
11827
b34976b6 11828 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11829 {
11830 ivna.vna_name = BYTE_GET (evna.vna_name);
11831
54806181 11832 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11833 name = invalid;
54806181
AM
11834 else
11835 name = strtab + ivna.vna_name;
252b5132
RH
11836 break;
11837 }
11838
11839 offset += ivn.vn_next;
11840 }
11841 while (ivn.vn_next);
11842 }
00d93f34 11843
ab273396 11844 if (data[cnt + j] != 0x8001
978c4450 11845 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 11846 {
b34976b6
AM
11847 Elf_Internal_Verdef ivd;
11848 Elf_External_Verdef evd;
11849 unsigned long offset;
252b5132 11850
d93f0186 11851 offset = offset_from_vma
978c4450
AM
11852 (filedata,
11853 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 11854 sizeof evd);
252b5132
RH
11855
11856 do
11857 {
dda8d76d 11858 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
11859 _("version def")) == NULL)
11860 {
11861 ivd.vd_next = 0;
948f632f 11862 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
11863 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
11864 break;
59245841
NC
11865 }
11866 else
11867 {
11868 ivd.vd_next = BYTE_GET (evd.vd_next);
11869 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11870 }
252b5132
RH
11871
11872 offset += ivd.vd_next;
11873 }
c244d050 11874 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
11875 && ivd.vd_next != 0);
11876
c244d050 11877 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 11878 {
b34976b6
AM
11879 Elf_External_Verdaux evda;
11880 Elf_Internal_Verdaux ivda;
252b5132
RH
11881
11882 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11883
dda8d76d 11884 if (get_data (&evda, filedata,
59245841
NC
11885 offset - ivd.vd_next + ivd.vd_aux,
11886 sizeof (evda), 1,
11887 _("version def aux")) == NULL)
11888 break;
252b5132
RH
11889
11890 ivda.vda_name = BYTE_GET (evda.vda_name);
11891
54806181 11892 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
11893 name = invalid;
11894 else if (name != NULL && name != invalid)
11895 name = _("*both*");
54806181
AM
11896 else
11897 name = strtab + ivda.vda_name;
252b5132
RH
11898 }
11899 }
ab273396
AM
11900 if (name != NULL)
11901 nn += printf ("(%s%-*s",
11902 name,
11903 12 - (int) strlen (name),
11904 ")");
252b5132
RH
11905
11906 if (nn < 18)
11907 printf ("%*c", 18 - nn, ' ');
11908 }
11909
11910 putchar ('\n');
11911 }
11912
11913 free (data);
11914 free (strtab);
11915 free (symbols);
11916 }
11917 break;
103f02d3 11918
252b5132
RH
11919 default:
11920 break;
11921 }
11922 }
11923
11924 if (! found)
ca0e11aa
NC
11925 {
11926 if (filedata->is_separate)
11927 printf (_("\nNo version information found in linked file '%s'.\n"),
11928 filedata->file_name);
11929 else
11930 printf (_("\nNo version information found in this file.\n"));
11931 }
252b5132 11932
015dc7e1 11933 return true;
252b5132
RH
11934}
11935
d1133906 11936static const char *
dda8d76d 11937get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 11938{
89246a0e 11939 static char buff[64];
252b5132
RH
11940
11941 switch (binding)
11942 {
b34976b6
AM
11943 case STB_LOCAL: return "LOCAL";
11944 case STB_GLOBAL: return "GLOBAL";
11945 case STB_WEAK: return "WEAK";
252b5132
RH
11946 default:
11947 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
11948 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
11949 binding);
252b5132 11950 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
11951 {
11952 if (binding == STB_GNU_UNIQUE
df3a023b 11953 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
11954 return "UNIQUE";
11955 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
11956 }
252b5132 11957 else
e9e44622 11958 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
11959 return buff;
11960 }
11961}
11962
d1133906 11963static const char *
dda8d76d 11964get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 11965{
89246a0e 11966 static char buff[64];
252b5132
RH
11967
11968 switch (type)
11969 {
b34976b6
AM
11970 case STT_NOTYPE: return "NOTYPE";
11971 case STT_OBJECT: return "OBJECT";
11972 case STT_FUNC: return "FUNC";
11973 case STT_SECTION: return "SECTION";
11974 case STT_FILE: return "FILE";
11975 case STT_COMMON: return "COMMON";
11976 case STT_TLS: return "TLS";
15ab5209
DB
11977 case STT_RELC: return "RELC";
11978 case STT_SRELC: return "SRELC";
252b5132
RH
11979 default:
11980 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 11981 {
dda8d76d 11982 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 11983 return "THUMB_FUNC";
103f02d3 11984
dda8d76d 11985 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
11986 return "REGISTER";
11987
dda8d76d 11988 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
11989 return "PARISC_MILLI";
11990
e9e44622 11991 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 11992 }
252b5132 11993 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 11994 {
dda8d76d 11995 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
11996 {
11997 if (type == STT_HP_OPAQUE)
11998 return "HP_OPAQUE";
11999 if (type == STT_HP_STUB)
12000 return "HP_STUB";
12001 }
12002
d8045f23 12003 if (type == STT_GNU_IFUNC
dda8d76d 12004 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12005 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12006 return "IFUNC";
12007
e9e44622 12008 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12009 }
252b5132 12010 else
e9e44622 12011 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12012 return buff;
12013 }
12014}
12015
d1133906 12016static const char *
d3ba0551 12017get_symbol_visibility (unsigned int visibility)
d1133906
NC
12018{
12019 switch (visibility)
12020 {
b34976b6
AM
12021 case STV_DEFAULT: return "DEFAULT";
12022 case STV_INTERNAL: return "INTERNAL";
12023 case STV_HIDDEN: return "HIDDEN";
d1133906 12024 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12025 default:
27a45f42 12026 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12027 return _("<unknown>");
d1133906
NC
12028 }
12029}
12030
2057d69d
CZ
12031static const char *
12032get_alpha_symbol_other (unsigned int other)
9abca702 12033{
2057d69d
CZ
12034 switch (other)
12035 {
12036 case STO_ALPHA_NOPV: return "NOPV";
12037 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12038 default:
27a45f42 12039 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12040 return _("<unknown>");
9abca702 12041 }
2057d69d
CZ
12042}
12043
fd85a6a1
NC
12044static const char *
12045get_solaris_symbol_visibility (unsigned int visibility)
12046{
12047 switch (visibility)
12048 {
12049 case 4: return "EXPORTED";
12050 case 5: return "SINGLETON";
12051 case 6: return "ELIMINATE";
12052 default: return get_symbol_visibility (visibility);
12053 }
12054}
12055
2301ed1c
SN
12056static const char *
12057get_aarch64_symbol_other (unsigned int other)
12058{
12059 static char buf[32];
12060
12061 if (other & STO_AARCH64_VARIANT_PCS)
12062 {
12063 other &= ~STO_AARCH64_VARIANT_PCS;
12064 if (other == 0)
12065 return "VARIANT_PCS";
12066 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12067 return buf;
12068 }
12069 return NULL;
12070}
12071
5e2b0d47
NC
12072static const char *
12073get_mips_symbol_other (unsigned int other)
12074{
12075 switch (other)
12076 {
32ec8896
NC
12077 case STO_OPTIONAL: return "OPTIONAL";
12078 case STO_MIPS_PLT: return "MIPS PLT";
12079 case STO_MIPS_PIC: return "MIPS PIC";
12080 case STO_MICROMIPS: return "MICROMIPS";
12081 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12082 case STO_MIPS16: return "MIPS16";
12083 default: return NULL;
5e2b0d47
NC
12084 }
12085}
12086
28f997cf 12087static const char *
dda8d76d 12088get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12089{
dda8d76d 12090 if (is_ia64_vms (filedata))
28f997cf
TG
12091 {
12092 static char res[32];
12093
12094 res[0] = 0;
12095
12096 /* Function types is for images and .STB files only. */
dda8d76d 12097 switch (filedata->file_header.e_type)
28f997cf
TG
12098 {
12099 case ET_DYN:
12100 case ET_EXEC:
12101 switch (VMS_ST_FUNC_TYPE (other))
12102 {
12103 case VMS_SFT_CODE_ADDR:
12104 strcat (res, " CA");
12105 break;
12106 case VMS_SFT_SYMV_IDX:
12107 strcat (res, " VEC");
12108 break;
12109 case VMS_SFT_FD:
12110 strcat (res, " FD");
12111 break;
12112 case VMS_SFT_RESERVE:
12113 strcat (res, " RSV");
12114 break;
12115 default:
bee0ee85
NC
12116 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12117 VMS_ST_FUNC_TYPE (other));
12118 strcat (res, " <unknown>");
12119 break;
28f997cf
TG
12120 }
12121 break;
12122 default:
12123 break;
12124 }
12125 switch (VMS_ST_LINKAGE (other))
12126 {
12127 case VMS_STL_IGNORE:
12128 strcat (res, " IGN");
12129 break;
12130 case VMS_STL_RESERVE:
12131 strcat (res, " RSV");
12132 break;
12133 case VMS_STL_STD:
12134 strcat (res, " STD");
12135 break;
12136 case VMS_STL_LNK:
12137 strcat (res, " LNK");
12138 break;
12139 default:
bee0ee85
NC
12140 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12141 VMS_ST_LINKAGE (other));
12142 strcat (res, " <unknown>");
12143 break;
28f997cf
TG
12144 }
12145
12146 if (res[0] != 0)
12147 return res + 1;
12148 else
12149 return res;
12150 }
12151 return NULL;
12152}
12153
6911b7dc
AM
12154static const char *
12155get_ppc64_symbol_other (unsigned int other)
12156{
14732552
AM
12157 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12158 return NULL;
12159
12160 other >>= STO_PPC64_LOCAL_BIT;
12161 if (other <= 6)
6911b7dc 12162 {
89246a0e 12163 static char buf[64];
14732552
AM
12164 if (other >= 2)
12165 other = ppc64_decode_local_entry (other);
12166 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12167 return buf;
12168 }
12169 return NULL;
12170}
12171
5e2b0d47 12172static const char *
dda8d76d 12173get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12174{
12175 const char * result = NULL;
89246a0e 12176 static char buff [64];
5e2b0d47
NC
12177
12178 if (other == 0)
12179 return "";
12180
dda8d76d 12181 switch (filedata->file_header.e_machine)
5e2b0d47 12182 {
2057d69d
CZ
12183 case EM_ALPHA:
12184 result = get_alpha_symbol_other (other);
12185 break;
2301ed1c
SN
12186 case EM_AARCH64:
12187 result = get_aarch64_symbol_other (other);
12188 break;
5e2b0d47
NC
12189 case EM_MIPS:
12190 result = get_mips_symbol_other (other);
28f997cf
TG
12191 break;
12192 case EM_IA_64:
dda8d76d 12193 result = get_ia64_symbol_other (filedata, other);
28f997cf 12194 break;
6911b7dc
AM
12195 case EM_PPC64:
12196 result = get_ppc64_symbol_other (other);
12197 break;
5e2b0d47 12198 default:
fd85a6a1 12199 result = NULL;
5e2b0d47
NC
12200 break;
12201 }
12202
12203 if (result)
12204 return result;
12205
12206 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12207 return buff;
12208}
12209
d1133906 12210static const char *
dda8d76d 12211get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12212{
b34976b6 12213 static char buff[32];
5cf1065c 12214
252b5132
RH
12215 switch (type)
12216 {
b34976b6
AM
12217 case SHN_UNDEF: return "UND";
12218 case SHN_ABS: return "ABS";
12219 case SHN_COMMON: return "COM";
252b5132 12220 default:
9ce701e2 12221 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12222 && filedata->file_header.e_machine == EM_IA_64
12223 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12224 return "ANSI_COM";
12225 else if ((filedata->file_header.e_machine == EM_X86_64
12226 || filedata->file_header.e_machine == EM_L1OM
12227 || filedata->file_header.e_machine == EM_K1OM)
12228 && type == SHN_X86_64_LCOMMON)
12229 return "LARGE_COM";
12230 else if ((type == SHN_MIPS_SCOMMON
12231 && filedata->file_header.e_machine == EM_MIPS)
12232 || (type == SHN_TIC6X_SCOMMON
12233 && filedata->file_header.e_machine == EM_TI_C6000))
12234 return "SCOM";
12235 else if (type == SHN_MIPS_SUNDEFINED
12236 && filedata->file_header.e_machine == EM_MIPS)
12237 return "SUND";
12238 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12239 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12240 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12241 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12242 else if (type >= SHN_LORESERVE)
12243 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12244 else if (filedata->file_header.e_shnum != 0
12245 && type >= filedata->file_header.e_shnum)
12246 sprintf (buff, _("bad section index[%3d]"), type);
12247 else
12248 sprintf (buff, "%3d", type);
12249 break;
fd85a6a1
NC
12250 }
12251
10ca4b04 12252 return buff;
6bd1a22c
L
12253}
12254
bb4d2ac2 12255static const char *
dda8d76d 12256get_symbol_version_string (Filedata * filedata,
015dc7e1 12257 bool is_dynsym,
1449284b
NC
12258 const char * strtab,
12259 unsigned long int strtab_size,
12260 unsigned int si,
12261 Elf_Internal_Sym * psym,
12262 enum versioned_symbol_info * sym_info,
12263 unsigned short * vna_other)
bb4d2ac2 12264{
ab273396
AM
12265 unsigned char data[2];
12266 unsigned short vers_data;
12267 unsigned long offset;
7a815dd5 12268 unsigned short max_vd_ndx;
bb4d2ac2 12269
ab273396 12270 if (!is_dynsym
978c4450 12271 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12272 return NULL;
bb4d2ac2 12273
978c4450
AM
12274 offset = offset_from_vma (filedata,
12275 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12276 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12277
dda8d76d 12278 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12279 sizeof (data), 1, _("version data")) == NULL)
12280 return NULL;
12281
12282 vers_data = byte_get (data, 2);
bb4d2ac2 12283
1f6f5dba 12284 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12285 return NULL;
bb4d2ac2 12286
0b8b7609 12287 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12288 max_vd_ndx = 0;
12289
ab273396
AM
12290 /* Usually we'd only see verdef for defined symbols, and verneed for
12291 undefined symbols. However, symbols defined by the linker in
12292 .dynbss for variables copied from a shared library in order to
12293 avoid text relocations are defined yet have verneed. We could
12294 use a heuristic to detect the special case, for example, check
12295 for verneed first on symbols defined in SHT_NOBITS sections, but
12296 it is simpler and more reliable to just look for both verdef and
12297 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12298
ab273396
AM
12299 if (psym->st_shndx != SHN_UNDEF
12300 && vers_data != 0x8001
978c4450 12301 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12302 {
12303 Elf_Internal_Verdef ivd;
12304 Elf_Internal_Verdaux ivda;
12305 Elf_External_Verdaux evda;
12306 unsigned long off;
bb4d2ac2 12307
dda8d76d 12308 off = offset_from_vma (filedata,
978c4450 12309 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12310 sizeof (Elf_External_Verdef));
12311
12312 do
bb4d2ac2 12313 {
ab273396
AM
12314 Elf_External_Verdef evd;
12315
dda8d76d 12316 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12317 _("version def")) == NULL)
12318 {
12319 ivd.vd_ndx = 0;
12320 ivd.vd_aux = 0;
12321 ivd.vd_next = 0;
1f6f5dba 12322 ivd.vd_flags = 0;
ab273396
AM
12323 }
12324 else
bb4d2ac2 12325 {
ab273396
AM
12326 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12327 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12328 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12329 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12330 }
bb4d2ac2 12331
7a815dd5
L
12332 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12333 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12334
ab273396
AM
12335 off += ivd.vd_next;
12336 }
12337 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12338
ab273396
AM
12339 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12340 {
9abca702 12341 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12342 return NULL;
12343
ab273396
AM
12344 off -= ivd.vd_next;
12345 off += ivd.vd_aux;
bb4d2ac2 12346
dda8d76d 12347 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12348 _("version def aux")) != NULL)
12349 {
12350 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12351
ab273396 12352 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12353 return (ivda.vda_name < strtab_size
12354 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12355 }
12356 }
12357 }
bb4d2ac2 12358
978c4450 12359 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12360 {
12361 Elf_External_Verneed evn;
12362 Elf_Internal_Verneed ivn;
12363 Elf_Internal_Vernaux ivna;
bb4d2ac2 12364
dda8d76d 12365 offset = offset_from_vma (filedata,
978c4450 12366 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12367 sizeof evn);
12368 do
12369 {
12370 unsigned long vna_off;
bb4d2ac2 12371
dda8d76d 12372 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12373 _("version need")) == NULL)
12374 {
12375 ivna.vna_next = 0;
12376 ivna.vna_other = 0;
12377 ivna.vna_name = 0;
12378 break;
12379 }
bb4d2ac2 12380
ab273396
AM
12381 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12382 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12383
ab273396 12384 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12385
ab273396
AM
12386 do
12387 {
12388 Elf_External_Vernaux evna;
bb4d2ac2 12389
dda8d76d 12390 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12391 _("version need aux (3)")) == NULL)
bb4d2ac2 12392 {
ab273396
AM
12393 ivna.vna_next = 0;
12394 ivna.vna_other = 0;
12395 ivna.vna_name = 0;
bb4d2ac2 12396 }
bb4d2ac2 12397 else
bb4d2ac2 12398 {
ab273396
AM
12399 ivna.vna_other = BYTE_GET (evna.vna_other);
12400 ivna.vna_next = BYTE_GET (evna.vna_next);
12401 ivna.vna_name = BYTE_GET (evna.vna_name);
12402 }
bb4d2ac2 12403
ab273396
AM
12404 vna_off += ivna.vna_next;
12405 }
12406 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12407
ab273396
AM
12408 if (ivna.vna_other == vers_data)
12409 break;
bb4d2ac2 12410
ab273396
AM
12411 offset += ivn.vn_next;
12412 }
12413 while (ivn.vn_next != 0);
bb4d2ac2 12414
ab273396
AM
12415 if (ivna.vna_other == vers_data)
12416 {
12417 *sym_info = symbol_undefined;
12418 *vna_other = ivna.vna_other;
12419 return (ivna.vna_name < strtab_size
12420 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12421 }
7a815dd5
L
12422 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12423 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12424 return _("<corrupt>");
bb4d2ac2 12425 }
ab273396 12426 return NULL;
bb4d2ac2
L
12427}
12428
047c3dbf
NL
12429/* Display a symbol size on stdout. Format is based on --sym-base setting. */
12430
12431static unsigned int
12432print_dynamic_symbol_size (bfd_vma vma, int base)
12433{
12434 switch (base)
12435 {
12436 case 8:
12437 return print_vma (vma, OCTAL_5);
12438
12439 case 10:
12440 return print_vma (vma, UNSIGNED_5);
12441
12442 case 16:
12443 return print_vma (vma, PREFIX_HEX_5);
12444
12445 case 0:
12446 default:
12447 return print_vma (vma, DEC_5);
12448 }
12449}
12450
10ca4b04
L
12451static void
12452print_dynamic_symbol (Filedata *filedata, unsigned long si,
12453 Elf_Internal_Sym *symtab,
12454 Elf_Internal_Shdr *section,
12455 char *strtab, size_t strtab_size)
252b5132 12456{
10ca4b04
L
12457 const char *version_string;
12458 enum versioned_symbol_info sym_info;
12459 unsigned short vna_other;
23356397
NC
12460 bool is_valid;
12461 const char * sstr;
10ca4b04 12462 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 12463
10ca4b04
L
12464 printf ("%6ld: ", si);
12465 print_vma (psym->st_value, LONG_HEX);
12466 putchar (' ');
047c3dbf 12467 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
12468 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12469 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12470 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12471 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12472 else
252b5132 12473 {
10ca4b04 12474 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12475
10ca4b04
L
12476 printf (" %-7s", get_symbol_visibility (vis));
12477 /* Check to see if any other bits in the st_other field are set.
12478 Note - displaying this information disrupts the layout of the
12479 table being generated, but for the moment this case is very rare. */
12480 if (psym->st_other ^ vis)
12481 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12482 }
10ca4b04 12483 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 12484
23356397
NC
12485 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
12486 && psym->st_shndx < filedata->file_header.e_shnum
12487 && psym->st_name == 0)
12488 {
12489 is_valid = SECTION_NAME_VALID (filedata->section_headers + psym->st_shndx);
12490 sstr = is_valid ?
12491 SECTION_NAME_PRINT (filedata->section_headers + psym->st_shndx)
12492 : _("<corrupt>");
12493 }
12494 else
12495 {
12496 is_valid = VALID_SYMBOL_NAME (strtab, strtab_size, psym->st_name);
12497 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
12498 }
10ca4b04
L
12499
12500 version_string
12501 = get_symbol_version_string (filedata,
12502 (section == NULL
12503 || section->sh_type == SHT_DYNSYM),
12504 strtab, strtab_size, si,
12505 psym, &sym_info, &vna_other);
b9e920ec 12506
0942c7ab
NC
12507 int len_avail = 21;
12508 if (! do_wide && version_string != NULL)
12509 {
ddb43bab 12510 char buffer[16];
0942c7ab 12511
ddb43bab 12512 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
12513
12514 if (sym_info == symbol_undefined)
12515 len_avail -= sprintf (buffer," (%d)", vna_other);
12516 else if (sym_info != symbol_hidden)
12517 len_avail -= 1;
12518 }
12519
12520 print_symbol (len_avail, sstr);
b9e920ec 12521
10ca4b04
L
12522 if (version_string)
12523 {
12524 if (sym_info == symbol_undefined)
12525 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12526 else
10ca4b04
L
12527 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12528 version_string);
12529 }
6bd1a22c 12530
10ca4b04 12531 putchar ('\n');
6bd1a22c 12532
10ca4b04
L
12533 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12534 && section != NULL
12535 && si >= section->sh_info
12536 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12537 && filedata->file_header.e_machine != EM_MIPS
12538 /* Solaris binaries have been found to violate this requirement as
12539 well. Not sure if this is a bug or an ABI requirement. */
12540 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12541 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12542 si, printable_section_name (filedata, section), section->sh_info);
12543}
f16a9783 12544
0f03783c
NC
12545static const char *
12546get_lto_kind (unsigned int kind)
12547{
12548 switch (kind)
12549 {
12550 case 0: return "DEF";
12551 case 1: return "WEAKDEF";
12552 case 2: return "UNDEF";
12553 case 3: return "WEAKUNDEF";
12554 case 4: return "COMMON";
12555 default:
12556 break;
12557 }
12558
12559 static char buffer[30];
12560 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
12561 sprintf (buffer, "<unknown: %u>", kind);
12562 return buffer;
12563}
12564
12565static const char *
12566get_lto_visibility (unsigned int visibility)
12567{
12568 switch (visibility)
12569 {
12570 case 0: return "DEFAULT";
12571 case 1: return "PROTECTED";
12572 case 2: return "INTERNAL";
12573 case 3: return "HIDDEN";
12574 default:
12575 break;
12576 }
12577
12578 static char buffer[30];
12579 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
12580 sprintf (buffer, "<unknown: %u>", visibility);
12581 return buffer;
12582}
12583
12584static const char *
12585get_lto_sym_type (unsigned int sym_type)
12586{
12587 switch (sym_type)
12588 {
12589 case 0: return "UNKNOWN";
12590 case 1: return "FUNCTION";
12591 case 2: return "VARIABLE";
12592 default:
12593 break;
12594 }
12595
12596 static char buffer[30];
12597 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
12598 sprintf (buffer, "<unknown: %u>", sym_type);
12599 return buffer;
12600}
12601
12602/* Display an LTO format symbol table.
12603 FIXME: The format of LTO symbol tables is not formalized.
12604 So this code could need changing in the future. */
12605
015dc7e1 12606static bool
0f03783c
NC
12607display_lto_symtab (Filedata * filedata,
12608 Elf_Internal_Shdr * section)
12609{
12610 if (section->sh_size == 0)
12611 {
ca0e11aa
NC
12612 if (filedata->is_separate)
12613 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
12614 printable_section_name (filedata, section),
12615 filedata->file_name);
12616 else
12617 printf (_("\nLTO Symbol table '%s' is empty!\n"),
12618 printable_section_name (filedata, section));
047c3dbf 12619
015dc7e1 12620 return true;
0f03783c
NC
12621 }
12622
12623 if (section->sh_size > filedata->file_size)
12624 {
12625 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
12626 printable_section_name (filedata, section),
12627 (unsigned long) section->sh_size);
015dc7e1 12628 return false;
0f03783c
NC
12629 }
12630
12631 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
12632 section->sh_size, 1, _("LTO symbols"));
12633 if (alloced_data == NULL)
015dc7e1 12634 return false;
0f03783c
NC
12635
12636 /* Look for extended data for the symbol table. */
12637 Elf_Internal_Shdr * ext;
12638 void * ext_data_orig = NULL;
12639 char * ext_data = NULL;
12640 char * ext_data_end = NULL;
12641 char * ext_name = NULL;
12642
12643 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
b9e920ec 12644 SECTION_NAME (section) + sizeof (".gnu.lto_.symtab.") - 1) > 0
0f03783c
NC
12645 && ext_name != NULL /* Paranoia. */
12646 && (ext = find_section (filedata, ext_name)) != NULL)
12647 {
12648 if (ext->sh_size < 3)
12649 error (_("LTO Symbol extension table '%s' is empty!\n"),
12650 printable_section_name (filedata, ext));
12651 else
12652 {
12653 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
12654 ext->sh_size, 1,
12655 _("LTO ext symbol data"));
12656 if (ext_data != NULL)
12657 {
12658 ext_data_end = ext_data + ext->sh_size;
12659 if (* ext_data++ != 1)
12660 error (_("Unexpected version number in symbol extension table\n"));
12661 }
12662 }
12663 }
b9e920ec 12664
0f03783c
NC
12665 const unsigned char * data = (const unsigned char *) alloced_data;
12666 const unsigned char * end = data + section->sh_size;
12667
ca0e11aa
NC
12668 if (filedata->is_separate)
12669 printf (_("\nIn linked file '%s': "), filedata->file_name);
12670 else
12671 printf ("\n");
12672
0f03783c
NC
12673 if (ext_data_orig != NULL)
12674 {
12675 if (do_wide)
ca0e11aa 12676 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
12677 printable_section_name (filedata, section),
12678 printable_section_name (filedata, ext));
12679 else
12680 {
ca0e11aa 12681 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
12682 printable_section_name (filedata, section));
12683 printf (_(" and extension table '%s' contain:\n"),
12684 printable_section_name (filedata, ext));
12685 }
12686 }
12687 else
ca0e11aa 12688 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 12689 printable_section_name (filedata, section));
b9e920ec 12690
0f03783c 12691 /* FIXME: Add a wide version. */
b9e920ec 12692 if (ext_data_orig != NULL)
0f03783c
NC
12693 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
12694 else
12695 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
12696
12697 /* FIXME: We do not handle style prefixes. */
12698
12699 while (data < end)
12700 {
12701 const unsigned char * sym_name = data;
12702 data += strnlen ((const char *) sym_name, end - data) + 1;
12703 if (data >= end)
12704 goto fail;
12705
12706 const unsigned char * comdat_key = data;
12707 data += strnlen ((const char *) comdat_key, end - data) + 1;
12708 if (data >= end)
12709 goto fail;
12710
12711 if (data + 2 + 8 + 4 > end)
12712 goto fail;
12713
12714 unsigned int kind = *data++;
12715 unsigned int visibility = *data++;
12716
12717 elf_vma size = byte_get (data, 8);
12718 data += 8;
12719
12720 elf_vma slot = byte_get (data, 4);
12721 data += 4;
12722
12723 if (ext_data != NULL)
12724 {
12725 if (ext_data < (ext_data_end - 1))
12726 {
12727 unsigned int sym_type = * ext_data ++;
12728 unsigned int sec_kind = * ext_data ++;
12729
12730 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
12731 * comdat_key == 0 ? "-" : (char *) comdat_key,
12732 get_lto_kind (kind),
12733 get_lto_visibility (visibility),
12734 (long) size,
12735 (long) slot,
12736 get_lto_sym_type (sym_type),
12737 (long) sec_kind);
12738 print_symbol (6, (const char *) sym_name);
12739 }
12740 else
12741 {
12742 error (_("Ran out of LTO symbol extension data\n"));
12743 ext_data = NULL;
12744 /* FIXME: return FAIL result ? */
12745 }
12746 }
12747 else
12748 {
12749 printf (" %10s %10s %11s %08lx %08lx _",
12750 * comdat_key == 0 ? "-" : (char *) comdat_key,
12751 get_lto_kind (kind),
12752 get_lto_visibility (visibility),
12753 (long) size,
12754 (long) slot);
12755 print_symbol (21, (const char *) sym_name);
12756 }
12757 putchar ('\n');
12758 }
12759
12760 if (ext_data != NULL && ext_data < ext_data_end)
12761 {
12762 error (_("Data remains in the LTO symbol extension table\n"));
12763 goto fail;
12764 }
12765
12766 free (alloced_data);
12767 free (ext_data_orig);
12768 free (ext_name);
015dc7e1 12769 return true;
b9e920ec 12770
0f03783c
NC
12771 fail:
12772 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
12773 free (alloced_data);
12774 free (ext_data_orig);
12775 free (ext_name);
015dc7e1 12776 return false;
0f03783c
NC
12777}
12778
12779/* Display LTO symbol tables. */
12780
015dc7e1 12781static bool
0f03783c
NC
12782process_lto_symbol_tables (Filedata * filedata)
12783{
12784 Elf_Internal_Shdr * section;
12785 unsigned int i;
015dc7e1 12786 bool res = true;
0f03783c
NC
12787
12788 if (!do_lto_syms)
015dc7e1 12789 return true;
0f03783c
NC
12790
12791 if (filedata->section_headers == NULL)
015dc7e1 12792 return true;
0f03783c
NC
12793
12794 for (i = 0, section = filedata->section_headers;
12795 i < filedata->file_header.e_shnum;
12796 i++, section++)
b9e920ec 12797 if (SECTION_NAME_VALID (section)
08dedd66 12798 && startswith (SECTION_NAME (section), ".gnu.lto_.symtab."))
0f03783c
NC
12799 res &= display_lto_symtab (filedata, section);
12800
b9e920ec 12801 return res;
0f03783c
NC
12802}
12803
10ca4b04 12804/* Dump the symbol table. */
0f03783c 12805
015dc7e1 12806static bool
10ca4b04
L
12807process_symbol_table (Filedata * filedata)
12808{
12809 Elf_Internal_Shdr * section;
f16a9783 12810
10ca4b04 12811 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 12812 return true;
6bd1a22c 12813
978c4450 12814 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
12815 && do_syms
12816 && do_using_dynamic
978c4450
AM
12817 && filedata->dynamic_strings != NULL
12818 && filedata->dynamic_symbols != NULL)
6bd1a22c 12819 {
10ca4b04 12820 unsigned long si;
6bd1a22c 12821
ca0e11aa
NC
12822 if (filedata->is_separate)
12823 {
12824 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
12825 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
12826 filedata->num_dynamic_syms),
12827 filedata->file_name,
12828 filedata->num_dynamic_syms);
12829 }
12830 else
12831 {
12832 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12833 "\nSymbol table for image contains %lu entries:\n",
12834 filedata->num_dynamic_syms),
12835 filedata->num_dynamic_syms);
12836 }
10ca4b04
L
12837 if (is_32bit_elf)
12838 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12839 else
12840 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12841
978c4450
AM
12842 for (si = 0; si < filedata->num_dynamic_syms; si++)
12843 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
12844 filedata->dynamic_strings,
12845 filedata->dynamic_strings_length);
252b5132 12846 }
8b73c356 12847 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 12848 && filedata->section_headers != NULL)
252b5132 12849 {
b34976b6 12850 unsigned int i;
252b5132 12851
dda8d76d
NC
12852 for (i = 0, section = filedata->section_headers;
12853 i < filedata->file_header.e_shnum;
252b5132
RH
12854 i++, section++)
12855 {
2cf0635d 12856 char * strtab = NULL;
c256ffe7 12857 unsigned long int strtab_size = 0;
2cf0635d 12858 Elf_Internal_Sym * symtab;
ef3df110 12859 unsigned long si, num_syms;
252b5132 12860
2c610e4b
L
12861 if ((section->sh_type != SHT_SYMTAB
12862 && section->sh_type != SHT_DYNSYM)
12863 || (!do_syms
12864 && section->sh_type == SHT_SYMTAB))
252b5132
RH
12865 continue;
12866
dd24e3da
NC
12867 if (section->sh_entsize == 0)
12868 {
12869 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 12870 printable_section_name (filedata, section));
dd24e3da
NC
12871 continue;
12872 }
12873
d3a49aa8 12874 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
12875
12876 if (filedata->is_separate)
12877 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
12878 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
12879 num_syms),
12880 filedata->file_name,
12881 printable_section_name (filedata, section),
12882 num_syms);
12883 else
12884 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
12885 "\nSymbol table '%s' contains %lu entries:\n",
12886 num_syms),
12887 printable_section_name (filedata, section),
12888 num_syms);
dd24e3da 12889
f7a99963 12890 if (is_32bit_elf)
ca47b30c 12891 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 12892 else
ca47b30c 12893 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 12894
dda8d76d 12895 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
12896 if (symtab == NULL)
12897 continue;
12898
dda8d76d 12899 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 12900 {
dda8d76d
NC
12901 strtab = filedata->string_table;
12902 strtab_size = filedata->string_table_length;
c256ffe7 12903 }
dda8d76d 12904 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 12905 {
2cf0635d 12906 Elf_Internal_Shdr * string_sec;
252b5132 12907
dda8d76d 12908 string_sec = filedata->section_headers + section->sh_link;
252b5132 12909
dda8d76d 12910 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
12911 1, string_sec->sh_size,
12912 _("string table"));
c256ffe7 12913 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
12914 }
12915
10ca4b04
L
12916 for (si = 0; si < num_syms; si++)
12917 print_dynamic_symbol (filedata, si, symtab, section,
12918 strtab, strtab_size);
252b5132
RH
12919
12920 free (symtab);
dda8d76d 12921 if (strtab != filedata->string_table)
252b5132
RH
12922 free (strtab);
12923 }
12924 }
12925 else if (do_syms)
12926 printf
12927 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
12928
978c4450 12929 if (do_histogram && filedata->buckets != NULL)
252b5132 12930 {
2cf0635d
NC
12931 unsigned long * lengths;
12932 unsigned long * counts;
66543521
AM
12933 unsigned long hn;
12934 bfd_vma si;
12935 unsigned long maxlength = 0;
12936 unsigned long nzero_counts = 0;
12937 unsigned long nsyms = 0;
6bd6a03d 12938 char *visited;
252b5132 12939
d3a49aa8
AM
12940 printf (ngettext ("\nHistogram for bucket list length "
12941 "(total of %lu bucket):\n",
12942 "\nHistogram for bucket list length "
12943 "(total of %lu buckets):\n",
978c4450
AM
12944 (unsigned long) filedata->nbuckets),
12945 (unsigned long) filedata->nbuckets);
252b5132 12946
978c4450
AM
12947 lengths = (unsigned long *) calloc (filedata->nbuckets,
12948 sizeof (*lengths));
252b5132
RH
12949 if (lengths == NULL)
12950 {
8b73c356 12951 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 12952 goto err_out;
252b5132 12953 }
978c4450
AM
12954 visited = xcmalloc (filedata->nchains, 1);
12955 memset (visited, 0, filedata->nchains);
8b73c356
NC
12956
12957 printf (_(" Length Number %% of total Coverage\n"));
978c4450 12958 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 12959 {
978c4450 12960 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 12961 {
b34976b6 12962 ++nsyms;
252b5132 12963 if (maxlength < ++lengths[hn])
b34976b6 12964 ++maxlength;
978c4450 12965 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
12966 {
12967 error (_("histogram chain is corrupt\n"));
12968 break;
12969 }
12970 visited[si] = 1;
252b5132
RH
12971 }
12972 }
6bd6a03d 12973 free (visited);
252b5132 12974
3f5e193b 12975 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
12976 if (counts == NULL)
12977 {
b2e951ec 12978 free (lengths);
8b73c356 12979 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 12980 goto err_out;
252b5132
RH
12981 }
12982
978c4450 12983 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 12984 ++counts[lengths[hn]];
252b5132 12985
978c4450 12986 if (filedata->nbuckets > 0)
252b5132 12987 {
66543521
AM
12988 unsigned long i;
12989 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12990 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 12991 for (i = 1; i <= maxlength; ++i)
103f02d3 12992 {
66543521
AM
12993 nzero_counts += counts[i] * i;
12994 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12995 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
12996 (nzero_counts * 100.0) / nsyms);
12997 }
252b5132
RH
12998 }
12999
13000 free (counts);
13001 free (lengths);
13002 }
13003
978c4450
AM
13004 free (filedata->buckets);
13005 filedata->buckets = NULL;
13006 filedata->nbuckets = 0;
13007 free (filedata->chains);
13008 filedata->chains = NULL;
252b5132 13009
978c4450 13010 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13011 {
2cf0635d
NC
13012 unsigned long * lengths;
13013 unsigned long * counts;
fdc90cb4
JJ
13014 unsigned long hn;
13015 unsigned long maxlength = 0;
13016 unsigned long nzero_counts = 0;
13017 unsigned long nsyms = 0;
fdc90cb4 13018
f16a9783 13019 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13020 "(total of %lu bucket):\n",
f16a9783 13021 "\nHistogram for `%s' bucket list length "
d3a49aa8 13022 "(total of %lu buckets):\n",
978c4450
AM
13023 (unsigned long) filedata->ngnubuckets),
13024 GNU_HASH_SECTION_NAME (filedata),
13025 (unsigned long) filedata->ngnubuckets);
8b73c356 13026
978c4450
AM
13027 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13028 sizeof (*lengths));
fdc90cb4
JJ
13029 if (lengths == NULL)
13030 {
8b73c356 13031 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13032 goto err_out;
fdc90cb4
JJ
13033 }
13034
fdc90cb4
JJ
13035 printf (_(" Length Number %% of total Coverage\n"));
13036
978c4450
AM
13037 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13038 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
13039 {
13040 bfd_vma off, length = 1;
13041
978c4450 13042 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13043 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13044 off < filedata->ngnuchains
13045 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13046 ++off)
fdc90cb4
JJ
13047 ++length;
13048 lengths[hn] = length;
13049 if (length > maxlength)
13050 maxlength = length;
13051 nsyms += length;
13052 }
13053
3f5e193b 13054 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13055 if (counts == NULL)
13056 {
b2e951ec 13057 free (lengths);
8b73c356 13058 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13059 goto err_out;
fdc90cb4
JJ
13060 }
13061
978c4450 13062 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13063 ++counts[lengths[hn]];
13064
978c4450 13065 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13066 {
13067 unsigned long j;
13068 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13069 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13070 for (j = 1; j <= maxlength; ++j)
13071 {
13072 nzero_counts += counts[j] * j;
13073 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13074 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13075 (nzero_counts * 100.0) / nsyms);
13076 }
13077 }
13078
13079 free (counts);
13080 free (lengths);
fdc90cb4 13081 }
978c4450
AM
13082 free (filedata->gnubuckets);
13083 filedata->gnubuckets = NULL;
13084 filedata->ngnubuckets = 0;
13085 free (filedata->gnuchains);
13086 filedata->gnuchains = NULL;
13087 filedata->ngnuchains = 0;
13088 free (filedata->mipsxlat);
13089 filedata->mipsxlat = NULL;
015dc7e1 13090 return true;
fd486f32
AM
13091
13092 err_out:
978c4450
AM
13093 free (filedata->gnubuckets);
13094 filedata->gnubuckets = NULL;
13095 filedata->ngnubuckets = 0;
13096 free (filedata->gnuchains);
13097 filedata->gnuchains = NULL;
13098 filedata->ngnuchains = 0;
13099 free (filedata->mipsxlat);
13100 filedata->mipsxlat = NULL;
13101 free (filedata->buckets);
13102 filedata->buckets = NULL;
13103 filedata->nbuckets = 0;
13104 free (filedata->chains);
13105 filedata->chains = NULL;
015dc7e1 13106 return false;
252b5132
RH
13107}
13108
015dc7e1 13109static bool
ca0e11aa 13110process_syminfo (Filedata * filedata)
252b5132 13111{
b4c96d0d 13112 unsigned int i;
252b5132 13113
978c4450 13114 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13115 || !do_dynamic)
13116 /* No syminfo, this is ok. */
015dc7e1 13117 return true;
252b5132
RH
13118
13119 /* There better should be a dynamic symbol section. */
978c4450 13120 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13121 return false;
252b5132 13122
ca0e11aa
NC
13123 if (filedata->is_separate)
13124 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13125 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13126 filedata->dynamic_syminfo_nent),
13127 filedata->file_name,
13128 filedata->dynamic_syminfo_offset,
13129 filedata->dynamic_syminfo_nent);
13130 else
d3a49aa8
AM
13131 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13132 "contains %d entry:\n",
13133 "\nDynamic info segment at offset 0x%lx "
13134 "contains %d entries:\n",
978c4450 13135 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13136 filedata->dynamic_syminfo_offset,
13137 filedata->dynamic_syminfo_nent);
252b5132
RH
13138
13139 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13140 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13141 {
978c4450 13142 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13143
31104126 13144 printf ("%4d: ", i);
978c4450 13145 if (i >= filedata->num_dynamic_syms)
4082ef84 13146 printf (_("<corrupt index>"));
978c4450
AM
13147 else if (VALID_DYNAMIC_NAME (filedata, filedata->dynamic_symbols[i].st_name))
13148 print_symbol (30, GET_DYNAMIC_NAME (filedata,
13149 filedata->dynamic_symbols[i].st_name));
d79b3d50 13150 else
978c4450 13151 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13152 putchar (' ');
252b5132 13153
978c4450 13154 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13155 {
13156 case SYMINFO_BT_SELF:
13157 fputs ("SELF ", stdout);
13158 break;
13159 case SYMINFO_BT_PARENT:
13160 fputs ("PARENT ", stdout);
13161 break;
13162 default:
978c4450
AM
13163 if (filedata->dynamic_syminfo[i].si_boundto > 0
13164 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
13165 && VALID_DYNAMIC_NAME (filedata,
13166 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13167 {
978c4450
AM
13168 print_symbol (10, GET_DYNAMIC_NAME (filedata,
13169 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13170 putchar (' ' );
13171 }
252b5132 13172 else
978c4450 13173 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13174 break;
13175 }
13176
13177 if (flags & SYMINFO_FLG_DIRECT)
13178 printf (" DIRECT");
13179 if (flags & SYMINFO_FLG_PASSTHRU)
13180 printf (" PASSTHRU");
13181 if (flags & SYMINFO_FLG_COPY)
13182 printf (" COPY");
13183 if (flags & SYMINFO_FLG_LAZYLOAD)
13184 printf (" LAZYLOAD");
13185
13186 puts ("");
13187 }
13188
015dc7e1 13189 return true;
252b5132
RH
13190}
13191
75802ccb
CE
13192/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13193 is contained by the region START .. END. The types of ADDR, START
13194 and END should all be the same. Note both ADDR + NELEM and END
13195 point to just beyond the end of the regions that are being tested. */
13196#define IN_RANGE(START,END,ADDR,NELEM) \
13197 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13198
cf13d699
NC
13199/* Check to see if the given reloc needs to be handled in a target specific
13200 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13201 FALSE.
13202
13203 If called with reloc == NULL, then this is a signal that reloc processing
13204 for the current section has finished, and any saved state should be
13205 discarded. */
09c11c86 13206
015dc7e1 13207static bool
dda8d76d
NC
13208target_specific_reloc_handling (Filedata * filedata,
13209 Elf_Internal_Rela * reloc,
13210 unsigned char * start,
13211 unsigned char * end,
13212 Elf_Internal_Sym * symtab,
13213 unsigned long num_syms)
252b5132 13214{
f84ce13b
NC
13215 unsigned int reloc_type = 0;
13216 unsigned long sym_index = 0;
13217
13218 if (reloc)
13219 {
dda8d76d 13220 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13221 sym_index = get_reloc_symindex (reloc->r_info);
13222 }
252b5132 13223
dda8d76d 13224 switch (filedata->file_header.e_machine)
252b5132 13225 {
13761a11
NC
13226 case EM_MSP430:
13227 case EM_MSP430_OLD:
13228 {
13229 static Elf_Internal_Sym * saved_sym = NULL;
13230
f84ce13b
NC
13231 if (reloc == NULL)
13232 {
13233 saved_sym = NULL;
015dc7e1 13234 return true;
f84ce13b
NC
13235 }
13236
13761a11
NC
13237 switch (reloc_type)
13238 {
13239 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13240 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13241 if (uses_msp430x_relocs (filedata))
13761a11 13242 break;
1a0670f3 13243 /* Fall through. */
13761a11 13244 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13245 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13246 /* PR 21139. */
13247 if (sym_index >= num_syms)
13248 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13249 sym_index);
13250 else
13251 saved_sym = symtab + sym_index;
015dc7e1 13252 return true;
13761a11
NC
13253
13254 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13255 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13256 goto handle_sym_diff;
0b4362b0 13257
13761a11
NC
13258 case 5: /* R_MSP430_16_BYTE */
13259 case 9: /* R_MSP430_8 */
7d81bc93 13260 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13261 if (uses_msp430x_relocs (filedata))
13761a11
NC
13262 break;
13263 goto handle_sym_diff;
13264
13265 case 2: /* R_MSP430_ABS16 */
13266 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13267 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13268 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13269 break;
13270 goto handle_sym_diff;
0b4362b0 13271
13761a11
NC
13272 handle_sym_diff:
13273 if (saved_sym != NULL)
13274 {
13275 bfd_vma value;
5a805384 13276 unsigned int reloc_size = 0;
7d81bc93
JL
13277 int leb_ret = 0;
13278 switch (reloc_type)
13279 {
13280 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13281 reloc_size = 4;
13282 break;
13283 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13284 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13285 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13286 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13287 &reloc_size, &leb_ret);
7d81bc93
JL
13288 break;
13289 default:
13290 reloc_size = 2;
13291 break;
13292 }
13761a11 13293
5a805384 13294 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13295 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13296 "ULEB128 value\n"),
13297 (long) reloc->r_offset);
13298 else if (sym_index >= num_syms)
f84ce13b
NC
13299 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13300 sym_index);
03f7786e 13301 else
f84ce13b
NC
13302 {
13303 value = reloc->r_addend + (symtab[sym_index].st_value
13304 - saved_sym->st_value);
13305
b32e566b 13306 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13307 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13308 else
13309 /* PR 21137 */
13310 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13311 (long) reloc->r_offset);
f84ce13b 13312 }
13761a11
NC
13313
13314 saved_sym = NULL;
015dc7e1 13315 return true;
13761a11
NC
13316 }
13317 break;
13318
13319 default:
13320 if (saved_sym != NULL)
071436c6 13321 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
13322 break;
13323 }
13324 break;
13325 }
13326
cf13d699
NC
13327 case EM_MN10300:
13328 case EM_CYGNUS_MN10300:
13329 {
13330 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 13331
f84ce13b
NC
13332 if (reloc == NULL)
13333 {
13334 saved_sym = NULL;
015dc7e1 13335 return true;
f84ce13b
NC
13336 }
13337
cf13d699
NC
13338 switch (reloc_type)
13339 {
13340 case 34: /* R_MN10300_ALIGN */
015dc7e1 13341 return true;
cf13d699 13342 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
13343 if (sym_index >= num_syms)
13344 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
13345 sym_index);
13346 else
13347 saved_sym = symtab + sym_index;
015dc7e1 13348 return true;
f84ce13b 13349
cf13d699
NC
13350 case 1: /* R_MN10300_32 */
13351 case 2: /* R_MN10300_16 */
13352 if (saved_sym != NULL)
13353 {
03f7786e 13354 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 13355 bfd_vma value;
252b5132 13356
f84ce13b
NC
13357 if (sym_index >= num_syms)
13358 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
13359 sym_index);
03f7786e 13360 else
f84ce13b
NC
13361 {
13362 value = reloc->r_addend + (symtab[sym_index].st_value
13363 - saved_sym->st_value);
13364
b32e566b 13365 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13366 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13367 else
13368 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
13369 (long) reloc->r_offset);
f84ce13b 13370 }
252b5132 13371
cf13d699 13372 saved_sym = NULL;
015dc7e1 13373 return true;
cf13d699
NC
13374 }
13375 break;
13376 default:
13377 if (saved_sym != NULL)
071436c6 13378 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
13379 break;
13380 }
13381 break;
13382 }
6ff71e76
NC
13383
13384 case EM_RL78:
13385 {
13386 static bfd_vma saved_sym1 = 0;
13387 static bfd_vma saved_sym2 = 0;
13388 static bfd_vma value;
13389
f84ce13b
NC
13390 if (reloc == NULL)
13391 {
13392 saved_sym1 = saved_sym2 = 0;
015dc7e1 13393 return true;
f84ce13b
NC
13394 }
13395
6ff71e76
NC
13396 switch (reloc_type)
13397 {
13398 case 0x80: /* R_RL78_SYM. */
13399 saved_sym1 = saved_sym2;
f84ce13b
NC
13400 if (sym_index >= num_syms)
13401 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
13402 sym_index);
13403 else
13404 {
13405 saved_sym2 = symtab[sym_index].st_value;
13406 saved_sym2 += reloc->r_addend;
13407 }
015dc7e1 13408 return true;
6ff71e76
NC
13409
13410 case 0x83: /* R_RL78_OPsub. */
13411 value = saved_sym1 - saved_sym2;
13412 saved_sym2 = saved_sym1 = 0;
015dc7e1 13413 return true;
6ff71e76
NC
13414 break;
13415
13416 case 0x41: /* R_RL78_ABS32. */
b32e566b 13417 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 13418 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
13419 else
13420 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13421 (long) reloc->r_offset);
6ff71e76 13422 value = 0;
015dc7e1 13423 return true;
6ff71e76
NC
13424
13425 case 0x43: /* R_RL78_ABS16. */
b32e566b 13426 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 13427 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
13428 else
13429 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13430 (long) reloc->r_offset);
6ff71e76 13431 value = 0;
015dc7e1 13432 return true;
6ff71e76
NC
13433
13434 default:
13435 break;
13436 }
13437 break;
13438 }
252b5132
RH
13439 }
13440
015dc7e1 13441 return false;
252b5132
RH
13442}
13443
aca88567
NC
13444/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
13445 DWARF debug sections. This is a target specific test. Note - we do not
13446 go through the whole including-target-headers-multiple-times route, (as
13447 we have already done with <elf/h8.h>) because this would become very
13448 messy and even then this function would have to contain target specific
13449 information (the names of the relocs instead of their numeric values).
13450 FIXME: This is not the correct way to solve this problem. The proper way
13451 is to have target specific reloc sizing and typing functions created by
13452 the reloc-macros.h header, in the same way that it already creates the
13453 reloc naming functions. */
13454
015dc7e1 13455static bool
dda8d76d 13456is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13457{
d347c9df 13458 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13459 switch (filedata->file_header.e_machine)
aca88567 13460 {
41e92641 13461 case EM_386:
22abe556 13462 case EM_IAMCU:
41e92641 13463 return reloc_type == 1; /* R_386_32. */
aca88567
NC
13464 case EM_68K:
13465 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
13466 case EM_860:
13467 return reloc_type == 1; /* R_860_32. */
13468 case EM_960:
13469 return reloc_type == 2; /* R_960_32. */
a06ea964 13470 case EM_AARCH64:
9282b95a
JW
13471 return (reloc_type == 258
13472 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
13473 case EM_BPF:
13474 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
13475 case EM_ADAPTEVA_EPIPHANY:
13476 return reloc_type == 3;
aca88567 13477 case EM_ALPHA:
137b6b5f 13478 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
13479 case EM_ARC:
13480 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
13481 case EM_ARC_COMPACT:
13482 case EM_ARC_COMPACT2:
13483 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
13484 case EM_ARM:
13485 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 13486 case EM_AVR_OLD:
aca88567
NC
13487 case EM_AVR:
13488 return reloc_type == 1;
13489 case EM_BLACKFIN:
13490 return reloc_type == 0x12; /* R_byte4_data. */
13491 case EM_CRIS:
13492 return reloc_type == 3; /* R_CRIS_32. */
13493 case EM_CR16:
13494 return reloc_type == 3; /* R_CR16_NUM32. */
13495 case EM_CRX:
13496 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
13497 case EM_CSKY:
13498 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
13499 case EM_CYGNUS_FRV:
13500 return reloc_type == 1;
41e92641
NC
13501 case EM_CYGNUS_D10V:
13502 case EM_D10V:
13503 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
13504 case EM_CYGNUS_D30V:
13505 case EM_D30V:
13506 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
13507 case EM_DLX:
13508 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
13509 case EM_CYGNUS_FR30:
13510 case EM_FR30:
13511 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
13512 case EM_FT32:
13513 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
13514 case EM_H8S:
13515 case EM_H8_300:
13516 case EM_H8_300H:
13517 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 13518 case EM_IA_64:
262cdac7
AM
13519 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
13520 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
13521 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
13522 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
13523 case EM_IP2K_OLD:
13524 case EM_IP2K:
13525 return reloc_type == 2; /* R_IP2K_32. */
13526 case EM_IQ2000:
13527 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
13528 case EM_LATTICEMICO32:
13529 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 13530 case EM_M32C_OLD:
aca88567
NC
13531 case EM_M32C:
13532 return reloc_type == 3; /* R_M32C_32. */
13533 case EM_M32R:
13534 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
13535 case EM_68HC11:
13536 case EM_68HC12:
13537 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 13538 case EM_S12Z:
2849d19f
JD
13539 return reloc_type == 7 || /* R_S12Z_EXT32 */
13540 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
13541 case EM_MCORE:
13542 return reloc_type == 1; /* R_MCORE_ADDR32. */
13543 case EM_CYGNUS_MEP:
13544 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
13545 case EM_METAG:
13546 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
13547 case EM_MICROBLAZE:
13548 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
13549 case EM_MIPS:
13550 return reloc_type == 2; /* R_MIPS_32. */
13551 case EM_MMIX:
13552 return reloc_type == 4; /* R_MMIX_32. */
13553 case EM_CYGNUS_MN10200:
13554 case EM_MN10200:
13555 return reloc_type == 1; /* R_MN10200_32. */
13556 case EM_CYGNUS_MN10300:
13557 case EM_MN10300:
13558 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
13559 case EM_MOXIE:
13560 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
13561 case EM_MSP430_OLD:
13562 case EM_MSP430:
13761a11 13563 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
13564 case EM_MT:
13565 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
13566 case EM_NDS32:
13567 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 13568 case EM_ALTERA_NIOS2:
36591ba1 13569 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
13570 case EM_NIOS32:
13571 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
13572 case EM_OR1K:
13573 return reloc_type == 1; /* R_OR1K_32. */
aca88567 13574 case EM_PARISC:
9abca702 13575 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 13576 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 13577 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
13578 case EM_PJ:
13579 case EM_PJ_OLD:
13580 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
13581 case EM_PPC64:
13582 return reloc_type == 1; /* R_PPC64_ADDR32. */
13583 case EM_PPC:
13584 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
13585 case EM_TI_PRU:
13586 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
13587 case EM_RISCV:
13588 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
13589 case EM_RL78:
13590 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
13591 case EM_RX:
13592 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
13593 case EM_S370:
13594 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
13595 case EM_S390_OLD:
13596 case EM_S390:
13597 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
13598 case EM_SCORE:
13599 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
13600 case EM_SH:
13601 return reloc_type == 1; /* R_SH_DIR32. */
13602 case EM_SPARC32PLUS:
13603 case EM_SPARCV9:
13604 case EM_SPARC:
13605 return reloc_type == 3 /* R_SPARC_32. */
13606 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
13607 case EM_SPU:
13608 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
13609 case EM_TI_C6000:
13610 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
13611 case EM_TILEGX:
13612 return reloc_type == 2; /* R_TILEGX_32. */
13613 case EM_TILEPRO:
13614 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
13615 case EM_CYGNUS_V850:
13616 case EM_V850:
13617 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
13618 case EM_V800:
13619 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
13620 case EM_VAX:
13621 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
13622 case EM_VISIUM:
13623 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
13624 case EM_WEBASSEMBLY:
13625 return reloc_type == 1; /* R_WASM32_32. */
aca88567 13626 case EM_X86_64:
8a9036a4 13627 case EM_L1OM:
7a9068fe 13628 case EM_K1OM:
aca88567 13629 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
13630 case EM_XC16X:
13631 case EM_C166:
13632 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
13633 case EM_XGATE:
13634 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
13635 case EM_XSTORMY16:
13636 return reloc_type == 1; /* R_XSTROMY16_32. */
13637 case EM_XTENSA_OLD:
13638 case EM_XTENSA:
13639 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
13640 case EM_Z80:
13641 return reloc_type == 6; /* R_Z80_32. */
aca88567 13642 default:
bee0ee85
NC
13643 {
13644 static unsigned int prev_warn = 0;
13645
13646 /* Avoid repeating the same warning multiple times. */
dda8d76d 13647 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 13648 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
13649 filedata->file_header.e_machine);
13650 prev_warn = filedata->file_header.e_machine;
015dc7e1 13651 return false;
bee0ee85 13652 }
aca88567
NC
13653 }
13654}
13655
13656/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13657 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
13658
015dc7e1 13659static bool
dda8d76d 13660is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13661{
dda8d76d 13662 switch (filedata->file_header.e_machine)
d347c9df 13663 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 13664 {
41e92641 13665 case EM_386:
22abe556 13666 case EM_IAMCU:
3e0873ac 13667 return reloc_type == 2; /* R_386_PC32. */
aca88567 13668 case EM_68K:
3e0873ac 13669 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
13670 case EM_AARCH64:
13671 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
13672 case EM_ADAPTEVA_EPIPHANY:
13673 return reloc_type == 6;
aca88567
NC
13674 case EM_ALPHA:
13675 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
13676 case EM_ARC_COMPACT:
13677 case EM_ARC_COMPACT2:
13678 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 13679 case EM_ARM:
3e0873ac 13680 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
13681 case EM_AVR_OLD:
13682 case EM_AVR:
13683 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
13684 case EM_MICROBLAZE:
13685 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
13686 case EM_OR1K:
13687 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 13688 case EM_PARISC:
85acf597 13689 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
13690 case EM_PPC:
13691 return reloc_type == 26; /* R_PPC_REL32. */
13692 case EM_PPC64:
3e0873ac 13693 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
13694 case EM_RISCV:
13695 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
13696 case EM_S390_OLD:
13697 case EM_S390:
3e0873ac 13698 return reloc_type == 5; /* R_390_PC32. */
aca88567 13699 case EM_SH:
3e0873ac 13700 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
13701 case EM_SPARC32PLUS:
13702 case EM_SPARCV9:
13703 case EM_SPARC:
3e0873ac 13704 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
13705 case EM_SPU:
13706 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
13707 case EM_TILEGX:
13708 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
13709 case EM_TILEPRO:
13710 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
13711 case EM_VISIUM:
13712 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 13713 case EM_X86_64:
8a9036a4 13714 case EM_L1OM:
7a9068fe 13715 case EM_K1OM:
3e0873ac 13716 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
13717 case EM_VAX:
13718 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
13719 case EM_XTENSA_OLD:
13720 case EM_XTENSA:
13721 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
13722 default:
13723 /* Do not abort or issue an error message here. Not all targets use
13724 pc-relative 32-bit relocs in their DWARF debug information and we
13725 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
13726 more helpful warning message will be generated by apply_relocations
13727 anyway, so just return. */
015dc7e1 13728 return false;
aca88567
NC
13729 }
13730}
13731
13732/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13733 a 64-bit absolute RELA relocation used in DWARF debug sections. */
13734
015dc7e1 13735static bool
dda8d76d 13736is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13737{
dda8d76d 13738 switch (filedata->file_header.e_machine)
aca88567 13739 {
a06ea964
NC
13740 case EM_AARCH64:
13741 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
13742 case EM_ALPHA:
13743 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 13744 case EM_IA_64:
262cdac7
AM
13745 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
13746 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
13747 case EM_PARISC:
13748 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
13749 case EM_PPC64:
13750 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
13751 case EM_RISCV:
13752 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
13753 case EM_SPARC32PLUS:
13754 case EM_SPARCV9:
13755 case EM_SPARC:
714da62f
NC
13756 return reloc_type == 32 /* R_SPARC_64. */
13757 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 13758 case EM_X86_64:
8a9036a4 13759 case EM_L1OM:
7a9068fe 13760 case EM_K1OM:
aca88567 13761 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
13762 case EM_S390_OLD:
13763 case EM_S390:
aa137e4d
NC
13764 return reloc_type == 22; /* R_S390_64. */
13765 case EM_TILEGX:
13766 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 13767 case EM_MIPS:
aa137e4d 13768 return reloc_type == 18; /* R_MIPS_64. */
aca88567 13769 default:
015dc7e1 13770 return false;
aca88567
NC
13771 }
13772}
13773
85acf597
RH
13774/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
13775 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
13776
015dc7e1 13777static bool
dda8d76d 13778is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 13779{
dda8d76d 13780 switch (filedata->file_header.e_machine)
85acf597 13781 {
a06ea964
NC
13782 case EM_AARCH64:
13783 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 13784 case EM_ALPHA:
aa137e4d 13785 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 13786 case EM_IA_64:
262cdac7
AM
13787 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
13788 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 13789 case EM_PARISC:
aa137e4d 13790 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 13791 case EM_PPC64:
aa137e4d 13792 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
13793 case EM_SPARC32PLUS:
13794 case EM_SPARCV9:
13795 case EM_SPARC:
aa137e4d 13796 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 13797 case EM_X86_64:
8a9036a4 13798 case EM_L1OM:
7a9068fe 13799 case EM_K1OM:
aa137e4d 13800 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
13801 case EM_S390_OLD:
13802 case EM_S390:
aa137e4d
NC
13803 return reloc_type == 23; /* R_S390_PC64. */
13804 case EM_TILEGX:
13805 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 13806 default:
015dc7e1 13807 return false;
85acf597
RH
13808 }
13809}
13810
4dc3c23d
AM
13811/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13812 a 24-bit absolute RELA relocation used in DWARF debug sections. */
13813
015dc7e1 13814static bool
dda8d76d 13815is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 13816{
dda8d76d 13817 switch (filedata->file_header.e_machine)
4dc3c23d
AM
13818 {
13819 case EM_CYGNUS_MN10200:
13820 case EM_MN10200:
13821 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
13822 case EM_FT32:
13823 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
13824 case EM_Z80:
13825 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 13826 default:
015dc7e1 13827 return false;
4dc3c23d
AM
13828 }
13829}
13830
aca88567
NC
13831/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13832 a 16-bit absolute RELA relocation used in DWARF debug sections. */
13833
015dc7e1 13834static bool
dda8d76d 13835is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 13836{
d347c9df 13837 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13838 switch (filedata->file_header.e_machine)
4b78141a 13839 {
886a2506
NC
13840 case EM_ARC:
13841 case EM_ARC_COMPACT:
13842 case EM_ARC_COMPACT2:
13843 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
13844 case EM_ADAPTEVA_EPIPHANY:
13845 return reloc_type == 5;
aca88567
NC
13846 case EM_AVR_OLD:
13847 case EM_AVR:
13848 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
13849 case EM_CYGNUS_D10V:
13850 case EM_D10V:
13851 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
13852 case EM_FT32:
13853 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
13854 case EM_H8S:
13855 case EM_H8_300:
13856 case EM_H8_300H:
aca88567
NC
13857 return reloc_type == R_H8_DIR16;
13858 case EM_IP2K_OLD:
13859 case EM_IP2K:
13860 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 13861 case EM_M32C_OLD:
f4236fe4
DD
13862 case EM_M32C:
13863 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
13864 case EM_CYGNUS_MN10200:
13865 case EM_MN10200:
13866 return reloc_type == 2; /* R_MN10200_16. */
13867 case EM_CYGNUS_MN10300:
13868 case EM_MN10300:
13869 return reloc_type == 2; /* R_MN10300_16. */
aca88567 13870 case EM_MSP430:
dda8d76d 13871 if (uses_msp430x_relocs (filedata))
13761a11 13872 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 13873 /* Fall through. */
78c8d46c 13874 case EM_MSP430_OLD:
aca88567 13875 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
13876 case EM_NDS32:
13877 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 13878 case EM_ALTERA_NIOS2:
36591ba1 13879 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
13880 case EM_NIOS32:
13881 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
13882 case EM_OR1K:
13883 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
13884 case EM_RISCV:
13885 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
13886 case EM_TI_PRU:
13887 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
13888 case EM_TI_C6000:
13889 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
13890 case EM_VISIUM:
13891 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
13892 case EM_XC16X:
13893 case EM_C166:
13894 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
13895 case EM_XGATE:
13896 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
13897 case EM_Z80:
13898 return reloc_type == 4; /* R_Z80_16. */
4b78141a 13899 default:
015dc7e1 13900 return false;
4b78141a
NC
13901 }
13902}
13903
39e07931
AS
13904/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13905 a 8-bit absolute RELA relocation used in DWARF debug sections. */
13906
015dc7e1 13907static bool
39e07931
AS
13908is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13909{
13910 switch (filedata->file_header.e_machine)
13911 {
13912 case EM_RISCV:
13913 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
13914 case EM_Z80:
13915 return reloc_type == 1; /* R_Z80_8. */
39e07931 13916 default:
015dc7e1 13917 return false;
39e07931
AS
13918 }
13919}
13920
13921/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13922 a 6-bit absolute RELA relocation used in DWARF debug sections. */
13923
015dc7e1 13924static bool
39e07931
AS
13925is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13926{
13927 switch (filedata->file_header.e_machine)
13928 {
13929 case EM_RISCV:
13930 return reloc_type == 53; /* R_RISCV_SET6. */
13931 default:
015dc7e1 13932 return false;
39e07931
AS
13933 }
13934}
13935
03336641
JW
13936/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13937 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
13938
015dc7e1 13939static bool
03336641
JW
13940is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13941{
13942 /* Please keep this table alpha-sorted for ease of visual lookup. */
13943 switch (filedata->file_header.e_machine)
13944 {
13945 case EM_RISCV:
13946 return reloc_type == 35; /* R_RISCV_ADD32. */
13947 default:
015dc7e1 13948 return false;
03336641
JW
13949 }
13950}
13951
13952/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13953 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
13954
015dc7e1 13955static bool
03336641
JW
13956is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13957{
13958 /* Please keep this table alpha-sorted for ease of visual lookup. */
13959 switch (filedata->file_header.e_machine)
13960 {
13961 case EM_RISCV:
13962 return reloc_type == 39; /* R_RISCV_SUB32. */
13963 default:
015dc7e1 13964 return false;
03336641
JW
13965 }
13966}
13967
13968/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13969 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
13970
015dc7e1 13971static bool
03336641
JW
13972is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13973{
13974 /* Please keep this table alpha-sorted for ease of visual lookup. */
13975 switch (filedata->file_header.e_machine)
13976 {
13977 case EM_RISCV:
13978 return reloc_type == 36; /* R_RISCV_ADD64. */
13979 default:
015dc7e1 13980 return false;
03336641
JW
13981 }
13982}
13983
13984/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13985 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
13986
015dc7e1 13987static bool
03336641
JW
13988is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13989{
13990 /* Please keep this table alpha-sorted for ease of visual lookup. */
13991 switch (filedata->file_header.e_machine)
13992 {
13993 case EM_RISCV:
13994 return reloc_type == 40; /* R_RISCV_SUB64. */
13995 default:
015dc7e1 13996 return false;
03336641
JW
13997 }
13998}
13999
14000/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14001 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14002
015dc7e1 14003static bool
03336641
JW
14004is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14005{
14006 /* Please keep this table alpha-sorted for ease of visual lookup. */
14007 switch (filedata->file_header.e_machine)
14008 {
14009 case EM_RISCV:
14010 return reloc_type == 34; /* R_RISCV_ADD16. */
14011 default:
015dc7e1 14012 return false;
03336641
JW
14013 }
14014}
14015
14016/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14017 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14018
015dc7e1 14019static bool
03336641
JW
14020is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14021{
14022 /* Please keep this table alpha-sorted for ease of visual lookup. */
14023 switch (filedata->file_header.e_machine)
14024 {
14025 case EM_RISCV:
14026 return reloc_type == 38; /* R_RISCV_SUB16. */
14027 default:
015dc7e1 14028 return false;
03336641
JW
14029 }
14030}
14031
14032/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14033 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14034
015dc7e1 14035static bool
03336641
JW
14036is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14037{
14038 /* Please keep this table alpha-sorted for ease of visual lookup. */
14039 switch (filedata->file_header.e_machine)
14040 {
14041 case EM_RISCV:
14042 return reloc_type == 33; /* R_RISCV_ADD8. */
14043 default:
015dc7e1 14044 return false;
03336641
JW
14045 }
14046}
14047
14048/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14049 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14050
015dc7e1 14051static bool
03336641
JW
14052is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14053{
14054 /* Please keep this table alpha-sorted for ease of visual lookup. */
14055 switch (filedata->file_header.e_machine)
14056 {
14057 case EM_RISCV:
14058 return reloc_type == 37; /* R_RISCV_SUB8. */
14059 default:
015dc7e1 14060 return false;
03336641
JW
14061 }
14062}
14063
39e07931
AS
14064/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14065 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14066
015dc7e1 14067static bool
39e07931
AS
14068is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14069{
14070 switch (filedata->file_header.e_machine)
14071 {
14072 case EM_RISCV:
14073 return reloc_type == 52; /* R_RISCV_SUB6. */
14074 default:
015dc7e1 14075 return false;
39e07931
AS
14076 }
14077}
14078
2a7b2e88
JK
14079/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14080 relocation entries (possibly formerly used for SHT_GROUP sections). */
14081
015dc7e1 14082static bool
dda8d76d 14083is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14084{
dda8d76d 14085 switch (filedata->file_header.e_machine)
2a7b2e88 14086 {
cb8f3167 14087 case EM_386: /* R_386_NONE. */
d347c9df 14088 case EM_68K: /* R_68K_NONE. */
cfb8c092 14089 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14090 case EM_ALPHA: /* R_ALPHA_NONE. */
14091 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14092 case EM_ARC: /* R_ARC_NONE. */
886a2506 14093 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14094 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14095 case EM_ARM: /* R_ARM_NONE. */
d347c9df 14096 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 14097 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14098 case EM_FT32: /* R_FT32_NONE. */
14099 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14100 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14101 case EM_L1OM: /* R_X86_64_NONE. */
14102 case EM_M32R: /* R_M32R_NONE. */
14103 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14104 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14105 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14106 case EM_NIOS32: /* R_NIOS_NONE. */
14107 case EM_OR1K: /* R_OR1K_NONE. */
14108 case EM_PARISC: /* R_PARISC_NONE. */
14109 case EM_PPC64: /* R_PPC64_NONE. */
14110 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14111 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14112 case EM_S390: /* R_390_NONE. */
14113 case EM_S390_OLD:
14114 case EM_SH: /* R_SH_NONE. */
14115 case EM_SPARC32PLUS:
14116 case EM_SPARC: /* R_SPARC_NONE. */
14117 case EM_SPARCV9:
aa137e4d
NC
14118 case EM_TILEGX: /* R_TILEGX_NONE. */
14119 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14120 case EM_TI_C6000:/* R_C6000_NONE. */
14121 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 14122 case EM_XC16X:
6655dba2 14123 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14124 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14125 return reloc_type == 0;
d347c9df 14126
a06ea964
NC
14127 case EM_AARCH64:
14128 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14129 case EM_AVR_OLD:
14130 case EM_AVR:
14131 return (reloc_type == 0 /* R_AVR_NONE. */
14132 || reloc_type == 30 /* R_AVR_DIFF8. */
14133 || reloc_type == 31 /* R_AVR_DIFF16. */
14134 || reloc_type == 32 /* R_AVR_DIFF32. */);
14135 case EM_METAG:
14136 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
14137 case EM_NDS32:
14138 return (reloc_type == 0 /* R_XTENSA_NONE. */
14139 || reloc_type == 204 /* R_NDS32_DIFF8. */
14140 || reloc_type == 205 /* R_NDS32_DIFF16. */
14141 || reloc_type == 206 /* R_NDS32_DIFF32. */
14142 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
14143 case EM_TI_PRU:
14144 return (reloc_type == 0 /* R_PRU_NONE. */
14145 || reloc_type == 65 /* R_PRU_DIFF8. */
14146 || reloc_type == 66 /* R_PRU_DIFF16. */
14147 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14148 case EM_XTENSA_OLD:
14149 case EM_XTENSA:
4dc3c23d
AM
14150 return (reloc_type == 0 /* R_XTENSA_NONE. */
14151 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14152 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14153 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14154 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14155 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14156 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14157 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14158 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14159 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14160 }
015dc7e1 14161 return false;
2a7b2e88
JK
14162}
14163
d1c4b12b
NC
14164/* Returns TRUE if there is a relocation against
14165 section NAME at OFFSET bytes. */
14166
015dc7e1 14167bool
d1c4b12b
NC
14168reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14169{
14170 Elf_Internal_Rela * relocs;
14171 Elf_Internal_Rela * rp;
14172
14173 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14174 return false;
d1c4b12b
NC
14175
14176 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14177
14178 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14179 if (rp->r_offset == offset)
015dc7e1 14180 return true;
d1c4b12b 14181
015dc7e1 14182 return false;
d1c4b12b
NC
14183}
14184
cf13d699 14185/* Apply relocations to a section.
32ec8896
NC
14186 Returns TRUE upon success, FALSE otherwise.
14187 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14188 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14189 will be set to the number of relocs loaded.
14190
cf13d699 14191 Note: So far support has been added only for those relocations
32ec8896
NC
14192 which can be found in debug sections. FIXME: Add support for
14193 more relocations ? */
1b315056 14194
015dc7e1 14195static bool
dda8d76d 14196apply_relocations (Filedata * filedata,
d1c4b12b
NC
14197 const Elf_Internal_Shdr * section,
14198 unsigned char * start,
14199 bfd_size_type size,
1449284b 14200 void ** relocs_return,
d1c4b12b 14201 unsigned long * num_relocs_return)
1b315056 14202{
cf13d699 14203 Elf_Internal_Shdr * relsec;
0d2a7a93 14204 unsigned char * end = start + size;
cb8f3167 14205
d1c4b12b
NC
14206 if (relocs_return != NULL)
14207 {
14208 * (Elf_Internal_Rela **) relocs_return = NULL;
14209 * num_relocs_return = 0;
14210 }
14211
dda8d76d 14212 if (filedata->file_header.e_type != ET_REL)
32ec8896 14213 /* No relocs to apply. */
015dc7e1 14214 return true;
1b315056 14215
cf13d699 14216 /* Find the reloc section associated with the section. */
dda8d76d
NC
14217 for (relsec = filedata->section_headers;
14218 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14219 ++relsec)
252b5132 14220 {
015dc7e1 14221 bool is_rela;
41e92641 14222 unsigned long num_relocs;
2cf0635d
NC
14223 Elf_Internal_Rela * relocs;
14224 Elf_Internal_Rela * rp;
14225 Elf_Internal_Shdr * symsec;
14226 Elf_Internal_Sym * symtab;
ba5cdace 14227 unsigned long num_syms;
2cf0635d 14228 Elf_Internal_Sym * sym;
252b5132 14229
41e92641 14230 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14231 || relsec->sh_info >= filedata->file_header.e_shnum
14232 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14233 || relsec->sh_size == 0
dda8d76d 14234 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14235 continue;
428409d5 14236
a788aedd
AM
14237 symsec = filedata->section_headers + relsec->sh_link;
14238 if (symsec->sh_type != SHT_SYMTAB
14239 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14240 return false;
a788aedd 14241
41e92641
NC
14242 is_rela = relsec->sh_type == SHT_RELA;
14243
14244 if (is_rela)
14245 {
dda8d76d 14246 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14247 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14248 return false;
41e92641
NC
14249 }
14250 else
14251 {
dda8d76d 14252 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14253 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14254 return false;
41e92641
NC
14255 }
14256
14257 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14258 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14259 is_rela = false;
428409d5 14260
dda8d76d 14261 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 14262
41e92641 14263 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14264 {
015dc7e1
AM
14265 bfd_vma addend;
14266 unsigned int reloc_type;
14267 unsigned int reloc_size;
14268 bool reloc_inplace = false;
14269 bool reloc_subtract = false;
14270 unsigned char *rloc;
14271 unsigned long sym_index;
4b78141a 14272
dda8d76d 14273 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14274
dda8d76d 14275 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14276 continue;
dda8d76d 14277 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14278 continue;
dda8d76d
NC
14279 else if (is_32bit_abs_reloc (filedata, reloc_type)
14280 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14281 reloc_size = 4;
dda8d76d
NC
14282 else if (is_64bit_abs_reloc (filedata, reloc_type)
14283 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14284 reloc_size = 8;
dda8d76d 14285 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14286 reloc_size = 3;
dda8d76d 14287 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14288 reloc_size = 2;
39e07931
AS
14289 else if (is_8bit_abs_reloc (filedata, reloc_type)
14290 || is_6bit_abs_reloc (filedata, reloc_type))
14291 reloc_size = 1;
03336641
JW
14292 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14293 reloc_type))
14294 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14295 {
14296 reloc_size = 4;
015dc7e1 14297 reloc_inplace = true;
03336641
JW
14298 }
14299 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14300 reloc_type))
14301 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14302 {
14303 reloc_size = 8;
015dc7e1 14304 reloc_inplace = true;
03336641
JW
14305 }
14306 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14307 reloc_type))
14308 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14309 {
14310 reloc_size = 2;
015dc7e1 14311 reloc_inplace = true;
03336641
JW
14312 }
14313 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14314 reloc_type))
14315 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14316 {
14317 reloc_size = 1;
015dc7e1 14318 reloc_inplace = true;
03336641 14319 }
39e07931
AS
14320 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
14321 reloc_type)))
14322 {
14323 reloc_size = 1;
015dc7e1 14324 reloc_inplace = true;
39e07931 14325 }
aca88567 14326 else
4b78141a 14327 {
bee0ee85 14328 static unsigned int prev_reloc = 0;
dda8d76d 14329
bee0ee85
NC
14330 if (reloc_type != prev_reloc)
14331 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 14332 reloc_type, printable_section_name (filedata, section));
bee0ee85 14333 prev_reloc = reloc_type;
4b78141a
NC
14334 continue;
14335 }
103f02d3 14336
91d6fa6a 14337 rloc = start + rp->r_offset;
75802ccb 14338 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
14339 {
14340 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
14341 (unsigned long) rp->r_offset,
dda8d76d 14342 printable_section_name (filedata, section));
700dd8b7
L
14343 continue;
14344 }
103f02d3 14345
ba5cdace
NC
14346 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
14347 if (sym_index >= num_syms)
14348 {
14349 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 14350 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
14351 continue;
14352 }
14353 sym = symtab + sym_index;
41e92641
NC
14354
14355 /* If the reloc has a symbol associated with it,
55f25fc3
L
14356 make sure that it is of an appropriate type.
14357
14358 Relocations against symbols without type can happen.
14359 Gcc -feliminate-dwarf2-dups may generate symbols
14360 without type for debug info.
14361
14362 Icc generates relocations against function symbols
14363 instead of local labels.
14364
14365 Relocations against object symbols can happen, eg when
14366 referencing a global array. For an example of this see
14367 the _clz.o binary in libgcc.a. */
aca88567 14368 if (sym != symtab
b8871f35 14369 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 14370 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 14371 {
d3a49aa8 14372 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
14373 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
14374 printable_section_name (filedata, relsec),
d3a49aa8 14375 (long int)(rp - relocs));
aca88567 14376 continue;
5b18a4bc 14377 }
252b5132 14378
4dc3c23d
AM
14379 addend = 0;
14380 if (is_rela)
14381 addend += rp->r_addend;
c47320c3
AM
14382 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
14383 partial_inplace. */
4dc3c23d 14384 if (!is_rela
dda8d76d 14385 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 14386 && reloc_type == 1)
dda8d76d
NC
14387 || ((filedata->file_header.e_machine == EM_PJ
14388 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 14389 && reloc_type == 1)
dda8d76d
NC
14390 || ((filedata->file_header.e_machine == EM_D30V
14391 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
14392 && reloc_type == 12)
14393 || reloc_inplace)
39e07931
AS
14394 {
14395 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
14396 addend += byte_get (rloc, reloc_size) & 0x3f;
14397 else
14398 addend += byte_get (rloc, reloc_size);
14399 }
cb8f3167 14400
dda8d76d
NC
14401 if (is_32bit_pcrel_reloc (filedata, reloc_type)
14402 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
14403 {
14404 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 14405 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 14406 addend -= 8;
91d6fa6a 14407 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
14408 reloc_size);
14409 }
39e07931
AS
14410 else if (is_6bit_abs_reloc (filedata, reloc_type)
14411 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
14412 {
14413 if (reloc_subtract)
14414 addend -= sym->st_value;
14415 else
14416 addend += sym->st_value;
14417 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
14418 byte_put (rloc, addend, reloc_size);
14419 }
03336641
JW
14420 else if (reloc_subtract)
14421 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 14422 else
91d6fa6a 14423 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 14424 }
252b5132 14425
5b18a4bc 14426 free (symtab);
f84ce13b
NC
14427 /* Let the target specific reloc processing code know that
14428 we have finished with these relocs. */
dda8d76d 14429 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
14430
14431 if (relocs_return)
14432 {
14433 * (Elf_Internal_Rela **) relocs_return = relocs;
14434 * num_relocs_return = num_relocs;
14435 }
14436 else
14437 free (relocs);
14438
5b18a4bc
NC
14439 break;
14440 }
32ec8896 14441
015dc7e1 14442 return true;
5b18a4bc 14443}
103f02d3 14444
cf13d699 14445#ifdef SUPPORT_DISASSEMBLY
015dc7e1 14446static bool
dda8d76d 14447disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14448{
dda8d76d 14449 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 14450
74e1a04b 14451 /* FIXME: XXX -- to be done --- XXX */
cf13d699 14452
015dc7e1 14453 return true;
cf13d699
NC
14454}
14455#endif
14456
14457/* Reads in the contents of SECTION from FILE, returning a pointer
14458 to a malloc'ed buffer or NULL if something went wrong. */
14459
14460static char *
dda8d76d 14461get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14462{
dda8d76d 14463 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
14464
14465 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
14466 {
c6b78c96 14467 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 14468 printable_section_name (filedata, section));
cf13d699
NC
14469 return NULL;
14470 }
14471
dda8d76d 14472 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 14473 _("section contents"));
cf13d699
NC
14474}
14475
0e602686
NC
14476/* Uncompresses a section that was compressed using zlib, in place. */
14477
015dc7e1 14478static bool
dda8d76d
NC
14479uncompress_section_contents (unsigned char ** buffer,
14480 dwarf_size_type uncompressed_size,
14481 dwarf_size_type * size)
0e602686
NC
14482{
14483 dwarf_size_type compressed_size = *size;
14484 unsigned char * compressed_buffer = *buffer;
14485 unsigned char * uncompressed_buffer;
14486 z_stream strm;
14487 int rc;
14488
14489 /* It is possible the section consists of several compressed
14490 buffers concatenated together, so we uncompress in a loop. */
14491 /* PR 18313: The state field in the z_stream structure is supposed
14492 to be invisible to the user (ie us), but some compilers will
14493 still complain about it being used without initialisation. So
14494 we first zero the entire z_stream structure and then set the fields
14495 that we need. */
14496 memset (& strm, 0, sizeof strm);
14497 strm.avail_in = compressed_size;
14498 strm.next_in = (Bytef *) compressed_buffer;
14499 strm.avail_out = uncompressed_size;
14500 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
14501
14502 rc = inflateInit (& strm);
14503 while (strm.avail_in > 0)
14504 {
14505 if (rc != Z_OK)
3624a6c1 14506 break;
0e602686
NC
14507 strm.next_out = ((Bytef *) uncompressed_buffer
14508 + (uncompressed_size - strm.avail_out));
14509 rc = inflate (&strm, Z_FINISH);
14510 if (rc != Z_STREAM_END)
3624a6c1 14511 break;
0e602686
NC
14512 rc = inflateReset (& strm);
14513 }
ad92f33d
AM
14514 if (inflateEnd (& strm) != Z_OK
14515 || rc != Z_OK
0e602686
NC
14516 || strm.avail_out != 0)
14517 goto fail;
14518
14519 *buffer = uncompressed_buffer;
14520 *size = uncompressed_size;
015dc7e1 14521 return true;
0e602686
NC
14522
14523 fail:
14524 free (uncompressed_buffer);
14525 /* Indicate decompression failure. */
14526 *buffer = NULL;
015dc7e1 14527 return false;
0e602686 14528}
dd24e3da 14529
015dc7e1 14530static bool
dda8d76d 14531dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14532{
015dc7e1
AM
14533 Elf_Internal_Shdr *relsec;
14534 bfd_size_type num_bytes;
14535 unsigned char *data;
14536 unsigned char *end;
14537 unsigned char *real_start;
14538 unsigned char *start;
14539 bool some_strings_shown;
cf13d699 14540
dda8d76d 14541 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14542 if (start == NULL)
c6b78c96 14543 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 14544 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 14545
0e602686 14546 num_bytes = section->sh_size;
cf13d699 14547
835f2fae
NC
14548 if (filedata->is_separate)
14549 printf (_("\nString dump of section '%s' in linked file %s:\n"),
14550 printable_section_name (filedata, section),
14551 filedata->file_name);
14552 else
14553 printf (_("\nString dump of section '%s':\n"),
14554 printable_section_name (filedata, section));
cf13d699 14555
0e602686
NC
14556 if (decompress_dumps)
14557 {
14558 dwarf_size_type new_size = num_bytes;
14559 dwarf_size_type uncompressed_size = 0;
14560
14561 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14562 {
14563 Elf_Internal_Chdr chdr;
14564 unsigned int compression_header_size
ebdf1ebf
NC
14565 = get_compression_header (& chdr, (unsigned char *) start,
14566 num_bytes);
5844b465
NC
14567 if (compression_header_size == 0)
14568 /* An error message will have already been generated
14569 by get_compression_header. */
14570 goto error_out;
0e602686 14571
813dabb9 14572 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14573 {
813dabb9 14574 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14575 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14576 goto error_out;
813dabb9 14577 }
813dabb9
L
14578 uncompressed_size = chdr.ch_size;
14579 start += compression_header_size;
14580 new_size -= compression_header_size;
0e602686
NC
14581 }
14582 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14583 {
14584 /* Read the zlib header. In this case, it should be "ZLIB"
14585 followed by the uncompressed section size, 8 bytes in
14586 big-endian order. */
14587 uncompressed_size = start[4]; uncompressed_size <<= 8;
14588 uncompressed_size += start[5]; uncompressed_size <<= 8;
14589 uncompressed_size += start[6]; uncompressed_size <<= 8;
14590 uncompressed_size += start[7]; uncompressed_size <<= 8;
14591 uncompressed_size += start[8]; uncompressed_size <<= 8;
14592 uncompressed_size += start[9]; uncompressed_size <<= 8;
14593 uncompressed_size += start[10]; uncompressed_size <<= 8;
14594 uncompressed_size += start[11];
14595 start += 12;
14596 new_size -= 12;
14597 }
14598
1835f746
NC
14599 if (uncompressed_size)
14600 {
14601 if (uncompress_section_contents (& start,
14602 uncompressed_size, & new_size))
14603 num_bytes = new_size;
14604 else
14605 {
14606 error (_("Unable to decompress section %s\n"),
dda8d76d 14607 printable_section_name (filedata, section));
f761cb13 14608 goto error_out;
1835f746
NC
14609 }
14610 }
bc303e5d
NC
14611 else
14612 start = real_start;
0e602686 14613 }
fd8008d8 14614
cf13d699
NC
14615 /* If the section being dumped has relocations against it the user might
14616 be expecting these relocations to have been applied. Check for this
14617 case and issue a warning message in order to avoid confusion.
14618 FIXME: Maybe we ought to have an option that dumps a section with
14619 relocs applied ? */
dda8d76d
NC
14620 for (relsec = filedata->section_headers;
14621 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14622 ++relsec)
14623 {
14624 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14625 || relsec->sh_info >= filedata->file_header.e_shnum
14626 || filedata->section_headers + relsec->sh_info != section
cf13d699 14627 || relsec->sh_size == 0
dda8d76d 14628 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14629 continue;
14630
14631 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14632 break;
14633 }
14634
cf13d699
NC
14635 data = start;
14636 end = start + num_bytes;
015dc7e1 14637 some_strings_shown = false;
cf13d699 14638
ba3265d0
NC
14639#ifdef HAVE_MBSTATE_T
14640 mbstate_t state;
14641 /* Initialise the multibyte conversion state. */
14642 memset (& state, 0, sizeof (state));
14643#endif
14644
015dc7e1 14645 bool continuing = false;
ba3265d0 14646
cf13d699
NC
14647 while (data < end)
14648 {
14649 while (!ISPRINT (* data))
14650 if (++ data >= end)
14651 break;
14652
14653 if (data < end)
14654 {
071436c6
NC
14655 size_t maxlen = end - data;
14656
ba3265d0
NC
14657 if (continuing)
14658 {
14659 printf (" ");
015dc7e1 14660 continuing = false;
ba3265d0
NC
14661 }
14662 else
14663 {
d1ce973e 14664 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
14665 }
14666
4082ef84
NC
14667 if (maxlen > 0)
14668 {
f3da8a96 14669 char c = 0;
ba3265d0
NC
14670
14671 while (maxlen)
14672 {
14673 c = *data++;
14674
14675 if (c == 0)
14676 break;
14677
14678 /* PR 25543: Treat new-lines as string-ending characters. */
14679 if (c == '\n')
14680 {
14681 printf ("\\n\n");
14682 if (*data != 0)
015dc7e1 14683 continuing = true;
ba3265d0
NC
14684 break;
14685 }
14686
14687 /* Do not print control characters directly as they can affect terminal
14688 settings. Such characters usually appear in the names generated
14689 by the assembler for local labels. */
14690 if (ISCNTRL (c))
14691 {
14692 printf ("^%c", c + 0x40);
14693 }
14694 else if (ISPRINT (c))
14695 {
14696 putchar (c);
14697 }
14698 else
14699 {
14700 size_t n;
14701#ifdef HAVE_MBSTATE_T
14702 wchar_t w;
14703#endif
14704 /* Let printf do the hard work of displaying multibyte characters. */
14705 printf ("%.1s", data - 1);
14706#ifdef HAVE_MBSTATE_T
14707 /* Try to find out how many bytes made up the character that was
14708 just printed. Advance the symbol pointer past the bytes that
14709 were displayed. */
14710 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
14711#else
14712 n = 1;
14713#endif
14714 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
14715 data += (n - 1);
14716 }
14717 }
14718
14719 if (c != '\n')
14720 putchar ('\n');
4082ef84
NC
14721 }
14722 else
14723 {
14724 printf (_("<corrupt>\n"));
14725 data = end;
14726 }
015dc7e1 14727 some_strings_shown = true;
cf13d699
NC
14728 }
14729 }
14730
14731 if (! some_strings_shown)
14732 printf (_(" No strings found in this section."));
14733
0e602686 14734 free (real_start);
cf13d699
NC
14735
14736 putchar ('\n');
015dc7e1 14737 return true;
f761cb13
AM
14738
14739error_out:
14740 free (real_start);
015dc7e1 14741 return false;
cf13d699
NC
14742}
14743
015dc7e1
AM
14744static bool
14745dump_section_as_bytes (Elf_Internal_Shdr *section,
14746 Filedata *filedata,
14747 bool relocate)
cf13d699
NC
14748{
14749 Elf_Internal_Shdr * relsec;
0e602686
NC
14750 bfd_size_type bytes;
14751 bfd_size_type section_size;
14752 bfd_vma addr;
14753 unsigned char * data;
14754 unsigned char * real_start;
14755 unsigned char * start;
14756
dda8d76d 14757 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14758 if (start == NULL)
c6b78c96 14759 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 14760 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 14761
0e602686 14762 section_size = section->sh_size;
cf13d699 14763
835f2fae
NC
14764 if (filedata->is_separate)
14765 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
14766 printable_section_name (filedata, section),
14767 filedata->file_name);
14768 else
14769 printf (_("\nHex dump of section '%s':\n"),
14770 printable_section_name (filedata, section));
cf13d699 14771
0e602686
NC
14772 if (decompress_dumps)
14773 {
14774 dwarf_size_type new_size = section_size;
14775 dwarf_size_type uncompressed_size = 0;
14776
14777 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14778 {
14779 Elf_Internal_Chdr chdr;
14780 unsigned int compression_header_size
ebdf1ebf 14781 = get_compression_header (& chdr, start, section_size);
0e602686 14782
5844b465
NC
14783 if (compression_header_size == 0)
14784 /* An error message will have already been generated
14785 by get_compression_header. */
14786 goto error_out;
14787
813dabb9 14788 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14789 {
813dabb9 14790 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14791 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14792 goto error_out;
0e602686 14793 }
813dabb9
L
14794 uncompressed_size = chdr.ch_size;
14795 start += compression_header_size;
14796 new_size -= compression_header_size;
0e602686
NC
14797 }
14798 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14799 {
14800 /* Read the zlib header. In this case, it should be "ZLIB"
14801 followed by the uncompressed section size, 8 bytes in
14802 big-endian order. */
14803 uncompressed_size = start[4]; uncompressed_size <<= 8;
14804 uncompressed_size += start[5]; uncompressed_size <<= 8;
14805 uncompressed_size += start[6]; uncompressed_size <<= 8;
14806 uncompressed_size += start[7]; uncompressed_size <<= 8;
14807 uncompressed_size += start[8]; uncompressed_size <<= 8;
14808 uncompressed_size += start[9]; uncompressed_size <<= 8;
14809 uncompressed_size += start[10]; uncompressed_size <<= 8;
14810 uncompressed_size += start[11];
14811 start += 12;
14812 new_size -= 12;
14813 }
14814
f055032e
NC
14815 if (uncompressed_size)
14816 {
14817 if (uncompress_section_contents (& start, uncompressed_size,
14818 & new_size))
bc303e5d
NC
14819 {
14820 section_size = new_size;
14821 }
f055032e
NC
14822 else
14823 {
14824 error (_("Unable to decompress section %s\n"),
dda8d76d 14825 printable_section_name (filedata, section));
bc303e5d 14826 /* FIXME: Print the section anyway ? */
f761cb13 14827 goto error_out;
f055032e
NC
14828 }
14829 }
bc303e5d
NC
14830 else
14831 start = real_start;
0e602686 14832 }
14ae95f2 14833
cf13d699
NC
14834 if (relocate)
14835 {
dda8d76d 14836 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 14837 goto error_out;
cf13d699
NC
14838 }
14839 else
14840 {
14841 /* If the section being dumped has relocations against it the user might
14842 be expecting these relocations to have been applied. Check for this
14843 case and issue a warning message in order to avoid confusion.
14844 FIXME: Maybe we ought to have an option that dumps a section with
14845 relocs applied ? */
dda8d76d
NC
14846 for (relsec = filedata->section_headers;
14847 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14848 ++relsec)
14849 {
14850 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14851 || relsec->sh_info >= filedata->file_header.e_shnum
14852 || filedata->section_headers + relsec->sh_info != section
cf13d699 14853 || relsec->sh_size == 0
dda8d76d 14854 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14855 continue;
14856
14857 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14858 break;
14859 }
14860 }
14861
14862 addr = section->sh_addr;
0e602686 14863 bytes = section_size;
cf13d699
NC
14864 data = start;
14865
14866 while (bytes)
14867 {
14868 int j;
14869 int k;
14870 int lbytes;
14871
14872 lbytes = (bytes > 16 ? 16 : bytes);
14873
14874 printf (" 0x%8.8lx ", (unsigned long) addr);
14875
14876 for (j = 0; j < 16; j++)
14877 {
14878 if (j < lbytes)
14879 printf ("%2.2x", data[j]);
14880 else
14881 printf (" ");
14882
14883 if ((j & 3) == 3)
14884 printf (" ");
14885 }
14886
14887 for (j = 0; j < lbytes; j++)
14888 {
14889 k = data[j];
14890 if (k >= ' ' && k < 0x7f)
14891 printf ("%c", k);
14892 else
14893 printf (".");
14894 }
14895
14896 putchar ('\n');
14897
14898 data += lbytes;
14899 addr += lbytes;
14900 bytes -= lbytes;
14901 }
14902
0e602686 14903 free (real_start);
cf13d699
NC
14904
14905 putchar ('\n');
015dc7e1 14906 return true;
f761cb13
AM
14907
14908 error_out:
14909 free (real_start);
015dc7e1 14910 return false;
cf13d699
NC
14911}
14912
094e34f2 14913#ifdef ENABLE_LIBCTF
7d9813f1
NA
14914static ctf_sect_t *
14915shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
14916{
b9e920ec 14917 buf->cts_name = SECTION_NAME_PRINT (shdr);
7d9813f1
NA
14918 buf->cts_size = shdr->sh_size;
14919 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
14920
14921 return buf;
14922}
14923
14924/* Formatting callback function passed to ctf_dump. Returns either the pointer
14925 it is passed, or a pointer to newly-allocated storage, in which case
14926 dump_ctf() will free it when it no longer needs it. */
14927
2f6ecaed
NA
14928static char *
14929dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14930 char *s, void *arg)
7d9813f1 14931{
3e50a591 14932 const char *blanks = arg;
7d9813f1
NA
14933 char *new_s;
14934
3e50a591 14935 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
14936 return s;
14937 return new_s;
14938}
14939
926c9e76
NA
14940/* Dump CTF errors/warnings. */
14941static void
139633c3 14942dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
14943{
14944 ctf_next_t *it = NULL;
14945 char *errtext;
14946 int is_warning;
14947 int err;
14948
14949 /* Dump accumulated errors and warnings. */
14950 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
14951 {
5e9b84f7 14952 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
14953 errtext);
14954 free (errtext);
14955 }
14956 if (err != ECTF_NEXT_END)
14957 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
14958}
14959
2f6ecaed
NA
14960/* Dump one CTF archive member. */
14961
14962static int
139633c3 14963dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
2f6ecaed 14964{
139633c3 14965 ctf_dict_t *parent = (ctf_dict_t *) arg;
2f6ecaed
NA
14966 const char *things[] = {"Header", "Labels", "Data objects",
14967 "Function objects", "Variables", "Types", "Strings",
14968 ""};
14969 const char **thing;
14970 size_t i;
8b37e7b6 14971 int err = 0;
2f6ecaed
NA
14972
14973 /* Only print out the name of non-default-named archive members.
14974 The name .ctf appears everywhere, even for things that aren't
14975 really archives, so printing it out is liable to be confusing.
14976
14977 The parent, if there is one, is the default-owned archive member:
14978 avoid importing it into itself. (This does no harm, but looks
14979 confusing.) */
14980
14981 if (strcmp (name, ".ctf") != 0)
14982 {
14983 printf (_("\nCTF archive member: %s:\n"), name);
14984 ctf_import (ctf, parent);
14985 }
14986
14987 for (i = 0, thing = things; *thing[0]; thing++, i++)
14988 {
14989 ctf_dump_state_t *s = NULL;
14990 char *item;
14991
14992 printf ("\n %s:\n", *thing);
14993 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
14994 (void *) " ")) != NULL)
14995 {
14996 printf ("%s\n", item);
14997 free (item);
14998 }
14999
15000 if (ctf_errno (ctf))
15001 {
15002 error (_("Iteration failed: %s, %s\n"), *thing,
15003 ctf_errmsg (ctf_errno (ctf)));
8b37e7b6
NA
15004 err = 1;
15005 goto out;
2f6ecaed
NA
15006 }
15007 }
8b37e7b6
NA
15008
15009 out:
926c9e76 15010 dump_ctf_errs (ctf);
8b37e7b6 15011 return err;
2f6ecaed
NA
15012}
15013
015dc7e1 15014static bool
7d9813f1
NA
15015dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15016{
15017 Elf_Internal_Shdr * parent_sec = NULL;
15018 Elf_Internal_Shdr * symtab_sec = NULL;
15019 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15020 void * data = NULL;
15021 void * symdata = NULL;
15022 void * strdata = NULL;
15023 void * parentdata = NULL;
15024 ctf_sect_t ctfsect, symsect, strsect, parentsect;
15025 ctf_sect_t * symsectp = NULL;
15026 ctf_sect_t * strsectp = NULL;
2f6ecaed
NA
15027 ctf_archive_t * ctfa = NULL;
15028 ctf_archive_t * parenta = NULL, *lookparent;
139633c3 15029 ctf_dict_t * parent = NULL;
7d9813f1 15030
7d9813f1 15031 int err;
015dc7e1 15032 bool ret = false;
7d9813f1
NA
15033
15034 shdr_to_ctf_sect (&ctfsect, section, filedata);
15035 data = get_section_contents (section, filedata);
15036 ctfsect.cts_data = data;
15037
616febde 15038 if (!dump_ctf_symtab_name)
3d16b64e 15039 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15040
15041 if (!dump_ctf_strtab_name)
3d16b64e 15042 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15043
15044 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15045 {
15046 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15047 {
15048 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15049 goto fail;
15050 }
15051 if ((symdata = (void *) get_data (NULL, filedata,
15052 symtab_sec->sh_offset, 1,
15053 symtab_sec->sh_size,
15054 _("symbols"))) == NULL)
15055 goto fail;
15056 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15057 symsect.cts_data = symdata;
15058 }
835f2fae 15059
df16e041 15060 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15061 {
15062 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15063 {
15064 error (_("No string table section named %s\n"),
15065 dump_ctf_strtab_name);
15066 goto fail;
15067 }
15068 if ((strdata = (void *) get_data (NULL, filedata,
15069 strtab_sec->sh_offset, 1,
15070 strtab_sec->sh_size,
15071 _("strings"))) == NULL)
15072 goto fail;
15073 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15074 strsect.cts_data = strdata;
15075 }
835f2fae 15076
7d9813f1
NA
15077 if (dump_ctf_parent_name)
15078 {
15079 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
15080 {
15081 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
15082 goto fail;
15083 }
15084 if ((parentdata = (void *) get_data (NULL, filedata,
15085 parent_sec->sh_offset, 1,
15086 parent_sec->sh_size,
15087 _("CTF parent"))) == NULL)
15088 goto fail;
15089 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
15090 parentsect.cts_data = parentdata;
15091 }
15092
2f6ecaed
NA
15093 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15094 libctf papers over the difference, so we can pretend it is always an
15095 archive. Possibly open the parent as well, if one was specified. */
7d9813f1 15096
2f6ecaed 15097 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15098 {
926c9e76 15099 dump_ctf_errs (NULL);
7d9813f1
NA
15100 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15101 goto fail;
15102 }
15103
96c61be5
NA
15104 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15105 != ELFDATA2MSB);
15106
7d9813f1
NA
15107 if (parentdata)
15108 {
2f6ecaed
NA
15109 if ((parenta = ctf_arc_bufopen (&parentsect, symsectp, strsectp,
15110 &err)) == NULL)
7d9813f1 15111 {
926c9e76 15112 dump_ctf_errs (NULL);
7d9813f1
NA
15113 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15114 goto fail;
15115 }
2f6ecaed
NA
15116 lookparent = parenta;
15117 }
15118 else
15119 lookparent = ctfa;
7d9813f1 15120
2f6ecaed
NA
15121 /* Assume that the applicable parent archive member is the default one.
15122 (This is what all known implementations are expected to do, if they
15123 put CTFs and their parents in archives together.) */
ae41200b 15124 if ((parent = ctf_dict_open (lookparent, NULL, &err)) == NULL)
2f6ecaed 15125 {
926c9e76 15126 dump_ctf_errs (NULL);
2f6ecaed
NA
15127 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15128 goto fail;
7d9813f1
NA
15129 }
15130
015dc7e1 15131 ret = true;
7d9813f1 15132
835f2fae
NC
15133 if (filedata->is_separate)
15134 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15135 printable_section_name (filedata, section),
15136 filedata->file_name);
15137 else
15138 printf (_("\nDump of CTF section '%s':\n"),
15139 printable_section_name (filedata, section));
7d9813f1 15140
83d59285
NA
15141 if ((err = ctf_archive_iter (ctfa, dump_ctf_archive_member, parent)) != 0)
15142 {
15143 dump_ctf_errs (NULL);
15144 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
015dc7e1 15145 ret = false;
83d59285 15146 }
7d9813f1
NA
15147
15148 fail:
139633c3 15149 ctf_dict_close (parent);
2f6ecaed
NA
15150 ctf_close (ctfa);
15151 ctf_close (parenta);
7d9813f1
NA
15152 free (parentdata);
15153 free (data);
15154 free (symdata);
15155 free (strdata);
15156 return ret;
15157}
094e34f2 15158#endif
7d9813f1 15159
015dc7e1 15160static bool
dda8d76d
NC
15161load_specific_debug_section (enum dwarf_section_display_enum debug,
15162 const Elf_Internal_Shdr * sec,
15163 void * data)
1007acb3 15164{
2cf0635d 15165 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15166 char buf [64];
dda8d76d 15167 Filedata * filedata = (Filedata *) data;
9abca702 15168
19e6b90e 15169 if (section->start != NULL)
dda8d76d
NC
15170 {
15171 /* If it is already loaded, do nothing. */
15172 if (streq (section->filename, filedata->file_name))
015dc7e1 15173 return true;
dda8d76d
NC
15174 free (section->start);
15175 }
1007acb3 15176
19e6b90e
L
15177 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15178 section->address = sec->sh_addr;
dda8d76d
NC
15179 section->filename = filedata->file_name;
15180 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15181 sec->sh_offset, 1,
15182 sec->sh_size, buf);
59245841
NC
15183 if (section->start == NULL)
15184 section->size = 0;
15185 else
15186 {
77115a4a
L
15187 unsigned char *start = section->start;
15188 dwarf_size_type size = sec->sh_size;
dab394de 15189 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15190
15191 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15192 {
15193 Elf_Internal_Chdr chdr;
d8024a91
NC
15194 unsigned int compression_header_size;
15195
f53be977
L
15196 if (size < (is_32bit_elf
15197 ? sizeof (Elf32_External_Chdr)
15198 : sizeof (Elf64_External_Chdr)))
d8024a91 15199 {
55be8fd0 15200 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15201 section->name);
015dc7e1 15202 return false;
d8024a91
NC
15203 }
15204
ebdf1ebf 15205 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15206 if (compression_header_size == 0)
15207 /* An error message will have already been generated
15208 by get_compression_header. */
015dc7e1 15209 return false;
d8024a91 15210
813dabb9
L
15211 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15212 {
15213 warn (_("section '%s' has unsupported compress type: %d\n"),
15214 section->name, chdr.ch_type);
015dc7e1 15215 return false;
813dabb9 15216 }
dab394de 15217 uncompressed_size = chdr.ch_size;
77115a4a
L
15218 start += compression_header_size;
15219 size -= compression_header_size;
15220 }
dab394de
L
15221 else if (size > 12 && streq ((char *) start, "ZLIB"))
15222 {
15223 /* Read the zlib header. In this case, it should be "ZLIB"
15224 followed by the uncompressed section size, 8 bytes in
15225 big-endian order. */
15226 uncompressed_size = start[4]; uncompressed_size <<= 8;
15227 uncompressed_size += start[5]; uncompressed_size <<= 8;
15228 uncompressed_size += start[6]; uncompressed_size <<= 8;
15229 uncompressed_size += start[7]; uncompressed_size <<= 8;
15230 uncompressed_size += start[8]; uncompressed_size <<= 8;
15231 uncompressed_size += start[9]; uncompressed_size <<= 8;
15232 uncompressed_size += start[10]; uncompressed_size <<= 8;
15233 uncompressed_size += start[11];
15234 start += 12;
15235 size -= 12;
15236 }
15237
1835f746 15238 if (uncompressed_size)
77115a4a 15239 {
1835f746
NC
15240 if (uncompress_section_contents (&start, uncompressed_size,
15241 &size))
15242 {
15243 /* Free the compressed buffer, update the section buffer
15244 and the section size if uncompress is successful. */
15245 free (section->start);
15246 section->start = start;
15247 }
15248 else
15249 {
15250 error (_("Unable to decompress section %s\n"),
dda8d76d 15251 printable_section_name (filedata, sec));
015dc7e1 15252 return false;
1835f746 15253 }
77115a4a 15254 }
bc303e5d 15255
77115a4a 15256 section->size = size;
59245841 15257 }
4a114e3e 15258
1b315056 15259 if (section->start == NULL)
015dc7e1 15260 return false;
1b315056 15261
19e6b90e 15262 if (debug_displays [debug].relocate)
32ec8896 15263 {
dda8d76d 15264 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15265 & section->reloc_info, & section->num_relocs))
015dc7e1 15266 return false;
32ec8896 15267 }
d1c4b12b
NC
15268 else
15269 {
15270 section->reloc_info = NULL;
15271 section->num_relocs = 0;
15272 }
1007acb3 15273
015dc7e1 15274 return true;
1007acb3
L
15275}
15276
301a9420
AM
15277#if HAVE_LIBDEBUGINFOD
15278/* Return a hex string representation of the build-id. */
15279unsigned char *
15280get_build_id (void * data)
15281{
ca0e11aa 15282 Filedata * filedata = (Filedata *) data;
301a9420
AM
15283 Elf_Internal_Shdr * shdr;
15284 unsigned long i;
15285
55be8fd0
NC
15286 /* Iterate through notes to find note.gnu.build-id.
15287 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15288 for (i = 0, shdr = filedata->section_headers;
15289 i < filedata->file_header.e_shnum && shdr != NULL;
15290 i++, shdr++)
15291 {
15292 if (shdr->sh_type != SHT_NOTE)
15293 continue;
15294
15295 char * next;
15296 char * end;
15297 size_t data_remaining;
15298 size_t min_notesz;
15299 Elf_External_Note * enote;
15300 Elf_Internal_Note inote;
15301
15302 bfd_vma offset = shdr->sh_offset;
15303 bfd_vma align = shdr->sh_addralign;
15304 bfd_vma length = shdr->sh_size;
15305
15306 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15307 if (enote == NULL)
15308 continue;
15309
15310 if (align < 4)
15311 align = 4;
15312 else if (align != 4 && align != 8)
f761cb13
AM
15313 {
15314 free (enote);
15315 continue;
15316 }
301a9420
AM
15317
15318 end = (char *) enote + length;
15319 data_remaining = end - (char *) enote;
15320
15321 if (!is_ia64_vms (filedata))
15322 {
15323 min_notesz = offsetof (Elf_External_Note, name);
15324 if (data_remaining < min_notesz)
15325 {
55be8fd0
NC
15326 warn (_("\
15327malformed note encountered in section %s whilst scanning for build-id note\n"),
15328 printable_section_name (filedata, shdr));
f761cb13 15329 free (enote);
55be8fd0 15330 continue;
301a9420
AM
15331 }
15332 data_remaining -= min_notesz;
15333
15334 inote.type = BYTE_GET (enote->type);
15335 inote.namesz = BYTE_GET (enote->namesz);
15336 inote.namedata = enote->name;
15337 inote.descsz = BYTE_GET (enote->descsz);
15338 inote.descdata = ((char *) enote
15339 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15340 inote.descpos = offset + (inote.descdata - (char *) enote);
15341 next = ((char *) enote
15342 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15343 }
15344 else
15345 {
15346 Elf64_External_VMS_Note *vms_enote;
15347
15348 /* PR binutils/15191
15349 Make sure that there is enough data to read. */
15350 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15351 if (data_remaining < min_notesz)
15352 {
55be8fd0
NC
15353 warn (_("\
15354malformed note encountered in section %s whilst scanning for build-id note\n"),
15355 printable_section_name (filedata, shdr));
f761cb13 15356 free (enote);
55be8fd0 15357 continue;
301a9420
AM
15358 }
15359 data_remaining -= min_notesz;
15360
15361 vms_enote = (Elf64_External_VMS_Note *) enote;
15362 inote.type = BYTE_GET (vms_enote->type);
15363 inote.namesz = BYTE_GET (vms_enote->namesz);
15364 inote.namedata = vms_enote->name;
15365 inote.descsz = BYTE_GET (vms_enote->descsz);
15366 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15367 inote.descpos = offset + (inote.descdata - (char *) enote);
15368 next = inote.descdata + align_power (inote.descsz, 3);
15369 }
15370
15371 /* Skip malformed notes. */
15372 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
15373 || (size_t) (inote.descdata - inote.namedata) > data_remaining
15374 || (size_t) (next - inote.descdata) < inote.descsz
15375 || ((size_t) (next - inote.descdata)
15376 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
15377 {
55be8fd0
NC
15378 warn (_("\
15379malformed note encountered in section %s whilst scanning for build-id note\n"),
15380 printable_section_name (filedata, shdr));
f761cb13 15381 free (enote);
301a9420
AM
15382 continue;
15383 }
15384
15385 /* Check if this is the build-id note. If so then convert the build-id
15386 bytes to a hex string. */
15387 if (inote.namesz > 0
24d127aa 15388 && startswith (inote.namedata, "GNU")
301a9420
AM
15389 && inote.type == NT_GNU_BUILD_ID)
15390 {
15391 unsigned long j;
15392 char * build_id;
15393
15394 build_id = malloc (inote.descsz * 2 + 1);
15395 if (build_id == NULL)
f761cb13
AM
15396 {
15397 free (enote);
15398 return NULL;
15399 }
301a9420
AM
15400
15401 for (j = 0; j < inote.descsz; ++j)
15402 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
15403 build_id[inote.descsz * 2] = '\0';
f761cb13 15404 free (enote);
301a9420 15405
55be8fd0 15406 return (unsigned char *) build_id;
301a9420 15407 }
f761cb13 15408 free (enote);
301a9420
AM
15409 }
15410
15411 return NULL;
15412}
15413#endif /* HAVE_LIBDEBUGINFOD */
15414
657d0d47
CC
15415/* If this is not NULL, load_debug_section will only look for sections
15416 within the list of sections given here. */
32ec8896 15417static unsigned int * section_subset = NULL;
657d0d47 15418
015dc7e1 15419bool
dda8d76d 15420load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 15421{
2cf0635d
NC
15422 struct dwarf_section * section = &debug_displays [debug].section;
15423 Elf_Internal_Shdr * sec;
dda8d76d
NC
15424 Filedata * filedata = (Filedata *) data;
15425
f425ec66
NC
15426 /* Without section headers we cannot find any sections. */
15427 if (filedata->section_headers == NULL)
015dc7e1 15428 return false;
f425ec66 15429
9c1ce108
AM
15430 if (filedata->string_table == NULL
15431 && filedata->file_header.e_shstrndx != SHN_UNDEF
15432 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
15433 {
15434 Elf_Internal_Shdr * strs;
15435
15436 /* Read in the string table, so that we have section names to scan. */
15437 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
15438
4dff97b2 15439 if (strs != NULL && strs->sh_size != 0)
dda8d76d 15440 {
9c1ce108
AM
15441 filedata->string_table
15442 = (char *) get_data (NULL, filedata, strs->sh_offset,
15443 1, strs->sh_size, _("string table"));
dda8d76d 15444
9c1ce108
AM
15445 filedata->string_table_length
15446 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
15447 }
15448 }
d966045b
DJ
15449
15450 /* Locate the debug section. */
dda8d76d 15451 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
15452 if (sec != NULL)
15453 section->name = section->uncompressed_name;
15454 else
15455 {
dda8d76d 15456 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
15457 if (sec != NULL)
15458 section->name = section->compressed_name;
15459 }
15460 if (sec == NULL)
015dc7e1 15461 return false;
d966045b 15462
657d0d47
CC
15463 /* If we're loading from a subset of sections, and we've loaded
15464 a section matching this name before, it's likely that it's a
15465 different one. */
15466 if (section_subset != NULL)
15467 free_debug_section (debug);
15468
dda8d76d 15469 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
15470}
15471
19e6b90e
L
15472void
15473free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 15474{
2cf0635d 15475 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 15476
19e6b90e
L
15477 if (section->start == NULL)
15478 return;
1007acb3 15479
19e6b90e
L
15480 free ((char *) section->start);
15481 section->start = NULL;
15482 section->address = 0;
15483 section->size = 0;
a788aedd 15484
9db70fc3
AM
15485 free (section->reloc_info);
15486 section->reloc_info = NULL;
15487 section->num_relocs = 0;
1007acb3
L
15488}
15489
015dc7e1 15490static bool
dda8d76d 15491display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 15492{
b9e920ec 15493 char * name = SECTION_NAME_VALID (section) ? SECTION_NAME (section) : "";
dda8d76d 15494 const char * print_name = printable_section_name (filedata, section);
19e6b90e 15495 bfd_size_type length;
015dc7e1 15496 bool result = true;
3f5e193b 15497 int i;
1007acb3 15498
19e6b90e
L
15499 length = section->sh_size;
15500 if (length == 0)
1007acb3 15501 {
74e1a04b 15502 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 15503 return true;
1007acb3 15504 }
5dff79d8
NC
15505 if (section->sh_type == SHT_NOBITS)
15506 {
15507 /* There is no point in dumping the contents of a debugging section
15508 which has the NOBITS type - the bits in the file will be random.
15509 This can happen when a file containing a .eh_frame section is
15510 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
15511 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
15512 print_name);
015dc7e1 15513 return false;
5dff79d8 15514 }
1007acb3 15515
24d127aa 15516 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 15517 name = ".debug_info";
1007acb3 15518
19e6b90e
L
15519 /* See if we know how to display the contents of this section. */
15520 for (i = 0; i < max; i++)
d85bf2ba
NC
15521 {
15522 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
15523 struct dwarf_section_display * display = debug_displays + i;
15524 struct dwarf_section * sec = & display->section;
d966045b 15525
d85bf2ba 15526 if (streq (sec->uncompressed_name, name)
24d127aa 15527 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15528 || streq (sec->compressed_name, name))
15529 {
015dc7e1 15530 bool secondary = (section != find_section (filedata, name));
1007acb3 15531
d85bf2ba
NC
15532 if (secondary)
15533 free_debug_section (id);
dda8d76d 15534
24d127aa 15535 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15536 sec->name = name;
15537 else if (streq (sec->uncompressed_name, name))
15538 sec->name = sec->uncompressed_name;
15539 else
15540 sec->name = sec->compressed_name;
657d0d47 15541
d85bf2ba
NC
15542 if (load_specific_debug_section (id, section, filedata))
15543 {
15544 /* If this debug section is part of a CU/TU set in a .dwp file,
15545 restrict load_debug_section to the sections in that set. */
15546 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 15547
d85bf2ba 15548 result &= display->display (sec, filedata);
657d0d47 15549
d85bf2ba 15550 section_subset = NULL;
1007acb3 15551
44266f36 15552 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
15553 free_debug_section (id);
15554 }
15555 break;
15556 }
15557 }
1007acb3 15558
19e6b90e 15559 if (i == max)
1007acb3 15560 {
74e1a04b 15561 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 15562 result = false;
1007acb3
L
15563 }
15564
19e6b90e 15565 return result;
5b18a4bc 15566}
103f02d3 15567
aef1f6d0
DJ
15568/* Set DUMP_SECTS for all sections where dumps were requested
15569 based on section name. */
15570
15571static void
dda8d76d 15572initialise_dumps_byname (Filedata * filedata)
aef1f6d0 15573{
2cf0635d 15574 struct dump_list_entry * cur;
aef1f6d0
DJ
15575
15576 for (cur = dump_sects_byname; cur; cur = cur->next)
15577 {
15578 unsigned int i;
015dc7e1 15579 bool any = false;
aef1f6d0 15580
dda8d76d 15581 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
15582 if (SECTION_NAME_VALID (filedata->section_headers + i)
15583 && streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 15584 {
6431e409 15585 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 15586 any = true;
aef1f6d0
DJ
15587 }
15588
835f2fae
NC
15589 if (!any && !filedata->is_separate)
15590 warn (_("Section '%s' was not dumped because it does not exist\n"),
15591 cur->name);
aef1f6d0
DJ
15592 }
15593}
15594
015dc7e1 15595static bool
dda8d76d 15596process_section_contents (Filedata * filedata)
5b18a4bc 15597{
2cf0635d 15598 Elf_Internal_Shdr * section;
19e6b90e 15599 unsigned int i;
015dc7e1 15600 bool res = true;
103f02d3 15601
19e6b90e 15602 if (! do_dump)
015dc7e1 15603 return true;
103f02d3 15604
dda8d76d 15605 initialise_dumps_byname (filedata);
aef1f6d0 15606
dda8d76d 15607 for (i = 0, section = filedata->section_headers;
6431e409 15608 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
15609 i++, section++)
15610 {
6431e409 15611 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 15612
d6bfbc39
NC
15613 if (filedata->is_separate && ! process_links)
15614 dump &= DEBUG_DUMP;
047c3dbf 15615
19e6b90e 15616#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
15617 if (dump & DISASS_DUMP)
15618 {
15619 if (! disassemble_section (section, filedata))
015dc7e1 15620 res = false;
dda8d76d 15621 }
19e6b90e 15622#endif
dda8d76d 15623 if (dump & HEX_DUMP)
32ec8896 15624 {
015dc7e1
AM
15625 if (! dump_section_as_bytes (section, filedata, false))
15626 res = false;
32ec8896 15627 }
103f02d3 15628
dda8d76d 15629 if (dump & RELOC_DUMP)
32ec8896 15630 {
015dc7e1
AM
15631 if (! dump_section_as_bytes (section, filedata, true))
15632 res = false;
32ec8896 15633 }
09c11c86 15634
dda8d76d 15635 if (dump & STRING_DUMP)
32ec8896 15636 {
dda8d76d 15637 if (! dump_section_as_strings (section, filedata))
015dc7e1 15638 res = false;
32ec8896 15639 }
cf13d699 15640
dda8d76d 15641 if (dump & DEBUG_DUMP)
32ec8896 15642 {
dda8d76d 15643 if (! display_debug_section (i, section, filedata))
015dc7e1 15644 res = false;
32ec8896 15645 }
7d9813f1 15646
094e34f2 15647#ifdef ENABLE_LIBCTF
7d9813f1
NA
15648 if (dump & CTF_DUMP)
15649 {
15650 if (! dump_section_as_ctf (section, filedata))
015dc7e1 15651 res = false;
7d9813f1 15652 }
094e34f2 15653#endif
5b18a4bc 15654 }
103f02d3 15655
835f2fae 15656 if (! filedata->is_separate)
0ee3043f 15657 {
835f2fae
NC
15658 /* Check to see if the user requested a
15659 dump of a section that does not exist. */
15660 for (; i < filedata->dump.num_dump_sects; i++)
15661 if (filedata->dump.dump_sects[i])
15662 {
ca0e11aa 15663 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 15664 res = false;
835f2fae 15665 }
0ee3043f 15666 }
32ec8896
NC
15667
15668 return res;
5b18a4bc 15669}
103f02d3 15670
5b18a4bc 15671static void
19e6b90e 15672process_mips_fpe_exception (int mask)
5b18a4bc 15673{
19e6b90e
L
15674 if (mask)
15675 {
015dc7e1 15676 bool first = true;
32ec8896 15677
19e6b90e 15678 if (mask & OEX_FPU_INEX)
015dc7e1 15679 fputs ("INEX", stdout), first = false;
19e6b90e 15680 if (mask & OEX_FPU_UFLO)
015dc7e1 15681 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 15682 if (mask & OEX_FPU_OFLO)
015dc7e1 15683 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 15684 if (mask & OEX_FPU_DIV0)
015dc7e1 15685 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
15686 if (mask & OEX_FPU_INVAL)
15687 printf ("%sINVAL", first ? "" : "|");
15688 }
5b18a4bc 15689 else
19e6b90e 15690 fputs ("0", stdout);
5b18a4bc 15691}
103f02d3 15692
f6f0e17b
NC
15693/* Display's the value of TAG at location P. If TAG is
15694 greater than 0 it is assumed to be an unknown tag, and
15695 a message is printed to this effect. Otherwise it is
15696 assumed that a message has already been printed.
15697
15698 If the bottom bit of TAG is set it assumed to have a
15699 string value, otherwise it is assumed to have an integer
15700 value.
15701
15702 Returns an updated P pointing to the first unread byte
15703 beyond the end of TAG's value.
15704
15705 Reads at or beyond END will not be made. */
15706
15707static unsigned char *
60abdbed 15708display_tag_value (signed int tag,
f6f0e17b
NC
15709 unsigned char * p,
15710 const unsigned char * const end)
15711{
15712 unsigned long val;
15713
15714 if (tag > 0)
15715 printf (" Tag_unknown_%d: ", tag);
15716
15717 if (p >= end)
15718 {
4082ef84 15719 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
15720 }
15721 else if (tag & 1)
15722 {
071436c6
NC
15723 /* PR 17531 file: 027-19978-0.004. */
15724 size_t maxlen = (end - p) - 1;
15725
15726 putchar ('"');
4082ef84
NC
15727 if (maxlen > 0)
15728 {
15729 print_symbol ((int) maxlen, (const char *) p);
15730 p += strnlen ((char *) p, maxlen) + 1;
15731 }
15732 else
15733 {
15734 printf (_("<corrupt string tag>"));
15735 p = (unsigned char *) end;
15736 }
071436c6 15737 printf ("\"\n");
f6f0e17b
NC
15738 }
15739 else
15740 {
cd30bcef 15741 READ_ULEB (val, p, end);
f6f0e17b
NC
15742 printf ("%ld (0x%lx)\n", val, val);
15743 }
15744
4082ef84 15745 assert (p <= end);
f6f0e17b
NC
15746 return p;
15747}
15748
53a346d8
CZ
15749/* ARC ABI attributes section. */
15750
15751static unsigned char *
15752display_arc_attribute (unsigned char * p,
15753 const unsigned char * const end)
15754{
15755 unsigned int tag;
53a346d8
CZ
15756 unsigned int val;
15757
cd30bcef 15758 READ_ULEB (tag, p, end);
53a346d8
CZ
15759
15760 switch (tag)
15761 {
15762 case Tag_ARC_PCS_config:
cd30bcef 15763 READ_ULEB (val, p, end);
53a346d8
CZ
15764 printf (" Tag_ARC_PCS_config: ");
15765 switch (val)
15766 {
15767 case 0:
15768 printf (_("Absent/Non standard\n"));
15769 break;
15770 case 1:
15771 printf (_("Bare metal/mwdt\n"));
15772 break;
15773 case 2:
15774 printf (_("Bare metal/newlib\n"));
15775 break;
15776 case 3:
15777 printf (_("Linux/uclibc\n"));
15778 break;
15779 case 4:
15780 printf (_("Linux/glibc\n"));
15781 break;
15782 default:
15783 printf (_("Unknown\n"));
15784 break;
15785 }
15786 break;
15787
15788 case Tag_ARC_CPU_base:
cd30bcef 15789 READ_ULEB (val, p, end);
53a346d8
CZ
15790 printf (" Tag_ARC_CPU_base: ");
15791 switch (val)
15792 {
15793 default:
15794 case TAG_CPU_NONE:
15795 printf (_("Absent\n"));
15796 break;
15797 case TAG_CPU_ARC6xx:
15798 printf ("ARC6xx\n");
15799 break;
15800 case TAG_CPU_ARC7xx:
15801 printf ("ARC7xx\n");
15802 break;
15803 case TAG_CPU_ARCEM:
15804 printf ("ARCEM\n");
15805 break;
15806 case TAG_CPU_ARCHS:
15807 printf ("ARCHS\n");
15808 break;
15809 }
15810 break;
15811
15812 case Tag_ARC_CPU_variation:
cd30bcef 15813 READ_ULEB (val, p, end);
53a346d8
CZ
15814 printf (" Tag_ARC_CPU_variation: ");
15815 switch (val)
15816 {
15817 default:
15818 if (val > 0 && val < 16)
53a346d8 15819 printf ("Core%d\n", val);
d8cbc93b
JL
15820 else
15821 printf ("Unknown\n");
15822 break;
15823
53a346d8
CZ
15824 case 0:
15825 printf (_("Absent\n"));
15826 break;
15827 }
15828 break;
15829
15830 case Tag_ARC_CPU_name:
15831 printf (" Tag_ARC_CPU_name: ");
15832 p = display_tag_value (-1, p, end);
15833 break;
15834
15835 case Tag_ARC_ABI_rf16:
cd30bcef 15836 READ_ULEB (val, p, end);
53a346d8
CZ
15837 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
15838 break;
15839
15840 case Tag_ARC_ABI_osver:
cd30bcef 15841 READ_ULEB (val, p, end);
53a346d8
CZ
15842 printf (" Tag_ARC_ABI_osver: v%d\n", val);
15843 break;
15844
15845 case Tag_ARC_ABI_pic:
15846 case Tag_ARC_ABI_sda:
cd30bcef 15847 READ_ULEB (val, p, end);
53a346d8
CZ
15848 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
15849 : " Tag_ARC_ABI_pic: ");
15850 switch (val)
15851 {
15852 case 0:
15853 printf (_("Absent\n"));
15854 break;
15855 case 1:
15856 printf ("MWDT\n");
15857 break;
15858 case 2:
15859 printf ("GNU\n");
15860 break;
15861 default:
15862 printf (_("Unknown\n"));
15863 break;
15864 }
15865 break;
15866
15867 case Tag_ARC_ABI_tls:
cd30bcef 15868 READ_ULEB (val, p, end);
53a346d8
CZ
15869 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
15870 break;
15871
15872 case Tag_ARC_ABI_enumsize:
cd30bcef 15873 READ_ULEB (val, p, end);
53a346d8
CZ
15874 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
15875 _("smallest"));
15876 break;
15877
15878 case Tag_ARC_ABI_exceptions:
cd30bcef 15879 READ_ULEB (val, p, end);
53a346d8
CZ
15880 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
15881 : _("default"));
15882 break;
15883
15884 case Tag_ARC_ABI_double_size:
cd30bcef 15885 READ_ULEB (val, p, end);
53a346d8
CZ
15886 printf (" Tag_ARC_ABI_double_size: %d\n", val);
15887 break;
15888
15889 case Tag_ARC_ISA_config:
15890 printf (" Tag_ARC_ISA_config: ");
15891 p = display_tag_value (-1, p, end);
15892 break;
15893
15894 case Tag_ARC_ISA_apex:
15895 printf (" Tag_ARC_ISA_apex: ");
15896 p = display_tag_value (-1, p, end);
15897 break;
15898
15899 case Tag_ARC_ISA_mpy_option:
cd30bcef 15900 READ_ULEB (val, p, end);
53a346d8
CZ
15901 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
15902 break;
15903
db1e1b45 15904 case Tag_ARC_ATR_version:
cd30bcef 15905 READ_ULEB (val, p, end);
db1e1b45 15906 printf (" Tag_ARC_ATR_version: %d\n", val);
15907 break;
15908
53a346d8
CZ
15909 default:
15910 return display_tag_value (tag & 1, p, end);
15911 }
15912
15913 return p;
15914}
15915
11c1ff18
PB
15916/* ARM EABI attributes section. */
15917typedef struct
15918{
70e99720 15919 unsigned int tag;
2cf0635d 15920 const char * name;
11c1ff18 15921 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 15922 unsigned int type;
288f0ba2 15923 const char *const *table;
11c1ff18
PB
15924} arm_attr_public_tag;
15925
288f0ba2 15926static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 15927 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 15928 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 15929 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
288f0ba2
AM
15930static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
15931static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 15932 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 15933static const char *const arm_attr_tag_FP_arch[] =
bca38921 15934 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 15935 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
15936static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
15937static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
15938 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
15939 "NEON for ARMv8.1"};
288f0ba2 15940static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
15941 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
15942 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 15943static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 15944 {"V6", "SB", "TLS", "Unused"};
288f0ba2 15945static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 15946 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 15947static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 15948 {"Absolute", "PC-relative", "None"};
288f0ba2 15949static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 15950 {"None", "direct", "GOT-indirect"};
288f0ba2 15951static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 15952 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
15953static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
15954static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 15955 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
15956static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
15957static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
15958static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 15959 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 15960static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 15961 {"Unused", "small", "int", "forced to int"};
288f0ba2 15962static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 15963 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 15964static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 15965 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 15966static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 15967 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 15968static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
15969 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15970 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 15971static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
15972 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15973 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
15974static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
15975static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 15976 {"Not Allowed", "Allowed"};
288f0ba2 15977static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 15978 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 15979static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 15980 {"Follow architecture", "Allowed"};
288f0ba2 15981static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 15982 {"Not Allowed", "Allowed"};
288f0ba2 15983static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 15984 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 15985 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
15986static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
15987static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 15988 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 15989 "TrustZone and Virtualization Extensions"};
288f0ba2 15990static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 15991 {"Not Allowed", "Allowed"};
11c1ff18 15992
288f0ba2 15993static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
15994 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
15995
11c1ff18
PB
15996#define LOOKUP(id, name) \
15997 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 15998static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
15999{
16000 {4, "CPU_raw_name", 1, NULL},
16001 {5, "CPU_name", 1, NULL},
16002 LOOKUP(6, CPU_arch),
16003 {7, "CPU_arch_profile", 0, NULL},
16004 LOOKUP(8, ARM_ISA_use),
16005 LOOKUP(9, THUMB_ISA_use),
75375b3e 16006 LOOKUP(10, FP_arch),
11c1ff18 16007 LOOKUP(11, WMMX_arch),
f5f53991
AS
16008 LOOKUP(12, Advanced_SIMD_arch),
16009 LOOKUP(13, PCS_config),
11c1ff18
PB
16010 LOOKUP(14, ABI_PCS_R9_use),
16011 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16012 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16013 LOOKUP(17, ABI_PCS_GOT_use),
16014 LOOKUP(18, ABI_PCS_wchar_t),
16015 LOOKUP(19, ABI_FP_rounding),
16016 LOOKUP(20, ABI_FP_denormal),
16017 LOOKUP(21, ABI_FP_exceptions),
16018 LOOKUP(22, ABI_FP_user_exceptions),
16019 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16020 {24, "ABI_align_needed", 0, NULL},
16021 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16022 LOOKUP(26, ABI_enum_size),
16023 LOOKUP(27, ABI_HardFP_use),
16024 LOOKUP(28, ABI_VFP_args),
16025 LOOKUP(29, ABI_WMMX_args),
16026 LOOKUP(30, ABI_optimization_goals),
16027 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16028 {32, "compatibility", 0, NULL},
f5f53991 16029 LOOKUP(34, CPU_unaligned_access),
75375b3e 16030 LOOKUP(36, FP_HP_extension),
8e79c3df 16031 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16032 LOOKUP(42, MPextension_use),
16033 LOOKUP(44, DIV_use),
15afaa63 16034 LOOKUP(46, DSP_extension),
a7ad558c 16035 LOOKUP(48, MVE_arch),
f5f53991
AS
16036 {64, "nodefaults", 0, NULL},
16037 {65, "also_compatible_with", 0, NULL},
16038 LOOKUP(66, T2EE_use),
16039 {67, "conformance", 1, NULL},
16040 LOOKUP(68, Virtualization_use),
cd21e546 16041 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16042};
16043#undef LOOKUP
16044
11c1ff18 16045static unsigned char *
f6f0e17b
NC
16046display_arm_attribute (unsigned char * p,
16047 const unsigned char * const end)
11c1ff18 16048{
70e99720 16049 unsigned int tag;
70e99720 16050 unsigned int val;
2cf0635d 16051 arm_attr_public_tag * attr;
11c1ff18 16052 unsigned i;
70e99720 16053 unsigned int type;
11c1ff18 16054
cd30bcef 16055 READ_ULEB (tag, p, end);
11c1ff18 16056 attr = NULL;
2cf0635d 16057 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16058 {
16059 if (arm_attr_public_tags[i].tag == tag)
16060 {
16061 attr = &arm_attr_public_tags[i];
16062 break;
16063 }
16064 }
16065
16066 if (attr)
16067 {
16068 printf (" Tag_%s: ", attr->name);
16069 switch (attr->type)
16070 {
16071 case 0:
16072 switch (tag)
16073 {
16074 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16075 READ_ULEB (val, p, end);
11c1ff18
PB
16076 switch (val)
16077 {
2b692964
NC
16078 case 0: printf (_("None\n")); break;
16079 case 'A': printf (_("Application\n")); break;
16080 case 'R': printf (_("Realtime\n")); break;
16081 case 'M': printf (_("Microcontroller\n")); break;
16082 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16083 default: printf ("??? (%d)\n", val); break;
16084 }
16085 break;
16086
75375b3e 16087 case 24: /* Tag_align_needed. */
cd30bcef 16088 READ_ULEB (val, p, end);
75375b3e
MGD
16089 switch (val)
16090 {
2b692964
NC
16091 case 0: printf (_("None\n")); break;
16092 case 1: printf (_("8-byte\n")); break;
16093 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16094 case 3: printf ("??? 3\n"); break;
16095 default:
16096 if (val <= 12)
dd24e3da 16097 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16098 1 << val);
16099 else
16100 printf ("??? (%d)\n", val);
16101 break;
16102 }
16103 break;
16104
16105 case 25: /* Tag_align_preserved. */
cd30bcef 16106 READ_ULEB (val, p, end);
75375b3e
MGD
16107 switch (val)
16108 {
2b692964
NC
16109 case 0: printf (_("None\n")); break;
16110 case 1: printf (_("8-byte, except leaf SP\n")); break;
16111 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16112 case 3: printf ("??? 3\n"); break;
16113 default:
16114 if (val <= 12)
dd24e3da 16115 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16116 1 << val);
16117 else
16118 printf ("??? (%d)\n", val);
16119 break;
16120 }
16121 break;
16122
11c1ff18 16123 case 32: /* Tag_compatibility. */
071436c6 16124 {
cd30bcef 16125 READ_ULEB (val, p, end);
071436c6 16126 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16127 if (p < end - 1)
16128 {
16129 size_t maxlen = (end - p) - 1;
16130
16131 print_symbol ((int) maxlen, (const char *) p);
16132 p += strnlen ((char *) p, maxlen) + 1;
16133 }
16134 else
16135 {
16136 printf (_("<corrupt>"));
16137 p = (unsigned char *) end;
16138 }
071436c6 16139 putchar ('\n');
071436c6 16140 }
11c1ff18
PB
16141 break;
16142
f5f53991 16143 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16144 /* PR 17531: file: 001-505008-0.01. */
16145 if (p < end)
16146 p++;
2b692964 16147 printf (_("True\n"));
f5f53991
AS
16148 break;
16149
16150 case 65: /* Tag_also_compatible_with. */
cd30bcef 16151 READ_ULEB (val, p, end);
f5f53991
AS
16152 if (val == 6 /* Tag_CPU_arch. */)
16153 {
cd30bcef 16154 READ_ULEB (val, p, end);
071436c6 16155 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16156 printf ("??? (%d)\n", val);
16157 else
16158 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16159 }
16160 else
16161 printf ("???\n");
071436c6
NC
16162 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16163 ;
f5f53991
AS
16164 break;
16165
11c1ff18 16166 default:
bee0ee85
NC
16167 printf (_("<unknown: %d>\n"), tag);
16168 break;
11c1ff18
PB
16169 }
16170 return p;
16171
16172 case 1:
f6f0e17b 16173 return display_tag_value (-1, p, end);
11c1ff18 16174 case 2:
f6f0e17b 16175 return display_tag_value (0, p, end);
11c1ff18
PB
16176
16177 default:
16178 assert (attr->type & 0x80);
cd30bcef 16179 READ_ULEB (val, p, end);
11c1ff18
PB
16180 type = attr->type & 0x7f;
16181 if (val >= type)
16182 printf ("??? (%d)\n", val);
16183 else
16184 printf ("%s\n", attr->table[val]);
16185 return p;
16186 }
16187 }
11c1ff18 16188
f6f0e17b 16189 return display_tag_value (tag, p, end);
11c1ff18
PB
16190}
16191
104d59d1 16192static unsigned char *
60bca95a 16193display_gnu_attribute (unsigned char * p,
60abdbed 16194 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16195 const unsigned char * const end)
104d59d1 16196{
cd30bcef 16197 unsigned int tag;
60abdbed 16198 unsigned int val;
104d59d1 16199
cd30bcef 16200 READ_ULEB (tag, p, end);
104d59d1
JM
16201
16202 /* Tag_compatibility is the only generic GNU attribute defined at
16203 present. */
16204 if (tag == 32)
16205 {
cd30bcef 16206 READ_ULEB (val, p, end);
071436c6
NC
16207
16208 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16209 if (p == end)
16210 {
071436c6 16211 printf (_("<corrupt>\n"));
f6f0e17b
NC
16212 warn (_("corrupt vendor attribute\n"));
16213 }
16214 else
16215 {
4082ef84
NC
16216 if (p < end - 1)
16217 {
16218 size_t maxlen = (end - p) - 1;
071436c6 16219
4082ef84
NC
16220 print_symbol ((int) maxlen, (const char *) p);
16221 p += strnlen ((char *) p, maxlen) + 1;
16222 }
16223 else
16224 {
16225 printf (_("<corrupt>"));
16226 p = (unsigned char *) end;
16227 }
071436c6 16228 putchar ('\n');
f6f0e17b 16229 }
104d59d1
JM
16230 return p;
16231 }
16232
16233 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16234 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16235
f6f0e17b 16236 return display_tag_value (tag, p, end);
104d59d1
JM
16237}
16238
85f7484a
PB
16239static unsigned char *
16240display_m68k_gnu_attribute (unsigned char * p,
16241 unsigned int tag,
16242 const unsigned char * const end)
16243{
16244 unsigned int val;
16245
16246 if (tag == Tag_GNU_M68K_ABI_FP)
16247 {
16248 printf (" Tag_GNU_M68K_ABI_FP: ");
16249 if (p == end)
16250 {
16251 printf (_("<corrupt>\n"));
16252 return p;
16253 }
16254 READ_ULEB (val, p, end);
16255
16256 if (val > 3)
16257 printf ("(%#x), ", val);
16258
16259 switch (val & 3)
16260 {
16261 case 0:
16262 printf (_("unspecified hard/soft float\n"));
16263 break;
16264 case 1:
16265 printf (_("hard float\n"));
16266 break;
16267 case 2:
16268 printf (_("soft float\n"));
16269 break;
16270 }
16271 return p;
16272 }
16273
16274 return display_tag_value (tag & 1, p, end);
16275}
16276
34c8bcba 16277static unsigned char *
f6f0e17b 16278display_power_gnu_attribute (unsigned char * p,
60abdbed 16279 unsigned int tag,
f6f0e17b 16280 const unsigned char * const end)
34c8bcba 16281{
005d79fd 16282 unsigned int val;
34c8bcba
JM
16283
16284 if (tag == Tag_GNU_Power_ABI_FP)
16285 {
34c8bcba 16286 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16287 if (p == end)
005d79fd
AM
16288 {
16289 printf (_("<corrupt>\n"));
16290 return p;
16291 }
cd30bcef 16292 READ_ULEB (val, p, end);
60bca95a 16293
005d79fd
AM
16294 if (val > 15)
16295 printf ("(%#x), ", val);
16296
16297 switch (val & 3)
34c8bcba
JM
16298 {
16299 case 0:
005d79fd 16300 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16301 break;
16302 case 1:
005d79fd 16303 printf (_("hard float, "));
34c8bcba
JM
16304 break;
16305 case 2:
005d79fd 16306 printf (_("soft float, "));
34c8bcba 16307 break;
3c7b9897 16308 case 3:
005d79fd 16309 printf (_("single-precision hard float, "));
3c7b9897 16310 break;
005d79fd
AM
16311 }
16312
16313 switch (val & 0xC)
16314 {
16315 case 0:
16316 printf (_("unspecified long double\n"));
16317 break;
16318 case 4:
16319 printf (_("128-bit IBM long double\n"));
16320 break;
16321 case 8:
16322 printf (_("64-bit long double\n"));
16323 break;
16324 case 12:
16325 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16326 break;
16327 }
16328 return p;
005d79fd 16329 }
34c8bcba 16330
c6e65352
DJ
16331 if (tag == Tag_GNU_Power_ABI_Vector)
16332 {
c6e65352 16333 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 16334 if (p == end)
005d79fd
AM
16335 {
16336 printf (_("<corrupt>\n"));
16337 return p;
16338 }
cd30bcef 16339 READ_ULEB (val, p, end);
005d79fd
AM
16340
16341 if (val > 3)
16342 printf ("(%#x), ", val);
16343
16344 switch (val & 3)
c6e65352
DJ
16345 {
16346 case 0:
005d79fd 16347 printf (_("unspecified\n"));
c6e65352
DJ
16348 break;
16349 case 1:
005d79fd 16350 printf (_("generic\n"));
c6e65352
DJ
16351 break;
16352 case 2:
16353 printf ("AltiVec\n");
16354 break;
16355 case 3:
16356 printf ("SPE\n");
16357 break;
c6e65352
DJ
16358 }
16359 return p;
005d79fd 16360 }
c6e65352 16361
f82e0623
NF
16362 if (tag == Tag_GNU_Power_ABI_Struct_Return)
16363 {
005d79fd 16364 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 16365 if (p == end)
f6f0e17b 16366 {
005d79fd 16367 printf (_("<corrupt>\n"));
f6f0e17b
NC
16368 return p;
16369 }
cd30bcef 16370 READ_ULEB (val, p, end);
0b4362b0 16371
005d79fd
AM
16372 if (val > 2)
16373 printf ("(%#x), ", val);
16374
16375 switch (val & 3)
16376 {
16377 case 0:
16378 printf (_("unspecified\n"));
16379 break;
16380 case 1:
16381 printf ("r3/r4\n");
16382 break;
16383 case 2:
16384 printf (_("memory\n"));
16385 break;
16386 case 3:
16387 printf ("???\n");
16388 break;
16389 }
f82e0623
NF
16390 return p;
16391 }
16392
f6f0e17b 16393 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
16394}
16395
643f7afb
AK
16396static unsigned char *
16397display_s390_gnu_attribute (unsigned char * p,
60abdbed 16398 unsigned int tag,
643f7afb
AK
16399 const unsigned char * const end)
16400{
cd30bcef 16401 unsigned int val;
643f7afb
AK
16402
16403 if (tag == Tag_GNU_S390_ABI_Vector)
16404 {
643f7afb 16405 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 16406 READ_ULEB (val, p, end);
643f7afb
AK
16407
16408 switch (val)
16409 {
16410 case 0:
16411 printf (_("any\n"));
16412 break;
16413 case 1:
16414 printf (_("software\n"));
16415 break;
16416 case 2:
16417 printf (_("hardware\n"));
16418 break;
16419 default:
16420 printf ("??? (%d)\n", val);
16421 break;
16422 }
16423 return p;
16424 }
16425
16426 return display_tag_value (tag & 1, p, end);
16427}
16428
9e8c70f9 16429static void
60abdbed 16430display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
16431{
16432 if (mask)
16433 {
015dc7e1 16434 bool first = true;
071436c6 16435
9e8c70f9 16436 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 16437 fputs ("mul32", stdout), first = false;
9e8c70f9 16438 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 16439 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 16440 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 16441 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 16442 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 16443 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 16444 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 16445 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 16446 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 16447 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 16448 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 16449 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 16450 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 16451 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 16452 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 16453 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 16454 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 16455 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 16456 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 16457 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 16458 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 16459 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 16460 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 16461 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 16462 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 16463 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 16464 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 16465 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 16466 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 16467 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
16468 }
16469 else
071436c6
NC
16470 fputc ('0', stdout);
16471 fputc ('\n', stdout);
9e8c70f9
DM
16472}
16473
3d68f91c 16474static void
60abdbed 16475display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
16476{
16477 if (mask)
16478 {
015dc7e1 16479 bool first = true;
071436c6 16480
3d68f91c 16481 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 16482 fputs ("fjathplus", stdout), first = false;
3d68f91c 16483 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 16484 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 16485 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 16486 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 16487 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 16488 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 16489 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 16490 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 16491 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 16492 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 16493 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 16494 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 16495 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 16496 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 16497 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 16498 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 16499 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 16500 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 16501 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 16502 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
16503 }
16504 else
071436c6
NC
16505 fputc ('0', stdout);
16506 fputc ('\n', stdout);
3d68f91c
JM
16507}
16508
9e8c70f9 16509static unsigned char *
f6f0e17b 16510display_sparc_gnu_attribute (unsigned char * p,
60abdbed 16511 unsigned int tag,
f6f0e17b 16512 const unsigned char * const end)
9e8c70f9 16513{
cd30bcef 16514 unsigned int val;
3d68f91c 16515
9e8c70f9
DM
16516 if (tag == Tag_GNU_Sparc_HWCAPS)
16517 {
cd30bcef 16518 READ_ULEB (val, p, end);
9e8c70f9 16519 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
16520 display_sparc_hwcaps (val);
16521 return p;
3d68f91c
JM
16522 }
16523 if (tag == Tag_GNU_Sparc_HWCAPS2)
16524 {
cd30bcef 16525 READ_ULEB (val, p, end);
3d68f91c
JM
16526 printf (" Tag_GNU_Sparc_HWCAPS2: ");
16527 display_sparc_hwcaps2 (val);
16528 return p;
16529 }
9e8c70f9 16530
f6f0e17b 16531 return display_tag_value (tag, p, end);
9e8c70f9
DM
16532}
16533
351cdf24 16534static void
32ec8896 16535print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
16536{
16537 switch (val)
16538 {
16539 case Val_GNU_MIPS_ABI_FP_ANY:
16540 printf (_("Hard or soft float\n"));
16541 break;
16542 case Val_GNU_MIPS_ABI_FP_DOUBLE:
16543 printf (_("Hard float (double precision)\n"));
16544 break;
16545 case Val_GNU_MIPS_ABI_FP_SINGLE:
16546 printf (_("Hard float (single precision)\n"));
16547 break;
16548 case Val_GNU_MIPS_ABI_FP_SOFT:
16549 printf (_("Soft float\n"));
16550 break;
16551 case Val_GNU_MIPS_ABI_FP_OLD_64:
16552 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
16553 break;
16554 case Val_GNU_MIPS_ABI_FP_XX:
16555 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
16556 break;
16557 case Val_GNU_MIPS_ABI_FP_64:
16558 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
16559 break;
16560 case Val_GNU_MIPS_ABI_FP_64A:
16561 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
16562 break;
3350cc01
CM
16563 case Val_GNU_MIPS_ABI_FP_NAN2008:
16564 printf (_("NaN 2008 compatibility\n"));
16565 break;
351cdf24
MF
16566 default:
16567 printf ("??? (%d)\n", val);
16568 break;
16569 }
16570}
16571
2cf19d5c 16572static unsigned char *
f6f0e17b 16573display_mips_gnu_attribute (unsigned char * p,
60abdbed 16574 unsigned int tag,
f6f0e17b 16575 const unsigned char * const end)
2cf19d5c 16576{
2cf19d5c
JM
16577 if (tag == Tag_GNU_MIPS_ABI_FP)
16578 {
32ec8896 16579 unsigned int val;
f6f0e17b 16580
2cf19d5c 16581 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 16582 READ_ULEB (val, p, end);
351cdf24 16583 print_mips_fp_abi_value (val);
2cf19d5c
JM
16584 return p;
16585 }
16586
a9f58168
CF
16587 if (tag == Tag_GNU_MIPS_ABI_MSA)
16588 {
32ec8896 16589 unsigned int val;
a9f58168 16590
a9f58168 16591 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 16592 READ_ULEB (val, p, end);
a9f58168
CF
16593
16594 switch (val)
16595 {
16596 case Val_GNU_MIPS_ABI_MSA_ANY:
16597 printf (_("Any MSA or not\n"));
16598 break;
16599 case Val_GNU_MIPS_ABI_MSA_128:
16600 printf (_("128-bit MSA\n"));
16601 break;
16602 default:
16603 printf ("??? (%d)\n", val);
16604 break;
16605 }
16606 return p;
16607 }
16608
f6f0e17b 16609 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
16610}
16611
59e6276b 16612static unsigned char *
f6f0e17b
NC
16613display_tic6x_attribute (unsigned char * p,
16614 const unsigned char * const end)
59e6276b 16615{
60abdbed 16616 unsigned int tag;
cd30bcef 16617 unsigned int val;
59e6276b 16618
cd30bcef 16619 READ_ULEB (tag, p, end);
59e6276b
JM
16620
16621 switch (tag)
16622 {
75fa6dc1 16623 case Tag_ISA:
75fa6dc1 16624 printf (" Tag_ISA: ");
cd30bcef 16625 READ_ULEB (val, p, end);
59e6276b
JM
16626
16627 switch (val)
16628 {
75fa6dc1 16629 case C6XABI_Tag_ISA_none:
59e6276b
JM
16630 printf (_("None\n"));
16631 break;
75fa6dc1 16632 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
16633 printf ("C62x\n");
16634 break;
75fa6dc1 16635 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
16636 printf ("C67x\n");
16637 break;
75fa6dc1 16638 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
16639 printf ("C67x+\n");
16640 break;
75fa6dc1 16641 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
16642 printf ("C64x\n");
16643 break;
75fa6dc1 16644 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
16645 printf ("C64x+\n");
16646 break;
75fa6dc1 16647 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
16648 printf ("C674x\n");
16649 break;
16650 default:
16651 printf ("??? (%d)\n", val);
16652 break;
16653 }
16654 return p;
16655
87779176 16656 case Tag_ABI_wchar_t:
87779176 16657 printf (" Tag_ABI_wchar_t: ");
cd30bcef 16658 READ_ULEB (val, p, end);
87779176
JM
16659 switch (val)
16660 {
16661 case 0:
16662 printf (_("Not used\n"));
16663 break;
16664 case 1:
16665 printf (_("2 bytes\n"));
16666 break;
16667 case 2:
16668 printf (_("4 bytes\n"));
16669 break;
16670 default:
16671 printf ("??? (%d)\n", val);
16672 break;
16673 }
16674 return p;
16675
16676 case Tag_ABI_stack_align_needed:
87779176 16677 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 16678 READ_ULEB (val, p, end);
87779176
JM
16679 switch (val)
16680 {
16681 case 0:
16682 printf (_("8-byte\n"));
16683 break;
16684 case 1:
16685 printf (_("16-byte\n"));
16686 break;
16687 default:
16688 printf ("??? (%d)\n", val);
16689 break;
16690 }
16691 return p;
16692
16693 case Tag_ABI_stack_align_preserved:
cd30bcef 16694 READ_ULEB (val, p, end);
87779176
JM
16695 printf (" Tag_ABI_stack_align_preserved: ");
16696 switch (val)
16697 {
16698 case 0:
16699 printf (_("8-byte\n"));
16700 break;
16701 case 1:
16702 printf (_("16-byte\n"));
16703 break;
16704 default:
16705 printf ("??? (%d)\n", val);
16706 break;
16707 }
16708 return p;
16709
b5593623 16710 case Tag_ABI_DSBT:
cd30bcef 16711 READ_ULEB (val, p, end);
b5593623
JM
16712 printf (" Tag_ABI_DSBT: ");
16713 switch (val)
16714 {
16715 case 0:
16716 printf (_("DSBT addressing not used\n"));
16717 break;
16718 case 1:
16719 printf (_("DSBT addressing used\n"));
16720 break;
16721 default:
16722 printf ("??? (%d)\n", val);
16723 break;
16724 }
16725 return p;
16726
87779176 16727 case Tag_ABI_PID:
cd30bcef 16728 READ_ULEB (val, p, end);
87779176
JM
16729 printf (" Tag_ABI_PID: ");
16730 switch (val)
16731 {
16732 case 0:
16733 printf (_("Data addressing position-dependent\n"));
16734 break;
16735 case 1:
16736 printf (_("Data addressing position-independent, GOT near DP\n"));
16737 break;
16738 case 2:
16739 printf (_("Data addressing position-independent, GOT far from DP\n"));
16740 break;
16741 default:
16742 printf ("??? (%d)\n", val);
16743 break;
16744 }
16745 return p;
16746
16747 case Tag_ABI_PIC:
cd30bcef 16748 READ_ULEB (val, p, end);
87779176
JM
16749 printf (" Tag_ABI_PIC: ");
16750 switch (val)
16751 {
16752 case 0:
16753 printf (_("Code addressing position-dependent\n"));
16754 break;
16755 case 1:
16756 printf (_("Code addressing position-independent\n"));
16757 break;
16758 default:
16759 printf ("??? (%d)\n", val);
16760 break;
16761 }
16762 return p;
16763
16764 case Tag_ABI_array_object_alignment:
cd30bcef 16765 READ_ULEB (val, p, end);
87779176
JM
16766 printf (" Tag_ABI_array_object_alignment: ");
16767 switch (val)
16768 {
16769 case 0:
16770 printf (_("8-byte\n"));
16771 break;
16772 case 1:
16773 printf (_("4-byte\n"));
16774 break;
16775 case 2:
16776 printf (_("16-byte\n"));
16777 break;
16778 default:
16779 printf ("??? (%d)\n", val);
16780 break;
16781 }
16782 return p;
16783
16784 case Tag_ABI_array_object_align_expected:
cd30bcef 16785 READ_ULEB (val, p, end);
87779176
JM
16786 printf (" Tag_ABI_array_object_align_expected: ");
16787 switch (val)
16788 {
16789 case 0:
16790 printf (_("8-byte\n"));
16791 break;
16792 case 1:
16793 printf (_("4-byte\n"));
16794 break;
16795 case 2:
16796 printf (_("16-byte\n"));
16797 break;
16798 default:
16799 printf ("??? (%d)\n", val);
16800 break;
16801 }
16802 return p;
16803
3cbd1c06 16804 case Tag_ABI_compatibility:
071436c6 16805 {
cd30bcef 16806 READ_ULEB (val, p, end);
071436c6 16807 printf (" Tag_ABI_compatibility: ");
071436c6 16808 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16809 if (p < end - 1)
16810 {
16811 size_t maxlen = (end - p) - 1;
16812
16813 print_symbol ((int) maxlen, (const char *) p);
16814 p += strnlen ((char *) p, maxlen) + 1;
16815 }
16816 else
16817 {
16818 printf (_("<corrupt>"));
16819 p = (unsigned char *) end;
16820 }
071436c6 16821 putchar ('\n');
071436c6
NC
16822 return p;
16823 }
87779176
JM
16824
16825 case Tag_ABI_conformance:
071436c6 16826 {
4082ef84
NC
16827 printf (" Tag_ABI_conformance: \"");
16828 if (p < end - 1)
16829 {
16830 size_t maxlen = (end - p) - 1;
071436c6 16831
4082ef84
NC
16832 print_symbol ((int) maxlen, (const char *) p);
16833 p += strnlen ((char *) p, maxlen) + 1;
16834 }
16835 else
16836 {
16837 printf (_("<corrupt>"));
16838 p = (unsigned char *) end;
16839 }
071436c6 16840 printf ("\"\n");
071436c6
NC
16841 return p;
16842 }
59e6276b
JM
16843 }
16844
f6f0e17b
NC
16845 return display_tag_value (tag, p, end);
16846}
59e6276b 16847
f6f0e17b 16848static void
60abdbed 16849display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
16850{
16851 unsigned long addr = 0;
16852 size_t bytes = end - p;
16853
feceaa59 16854 assert (end >= p);
f6f0e17b 16855 while (bytes)
87779176 16856 {
f6f0e17b
NC
16857 int j;
16858 int k;
16859 int lbytes = (bytes > 16 ? 16 : bytes);
16860
16861 printf (" 0x%8.8lx ", addr);
16862
16863 for (j = 0; j < 16; j++)
16864 {
16865 if (j < lbytes)
16866 printf ("%2.2x", p[j]);
16867 else
16868 printf (" ");
16869
16870 if ((j & 3) == 3)
16871 printf (" ");
16872 }
16873
16874 for (j = 0; j < lbytes; j++)
16875 {
16876 k = p[j];
16877 if (k >= ' ' && k < 0x7f)
16878 printf ("%c", k);
16879 else
16880 printf (".");
16881 }
16882
16883 putchar ('\n');
16884
16885 p += lbytes;
16886 bytes -= lbytes;
16887 addr += lbytes;
87779176 16888 }
59e6276b 16889
f6f0e17b 16890 putchar ('\n');
59e6276b
JM
16891}
16892
13761a11 16893static unsigned char *
b0191216 16894display_msp430_attribute (unsigned char * p,
13761a11
NC
16895 const unsigned char * const end)
16896{
60abdbed
NC
16897 unsigned int val;
16898 unsigned int tag;
13761a11 16899
cd30bcef 16900 READ_ULEB (tag, p, end);
0b4362b0 16901
13761a11
NC
16902 switch (tag)
16903 {
16904 case OFBA_MSPABI_Tag_ISA:
13761a11 16905 printf (" Tag_ISA: ");
cd30bcef 16906 READ_ULEB (val, p, end);
13761a11
NC
16907 switch (val)
16908 {
16909 case 0: printf (_("None\n")); break;
16910 case 1: printf (_("MSP430\n")); break;
16911 case 2: printf (_("MSP430X\n")); break;
16912 default: printf ("??? (%d)\n", val); break;
16913 }
16914 break;
16915
16916 case OFBA_MSPABI_Tag_Code_Model:
13761a11 16917 printf (" Tag_Code_Model: ");
cd30bcef 16918 READ_ULEB (val, p, end);
13761a11
NC
16919 switch (val)
16920 {
16921 case 0: printf (_("None\n")); break;
16922 case 1: printf (_("Small\n")); break;
16923 case 2: printf (_("Large\n")); break;
16924 default: printf ("??? (%d)\n", val); break;
16925 }
16926 break;
16927
16928 case OFBA_MSPABI_Tag_Data_Model:
13761a11 16929 printf (" Tag_Data_Model: ");
cd30bcef 16930 READ_ULEB (val, p, end);
13761a11
NC
16931 switch (val)
16932 {
16933 case 0: printf (_("None\n")); break;
16934 case 1: printf (_("Small\n")); break;
16935 case 2: printf (_("Large\n")); break;
16936 case 3: printf (_("Restricted Large\n")); break;
16937 default: printf ("??? (%d)\n", val); break;
16938 }
16939 break;
16940
16941 default:
16942 printf (_(" <unknown tag %d>: "), tag);
16943
16944 if (tag & 1)
16945 {
071436c6 16946 putchar ('"');
4082ef84
NC
16947 if (p < end - 1)
16948 {
16949 size_t maxlen = (end - p) - 1;
16950
16951 print_symbol ((int) maxlen, (const char *) p);
16952 p += strnlen ((char *) p, maxlen) + 1;
16953 }
16954 else
16955 {
16956 printf (_("<corrupt>"));
16957 p = (unsigned char *) end;
16958 }
071436c6 16959 printf ("\"\n");
13761a11
NC
16960 }
16961 else
16962 {
cd30bcef 16963 READ_ULEB (val, p, end);
13761a11
NC
16964 printf ("%d (0x%x)\n", val, val);
16965 }
16966 break;
16967 }
16968
4082ef84 16969 assert (p <= end);
13761a11
NC
16970 return p;
16971}
16972
c0ea7c52
JL
16973static unsigned char *
16974display_msp430_gnu_attribute (unsigned char * p,
16975 unsigned int tag,
16976 const unsigned char * const end)
16977{
16978 if (tag == Tag_GNU_MSP430_Data_Region)
16979 {
cd30bcef 16980 unsigned int val;
c0ea7c52 16981
c0ea7c52 16982 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 16983 READ_ULEB (val, p, end);
c0ea7c52
JL
16984
16985 switch (val)
16986 {
16987 case Val_GNU_MSP430_Data_Region_Any:
16988 printf (_("Any Region\n"));
16989 break;
16990 case Val_GNU_MSP430_Data_Region_Lower:
16991 printf (_("Lower Region Only\n"));
16992 break;
16993 default:
cd30bcef 16994 printf ("??? (%u)\n", val);
c0ea7c52
JL
16995 }
16996 return p;
16997 }
16998 return display_tag_value (tag & 1, p, end);
16999}
17000
2dc8dd17
JW
17001struct riscv_attr_tag_t {
17002 const char *name;
cd30bcef 17003 unsigned int tag;
2dc8dd17
JW
17004};
17005
17006static struct riscv_attr_tag_t riscv_attr_tag[] =
17007{
17008#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17009 T(arch),
17010 T(priv_spec),
17011 T(priv_spec_minor),
17012 T(priv_spec_revision),
17013 T(unaligned_access),
17014 T(stack_align),
17015#undef T
17016};
17017
17018static unsigned char *
17019display_riscv_attribute (unsigned char *p,
17020 const unsigned char * const end)
17021{
cd30bcef
AM
17022 unsigned int val;
17023 unsigned int tag;
2dc8dd17
JW
17024 struct riscv_attr_tag_t *attr = NULL;
17025 unsigned i;
17026
cd30bcef 17027 READ_ULEB (tag, p, end);
2dc8dd17
JW
17028
17029 /* Find the name of attribute. */
17030 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17031 {
17032 if (riscv_attr_tag[i].tag == tag)
17033 {
17034 attr = &riscv_attr_tag[i];
17035 break;
17036 }
17037 }
17038
17039 if (attr)
17040 printf (" %s: ", attr->name);
17041 else
17042 return display_tag_value (tag, p, end);
17043
17044 switch (tag)
17045 {
17046 case Tag_RISCV_priv_spec:
17047 case Tag_RISCV_priv_spec_minor:
17048 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17049 READ_ULEB (val, p, end);
17050 printf (_("%u\n"), val);
2dc8dd17
JW
17051 break;
17052 case Tag_RISCV_unaligned_access:
cd30bcef 17053 READ_ULEB (val, p, end);
2dc8dd17
JW
17054 switch (val)
17055 {
17056 case 0:
17057 printf (_("No unaligned access\n"));
17058 break;
17059 case 1:
17060 printf (_("Unaligned access\n"));
17061 break;
17062 }
17063 break;
17064 case Tag_RISCV_stack_align:
cd30bcef
AM
17065 READ_ULEB (val, p, end);
17066 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17067 break;
17068 case Tag_RISCV_arch:
17069 p = display_tag_value (-1, p, end);
17070 break;
17071 default:
17072 return display_tag_value (tag, p, end);
17073 }
17074
17075 return p;
17076}
17077
0861f561
CQ
17078static unsigned char *
17079display_csky_attribute (unsigned char * p,
17080 const unsigned char * const end)
17081{
17082 unsigned int tag;
17083 unsigned int val;
17084 READ_ULEB (tag, p, end);
17085
17086 if (tag >= Tag_CSKY_MAX)
17087 {
17088 return display_tag_value (-1, p, end);
17089 }
17090
17091 switch (tag)
17092 {
17093 case Tag_CSKY_ARCH_NAME:
17094 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17095 return display_tag_value (-1, p, end);
17096 case Tag_CSKY_CPU_NAME:
17097 printf (" Tag_CSKY_CPU_NAME:\t\t");
17098 return display_tag_value (-1, p, end);
17099
17100 case Tag_CSKY_ISA_FLAGS:
17101 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17102 return display_tag_value (0, p, end);
17103 case Tag_CSKY_ISA_EXT_FLAGS:
17104 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17105 return display_tag_value (0, p, end);
17106
17107 case Tag_CSKY_DSP_VERSION:
17108 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17109 READ_ULEB (val, p, end);
17110 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17111 printf ("DSP Extension\n");
17112 else if (val == VAL_CSKY_DSP_VERSION_2)
17113 printf ("DSP 2.0\n");
17114 break;
17115
17116 case Tag_CSKY_VDSP_VERSION:
17117 printf (" Tag_CSKY_VDSP_VERSION:\t");
17118 READ_ULEB (val, p, end);
17119 printf ("VDSP Version %d\n", val);
17120 break;
17121
17122 case Tag_CSKY_FPU_VERSION:
17123 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17124 READ_ULEB (val, p, end);
17125 if (val == VAL_CSKY_FPU_VERSION_1)
17126 printf ("ABIV1 FPU Version 1\n");
17127 else if (val == VAL_CSKY_FPU_VERSION_2)
17128 printf ("FPU Version 2\n");
17129 break;
17130
17131 case Tag_CSKY_FPU_ABI:
17132 printf (" Tag_CSKY_FPU_ABI:\t\t");
17133 READ_ULEB (val, p, end);
17134 if (val == VAL_CSKY_FPU_ABI_HARD)
17135 printf ("Hard\n");
17136 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17137 printf ("SoftFP\n");
17138 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17139 printf ("Soft\n");
17140 break;
17141 case Tag_CSKY_FPU_ROUNDING:
17142 READ_ULEB (val, p, end);
17143 if (val == 1) {
17144 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17145 printf ("Needed\n");
17146 }
17147 break;
17148 case Tag_CSKY_FPU_DENORMAL:
17149 READ_ULEB (val, p, end);
17150 if (val == 1) {
17151 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17152 printf ("Needed\n");
17153 }
17154 break;
17155 case Tag_CSKY_FPU_Exception:
17156 READ_ULEB (val, p, end);
17157 if (val == 1) {
17158 printf (" Tag_CSKY_FPU_Exception:\t");
17159 printf ("Needed\n");
17160 }
17161 break;
17162 case Tag_CSKY_FPU_NUMBER_MODULE:
17163 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17164 return display_tag_value (-1, p, end);
17165 case Tag_CSKY_FPU_HARDFP:
17166 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17167 READ_ULEB (val, p, end);
17168 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17169 printf (" Half");
17170 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17171 printf (" Single");
17172 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17173 printf (" Double");
17174 printf ("\n");
17175 break;
17176 default:
17177 return display_tag_value (tag, p, end);
17178 }
17179 return p;
17180}
17181
015dc7e1 17182static bool
dda8d76d 17183process_attributes (Filedata * filedata,
60bca95a 17184 const char * public_name,
104d59d1 17185 unsigned int proc_type,
f6f0e17b 17186 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17187 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17188{
2cf0635d 17189 Elf_Internal_Shdr * sect;
11c1ff18 17190 unsigned i;
015dc7e1 17191 bool res = true;
11c1ff18
PB
17192
17193 /* Find the section header so that we get the size. */
dda8d76d
NC
17194 for (i = 0, sect = filedata->section_headers;
17195 i < filedata->file_header.e_shnum;
11c1ff18
PB
17196 i++, sect++)
17197 {
071436c6
NC
17198 unsigned char * contents;
17199 unsigned char * p;
17200
104d59d1 17201 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17202 continue;
17203
dda8d76d 17204 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17205 sect->sh_size, _("attributes"));
60bca95a 17206 if (contents == NULL)
32ec8896 17207 {
015dc7e1 17208 res = false;
32ec8896
NC
17209 continue;
17210 }
60bca95a 17211
11c1ff18 17212 p = contents;
60abdbed
NC
17213 /* The first character is the version of the attributes.
17214 Currently only version 1, (aka 'A') is recognised here. */
17215 if (*p != 'A')
32ec8896
NC
17216 {
17217 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17218 res = false;
32ec8896 17219 }
60abdbed 17220 else
11c1ff18 17221 {
071436c6
NC
17222 bfd_vma section_len;
17223
17224 section_len = sect->sh_size - 1;
11c1ff18 17225 p++;
60bca95a 17226
071436c6 17227 while (section_len > 0)
11c1ff18 17228 {
071436c6 17229 bfd_vma attr_len;
e9847026 17230 unsigned int namelen;
015dc7e1
AM
17231 bool public_section;
17232 bool gnu_section;
11c1ff18 17233
071436c6 17234 if (section_len <= 4)
e0a31db1
NC
17235 {
17236 error (_("Tag section ends prematurely\n"));
015dc7e1 17237 res = false;
e0a31db1
NC
17238 break;
17239 }
071436c6 17240 attr_len = byte_get (p, 4);
11c1ff18 17241 p += 4;
60bca95a 17242
071436c6 17243 if (attr_len > section_len)
11c1ff18 17244 {
071436c6
NC
17245 error (_("Bad attribute length (%u > %u)\n"),
17246 (unsigned) attr_len, (unsigned) section_len);
17247 attr_len = section_len;
015dc7e1 17248 res = false;
11c1ff18 17249 }
74e1a04b 17250 /* PR 17531: file: 001-101425-0.004 */
071436c6 17251 else if (attr_len < 5)
74e1a04b 17252 {
071436c6 17253 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17254 res = false;
74e1a04b
NC
17255 break;
17256 }
e9847026 17257
071436c6
NC
17258 section_len -= attr_len;
17259 attr_len -= 4;
17260
17261 namelen = strnlen ((char *) p, attr_len) + 1;
17262 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17263 {
17264 error (_("Corrupt attribute section name\n"));
015dc7e1 17265 res = false;
e9847026
NC
17266 break;
17267 }
17268
071436c6
NC
17269 printf (_("Attribute Section: "));
17270 print_symbol (INT_MAX, (const char *) p);
17271 putchar ('\n');
60bca95a
NC
17272
17273 if (public_name && streq ((char *) p, public_name))
015dc7e1 17274 public_section = true;
11c1ff18 17275 else
015dc7e1 17276 public_section = false;
60bca95a
NC
17277
17278 if (streq ((char *) p, "gnu"))
015dc7e1 17279 gnu_section = true;
104d59d1 17280 else
015dc7e1 17281 gnu_section = false;
60bca95a 17282
11c1ff18 17283 p += namelen;
071436c6 17284 attr_len -= namelen;
e0a31db1 17285
071436c6 17286 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17287 {
e0a31db1 17288 int tag;
cd30bcef 17289 unsigned int val;
11c1ff18 17290 bfd_vma size;
071436c6 17291 unsigned char * end;
60bca95a 17292
e0a31db1 17293 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17294 if (attr_len < 6)
e0a31db1
NC
17295 {
17296 error (_("Unused bytes at end of section\n"));
015dc7e1 17297 res = false;
e0a31db1
NC
17298 section_len = 0;
17299 break;
17300 }
17301
17302 tag = *(p++);
11c1ff18 17303 size = byte_get (p, 4);
071436c6 17304 if (size > attr_len)
11c1ff18 17305 {
e9847026 17306 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17307 (unsigned) size, (unsigned) attr_len);
015dc7e1 17308 res = false;
071436c6 17309 size = attr_len;
11c1ff18 17310 }
e0a31db1
NC
17311 /* PR binutils/17531: Safe handling of corrupt files. */
17312 if (size < 6)
17313 {
17314 error (_("Bad subsection length (%u < 6)\n"),
17315 (unsigned) size);
015dc7e1 17316 res = false;
e0a31db1
NC
17317 section_len = 0;
17318 break;
17319 }
60bca95a 17320
071436c6 17321 attr_len -= size;
11c1ff18 17322 end = p + size - 1;
071436c6 17323 assert (end <= contents + sect->sh_size);
11c1ff18 17324 p += 4;
60bca95a 17325
11c1ff18
PB
17326 switch (tag)
17327 {
17328 case 1:
2b692964 17329 printf (_("File Attributes\n"));
11c1ff18
PB
17330 break;
17331 case 2:
2b692964 17332 printf (_("Section Attributes:"));
11c1ff18
PB
17333 goto do_numlist;
17334 case 3:
2b692964 17335 printf (_("Symbol Attributes:"));
1a0670f3 17336 /* Fall through. */
11c1ff18
PB
17337 do_numlist:
17338 for (;;)
17339 {
cd30bcef 17340 READ_ULEB (val, p, end);
11c1ff18
PB
17341 if (val == 0)
17342 break;
17343 printf (" %d", val);
17344 }
17345 printf ("\n");
17346 break;
17347 default:
2b692964 17348 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 17349 public_section = false;
11c1ff18
PB
17350 break;
17351 }
60bca95a 17352
071436c6 17353 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
17354 {
17355 while (p < end)
f6f0e17b 17356 p = display_pub_attribute (p, end);
60abdbed 17357 assert (p == end);
104d59d1 17358 }
071436c6 17359 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
17360 {
17361 while (p < end)
17362 p = display_gnu_attribute (p,
f6f0e17b
NC
17363 display_proc_gnu_attribute,
17364 end);
60abdbed 17365 assert (p == end);
11c1ff18 17366 }
071436c6 17367 else if (p < end)
11c1ff18 17368 {
071436c6 17369 printf (_(" Unknown attribute:\n"));
f6f0e17b 17370 display_raw_attribute (p, end);
11c1ff18
PB
17371 p = end;
17372 }
071436c6
NC
17373 else
17374 attr_len = 0;
11c1ff18
PB
17375 }
17376 }
17377 }
d70c5fc7 17378
60bca95a 17379 free (contents);
11c1ff18 17380 }
32ec8896
NC
17381
17382 return res;
11c1ff18
PB
17383}
17384
ccb4c951
RS
17385/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
17386 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
17387 and return the VMA of the next entry, or -1 if there was a problem.
17388 Does not read from DATA_END or beyond. */
ccb4c951
RS
17389
17390static bfd_vma
82b1b41b
NC
17391print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
17392 unsigned char * data_end)
ccb4c951
RS
17393{
17394 printf (" ");
17395 print_vma (addr, LONG_HEX);
17396 printf (" ");
17397 if (addr < pltgot + 0xfff0)
17398 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
17399 else
17400 printf ("%10s", "");
17401 printf (" ");
17402 if (data == NULL)
2b692964 17403 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
17404 else
17405 {
17406 bfd_vma entry;
82b1b41b 17407 unsigned char * from = data + addr - pltgot;
ccb4c951 17408
82b1b41b
NC
17409 if (from + (is_32bit_elf ? 4 : 8) > data_end)
17410 {
17411 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
17412 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
17413 return (bfd_vma) -1;
17414 }
17415 else
17416 {
17417 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17418 print_vma (entry, LONG_HEX);
17419 }
ccb4c951
RS
17420 }
17421 return addr + (is_32bit_elf ? 4 : 8);
17422}
17423
861fb55a
DJ
17424/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
17425 PLTGOT. Print the Address and Initial fields of an entry at VMA
17426 ADDR and return the VMA of the next entry. */
17427
17428static bfd_vma
2cf0635d 17429print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
17430{
17431 printf (" ");
17432 print_vma (addr, LONG_HEX);
17433 printf (" ");
17434 if (data == NULL)
2b692964 17435 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
17436 else
17437 {
17438 bfd_vma entry;
17439
17440 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17441 print_vma (entry, LONG_HEX);
17442 }
17443 return addr + (is_32bit_elf ? 4 : 8);
17444}
17445
351cdf24
MF
17446static void
17447print_mips_ases (unsigned int mask)
17448{
17449 if (mask & AFL_ASE_DSP)
17450 fputs ("\n\tDSP ASE", stdout);
17451 if (mask & AFL_ASE_DSPR2)
17452 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
17453 if (mask & AFL_ASE_DSPR3)
17454 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
17455 if (mask & AFL_ASE_EVA)
17456 fputs ("\n\tEnhanced VA Scheme", stdout);
17457 if (mask & AFL_ASE_MCU)
17458 fputs ("\n\tMCU (MicroController) ASE", stdout);
17459 if (mask & AFL_ASE_MDMX)
17460 fputs ("\n\tMDMX ASE", stdout);
17461 if (mask & AFL_ASE_MIPS3D)
17462 fputs ("\n\tMIPS-3D ASE", stdout);
17463 if (mask & AFL_ASE_MT)
17464 fputs ("\n\tMT ASE", stdout);
17465 if (mask & AFL_ASE_SMARTMIPS)
17466 fputs ("\n\tSmartMIPS ASE", stdout);
17467 if (mask & AFL_ASE_VIRT)
17468 fputs ("\n\tVZ ASE", stdout);
17469 if (mask & AFL_ASE_MSA)
17470 fputs ("\n\tMSA ASE", stdout);
17471 if (mask & AFL_ASE_MIPS16)
17472 fputs ("\n\tMIPS16 ASE", stdout);
17473 if (mask & AFL_ASE_MICROMIPS)
17474 fputs ("\n\tMICROMIPS ASE", stdout);
17475 if (mask & AFL_ASE_XPA)
17476 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
17477 if (mask & AFL_ASE_MIPS16E2)
17478 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
17479 if (mask & AFL_ASE_CRC)
17480 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
17481 if (mask & AFL_ASE_GINV)
17482 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
17483 if (mask & AFL_ASE_LOONGSON_MMI)
17484 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
17485 if (mask & AFL_ASE_LOONGSON_CAM)
17486 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
17487 if (mask & AFL_ASE_LOONGSON_EXT)
17488 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
17489 if (mask & AFL_ASE_LOONGSON_EXT2)
17490 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
17491 if (mask == 0)
17492 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
17493 else if ((mask & ~AFL_ASE_MASK) != 0)
17494 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
17495}
17496
17497static void
17498print_mips_isa_ext (unsigned int isa_ext)
17499{
17500 switch (isa_ext)
17501 {
17502 case 0:
17503 fputs (_("None"), stdout);
17504 break;
17505 case AFL_EXT_XLR:
17506 fputs ("RMI XLR", stdout);
17507 break;
2c629856
N
17508 case AFL_EXT_OCTEON3:
17509 fputs ("Cavium Networks Octeon3", stdout);
17510 break;
351cdf24
MF
17511 case AFL_EXT_OCTEON2:
17512 fputs ("Cavium Networks Octeon2", stdout);
17513 break;
17514 case AFL_EXT_OCTEONP:
17515 fputs ("Cavium Networks OcteonP", stdout);
17516 break;
351cdf24
MF
17517 case AFL_EXT_OCTEON:
17518 fputs ("Cavium Networks Octeon", stdout);
17519 break;
17520 case AFL_EXT_5900:
17521 fputs ("Toshiba R5900", stdout);
17522 break;
17523 case AFL_EXT_4650:
17524 fputs ("MIPS R4650", stdout);
17525 break;
17526 case AFL_EXT_4010:
17527 fputs ("LSI R4010", stdout);
17528 break;
17529 case AFL_EXT_4100:
17530 fputs ("NEC VR4100", stdout);
17531 break;
17532 case AFL_EXT_3900:
17533 fputs ("Toshiba R3900", stdout);
17534 break;
17535 case AFL_EXT_10000:
17536 fputs ("MIPS R10000", stdout);
17537 break;
17538 case AFL_EXT_SB1:
17539 fputs ("Broadcom SB-1", stdout);
17540 break;
17541 case AFL_EXT_4111:
17542 fputs ("NEC VR4111/VR4181", stdout);
17543 break;
17544 case AFL_EXT_4120:
17545 fputs ("NEC VR4120", stdout);
17546 break;
17547 case AFL_EXT_5400:
17548 fputs ("NEC VR5400", stdout);
17549 break;
17550 case AFL_EXT_5500:
17551 fputs ("NEC VR5500", stdout);
17552 break;
17553 case AFL_EXT_LOONGSON_2E:
17554 fputs ("ST Microelectronics Loongson 2E", stdout);
17555 break;
17556 case AFL_EXT_LOONGSON_2F:
17557 fputs ("ST Microelectronics Loongson 2F", stdout);
17558 break;
38bf472a
MR
17559 case AFL_EXT_INTERAPTIV_MR2:
17560 fputs ("Imagination interAptiv MR2", stdout);
17561 break;
351cdf24 17562 default:
00ac7aa0 17563 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
17564 }
17565}
17566
32ec8896 17567static signed int
351cdf24
MF
17568get_mips_reg_size (int reg_size)
17569{
17570 return (reg_size == AFL_REG_NONE) ? 0
17571 : (reg_size == AFL_REG_32) ? 32
17572 : (reg_size == AFL_REG_64) ? 64
17573 : (reg_size == AFL_REG_128) ? 128
17574 : -1;
17575}
17576
015dc7e1 17577static bool
dda8d76d 17578process_mips_specific (Filedata * filedata)
5b18a4bc 17579{
2cf0635d 17580 Elf_Internal_Dyn * entry;
351cdf24 17581 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
17582 size_t liblist_offset = 0;
17583 size_t liblistno = 0;
17584 size_t conflictsno = 0;
17585 size_t options_offset = 0;
17586 size_t conflicts_offset = 0;
861fb55a
DJ
17587 size_t pltrelsz = 0;
17588 size_t pltrel = 0;
ccb4c951 17589 bfd_vma pltgot = 0;
861fb55a
DJ
17590 bfd_vma mips_pltgot = 0;
17591 bfd_vma jmprel = 0;
ccb4c951
RS
17592 bfd_vma local_gotno = 0;
17593 bfd_vma gotsym = 0;
17594 bfd_vma symtabno = 0;
015dc7e1 17595 bool res = true;
103f02d3 17596
dda8d76d 17597 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 17598 display_mips_gnu_attribute))
015dc7e1 17599 res = false;
2cf19d5c 17600
dda8d76d 17601 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
17602
17603 if (sect != NULL)
17604 {
17605 Elf_External_ABIFlags_v0 *abiflags_ext;
17606 Elf_Internal_ABIFlags_v0 abiflags_in;
17607
17608 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
17609 {
17610 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 17611 res = false;
32ec8896 17612 }
351cdf24
MF
17613 else
17614 {
dda8d76d 17615 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
17616 sect->sh_size, _("MIPS ABI Flags section"));
17617 if (abiflags_ext)
17618 {
17619 abiflags_in.version = BYTE_GET (abiflags_ext->version);
17620 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
17621 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
17622 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
17623 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
17624 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
17625 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
17626 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
17627 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
17628 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
17629 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
17630
17631 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
17632 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
17633 if (abiflags_in.isa_rev > 1)
17634 printf ("r%d", abiflags_in.isa_rev);
17635 printf ("\nGPR size: %d",
17636 get_mips_reg_size (abiflags_in.gpr_size));
17637 printf ("\nCPR1 size: %d",
17638 get_mips_reg_size (abiflags_in.cpr1_size));
17639 printf ("\nCPR2 size: %d",
17640 get_mips_reg_size (abiflags_in.cpr2_size));
17641 fputs ("\nFP ABI: ", stdout);
17642 print_mips_fp_abi_value (abiflags_in.fp_abi);
17643 fputs ("ISA Extension: ", stdout);
17644 print_mips_isa_ext (abiflags_in.isa_ext);
17645 fputs ("\nASEs:", stdout);
17646 print_mips_ases (abiflags_in.ases);
17647 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
17648 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
17649 fputc ('\n', stdout);
17650 free (abiflags_ext);
17651 }
17652 }
17653 }
17654
19e6b90e 17655 /* We have a lot of special sections. Thanks SGI! */
978c4450 17656 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
17657 {
17658 /* No dynamic information available. See if there is static GOT. */
dda8d76d 17659 sect = find_section (filedata, ".got");
bbdd9a68
MR
17660 if (sect != NULL)
17661 {
17662 unsigned char *data_end;
17663 unsigned char *data;
17664 bfd_vma ent, end;
17665 int addr_size;
17666
17667 pltgot = sect->sh_addr;
17668
17669 ent = pltgot;
17670 addr_size = (is_32bit_elf ? 4 : 8);
17671 end = pltgot + sect->sh_size;
17672
dda8d76d 17673 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
17674 end - pltgot, 1,
17675 _("Global Offset Table data"));
17676 /* PR 12855: Null data is handled gracefully throughout. */
17677 data_end = data + (end - pltgot);
17678
17679 printf (_("\nStatic GOT:\n"));
17680 printf (_(" Canonical gp value: "));
17681 print_vma (ent + 0x7ff0, LONG_HEX);
17682 printf ("\n\n");
17683
17684 /* In a dynamic binary GOT[0] is reserved for the dynamic
17685 loader to store the lazy resolver pointer, however in
17686 a static binary it may well have been omitted and GOT
17687 reduced to a table of addresses.
17688 PR 21344: Check for the entry being fully available
17689 before fetching it. */
17690 if (data
17691 && data + ent - pltgot + addr_size <= data_end
17692 && byte_get (data + ent - pltgot, addr_size) == 0)
17693 {
17694 printf (_(" Reserved entries:\n"));
17695 printf (_(" %*s %10s %*s\n"),
17696 addr_size * 2, _("Address"), _("Access"),
17697 addr_size * 2, _("Value"));
17698 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17699 printf ("\n");
17700 if (ent == (bfd_vma) -1)
17701 goto sgot_print_fail;
17702
17703 /* Check for the MSB of GOT[1] being set, identifying a
17704 GNU object. This entry will be used by some runtime
17705 loaders, to store the module pointer. Otherwise this
17706 is an ordinary local entry.
17707 PR 21344: Check for the entry being fully available
17708 before fetching it. */
17709 if (data
17710 && data + ent - pltgot + addr_size <= data_end
17711 && (byte_get (data + ent - pltgot, addr_size)
17712 >> (addr_size * 8 - 1)) != 0)
17713 {
17714 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17715 printf ("\n");
17716 if (ent == (bfd_vma) -1)
17717 goto sgot_print_fail;
17718 }
17719 printf ("\n");
17720 }
17721
f17e9d8a 17722 if (data != NULL && ent < end)
bbdd9a68
MR
17723 {
17724 printf (_(" Local entries:\n"));
17725 printf (" %*s %10s %*s\n",
17726 addr_size * 2, _("Address"), _("Access"),
17727 addr_size * 2, _("Value"));
17728 while (ent < end)
17729 {
17730 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17731 printf ("\n");
17732 if (ent == (bfd_vma) -1)
17733 goto sgot_print_fail;
17734 }
17735 printf ("\n");
17736 }
17737
17738 sgot_print_fail:
9db70fc3 17739 free (data);
bbdd9a68
MR
17740 }
17741 return res;
17742 }
252b5132 17743
978c4450 17744 for (entry = filedata->dynamic_section;
071436c6 17745 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
17746 (entry < filedata->dynamic_section + filedata->dynamic_nent
17747 && entry->d_tag != DT_NULL);
071436c6 17748 ++entry)
252b5132
RH
17749 switch (entry->d_tag)
17750 {
17751 case DT_MIPS_LIBLIST:
d93f0186 17752 liblist_offset
dda8d76d 17753 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17754 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
17755 break;
17756 case DT_MIPS_LIBLISTNO:
17757 liblistno = entry->d_un.d_val;
17758 break;
17759 case DT_MIPS_OPTIONS:
dda8d76d 17760 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
17761 break;
17762 case DT_MIPS_CONFLICT:
d93f0186 17763 conflicts_offset
dda8d76d 17764 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17765 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
17766 break;
17767 case DT_MIPS_CONFLICTNO:
17768 conflictsno = entry->d_un.d_val;
17769 break;
ccb4c951 17770 case DT_PLTGOT:
861fb55a
DJ
17771 pltgot = entry->d_un.d_ptr;
17772 break;
ccb4c951
RS
17773 case DT_MIPS_LOCAL_GOTNO:
17774 local_gotno = entry->d_un.d_val;
17775 break;
17776 case DT_MIPS_GOTSYM:
17777 gotsym = entry->d_un.d_val;
17778 break;
17779 case DT_MIPS_SYMTABNO:
17780 symtabno = entry->d_un.d_val;
17781 break;
861fb55a
DJ
17782 case DT_MIPS_PLTGOT:
17783 mips_pltgot = entry->d_un.d_ptr;
17784 break;
17785 case DT_PLTREL:
17786 pltrel = entry->d_un.d_val;
17787 break;
17788 case DT_PLTRELSZ:
17789 pltrelsz = entry->d_un.d_val;
17790 break;
17791 case DT_JMPREL:
17792 jmprel = entry->d_un.d_ptr;
17793 break;
252b5132
RH
17794 default:
17795 break;
17796 }
17797
17798 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
17799 {
2cf0635d 17800 Elf32_External_Lib * elib;
252b5132
RH
17801 size_t cnt;
17802
dda8d76d 17803 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
17804 sizeof (Elf32_External_Lib),
17805 liblistno,
17806 _("liblist section data"));
a6e9f9df 17807 if (elib)
252b5132 17808 {
d3a49aa8
AM
17809 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
17810 "\nSection '.liblist' contains %lu entries:\n",
17811 (unsigned long) liblistno),
a6e9f9df 17812 (unsigned long) liblistno);
2b692964 17813 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
17814 stdout);
17815
17816 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 17817 {
a6e9f9df 17818 Elf32_Lib liblist;
91d6fa6a 17819 time_t atime;
d5b07ef4 17820 char timebuf[128];
2cf0635d 17821 struct tm * tmp;
a6e9f9df
AM
17822
17823 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17824 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
17825 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17826 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17827 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17828
91d6fa6a 17829 tmp = gmtime (&atime);
e9e44622
JJ
17830 snprintf (timebuf, sizeof (timebuf),
17831 "%04u-%02u-%02uT%02u:%02u:%02u",
17832 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17833 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 17834
31104126 17835 printf ("%3lu: ", (unsigned long) cnt);
978c4450
AM
17836 if (VALID_DYNAMIC_NAME (filedata, liblist.l_name))
17837 print_symbol (20, GET_DYNAMIC_NAME (filedata, liblist.l_name));
d79b3d50 17838 else
2b692964 17839 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
17840 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
17841 liblist.l_version);
a6e9f9df
AM
17842
17843 if (liblist.l_flags == 0)
2b692964 17844 puts (_(" NONE"));
a6e9f9df
AM
17845 else
17846 {
17847 static const struct
252b5132 17848 {
2cf0635d 17849 const char * name;
a6e9f9df 17850 int bit;
252b5132 17851 }
a6e9f9df
AM
17852 l_flags_vals[] =
17853 {
17854 { " EXACT_MATCH", LL_EXACT_MATCH },
17855 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
17856 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
17857 { " EXPORTS", LL_EXPORTS },
17858 { " DELAY_LOAD", LL_DELAY_LOAD },
17859 { " DELTA", LL_DELTA }
17860 };
17861 int flags = liblist.l_flags;
17862 size_t fcnt;
17863
60bca95a 17864 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
17865 if ((flags & l_flags_vals[fcnt].bit) != 0)
17866 {
17867 fputs (l_flags_vals[fcnt].name, stdout);
17868 flags ^= l_flags_vals[fcnt].bit;
17869 }
17870 if (flags != 0)
17871 printf (" %#x", (unsigned int) flags);
252b5132 17872
a6e9f9df
AM
17873 puts ("");
17874 }
252b5132 17875 }
252b5132 17876
a6e9f9df
AM
17877 free (elib);
17878 }
32ec8896 17879 else
015dc7e1 17880 res = false;
252b5132
RH
17881 }
17882
17883 if (options_offset != 0)
17884 {
2cf0635d 17885 Elf_External_Options * eopt;
252b5132
RH
17886 size_t offset;
17887 int cnt;
dda8d76d 17888 sect = filedata->section_headers;
252b5132
RH
17889
17890 /* Find the section header so that we get the size. */
dda8d76d 17891 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 17892 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
17893 if (sect == NULL)
17894 {
17895 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 17896 return false;
071436c6 17897 }
7fc0c668
NC
17898 /* PR 24243 */
17899 if (sect->sh_size < sizeof (* eopt))
17900 {
17901 error (_("The MIPS options section is too small.\n"));
015dc7e1 17902 return false;
7fc0c668 17903 }
252b5132 17904
dda8d76d 17905 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 17906 sect->sh_size, _("options"));
a6e9f9df 17907 if (eopt)
252b5132 17908 {
fd17d1e6 17909 Elf_Internal_Options option;
76da6bbe 17910
a6e9f9df 17911 offset = cnt = 0;
82b1b41b 17912 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 17913 {
2cf0635d 17914 Elf_External_Options * eoption;
fd17d1e6 17915 unsigned int optsize;
252b5132 17916
a6e9f9df 17917 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 17918
fd17d1e6 17919 optsize = BYTE_GET (eoption->size);
76da6bbe 17920
82b1b41b 17921 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
17922 if (optsize < sizeof (* eopt)
17923 || optsize > sect->sh_size - offset)
82b1b41b 17924 {
645f43a8 17925 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 17926 optsize);
645f43a8 17927 free (eopt);
015dc7e1 17928 return false;
82b1b41b 17929 }
fd17d1e6 17930 offset += optsize;
a6e9f9df
AM
17931 ++cnt;
17932 }
252b5132 17933
d3a49aa8
AM
17934 printf (ngettext ("\nSection '%s' contains %d entry:\n",
17935 "\nSection '%s' contains %d entries:\n",
17936 cnt),
dda8d76d 17937 printable_section_name (filedata, sect), cnt);
76da6bbe 17938
82b1b41b 17939 offset = 0;
a6e9f9df 17940 while (cnt-- > 0)
252b5132 17941 {
a6e9f9df 17942 size_t len;
fd17d1e6
AM
17943 Elf_External_Options * eoption;
17944
17945 eoption = (Elf_External_Options *) ((char *) eopt + offset);
17946
17947 option.kind = BYTE_GET (eoption->kind);
17948 option.size = BYTE_GET (eoption->size);
17949 option.section = BYTE_GET (eoption->section);
17950 option.info = BYTE_GET (eoption->info);
a6e9f9df 17951
fd17d1e6 17952 switch (option.kind)
252b5132 17953 {
a6e9f9df
AM
17954 case ODK_NULL:
17955 /* This shouldn't happen. */
d0c4e780 17956 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 17957 option.section, option.info);
a6e9f9df 17958 break;
2e6be59c 17959
a6e9f9df
AM
17960 case ODK_REGINFO:
17961 printf (" REGINFO ");
dda8d76d 17962 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 17963 {
2cf0635d 17964 Elf32_External_RegInfo * ereg;
b34976b6 17965 Elf32_RegInfo reginfo;
a6e9f9df 17966
2e6be59c 17967 /* 32bit form. */
fd17d1e6
AM
17968 if (option.size < (sizeof (Elf_External_Options)
17969 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
17970 {
17971 printf (_("<corrupt>\n"));
17972 error (_("Truncated MIPS REGINFO option\n"));
17973 cnt = 0;
17974 break;
17975 }
17976
fd17d1e6 17977 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 17978
a6e9f9df
AM
17979 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17980 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17981 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17982 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17983 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
17984 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
17985
d0c4e780
AM
17986 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
17987 reginfo.ri_gprmask, reginfo.ri_gp_value);
17988 printf (" "
17989 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
17990 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
17991 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17992 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17993 }
17994 else
17995 {
17996 /* 64 bit form. */
2cf0635d 17997 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
17998 Elf64_Internal_RegInfo reginfo;
17999
fd17d1e6
AM
18000 if (option.size < (sizeof (Elf_External_Options)
18001 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18002 {
18003 printf (_("<corrupt>\n"));
18004 error (_("Truncated MIPS REGINFO option\n"));
18005 cnt = 0;
18006 break;
18007 }
18008
fd17d1e6 18009 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18010 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18011 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18012 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18013 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18014 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18015 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18016
d0c4e780
AM
18017 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18018 reginfo.ri_gprmask, reginfo.ri_gp_value);
18019 printf (" "
18020 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18021 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18022 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18023 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18024 }
fd17d1e6 18025 offset += option.size;
a6e9f9df 18026 continue;
2e6be59c 18027
a6e9f9df
AM
18028 case ODK_EXCEPTIONS:
18029 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18030 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18031 fputs (") fpe_max(", stdout);
fd17d1e6 18032 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18033 fputs (")", stdout);
18034
fd17d1e6 18035 if (option.info & OEX_PAGE0)
a6e9f9df 18036 fputs (" PAGE0", stdout);
fd17d1e6 18037 if (option.info & OEX_SMM)
a6e9f9df 18038 fputs (" SMM", stdout);
fd17d1e6 18039 if (option.info & OEX_FPDBUG)
a6e9f9df 18040 fputs (" FPDBUG", stdout);
fd17d1e6 18041 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18042 fputs (" DISMISS", stdout);
18043 break;
2e6be59c 18044
a6e9f9df
AM
18045 case ODK_PAD:
18046 fputs (" PAD ", stdout);
fd17d1e6 18047 if (option.info & OPAD_PREFIX)
a6e9f9df 18048 fputs (" PREFIX", stdout);
fd17d1e6 18049 if (option.info & OPAD_POSTFIX)
a6e9f9df 18050 fputs (" POSTFIX", stdout);
fd17d1e6 18051 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18052 fputs (" SYMBOL", stdout);
18053 break;
2e6be59c 18054
a6e9f9df
AM
18055 case ODK_HWPATCH:
18056 fputs (" HWPATCH ", stdout);
fd17d1e6 18057 if (option.info & OHW_R4KEOP)
a6e9f9df 18058 fputs (" R4KEOP", stdout);
fd17d1e6 18059 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18060 fputs (" R8KPFETCH", stdout);
fd17d1e6 18061 if (option.info & OHW_R5KEOP)
a6e9f9df 18062 fputs (" R5KEOP", stdout);
fd17d1e6 18063 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18064 fputs (" R5KCVTL", stdout);
18065 break;
2e6be59c 18066
a6e9f9df
AM
18067 case ODK_FILL:
18068 fputs (" FILL ", stdout);
18069 /* XXX Print content of info word? */
18070 break;
2e6be59c 18071
a6e9f9df
AM
18072 case ODK_TAGS:
18073 fputs (" TAGS ", stdout);
18074 /* XXX Print content of info word? */
18075 break;
2e6be59c 18076
a6e9f9df
AM
18077 case ODK_HWAND:
18078 fputs (" HWAND ", stdout);
fd17d1e6 18079 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18080 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18081 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18082 fputs (" R4KEOP_CLEAN", stdout);
18083 break;
2e6be59c 18084
a6e9f9df
AM
18085 case ODK_HWOR:
18086 fputs (" HWOR ", stdout);
fd17d1e6 18087 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18088 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18089 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18090 fputs (" R4KEOP_CLEAN", stdout);
18091 break;
2e6be59c 18092
a6e9f9df 18093 case ODK_GP_GROUP:
d0c4e780 18094 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18095 option.info & OGP_GROUP,
18096 (option.info & OGP_SELF) >> 16);
a6e9f9df 18097 break;
2e6be59c 18098
a6e9f9df 18099 case ODK_IDENT:
d0c4e780 18100 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18101 option.info & OGP_GROUP,
18102 (option.info & OGP_SELF) >> 16);
a6e9f9df 18103 break;
2e6be59c 18104
a6e9f9df
AM
18105 default:
18106 /* This shouldn't happen. */
d0c4e780 18107 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18108 option.kind, option.section, option.info);
a6e9f9df 18109 break;
252b5132 18110 }
a6e9f9df 18111
2cf0635d 18112 len = sizeof (* eopt);
fd17d1e6 18113 while (len < option.size)
82b1b41b 18114 {
fd17d1e6 18115 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18116
82b1b41b
NC
18117 if (ISPRINT (datum))
18118 printf ("%c", datum);
18119 else
18120 printf ("\\%03o", datum);
18121 len ++;
18122 }
a6e9f9df 18123 fputs ("\n", stdout);
82b1b41b 18124
fd17d1e6 18125 offset += option.size;
252b5132 18126 }
a6e9f9df 18127 free (eopt);
252b5132 18128 }
32ec8896 18129 else
015dc7e1 18130 res = false;
252b5132
RH
18131 }
18132
18133 if (conflicts_offset != 0 && conflictsno != 0)
18134 {
2cf0635d 18135 Elf32_Conflict * iconf;
252b5132
RH
18136 size_t cnt;
18137
978c4450 18138 if (filedata->dynamic_symbols == NULL)
252b5132 18139 {
591a748a 18140 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18141 return false;
252b5132
RH
18142 }
18143
7296a62a
NC
18144 /* PR 21345 - print a slightly more helpful error message
18145 if we are sure that the cmalloc will fail. */
645f43a8 18146 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18147 {
18148 error (_("Overlarge number of conflicts detected: %lx\n"),
18149 (long) conflictsno);
015dc7e1 18150 return false;
7296a62a
NC
18151 }
18152
3f5e193b 18153 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18154 if (iconf == NULL)
18155 {
8b73c356 18156 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18157 return false;
252b5132
RH
18158 }
18159
9ea033b2 18160 if (is_32bit_elf)
252b5132 18161 {
2cf0635d 18162 Elf32_External_Conflict * econf32;
a6e9f9df 18163
3f5e193b 18164 econf32 = (Elf32_External_Conflict *)
95099889
AM
18165 get_data (NULL, filedata, conflicts_offset,
18166 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18167 if (!econf32)
5a814d6d
AM
18168 {
18169 free (iconf);
015dc7e1 18170 return false;
5a814d6d 18171 }
252b5132
RH
18172
18173 for (cnt = 0; cnt < conflictsno; ++cnt)
18174 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18175
18176 free (econf32);
252b5132
RH
18177 }
18178 else
18179 {
2cf0635d 18180 Elf64_External_Conflict * econf64;
a6e9f9df 18181
3f5e193b 18182 econf64 = (Elf64_External_Conflict *)
95099889
AM
18183 get_data (NULL, filedata, conflicts_offset,
18184 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18185 if (!econf64)
5a814d6d
AM
18186 {
18187 free (iconf);
015dc7e1 18188 return false;
5a814d6d 18189 }
252b5132
RH
18190
18191 for (cnt = 0; cnt < conflictsno; ++cnt)
18192 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18193
18194 free (econf64);
252b5132
RH
18195 }
18196
d3a49aa8
AM
18197 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18198 "\nSection '.conflict' contains %lu entries:\n",
18199 (unsigned long) conflictsno),
c7e7ca54 18200 (unsigned long) conflictsno);
252b5132
RH
18201 puts (_(" Num: Index Value Name"));
18202
18203 for (cnt = 0; cnt < conflictsno; ++cnt)
18204 {
b34976b6 18205 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18206
978c4450 18207 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18208 printf (_("<corrupt symbol index>"));
d79b3d50 18209 else
e0a31db1
NC
18210 {
18211 Elf_Internal_Sym * psym;
18212
978c4450 18213 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18214 print_vma (psym->st_value, FULL_HEX);
18215 putchar (' ');
978c4450
AM
18216 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18217 print_symbol (25, GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18218 else
18219 printf (_("<corrupt: %14ld>"), psym->st_name);
18220 }
31104126 18221 putchar ('\n');
252b5132
RH
18222 }
18223
252b5132
RH
18224 free (iconf);
18225 }
18226
ccb4c951
RS
18227 if (pltgot != 0 && local_gotno != 0)
18228 {
91d6fa6a 18229 bfd_vma ent, local_end, global_end;
bbeee7ea 18230 size_t i, offset;
2cf0635d 18231 unsigned char * data;
82b1b41b 18232 unsigned char * data_end;
bbeee7ea 18233 int addr_size;
ccb4c951 18234
91d6fa6a 18235 ent = pltgot;
ccb4c951
RS
18236 addr_size = (is_32bit_elf ? 4 : 8);
18237 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18238
74e1a04b
NC
18239 /* PR binutils/17533 file: 012-111227-0.004 */
18240 if (symtabno < gotsym)
18241 {
18242 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18243 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18244 return false;
74e1a04b 18245 }
82b1b41b 18246
74e1a04b 18247 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18248 /* PR 17531: file: 54c91a34. */
18249 if (global_end < local_end)
18250 {
18251 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18252 return false;
82b1b41b 18253 }
948f632f 18254
dda8d76d
NC
18255 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18256 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18257 global_end - pltgot, 1,
18258 _("Global Offset Table data"));
919383ac 18259 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18260 data_end = data + (global_end - pltgot);
59245841 18261
ccb4c951
RS
18262 printf (_("\nPrimary GOT:\n"));
18263 printf (_(" Canonical gp value: "));
18264 print_vma (pltgot + 0x7ff0, LONG_HEX);
18265 printf ("\n\n");
18266
18267 printf (_(" Reserved entries:\n"));
18268 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18269 addr_size * 2, _("Address"), _("Access"),
18270 addr_size * 2, _("Initial"));
82b1b41b 18271 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18272 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18273 if (ent == (bfd_vma) -1)
18274 goto got_print_fail;
75ec1fdb 18275
c4ab9505
MR
18276 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18277 This entry will be used by some runtime loaders, to store the
18278 module pointer. Otherwise this is an ordinary local entry.
18279 PR 21344: Check for the entry being fully available before
18280 fetching it. */
18281 if (data
18282 && data + ent - pltgot + addr_size <= data_end
18283 && (byte_get (data + ent - pltgot, addr_size)
18284 >> (addr_size * 8 - 1)) != 0)
18285 {
18286 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18287 printf (_(" Module pointer (GNU extension)\n"));
18288 if (ent == (bfd_vma) -1)
18289 goto got_print_fail;
ccb4c951
RS
18290 }
18291 printf ("\n");
18292
f17e9d8a 18293 if (data != NULL && ent < local_end)
ccb4c951
RS
18294 {
18295 printf (_(" Local entries:\n"));
cc5914eb 18296 printf (" %*s %10s %*s\n",
2b692964
NC
18297 addr_size * 2, _("Address"), _("Access"),
18298 addr_size * 2, _("Initial"));
91d6fa6a 18299 while (ent < local_end)
ccb4c951 18300 {
82b1b41b 18301 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18302 printf ("\n");
82b1b41b
NC
18303 if (ent == (bfd_vma) -1)
18304 goto got_print_fail;
ccb4c951
RS
18305 }
18306 printf ("\n");
18307 }
18308
f17e9d8a 18309 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18310 {
18311 int sym_width;
18312
18313 printf (_(" Global entries:\n"));
cc5914eb 18314 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18315 addr_size * 2, _("Address"),
18316 _("Access"),
2b692964 18317 addr_size * 2, _("Initial"),
9cf03b7e
NC
18318 addr_size * 2, _("Sym.Val."),
18319 _("Type"),
18320 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18321 _("Ndx"), _("Name"));
0b4362b0 18322
ccb4c951 18323 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18324
ccb4c951
RS
18325 for (i = gotsym; i < symtabno; i++)
18326 {
82b1b41b 18327 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18328 printf (" ");
e0a31db1 18329
978c4450 18330 if (filedata->dynamic_symbols == NULL)
e0a31db1 18331 printf (_("<no dynamic symbols>"));
978c4450 18332 else if (i < filedata->num_dynamic_syms)
e0a31db1 18333 {
978c4450 18334 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
18335
18336 print_vma (psym->st_value, LONG_HEX);
18337 printf (" %-7s %3s ",
dda8d76d
NC
18338 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18339 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 18340
978c4450
AM
18341 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18342 print_symbol (sym_width,
18343 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18344 else
18345 printf (_("<corrupt: %14ld>"), psym->st_name);
18346 }
ccb4c951 18347 else
7fc5ac57
JBG
18348 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
18349 (unsigned long) i);
e0a31db1 18350
ccb4c951 18351 printf ("\n");
82b1b41b
NC
18352 if (ent == (bfd_vma) -1)
18353 break;
ccb4c951
RS
18354 }
18355 printf ("\n");
18356 }
18357
82b1b41b 18358 got_print_fail:
9db70fc3 18359 free (data);
ccb4c951
RS
18360 }
18361
861fb55a
DJ
18362 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
18363 {
91d6fa6a 18364 bfd_vma ent, end;
861fb55a
DJ
18365 size_t offset, rel_offset;
18366 unsigned long count, i;
2cf0635d 18367 unsigned char * data;
861fb55a 18368 int addr_size, sym_width;
2cf0635d 18369 Elf_Internal_Rela * rels;
861fb55a 18370
dda8d76d 18371 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
18372 if (pltrel == DT_RELA)
18373 {
dda8d76d 18374 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18375 return false;
861fb55a
DJ
18376 }
18377 else
18378 {
dda8d76d 18379 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18380 return false;
861fb55a
DJ
18381 }
18382
91d6fa6a 18383 ent = mips_pltgot;
861fb55a
DJ
18384 addr_size = (is_32bit_elf ? 4 : 8);
18385 end = mips_pltgot + (2 + count) * addr_size;
18386
dda8d76d
NC
18387 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
18388 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 18389 1, _("Procedure Linkage Table data"));
59245841 18390 if (data == NULL)
288f0ba2
AM
18391 {
18392 free (rels);
015dc7e1 18393 return false;
288f0ba2 18394 }
59245841 18395
9cf03b7e 18396 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
18397 printf (_(" Reserved entries:\n"));
18398 printf (_(" %*s %*s Purpose\n"),
2b692964 18399 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 18400 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18401 printf (_(" PLT lazy resolver\n"));
91d6fa6a 18402 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18403 printf (_(" Module pointer\n"));
861fb55a
DJ
18404 printf ("\n");
18405
18406 printf (_(" Entries:\n"));
cc5914eb 18407 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
18408 addr_size * 2, _("Address"),
18409 addr_size * 2, _("Initial"),
18410 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
18411 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
18412 for (i = 0; i < count; i++)
18413 {
df97ab2a 18414 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 18415
91d6fa6a 18416 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 18417 printf (" ");
e0a31db1 18418
978c4450 18419 if (idx >= filedata->num_dynamic_syms)
df97ab2a 18420 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 18421 else
e0a31db1 18422 {
978c4450 18423 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
18424
18425 print_vma (psym->st_value, LONG_HEX);
18426 printf (" %-7s %3s ",
dda8d76d
NC
18427 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18428 get_symbol_index_type (filedata, psym->st_shndx));
978c4450
AM
18429 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18430 print_symbol (sym_width,
18431 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18432 else
18433 printf (_("<corrupt: %14ld>"), psym->st_name);
18434 }
861fb55a
DJ
18435 printf ("\n");
18436 }
18437 printf ("\n");
18438
9db70fc3 18439 free (data);
861fb55a
DJ
18440 free (rels);
18441 }
18442
32ec8896 18443 return res;
252b5132
RH
18444}
18445
015dc7e1 18446static bool
dda8d76d 18447process_nds32_specific (Filedata * filedata)
35c08157
KLC
18448{
18449 Elf_Internal_Shdr *sect = NULL;
18450
dda8d76d 18451 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 18452 if (sect != NULL && sect->sh_size >= 4)
35c08157 18453 {
9c7b8e9b
AM
18454 unsigned char *buf;
18455 unsigned int flag;
35c08157
KLC
18456
18457 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
18458 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
18459 _("NDS32 elf flags section"));
35c08157 18460
9c7b8e9b 18461 if (buf == NULL)
015dc7e1 18462 return false;
32ec8896 18463
9c7b8e9b
AM
18464 flag = byte_get (buf, 4);
18465 free (buf);
18466 switch (flag & 0x3)
35c08157
KLC
18467 {
18468 case 0:
18469 printf ("(VEC_SIZE):\tNo entry.\n");
18470 break;
18471 case 1:
18472 printf ("(VEC_SIZE):\t4 bytes\n");
18473 break;
18474 case 2:
18475 printf ("(VEC_SIZE):\t16 bytes\n");
18476 break;
18477 case 3:
18478 printf ("(VEC_SIZE):\treserved\n");
18479 break;
18480 }
18481 }
18482
015dc7e1 18483 return true;
35c08157
KLC
18484}
18485
015dc7e1 18486static bool
dda8d76d 18487process_gnu_liblist (Filedata * filedata)
047b2264 18488{
2cf0635d
NC
18489 Elf_Internal_Shdr * section;
18490 Elf_Internal_Shdr * string_sec;
18491 Elf32_External_Lib * elib;
18492 char * strtab;
c256ffe7 18493 size_t strtab_size;
047b2264 18494 size_t cnt;
d3a49aa8 18495 unsigned long num_liblist;
047b2264 18496 unsigned i;
015dc7e1 18497 bool res = true;
047b2264
JJ
18498
18499 if (! do_arch)
015dc7e1 18500 return true;
047b2264 18501
dda8d76d
NC
18502 for (i = 0, section = filedata->section_headers;
18503 i < filedata->file_header.e_shnum;
b34976b6 18504 i++, section++)
047b2264
JJ
18505 {
18506 switch (section->sh_type)
18507 {
18508 case SHT_GNU_LIBLIST:
dda8d76d 18509 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
18510 break;
18511
3f5e193b 18512 elib = (Elf32_External_Lib *)
dda8d76d 18513 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 18514 _("liblist section data"));
047b2264
JJ
18515
18516 if (elib == NULL)
32ec8896 18517 {
015dc7e1 18518 res = false;
32ec8896
NC
18519 break;
18520 }
047b2264 18521
dda8d76d
NC
18522 string_sec = filedata->section_headers + section->sh_link;
18523 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
18524 string_sec->sh_size,
18525 _("liblist string table"));
047b2264
JJ
18526 if (strtab == NULL
18527 || section->sh_entsize != sizeof (Elf32_External_Lib))
18528 {
18529 free (elib);
2842702f 18530 free (strtab);
015dc7e1 18531 res = false;
047b2264
JJ
18532 break;
18533 }
59245841 18534 strtab_size = string_sec->sh_size;
047b2264 18535
d3a49aa8
AM
18536 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
18537 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
18538 "\nLibrary list section '%s' contains %lu entries:\n",
18539 num_liblist),
dda8d76d 18540 printable_section_name (filedata, section),
d3a49aa8 18541 num_liblist);
047b2264 18542
2b692964 18543 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
18544
18545 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
18546 ++cnt)
18547 {
18548 Elf32_Lib liblist;
91d6fa6a 18549 time_t atime;
d5b07ef4 18550 char timebuf[128];
2cf0635d 18551 struct tm * tmp;
047b2264
JJ
18552
18553 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18554 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
18555 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18556 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18557 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18558
91d6fa6a 18559 tmp = gmtime (&atime);
e9e44622
JJ
18560 snprintf (timebuf, sizeof (timebuf),
18561 "%04u-%02u-%02uT%02u:%02u:%02u",
18562 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18563 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
18564
18565 printf ("%3lu: ", (unsigned long) cnt);
18566 if (do_wide)
c256ffe7 18567 printf ("%-20s", liblist.l_name < strtab_size
2b692964 18568 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 18569 else
c256ffe7 18570 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 18571 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
18572 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
18573 liblist.l_version, liblist.l_flags);
18574 }
18575
18576 free (elib);
2842702f 18577 free (strtab);
047b2264
JJ
18578 }
18579 }
18580
32ec8896 18581 return res;
047b2264
JJ
18582}
18583
9437c45b 18584static const char *
dda8d76d 18585get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
18586{
18587 static char buff[64];
103f02d3 18588
dda8d76d 18589 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
18590 switch (e_type)
18591 {
57346661 18592 case NT_AUXV:
1ec5cd37 18593 return _("NT_AUXV (auxiliary vector)");
57346661 18594 case NT_PRSTATUS:
1ec5cd37 18595 return _("NT_PRSTATUS (prstatus structure)");
57346661 18596 case NT_FPREGSET:
1ec5cd37 18597 return _("NT_FPREGSET (floating point registers)");
57346661 18598 case NT_PRPSINFO:
1ec5cd37 18599 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 18600 case NT_TASKSTRUCT:
1ec5cd37 18601 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
18602 case NT_GDB_TDESC:
18603 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 18604 case NT_PRXFPREG:
1ec5cd37 18605 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
18606 case NT_PPC_VMX:
18607 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
18608 case NT_PPC_VSX:
18609 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
18610 case NT_PPC_TAR:
18611 return _("NT_PPC_TAR (ppc TAR register)");
18612 case NT_PPC_PPR:
18613 return _("NT_PPC_PPR (ppc PPR register)");
18614 case NT_PPC_DSCR:
18615 return _("NT_PPC_DSCR (ppc DSCR register)");
18616 case NT_PPC_EBB:
18617 return _("NT_PPC_EBB (ppc EBB registers)");
18618 case NT_PPC_PMU:
18619 return _("NT_PPC_PMU (ppc PMU registers)");
18620 case NT_PPC_TM_CGPR:
18621 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
18622 case NT_PPC_TM_CFPR:
18623 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
18624 case NT_PPC_TM_CVMX:
18625 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
18626 case NT_PPC_TM_CVSX:
3fd21718 18627 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
18628 case NT_PPC_TM_SPR:
18629 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
18630 case NT_PPC_TM_CTAR:
18631 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
18632 case NT_PPC_TM_CPPR:
18633 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
18634 case NT_PPC_TM_CDSCR:
18635 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
18636 case NT_386_TLS:
18637 return _("NT_386_TLS (x86 TLS information)");
18638 case NT_386_IOPERM:
18639 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
18640 case NT_X86_XSTATE:
18641 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
18642 case NT_X86_CET:
18643 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
18644 case NT_S390_HIGH_GPRS:
18645 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
18646 case NT_S390_TIMER:
18647 return _("NT_S390_TIMER (s390 timer register)");
18648 case NT_S390_TODCMP:
18649 return _("NT_S390_TODCMP (s390 TOD comparator register)");
18650 case NT_S390_TODPREG:
18651 return _("NT_S390_TODPREG (s390 TOD programmable register)");
18652 case NT_S390_CTRS:
18653 return _("NT_S390_CTRS (s390 control registers)");
18654 case NT_S390_PREFIX:
18655 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
18656 case NT_S390_LAST_BREAK:
18657 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
18658 case NT_S390_SYSTEM_CALL:
18659 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
18660 case NT_S390_TDB:
18661 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
18662 case NT_S390_VXRS_LOW:
18663 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
18664 case NT_S390_VXRS_HIGH:
18665 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
18666 case NT_S390_GS_CB:
18667 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
18668 case NT_S390_GS_BC:
18669 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
18670 case NT_ARM_VFP:
18671 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
18672 case NT_ARM_TLS:
18673 return _("NT_ARM_TLS (AArch TLS registers)");
18674 case NT_ARM_HW_BREAK:
18675 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
18676 case NT_ARM_HW_WATCH:
18677 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
3b2bef8b
LM
18678 case NT_ARM_SVE:
18679 return _("NT_ARM_SVE (AArch SVE registers)");
18680 case NT_ARM_PAC_MASK:
18681 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
18682 case NT_ARM_TAGGED_ADDR_CTRL:
18683 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
27456742
AK
18684 case NT_ARC_V2:
18685 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
18686 case NT_RISCV_CSR:
18687 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 18688 case NT_PSTATUS:
1ec5cd37 18689 return _("NT_PSTATUS (pstatus structure)");
57346661 18690 case NT_FPREGS:
1ec5cd37 18691 return _("NT_FPREGS (floating point registers)");
57346661 18692 case NT_PSINFO:
1ec5cd37 18693 return _("NT_PSINFO (psinfo structure)");
57346661 18694 case NT_LWPSTATUS:
1ec5cd37 18695 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 18696 case NT_LWPSINFO:
1ec5cd37 18697 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 18698 case NT_WIN32PSTATUS:
1ec5cd37 18699 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
18700 case NT_SIGINFO:
18701 return _("NT_SIGINFO (siginfo_t data)");
18702 case NT_FILE:
18703 return _("NT_FILE (mapped files)");
894982bf
LM
18704 case NT_MEMTAG:
18705 return _("NT_MEMTAG (memory tags)");
1ec5cd37
NC
18706 default:
18707 break;
18708 }
18709 else
18710 switch (e_type)
18711 {
18712 case NT_VERSION:
18713 return _("NT_VERSION (version)");
18714 case NT_ARCH:
18715 return _("NT_ARCH (architecture)");
9ef920e9 18716 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 18717 return _("OPEN");
9ef920e9 18718 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 18719 return _("func");
1ec5cd37
NC
18720 default:
18721 break;
18722 }
18723
e9e44622 18724 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 18725 return buff;
779fe533
NC
18726}
18727
015dc7e1 18728static bool
9ece1fa9
TT
18729print_core_note (Elf_Internal_Note *pnote)
18730{
18731 unsigned int addr_size = is_32bit_elf ? 4 : 8;
18732 bfd_vma count, page_size;
18733 unsigned char *descdata, *filenames, *descend;
18734
18735 if (pnote->type != NT_FILE)
04ac15ab
AS
18736 {
18737 if (do_wide)
18738 printf ("\n");
015dc7e1 18739 return true;
04ac15ab 18740 }
9ece1fa9
TT
18741
18742#ifndef BFD64
18743 if (!is_32bit_elf)
18744 {
18745 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
18746 /* Still "successful". */
015dc7e1 18747 return true;
9ece1fa9
TT
18748 }
18749#endif
18750
18751 if (pnote->descsz < 2 * addr_size)
18752 {
32ec8896 18753 error (_(" Malformed note - too short for header\n"));
015dc7e1 18754 return false;
9ece1fa9
TT
18755 }
18756
18757 descdata = (unsigned char *) pnote->descdata;
18758 descend = descdata + pnote->descsz;
18759
18760 if (descdata[pnote->descsz - 1] != '\0')
18761 {
32ec8896 18762 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 18763 return false;
9ece1fa9
TT
18764 }
18765
18766 count = byte_get (descdata, addr_size);
18767 descdata += addr_size;
18768
18769 page_size = byte_get (descdata, addr_size);
18770 descdata += addr_size;
18771
5396a86e
AM
18772 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
18773 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 18774 {
32ec8896 18775 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 18776 return false;
9ece1fa9
TT
18777 }
18778
18779 printf (_(" Page size: "));
18780 print_vma (page_size, DEC);
18781 printf ("\n");
18782
18783 printf (_(" %*s%*s%*s\n"),
18784 (int) (2 + 2 * addr_size), _("Start"),
18785 (int) (4 + 2 * addr_size), _("End"),
18786 (int) (4 + 2 * addr_size), _("Page Offset"));
18787 filenames = descdata + count * 3 * addr_size;
595712bb 18788 while (count-- > 0)
9ece1fa9
TT
18789 {
18790 bfd_vma start, end, file_ofs;
18791
18792 if (filenames == descend)
18793 {
32ec8896 18794 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 18795 return false;
9ece1fa9
TT
18796 }
18797
18798 start = byte_get (descdata, addr_size);
18799 descdata += addr_size;
18800 end = byte_get (descdata, addr_size);
18801 descdata += addr_size;
18802 file_ofs = byte_get (descdata, addr_size);
18803 descdata += addr_size;
18804
18805 printf (" ");
18806 print_vma (start, FULL_HEX);
18807 printf (" ");
18808 print_vma (end, FULL_HEX);
18809 printf (" ");
18810 print_vma (file_ofs, FULL_HEX);
18811 printf ("\n %s\n", filenames);
18812
18813 filenames += 1 + strlen ((char *) filenames);
18814 }
18815
015dc7e1 18816 return true;
9ece1fa9
TT
18817}
18818
1118d252
RM
18819static const char *
18820get_gnu_elf_note_type (unsigned e_type)
18821{
1449284b 18822 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
18823 switch (e_type)
18824 {
18825 case NT_GNU_ABI_TAG:
18826 return _("NT_GNU_ABI_TAG (ABI version tag)");
18827 case NT_GNU_HWCAP:
18828 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
18829 case NT_GNU_BUILD_ID:
18830 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
18831 case NT_GNU_GOLD_VERSION:
18832 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
18833 case NT_GNU_PROPERTY_TYPE_0:
18834 return _("NT_GNU_PROPERTY_TYPE_0");
18835 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
18836 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
18837 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
18838 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 18839 default:
1449284b
NC
18840 {
18841 static char buff[64];
1118d252 18842
1449284b
NC
18843 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18844 return buff;
18845 }
18846 }
1118d252
RM
18847}
18848
a9eafb08
L
18849static void
18850decode_x86_compat_isa (unsigned int bitmask)
18851{
18852 while (bitmask)
18853 {
18854 unsigned int bit = bitmask & (- bitmask);
18855
18856 bitmask &= ~ bit;
18857 switch (bit)
18858 {
18859 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
18860 printf ("i486");
18861 break;
18862 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
18863 printf ("586");
18864 break;
18865 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
18866 printf ("686");
18867 break;
18868 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
18869 printf ("SSE");
18870 break;
18871 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
18872 printf ("SSE2");
18873 break;
18874 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
18875 printf ("SSE3");
18876 break;
18877 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
18878 printf ("SSSE3");
18879 break;
18880 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
18881 printf ("SSE4_1");
18882 break;
18883 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
18884 printf ("SSE4_2");
18885 break;
18886 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
18887 printf ("AVX");
18888 break;
18889 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
18890 printf ("AVX2");
18891 break;
18892 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
18893 printf ("AVX512F");
18894 break;
18895 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
18896 printf ("AVX512CD");
18897 break;
18898 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
18899 printf ("AVX512ER");
18900 break;
18901 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
18902 printf ("AVX512PF");
18903 break;
18904 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
18905 printf ("AVX512VL");
18906 break;
18907 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
18908 printf ("AVX512DQ");
18909 break;
18910 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
18911 printf ("AVX512BW");
18912 break;
65b3d26e
L
18913 default:
18914 printf (_("<unknown: %x>"), bit);
18915 break;
a9eafb08
L
18916 }
18917 if (bitmask)
18918 printf (", ");
18919 }
18920}
18921
9ef920e9 18922static void
32930e4e 18923decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 18924{
0a59decb 18925 if (!bitmask)
90c745dc
L
18926 {
18927 printf (_("<None>"));
18928 return;
18929 }
90c745dc 18930
9ef920e9
NC
18931 while (bitmask)
18932 {
1fc87489 18933 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
18934
18935 bitmask &= ~ bit;
18936 switch (bit)
18937 {
32930e4e 18938 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
18939 printf ("CMOV");
18940 break;
32930e4e 18941 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
18942 printf ("SSE");
18943 break;
32930e4e 18944 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
18945 printf ("SSE2");
18946 break;
32930e4e 18947 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
18948 printf ("SSE3");
18949 break;
32930e4e 18950 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
18951 printf ("SSSE3");
18952 break;
32930e4e 18953 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
18954 printf ("SSE4_1");
18955 break;
32930e4e 18956 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
18957 printf ("SSE4_2");
18958 break;
32930e4e 18959 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
18960 printf ("AVX");
18961 break;
32930e4e 18962 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
18963 printf ("AVX2");
18964 break;
32930e4e 18965 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
18966 printf ("FMA");
18967 break;
32930e4e 18968 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
18969 printf ("AVX512F");
18970 break;
32930e4e 18971 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
18972 printf ("AVX512CD");
18973 break;
32930e4e 18974 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
18975 printf ("AVX512ER");
18976 break;
32930e4e 18977 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
18978 printf ("AVX512PF");
18979 break;
32930e4e 18980 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
18981 printf ("AVX512VL");
18982 break;
32930e4e 18983 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
18984 printf ("AVX512DQ");
18985 break;
32930e4e 18986 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
18987 printf ("AVX512BW");
18988 break;
32930e4e 18989 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
18990 printf ("AVX512_4FMAPS");
18991 break;
32930e4e 18992 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
18993 printf ("AVX512_4VNNIW");
18994 break;
32930e4e 18995 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
18996 printf ("AVX512_BITALG");
18997 break;
32930e4e 18998 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
18999 printf ("AVX512_IFMA");
19000 break;
32930e4e 19001 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19002 printf ("AVX512_VBMI");
19003 break;
32930e4e 19004 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19005 printf ("AVX512_VBMI2");
19006 break;
32930e4e 19007 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19008 printf ("AVX512_VNNI");
19009 break;
32930e4e 19010 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19011 printf ("AVX512_BF16");
19012 break;
65b3d26e
L
19013 default:
19014 printf (_("<unknown: %x>"), bit);
19015 break;
9ef920e9
NC
19016 }
19017 if (bitmask)
19018 printf (", ");
19019 }
19020}
19021
32930e4e
L
19022static void
19023decode_x86_isa (unsigned int bitmask)
19024{
32930e4e
L
19025 while (bitmask)
19026 {
19027 unsigned int bit = bitmask & (- bitmask);
19028
19029 bitmask &= ~ bit;
19030 switch (bit)
19031 {
b0ab0693
L
19032 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19033 printf ("x86-64-baseline");
19034 break;
32930e4e
L
19035 case GNU_PROPERTY_X86_ISA_1_V2:
19036 printf ("x86-64-v2");
19037 break;
19038 case GNU_PROPERTY_X86_ISA_1_V3:
19039 printf ("x86-64-v3");
19040 break;
19041 case GNU_PROPERTY_X86_ISA_1_V4:
19042 printf ("x86-64-v4");
19043 break;
19044 default:
19045 printf (_("<unknown: %x>"), bit);
19046 break;
19047 }
19048 if (bitmask)
19049 printf (", ");
19050 }
19051}
19052
ee2fdd6f 19053static void
a9eafb08 19054decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19055{
0a59decb 19056 if (!bitmask)
90c745dc
L
19057 {
19058 printf (_("<None>"));
19059 return;
19060 }
90c745dc 19061
ee2fdd6f
L
19062 while (bitmask)
19063 {
19064 unsigned int bit = bitmask & (- bitmask);
19065
19066 bitmask &= ~ bit;
19067 switch (bit)
19068 {
19069 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19070 printf ("IBT");
ee2fdd6f 19071 break;
48580982 19072 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19073 printf ("SHSTK");
48580982 19074 break;
279d901e
L
19075 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19076 printf ("LAM_U48");
19077 break;
19078 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19079 printf ("LAM_U57");
19080 break;
ee2fdd6f
L
19081 default:
19082 printf (_("<unknown: %x>"), bit);
19083 break;
19084 }
19085 if (bitmask)
19086 printf (", ");
19087 }
19088}
19089
a9eafb08
L
19090static void
19091decode_x86_feature_2 (unsigned int bitmask)
19092{
0a59decb 19093 if (!bitmask)
90c745dc
L
19094 {
19095 printf (_("<None>"));
19096 return;
19097 }
90c745dc 19098
a9eafb08
L
19099 while (bitmask)
19100 {
19101 unsigned int bit = bitmask & (- bitmask);
19102
19103 bitmask &= ~ bit;
19104 switch (bit)
19105 {
19106 case GNU_PROPERTY_X86_FEATURE_2_X86:
19107 printf ("x86");
19108 break;
19109 case GNU_PROPERTY_X86_FEATURE_2_X87:
19110 printf ("x87");
19111 break;
19112 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19113 printf ("MMX");
19114 break;
19115 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19116 printf ("XMM");
19117 break;
19118 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19119 printf ("YMM");
19120 break;
19121 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19122 printf ("ZMM");
19123 break;
a308b89d
L
19124 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19125 printf ("TMM");
19126 break;
32930e4e
L
19127 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19128 printf ("MASK");
19129 break;
a9eafb08
L
19130 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19131 printf ("FXSR");
19132 break;
19133 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19134 printf ("XSAVE");
19135 break;
19136 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19137 printf ("XSAVEOPT");
19138 break;
19139 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19140 printf ("XSAVEC");
19141 break;
65b3d26e
L
19142 default:
19143 printf (_("<unknown: %x>"), bit);
19144 break;
a9eafb08
L
19145 }
19146 if (bitmask)
19147 printf (", ");
19148 }
19149}
19150
cd702818
SD
19151static void
19152decode_aarch64_feature_1_and (unsigned int bitmask)
19153{
19154 while (bitmask)
19155 {
19156 unsigned int bit = bitmask & (- bitmask);
19157
19158 bitmask &= ~ bit;
19159 switch (bit)
19160 {
19161 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19162 printf ("BTI");
19163 break;
19164
19165 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19166 printf ("PAC");
19167 break;
19168
19169 default:
19170 printf (_("<unknown: %x>"), bit);
19171 break;
19172 }
19173 if (bitmask)
19174 printf (", ");
19175 }
19176}
19177
9ef920e9 19178static void
dda8d76d 19179print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19180{
19181 unsigned char * ptr = (unsigned char *) pnote->descdata;
19182 unsigned char * ptr_end = ptr + pnote->descsz;
19183 unsigned int size = is_32bit_elf ? 4 : 8;
19184
19185 printf (_(" Properties: "));
19186
1fc87489 19187 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19188 {
19189 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19190 return;
19191 }
19192
6ab2c4ed 19193 while (ptr < ptr_end)
9ef920e9 19194 {
1fc87489 19195 unsigned int j;
6ab2c4ed
MC
19196 unsigned int type;
19197 unsigned int datasz;
19198
19199 if ((size_t) (ptr_end - ptr) < 8)
19200 {
19201 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19202 break;
19203 }
19204
19205 type = byte_get (ptr, 4);
19206 datasz = byte_get (ptr + 4, 4);
9ef920e9 19207
1fc87489 19208 ptr += 8;
9ef920e9 19209
6ab2c4ed 19210 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19211 {
1fc87489
L
19212 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19213 type, datasz);
9ef920e9 19214 break;
1fc87489 19215 }
9ef920e9 19216
1fc87489
L
19217 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19218 {
dda8d76d
NC
19219 if (filedata->file_header.e_machine == EM_X86_64
19220 || filedata->file_header.e_machine == EM_IAMCU
19221 || filedata->file_header.e_machine == EM_386)
1fc87489 19222 {
aa7bca9b
L
19223 unsigned int bitmask;
19224
19225 if (datasz == 4)
0a59decb 19226 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19227 else
19228 bitmask = 0;
19229
1fc87489
L
19230 switch (type)
19231 {
19232 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19233 if (datasz != 4)
aa7bca9b
L
19234 printf (_("x86 ISA used: <corrupt length: %#x> "),
19235 datasz);
1fc87489 19236 else
aa7bca9b
L
19237 {
19238 printf ("x86 ISA used: ");
19239 decode_x86_isa (bitmask);
19240 }
1fc87489 19241 goto next;
9ef920e9 19242
1fc87489 19243 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19244 if (datasz != 4)
aa7bca9b
L
19245 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19246 datasz);
1fc87489 19247 else
aa7bca9b
L
19248 {
19249 printf ("x86 ISA needed: ");
19250 decode_x86_isa (bitmask);
19251 }
1fc87489 19252 goto next;
9ef920e9 19253
ee2fdd6f 19254 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19255 if (datasz != 4)
aa7bca9b
L
19256 printf (_("x86 feature: <corrupt length: %#x> "),
19257 datasz);
ee2fdd6f 19258 else
aa7bca9b
L
19259 {
19260 printf ("x86 feature: ");
a9eafb08
L
19261 decode_x86_feature_1 (bitmask);
19262 }
19263 goto next;
19264
19265 case GNU_PROPERTY_X86_FEATURE_2_USED:
19266 if (datasz != 4)
19267 printf (_("x86 feature used: <corrupt length: %#x> "),
19268 datasz);
19269 else
19270 {
19271 printf ("x86 feature used: ");
19272 decode_x86_feature_2 (bitmask);
19273 }
19274 goto next;
19275
19276 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
19277 if (datasz != 4)
19278 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
19279 else
19280 {
19281 printf ("x86 feature needed: ");
19282 decode_x86_feature_2 (bitmask);
19283 }
19284 goto next;
19285
19286 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
19287 if (datasz != 4)
19288 printf (_("x86 ISA used: <corrupt length: %#x> "),
19289 datasz);
19290 else
19291 {
19292 printf ("x86 ISA used: ");
19293 decode_x86_compat_isa (bitmask);
19294 }
19295 goto next;
19296
19297 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
19298 if (datasz != 4)
19299 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19300 datasz);
19301 else
19302 {
19303 printf ("x86 ISA needed: ");
19304 decode_x86_compat_isa (bitmask);
aa7bca9b 19305 }
ee2fdd6f
L
19306 goto next;
19307
32930e4e
L
19308 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
19309 if (datasz != 4)
19310 printf (_("x86 ISA used: <corrupt length: %#x> "),
19311 datasz);
19312 else
19313 {
19314 printf ("x86 ISA used: ");
19315 decode_x86_compat_2_isa (bitmask);
19316 }
19317 goto next;
19318
19319 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
19320 if (datasz != 4)
19321 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19322 datasz);
19323 else
19324 {
19325 printf ("x86 ISA needed: ");
19326 decode_x86_compat_2_isa (bitmask);
19327 }
19328 goto next;
19329
1fc87489
L
19330 default:
19331 break;
19332 }
19333 }
cd702818
SD
19334 else if (filedata->file_header.e_machine == EM_AARCH64)
19335 {
19336 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
19337 {
19338 printf ("AArch64 feature: ");
19339 if (datasz != 4)
19340 printf (_("<corrupt length: %#x> "), datasz);
19341 else
19342 decode_aarch64_feature_1_and (byte_get (ptr, 4));
19343 goto next;
19344 }
19345 }
1fc87489
L
19346 }
19347 else
19348 {
19349 switch (type)
9ef920e9 19350 {
1fc87489
L
19351 case GNU_PROPERTY_STACK_SIZE:
19352 printf (_("stack size: "));
19353 if (datasz != size)
19354 printf (_("<corrupt length: %#x> "), datasz);
19355 else
19356 printf ("%#lx", (unsigned long) byte_get (ptr, size));
19357 goto next;
19358
19359 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
19360 printf ("no copy on protected ");
19361 if (datasz)
19362 printf (_("<corrupt length: %#x> "), datasz);
19363 goto next;
19364
19365 default:
9ef920e9
NC
19366 break;
19367 }
9ef920e9
NC
19368 }
19369
1fc87489
L
19370 if (type < GNU_PROPERTY_LOPROC)
19371 printf (_("<unknown type %#x data: "), type);
19372 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 19373 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
19374 else
19375 printf (_("<application-specific type %#x data: "), type);
19376 for (j = 0; j < datasz; ++j)
19377 printf ("%02x ", ptr[j] & 0xff);
19378 printf (">");
19379
dc1e8a47 19380 next:
9ef920e9 19381 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
19382 if (ptr == ptr_end)
19383 break;
1fc87489 19384
6ab2c4ed
MC
19385 if (do_wide)
19386 printf (", ");
19387 else
19388 printf ("\n\t");
9ef920e9
NC
19389 }
19390
19391 printf ("\n");
19392}
19393
015dc7e1 19394static bool
dda8d76d 19395print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 19396{
1449284b 19397 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
19398 switch (pnote->type)
19399 {
19400 case NT_GNU_BUILD_ID:
19401 {
19402 unsigned long i;
19403
19404 printf (_(" Build ID: "));
19405 for (i = 0; i < pnote->descsz; ++i)
19406 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 19407 printf ("\n");
664f90a3
TT
19408 }
19409 break;
19410
19411 case NT_GNU_ABI_TAG:
19412 {
19413 unsigned long os, major, minor, subminor;
19414 const char *osname;
19415
3102e897
NC
19416 /* PR 17531: file: 030-599401-0.004. */
19417 if (pnote->descsz < 16)
19418 {
19419 printf (_(" <corrupt GNU_ABI_TAG>\n"));
19420 break;
19421 }
19422
664f90a3
TT
19423 os = byte_get ((unsigned char *) pnote->descdata, 4);
19424 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19425 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
19426 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
19427
19428 switch (os)
19429 {
19430 case GNU_ABI_TAG_LINUX:
19431 osname = "Linux";
19432 break;
19433 case GNU_ABI_TAG_HURD:
19434 osname = "Hurd";
19435 break;
19436 case GNU_ABI_TAG_SOLARIS:
19437 osname = "Solaris";
19438 break;
19439 case GNU_ABI_TAG_FREEBSD:
19440 osname = "FreeBSD";
19441 break;
19442 case GNU_ABI_TAG_NETBSD:
19443 osname = "NetBSD";
19444 break;
14ae95f2
RM
19445 case GNU_ABI_TAG_SYLLABLE:
19446 osname = "Syllable";
19447 break;
19448 case GNU_ABI_TAG_NACL:
19449 osname = "NaCl";
19450 break;
664f90a3
TT
19451 default:
19452 osname = "Unknown";
19453 break;
19454 }
19455
19456 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
19457 major, minor, subminor);
19458 }
19459 break;
926c5385
CC
19460
19461 case NT_GNU_GOLD_VERSION:
19462 {
19463 unsigned long i;
19464
19465 printf (_(" Version: "));
19466 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
19467 printf ("%c", pnote->descdata[i]);
19468 printf ("\n");
19469 }
19470 break;
1449284b
NC
19471
19472 case NT_GNU_HWCAP:
19473 {
19474 unsigned long num_entries, mask;
19475
19476 /* Hardware capabilities information. Word 0 is the number of entries.
19477 Word 1 is a bitmask of enabled entries. The rest of the descriptor
19478 is a series of entries, where each entry is a single byte followed
19479 by a nul terminated string. The byte gives the bit number to test
19480 if enabled in the bitmask. */
19481 printf (_(" Hardware Capabilities: "));
19482 if (pnote->descsz < 8)
19483 {
32ec8896 19484 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 19485 return false;
1449284b
NC
19486 }
19487 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
19488 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19489 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
19490 /* FIXME: Add code to display the entries... */
19491 }
19492 break;
19493
9ef920e9 19494 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 19495 print_gnu_property_note (filedata, pnote);
9ef920e9 19496 break;
9abca702 19497
1449284b
NC
19498 default:
19499 /* Handle unrecognised types. An error message should have already been
19500 created by get_gnu_elf_note_type(), so all that we need to do is to
19501 display the data. */
19502 {
19503 unsigned long i;
19504
19505 printf (_(" Description data: "));
19506 for (i = 0; i < pnote->descsz; ++i)
19507 printf ("%02x ", pnote->descdata[i] & 0xff);
19508 printf ("\n");
19509 }
19510 break;
664f90a3
TT
19511 }
19512
015dc7e1 19513 return true;
664f90a3
TT
19514}
19515
685080f2
NC
19516static const char *
19517get_v850_elf_note_type (enum v850_notes n_type)
19518{
19519 static char buff[64];
19520
19521 switch (n_type)
19522 {
19523 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
19524 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
19525 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
19526 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
19527 case V850_NOTE_CACHE_INFO: return _("Use of cache");
19528 case V850_NOTE_MMU_INFO: return _("Use of MMU");
19529 default:
19530 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
19531 return buff;
19532 }
19533}
19534
015dc7e1 19535static bool
685080f2
NC
19536print_v850_note (Elf_Internal_Note * pnote)
19537{
19538 unsigned int val;
19539
19540 if (pnote->descsz != 4)
015dc7e1 19541 return false;
32ec8896 19542
685080f2
NC
19543 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
19544
19545 if (val == 0)
19546 {
19547 printf (_("not set\n"));
015dc7e1 19548 return true;
685080f2
NC
19549 }
19550
19551 switch (pnote->type)
19552 {
19553 case V850_NOTE_ALIGNMENT:
19554 switch (val)
19555 {
015dc7e1
AM
19556 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
19557 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
19558 }
19559 break;
14ae95f2 19560
685080f2
NC
19561 case V850_NOTE_DATA_SIZE:
19562 switch (val)
19563 {
015dc7e1
AM
19564 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
19565 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
19566 }
19567 break;
14ae95f2 19568
685080f2
NC
19569 case V850_NOTE_FPU_INFO:
19570 switch (val)
19571 {
015dc7e1
AM
19572 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
19573 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
19574 }
19575 break;
14ae95f2 19576
685080f2
NC
19577 case V850_NOTE_MMU_INFO:
19578 case V850_NOTE_CACHE_INFO:
19579 case V850_NOTE_SIMD_INFO:
19580 if (val == EF_RH850_SIMD)
19581 {
19582 printf (_("yes\n"));
015dc7e1 19583 return true;
685080f2
NC
19584 }
19585 break;
19586
19587 default:
19588 /* An 'unknown note type' message will already have been displayed. */
19589 break;
19590 }
19591
19592 printf (_("unknown value: %x\n"), val);
015dc7e1 19593 return false;
685080f2
NC
19594}
19595
015dc7e1 19596static bool
c6056a74
SF
19597process_netbsd_elf_note (Elf_Internal_Note * pnote)
19598{
19599 unsigned int version;
19600
19601 switch (pnote->type)
19602 {
19603 case NT_NETBSD_IDENT:
b966f55f
AM
19604 if (pnote->descsz < 1)
19605 break;
c6056a74
SF
19606 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19607 if ((version / 10000) % 100)
b966f55f 19608 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
19609 version, version / 100000000, (version / 1000000) % 100,
19610 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 19611 'A' + (version / 10000) % 26);
c6056a74
SF
19612 else
19613 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 19614 version, version / 100000000, (version / 1000000) % 100,
15f205b1 19615 (version / 100) % 100);
015dc7e1 19616 return true;
c6056a74
SF
19617
19618 case NT_NETBSD_MARCH:
9abca702 19619 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 19620 pnote->descdata);
015dc7e1 19621 return true;
c6056a74 19622
9abca702 19623 case NT_NETBSD_PAX:
b966f55f
AM
19624 if (pnote->descsz < 1)
19625 break;
9abca702
CZ
19626 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19627 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
19628 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
19629 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
19630 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
19631 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
19632 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
19633 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 19634 return true;
c6056a74 19635 }
b966f55f
AM
19636
19637 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
19638 pnote->descsz, pnote->type);
015dc7e1 19639 return false;
c6056a74
SF
19640}
19641
f4ddf30f 19642static const char *
dda8d76d 19643get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 19644{
f4ddf30f
JB
19645 switch (e_type)
19646 {
19647 case NT_FREEBSD_THRMISC:
19648 return _("NT_THRMISC (thrmisc structure)");
19649 case NT_FREEBSD_PROCSTAT_PROC:
19650 return _("NT_PROCSTAT_PROC (proc data)");
19651 case NT_FREEBSD_PROCSTAT_FILES:
19652 return _("NT_PROCSTAT_FILES (files data)");
19653 case NT_FREEBSD_PROCSTAT_VMMAP:
19654 return _("NT_PROCSTAT_VMMAP (vmmap data)");
19655 case NT_FREEBSD_PROCSTAT_GROUPS:
19656 return _("NT_PROCSTAT_GROUPS (groups data)");
19657 case NT_FREEBSD_PROCSTAT_UMASK:
19658 return _("NT_PROCSTAT_UMASK (umask data)");
19659 case NT_FREEBSD_PROCSTAT_RLIMIT:
19660 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
19661 case NT_FREEBSD_PROCSTAT_OSREL:
19662 return _("NT_PROCSTAT_OSREL (osreldate data)");
19663 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
19664 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
19665 case NT_FREEBSD_PROCSTAT_AUXV:
19666 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
19667 case NT_FREEBSD_PTLWPINFO:
19668 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 19669 }
dda8d76d 19670 return get_note_type (filedata, e_type);
f4ddf30f
JB
19671}
19672
9437c45b 19673static const char *
dda8d76d 19674get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
19675{
19676 static char buff[64];
19677
540e6170
CZ
19678 switch (e_type)
19679 {
19680 case NT_NETBSDCORE_PROCINFO:
19681 /* NetBSD core "procinfo" structure. */
19682 return _("NetBSD procinfo structure");
9437c45b 19683
540e6170
CZ
19684 case NT_NETBSDCORE_AUXV:
19685 return _("NetBSD ELF auxiliary vector data");
9437c45b 19686
06d949ec
KR
19687 case NT_NETBSDCORE_LWPSTATUS:
19688 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 19689
540e6170 19690 default:
06d949ec 19691 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
19692 defined for NetBSD core files. If the note type is less
19693 than the start of the machine-dependent note types, we don't
19694 understand it. */
19695
19696 if (e_type < NT_NETBSDCORE_FIRSTMACH)
19697 {
19698 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19699 return buff;
19700 }
19701 break;
9437c45b
JT
19702 }
19703
dda8d76d 19704 switch (filedata->file_header.e_machine)
9437c45b
JT
19705 {
19706 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
19707 and PT_GETFPREGS == mach+2. */
19708
19709 case EM_OLD_ALPHA:
19710 case EM_ALPHA:
19711 case EM_SPARC:
19712 case EM_SPARC32PLUS:
19713 case EM_SPARCV9:
19714 switch (e_type)
19715 {
2b692964 19716 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 19717 return _("PT_GETREGS (reg structure)");
2b692964 19718 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 19719 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19720 default:
19721 break;
19722 }
19723 break;
19724
c0d38b0e
CZ
19725 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
19726 There's also old PT___GETREGS40 == mach + 1 for old reg
19727 structure which lacks GBR. */
19728 case EM_SH:
19729 switch (e_type)
19730 {
19731 case NT_NETBSDCORE_FIRSTMACH + 1:
19732 return _("PT___GETREGS40 (old reg structure)");
19733 case NT_NETBSDCORE_FIRSTMACH + 3:
19734 return _("PT_GETREGS (reg structure)");
19735 case NT_NETBSDCORE_FIRSTMACH + 5:
19736 return _("PT_GETFPREGS (fpreg structure)");
19737 default:
19738 break;
19739 }
19740 break;
19741
9437c45b
JT
19742 /* On all other arch's, PT_GETREGS == mach+1 and
19743 PT_GETFPREGS == mach+3. */
19744 default:
19745 switch (e_type)
19746 {
2b692964 19747 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 19748 return _("PT_GETREGS (reg structure)");
2b692964 19749 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 19750 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19751 default:
19752 break;
19753 }
19754 }
19755
9cf03b7e 19756 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 19757 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
19758 return buff;
19759}
19760
70616151
TT
19761static const char *
19762get_stapsdt_note_type (unsigned e_type)
19763{
19764 static char buff[64];
19765
19766 switch (e_type)
19767 {
19768 case NT_STAPSDT:
19769 return _("NT_STAPSDT (SystemTap probe descriptors)");
19770
19771 default:
19772 break;
19773 }
19774
19775 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19776 return buff;
19777}
19778
015dc7e1 19779static bool
c6a9fc58
TT
19780print_stapsdt_note (Elf_Internal_Note *pnote)
19781{
3ca60c57
NC
19782 size_t len, maxlen;
19783 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
19784 char *data = pnote->descdata;
19785 char *data_end = pnote->descdata + pnote->descsz;
19786 bfd_vma pc, base_addr, semaphore;
19787 char *provider, *probe, *arg_fmt;
19788
3ca60c57
NC
19789 if (pnote->descsz < (addr_size * 3))
19790 goto stapdt_note_too_small;
19791
c6a9fc58
TT
19792 pc = byte_get ((unsigned char *) data, addr_size);
19793 data += addr_size;
3ca60c57 19794
c6a9fc58
TT
19795 base_addr = byte_get ((unsigned char *) data, addr_size);
19796 data += addr_size;
3ca60c57 19797
c6a9fc58
TT
19798 semaphore = byte_get ((unsigned char *) data, addr_size);
19799 data += addr_size;
19800
3ca60c57
NC
19801 if (data >= data_end)
19802 goto stapdt_note_too_small;
19803 maxlen = data_end - data;
19804 len = strnlen (data, maxlen);
19805 if (len < maxlen)
19806 {
19807 provider = data;
19808 data += len + 1;
19809 }
19810 else
19811 goto stapdt_note_too_small;
19812
19813 if (data >= data_end)
19814 goto stapdt_note_too_small;
19815 maxlen = data_end - data;
19816 len = strnlen (data, maxlen);
19817 if (len < maxlen)
19818 {
19819 probe = data;
19820 data += len + 1;
19821 }
19822 else
19823 goto stapdt_note_too_small;
9abca702 19824
3ca60c57
NC
19825 if (data >= data_end)
19826 goto stapdt_note_too_small;
19827 maxlen = data_end - data;
19828 len = strnlen (data, maxlen);
19829 if (len < maxlen)
19830 {
19831 arg_fmt = data;
19832 data += len + 1;
19833 }
19834 else
19835 goto stapdt_note_too_small;
c6a9fc58
TT
19836
19837 printf (_(" Provider: %s\n"), provider);
19838 printf (_(" Name: %s\n"), probe);
19839 printf (_(" Location: "));
19840 print_vma (pc, FULL_HEX);
19841 printf (_(", Base: "));
19842 print_vma (base_addr, FULL_HEX);
19843 printf (_(", Semaphore: "));
19844 print_vma (semaphore, FULL_HEX);
9cf03b7e 19845 printf ("\n");
c6a9fc58
TT
19846 printf (_(" Arguments: %s\n"), arg_fmt);
19847
19848 return data == data_end;
3ca60c57
NC
19849
19850 stapdt_note_too_small:
19851 printf (_(" <corrupt - note is too small>\n"));
19852 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 19853 return false;
c6a9fc58
TT
19854}
19855
00e98fc7
TG
19856static const char *
19857get_ia64_vms_note_type (unsigned e_type)
19858{
19859 static char buff[64];
19860
19861 switch (e_type)
19862 {
19863 case NT_VMS_MHD:
19864 return _("NT_VMS_MHD (module header)");
19865 case NT_VMS_LNM:
19866 return _("NT_VMS_LNM (language name)");
19867 case NT_VMS_SRC:
19868 return _("NT_VMS_SRC (source files)");
19869 case NT_VMS_TITLE:
9cf03b7e 19870 return "NT_VMS_TITLE";
00e98fc7
TG
19871 case NT_VMS_EIDC:
19872 return _("NT_VMS_EIDC (consistency check)");
19873 case NT_VMS_FPMODE:
19874 return _("NT_VMS_FPMODE (FP mode)");
19875 case NT_VMS_LINKTIME:
9cf03b7e 19876 return "NT_VMS_LINKTIME";
00e98fc7
TG
19877 case NT_VMS_IMGNAM:
19878 return _("NT_VMS_IMGNAM (image name)");
19879 case NT_VMS_IMGID:
19880 return _("NT_VMS_IMGID (image id)");
19881 case NT_VMS_LINKID:
19882 return _("NT_VMS_LINKID (link id)");
19883 case NT_VMS_IMGBID:
19884 return _("NT_VMS_IMGBID (build id)");
19885 case NT_VMS_GSTNAM:
19886 return _("NT_VMS_GSTNAM (sym table name)");
19887 case NT_VMS_ORIG_DYN:
9cf03b7e 19888 return "NT_VMS_ORIG_DYN";
00e98fc7 19889 case NT_VMS_PATCHTIME:
9cf03b7e 19890 return "NT_VMS_PATCHTIME";
00e98fc7
TG
19891 default:
19892 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19893 return buff;
19894 }
19895}
19896
015dc7e1 19897static bool
00e98fc7
TG
19898print_ia64_vms_note (Elf_Internal_Note * pnote)
19899{
8d18bf79
NC
19900 int maxlen = pnote->descsz;
19901
19902 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
19903 goto desc_size_fail;
19904
00e98fc7
TG
19905 switch (pnote->type)
19906 {
19907 case NT_VMS_MHD:
8d18bf79
NC
19908 if (maxlen <= 36)
19909 goto desc_size_fail;
19910
19911 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
19912
19913 printf (_(" Creation date : %.17s\n"), pnote->descdata);
19914 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
19915 if (l + 34 < maxlen)
19916 {
19917 printf (_(" Module name : %s\n"), pnote->descdata + 34);
19918 if (l + 35 < maxlen)
19919 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
19920 else
19921 printf (_(" Module version : <missing>\n"));
19922 }
00e98fc7 19923 else
8d18bf79
NC
19924 {
19925 printf (_(" Module name : <missing>\n"));
19926 printf (_(" Module version : <missing>\n"));
19927 }
00e98fc7 19928 break;
8d18bf79 19929
00e98fc7 19930 case NT_VMS_LNM:
8d18bf79 19931 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19932 break;
8d18bf79 19933
00e98fc7
TG
19934#ifdef BFD64
19935 case NT_VMS_FPMODE:
9cf03b7e 19936 printf (_(" Floating Point mode: "));
8d18bf79
NC
19937 if (maxlen < 8)
19938 goto desc_size_fail;
19939 /* FIXME: Generate an error if descsz > 8 ? */
19940
4a5cb34f 19941 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 19942 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 19943 break;
8d18bf79 19944
00e98fc7
TG
19945 case NT_VMS_LINKTIME:
19946 printf (_(" Link time: "));
8d18bf79
NC
19947 if (maxlen < 8)
19948 goto desc_size_fail;
19949 /* FIXME: Generate an error if descsz > 8 ? */
19950
00e98fc7 19951 print_vms_time
8d18bf79 19952 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19953 printf ("\n");
19954 break;
8d18bf79 19955
00e98fc7
TG
19956 case NT_VMS_PATCHTIME:
19957 printf (_(" Patch time: "));
8d18bf79
NC
19958 if (maxlen < 8)
19959 goto desc_size_fail;
19960 /* FIXME: Generate an error if descsz > 8 ? */
19961
00e98fc7 19962 print_vms_time
8d18bf79 19963 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19964 printf ("\n");
19965 break;
8d18bf79 19966
00e98fc7 19967 case NT_VMS_ORIG_DYN:
8d18bf79
NC
19968 if (maxlen < 34)
19969 goto desc_size_fail;
19970
00e98fc7
TG
19971 printf (_(" Major id: %u, minor id: %u\n"),
19972 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
19973 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 19974 printf (_(" Last modified : "));
00e98fc7
TG
19975 print_vms_time
19976 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 19977 printf (_("\n Link flags : "));
4a5cb34f 19978 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 19979 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 19980 printf (_(" Header flags: 0x%08x\n"),
948f632f 19981 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 19982 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
19983 break;
19984#endif
8d18bf79 19985
00e98fc7 19986 case NT_VMS_IMGNAM:
8d18bf79 19987 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19988 break;
8d18bf79 19989
00e98fc7 19990 case NT_VMS_GSTNAM:
8d18bf79 19991 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19992 break;
8d18bf79 19993
00e98fc7 19994 case NT_VMS_IMGID:
8d18bf79 19995 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19996 break;
8d18bf79 19997
00e98fc7 19998 case NT_VMS_LINKID:
8d18bf79 19999 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20000 break;
8d18bf79 20001
00e98fc7 20002 default:
015dc7e1 20003 return false;
00e98fc7 20004 }
8d18bf79 20005
015dc7e1 20006 return true;
8d18bf79
NC
20007
20008 desc_size_fail:
20009 printf (_(" <corrupt - data size is too small>\n"));
20010 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20011 return false;
00e98fc7
TG
20012}
20013
fd486f32
AM
20014struct build_attr_cache {
20015 Filedata *filedata;
20016 char *strtab;
20017 unsigned long strtablen;
20018 Elf_Internal_Sym *symtab;
20019 unsigned long nsyms;
20020} ba_cache;
20021
6f156d7a
NC
20022/* Find the symbol associated with a build attribute that is attached
20023 to address OFFSET. If PNAME is non-NULL then store the name of
20024 the symbol (if found) in the provided pointer, Returns NULL if a
20025 symbol could not be found. */
c799a79d 20026
6f156d7a 20027static Elf_Internal_Sym *
015dc7e1
AM
20028get_symbol_for_build_attribute (Filedata *filedata,
20029 unsigned long offset,
20030 bool is_open_attr,
20031 const char **pname)
9ef920e9 20032{
fd486f32
AM
20033 Elf_Internal_Sym *saved_sym = NULL;
20034 Elf_Internal_Sym *sym;
9ef920e9 20035
dda8d76d 20036 if (filedata->section_headers != NULL
fd486f32 20037 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20038 {
c799a79d 20039 Elf_Internal_Shdr * symsec;
9ef920e9 20040
fd486f32
AM
20041 free (ba_cache.strtab);
20042 ba_cache.strtab = NULL;
20043 free (ba_cache.symtab);
20044 ba_cache.symtab = NULL;
20045
c799a79d 20046 /* Load the symbol and string sections. */
dda8d76d
NC
20047 for (symsec = filedata->section_headers;
20048 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20049 symsec ++)
9ef920e9 20050 {
28d13567
AM
20051 if (symsec->sh_type == SHT_SYMTAB
20052 && get_symtab (filedata, symsec,
20053 &ba_cache.symtab, &ba_cache.nsyms,
20054 &ba_cache.strtab, &ba_cache.strtablen))
20055 break;
9ef920e9 20056 }
fd486f32 20057 ba_cache.filedata = filedata;
9ef920e9
NC
20058 }
20059
fd486f32 20060 if (ba_cache.symtab == NULL)
6f156d7a 20061 return NULL;
9ef920e9 20062
c799a79d 20063 /* Find a symbol whose value matches offset. */
fd486f32 20064 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20065 if (sym->st_value == offset)
20066 {
fd486f32 20067 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20068 /* Huh ? This should not happen. */
20069 continue;
9ef920e9 20070
fd486f32 20071 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20072 continue;
9ef920e9 20073
8fd75781
NC
20074 /* The AArch64 and ARM architectures define mapping symbols
20075 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20076 if (ba_cache.strtab[sym->st_name] == '$'
20077 && ba_cache.strtab[sym->st_name + 1] != 0
20078 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20079 continue;
20080
c799a79d
NC
20081 if (is_open_attr)
20082 {
20083 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20084 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20085 FUNC symbols entirely. */
20086 switch (ELF_ST_TYPE (sym->st_info))
20087 {
c799a79d 20088 case STT_OBJECT:
6f156d7a 20089 case STT_FILE:
c799a79d 20090 saved_sym = sym;
6f156d7a
NC
20091 if (sym->st_size)
20092 {
20093 /* If the symbol has a size associated
20094 with it then we can stop searching. */
fd486f32 20095 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20096 }
c799a79d 20097 continue;
9ef920e9 20098
c799a79d
NC
20099 case STT_FUNC:
20100 /* Ignore function symbols. */
20101 continue;
20102
20103 default:
20104 break;
20105 }
20106
20107 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20108 {
c799a79d
NC
20109 case STB_GLOBAL:
20110 if (saved_sym == NULL
20111 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20112 saved_sym = sym;
20113 break;
c871dade 20114
c799a79d
NC
20115 case STB_LOCAL:
20116 if (saved_sym == NULL)
20117 saved_sym = sym;
20118 break;
20119
20120 default:
9ef920e9
NC
20121 break;
20122 }
20123 }
c799a79d
NC
20124 else
20125 {
20126 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20127 continue;
20128
20129 saved_sym = sym;
20130 break;
20131 }
20132 }
20133
6f156d7a 20134 if (saved_sym && pname)
fd486f32 20135 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20136
20137 return saved_sym;
c799a79d
NC
20138}
20139
d20e98ab
NC
20140/* Returns true iff addr1 and addr2 are in the same section. */
20141
015dc7e1 20142static bool
d20e98ab
NC
20143same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20144{
20145 Elf_Internal_Shdr * a1;
20146 Elf_Internal_Shdr * a2;
20147
20148 a1 = find_section_by_address (filedata, addr1);
20149 a2 = find_section_by_address (filedata, addr2);
9abca702 20150
d20e98ab
NC
20151 return a1 == a2 && a1 != NULL;
20152}
20153
015dc7e1 20154static bool
dda8d76d
NC
20155print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20156 Filedata * filedata)
c799a79d 20157{
015dc7e1
AM
20158 static unsigned long global_offset = 0;
20159 static unsigned long global_end = 0;
20160 static unsigned long func_offset = 0;
20161 static unsigned long func_end = 0;
c871dade 20162
015dc7e1
AM
20163 Elf_Internal_Sym *sym;
20164 const char *name;
20165 unsigned long start;
20166 unsigned long end;
20167 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20168
20169 switch (pnote->descsz)
c799a79d 20170 {
6f156d7a
NC
20171 case 0:
20172 /* A zero-length description means that the range of
20173 the previous note of the same type should be used. */
c799a79d 20174 if (is_open_attr)
c871dade 20175 {
6f156d7a
NC
20176 if (global_end > global_offset)
20177 printf (_(" Applies to region from %#lx to %#lx\n"),
20178 global_offset, global_end);
20179 else
20180 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20181 }
20182 else
20183 {
6f156d7a
NC
20184 if (func_end > func_offset)
20185 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20186 else
20187 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20188 }
015dc7e1 20189 return true;
9ef920e9 20190
6f156d7a
NC
20191 case 4:
20192 start = byte_get ((unsigned char *) pnote->descdata, 4);
20193 end = 0;
20194 break;
20195
20196 case 8:
c74147bb
NC
20197 start = byte_get ((unsigned char *) pnote->descdata, 4);
20198 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20199 break;
20200
20201 case 16:
20202 start = byte_get ((unsigned char *) pnote->descdata, 8);
20203 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20204 break;
9abca702 20205
6f156d7a 20206 default:
c799a79d
NC
20207 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
20208 printf (_(" <invalid descsz>"));
015dc7e1 20209 return false;
c799a79d
NC
20210 }
20211
6f156d7a
NC
20212 name = NULL;
20213 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
20214 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
20215 in order to avoid them being confused with the start address of the
20216 first function in the file... */
20217 if (sym == NULL && is_open_attr)
20218 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
20219 & name);
6f156d7a
NC
20220
20221 if (end == 0 && sym != NULL && sym->st_size > 0)
20222 end = start + sym->st_size;
c799a79d
NC
20223
20224 if (is_open_attr)
20225 {
d20e98ab
NC
20226 /* FIXME: Need to properly allow for section alignment.
20227 16 is just the alignment used on x86_64. */
20228 if (global_end > 0
20229 && start > BFD_ALIGN (global_end, 16)
20230 /* Build notes are not guaranteed to be organised in order of
20231 increasing address, but we should find the all of the notes
20232 for one section in the same place. */
20233 && same_section (filedata, start, global_end))
6f156d7a
NC
20234 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
20235 global_end + 1, start - 1);
20236
20237 printf (_(" Applies to region from %#lx"), start);
20238 global_offset = start;
20239
20240 if (end)
20241 {
20242 printf (_(" to %#lx"), end);
20243 global_end = end;
20244 }
c799a79d
NC
20245 }
20246 else
20247 {
6f156d7a
NC
20248 printf (_(" Applies to region from %#lx"), start);
20249 func_offset = start;
20250
20251 if (end)
20252 {
20253 printf (_(" to %#lx"), end);
20254 func_end = end;
20255 }
c799a79d
NC
20256 }
20257
6f156d7a
NC
20258 if (sym && name)
20259 printf (_(" (%s)"), name);
20260
20261 printf ("\n");
015dc7e1 20262 return true;
9ef920e9
NC
20263}
20264
015dc7e1 20265static bool
9ef920e9
NC
20266print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
20267{
1d15e434
NC
20268 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
20269 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
20270 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
20271 char name_type;
20272 char name_attribute;
1d15e434 20273 const char * expected_types;
9ef920e9
NC
20274 const char * name = pnote->namedata;
20275 const char * text;
88305e1b 20276 signed int left;
9ef920e9
NC
20277
20278 if (name == NULL || pnote->namesz < 2)
20279 {
20280 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 20281 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20282 return false;
9ef920e9
NC
20283 }
20284
6f156d7a
NC
20285 if (do_wide)
20286 left = 28;
20287 else
20288 left = 20;
88305e1b
NC
20289
20290 /* Version 2 of the spec adds a "GA" prefix to the name field. */
20291 if (name[0] == 'G' && name[1] == 'A')
20292 {
6f156d7a
NC
20293 if (pnote->namesz < 4)
20294 {
20295 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
20296 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20297 return false;
6f156d7a
NC
20298 }
20299
88305e1b
NC
20300 printf ("GA");
20301 name += 2;
20302 left -= 2;
20303 }
20304
9ef920e9
NC
20305 switch ((name_type = * name))
20306 {
20307 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20308 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20309 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20310 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20311 printf ("%c", * name);
88305e1b 20312 left --;
9ef920e9
NC
20313 break;
20314 default:
20315 error (_("unrecognised attribute type in name field: %d\n"), name_type);
20316 print_symbol (-20, _("<unknown name type>"));
015dc7e1 20317 return false;
9ef920e9
NC
20318 }
20319
9ef920e9
NC
20320 ++ name;
20321 text = NULL;
20322
20323 switch ((name_attribute = * name))
20324 {
20325 case GNU_BUILD_ATTRIBUTE_VERSION:
20326 text = _("<version>");
1d15e434 20327 expected_types = string_expected;
9ef920e9
NC
20328 ++ name;
20329 break;
20330 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20331 text = _("<stack prot>");
75d7d298 20332 expected_types = "!+*";
9ef920e9
NC
20333 ++ name;
20334 break;
20335 case GNU_BUILD_ATTRIBUTE_RELRO:
20336 text = _("<relro>");
1d15e434 20337 expected_types = bool_expected;
9ef920e9
NC
20338 ++ name;
20339 break;
20340 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
20341 text = _("<stack size>");
1d15e434 20342 expected_types = number_expected;
9ef920e9
NC
20343 ++ name;
20344 break;
20345 case GNU_BUILD_ATTRIBUTE_TOOL:
20346 text = _("<tool>");
1d15e434 20347 expected_types = string_expected;
9ef920e9
NC
20348 ++ name;
20349 break;
20350 case GNU_BUILD_ATTRIBUTE_ABI:
20351 text = _("<ABI>");
20352 expected_types = "$*";
20353 ++ name;
20354 break;
20355 case GNU_BUILD_ATTRIBUTE_PIC:
20356 text = _("<PIC>");
1d15e434 20357 expected_types = number_expected;
9ef920e9
NC
20358 ++ name;
20359 break;
a8be5506
NC
20360 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
20361 text = _("<short enum>");
1d15e434 20362 expected_types = bool_expected;
a8be5506
NC
20363 ++ name;
20364 break;
9ef920e9
NC
20365 default:
20366 if (ISPRINT (* name))
20367 {
20368 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
20369
20370 if (len > left && ! do_wide)
20371 len = left;
75d7d298 20372 printf ("%.*s:", len, name);
9ef920e9 20373 left -= len;
0dd6ae21 20374 name += len;
9ef920e9
NC
20375 }
20376 else
20377 {
3e6b6445 20378 static char tmpbuf [128];
88305e1b 20379
3e6b6445
NC
20380 error (_("unrecognised byte in name field: %d\n"), * name);
20381 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
20382 text = tmpbuf;
20383 name ++;
9ef920e9
NC
20384 }
20385 expected_types = "*$!+";
20386 break;
20387 }
20388
20389 if (text)
88305e1b 20390 left -= printf ("%s", text);
9ef920e9
NC
20391
20392 if (strchr (expected_types, name_type) == NULL)
75d7d298 20393 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
20394
20395 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
20396 {
20397 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
20398 (unsigned long) pnote->namesz,
20399 (long) (name - pnote->namedata));
015dc7e1 20400 return false;
9ef920e9
NC
20401 }
20402
20403 if (left < 1 && ! do_wide)
015dc7e1 20404 return true;
9ef920e9
NC
20405
20406 switch (name_type)
20407 {
20408 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20409 {
b06b2c92 20410 unsigned int bytes;
ddef72cd
NC
20411 unsigned long long val = 0;
20412 unsigned int shift = 0;
20413 char * decoded = NULL;
20414
b06b2c92
NC
20415 bytes = pnote->namesz - (name - pnote->namedata);
20416 if (bytes > 0)
20417 /* The -1 is because the name field is always 0 terminated, and we
20418 want to be able to ensure that the shift in the while loop below
20419 will not overflow. */
20420 -- bytes;
20421
ddef72cd
NC
20422 if (bytes > sizeof (val))
20423 {
3e6b6445
NC
20424 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
20425 bytes);
20426 bytes = sizeof (val);
ddef72cd 20427 }
3e6b6445
NC
20428 /* We do not bother to warn if bytes == 0 as this can
20429 happen with some early versions of the gcc plugin. */
9ef920e9
NC
20430
20431 while (bytes --)
20432 {
54b8331d 20433 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
20434
20435 val |= byte << shift;
9ef920e9
NC
20436 shift += 8;
20437 }
20438
75d7d298 20439 switch (name_attribute)
9ef920e9 20440 {
75d7d298 20441 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
20442 switch (val)
20443 {
75d7d298
NC
20444 case 0: decoded = "static"; break;
20445 case 1: decoded = "pic"; break;
20446 case 2: decoded = "PIC"; break;
20447 case 3: decoded = "pie"; break;
20448 case 4: decoded = "PIE"; break;
20449 default: break;
9ef920e9 20450 }
75d7d298
NC
20451 break;
20452 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20453 switch (val)
9ef920e9 20454 {
75d7d298
NC
20455 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
20456 case 0: decoded = "off"; break;
20457 case 1: decoded = "on"; break;
20458 case 2: decoded = "all"; break;
20459 case 3: decoded = "strong"; break;
20460 case 4: decoded = "explicit"; break;
20461 default: break;
9ef920e9 20462 }
75d7d298
NC
20463 break;
20464 default:
20465 break;
9ef920e9
NC
20466 }
20467
75d7d298 20468 if (decoded != NULL)
3e6b6445
NC
20469 {
20470 print_symbol (-left, decoded);
20471 left = 0;
20472 }
20473 else if (val == 0)
20474 {
20475 printf ("0x0");
20476 left -= 3;
20477 }
9ef920e9 20478 else
75d7d298
NC
20479 {
20480 if (do_wide)
ddef72cd 20481 left -= printf ("0x%llx", val);
75d7d298 20482 else
ddef72cd 20483 left -= printf ("0x%-.*llx", left, val);
75d7d298 20484 }
9ef920e9
NC
20485 }
20486 break;
20487 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20488 left -= print_symbol (- left, name);
20489 break;
20490 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20491 left -= print_symbol (- left, "true");
20492 break;
20493 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20494 left -= print_symbol (- left, "false");
20495 break;
20496 }
20497
20498 if (do_wide && left > 0)
20499 printf ("%-*s", left, " ");
9abca702 20500
015dc7e1 20501 return true;
9ef920e9
NC
20502}
20503
6d118b09
NC
20504/* Note that by the ELF standard, the name field is already null byte
20505 terminated, and namesz includes the terminating null byte.
20506 I.E. the value of namesz for the name "FSF" is 4.
20507
e3c8793a 20508 If the value of namesz is zero, there is no name present. */
9ef920e9 20509
015dc7e1 20510static bool
9ef920e9 20511process_note (Elf_Internal_Note * pnote,
dda8d76d 20512 Filedata * filedata)
779fe533 20513{
2cf0635d
NC
20514 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
20515 const char * nt;
9437c45b
JT
20516
20517 if (pnote->namesz == 0)
1ec5cd37
NC
20518 /* If there is no note name, then use the default set of
20519 note type strings. */
dda8d76d 20520 nt = get_note_type (filedata, pnote->type);
1ec5cd37 20521
24d127aa 20522 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
20523 /* GNU-specific object file notes. */
20524 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 20525
24d127aa 20526 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 20527 /* FreeBSD-specific core file notes. */
dda8d76d 20528 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 20529
24d127aa 20530 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 20531 /* NetBSD-specific core file notes. */
dda8d76d 20532 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 20533
24d127aa 20534 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
20535 /* NetBSD-specific core file notes. */
20536 return process_netbsd_elf_note (pnote);
20537
24d127aa 20538 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
20539 /* NetBSD-specific core file notes. */
20540 return process_netbsd_elf_note (pnote);
20541
e9b095a5 20542 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
20543 {
20544 /* SPU-specific core file notes. */
20545 nt = pnote->namedata + 4;
20546 name = "SPU";
20547 }
20548
24d127aa 20549 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
20550 /* VMS/ia64-specific file notes. */
20551 nt = get_ia64_vms_note_type (pnote->type);
20552
24d127aa 20553 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
20554 nt = get_stapsdt_note_type (pnote->type);
20555
9437c45b 20556 else
1ec5cd37
NC
20557 /* Don't recognize this note name; just use the default set of
20558 note type strings. */
dda8d76d 20559 nt = get_note_type (filedata, pnote->type);
9437c45b 20560
1449284b 20561 printf (" ");
9ef920e9 20562
24d127aa 20563 if (((startswith (pnote->namedata, "GA")
483767a3
AM
20564 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20565 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20566 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20567 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
20568 print_gnu_build_attribute_name (pnote);
20569 else
20570 print_symbol (-20, name);
20571
20572 if (do_wide)
20573 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
20574 else
20575 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 20576
24d127aa 20577 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 20578 return print_ia64_vms_note (pnote);
24d127aa 20579 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 20580 return print_gnu_note (filedata, pnote);
24d127aa 20581 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 20582 return print_stapsdt_note (pnote);
24d127aa 20583 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 20584 return print_core_note (pnote);
24d127aa 20585 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
20586 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20587 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20588 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20589 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 20590 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 20591
9ef920e9 20592 if (pnote->descsz)
1449284b
NC
20593 {
20594 unsigned long i;
20595
20596 printf (_(" description data: "));
20597 for (i = 0; i < pnote->descsz; i++)
178d8719 20598 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
20599 if (!do_wide)
20600 printf ("\n");
1449284b
NC
20601 }
20602
9ef920e9
NC
20603 if (do_wide)
20604 printf ("\n");
20605
015dc7e1 20606 return true;
1449284b 20607}
6d118b09 20608
015dc7e1 20609static bool
dda8d76d
NC
20610process_notes_at (Filedata * filedata,
20611 Elf_Internal_Shdr * section,
20612 bfd_vma offset,
82ed9683
L
20613 bfd_vma length,
20614 bfd_vma align)
779fe533 20615{
015dc7e1
AM
20616 Elf_External_Note *pnotes;
20617 Elf_External_Note *external;
20618 char *end;
20619 bool res = true;
103f02d3 20620
779fe533 20621 if (length <= 0)
015dc7e1 20622 return false;
103f02d3 20623
1449284b
NC
20624 if (section)
20625 {
dda8d76d 20626 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 20627 if (pnotes)
32ec8896 20628 {
dda8d76d 20629 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
20630 {
20631 free (pnotes);
015dc7e1 20632 return false;
f761cb13 20633 }
32ec8896 20634 }
1449284b
NC
20635 }
20636 else
82ed9683 20637 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 20638 _("notes"));
4dff97b2 20639
dd24e3da 20640 if (pnotes == NULL)
015dc7e1 20641 return false;
779fe533 20642
103f02d3 20643 external = pnotes;
103f02d3 20644
ca0e11aa
NC
20645 if (filedata->is_separate)
20646 printf (_("In linked file '%s': "), filedata->file_name);
20647 else
20648 printf ("\n");
1449284b 20649 if (section)
ca0e11aa 20650 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 20651 else
ca0e11aa 20652 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
20653 (unsigned long) offset, (unsigned long) length);
20654
82ed9683
L
20655 /* NB: Some note sections may have alignment value of 0 or 1. gABI
20656 specifies that notes should be aligned to 4 bytes in 32-bit
20657 objects and to 8 bytes in 64-bit objects. As a Linux extension,
20658 we also support 4 byte alignment in 64-bit objects. If section
20659 alignment is less than 4, we treate alignment as 4 bytes. */
20660 if (align < 4)
20661 align = 4;
20662 else if (align != 4 && align != 8)
20663 {
20664 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
20665 (long) align);
a788aedd 20666 free (pnotes);
015dc7e1 20667 return false;
82ed9683
L
20668 }
20669
dbe15e4e 20670 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 20671
c8071705
NC
20672 end = (char *) pnotes + length;
20673 while ((char *) external < end)
779fe533 20674 {
b34976b6 20675 Elf_Internal_Note inote;
15b42fb0 20676 size_t min_notesz;
4dff97b2 20677 char * next;
2cf0635d 20678 char * temp = NULL;
c8071705 20679 size_t data_remaining = end - (char *) external;
6d118b09 20680
dda8d76d 20681 if (!is_ia64_vms (filedata))
15b42fb0 20682 {
9dd3a467
NC
20683 /* PR binutils/15191
20684 Make sure that there is enough data to read. */
15b42fb0
AM
20685 min_notesz = offsetof (Elf_External_Note, name);
20686 if (data_remaining < min_notesz)
9dd3a467 20687 {
d3a49aa8
AM
20688 warn (ngettext ("Corrupt note: only %ld byte remains, "
20689 "not enough for a full note\n",
20690 "Corrupt note: only %ld bytes remain, "
20691 "not enough for a full note\n",
20692 data_remaining),
20693 (long) data_remaining);
9dd3a467
NC
20694 break;
20695 }
5396a86e
AM
20696 data_remaining -= min_notesz;
20697
15b42fb0
AM
20698 inote.type = BYTE_GET (external->type);
20699 inote.namesz = BYTE_GET (external->namesz);
20700 inote.namedata = external->name;
20701 inote.descsz = BYTE_GET (external->descsz);
276da9b3 20702 inote.descdata = ((char *) external
4dff97b2 20703 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 20704 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 20705 next = ((char *) external
4dff97b2 20706 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 20707 }
00e98fc7 20708 else
15b42fb0
AM
20709 {
20710 Elf64_External_VMS_Note *vms_external;
00e98fc7 20711
9dd3a467
NC
20712 /* PR binutils/15191
20713 Make sure that there is enough data to read. */
15b42fb0
AM
20714 min_notesz = offsetof (Elf64_External_VMS_Note, name);
20715 if (data_remaining < min_notesz)
9dd3a467 20716 {
d3a49aa8
AM
20717 warn (ngettext ("Corrupt note: only %ld byte remains, "
20718 "not enough for a full note\n",
20719 "Corrupt note: only %ld bytes remain, "
20720 "not enough for a full note\n",
20721 data_remaining),
20722 (long) data_remaining);
9dd3a467
NC
20723 break;
20724 }
5396a86e 20725 data_remaining -= min_notesz;
3e55a963 20726
15b42fb0
AM
20727 vms_external = (Elf64_External_VMS_Note *) external;
20728 inote.type = BYTE_GET (vms_external->type);
20729 inote.namesz = BYTE_GET (vms_external->namesz);
20730 inote.namedata = vms_external->name;
20731 inote.descsz = BYTE_GET (vms_external->descsz);
20732 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
20733 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20734 next = inote.descdata + align_power (inote.descsz, 3);
20735 }
20736
5396a86e
AM
20737 /* PR 17531: file: 3443835e. */
20738 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
20739 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
20740 || (size_t) (inote.descdata - inote.namedata) > data_remaining
20741 || (size_t) (next - inote.descdata) < inote.descsz
20742 || ((size_t) (next - inote.descdata)
20743 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 20744 {
15b42fb0 20745 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 20746 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
20747 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
20748 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
20749 break;
20750 }
20751
15b42fb0 20752 external = (Elf_External_Note *) next;
dd24e3da 20753
6d118b09
NC
20754 /* Verify that name is null terminated. It appears that at least
20755 one version of Linux (RedHat 6.0) generates corefiles that don't
20756 comply with the ELF spec by failing to include the null byte in
20757 namesz. */
18344509 20758 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 20759 {
5396a86e 20760 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 20761 {
5396a86e
AM
20762 temp = (char *) malloc (inote.namesz + 1);
20763 if (temp == NULL)
20764 {
20765 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 20766 res = false;
5396a86e
AM
20767 break;
20768 }
76da6bbe 20769
5396a86e
AM
20770 memcpy (temp, inote.namedata, inote.namesz);
20771 inote.namedata = temp;
20772 }
20773 inote.namedata[inote.namesz] = 0;
6d118b09
NC
20774 }
20775
dda8d76d 20776 if (! process_note (& inote, filedata))
015dc7e1 20777 res = false;
103f02d3 20778
9db70fc3
AM
20779 free (temp);
20780 temp = NULL;
779fe533
NC
20781 }
20782
20783 free (pnotes);
103f02d3 20784
779fe533
NC
20785 return res;
20786}
20787
015dc7e1 20788static bool
dda8d76d 20789process_corefile_note_segments (Filedata * filedata)
779fe533 20790{
015dc7e1 20791 Elf_Internal_Phdr *segment;
b34976b6 20792 unsigned int i;
015dc7e1 20793 bool res = true;
103f02d3 20794
dda8d76d 20795 if (! get_program_headers (filedata))
015dc7e1 20796 return true;
103f02d3 20797
dda8d76d
NC
20798 for (i = 0, segment = filedata->program_headers;
20799 i < filedata->file_header.e_phnum;
b34976b6 20800 i++, segment++)
779fe533
NC
20801 {
20802 if (segment->p_type == PT_NOTE)
dda8d76d 20803 if (! process_notes_at (filedata, NULL,
32ec8896 20804 (bfd_vma) segment->p_offset,
82ed9683
L
20805 (bfd_vma) segment->p_filesz,
20806 (bfd_vma) segment->p_align))
015dc7e1 20807 res = false;
779fe533 20808 }
103f02d3 20809
779fe533
NC
20810 return res;
20811}
20812
015dc7e1 20813static bool
dda8d76d 20814process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
20815{
20816 Elf_External_Note * pnotes;
20817 Elf_External_Note * external;
c8071705 20818 char * end;
015dc7e1 20819 bool res = true;
685080f2
NC
20820
20821 if (length <= 0)
015dc7e1 20822 return false;
685080f2 20823
dda8d76d 20824 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
20825 _("v850 notes"));
20826 if (pnotes == NULL)
015dc7e1 20827 return false;
685080f2
NC
20828
20829 external = pnotes;
c8071705 20830 end = (char*) pnotes + length;
685080f2
NC
20831
20832 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
20833 (unsigned long) offset, (unsigned long) length);
20834
c8071705 20835 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
20836 {
20837 Elf_External_Note * next;
20838 Elf_Internal_Note inote;
20839
20840 inote.type = BYTE_GET (external->type);
20841 inote.namesz = BYTE_GET (external->namesz);
20842 inote.namedata = external->name;
20843 inote.descsz = BYTE_GET (external->descsz);
20844 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
20845 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20846
c8071705
NC
20847 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
20848 {
20849 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
20850 inote.descdata = inote.namedata;
20851 inote.namesz = 0;
20852 }
20853
685080f2
NC
20854 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
20855
c8071705 20856 if ( ((char *) next > end)
685080f2
NC
20857 || ((char *) next < (char *) pnotes))
20858 {
20859 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
20860 (unsigned long) ((char *) external - (char *) pnotes));
20861 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20862 inote.type, inote.namesz, inote.descsz);
20863 break;
20864 }
20865
20866 external = next;
20867
20868 /* Prevent out-of-bounds indexing. */
c8071705 20869 if ( inote.namedata + inote.namesz > end
685080f2
NC
20870 || inote.namedata + inote.namesz < inote.namedata)
20871 {
20872 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
20873 (unsigned long) ((char *) external - (char *) pnotes));
20874 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20875 inote.type, inote.namesz, inote.descsz);
20876 break;
20877 }
20878
20879 printf (" %s: ", get_v850_elf_note_type (inote.type));
20880
20881 if (! print_v850_note (& inote))
20882 {
015dc7e1 20883 res = false;
685080f2
NC
20884 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
20885 inote.namesz, inote.descsz);
20886 }
20887 }
20888
20889 free (pnotes);
20890
20891 return res;
20892}
20893
015dc7e1 20894static bool
dda8d76d 20895process_note_sections (Filedata * filedata)
1ec5cd37 20896{
015dc7e1 20897 Elf_Internal_Shdr *section;
1ec5cd37 20898 unsigned long i;
32ec8896 20899 unsigned int n = 0;
015dc7e1 20900 bool res = true;
1ec5cd37 20901
dda8d76d
NC
20902 for (i = 0, section = filedata->section_headers;
20903 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 20904 i++, section++)
685080f2
NC
20905 {
20906 if (section->sh_type == SHT_NOTE)
20907 {
dda8d76d 20908 if (! process_notes_at (filedata, section,
32ec8896 20909 (bfd_vma) section->sh_offset,
82ed9683
L
20910 (bfd_vma) section->sh_size,
20911 (bfd_vma) section->sh_addralign))
015dc7e1 20912 res = false;
685080f2
NC
20913 n++;
20914 }
20915
dda8d76d
NC
20916 if (( filedata->file_header.e_machine == EM_V800
20917 || filedata->file_header.e_machine == EM_V850
20918 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
20919 && section->sh_type == SHT_RENESAS_INFO)
20920 {
dda8d76d 20921 if (! process_v850_notes (filedata,
32ec8896
NC
20922 (bfd_vma) section->sh_offset,
20923 (bfd_vma) section->sh_size))
015dc7e1 20924 res = false;
685080f2
NC
20925 n++;
20926 }
20927 }
df565f32
NC
20928
20929 if (n == 0)
20930 /* Try processing NOTE segments instead. */
dda8d76d 20931 return process_corefile_note_segments (filedata);
1ec5cd37
NC
20932
20933 return res;
20934}
20935
015dc7e1 20936static bool
dda8d76d 20937process_notes (Filedata * filedata)
779fe533
NC
20938{
20939 /* If we have not been asked to display the notes then do nothing. */
20940 if (! do_notes)
015dc7e1 20941 return true;
103f02d3 20942
dda8d76d
NC
20943 if (filedata->file_header.e_type != ET_CORE)
20944 return process_note_sections (filedata);
103f02d3 20945
779fe533 20946 /* No program headers means no NOTE segment. */
dda8d76d
NC
20947 if (filedata->file_header.e_phnum > 0)
20948 return process_corefile_note_segments (filedata);
779fe533 20949
ca0e11aa
NC
20950 if (filedata->is_separate)
20951 printf (_("No notes found in linked file '%s'.\n"),
20952 filedata->file_name);
20953 else
20954 printf (_("No notes found file.\n"));
20955
015dc7e1 20956 return true;
779fe533
NC
20957}
20958
60abdbed
NC
20959static unsigned char *
20960display_public_gnu_attributes (unsigned char * start,
20961 const unsigned char * const end)
20962{
20963 printf (_(" Unknown GNU attribute: %s\n"), start);
20964
20965 start += strnlen ((char *) start, end - start);
20966 display_raw_attribute (start, end);
20967
20968 return (unsigned char *) end;
20969}
20970
20971static unsigned char *
20972display_generic_attribute (unsigned char * start,
20973 unsigned int tag,
20974 const unsigned char * const end)
20975{
20976 if (tag == 0)
20977 return (unsigned char *) end;
20978
20979 return display_tag_value (tag, start, end);
20980}
20981
015dc7e1 20982static bool
dda8d76d 20983process_arch_specific (Filedata * filedata)
252b5132 20984{
a952a375 20985 if (! do_arch)
015dc7e1 20986 return true;
a952a375 20987
dda8d76d 20988 switch (filedata->file_header.e_machine)
252b5132 20989 {
53a346d8
CZ
20990 case EM_ARC:
20991 case EM_ARC_COMPACT:
20992 case EM_ARC_COMPACT2:
dda8d76d 20993 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
20994 display_arc_attribute,
20995 display_generic_attribute);
11c1ff18 20996 case EM_ARM:
dda8d76d 20997 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
20998 display_arm_attribute,
20999 display_generic_attribute);
21000
252b5132 21001 case EM_MIPS:
4fe85591 21002 case EM_MIPS_RS3_LE:
dda8d76d 21003 return process_mips_specific (filedata);
60abdbed
NC
21004
21005 case EM_MSP430:
dda8d76d 21006 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21007 display_msp430_attribute,
c0ea7c52 21008 display_msp430_gnu_attribute);
60abdbed 21009
2dc8dd17
JW
21010 case EM_RISCV:
21011 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21012 display_riscv_attribute,
21013 display_generic_attribute);
21014
35c08157 21015 case EM_NDS32:
dda8d76d 21016 return process_nds32_specific (filedata);
60abdbed 21017
85f7484a
PB
21018 case EM_68K:
21019 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21020 display_m68k_gnu_attribute);
21021
34c8bcba 21022 case EM_PPC:
b82317dd 21023 case EM_PPC64:
dda8d76d 21024 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21025 display_power_gnu_attribute);
21026
643f7afb
AK
21027 case EM_S390:
21028 case EM_S390_OLD:
dda8d76d 21029 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21030 display_s390_gnu_attribute);
21031
9e8c70f9
DM
21032 case EM_SPARC:
21033 case EM_SPARC32PLUS:
21034 case EM_SPARCV9:
dda8d76d 21035 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21036 display_sparc_gnu_attribute);
21037
59e6276b 21038 case EM_TI_C6000:
dda8d76d 21039 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
21040 display_tic6x_attribute,
21041 display_generic_attribute);
21042
0861f561
CQ
21043 case EM_CSKY:
21044 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
21045 display_csky_attribute, NULL);
21046
252b5132 21047 default:
dda8d76d 21048 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
21049 display_public_gnu_attributes,
21050 display_generic_attribute);
252b5132 21051 }
252b5132
RH
21052}
21053
015dc7e1 21054static bool
dda8d76d 21055get_file_header (Filedata * filedata)
252b5132 21056{
9ea033b2 21057 /* Read in the identity array. */
dda8d76d 21058 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21059 return false;
252b5132 21060
9ea033b2 21061 /* Determine how to read the rest of the header. */
dda8d76d 21062 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 21063 {
1a0670f3
AM
21064 default:
21065 case ELFDATANONE:
adab8cdc
AO
21066 case ELFDATA2LSB:
21067 byte_get = byte_get_little_endian;
21068 byte_put = byte_put_little_endian;
21069 break;
21070 case ELFDATA2MSB:
21071 byte_get = byte_get_big_endian;
21072 byte_put = byte_put_big_endian;
21073 break;
9ea033b2
NC
21074 }
21075
21076 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 21077 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
21078
21079 /* Read in the rest of the header. */
21080 if (is_32bit_elf)
21081 {
21082 Elf32_External_Ehdr ehdr32;
252b5132 21083
dda8d76d 21084 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21085 return false;
103f02d3 21086
dda8d76d
NC
21087 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
21088 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
21089 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
21090 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
21091 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
21092 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
21093 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
21094 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
21095 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
21096 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
21097 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
21098 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
21099 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 21100 }
252b5132 21101 else
9ea033b2
NC
21102 {
21103 Elf64_External_Ehdr ehdr64;
a952a375
NC
21104
21105 /* If we have been compiled with sizeof (bfd_vma) == 4, then
21106 we will not be able to cope with the 64bit data found in
21107 64 ELF files. Detect this now and abort before we start
50c2245b 21108 overwriting things. */
a952a375
NC
21109 if (sizeof (bfd_vma) < 8)
21110 {
e3c8793a
NC
21111 error (_("This instance of readelf has been built without support for a\n\
2111264 bit data type and so it cannot read 64 bit ELF files.\n"));
015dc7e1 21113 return false;
a952a375 21114 }
103f02d3 21115
dda8d76d 21116 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21117 return false;
103f02d3 21118
dda8d76d
NC
21119 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
21120 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
21121 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
21122 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
21123 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
21124 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
21125 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
21126 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
21127 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
21128 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
21129 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
21130 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
21131 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 21132 }
252b5132 21133
dda8d76d 21134 if (filedata->file_header.e_shoff)
7ece0d85
JJ
21135 {
21136 /* There may be some extensions in the first section header. Don't
21137 bomb if we can't read it. */
21138 if (is_32bit_elf)
015dc7e1 21139 get_32bit_section_headers (filedata, true);
7ece0d85 21140 else
015dc7e1 21141 get_64bit_section_headers (filedata, true);
7ece0d85 21142 }
560f3c1c 21143
015dc7e1 21144 return true;
252b5132
RH
21145}
21146
13acb58d
AM
21147static void
21148free_filedata (Filedata *filedata)
21149{
21150 free (filedata->program_interpreter);
21151 filedata->program_interpreter = NULL;
21152
21153 free (filedata->program_headers);
21154 filedata->program_headers = NULL;
21155
21156 free (filedata->section_headers);
21157 filedata->section_headers = NULL;
21158
21159 free (filedata->string_table);
21160 filedata->string_table = NULL;
21161 filedata->string_table_length = 0;
21162
21163 free (filedata->dump.dump_sects);
21164 filedata->dump.dump_sects = NULL;
21165 filedata->dump.num_dump_sects = 0;
21166
21167 free (filedata->dynamic_strings);
21168 filedata->dynamic_strings = NULL;
21169 filedata->dynamic_strings_length = 0;
21170
21171 free (filedata->dynamic_symbols);
21172 filedata->dynamic_symbols = NULL;
21173 filedata->num_dynamic_syms = 0;
21174
21175 free (filedata->dynamic_syminfo);
21176 filedata->dynamic_syminfo = NULL;
21177
21178 free (filedata->dynamic_section);
21179 filedata->dynamic_section = NULL;
21180
21181 while (filedata->symtab_shndx_list != NULL)
21182 {
21183 elf_section_list *next = filedata->symtab_shndx_list->next;
21184 free (filedata->symtab_shndx_list);
21185 filedata->symtab_shndx_list = next;
21186 }
21187
21188 free (filedata->section_headers_groups);
21189 filedata->section_headers_groups = NULL;
21190
21191 if (filedata->section_groups)
21192 {
21193 size_t i;
21194 struct group_list * g;
21195 struct group_list * next;
21196
21197 for (i = 0; i < filedata->group_count; i++)
21198 {
21199 for (g = filedata->section_groups [i].root; g != NULL; g = next)
21200 {
21201 next = g->next;
21202 free (g);
21203 }
21204 }
21205
21206 free (filedata->section_groups);
21207 filedata->section_groups = NULL;
21208 }
21209}
21210
dda8d76d
NC
21211static void
21212close_file (Filedata * filedata)
21213{
21214 if (filedata)
21215 {
21216 if (filedata->handle)
21217 fclose (filedata->handle);
21218 free (filedata);
21219 }
21220}
21221
21222void
21223close_debug_file (void * data)
21224{
13acb58d 21225 free_filedata ((Filedata *) data);
dda8d76d
NC
21226 close_file ((Filedata *) data);
21227}
21228
21229static Filedata *
015dc7e1 21230open_file (const char * pathname, bool is_separate)
dda8d76d
NC
21231{
21232 struct stat statbuf;
21233 Filedata * filedata = NULL;
21234
21235 if (stat (pathname, & statbuf) < 0
21236 || ! S_ISREG (statbuf.st_mode))
21237 goto fail;
21238
21239 filedata = calloc (1, sizeof * filedata);
21240 if (filedata == NULL)
21241 goto fail;
21242
21243 filedata->handle = fopen (pathname, "rb");
21244 if (filedata->handle == NULL)
21245 goto fail;
21246
21247 filedata->file_size = (bfd_size_type) statbuf.st_size;
21248 filedata->file_name = pathname;
ca0e11aa 21249 filedata->is_separate = is_separate;
dda8d76d
NC
21250
21251 if (! get_file_header (filedata))
21252 goto fail;
21253
21254 if (filedata->file_header.e_shoff)
21255 {
015dc7e1 21256 bool res;
dda8d76d
NC
21257
21258 /* Read the section headers again, this time for real. */
21259 if (is_32bit_elf)
015dc7e1 21260 res = get_32bit_section_headers (filedata, false);
dda8d76d 21261 else
015dc7e1 21262 res = get_64bit_section_headers (filedata, false);
dda8d76d
NC
21263
21264 if (!res)
21265 goto fail;
21266 }
21267
21268 return filedata;
21269
21270 fail:
21271 if (filedata)
21272 {
21273 if (filedata->handle)
21274 fclose (filedata->handle);
21275 free (filedata);
21276 }
21277 return NULL;
21278}
21279
21280void *
21281open_debug_file (const char * pathname)
21282{
015dc7e1 21283 return open_file (pathname, true);
dda8d76d
NC
21284}
21285
835f2fae
NC
21286static void
21287initialise_dump_sects (Filedata * filedata)
21288{
21289 /* Initialise the dump_sects array from the cmdline_dump_sects array.
21290 Note we do this even if cmdline_dump_sects is empty because we
21291 must make sure that the dump_sets array is zeroed out before each
21292 object file is processed. */
21293 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
21294 memset (filedata->dump.dump_sects, 0,
21295 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21296
21297 if (cmdline.num_dump_sects > 0)
21298 {
21299 if (filedata->dump.num_dump_sects == 0)
21300 /* A sneaky way of allocating the dump_sects array. */
21301 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
21302
21303 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
21304 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
21305 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21306 }
21307}
21308
fb52b2f4
NC
21309/* Process one ELF object file according to the command line options.
21310 This file may actually be stored in an archive. The file is
32ec8896
NC
21311 positioned at the start of the ELF object. Returns TRUE if no
21312 problems were encountered, FALSE otherwise. */
fb52b2f4 21313
015dc7e1 21314static bool
dda8d76d 21315process_object (Filedata * filedata)
252b5132 21316{
015dc7e1 21317 bool have_separate_files;
252b5132 21318 unsigned int i;
015dc7e1 21319 bool res;
252b5132 21320
dda8d76d 21321 if (! get_file_header (filedata))
252b5132 21322 {
dda8d76d 21323 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 21324 return false;
252b5132
RH
21325 }
21326
21327 /* Initialise per file variables. */
978c4450
AM
21328 for (i = ARRAY_SIZE (filedata->version_info); i--;)
21329 filedata->version_info[i] = 0;
252b5132 21330
978c4450
AM
21331 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
21332 filedata->dynamic_info[i] = 0;
21333 filedata->dynamic_info_DT_GNU_HASH = 0;
21334 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
21335
21336 /* Process the file. */
21337 if (show_name)
dda8d76d 21338 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 21339
835f2fae 21340 initialise_dump_sects (filedata);
d70c5fc7 21341
dda8d76d 21342 if (! process_file_header (filedata))
015dc7e1 21343 return false;
252b5132 21344
dda8d76d 21345 if (! process_section_headers (filedata))
2f62977e 21346 {
32ec8896 21347 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 21348 do_unwind = do_version = do_dump = do_arch = false;
252b5132 21349
2f62977e 21350 if (! do_using_dynamic)
015dc7e1 21351 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 21352 }
252b5132 21353
dda8d76d 21354 if (! process_section_groups (filedata))
32ec8896 21355 /* Without loaded section groups we cannot process unwind. */
015dc7e1 21356 do_unwind = false;
d1f5c6e3 21357
2482f306
AM
21358 res = process_program_headers (filedata);
21359 if (res)
21360 res = process_dynamic_section (filedata);
252b5132 21361
dda8d76d 21362 if (! process_relocs (filedata))
015dc7e1 21363 res = false;
252b5132 21364
dda8d76d 21365 if (! process_unwind (filedata))
015dc7e1 21366 res = false;
4d6ed7c8 21367
dda8d76d 21368 if (! process_symbol_table (filedata))
015dc7e1 21369 res = false;
252b5132 21370
0f03783c 21371 if (! process_lto_symbol_tables (filedata))
015dc7e1 21372 res = false;
b9e920ec 21373
dda8d76d 21374 if (! process_syminfo (filedata))
015dc7e1 21375 res = false;
252b5132 21376
dda8d76d 21377 if (! process_version_sections (filedata))
015dc7e1 21378 res = false;
252b5132 21379
82ed9683 21380 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 21381 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 21382 else
015dc7e1 21383 have_separate_files = false;
dda8d76d
NC
21384
21385 if (! process_section_contents (filedata))
015dc7e1 21386 res = false;
f5842774 21387
24841daa 21388 if (have_separate_files)
dda8d76d 21389 {
24841daa
NC
21390 separate_info * d;
21391
21392 for (d = first_separate_info; d != NULL; d = d->next)
21393 {
835f2fae
NC
21394 initialise_dump_sects (d->handle);
21395
ca0e11aa 21396 if (process_links && ! process_file_header (d->handle))
015dc7e1 21397 res = false;
ca0e11aa 21398 else if (! process_section_headers (d->handle))
015dc7e1 21399 res = false;
d6bfbc39 21400 else if (! process_section_contents (d->handle))
015dc7e1 21401 res = false;
ca0e11aa
NC
21402 else if (process_links)
21403 {
ca0e11aa 21404 if (! process_section_groups (d->handle))
015dc7e1 21405 res = false;
ca0e11aa 21406 if (! process_program_headers (d->handle))
015dc7e1 21407 res = false;
ca0e11aa 21408 if (! process_dynamic_section (d->handle))
015dc7e1 21409 res = false;
ca0e11aa 21410 if (! process_relocs (d->handle))
015dc7e1 21411 res = false;
ca0e11aa 21412 if (! process_unwind (d->handle))
015dc7e1 21413 res = false;
ca0e11aa 21414 if (! process_symbol_table (d->handle))
015dc7e1 21415 res = false;
ca0e11aa 21416 if (! process_lto_symbol_tables (d->handle))
015dc7e1 21417 res = false;
ca0e11aa 21418 if (! process_syminfo (d->handle))
015dc7e1 21419 res = false;
ca0e11aa 21420 if (! process_version_sections (d->handle))
015dc7e1 21421 res = false;
ca0e11aa 21422 if (! process_notes (d->handle))
015dc7e1 21423 res = false;
ca0e11aa 21424 }
24841daa
NC
21425 }
21426
21427 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
21428 }
21429
21430 if (! process_notes (filedata))
015dc7e1 21431 res = false;
103f02d3 21432
dda8d76d 21433 if (! process_gnu_liblist (filedata))
015dc7e1 21434 res = false;
047b2264 21435
dda8d76d 21436 if (! process_arch_specific (filedata))
015dc7e1 21437 res = false;
252b5132 21438
13acb58d 21439 free_filedata (filedata);
e4b17d5c 21440
19e6b90e 21441 free_debug_memory ();
18bd398b 21442
32ec8896 21443 return res;
252b5132
RH
21444}
21445
2cf0635d 21446/* Process an ELF archive.
32ec8896
NC
21447 On entry the file is positioned just after the ARMAG string.
21448 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 21449
015dc7e1
AM
21450static bool
21451process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
21452{
21453 struct archive_info arch;
21454 struct archive_info nested_arch;
21455 size_t got;
015dc7e1 21456 bool ret = true;
2cf0635d 21457
015dc7e1 21458 show_name = true;
2cf0635d
NC
21459
21460 /* The ARCH structure is used to hold information about this archive. */
21461 arch.file_name = NULL;
21462 arch.file = NULL;
21463 arch.index_array = NULL;
21464 arch.sym_table = NULL;
21465 arch.longnames = NULL;
21466
21467 /* The NESTED_ARCH structure is used as a single-item cache of information
21468 about a nested archive (when members of a thin archive reside within
21469 another regular archive file). */
21470 nested_arch.file_name = NULL;
21471 nested_arch.file = NULL;
21472 nested_arch.index_array = NULL;
21473 nested_arch.sym_table = NULL;
21474 nested_arch.longnames = NULL;
21475
dda8d76d 21476 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
21477 filedata->file_size, is_thin_archive,
21478 do_archive_index) != 0)
2cf0635d 21479 {
015dc7e1 21480 ret = false;
2cf0635d 21481 goto out;
4145f1d5 21482 }
fb52b2f4 21483
4145f1d5
NC
21484 if (do_archive_index)
21485 {
2cf0635d 21486 if (arch.sym_table == NULL)
1cb7d8b1
AM
21487 error (_("%s: unable to dump the index as none was found\n"),
21488 filedata->file_name);
4145f1d5
NC
21489 else
21490 {
591f7597 21491 unsigned long i, l;
4145f1d5
NC
21492 unsigned long current_pos;
21493
1cb7d8b1
AM
21494 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
21495 "in the symbol table)\n"),
21496 filedata->file_name, (unsigned long) arch.index_num,
21497 arch.sym_size);
dda8d76d
NC
21498
21499 current_pos = ftell (filedata->handle);
4145f1d5 21500
2cf0635d 21501 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 21502 {
1cb7d8b1
AM
21503 if (i == 0
21504 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
21505 {
21506 char * member_name
21507 = get_archive_member_name_at (&arch, arch.index_array[i],
21508 &nested_arch);
2cf0635d 21509
1cb7d8b1
AM
21510 if (member_name != NULL)
21511 {
21512 char * qualified_name
21513 = make_qualified_name (&arch, &nested_arch,
21514 member_name);
2cf0635d 21515
1cb7d8b1
AM
21516 if (qualified_name != NULL)
21517 {
21518 printf (_("Contents of binary %s at offset "),
21519 qualified_name);
c2a7d3f5
NC
21520 (void) print_vma (arch.index_array[i], PREFIX_HEX);
21521 putchar ('\n');
1cb7d8b1
AM
21522 free (qualified_name);
21523 }
fd486f32 21524 free (member_name);
4145f1d5
NC
21525 }
21526 }
2cf0635d
NC
21527
21528 if (l >= arch.sym_size)
4145f1d5 21529 {
1cb7d8b1
AM
21530 error (_("%s: end of the symbol table reached "
21531 "before the end of the index\n"),
dda8d76d 21532 filedata->file_name);
015dc7e1 21533 ret = false;
cb8f3167 21534 break;
4145f1d5 21535 }
591f7597 21536 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
21537 printf ("\t%.*s\n",
21538 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 21539 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
21540 }
21541
67ce483b 21542 if (arch.uses_64bit_indices)
c2a7d3f5
NC
21543 l = (l + 7) & ~ 7;
21544 else
21545 l += l & 1;
21546
2cf0635d 21547 if (l < arch.sym_size)
32ec8896 21548 {
d3a49aa8
AM
21549 error (ngettext ("%s: %ld byte remains in the symbol table, "
21550 "but without corresponding entries in "
21551 "the index table\n",
21552 "%s: %ld bytes remain in the symbol table, "
21553 "but without corresponding entries in "
21554 "the index table\n",
21555 arch.sym_size - l),
dda8d76d 21556 filedata->file_name, arch.sym_size - l);
015dc7e1 21557 ret = false;
32ec8896 21558 }
4145f1d5 21559
dda8d76d 21560 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 21561 {
1cb7d8b1
AM
21562 error (_("%s: failed to seek back to start of object files "
21563 "in the archive\n"),
dda8d76d 21564 filedata->file_name);
015dc7e1 21565 ret = false;
2cf0635d 21566 goto out;
4145f1d5 21567 }
fb52b2f4 21568 }
4145f1d5
NC
21569
21570 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
21571 && !do_segments && !do_header && !do_dump && !do_version
21572 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 21573 && !do_section_groups && !do_dyn_syms)
2cf0635d 21574 {
015dc7e1 21575 ret = true; /* Archive index only. */
2cf0635d
NC
21576 goto out;
21577 }
fb52b2f4
NC
21578 }
21579
fb52b2f4
NC
21580 while (1)
21581 {
2cf0635d
NC
21582 char * name;
21583 size_t namelen;
21584 char * qualified_name;
21585
21586 /* Read the next archive header. */
dda8d76d 21587 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
21588 {
21589 error (_("%s: failed to seek to next archive header\n"),
21590 arch.file_name);
015dc7e1 21591 ret = false;
1cb7d8b1
AM
21592 break;
21593 }
dda8d76d 21594 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 21595 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
21596 {
21597 if (got == 0)
2cf0635d 21598 break;
28e817cc
NC
21599 /* PR 24049 - we cannot use filedata->file_name as this will
21600 have already been freed. */
21601 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 21602
015dc7e1 21603 ret = false;
1cb7d8b1
AM
21604 break;
21605 }
2cf0635d 21606 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
21607 {
21608 error (_("%s: did not find a valid archive header\n"),
21609 arch.file_name);
015dc7e1 21610 ret = false;
1cb7d8b1
AM
21611 break;
21612 }
2cf0635d
NC
21613
21614 arch.next_arhdr_offset += sizeof arch.arhdr;
21615
978c4450
AM
21616 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
21617 if (filedata->archive_file_size & 01)
21618 ++filedata->archive_file_size;
2cf0635d
NC
21619
21620 name = get_archive_member_name (&arch, &nested_arch);
21621 if (name == NULL)
fb52b2f4 21622 {
28e817cc 21623 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 21624 ret = false;
d989285c 21625 break;
fb52b2f4 21626 }
2cf0635d 21627 namelen = strlen (name);
fb52b2f4 21628
2cf0635d
NC
21629 qualified_name = make_qualified_name (&arch, &nested_arch, name);
21630 if (qualified_name == NULL)
fb52b2f4 21631 {
28e817cc 21632 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 21633 free (name);
015dc7e1 21634 ret = false;
d989285c 21635 break;
fb52b2f4
NC
21636 }
21637
2cf0635d 21638 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
21639 {
21640 /* This is a proxy for an external member of a thin archive. */
21641 Filedata * member_filedata;
21642 char * member_file_name = adjust_relative_path
dda8d76d 21643 (filedata->file_name, name, namelen);
32ec8896 21644
fd486f32 21645 free (name);
1cb7d8b1
AM
21646 if (member_file_name == NULL)
21647 {
fd486f32 21648 free (qualified_name);
015dc7e1 21649 ret = false;
1cb7d8b1
AM
21650 break;
21651 }
2cf0635d 21652
015dc7e1 21653 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
21654 if (member_filedata == NULL)
21655 {
21656 error (_("Input file '%s' is not readable.\n"), member_file_name);
21657 free (member_file_name);
fd486f32 21658 free (qualified_name);
015dc7e1 21659 ret = false;
1cb7d8b1
AM
21660 break;
21661 }
2cf0635d 21662
978c4450 21663 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 21664 member_filedata->file_name = qualified_name;
2cf0635d 21665
1cb7d8b1 21666 if (! process_object (member_filedata))
015dc7e1 21667 ret = false;
2cf0635d 21668
1cb7d8b1
AM
21669 close_file (member_filedata);
21670 free (member_file_name);
1cb7d8b1 21671 }
2cf0635d 21672 else if (is_thin_archive)
1cb7d8b1
AM
21673 {
21674 Filedata thin_filedata;
eb02c04d 21675
1cb7d8b1 21676 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 21677
a043396b
NC
21678 /* PR 15140: Allow for corrupt thin archives. */
21679 if (nested_arch.file == NULL)
21680 {
21681 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 21682 qualified_name, name);
fd486f32
AM
21683 free (qualified_name);
21684 free (name);
015dc7e1 21685 ret = false;
a043396b
NC
21686 break;
21687 }
fd486f32 21688 free (name);
a043396b 21689
1cb7d8b1 21690 /* This is a proxy for a member of a nested archive. */
978c4450
AM
21691 filedata->archive_file_offset
21692 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 21693
1cb7d8b1
AM
21694 /* The nested archive file will have been opened and setup by
21695 get_archive_member_name. */
978c4450
AM
21696 if (fseek (nested_arch.file, filedata->archive_file_offset,
21697 SEEK_SET) != 0)
1cb7d8b1
AM
21698 {
21699 error (_("%s: failed to seek to archive member.\n"),
21700 nested_arch.file_name);
fd486f32 21701 free (qualified_name);
015dc7e1 21702 ret = false;
1cb7d8b1
AM
21703 break;
21704 }
2cf0635d 21705
dda8d76d
NC
21706 thin_filedata.handle = nested_arch.file;
21707 thin_filedata.file_name = qualified_name;
9abca702 21708
1cb7d8b1 21709 if (! process_object (& thin_filedata))
015dc7e1 21710 ret = false;
1cb7d8b1 21711 }
2cf0635d 21712 else
1cb7d8b1 21713 {
fd486f32 21714 free (name);
978c4450 21715 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 21716 filedata->file_name = qualified_name;
1cb7d8b1 21717 if (! process_object (filedata))
015dc7e1 21718 ret = false;
978c4450 21719 arch.next_arhdr_offset += filedata->archive_file_size;
4c836627 21720 /* Stop looping with "negative" archive_file_size. */
978c4450 21721 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 21722 arch.next_arhdr_offset = -1ul;
1cb7d8b1 21723 }
fb52b2f4 21724
2cf0635d 21725 free (qualified_name);
fb52b2f4
NC
21726 }
21727
4145f1d5 21728 out:
2cf0635d
NC
21729 if (nested_arch.file != NULL)
21730 fclose (nested_arch.file);
21731 release_archive (&nested_arch);
21732 release_archive (&arch);
fb52b2f4 21733
d989285c 21734 return ret;
fb52b2f4
NC
21735}
21736
015dc7e1 21737static bool
2cf0635d 21738process_file (char * file_name)
fb52b2f4 21739{
dda8d76d 21740 Filedata * filedata = NULL;
fb52b2f4
NC
21741 struct stat statbuf;
21742 char armag[SARMAG];
015dc7e1 21743 bool ret = true;
fb52b2f4
NC
21744
21745 if (stat (file_name, &statbuf) < 0)
21746 {
f24ddbdd
NC
21747 if (errno == ENOENT)
21748 error (_("'%s': No such file\n"), file_name);
21749 else
21750 error (_("Could not locate '%s'. System error message: %s\n"),
21751 file_name, strerror (errno));
015dc7e1 21752 return false;
f24ddbdd
NC
21753 }
21754
21755 if (! S_ISREG (statbuf.st_mode))
21756 {
21757 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 21758 return false;
fb52b2f4
NC
21759 }
21760
dda8d76d
NC
21761 filedata = calloc (1, sizeof * filedata);
21762 if (filedata == NULL)
21763 {
21764 error (_("Out of memory allocating file data structure\n"));
015dc7e1 21765 return false;
dda8d76d
NC
21766 }
21767
21768 filedata->file_name = file_name;
21769 filedata->handle = fopen (file_name, "rb");
21770 if (filedata->handle == NULL)
fb52b2f4 21771 {
f24ddbdd 21772 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 21773 free (filedata);
015dc7e1 21774 return false;
fb52b2f4
NC
21775 }
21776
dda8d76d 21777 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 21778 {
4145f1d5 21779 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
21780 fclose (filedata->handle);
21781 free (filedata);
015dc7e1 21782 return false;
fb52b2f4
NC
21783 }
21784
dda8d76d 21785 filedata->file_size = (bfd_size_type) statbuf.st_size;
015dc7e1 21786 filedata->is_separate = false;
f54498b4 21787
fb52b2f4 21788 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 21789 {
015dc7e1
AM
21790 if (! process_archive (filedata, false))
21791 ret = false;
32ec8896 21792 }
2cf0635d 21793 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 21794 {
015dc7e1
AM
21795 if ( ! process_archive (filedata, true))
21796 ret = false;
32ec8896 21797 }
fb52b2f4
NC
21798 else
21799 {
1b513401 21800 if (do_archive_index && !check_all)
4145f1d5
NC
21801 error (_("File %s is not an archive so its index cannot be displayed.\n"),
21802 file_name);
21803
dda8d76d 21804 rewind (filedata->handle);
978c4450 21805 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 21806
dda8d76d 21807 if (! process_object (filedata))
015dc7e1 21808 ret = false;
fb52b2f4
NC
21809 }
21810
dda8d76d 21811 fclose (filedata->handle);
8fb879cd
AM
21812 free (filedata->section_headers);
21813 free (filedata->program_headers);
21814 free (filedata->string_table);
6431e409 21815 free (filedata->dump.dump_sects);
dda8d76d 21816 free (filedata);
32ec8896 21817
fd486f32 21818 free (ba_cache.strtab);
1bd6175a 21819 ba_cache.strtab = NULL;
fd486f32 21820 free (ba_cache.symtab);
1bd6175a 21821 ba_cache.symtab = NULL;
fd486f32
AM
21822 ba_cache.filedata = NULL;
21823
fb52b2f4
NC
21824 return ret;
21825}
21826
252b5132
RH
21827#ifdef SUPPORT_DISASSEMBLY
21828/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 21829 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 21830 symbols. */
252b5132
RH
21831
21832void
2cf0635d 21833print_address (unsigned int addr, FILE * outfile)
252b5132
RH
21834{
21835 fprintf (outfile,"0x%8.8x", addr);
21836}
21837
e3c8793a 21838/* Needed by the i386 disassembler. */
dda8d76d 21839
252b5132
RH
21840void
21841db_task_printsym (unsigned int addr)
21842{
21843 print_address (addr, stderr);
21844}
21845#endif
21846
21847int
2cf0635d 21848main (int argc, char ** argv)
252b5132 21849{
ff78d6d6
L
21850 int err;
21851
87b9f255 21852#ifdef HAVE_LC_MESSAGES
252b5132 21853 setlocale (LC_MESSAGES, "");
3882b010 21854#endif
3882b010 21855 setlocale (LC_CTYPE, "");
252b5132
RH
21856 bindtextdomain (PACKAGE, LOCALEDIR);
21857 textdomain (PACKAGE);
21858
869b9d07
MM
21859 expandargv (&argc, &argv);
21860
dda8d76d 21861 parse_args (& cmdline, argc, argv);
59f14fc0 21862
18bd398b 21863 if (optind < (argc - 1))
1b513401
NC
21864 /* When displaying information for more than one file,
21865 prefix the information with the file name. */
015dc7e1 21866 show_name = true;
5656ba2c
L
21867 else if (optind >= argc)
21868 {
1b513401 21869 /* Ensure that the warning is always displayed. */
015dc7e1 21870 do_checks = true;
1b513401 21871
5656ba2c
L
21872 warn (_("Nothing to do.\n"));
21873 usage (stderr);
21874 }
18bd398b 21875
015dc7e1 21876 err = false;
252b5132 21877 while (optind < argc)
32ec8896 21878 if (! process_file (argv[optind++]))
015dc7e1 21879 err = true;
252b5132 21880
9db70fc3 21881 free (cmdline.dump_sects);
252b5132 21882
7d9813f1
NA
21883 free (dump_ctf_symtab_name);
21884 free (dump_ctf_strtab_name);
21885 free (dump_ctf_parent_name);
21886
32ec8896 21887 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 21888}
This page took 4.690673 seconds and 4 git commands to generate.