]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
libiberty: add htab_eq_string
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
250d07de 2 Copyright (C) 1998-2021 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056 46#include <zlib.h>
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";
2608 case EM_LOONGARCH: return "Loongson Loongarch";
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\
ca0e11aa 4656 -w[lLiaprmfFsoORtUuTgAc] or\n\
1ed06042 4657 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
e4b7104b 4658 =frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,\n\
657d0d47 4659 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
ca0e11aa
NC
4660 =addr,=cu_index]\n\
4661 Display the contents of DWARF debug sections\n\
4662 -wk,--debug-dump=links Display the contents of sections that link to separate debuginfo files\n\
4663 -P,--process-links Display the contents of non-debug sections in separate debuginfo files. (Implies -wK)\n"));
c46b7066
NC
4664#if DEFAULT_FOR_FOLLOW_LINKS
4665 fprintf (stream, _("\
4666 -wK,--debug-dump=follow-links Follow links to separate debug info files (default)\n\
4667 -wN,--debug-dump=no-follow-links Do not follow links to separate debug info files\n\
4668"));
4669#else
4670 fprintf (stream, _("\
4671 -wK,--debug-dump=follow-links Follow links to separate debug info files\n\
4672 -wN,--debug-dump=no-follow-links Do not follow links to separate debug info files (default)\n\
4673"));
4674#endif
fd2f0033
TT
4675 fprintf (stream, _("\
4676 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4677 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4678 or deeper\n"));
094e34f2 4679#ifdef ENABLE_LIBCTF
7d9813f1
NA
4680 fprintf (stream, _("\
4681 --ctf=<number|name> Display CTF info from section <number|name>\n\
4682 --ctf-parent=<number|name>\n\
4683 Use section <number|name> as the CTF parent\n\n\
4684 --ctf-symbols=<number|name>\n\
4685 Use section <number|name> as the CTF external symtab\n\n\
4686 --ctf-strings=<number|name>\n\
4687 Use section <number|name> as the CTF external strtab\n\n"));
094e34f2 4688#endif
7d9813f1 4689
252b5132 4690#ifdef SUPPORT_DISASSEMBLY
92f01d61 4691 fprintf (stream, _("\
09c11c86
NC
4692 -i --instruction-dump=<number|name>\n\
4693 Disassemble the contents of section <number|name>\n"));
252b5132 4694#endif
92f01d61 4695 fprintf (stream, _("\
8b53311e
NC
4696 -I --histogram Display histogram of bucket list lengths\n\
4697 -W --wide Allow output width to exceed 80 characters\n\
0942c7ab 4698 -T --silent-truncation If a symbol name is truncated, do not add a suffix [...]\n\
07012eee 4699 @<file> Read options from <file>\n\
8b53311e
NC
4700 -H --help Display this information\n\
4701 -v --version Display the version number of readelf\n"));
1118d252 4702
92f01d61
JM
4703 if (REPORT_BUGS_TO[0] && stream == stdout)
4704 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4705
92f01d61 4706 exit (stream == stdout ? 0 : 1);
252b5132
RH
4707}
4708
18bd398b
NC
4709/* Record the fact that the user wants the contents of section number
4710 SECTION to be displayed using the method(s) encoded as flags bits
4711 in TYPE. Note, TYPE can be zero if we are creating the array for
4712 the first time. */
4713
252b5132 4714static void
6431e409
AM
4715request_dump_bynumber (struct dump_data *dumpdata,
4716 unsigned int section, dump_type type)
252b5132 4717{
6431e409 4718 if (section >= dumpdata->num_dump_sects)
252b5132 4719 {
2cf0635d 4720 dump_type * new_dump_sects;
252b5132 4721
3f5e193b 4722 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4723 sizeof (* new_dump_sects));
252b5132
RH
4724
4725 if (new_dump_sects == NULL)
591a748a 4726 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4727 else
4728 {
6431e409 4729 if (dumpdata->dump_sects)
21b65bac
NC
4730 {
4731 /* Copy current flag settings. */
6431e409
AM
4732 memcpy (new_dump_sects, dumpdata->dump_sects,
4733 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4734
6431e409 4735 free (dumpdata->dump_sects);
21b65bac 4736 }
252b5132 4737
6431e409
AM
4738 dumpdata->dump_sects = new_dump_sects;
4739 dumpdata->num_dump_sects = section + 1;
252b5132
RH
4740 }
4741 }
4742
6431e409
AM
4743 if (dumpdata->dump_sects)
4744 dumpdata->dump_sects[section] |= type;
252b5132
RH
4745}
4746
aef1f6d0
DJ
4747/* Request a dump by section name. */
4748
4749static void
2cf0635d 4750request_dump_byname (const char * section, dump_type type)
aef1f6d0 4751{
2cf0635d 4752 struct dump_list_entry * new_request;
aef1f6d0 4753
3f5e193b
NC
4754 new_request = (struct dump_list_entry *)
4755 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4756 if (!new_request)
591a748a 4757 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4758
4759 new_request->name = strdup (section);
4760 if (!new_request->name)
591a748a 4761 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4762
4763 new_request->type = type;
4764
4765 new_request->next = dump_sects_byname;
4766 dump_sects_byname = new_request;
4767}
4768
cf13d699 4769static inline void
6431e409 4770request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
4771{
4772 int section;
4773 char * cp;
4774
015dc7e1 4775 do_dump = true;
cf13d699
NC
4776 section = strtoul (optarg, & cp, 0);
4777
4778 if (! *cp && section >= 0)
6431e409 4779 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
4780 else
4781 request_dump_byname (optarg, type);
4782}
4783
252b5132 4784static void
6431e409 4785parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
4786{
4787 int c;
4788
4789 if (argc < 2)
92f01d61 4790 usage (stderr);
252b5132
RH
4791
4792 while ((c = getopt_long
ca0e11aa 4793 (argc, argv, "ACDHILNPR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4794 {
252b5132
RH
4795 switch (c)
4796 {
4797 case 0:
4798 /* Long options. */
4799 break;
4800 case 'H':
92f01d61 4801 usage (stdout);
252b5132
RH
4802 break;
4803
4804 case 'a':
015dc7e1
AM
4805 do_syms = true;
4806 do_reloc = true;
4807 do_unwind = true;
4808 do_dynamic = true;
4809 do_header = true;
4810 do_sections = true;
4811 do_section_groups = true;
4812 do_segments = true;
4813 do_version = true;
4814 do_histogram = true;
4815 do_arch = true;
4816 do_notes = true;
252b5132 4817 break;
79bc120c 4818
f5842774 4819 case 'g':
015dc7e1 4820 do_section_groups = true;
f5842774 4821 break;
5477e8a0 4822 case 't':
595cf52e 4823 case 'N':
015dc7e1
AM
4824 do_sections = true;
4825 do_section_details = true;
595cf52e 4826 break;
252b5132 4827 case 'e':
015dc7e1
AM
4828 do_header = true;
4829 do_sections = true;
4830 do_segments = true;
252b5132 4831 break;
a952a375 4832 case 'A':
015dc7e1 4833 do_arch = true;
a952a375 4834 break;
252b5132 4835 case 'D':
015dc7e1 4836 do_using_dynamic = true;
252b5132
RH
4837 break;
4838 case 'r':
015dc7e1 4839 do_reloc = true;
252b5132 4840 break;
4d6ed7c8 4841 case 'u':
015dc7e1 4842 do_unwind = true;
4d6ed7c8 4843 break;
252b5132 4844 case 'h':
015dc7e1 4845 do_header = true;
252b5132
RH
4846 break;
4847 case 'l':
015dc7e1 4848 do_segments = true;
252b5132
RH
4849 break;
4850 case 's':
015dc7e1 4851 do_syms = true;
252b5132
RH
4852 break;
4853 case 'S':
015dc7e1 4854 do_sections = true;
252b5132
RH
4855 break;
4856 case 'd':
015dc7e1 4857 do_dynamic = true;
252b5132 4858 break;
a952a375 4859 case 'I':
015dc7e1 4860 do_histogram = true;
a952a375 4861 break;
779fe533 4862 case 'n':
015dc7e1 4863 do_notes = true;
779fe533 4864 break;
4145f1d5 4865 case 'c':
015dc7e1 4866 do_archive_index = true;
4145f1d5 4867 break;
1b513401 4868 case 'L':
015dc7e1 4869 do_checks = true;
1b513401 4870 break;
ca0e11aa 4871 case 'P':
015dc7e1
AM
4872 process_links = true;
4873 do_follow_links = true;
ca0e11aa 4874 break;
252b5132 4875 case 'x':
6431e409 4876 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 4877 break;
09c11c86 4878 case 'p':
6431e409 4879 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
4880 break;
4881 case 'R':
6431e409 4882 request_dump (dumpdata, RELOC_DUMP);
09c11c86 4883 break;
0e602686 4884 case 'z':
015dc7e1 4885 decompress_dumps = true;
0e602686 4886 break;
252b5132 4887 case 'w':
015dc7e1 4888 do_dump = true;
0f03783c 4889 if (optarg == NULL)
613ff48b 4890 {
015dc7e1 4891 do_debugging = true;
613ff48b
CC
4892 dwarf_select_sections_all ();
4893 }
252b5132
RH
4894 else
4895 {
015dc7e1 4896 do_debugging = false;
4cb93e3b 4897 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4898 }
4899 break;
2979dc34 4900 case OPTION_DEBUG_DUMP:
015dc7e1 4901 do_dump = true;
0f03783c 4902 if (optarg == NULL)
015dc7e1 4903 do_debugging = true;
2979dc34
JJ
4904 else
4905 {
015dc7e1 4906 do_debugging = false;
4cb93e3b 4907 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4908 }
4909 break;
fd2f0033
TT
4910 case OPTION_DWARF_DEPTH:
4911 {
4912 char *cp;
4913
4914 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4915 }
4916 break;
4917 case OPTION_DWARF_START:
4918 {
4919 char *cp;
4920
4921 dwarf_start_die = strtoul (optarg, & cp, 0);
4922 }
4923 break;
4723351a 4924 case OPTION_DWARF_CHECK:
015dc7e1 4925 dwarf_check = true;
4723351a 4926 break;
7d9813f1 4927 case OPTION_CTF_DUMP:
015dc7e1 4928 do_ctf = true;
6431e409 4929 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
4930 break;
4931 case OPTION_CTF_SYMBOLS:
df16e041 4932 free (dump_ctf_symtab_name);
7d9813f1
NA
4933 dump_ctf_symtab_name = strdup (optarg);
4934 break;
4935 case OPTION_CTF_STRINGS:
df16e041 4936 free (dump_ctf_strtab_name);
7d9813f1
NA
4937 dump_ctf_strtab_name = strdup (optarg);
4938 break;
4939 case OPTION_CTF_PARENT:
df16e041 4940 free (dump_ctf_parent_name);
7d9813f1
NA
4941 dump_ctf_parent_name = strdup (optarg);
4942 break;
2c610e4b 4943 case OPTION_DYN_SYMS:
015dc7e1 4944 do_dyn_syms = true;
2c610e4b 4945 break;
0f03783c 4946 case OPTION_LTO_SYMS:
015dc7e1 4947 do_lto_syms = true;
0f03783c 4948 break;
252b5132
RH
4949#ifdef SUPPORT_DISASSEMBLY
4950 case 'i':
6431e409 4951 request_dump (dumpdata, DISASS_DUMP);
cf13d699 4952 break;
252b5132
RH
4953#endif
4954 case 'v':
4955 print_version (program_name);
4956 break;
4957 case 'V':
015dc7e1 4958 do_version = true;
252b5132 4959 break;
d974e256 4960 case 'W':
015dc7e1 4961 do_wide = true;
d974e256 4962 break;
0942c7ab 4963 case 'T':
015dc7e1 4964 do_not_show_symbol_truncation = true;
0942c7ab 4965 break;
79bc120c 4966 case 'C':
015dc7e1 4967 do_demangle = true;
79bc120c
NC
4968 if (optarg != NULL)
4969 {
4970 enum demangling_styles style;
4971
4972 style = cplus_demangle_name_to_style (optarg);
4973 if (style == unknown_demangling)
4974 error (_("unknown demangling style `%s'"), optarg);
4975
4976 cplus_demangle_set_style (style);
4977 }
4978 break;
4979 case OPTION_NO_DEMANGLING:
015dc7e1 4980 do_demangle = false;
79bc120c
NC
4981 break;
4982 case OPTION_RECURSE_LIMIT:
4983 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
4984 break;
4985 case OPTION_NO_RECURSE_LIMIT:
4986 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
4987 break;
4988 case OPTION_WITH_SYMBOL_VERSIONS:
4989 /* Ignored for backward compatibility. */
4990 break;
b9e920ec 4991
047c3dbf
NL
4992 case OPTION_SYM_BASE:
4993 sym_base = 0;
4994 if (optarg != NULL)
4995 {
4996 sym_base = strtoul (optarg, NULL, 0);
4997 switch (sym_base)
4998 {
4999 case 0:
5000 case 8:
5001 case 10:
5002 case 16:
5003 break;
5004
5005 default:
5006 sym_base = 0;
5007 break;
5008 }
5009 }
5010 break;
5011
252b5132 5012 default:
252b5132
RH
5013 /* xgettext:c-format */
5014 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5015 /* Fall through. */
252b5132 5016 case '?':
92f01d61 5017 usage (stderr);
252b5132
RH
5018 }
5019 }
5020
4d6ed7c8 5021 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5022 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5023 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5024 && !do_section_groups && !do_archive_index
0f03783c 5025 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5026 {
5027 if (do_checks)
5028 {
015dc7e1
AM
5029 check_all = true;
5030 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5031 do_segments = do_header = do_dump = do_version = true;
5032 do_histogram = do_debugging = do_arch = do_notes = true;
5033 do_section_groups = do_archive_index = do_dyn_syms = true;
5034 do_lto_syms = true;
1b513401
NC
5035 }
5036 else
5037 usage (stderr);
5038 }
252b5132
RH
5039}
5040
5041static const char *
d3ba0551 5042get_elf_class (unsigned int elf_class)
252b5132 5043{
b34976b6 5044 static char buff[32];
103f02d3 5045
252b5132
RH
5046 switch (elf_class)
5047 {
5048 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5049 case ELFCLASS32: return "ELF32";
5050 case ELFCLASS64: return "ELF64";
ab5e7794 5051 default:
e9e44622 5052 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5053 return buff;
252b5132
RH
5054 }
5055}
5056
5057static const char *
d3ba0551 5058get_data_encoding (unsigned int encoding)
252b5132 5059{
b34976b6 5060 static char buff[32];
103f02d3 5061
252b5132
RH
5062 switch (encoding)
5063 {
5064 case ELFDATANONE: return _("none");
33c63f9d
CM
5065 case ELFDATA2LSB: return _("2's complement, little endian");
5066 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5067 default:
e9e44622 5068 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5069 return buff;
252b5132
RH
5070 }
5071}
5072
dda8d76d 5073/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5074
015dc7e1 5075static bool
dda8d76d 5076process_file_header (Filedata * filedata)
252b5132 5077{
dda8d76d
NC
5078 Elf_Internal_Ehdr * header = & filedata->file_header;
5079
5080 if ( header->e_ident[EI_MAG0] != ELFMAG0
5081 || header->e_ident[EI_MAG1] != ELFMAG1
5082 || header->e_ident[EI_MAG2] != ELFMAG2
5083 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5084 {
5085 error
5086 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
015dc7e1 5087 return false;
252b5132
RH
5088 }
5089
ca0e11aa
NC
5090 if (! filedata->is_separate)
5091 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5092
252b5132
RH
5093 if (do_header)
5094 {
32ec8896 5095 unsigned i;
252b5132 5096
ca0e11aa
NC
5097 if (filedata->is_separate)
5098 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5099 else
5100 printf (_("ELF Header:\n"));
252b5132 5101 printf (_(" Magic: "));
b34976b6 5102 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5103 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5104 printf ("\n");
5105 printf (_(" Class: %s\n"),
dda8d76d 5106 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5107 printf (_(" Data: %s\n"),
dda8d76d 5108 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5109 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5110 header->e_ident[EI_VERSION],
5111 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5112 ? _(" (current)")
dda8d76d 5113 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5114 ? _(" <unknown>")
789be9f7 5115 : "")));
252b5132 5116 printf (_(" OS/ABI: %s\n"),
dda8d76d 5117 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5118 printf (_(" ABI Version: %d\n"),
dda8d76d 5119 header->e_ident[EI_ABIVERSION]);
252b5132 5120 printf (_(" Type: %s\n"),
dda8d76d 5121 get_file_type (header->e_type));
252b5132 5122 printf (_(" Machine: %s\n"),
dda8d76d 5123 get_machine_name (header->e_machine));
252b5132 5124 printf (_(" Version: 0x%lx\n"),
e8a64888 5125 header->e_version);
76da6bbe 5126
f7a99963 5127 printf (_(" Entry point address: "));
e8a64888 5128 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5129 printf (_("\n Start of program headers: "));
e8a64888 5130 print_vma (header->e_phoff, DEC);
f7a99963 5131 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5132 print_vma (header->e_shoff, DEC);
f7a99963 5133 printf (_(" (bytes into file)\n"));
76da6bbe 5134
252b5132 5135 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5136 header->e_flags,
dda8d76d 5137 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5138 printf (_(" Size of this header: %u (bytes)\n"),
5139 header->e_ehsize);
5140 printf (_(" Size of program headers: %u (bytes)\n"),
5141 header->e_phentsize);
5142 printf (_(" Number of program headers: %u"),
5143 header->e_phnum);
dda8d76d
NC
5144 if (filedata->section_headers != NULL
5145 && header->e_phnum == PN_XNUM
5146 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
5147 {
5148 header->e_phnum = filedata->section_headers[0].sh_info;
5149 printf (" (%u)", header->e_phnum);
5150 }
2046a35d 5151 putc ('\n', stdout);
e8a64888
AM
5152 printf (_(" Size of section headers: %u (bytes)\n"),
5153 header->e_shentsize);
5154 printf (_(" Number of section headers: %u"),
5155 header->e_shnum);
dda8d76d 5156 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5157 {
5158 header->e_shnum = filedata->section_headers[0].sh_size;
5159 printf (" (%u)", header->e_shnum);
5160 }
560f3c1c 5161 putc ('\n', stdout);
e8a64888
AM
5162 printf (_(" Section header string table index: %u"),
5163 header->e_shstrndx);
dda8d76d
NC
5164 if (filedata->section_headers != NULL
5165 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5166 {
5167 header->e_shstrndx = filedata->section_headers[0].sh_link;
5168 printf (" (%u)", header->e_shstrndx);
5169 }
5170 if (header->e_shstrndx != SHN_UNDEF
5171 && header->e_shstrndx >= header->e_shnum)
5172 {
5173 header->e_shstrndx = SHN_UNDEF;
5174 printf (_(" <corrupt: out of range>"));
5175 }
560f3c1c
AM
5176 putc ('\n', stdout);
5177 }
5178
dda8d76d 5179 if (filedata->section_headers != NULL)
560f3c1c 5180 {
dda8d76d
NC
5181 if (header->e_phnum == PN_XNUM
5182 && filedata->section_headers[0].sh_info != 0)
5183 header->e_phnum = filedata->section_headers[0].sh_info;
5184 if (header->e_shnum == SHN_UNDEF)
5185 header->e_shnum = filedata->section_headers[0].sh_size;
5186 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5187 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5188 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
5189 header->e_shstrndx = SHN_UNDEF;
5190 free (filedata->section_headers);
5191 filedata->section_headers = NULL;
252b5132 5192 }
103f02d3 5193
015dc7e1 5194 return true;
9ea033b2
NC
5195}
5196
dda8d76d
NC
5197/* Read in the program headers from FILEDATA and store them in PHEADERS.
5198 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5199
015dc7e1 5200static bool
dda8d76d 5201get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5202{
2cf0635d
NC
5203 Elf32_External_Phdr * phdrs;
5204 Elf32_External_Phdr * external;
5205 Elf_Internal_Phdr * internal;
b34976b6 5206 unsigned int i;
dda8d76d
NC
5207 unsigned int size = filedata->file_header.e_phentsize;
5208 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5209
5210 /* PR binutils/17531: Cope with unexpected section header sizes. */
5211 if (size == 0 || num == 0)
015dc7e1 5212 return false;
e0a31db1
NC
5213 if (size < sizeof * phdrs)
5214 {
5215 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5216 return false;
e0a31db1
NC
5217 }
5218 if (size > sizeof * phdrs)
5219 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5220
dda8d76d 5221 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5222 size, num, _("program headers"));
5223 if (phdrs == NULL)
015dc7e1 5224 return false;
9ea033b2 5225
91d6fa6a 5226 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5227 i < filedata->file_header.e_phnum;
b34976b6 5228 i++, internal++, external++)
252b5132 5229 {
9ea033b2
NC
5230 internal->p_type = BYTE_GET (external->p_type);
5231 internal->p_offset = BYTE_GET (external->p_offset);
5232 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5233 internal->p_paddr = BYTE_GET (external->p_paddr);
5234 internal->p_filesz = BYTE_GET (external->p_filesz);
5235 internal->p_memsz = BYTE_GET (external->p_memsz);
5236 internal->p_flags = BYTE_GET (external->p_flags);
5237 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5238 }
5239
9ea033b2 5240 free (phdrs);
015dc7e1 5241 return true;
252b5132
RH
5242}
5243
dda8d76d
NC
5244/* Read in the program headers from FILEDATA and store them in PHEADERS.
5245 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5246
015dc7e1 5247static bool
dda8d76d 5248get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5249{
2cf0635d
NC
5250 Elf64_External_Phdr * phdrs;
5251 Elf64_External_Phdr * external;
5252 Elf_Internal_Phdr * internal;
b34976b6 5253 unsigned int i;
dda8d76d
NC
5254 unsigned int size = filedata->file_header.e_phentsize;
5255 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5256
5257 /* PR binutils/17531: Cope with unexpected section header sizes. */
5258 if (size == 0 || num == 0)
015dc7e1 5259 return false;
e0a31db1
NC
5260 if (size < sizeof * phdrs)
5261 {
5262 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5263 return false;
e0a31db1
NC
5264 }
5265 if (size > sizeof * phdrs)
5266 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5267
dda8d76d 5268 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5269 size, num, _("program headers"));
a6e9f9df 5270 if (!phdrs)
015dc7e1 5271 return false;
9ea033b2 5272
91d6fa6a 5273 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5274 i < filedata->file_header.e_phnum;
b34976b6 5275 i++, internal++, external++)
9ea033b2
NC
5276 {
5277 internal->p_type = BYTE_GET (external->p_type);
5278 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5279 internal->p_offset = BYTE_GET (external->p_offset);
5280 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5281 internal->p_paddr = BYTE_GET (external->p_paddr);
5282 internal->p_filesz = BYTE_GET (external->p_filesz);
5283 internal->p_memsz = BYTE_GET (external->p_memsz);
5284 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5285 }
5286
5287 free (phdrs);
015dc7e1 5288 return true;
9ea033b2 5289}
252b5132 5290
32ec8896 5291/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5292
015dc7e1 5293static bool
dda8d76d 5294get_program_headers (Filedata * filedata)
d93f0186 5295{
2cf0635d 5296 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5297
5298 /* Check cache of prior read. */
dda8d76d 5299 if (filedata->program_headers != NULL)
015dc7e1 5300 return true;
d93f0186 5301
82156ab7
NC
5302 /* Be kind to memory checkers by looking for
5303 e_phnum values which we know must be invalid. */
dda8d76d 5304 if (filedata->file_header.e_phnum
82156ab7 5305 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5306 >= filedata->file_size)
82156ab7
NC
5307 {
5308 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5309 filedata->file_header.e_phnum);
015dc7e1 5310 return false;
82156ab7 5311 }
d93f0186 5312
dda8d76d 5313 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5314 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5315 if (phdrs == NULL)
5316 {
8b73c356 5317 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5318 filedata->file_header.e_phnum);
015dc7e1 5319 return false;
d93f0186
NC
5320 }
5321
5322 if (is_32bit_elf
dda8d76d
NC
5323 ? get_32bit_program_headers (filedata, phdrs)
5324 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5325 {
dda8d76d 5326 filedata->program_headers = phdrs;
015dc7e1 5327 return true;
d93f0186
NC
5328 }
5329
5330 free (phdrs);
015dc7e1 5331 return false;
d93f0186
NC
5332}
5333
32ec8896 5334/* Returns TRUE if the program headers were loaded. */
2f62977e 5335
015dc7e1 5336static bool
dda8d76d 5337process_program_headers (Filedata * filedata)
252b5132 5338{
2cf0635d 5339 Elf_Internal_Phdr * segment;
b34976b6 5340 unsigned int i;
1a9ccd70 5341 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5342
978c4450
AM
5343 filedata->dynamic_addr = 0;
5344 filedata->dynamic_size = 0;
663f67df 5345
dda8d76d 5346 if (filedata->file_header.e_phnum == 0)
252b5132 5347 {
82f2dbf7 5348 /* PR binutils/12467. */
dda8d76d 5349 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5350 {
5351 warn (_("possibly corrupt ELF header - it has a non-zero program"
5352 " header offset, but no program headers\n"));
015dc7e1 5353 return false;
32ec8896 5354 }
82f2dbf7 5355 else if (do_segments)
ca0e11aa
NC
5356 {
5357 if (filedata->is_separate)
5358 printf (_("\nThere are no program headers in linked file '%s'.\n"),
5359 filedata->file_name);
5360 else
5361 printf (_("\nThere are no program headers in this file.\n"));
5362 }
015dc7e1 5363 return true;
252b5132
RH
5364 }
5365
5366 if (do_segments && !do_header)
5367 {
ca0e11aa
NC
5368 if (filedata->is_separate)
5369 printf ("\nIn linked file '%s' the ELF file type is %s\n",
5370 filedata->file_name,
5371 get_file_type (filedata->file_header.e_type));
5372 else
5373 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
dda8d76d 5374 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5375 printf (ngettext ("There is %d program header, starting at offset %s\n",
5376 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5377 filedata->file_header.e_phnum),
5378 filedata->file_header.e_phnum,
5379 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5380 }
5381
dda8d76d 5382 if (! get_program_headers (filedata))
015dc7e1 5383 return true;
103f02d3 5384
252b5132
RH
5385 if (do_segments)
5386 {
dda8d76d 5387 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5388 printf (_("\nProgram Headers:\n"));
5389 else
5390 printf (_("\nProgram Headers:\n"));
76da6bbe 5391
f7a99963
NC
5392 if (is_32bit_elf)
5393 printf
5394 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5395 else if (do_wide)
5396 printf
5397 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5398 else
5399 {
5400 printf
5401 (_(" Type Offset VirtAddr PhysAddr\n"));
5402 printf
5403 (_(" FileSiz MemSiz Flags Align\n"));
5404 }
252b5132
RH
5405 }
5406
dda8d76d
NC
5407 for (i = 0, segment = filedata->program_headers;
5408 i < filedata->file_header.e_phnum;
b34976b6 5409 i++, segment++)
252b5132
RH
5410 {
5411 if (do_segments)
5412 {
dda8d76d 5413 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5414
5415 if (is_32bit_elf)
5416 {
5417 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5418 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5419 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5420 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5421 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5422 printf ("%c%c%c ",
5423 (segment->p_flags & PF_R ? 'R' : ' '),
5424 (segment->p_flags & PF_W ? 'W' : ' '),
5425 (segment->p_flags & PF_X ? 'E' : ' '));
5426 printf ("%#lx", (unsigned long) segment->p_align);
5427 }
d974e256
JJ
5428 else if (do_wide)
5429 {
5430 if ((unsigned long) segment->p_offset == segment->p_offset)
5431 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5432 else
5433 {
5434 print_vma (segment->p_offset, FULL_HEX);
5435 putchar (' ');
5436 }
5437
5438 print_vma (segment->p_vaddr, FULL_HEX);
5439 putchar (' ');
5440 print_vma (segment->p_paddr, FULL_HEX);
5441 putchar (' ');
5442
5443 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5444 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5445 else
5446 {
5447 print_vma (segment->p_filesz, FULL_HEX);
5448 putchar (' ');
5449 }
5450
5451 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5452 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5453 else
5454 {
f48e6c45 5455 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5456 }
5457
5458 printf (" %c%c%c ",
5459 (segment->p_flags & PF_R ? 'R' : ' '),
5460 (segment->p_flags & PF_W ? 'W' : ' '),
5461 (segment->p_flags & PF_X ? 'E' : ' '));
5462
5463 if ((unsigned long) segment->p_align == segment->p_align)
5464 printf ("%#lx", (unsigned long) segment->p_align);
5465 else
5466 {
5467 print_vma (segment->p_align, PREFIX_HEX);
5468 }
5469 }
f7a99963
NC
5470 else
5471 {
5472 print_vma (segment->p_offset, FULL_HEX);
5473 putchar (' ');
5474 print_vma (segment->p_vaddr, FULL_HEX);
5475 putchar (' ');
5476 print_vma (segment->p_paddr, FULL_HEX);
5477 printf ("\n ");
5478 print_vma (segment->p_filesz, FULL_HEX);
5479 putchar (' ');
5480 print_vma (segment->p_memsz, FULL_HEX);
5481 printf (" %c%c%c ",
5482 (segment->p_flags & PF_R ? 'R' : ' '),
5483 (segment->p_flags & PF_W ? 'W' : ' '),
5484 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5485 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5486 }
252b5132 5487
1a9ccd70
NC
5488 putc ('\n', stdout);
5489 }
f54498b4 5490
252b5132
RH
5491 switch (segment->p_type)
5492 {
1a9ccd70 5493 case PT_LOAD:
502d895c
NC
5494#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5495 required by the ELF standard, several programs, including the Linux
5496 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5497 if (previous_load
5498 && previous_load->p_vaddr > segment->p_vaddr)
5499 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5500#endif
1a9ccd70
NC
5501 if (segment->p_memsz < segment->p_filesz)
5502 error (_("the segment's file size is larger than its memory size\n"));
5503 previous_load = segment;
5504 break;
5505
5506 case PT_PHDR:
5507 /* PR 20815 - Verify that the program header is loaded into memory. */
5508 if (i > 0 && previous_load != NULL)
5509 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5510 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5511 {
5512 unsigned int j;
5513
dda8d76d 5514 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5515 {
5516 Elf_Internal_Phdr *load = filedata->program_headers + j;
5517 if (load->p_type == PT_LOAD
5518 && load->p_offset <= segment->p_offset
5519 && (load->p_offset + load->p_filesz
5520 >= segment->p_offset + segment->p_filesz)
5521 && load->p_vaddr <= segment->p_vaddr
5522 && (load->p_vaddr + load->p_filesz
5523 >= segment->p_vaddr + segment->p_filesz))
5524 break;
5525 }
dda8d76d 5526 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5527 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5528 }
5529 break;
5530
252b5132 5531 case PT_DYNAMIC:
978c4450 5532 if (filedata->dynamic_addr)
252b5132
RH
5533 error (_("more than one dynamic segment\n"));
5534
20737c13
AM
5535 /* By default, assume that the .dynamic section is the first
5536 section in the DYNAMIC segment. */
978c4450
AM
5537 filedata->dynamic_addr = segment->p_offset;
5538 filedata->dynamic_size = segment->p_filesz;
20737c13 5539
b2d38a17
NC
5540 /* Try to locate the .dynamic section. If there is
5541 a section header table, we can easily locate it. */
dda8d76d 5542 if (filedata->section_headers != NULL)
b2d38a17 5543 {
2cf0635d 5544 Elf_Internal_Shdr * sec;
b2d38a17 5545
dda8d76d 5546 sec = find_section (filedata, ".dynamic");
89fac5e3 5547 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5548 {
28f997cf
TG
5549 /* A corresponding .dynamic section is expected, but on
5550 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5551 if (!is_ia64_vms (filedata))
28f997cf 5552 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5553 break;
5554 }
5555
42bb2e33 5556 if (sec->sh_type == SHT_NOBITS)
20737c13 5557 {
978c4450 5558 filedata->dynamic_size = 0;
20737c13
AM
5559 break;
5560 }
42bb2e33 5561
978c4450
AM
5562 filedata->dynamic_addr = sec->sh_offset;
5563 filedata->dynamic_size = sec->sh_size;
b2d38a17 5564
8ac10c5b
L
5565 /* The PT_DYNAMIC segment, which is used by the run-time
5566 loader, should exactly match the .dynamic section. */
5567 if (do_checks
5568 && (filedata->dynamic_addr != segment->p_offset
5569 || filedata->dynamic_size != segment->p_filesz))
5570 warn (_("\
5571the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 5572 }
39e224f6
MW
5573
5574 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5575 segment. Check this after matching against the section headers
5576 so we don't warn on debuginfo file (which have NOBITS .dynamic
5577 sections). */
978c4450
AM
5578 if (filedata->dynamic_addr > filedata->file_size
5579 || (filedata->dynamic_size
5580 > filedata->file_size - filedata->dynamic_addr))
39e224f6
MW
5581 {
5582 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
978c4450 5583 filedata->dynamic_addr = filedata->dynamic_size = 0;
39e224f6 5584 }
252b5132
RH
5585 break;
5586
5587 case PT_INTERP:
13acb58d
AM
5588 if (segment->p_offset >= filedata->file_size
5589 || segment->p_filesz > filedata->file_size - segment->p_offset
5590 || segment->p_filesz - 1 >= (size_t) -2
5591 || fseek (filedata->handle,
5592 filedata->archive_file_offset + (long) segment->p_offset,
5593 SEEK_SET))
252b5132
RH
5594 error (_("Unable to find program interpreter name\n"));
5595 else
5596 {
13acb58d
AM
5597 size_t len = segment->p_filesz;
5598 free (filedata->program_interpreter);
5599 filedata->program_interpreter = xmalloc (len + 1);
5600 len = fread (filedata->program_interpreter, 1, len,
5601 filedata->handle);
5602 filedata->program_interpreter[len] = 0;
252b5132
RH
5603
5604 if (do_segments)
f54498b4 5605 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 5606 filedata->program_interpreter);
252b5132
RH
5607 }
5608 break;
5609 }
252b5132
RH
5610 }
5611
dda8d76d
NC
5612 if (do_segments
5613 && filedata->section_headers != NULL
5614 && filedata->string_table != NULL)
252b5132
RH
5615 {
5616 printf (_("\n Section to Segment mapping:\n"));
5617 printf (_(" Segment Sections...\n"));
5618
dda8d76d 5619 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5620 {
9ad5cbcf 5621 unsigned int j;
2cf0635d 5622 Elf_Internal_Shdr * section;
252b5132 5623
dda8d76d
NC
5624 segment = filedata->program_headers + i;
5625 section = filedata->section_headers + 1;
252b5132
RH
5626
5627 printf (" %2.2d ", i);
5628
dda8d76d 5629 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5630 {
f4638467
AM
5631 if (!ELF_TBSS_SPECIAL (section, segment)
5632 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5633 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5634 }
5635
5636 putc ('\n',stdout);
5637 }
5638 }
5639
015dc7e1 5640 return true;
252b5132
RH
5641}
5642
5643
d93f0186
NC
5644/* Find the file offset corresponding to VMA by using the program headers. */
5645
5646static long
dda8d76d 5647offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5648{
2cf0635d 5649 Elf_Internal_Phdr * seg;
d93f0186 5650
dda8d76d 5651 if (! get_program_headers (filedata))
d93f0186
NC
5652 {
5653 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5654 return (long) vma;
5655 }
5656
dda8d76d
NC
5657 for (seg = filedata->program_headers;
5658 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5659 ++seg)
5660 {
5661 if (seg->p_type != PT_LOAD)
5662 continue;
5663
5664 if (vma >= (seg->p_vaddr & -seg->p_align)
5665 && vma + size <= seg->p_vaddr + seg->p_filesz)
5666 return vma - seg->p_vaddr + seg->p_offset;
5667 }
5668
5669 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5670 (unsigned long) vma);
d93f0186
NC
5671 return (long) vma;
5672}
5673
5674
dda8d76d
NC
5675/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5676 If PROBE is true, this is just a probe and we do not generate any error
5677 messages if the load fails. */
049b0c3a 5678
015dc7e1
AM
5679static bool
5680get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 5681{
2cf0635d
NC
5682 Elf32_External_Shdr * shdrs;
5683 Elf_Internal_Shdr * internal;
dda8d76d
NC
5684 unsigned int i;
5685 unsigned int size = filedata->file_header.e_shentsize;
5686 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5687
5688 /* PR binutils/17531: Cope with unexpected section header sizes. */
5689 if (size == 0 || num == 0)
015dc7e1 5690 return false;
049b0c3a
NC
5691 if (size < sizeof * shdrs)
5692 {
5693 if (! probe)
5694 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 5695 return false;
049b0c3a
NC
5696 }
5697 if (!probe && size > sizeof * shdrs)
5698 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5699
dda8d76d 5700 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5701 size, num,
5702 probe ? NULL : _("section headers"));
5703 if (shdrs == NULL)
015dc7e1 5704 return false;
252b5132 5705
dda8d76d
NC
5706 free (filedata->section_headers);
5707 filedata->section_headers = (Elf_Internal_Shdr *)
5708 cmalloc (num, sizeof (Elf_Internal_Shdr));
5709 if (filedata->section_headers == NULL)
252b5132 5710 {
049b0c3a 5711 if (!probe)
8b73c356 5712 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5713 free (shdrs);
015dc7e1 5714 return false;
252b5132
RH
5715 }
5716
dda8d76d 5717 for (i = 0, internal = filedata->section_headers;
560f3c1c 5718 i < num;
b34976b6 5719 i++, internal++)
252b5132
RH
5720 {
5721 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5722 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5723 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5724 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5725 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5726 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5727 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5728 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5729 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5730 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5731 if (!probe && internal->sh_link > num)
5732 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5733 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5734 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5735 }
5736
5737 free (shdrs);
015dc7e1 5738 return true;
252b5132
RH
5739}
5740
dda8d76d
NC
5741/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5742
015dc7e1
AM
5743static bool
5744get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 5745{
dda8d76d
NC
5746 Elf64_External_Shdr * shdrs;
5747 Elf_Internal_Shdr * internal;
5748 unsigned int i;
5749 unsigned int size = filedata->file_header.e_shentsize;
5750 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5751
5752 /* PR binutils/17531: Cope with unexpected section header sizes. */
5753 if (size == 0 || num == 0)
015dc7e1 5754 return false;
dda8d76d 5755
049b0c3a
NC
5756 if (size < sizeof * shdrs)
5757 {
5758 if (! probe)
5759 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 5760 return false;
049b0c3a 5761 }
dda8d76d 5762
049b0c3a
NC
5763 if (! probe && size > sizeof * shdrs)
5764 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5765
dda8d76d
NC
5766 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5767 filedata->file_header.e_shoff,
049b0c3a
NC
5768 size, num,
5769 probe ? NULL : _("section headers"));
5770 if (shdrs == NULL)
015dc7e1 5771 return false;
9ea033b2 5772
dda8d76d
NC
5773 free (filedata->section_headers);
5774 filedata->section_headers = (Elf_Internal_Shdr *)
5775 cmalloc (num, sizeof (Elf_Internal_Shdr));
5776 if (filedata->section_headers == NULL)
9ea033b2 5777 {
049b0c3a 5778 if (! probe)
8b73c356 5779 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5780 free (shdrs);
015dc7e1 5781 return false;
9ea033b2
NC
5782 }
5783
dda8d76d 5784 for (i = 0, internal = filedata->section_headers;
560f3c1c 5785 i < num;
b34976b6 5786 i++, internal++)
9ea033b2
NC
5787 {
5788 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5789 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5790 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5791 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5792 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5793 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5794 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5795 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5796 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5797 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5798 if (!probe && internal->sh_link > num)
5799 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5800 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5801 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5802 }
5803
5804 free (shdrs);
015dc7e1 5805 return true;
9ea033b2
NC
5806}
5807
252b5132 5808static Elf_Internal_Sym *
dda8d76d
NC
5809get_32bit_elf_symbols (Filedata * filedata,
5810 Elf_Internal_Shdr * section,
5811 unsigned long * num_syms_return)
252b5132 5812{
ba5cdace 5813 unsigned long number = 0;
dd24e3da 5814 Elf32_External_Sym * esyms = NULL;
ba5cdace 5815 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5816 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5817 Elf_Internal_Sym * psym;
b34976b6 5818 unsigned int j;
e3d39609 5819 elf_section_list * entry;
252b5132 5820
c9c1d674
EG
5821 if (section->sh_size == 0)
5822 {
5823 if (num_syms_return != NULL)
5824 * num_syms_return = 0;
5825 return NULL;
5826 }
5827
dd24e3da 5828 /* Run some sanity checks first. */
c9c1d674 5829 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5830 {
c9c1d674 5831 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5832 printable_section_name (filedata, section),
5833 (unsigned long) section->sh_entsize);
ba5cdace 5834 goto exit_point;
dd24e3da
NC
5835 }
5836
dda8d76d 5837 if (section->sh_size > filedata->file_size)
f54498b4
NC
5838 {
5839 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5840 printable_section_name (filedata, section),
5841 (unsigned long) section->sh_size);
f54498b4
NC
5842 goto exit_point;
5843 }
5844
dd24e3da
NC
5845 number = section->sh_size / section->sh_entsize;
5846
5847 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5848 {
c9c1d674 5849 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5850 (unsigned long) section->sh_size,
dda8d76d 5851 printable_section_name (filedata, section),
8066deb1 5852 (unsigned long) section->sh_entsize);
ba5cdace 5853 goto exit_point;
dd24e3da
NC
5854 }
5855
dda8d76d 5856 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5857 section->sh_size, _("symbols"));
dd24e3da 5858 if (esyms == NULL)
ba5cdace 5859 goto exit_point;
252b5132 5860
e3d39609 5861 shndx = NULL;
978c4450 5862 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5863 {
5864 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5865 continue;
5866
5867 if (shndx != NULL)
5868 {
5869 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5870 free (shndx);
5871 }
5872
5873 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5874 entry->hdr->sh_offset,
5875 1, entry->hdr->sh_size,
5876 _("symbol table section indices"));
5877 if (shndx == NULL)
5878 goto exit_point;
5879
5880 /* PR17531: file: heap-buffer-overflow */
5881 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5882 {
5883 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5884 printable_section_name (filedata, entry->hdr),
5885 (unsigned long) entry->hdr->sh_size,
5886 (unsigned long) section->sh_size);
5887 goto exit_point;
c9c1d674 5888 }
e3d39609 5889 }
9ad5cbcf 5890
3f5e193b 5891 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5892
5893 if (isyms == NULL)
5894 {
8b73c356
NC
5895 error (_("Out of memory reading %lu symbols\n"),
5896 (unsigned long) number);
dd24e3da 5897 goto exit_point;
252b5132
RH
5898 }
5899
dd24e3da 5900 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5901 {
5902 psym->st_name = BYTE_GET (esyms[j].st_name);
5903 psym->st_value = BYTE_GET (esyms[j].st_value);
5904 psym->st_size = BYTE_GET (esyms[j].st_size);
5905 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5906 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5907 psym->st_shndx
5908 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5909 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5910 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5911 psym->st_info = BYTE_GET (esyms[j].st_info);
5912 psym->st_other = BYTE_GET (esyms[j].st_other);
5913 }
5914
dd24e3da 5915 exit_point:
e3d39609
NC
5916 free (shndx);
5917 free (esyms);
252b5132 5918
ba5cdace
NC
5919 if (num_syms_return != NULL)
5920 * num_syms_return = isyms == NULL ? 0 : number;
5921
252b5132
RH
5922 return isyms;
5923}
5924
9ea033b2 5925static Elf_Internal_Sym *
dda8d76d
NC
5926get_64bit_elf_symbols (Filedata * filedata,
5927 Elf_Internal_Shdr * section,
5928 unsigned long * num_syms_return)
9ea033b2 5929{
ba5cdace
NC
5930 unsigned long number = 0;
5931 Elf64_External_Sym * esyms = NULL;
5932 Elf_External_Sym_Shndx * shndx = NULL;
5933 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5934 Elf_Internal_Sym * psym;
b34976b6 5935 unsigned int j;
e3d39609 5936 elf_section_list * entry;
9ea033b2 5937
c9c1d674
EG
5938 if (section->sh_size == 0)
5939 {
5940 if (num_syms_return != NULL)
5941 * num_syms_return = 0;
5942 return NULL;
5943 }
5944
dd24e3da 5945 /* Run some sanity checks first. */
c9c1d674 5946 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5947 {
c9c1d674 5948 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5949 printable_section_name (filedata, section),
8066deb1 5950 (unsigned long) section->sh_entsize);
ba5cdace 5951 goto exit_point;
dd24e3da
NC
5952 }
5953
dda8d76d 5954 if (section->sh_size > filedata->file_size)
f54498b4
NC
5955 {
5956 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5957 printable_section_name (filedata, section),
8066deb1 5958 (unsigned long) section->sh_size);
f54498b4
NC
5959 goto exit_point;
5960 }
5961
dd24e3da
NC
5962 number = section->sh_size / section->sh_entsize;
5963
5964 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5965 {
c9c1d674 5966 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5967 (unsigned long) section->sh_size,
dda8d76d 5968 printable_section_name (filedata, section),
8066deb1 5969 (unsigned long) section->sh_entsize);
ba5cdace 5970 goto exit_point;
dd24e3da
NC
5971 }
5972
dda8d76d 5973 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5974 section->sh_size, _("symbols"));
a6e9f9df 5975 if (!esyms)
ba5cdace 5976 goto exit_point;
9ea033b2 5977
e3d39609 5978 shndx = NULL;
978c4450 5979 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5980 {
5981 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5982 continue;
5983
5984 if (shndx != NULL)
5985 {
5986 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5987 free (shndx);
c9c1d674 5988 }
e3d39609
NC
5989
5990 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5991 entry->hdr->sh_offset,
5992 1, entry->hdr->sh_size,
5993 _("symbol table section indices"));
5994 if (shndx == NULL)
5995 goto exit_point;
5996
5997 /* PR17531: file: heap-buffer-overflow */
5998 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5999 {
6000 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6001 printable_section_name (filedata, entry->hdr),
6002 (unsigned long) entry->hdr->sh_size,
6003 (unsigned long) section->sh_size);
6004 goto exit_point;
6005 }
6006 }
9ad5cbcf 6007
3f5e193b 6008 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6009
6010 if (isyms == NULL)
6011 {
8b73c356
NC
6012 error (_("Out of memory reading %lu symbols\n"),
6013 (unsigned long) number);
ba5cdace 6014 goto exit_point;
9ea033b2
NC
6015 }
6016
ba5cdace 6017 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6018 {
6019 psym->st_name = BYTE_GET (esyms[j].st_name);
6020 psym->st_info = BYTE_GET (esyms[j].st_info);
6021 psym->st_other = BYTE_GET (esyms[j].st_other);
6022 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6023
4fbb74a6 6024 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6025 psym->st_shndx
6026 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6027 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6028 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6029
66543521
AM
6030 psym->st_value = BYTE_GET (esyms[j].st_value);
6031 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6032 }
6033
ba5cdace 6034 exit_point:
e3d39609
NC
6035 free (shndx);
6036 free (esyms);
ba5cdace
NC
6037
6038 if (num_syms_return != NULL)
6039 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6040
6041 return isyms;
6042}
6043
d1133906 6044static const char *
dda8d76d 6045get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 6046{
5477e8a0 6047 static char buff[1024];
2cf0635d 6048 char * p = buff;
32ec8896
NC
6049 unsigned int field_size = is_32bit_elf ? 8 : 16;
6050 signed int sindex;
6051 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
6052 bfd_vma os_flags = 0;
6053 bfd_vma proc_flags = 0;
6054 bfd_vma unknown_flags = 0;
148b93f2 6055 static const struct
5477e8a0 6056 {
2cf0635d 6057 const char * str;
32ec8896 6058 unsigned int len;
5477e8a0
L
6059 }
6060 flags [] =
6061 {
cfcac11d
NC
6062 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6063 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6064 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6065 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6066 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6067 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6068 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6069 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6070 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6071 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6072 /* IA-64 specific. */
6073 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6074 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6075 /* IA-64 OpenVMS specific. */
6076 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6077 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6078 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6079 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6080 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6081 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6082 /* Generic. */
cfcac11d 6083 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6084 /* SPARC specific. */
77115a4a 6085 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6086 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6087 /* ARM specific. */
6088 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6089 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6090 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6091 /* GNU specific. */
6092 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6093 /* VLE specific. */
6094 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6095 /* GNU specific. */
6096 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6097 };
6098
6099 if (do_section_details)
6100 {
8d5ff12c
L
6101 sprintf (buff, "[%*.*lx]: ",
6102 field_size, field_size, (unsigned long) sh_flags);
6103 p += field_size + 4;
5477e8a0 6104 }
76da6bbe 6105
d1133906
NC
6106 while (sh_flags)
6107 {
6108 bfd_vma flag;
6109
6110 flag = sh_flags & - sh_flags;
6111 sh_flags &= ~ flag;
76da6bbe 6112
5477e8a0 6113 if (do_section_details)
d1133906 6114 {
5477e8a0
L
6115 switch (flag)
6116 {
91d6fa6a
NC
6117 case SHF_WRITE: sindex = 0; break;
6118 case SHF_ALLOC: sindex = 1; break;
6119 case SHF_EXECINSTR: sindex = 2; break;
6120 case SHF_MERGE: sindex = 3; break;
6121 case SHF_STRINGS: sindex = 4; break;
6122 case SHF_INFO_LINK: sindex = 5; break;
6123 case SHF_LINK_ORDER: sindex = 6; break;
6124 case SHF_OS_NONCONFORMING: sindex = 7; break;
6125 case SHF_GROUP: sindex = 8; break;
6126 case SHF_TLS: sindex = 9; break;
18ae9cc1 6127 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6128 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6129
5477e8a0 6130 default:
91d6fa6a 6131 sindex = -1;
dda8d76d 6132 switch (filedata->file_header.e_machine)
148b93f2 6133 {
cfcac11d 6134 case EM_IA_64:
148b93f2 6135 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6136 sindex = 10;
148b93f2 6137 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6138 sindex = 11;
148b93f2 6139#ifdef BFD64
dda8d76d 6140 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6141 switch (flag)
6142 {
91d6fa6a
NC
6143 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6144 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6145 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6146 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6147 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6148 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6149 default: break;
6150 }
6151#endif
cfcac11d
NC
6152 break;
6153
caa83f8b 6154 case EM_386:
22abe556 6155 case EM_IAMCU:
caa83f8b 6156 case EM_X86_64:
7f502d6c 6157 case EM_L1OM:
7a9068fe 6158 case EM_K1OM:
cfcac11d
NC
6159 case EM_OLD_SPARCV9:
6160 case EM_SPARC32PLUS:
6161 case EM_SPARCV9:
6162 case EM_SPARC:
18ae9cc1 6163 if (flag == SHF_ORDERED)
91d6fa6a 6164 sindex = 19;
cfcac11d 6165 break;
ac4c9b04
MG
6166
6167 case EM_ARM:
6168 switch (flag)
6169 {
6170 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6171 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6172 case SHF_COMDEF: sindex = 23; break;
6173 default: break;
6174 }
6175 break;
83eef883
AFB
6176 case EM_PPC:
6177 if (flag == SHF_PPC_VLE)
6178 sindex = 25;
6179 break;
99fabbc9
JL
6180 default:
6181 break;
6182 }
ac4c9b04 6183
99fabbc9
JL
6184 switch (filedata->file_header.e_ident[EI_OSABI])
6185 {
6186 case ELFOSABI_GNU:
6187 case ELFOSABI_FREEBSD:
6188 if (flag == SHF_GNU_RETAIN)
6189 sindex = 26;
6190 /* Fall through */
6191 case ELFOSABI_NONE:
6192 if (flag == SHF_GNU_MBIND)
6193 /* We should not recognize SHF_GNU_MBIND for
6194 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6195 not set the EI_OSABI header byte. */
6196 sindex = 24;
6197 break;
cfcac11d
NC
6198 default:
6199 break;
148b93f2 6200 }
99fabbc9 6201 break;
5477e8a0
L
6202 }
6203
91d6fa6a 6204 if (sindex != -1)
5477e8a0 6205 {
8d5ff12c
L
6206 if (p != buff + field_size + 4)
6207 {
6208 if (size < (10 + 2))
bee0ee85
NC
6209 {
6210 warn (_("Internal error: not enough buffer room for section flag info"));
6211 return _("<unknown>");
6212 }
8d5ff12c
L
6213 size -= 2;
6214 *p++ = ',';
6215 *p++ = ' ';
6216 }
6217
91d6fa6a
NC
6218 size -= flags [sindex].len;
6219 p = stpcpy (p, flags [sindex].str);
5477e8a0 6220 }
3b22753a 6221 else if (flag & SHF_MASKOS)
8d5ff12c 6222 os_flags |= flag;
d1133906 6223 else if (flag & SHF_MASKPROC)
8d5ff12c 6224 proc_flags |= flag;
d1133906 6225 else
8d5ff12c 6226 unknown_flags |= flag;
5477e8a0
L
6227 }
6228 else
6229 {
6230 switch (flag)
6231 {
6232 case SHF_WRITE: *p = 'W'; break;
6233 case SHF_ALLOC: *p = 'A'; break;
6234 case SHF_EXECINSTR: *p = 'X'; break;
6235 case SHF_MERGE: *p = 'M'; break;
6236 case SHF_STRINGS: *p = 'S'; break;
6237 case SHF_INFO_LINK: *p = 'I'; break;
6238 case SHF_LINK_ORDER: *p = 'L'; break;
6239 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6240 case SHF_GROUP: *p = 'G'; break;
6241 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6242 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6243 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6244
6245 default:
dda8d76d
NC
6246 if ((filedata->file_header.e_machine == EM_X86_64
6247 || filedata->file_header.e_machine == EM_L1OM
6248 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6249 && flag == SHF_X86_64_LARGE)
6250 *p = 'l';
dda8d76d 6251 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6252 && flag == SHF_ARM_PURECODE)
99fabbc9 6253 *p = 'y';
dda8d76d 6254 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6255 && flag == SHF_PPC_VLE)
99fabbc9 6256 *p = 'v';
5477e8a0
L
6257 else if (flag & SHF_MASKOS)
6258 {
99fabbc9
JL
6259 switch (filedata->file_header.e_ident[EI_OSABI])
6260 {
6261 case ELFOSABI_GNU:
6262 case ELFOSABI_FREEBSD:
6263 if (flag == SHF_GNU_RETAIN)
6264 {
6265 *p = 'R';
6266 break;
6267 }
6268 /* Fall through */
6269 case ELFOSABI_NONE:
6270 if (flag == SHF_GNU_MBIND)
6271 {
6272 /* We should not recognize SHF_GNU_MBIND for
6273 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6274 not set the EI_OSABI header byte. */
6275 *p = 'D';
6276 break;
6277 }
6278 /* Fall through */
6279 default:
6280 *p = 'o';
6281 sh_flags &= ~SHF_MASKOS;
6282 break;
6283 }
5477e8a0
L
6284 }
6285 else if (flag & SHF_MASKPROC)
6286 {
6287 *p = 'p';
6288 sh_flags &= ~ SHF_MASKPROC;
6289 }
6290 else
6291 *p = 'x';
6292 break;
6293 }
6294 p++;
d1133906
NC
6295 }
6296 }
76da6bbe 6297
8d5ff12c
L
6298 if (do_section_details)
6299 {
6300 if (os_flags)
6301 {
6302 size -= 5 + field_size;
6303 if (p != buff + field_size + 4)
6304 {
6305 if (size < (2 + 1))
bee0ee85
NC
6306 {
6307 warn (_("Internal error: not enough buffer room for section flag info"));
6308 return _("<unknown>");
6309 }
8d5ff12c
L
6310 size -= 2;
6311 *p++ = ',';
6312 *p++ = ' ';
6313 }
6314 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6315 (unsigned long) os_flags);
6316 p += 5 + field_size;
6317 }
6318 if (proc_flags)
6319 {
6320 size -= 7 + field_size;
6321 if (p != buff + field_size + 4)
6322 {
6323 if (size < (2 + 1))
bee0ee85
NC
6324 {
6325 warn (_("Internal error: not enough buffer room for section flag info"));
6326 return _("<unknown>");
6327 }
8d5ff12c
L
6328 size -= 2;
6329 *p++ = ',';
6330 *p++ = ' ';
6331 }
6332 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6333 (unsigned long) proc_flags);
6334 p += 7 + field_size;
6335 }
6336 if (unknown_flags)
6337 {
6338 size -= 10 + field_size;
6339 if (p != buff + field_size + 4)
6340 {
6341 if (size < (2 + 1))
bee0ee85
NC
6342 {
6343 warn (_("Internal error: not enough buffer room for section flag info"));
6344 return _("<unknown>");
6345 }
8d5ff12c
L
6346 size -= 2;
6347 *p++ = ',';
6348 *p++ = ' ';
6349 }
2b692964 6350 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6351 (unsigned long) unknown_flags);
6352 p += 10 + field_size;
6353 }
6354 }
6355
e9e44622 6356 *p = '\0';
d1133906
NC
6357 return buff;
6358}
6359
5844b465 6360static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6361get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6362{
6363 if (is_32bit_elf)
6364 {
6365 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6366
ebdf1ebf
NC
6367 if (size < sizeof (* echdr))
6368 {
6369 error (_("Compressed section is too small even for a compression header\n"));
6370 return 0;
6371 }
6372
77115a4a
L
6373 chdr->ch_type = BYTE_GET (echdr->ch_type);
6374 chdr->ch_size = BYTE_GET (echdr->ch_size);
6375 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6376 return sizeof (*echdr);
6377 }
6378 else
6379 {
6380 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6381
ebdf1ebf
NC
6382 if (size < sizeof (* echdr))
6383 {
6384 error (_("Compressed section is too small even for a compression header\n"));
6385 return 0;
6386 }
6387
77115a4a
L
6388 chdr->ch_type = BYTE_GET (echdr->ch_type);
6389 chdr->ch_size = BYTE_GET (echdr->ch_size);
6390 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6391 return sizeof (*echdr);
6392 }
6393}
6394
015dc7e1 6395static bool
dda8d76d 6396process_section_headers (Filedata * filedata)
252b5132 6397{
2cf0635d 6398 Elf_Internal_Shdr * section;
b34976b6 6399 unsigned int i;
252b5132 6400
8fb879cd 6401 free (filedata->section_headers);
dda8d76d 6402 filedata->section_headers = NULL;
978c4450
AM
6403 free (filedata->dynamic_symbols);
6404 filedata->dynamic_symbols = NULL;
6405 filedata->num_dynamic_syms = 0;
6406 free (filedata->dynamic_strings);
6407 filedata->dynamic_strings = NULL;
6408 filedata->dynamic_strings_length = 0;
6409 free (filedata->dynamic_syminfo);
6410 filedata->dynamic_syminfo = NULL;
6411 while (filedata->symtab_shndx_list != NULL)
8ff66993 6412 {
978c4450
AM
6413 elf_section_list *next = filedata->symtab_shndx_list->next;
6414 free (filedata->symtab_shndx_list);
6415 filedata->symtab_shndx_list = next;
8ff66993 6416 }
252b5132 6417
dda8d76d 6418 if (filedata->file_header.e_shnum == 0)
252b5132 6419 {
82f2dbf7 6420 /* PR binutils/12467. */
dda8d76d 6421 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6422 {
6423 warn (_("possibly corrupt ELF file header - it has a non-zero"
6424 " section header offset, but no section headers\n"));
015dc7e1 6425 return false;
32ec8896 6426 }
82f2dbf7 6427 else if (do_sections)
252b5132
RH
6428 printf (_("\nThere are no sections in this file.\n"));
6429
015dc7e1 6430 return true;
252b5132
RH
6431 }
6432
6433 if (do_sections && !do_header)
ca0e11aa
NC
6434 {
6435 if (filedata->is_separate && process_links)
6436 printf (_("In linked file '%s': "), filedata->file_name);
6437 if (! filedata->is_separate || process_links)
6438 printf (ngettext ("There is %d section header, "
6439 "starting at offset 0x%lx:\n",
6440 "There are %d section headers, "
6441 "starting at offset 0x%lx:\n",
6442 filedata->file_header.e_shnum),
6443 filedata->file_header.e_shnum,
6444 (unsigned long) filedata->file_header.e_shoff);
6445 }
252b5132 6446
9ea033b2
NC
6447 if (is_32bit_elf)
6448 {
015dc7e1
AM
6449 if (! get_32bit_section_headers (filedata, false))
6450 return false;
32ec8896
NC
6451 }
6452 else
6453 {
015dc7e1
AM
6454 if (! get_64bit_section_headers (filedata, false))
6455 return false;
9ea033b2 6456 }
252b5132
RH
6457
6458 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6459 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6460 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6461 {
dda8d76d 6462 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6463
c256ffe7
JJ
6464 if (section->sh_size != 0)
6465 {
dda8d76d
NC
6466 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6467 1, section->sh_size,
6468 _("string table"));
0de14b54 6469
dda8d76d 6470 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6471 }
252b5132
RH
6472 }
6473
6474 /* Scan the sections for the dynamic symbol table
e3c8793a 6475 and dynamic string table and debug sections. */
89fac5e3 6476 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6477 switch (filedata->file_header.e_machine)
89fac5e3
RS
6478 {
6479 case EM_MIPS:
6480 case EM_MIPS_RS3_LE:
6481 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6482 FDE addresses. However, the ABI also has a semi-official ILP32
6483 variant for which the normal FDE address size rules apply.
6484
6485 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6486 section, where XX is the size of longs in bits. Unfortunately,
6487 earlier compilers provided no way of distinguishing ILP32 objects
6488 from LP64 objects, so if there's any doubt, we should assume that
6489 the official LP64 form is being used. */
dda8d76d
NC
6490 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6491 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6492 eh_addr_size = 8;
6493 break;
0f56a26a
DD
6494
6495 case EM_H8_300:
6496 case EM_H8_300H:
dda8d76d 6497 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6498 {
6499 case E_H8_MACH_H8300:
6500 case E_H8_MACH_H8300HN:
6501 case E_H8_MACH_H8300SN:
6502 case E_H8_MACH_H8300SXN:
6503 eh_addr_size = 2;
6504 break;
6505 case E_H8_MACH_H8300H:
6506 case E_H8_MACH_H8300S:
6507 case E_H8_MACH_H8300SX:
6508 eh_addr_size = 4;
6509 break;
6510 }
f4236fe4
DD
6511 break;
6512
ff7eeb89 6513 case EM_M32C_OLD:
f4236fe4 6514 case EM_M32C:
dda8d76d 6515 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6516 {
6517 case EF_M32C_CPU_M16C:
6518 eh_addr_size = 2;
6519 break;
6520 }
6521 break;
89fac5e3
RS
6522 }
6523
76ca31c0
NC
6524#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6525 do \
6526 { \
6527 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6528 if (section->sh_entsize != expected_entsize) \
9dd3a467 6529 { \
76ca31c0
NC
6530 char buf[40]; \
6531 sprintf_vma (buf, section->sh_entsize); \
6532 /* Note: coded this way so that there is a single string for \
6533 translation. */ \
6534 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6535 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6536 (unsigned) expected_entsize); \
9dd3a467 6537 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6538 } \
6539 } \
08d8fa11 6540 while (0)
9dd3a467
NC
6541
6542#define CHECK_ENTSIZE(section, i, type) \
1b513401 6543 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
6544 sizeof (Elf64_External_##type))
6545
dda8d76d
NC
6546 for (i = 0, section = filedata->section_headers;
6547 i < filedata->file_header.e_shnum;
b34976b6 6548 i++, section++)
252b5132 6549 {
b9e920ec 6550 char * name = SECTION_NAME_PRINT (section);
252b5132 6551
1b513401
NC
6552 /* Run some sanity checks on the headers and
6553 possibly fill in some file data as well. */
6554 switch (section->sh_type)
252b5132 6555 {
1b513401 6556 case SHT_DYNSYM:
978c4450 6557 if (filedata->dynamic_symbols != NULL)
252b5132
RH
6558 {
6559 error (_("File contains multiple dynamic symbol tables\n"));
6560 continue;
6561 }
6562
08d8fa11 6563 CHECK_ENTSIZE (section, i, Sym);
978c4450
AM
6564 filedata->dynamic_symbols
6565 = GET_ELF_SYMBOLS (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 6566 filedata->dynamic_symtab_section = section;
1b513401
NC
6567 break;
6568
6569 case SHT_STRTAB:
6570 if (streq (name, ".dynstr"))
252b5132 6571 {
1b513401
NC
6572 if (filedata->dynamic_strings != NULL)
6573 {
6574 error (_("File contains multiple dynamic string tables\n"));
6575 continue;
6576 }
6577
6578 filedata->dynamic_strings
6579 = (char *) get_data (NULL, filedata, section->sh_offset,
6580 1, section->sh_size, _("dynamic strings"));
6581 filedata->dynamic_strings_length
6582 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 6583 filedata->dynamic_strtab_section = section;
252b5132 6584 }
1b513401
NC
6585 break;
6586
6587 case SHT_SYMTAB_SHNDX:
6588 {
6589 elf_section_list * entry = xmalloc (sizeof * entry);
6590
6591 entry->hdr = section;
6592 entry->next = filedata->symtab_shndx_list;
6593 filedata->symtab_shndx_list = entry;
6594 }
6595 break;
6596
6597 case SHT_SYMTAB:
6598 CHECK_ENTSIZE (section, i, Sym);
6599 break;
6600
6601 case SHT_GROUP:
6602 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6603 break;
252b5132 6604
1b513401
NC
6605 case SHT_REL:
6606 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 6607 if (do_checks && section->sh_size == 0)
1b513401
NC
6608 warn (_("Section '%s': zero-sized relocation section\n"), name);
6609 break;
6610
6611 case SHT_RELA:
6612 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 6613 if (do_checks && section->sh_size == 0)
1b513401
NC
6614 warn (_("Section '%s': zero-sized relocation section\n"), name);
6615 break;
6616
6617 case SHT_NOTE:
6618 case SHT_PROGBITS:
546cb2d8
NC
6619 /* Having a zero sized section is not illegal according to the
6620 ELF standard, but it might be an indication that something
6621 is wrong. So issue a warning if we are running in lint mode. */
6622 if (do_checks && section->sh_size == 0)
1b513401
NC
6623 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
6624 break;
6625
6626 default:
6627 break;
6628 }
6629
6630 if ((do_debugging || do_debug_info || do_debug_abbrevs
6631 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
6632 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
6633 || do_debug_str || do_debug_str_offsets || do_debug_loc
6634 || do_debug_ranges
1b513401 6635 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
6636 && (startswith (name, ".debug_")
6637 || startswith (name, ".zdebug_")))
252b5132 6638 {
1b315056
CS
6639 if (name[1] == 'z')
6640 name += sizeof (".zdebug_") - 1;
6641 else
6642 name += sizeof (".debug_") - 1;
252b5132
RH
6643
6644 if (do_debugging
24d127aa
ML
6645 || (do_debug_info && startswith (name, "info"))
6646 || (do_debug_info && startswith (name, "types"))
6647 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 6648 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
6649 || (do_debug_lines && startswith (name, "line."))
6650 || (do_debug_pubnames && startswith (name, "pubnames"))
6651 || (do_debug_pubtypes && startswith (name, "pubtypes"))
6652 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
6653 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
6654 || (do_debug_aranges && startswith (name, "aranges"))
6655 || (do_debug_ranges && startswith (name, "ranges"))
6656 || (do_debug_ranges && startswith (name, "rnglists"))
6657 || (do_debug_frames && startswith (name, "frame"))
6658 || (do_debug_macinfo && startswith (name, "macinfo"))
6659 || (do_debug_macinfo && startswith (name, "macro"))
6660 || (do_debug_str && startswith (name, "str"))
6661 || (do_debug_links && startswith (name, "sup"))
6662 || (do_debug_str_offsets && startswith (name, "str_offsets"))
6663 || (do_debug_loc && startswith (name, "loc"))
6664 || (do_debug_loc && startswith (name, "loclists"))
6665 || (do_debug_addr && startswith (name, "addr"))
6666 || (do_debug_cu_index && startswith (name, "cu_index"))
6667 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 6668 )
6431e409 6669 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6670 }
a262ae96 6671 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6672 else if ((do_debugging || do_debug_info)
24d127aa 6673 && startswith (name, ".gnu.linkonce.wi."))
6431e409 6674 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6675 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6676 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6677 else if (do_gdb_index && (streq (name, ".gdb_index")
6678 || streq (name, ".debug_names")))
6431e409 6679 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6680 /* Trace sections for Itanium VMS. */
6681 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6682 || do_trace_aranges)
24d127aa 6683 && startswith (name, ".trace_"))
6f875884
TG
6684 {
6685 name += sizeof (".trace_") - 1;
6686
6687 if (do_debugging
6688 || (do_trace_info && streq (name, "info"))
6689 || (do_trace_abbrevs && streq (name, "abbrev"))
6690 || (do_trace_aranges && streq (name, "aranges"))
6691 )
6431e409 6692 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6693 }
dda8d76d 6694 else if ((do_debugging || do_debug_links)
24d127aa
ML
6695 && (startswith (name, ".gnu_debuglink")
6696 || startswith (name, ".gnu_debugaltlink")))
6431e409 6697 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6698 }
6699
6700 if (! do_sections)
015dc7e1 6701 return true;
252b5132 6702
ca0e11aa 6703 if (filedata->is_separate && ! process_links)
015dc7e1 6704 return true;
ca0e11aa
NC
6705
6706 if (filedata->is_separate)
6707 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
6708 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6709 printf (_("\nSection Headers:\n"));
6710 else
6711 printf (_("\nSection Header:\n"));
76da6bbe 6712
f7a99963 6713 if (is_32bit_elf)
595cf52e 6714 {
5477e8a0 6715 if (do_section_details)
595cf52e
L
6716 {
6717 printf (_(" [Nr] Name\n"));
5477e8a0 6718 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6719 }
6720 else
6721 printf
6722 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6723 }
d974e256 6724 else if (do_wide)
595cf52e 6725 {
5477e8a0 6726 if (do_section_details)
595cf52e
L
6727 {
6728 printf (_(" [Nr] Name\n"));
5477e8a0 6729 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6730 }
6731 else
6732 printf
6733 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6734 }
f7a99963
NC
6735 else
6736 {
5477e8a0 6737 if (do_section_details)
595cf52e
L
6738 {
6739 printf (_(" [Nr] Name\n"));
5477e8a0
L
6740 printf (_(" Type Address Offset Link\n"));
6741 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6742 }
6743 else
6744 {
6745 printf (_(" [Nr] Name Type Address Offset\n"));
6746 printf (_(" Size EntSize Flags Link Info Align\n"));
6747 }
f7a99963 6748 }
252b5132 6749
5477e8a0
L
6750 if (do_section_details)
6751 printf (_(" Flags\n"));
6752
dda8d76d
NC
6753 for (i = 0, section = filedata->section_headers;
6754 i < filedata->file_header.e_shnum;
b34976b6 6755 i++, section++)
252b5132 6756 {
dd905818
NC
6757 /* Run some sanity checks on the section header. */
6758
6759 /* Check the sh_link field. */
6760 switch (section->sh_type)
6761 {
285e3f99
AM
6762 case SHT_REL:
6763 case SHT_RELA:
6764 if (section->sh_link == 0
6765 && (filedata->file_header.e_type == ET_EXEC
6766 || filedata->file_header.e_type == ET_DYN))
6767 /* A dynamic relocation section where all entries use a
6768 zero symbol index need not specify a symtab section. */
6769 break;
6770 /* Fall through. */
dd905818
NC
6771 case SHT_SYMTAB_SHNDX:
6772 case SHT_GROUP:
6773 case SHT_HASH:
6774 case SHT_GNU_HASH:
6775 case SHT_GNU_versym:
285e3f99 6776 if (section->sh_link == 0
dda8d76d
NC
6777 || section->sh_link >= filedata->file_header.e_shnum
6778 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6779 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6780 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6781 i, section->sh_link);
6782 break;
6783
6784 case SHT_DYNAMIC:
6785 case SHT_SYMTAB:
6786 case SHT_DYNSYM:
6787 case SHT_GNU_verneed:
6788 case SHT_GNU_verdef:
6789 case SHT_GNU_LIBLIST:
285e3f99 6790 if (section->sh_link == 0
dda8d76d
NC
6791 || section->sh_link >= filedata->file_header.e_shnum
6792 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6793 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6794 i, section->sh_link);
6795 break;
6796
6797 case SHT_INIT_ARRAY:
6798 case SHT_FINI_ARRAY:
6799 case SHT_PREINIT_ARRAY:
6800 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6801 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6802 i, section->sh_link);
6803 break;
6804
6805 default:
6806 /* FIXME: Add support for target specific section types. */
6807#if 0 /* Currently we do not check other section types as there are too
6808 many special cases. Stab sections for example have a type
6809 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6810 section. */
6811 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6812 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6813 i, section->sh_link);
6814#endif
6815 break;
6816 }
6817
6818 /* Check the sh_info field. */
6819 switch (section->sh_type)
6820 {
6821 case SHT_REL:
6822 case SHT_RELA:
285e3f99
AM
6823 if (section->sh_info == 0
6824 && (filedata->file_header.e_type == ET_EXEC
6825 || filedata->file_header.e_type == ET_DYN))
6826 /* Dynamic relocations apply to segments, so they do not
6827 need to specify the section they relocate. */
6828 break;
6829 if (section->sh_info == 0
dda8d76d
NC
6830 || section->sh_info >= filedata->file_header.e_shnum
6831 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6832 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6833 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6834 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6835 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6836 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6837 /* FIXME: Are other section types valid ? */
dda8d76d 6838 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6839 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6840 i, section->sh_info);
dd905818
NC
6841 break;
6842
6843 case SHT_DYNAMIC:
6844 case SHT_HASH:
6845 case SHT_SYMTAB_SHNDX:
6846 case SHT_INIT_ARRAY:
6847 case SHT_FINI_ARRAY:
6848 case SHT_PREINIT_ARRAY:
6849 if (section->sh_info != 0)
6850 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6851 i, section->sh_info);
6852 break;
6853
6854 case SHT_GROUP:
6855 case SHT_SYMTAB:
6856 case SHT_DYNSYM:
6857 /* A symbol index - we assume that it is valid. */
6858 break;
6859
6860 default:
6861 /* FIXME: Add support for target specific section types. */
6862 if (section->sh_type == SHT_NOBITS)
6863 /* NOBITS section headers with non-zero sh_info fields can be
6864 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6865 information. The stripped sections have their headers
6866 preserved but their types set to SHT_NOBITS. So do not check
6867 this type of section. */
dd905818
NC
6868 ;
6869 else if (section->sh_flags & SHF_INFO_LINK)
6870 {
dda8d76d 6871 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6872 warn (_("[%2u]: Expected link to another section in info field"), i);
6873 }
a91e1603
L
6874 else if (section->sh_type < SHT_LOOS
6875 && (section->sh_flags & SHF_GNU_MBIND) == 0
6876 && section->sh_info != 0)
dd905818
NC
6877 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6878 i, section->sh_info);
6879 break;
6880 }
6881
3e6b6445 6882 /* Check the sh_size field. */
dda8d76d 6883 if (section->sh_size > filedata->file_size
3e6b6445
NC
6884 && section->sh_type != SHT_NOBITS
6885 && section->sh_type != SHT_NULL
6886 && section->sh_type < SHT_LOOS)
6887 warn (_("Size of section %u is larger than the entire file!\n"), i);
6888
7bfd842d 6889 printf (" [%2u] ", i);
5477e8a0 6890 if (do_section_details)
dda8d76d 6891 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6892 else
b9e920ec 6893 print_symbol (-17, SECTION_NAME_PRINT (section));
0b4362b0 6894
ea52a088 6895 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6896 get_section_type_name (filedata, section->sh_type));
0b4362b0 6897
f7a99963
NC
6898 if (is_32bit_elf)
6899 {
cfcac11d
NC
6900 const char * link_too_big = NULL;
6901
f7a99963 6902 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6903
f7a99963
NC
6904 printf ( " %6.6lx %6.6lx %2.2lx",
6905 (unsigned long) section->sh_offset,
6906 (unsigned long) section->sh_size,
6907 (unsigned long) section->sh_entsize);
d1133906 6908
5477e8a0
L
6909 if (do_section_details)
6910 fputs (" ", stdout);
6911 else
dda8d76d 6912 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6913
dda8d76d 6914 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6915 {
6916 link_too_big = "";
6917 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6918 an error but it can have special values in Solaris binaries. */
dda8d76d 6919 switch (filedata->file_header.e_machine)
cfcac11d 6920 {
caa83f8b 6921 case EM_386:
22abe556 6922 case EM_IAMCU:
caa83f8b 6923 case EM_X86_64:
7f502d6c 6924 case EM_L1OM:
7a9068fe 6925 case EM_K1OM:
cfcac11d
NC
6926 case EM_OLD_SPARCV9:
6927 case EM_SPARC32PLUS:
6928 case EM_SPARCV9:
6929 case EM_SPARC:
6930 if (section->sh_link == (SHN_BEFORE & 0xffff))
6931 link_too_big = "BEFORE";
6932 else if (section->sh_link == (SHN_AFTER & 0xffff))
6933 link_too_big = "AFTER";
6934 break;
6935 default:
6936 break;
6937 }
6938 }
6939
6940 if (do_section_details)
6941 {
6942 if (link_too_big != NULL && * link_too_big)
6943 printf ("<%s> ", link_too_big);
6944 else
6945 printf ("%2u ", section->sh_link);
6946 printf ("%3u %2lu\n", section->sh_info,
6947 (unsigned long) section->sh_addralign);
6948 }
6949 else
6950 printf ("%2u %3u %2lu\n",
6951 section->sh_link,
6952 section->sh_info,
6953 (unsigned long) section->sh_addralign);
6954
6955 if (link_too_big && ! * link_too_big)
6956 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6957 i, section->sh_link);
f7a99963 6958 }
d974e256
JJ
6959 else if (do_wide)
6960 {
6961 print_vma (section->sh_addr, LONG_HEX);
6962
6963 if ((long) section->sh_offset == section->sh_offset)
6964 printf (" %6.6lx", (unsigned long) section->sh_offset);
6965 else
6966 {
6967 putchar (' ');
6968 print_vma (section->sh_offset, LONG_HEX);
6969 }
6970
6971 if ((unsigned long) section->sh_size == section->sh_size)
6972 printf (" %6.6lx", (unsigned long) section->sh_size);
6973 else
6974 {
6975 putchar (' ');
6976 print_vma (section->sh_size, LONG_HEX);
6977 }
6978
6979 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6980 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6981 else
6982 {
6983 putchar (' ');
6984 print_vma (section->sh_entsize, LONG_HEX);
6985 }
6986
5477e8a0
L
6987 if (do_section_details)
6988 fputs (" ", stdout);
6989 else
dda8d76d 6990 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6991
72de5009 6992 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6993
6994 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6995 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6996 else
6997 {
6998 print_vma (section->sh_addralign, DEC);
6999 putchar ('\n');
7000 }
7001 }
5477e8a0 7002 else if (do_section_details)
595cf52e 7003 {
55cc53e9 7004 putchar (' ');
595cf52e
L
7005 print_vma (section->sh_addr, LONG_HEX);
7006 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7007 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7008 else
7009 {
7010 printf (" ");
7011 print_vma (section->sh_offset, LONG_HEX);
7012 }
72de5009 7013 printf (" %u\n ", section->sh_link);
595cf52e 7014 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7015 putchar (' ');
595cf52e
L
7016 print_vma (section->sh_entsize, LONG_HEX);
7017
72de5009
AM
7018 printf (" %-16u %lu\n",
7019 section->sh_info,
595cf52e
L
7020 (unsigned long) section->sh_addralign);
7021 }
f7a99963
NC
7022 else
7023 {
7024 putchar (' ');
7025 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7026 if ((long) section->sh_offset == section->sh_offset)
7027 printf (" %8.8lx", (unsigned long) section->sh_offset);
7028 else
7029 {
7030 printf (" ");
7031 print_vma (section->sh_offset, LONG_HEX);
7032 }
f7a99963
NC
7033 printf ("\n ");
7034 print_vma (section->sh_size, LONG_HEX);
7035 printf (" ");
7036 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7037
dda8d76d 7038 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7039
72de5009
AM
7040 printf (" %2u %3u %lu\n",
7041 section->sh_link,
7042 section->sh_info,
f7a99963
NC
7043 (unsigned long) section->sh_addralign);
7044 }
5477e8a0
L
7045
7046 if (do_section_details)
77115a4a 7047 {
dda8d76d 7048 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7049 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7050 {
7051 /* Minimum section size is 12 bytes for 32-bit compression
7052 header + 12 bytes for compressed data header. */
7053 unsigned char buf[24];
d8024a91 7054
77115a4a 7055 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7056 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7057 sizeof (buf), _("compression header")))
7058 {
7059 Elf_Internal_Chdr chdr;
d8024a91 7060
5844b465
NC
7061 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7062 printf (_(" [<corrupt>]\n"));
77115a4a 7063 else
5844b465
NC
7064 {
7065 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7066 printf (" ZLIB, ");
7067 else
7068 printf (_(" [<unknown>: 0x%x], "),
7069 chdr.ch_type);
7070 print_vma (chdr.ch_size, LONG_HEX);
7071 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7072 }
77115a4a
L
7073 }
7074 }
7075 }
252b5132
RH
7076 }
7077
5477e8a0 7078 if (!do_section_details)
3dbcc61d 7079 {
9fb71ee4
NC
7080 /* The ordering of the letters shown here matches the ordering of the
7081 corresponding SHF_xxx values, and hence the order in which these
7082 letters will be displayed to the user. */
7083 printf (_("Key to Flags:\n\
7084 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7085 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7086 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7087 switch (filedata->file_header.e_ident[EI_OSABI])
7088 {
7089 case ELFOSABI_GNU:
7090 case ELFOSABI_FREEBSD:
7091 printf (_("R (retain), "));
7092 /* Fall through */
7093 case ELFOSABI_NONE:
7094 printf (_("D (mbind), "));
7095 break;
7096 default:
7097 break;
7098 }
dda8d76d
NC
7099 if (filedata->file_header.e_machine == EM_X86_64
7100 || filedata->file_header.e_machine == EM_L1OM
7101 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7102 printf (_("l (large), "));
dda8d76d 7103 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7104 printf (_("y (purecode), "));
dda8d76d 7105 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7106 printf (_("v (VLE), "));
9fb71ee4 7107 printf ("p (processor specific)\n");
0b4362b0 7108 }
d1133906 7109
015dc7e1 7110 return true;
252b5132
RH
7111}
7112
015dc7e1 7113static bool
28d13567
AM
7114get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7115 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7116 char **strtab, unsigned long *strtablen)
7117{
7118 *strtab = NULL;
7119 *strtablen = 0;
7120 *symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms);
7121
7122 if (*symtab == NULL)
015dc7e1 7123 return false;
28d13567
AM
7124
7125 if (symsec->sh_link != 0)
7126 {
7127 Elf_Internal_Shdr *strsec;
7128
7129 if (symsec->sh_link >= filedata->file_header.e_shnum)
7130 {
7131 error (_("Bad sh_link in symbol table section\n"));
7132 free (*symtab);
7133 *symtab = NULL;
7134 *nsyms = 0;
015dc7e1 7135 return false;
28d13567
AM
7136 }
7137
7138 strsec = filedata->section_headers + symsec->sh_link;
7139
7140 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7141 1, strsec->sh_size, _("string table"));
7142 if (*strtab == NULL)
7143 {
7144 free (*symtab);
7145 *symtab = NULL;
7146 *nsyms = 0;
015dc7e1 7147 return false;
28d13567
AM
7148 }
7149 *strtablen = strsec->sh_size;
7150 }
015dc7e1 7151 return true;
28d13567
AM
7152}
7153
f5842774
L
7154static const char *
7155get_group_flags (unsigned int flags)
7156{
1449284b 7157 static char buff[128];
220453ec 7158
6d913794
NC
7159 if (flags == 0)
7160 return "";
7161 else if (flags == GRP_COMDAT)
7162 return "COMDAT ";
f5842774 7163
89246a0e
AM
7164 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7165 flags,
7166 flags & GRP_MASKOS ? _("<OS specific>") : "",
7167 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7168 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7169 ? _("<unknown>") : ""));
6d913794 7170
f5842774
L
7171 return buff;
7172}
7173
015dc7e1 7174static bool
dda8d76d 7175process_section_groups (Filedata * filedata)
f5842774 7176{
2cf0635d 7177 Elf_Internal_Shdr * section;
f5842774 7178 unsigned int i;
2cf0635d
NC
7179 struct group * group;
7180 Elf_Internal_Shdr * symtab_sec;
7181 Elf_Internal_Shdr * strtab_sec;
7182 Elf_Internal_Sym * symtab;
ba5cdace 7183 unsigned long num_syms;
2cf0635d 7184 char * strtab;
c256ffe7 7185 size_t strtab_size;
d1f5c6e3
L
7186
7187 /* Don't process section groups unless needed. */
7188 if (!do_unwind && !do_section_groups)
015dc7e1 7189 return true;
f5842774 7190
dda8d76d 7191 if (filedata->file_header.e_shnum == 0)
f5842774
L
7192 {
7193 if (do_section_groups)
ca0e11aa
NC
7194 {
7195 if (filedata->is_separate)
7196 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7197 filedata->file_name);
7198 else
7199 printf (_("\nThere are no section groups in this file.\n"));
7200 }
015dc7e1 7201 return true;
f5842774
L
7202 }
7203
dda8d76d 7204 if (filedata->section_headers == NULL)
f5842774
L
7205 {
7206 error (_("Section headers are not available!\n"));
fa1908fd 7207 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7208 return false;
f5842774
L
7209 }
7210
978c4450
AM
7211 filedata->section_headers_groups
7212 = (struct group **) calloc (filedata->file_header.e_shnum,
7213 sizeof (struct group *));
e4b17d5c 7214
978c4450 7215 if (filedata->section_headers_groups == NULL)
e4b17d5c 7216 {
8b73c356 7217 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7218 filedata->file_header.e_shnum);
015dc7e1 7219 return false;
e4b17d5c
L
7220 }
7221
f5842774 7222 /* Scan the sections for the group section. */
978c4450 7223 filedata->group_count = 0;
dda8d76d
NC
7224 for (i = 0, section = filedata->section_headers;
7225 i < filedata->file_header.e_shnum;
f5842774 7226 i++, section++)
e4b17d5c 7227 if (section->sh_type == SHT_GROUP)
978c4450 7228 filedata->group_count++;
e4b17d5c 7229
978c4450 7230 if (filedata->group_count == 0)
d1f5c6e3
L
7231 {
7232 if (do_section_groups)
ca0e11aa
NC
7233 {
7234 if (filedata->is_separate)
7235 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7236 filedata->file_name);
7237 else
7238 printf (_("\nThere are no section groups in this file.\n"));
7239 }
d1f5c6e3 7240
015dc7e1 7241 return true;
d1f5c6e3
L
7242 }
7243
978c4450
AM
7244 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7245 sizeof (struct group));
e4b17d5c 7246
978c4450 7247 if (filedata->section_groups == NULL)
e4b17d5c 7248 {
8b73c356 7249 error (_("Out of memory reading %lu groups\n"),
978c4450 7250 (unsigned long) filedata->group_count);
015dc7e1 7251 return false;
e4b17d5c
L
7252 }
7253
d1f5c6e3
L
7254 symtab_sec = NULL;
7255 strtab_sec = NULL;
7256 symtab = NULL;
ba5cdace 7257 num_syms = 0;
d1f5c6e3 7258 strtab = NULL;
c256ffe7 7259 strtab_size = 0;
ca0e11aa
NC
7260
7261 if (filedata->is_separate)
7262 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7263
978c4450 7264 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7265 i < filedata->file_header.e_shnum;
e4b17d5c 7266 i++, section++)
f5842774
L
7267 {
7268 if (section->sh_type == SHT_GROUP)
7269 {
dda8d76d 7270 const char * name = printable_section_name (filedata, section);
74e1a04b 7271 const char * group_name;
2cf0635d
NC
7272 unsigned char * start;
7273 unsigned char * indices;
f5842774 7274 unsigned int entry, j, size;
2cf0635d
NC
7275 Elf_Internal_Shdr * sec;
7276 Elf_Internal_Sym * sym;
f5842774
L
7277
7278 /* Get the symbol table. */
dda8d76d
NC
7279 if (section->sh_link >= filedata->file_header.e_shnum
7280 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7281 != SHT_SYMTAB))
f5842774
L
7282 {
7283 error (_("Bad sh_link in group section `%s'\n"), name);
7284 continue;
7285 }
d1f5c6e3
L
7286
7287 if (symtab_sec != sec)
7288 {
7289 symtab_sec = sec;
9db70fc3 7290 free (symtab);
dda8d76d 7291 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 7292 }
f5842774 7293
dd24e3da
NC
7294 if (symtab == NULL)
7295 {
7296 error (_("Corrupt header in group section `%s'\n"), name);
7297 continue;
7298 }
7299
ba5cdace
NC
7300 if (section->sh_info >= num_syms)
7301 {
7302 error (_("Bad sh_info in group section `%s'\n"), name);
7303 continue;
7304 }
7305
f5842774
L
7306 sym = symtab + section->sh_info;
7307
7308 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7309 {
4fbb74a6 7310 if (sym->st_shndx == 0
dda8d76d 7311 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7312 {
7313 error (_("Bad sh_info in group section `%s'\n"), name);
7314 continue;
7315 }
ba2685cc 7316
b9e920ec
AM
7317 group_name = SECTION_NAME_PRINT (filedata->section_headers
7318 + sym->st_shndx);
c256ffe7 7319 strtab_sec = NULL;
9db70fc3 7320 free (strtab);
f5842774 7321 strtab = NULL;
c256ffe7 7322 strtab_size = 0;
f5842774
L
7323 }
7324 else
7325 {
7326 /* Get the string table. */
dda8d76d 7327 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7328 {
7329 strtab_sec = NULL;
9db70fc3 7330 free (strtab);
c256ffe7
JJ
7331 strtab = NULL;
7332 strtab_size = 0;
7333 }
7334 else if (strtab_sec
dda8d76d 7335 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7336 {
7337 strtab_sec = sec;
9db70fc3 7338 free (strtab);
071436c6 7339
dda8d76d 7340 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7341 1, strtab_sec->sh_size,
7342 _("string table"));
c256ffe7 7343 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7344 }
c256ffe7 7345 group_name = sym->st_name < strtab_size
2b692964 7346 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7347 }
7348
c9c1d674
EG
7349 /* PR 17531: file: loop. */
7350 if (section->sh_entsize > section->sh_size)
7351 {
7352 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7353 printable_section_name (filedata, section),
8066deb1
AM
7354 (unsigned long) section->sh_entsize,
7355 (unsigned long) section->sh_size);
61dd8e19 7356 continue;
c9c1d674
EG
7357 }
7358
dda8d76d 7359 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7360 1, section->sh_size,
7361 _("section data"));
59245841
NC
7362 if (start == NULL)
7363 continue;
f5842774
L
7364
7365 indices = start;
7366 size = (section->sh_size / section->sh_entsize) - 1;
7367 entry = byte_get (indices, 4);
7368 indices += 4;
e4b17d5c
L
7369
7370 if (do_section_groups)
7371 {
2b692964 7372 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7373 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7374
e4b17d5c
L
7375 printf (_(" [Index] Name\n"));
7376 }
7377
7378 group->group_index = i;
7379
f5842774
L
7380 for (j = 0; j < size; j++)
7381 {
2cf0635d 7382 struct group_list * g;
e4b17d5c 7383
f5842774
L
7384 entry = byte_get (indices, 4);
7385 indices += 4;
7386
dda8d76d 7387 if (entry >= filedata->file_header.e_shnum)
391cb864 7388 {
57028622
NC
7389 static unsigned num_group_errors = 0;
7390
7391 if (num_group_errors ++ < 10)
7392 {
7393 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7394 entry, i, filedata->file_header.e_shnum - 1);
57028622 7395 if (num_group_errors == 10)
67ce483b 7396 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7397 }
391cb864
L
7398 continue;
7399 }
391cb864 7400
978c4450 7401 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7402 {
d1f5c6e3
L
7403 if (entry)
7404 {
57028622
NC
7405 static unsigned num_errs = 0;
7406
7407 if (num_errs ++ < 10)
7408 {
7409 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7410 entry, i,
978c4450 7411 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7412 if (num_errs == 10)
7413 warn (_("Further error messages about already contained group sections suppressed\n"));
7414 }
d1f5c6e3
L
7415 continue;
7416 }
7417 else
7418 {
7419 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7420 section group. We just warn it the first time
d1f5c6e3 7421 and ignore it afterwards. */
015dc7e1 7422 static bool warned = false;
d1f5c6e3
L
7423 if (!warned)
7424 {
7425 error (_("section 0 in group section [%5u]\n"),
978c4450 7426 filedata->section_headers_groups [entry]->group_index);
015dc7e1 7427 warned = true;
d1f5c6e3
L
7428 }
7429 }
e4b17d5c
L
7430 }
7431
978c4450 7432 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7433
7434 if (do_section_groups)
7435 {
dda8d76d
NC
7436 sec = filedata->section_headers + entry;
7437 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7438 }
7439
3f5e193b 7440 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7441 g->section_index = entry;
7442 g->next = group->root;
7443 group->root = g;
f5842774
L
7444 }
7445
9db70fc3 7446 free (start);
e4b17d5c
L
7447
7448 group++;
f5842774
L
7449 }
7450 }
7451
9db70fc3
AM
7452 free (symtab);
7453 free (strtab);
015dc7e1 7454 return true;
f5842774
L
7455}
7456
28f997cf
TG
7457/* Data used to display dynamic fixups. */
7458
7459struct ia64_vms_dynfixup
7460{
7461 bfd_vma needed_ident; /* Library ident number. */
7462 bfd_vma needed; /* Index in the dstrtab of the library name. */
7463 bfd_vma fixup_needed; /* Index of the library. */
7464 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7465 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7466};
7467
7468/* Data used to display dynamic relocations. */
7469
7470struct ia64_vms_dynimgrela
7471{
7472 bfd_vma img_rela_cnt; /* Number of relocations. */
7473 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7474};
7475
7476/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7477 library). */
7478
015dc7e1 7479static bool
dda8d76d
NC
7480dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7481 struct ia64_vms_dynfixup * fixup,
7482 const char * strtab,
7483 unsigned int strtab_sz)
28f997cf 7484{
32ec8896 7485 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7486 long i;
32ec8896 7487 const char * lib_name;
28f997cf 7488
978c4450
AM
7489 imfs = get_data (NULL, filedata,
7490 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7491 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7492 _("dynamic section image fixups"));
7493 if (!imfs)
015dc7e1 7494 return false;
28f997cf
TG
7495
7496 if (fixup->needed < strtab_sz)
7497 lib_name = strtab + fixup->needed;
7498 else
7499 {
32ec8896 7500 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7501 (unsigned long) fixup->needed);
28f997cf
TG
7502 lib_name = "???";
7503 }
736990c4 7504
28f997cf
TG
7505 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7506 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7507 printf
7508 (_("Seg Offset Type SymVec DataType\n"));
7509
7510 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7511 {
7512 unsigned int type;
7513 const char *rtype;
7514
7515 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7516 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7517 type = BYTE_GET (imfs [i].type);
7518 rtype = elf_ia64_reloc_type (type);
7519 if (rtype == NULL)
7520 printf (" 0x%08x ", type);
7521 else
7522 printf (" %-32s ", rtype);
7523 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7524 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7525 }
7526
7527 free (imfs);
015dc7e1 7528 return true;
28f997cf
TG
7529}
7530
7531/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7532
015dc7e1 7533static bool
dda8d76d 7534dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7535{
7536 Elf64_External_VMS_IMAGE_RELA *imrs;
7537 long i;
7538
978c4450
AM
7539 imrs = get_data (NULL, filedata,
7540 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 7541 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7542 _("dynamic section image relocations"));
28f997cf 7543 if (!imrs)
015dc7e1 7544 return false;
28f997cf
TG
7545
7546 printf (_("\nImage relocs\n"));
7547 printf
7548 (_("Seg Offset Type Addend Seg Sym Off\n"));
7549
7550 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7551 {
7552 unsigned int type;
7553 const char *rtype;
7554
7555 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7556 printf ("%08" BFD_VMA_FMT "x ",
7557 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7558 type = BYTE_GET (imrs [i].type);
7559 rtype = elf_ia64_reloc_type (type);
7560 if (rtype == NULL)
7561 printf ("0x%08x ", type);
7562 else
7563 printf ("%-31s ", rtype);
7564 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7565 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7566 printf ("%08" BFD_VMA_FMT "x\n",
7567 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7568 }
7569
7570 free (imrs);
015dc7e1 7571 return true;
28f997cf
TG
7572}
7573
7574/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7575
015dc7e1 7576static bool
dda8d76d 7577process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7578{
7579 struct ia64_vms_dynfixup fixup;
7580 struct ia64_vms_dynimgrela imgrela;
7581 Elf_Internal_Dyn *entry;
28f997cf
TG
7582 bfd_vma strtab_off = 0;
7583 bfd_vma strtab_sz = 0;
7584 char *strtab = NULL;
015dc7e1 7585 bool res = true;
28f997cf
TG
7586
7587 memset (&fixup, 0, sizeof (fixup));
7588 memset (&imgrela, 0, sizeof (imgrela));
7589
7590 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
7591 for (entry = filedata->dynamic_section;
7592 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
7593 entry++)
7594 {
7595 switch (entry->d_tag)
7596 {
7597 case DT_IA_64_VMS_STRTAB_OFFSET:
7598 strtab_off = entry->d_un.d_val;
7599 break;
7600 case DT_STRSZ:
7601 strtab_sz = entry->d_un.d_val;
7602 if (strtab == NULL)
978c4450
AM
7603 strtab = get_data (NULL, filedata,
7604 filedata->dynamic_addr + strtab_off,
28f997cf 7605 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7606 if (strtab == NULL)
7607 strtab_sz = 0;
28f997cf
TG
7608 break;
7609
7610 case DT_IA_64_VMS_NEEDED_IDENT:
7611 fixup.needed_ident = entry->d_un.d_val;
7612 break;
7613 case DT_NEEDED:
7614 fixup.needed = entry->d_un.d_val;
7615 break;
7616 case DT_IA_64_VMS_FIXUP_NEEDED:
7617 fixup.fixup_needed = entry->d_un.d_val;
7618 break;
7619 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7620 fixup.fixup_rela_cnt = entry->d_un.d_val;
7621 break;
7622 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7623 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7624 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 7625 res = false;
28f997cf 7626 break;
28f997cf
TG
7627 case DT_IA_64_VMS_IMG_RELA_CNT:
7628 imgrela.img_rela_cnt = entry->d_un.d_val;
7629 break;
7630 case DT_IA_64_VMS_IMG_RELA_OFF:
7631 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7632 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 7633 res = false;
28f997cf
TG
7634 break;
7635
7636 default:
7637 break;
7638 }
7639 }
7640
9db70fc3 7641 free (strtab);
28f997cf
TG
7642
7643 return res;
7644}
7645
85b1c36d 7646static struct
566b0d53 7647{
2cf0635d 7648 const char * name;
566b0d53
L
7649 int reloc;
7650 int size;
7651 int rela;
32ec8896
NC
7652}
7653 dynamic_relocations [] =
566b0d53 7654{
015dc7e1
AM
7655 { "REL", DT_REL, DT_RELSZ, false },
7656 { "RELA", DT_RELA, DT_RELASZ, true },
32ec8896 7657 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7658};
7659
252b5132 7660/* Process the reloc section. */
18bd398b 7661
015dc7e1 7662static bool
dda8d76d 7663process_relocs (Filedata * filedata)
252b5132 7664{
b34976b6
AM
7665 unsigned long rel_size;
7666 unsigned long rel_offset;
252b5132 7667
252b5132 7668 if (!do_reloc)
015dc7e1 7669 return true;
252b5132
RH
7670
7671 if (do_using_dynamic)
7672 {
32ec8896 7673 int is_rela;
2cf0635d 7674 const char * name;
015dc7e1 7675 bool has_dynamic_reloc;
566b0d53 7676 unsigned int i;
0de14b54 7677
015dc7e1 7678 has_dynamic_reloc = false;
252b5132 7679
566b0d53 7680 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7681 {
566b0d53
L
7682 is_rela = dynamic_relocations [i].rela;
7683 name = dynamic_relocations [i].name;
978c4450
AM
7684 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
7685 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 7686
32ec8896 7687 if (rel_size)
015dc7e1 7688 has_dynamic_reloc = true;
566b0d53
L
7689
7690 if (is_rela == UNKNOWN)
aa903cfb 7691 {
566b0d53 7692 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 7693 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
7694 {
7695 case DT_REL:
015dc7e1 7696 is_rela = false;
566b0d53
L
7697 break;
7698 case DT_RELA:
015dc7e1 7699 is_rela = true;
566b0d53
L
7700 break;
7701 }
aa903cfb 7702 }
252b5132 7703
566b0d53
L
7704 if (rel_size)
7705 {
ca0e11aa
NC
7706 if (filedata->is_separate)
7707 printf
7708 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
7709 filedata->file_name, name, rel_offset, rel_size);
7710 else
7711 printf
7712 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7713 name, rel_offset, rel_size);
252b5132 7714
dda8d76d
NC
7715 dump_relocations (filedata,
7716 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7717 rel_size,
978c4450
AM
7718 filedata->dynamic_symbols,
7719 filedata->num_dynamic_syms,
7720 filedata->dynamic_strings,
7721 filedata->dynamic_strings_length,
015dc7e1 7722 is_rela, true /* is_dynamic */);
566b0d53 7723 }
252b5132 7724 }
566b0d53 7725
dda8d76d
NC
7726 if (is_ia64_vms (filedata))
7727 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 7728 has_dynamic_reloc = true;
28f997cf 7729
566b0d53 7730 if (! has_dynamic_reloc)
ca0e11aa
NC
7731 {
7732 if (filedata->is_separate)
7733 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
7734 filedata->file_name);
7735 else
7736 printf (_("\nThere are no dynamic relocations in this file.\n"));
7737 }
252b5132
RH
7738 }
7739 else
7740 {
2cf0635d 7741 Elf_Internal_Shdr * section;
b34976b6 7742 unsigned long i;
015dc7e1 7743 bool found = false;
252b5132 7744
dda8d76d
NC
7745 for (i = 0, section = filedata->section_headers;
7746 i < filedata->file_header.e_shnum;
b34976b6 7747 i++, section++)
252b5132
RH
7748 {
7749 if ( section->sh_type != SHT_RELA
7750 && section->sh_type != SHT_REL)
7751 continue;
7752
7753 rel_offset = section->sh_offset;
7754 rel_size = section->sh_size;
7755
7756 if (rel_size)
7757 {
b34976b6 7758 int is_rela;
d3a49aa8 7759 unsigned long num_rela;
103f02d3 7760
ca0e11aa
NC
7761 if (filedata->is_separate)
7762 printf (_("\nIn linked file '%s' relocation section "),
7763 filedata->file_name);
7764 else
7765 printf (_("\nRelocation section "));
252b5132 7766
dda8d76d 7767 if (filedata->string_table == NULL)
19936277 7768 printf ("%d", section->sh_name);
252b5132 7769 else
dda8d76d 7770 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7771
d3a49aa8
AM
7772 num_rela = rel_size / section->sh_entsize;
7773 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7774 " at offset 0x%lx contains %lu entries:\n",
7775 num_rela),
7776 rel_offset, num_rela);
252b5132 7777
d79b3d50
NC
7778 is_rela = section->sh_type == SHT_RELA;
7779
4fbb74a6 7780 if (section->sh_link != 0
dda8d76d 7781 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7782 {
2cf0635d
NC
7783 Elf_Internal_Shdr * symsec;
7784 Elf_Internal_Sym * symtab;
d79b3d50 7785 unsigned long nsyms;
c256ffe7 7786 unsigned long strtablen = 0;
2cf0635d 7787 char * strtab = NULL;
57346661 7788
dda8d76d 7789 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7790 if (symsec->sh_type != SHT_SYMTAB
7791 && symsec->sh_type != SHT_DYNSYM)
7792 continue;
7793
28d13567
AM
7794 if (!get_symtab (filedata, symsec,
7795 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7796 continue;
252b5132 7797
dda8d76d 7798 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7799 symtab, nsyms, strtab, strtablen,
7800 is_rela,
7801 symsec->sh_type == SHT_DYNSYM);
9db70fc3 7802 free (strtab);
d79b3d50
NC
7803 free (symtab);
7804 }
7805 else
dda8d76d 7806 dump_relocations (filedata, rel_offset, rel_size,
32ec8896 7807 NULL, 0, NULL, 0, is_rela,
015dc7e1 7808 false /* is_dynamic */);
252b5132 7809
015dc7e1 7810 found = true;
252b5132
RH
7811 }
7812 }
7813
7814 if (! found)
45ac8f4f
NC
7815 {
7816 /* Users sometimes forget the -D option, so try to be helpful. */
7817 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7818 {
978c4450 7819 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 7820 {
ca0e11aa
NC
7821 if (filedata->is_separate)
7822 printf (_("\nThere are no static relocations in linked file '%s'."),
7823 filedata->file_name);
7824 else
7825 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
7826 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7827
7828 break;
7829 }
7830 }
7831 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
7832 {
7833 if (filedata->is_separate)
7834 printf (_("\nThere are no relocations in linked file '%s'.\n"),
7835 filedata->file_name);
7836 else
7837 printf (_("\nThere are no relocations in this file.\n"));
7838 }
45ac8f4f 7839 }
252b5132
RH
7840 }
7841
015dc7e1 7842 return true;
252b5132
RH
7843}
7844
4d6ed7c8
NC
7845/* An absolute address consists of a section and an offset. If the
7846 section is NULL, the offset itself is the address, otherwise, the
7847 address equals to LOAD_ADDRESS(section) + offset. */
7848
7849struct absaddr
948f632f
DA
7850{
7851 unsigned short section;
7852 bfd_vma offset;
7853};
4d6ed7c8 7854
948f632f
DA
7855/* Find the nearest symbol at or below ADDR. Returns the symbol
7856 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7857
4d6ed7c8 7858static void
dda8d76d
NC
7859find_symbol_for_address (Filedata * filedata,
7860 Elf_Internal_Sym * symtab,
7861 unsigned long nsyms,
7862 const char * strtab,
7863 unsigned long strtab_size,
7864 struct absaddr addr,
7865 const char ** symname,
7866 bfd_vma * offset)
4d6ed7c8 7867{
d3ba0551 7868 bfd_vma dist = 0x100000;
2cf0635d 7869 Elf_Internal_Sym * sym;
948f632f
DA
7870 Elf_Internal_Sym * beg;
7871 Elf_Internal_Sym * end;
2cf0635d 7872 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7873
0b6ae522 7874 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7875 beg = symtab;
7876 end = symtab + nsyms;
0b6ae522 7877
948f632f 7878 while (beg < end)
4d6ed7c8 7879 {
948f632f
DA
7880 bfd_vma value;
7881
7882 sym = beg + (end - beg) / 2;
0b6ae522 7883
948f632f 7884 value = sym->st_value;
0b6ae522
DJ
7885 REMOVE_ARCH_BITS (value);
7886
948f632f 7887 if (sym->st_name != 0
4d6ed7c8 7888 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7889 && addr.offset >= value
7890 && addr.offset - value < dist)
4d6ed7c8
NC
7891 {
7892 best = sym;
0b6ae522 7893 dist = addr.offset - value;
4d6ed7c8
NC
7894 if (!dist)
7895 break;
7896 }
948f632f
DA
7897
7898 if (addr.offset < value)
7899 end = sym;
7900 else
7901 beg = sym + 1;
4d6ed7c8 7902 }
1b31d05e 7903
4d6ed7c8
NC
7904 if (best)
7905 {
57346661 7906 *symname = (best->st_name >= strtab_size
2b692964 7907 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7908 *offset = dist;
7909 return;
7910 }
1b31d05e 7911
4d6ed7c8
NC
7912 *symname = NULL;
7913 *offset = addr.offset;
7914}
7915
32ec8896 7916static /* signed */ int
948f632f
DA
7917symcmp (const void *p, const void *q)
7918{
7919 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7920 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7921
7922 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7923}
7924
7925/* Process the unwind section. */
7926
7927#include "unwind-ia64.h"
7928
7929struct ia64_unw_table_entry
7930{
7931 struct absaddr start;
7932 struct absaddr end;
7933 struct absaddr info;
7934};
7935
7936struct ia64_unw_aux_info
7937{
32ec8896
NC
7938 struct ia64_unw_table_entry * table; /* Unwind table. */
7939 unsigned long table_len; /* Length of unwind table. */
7940 unsigned char * info; /* Unwind info. */
7941 unsigned long info_size; /* Size of unwind info. */
7942 bfd_vma info_addr; /* Starting address of unwind info. */
7943 bfd_vma seg_base; /* Starting address of segment. */
7944 Elf_Internal_Sym * symtab; /* The symbol table. */
7945 unsigned long nsyms; /* Number of symbols. */
7946 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7947 unsigned long nfuns; /* Number of entries in funtab. */
7948 char * strtab; /* The string table. */
7949 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7950};
7951
015dc7e1 7952static bool
dda8d76d 7953dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7954{
2cf0635d 7955 struct ia64_unw_table_entry * tp;
948f632f 7956 unsigned long j, nfuns;
4d6ed7c8 7957 int in_body;
015dc7e1 7958 bool res = true;
7036c0e1 7959
948f632f
DA
7960 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7961 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7962 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7963 aux->funtab[nfuns++] = aux->symtab[j];
7964 aux->nfuns = nfuns;
7965 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7966
4d6ed7c8
NC
7967 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7968 {
7969 bfd_vma stamp;
7970 bfd_vma offset;
2cf0635d
NC
7971 const unsigned char * dp;
7972 const unsigned char * head;
53774b7e 7973 const unsigned char * end;
2cf0635d 7974 const char * procname;
4d6ed7c8 7975
dda8d76d 7976 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7977 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7978
7979 fputs ("\n<", stdout);
7980
7981 if (procname)
7982 {
7983 fputs (procname, stdout);
7984
7985 if (offset)
7986 printf ("+%lx", (unsigned long) offset);
7987 }
7988
7989 fputs (">: [", stdout);
7990 print_vma (tp->start.offset, PREFIX_HEX);
7991 fputc ('-', stdout);
7992 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7993 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7994 (unsigned long) (tp->info.offset - aux->seg_base));
7995
53774b7e
NC
7996 /* PR 17531: file: 86232b32. */
7997 if (aux->info == NULL)
7998 continue;
7999
97c0a079
AM
8000 offset = tp->info.offset;
8001 if (tp->info.section)
8002 {
8003 if (tp->info.section >= filedata->file_header.e_shnum)
8004 {
8005 warn (_("Invalid section %u in table entry %ld\n"),
8006 tp->info.section, (long) (tp - aux->table));
015dc7e1 8007 res = false;
97c0a079
AM
8008 continue;
8009 }
8010 offset += filedata->section_headers[tp->info.section].sh_addr;
8011 }
8012 offset -= aux->info_addr;
53774b7e 8013 /* PR 17531: file: 0997b4d1. */
90679903
AM
8014 if (offset >= aux->info_size
8015 || aux->info_size - offset < 8)
53774b7e
NC
8016 {
8017 warn (_("Invalid offset %lx in table entry %ld\n"),
8018 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8019 res = false;
53774b7e
NC
8020 continue;
8021 }
8022
97c0a079 8023 head = aux->info + offset;
a4a00738 8024 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8025
86f55779 8026 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8027 (unsigned) UNW_VER (stamp),
8028 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8029 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8030 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8031 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8032
8033 if (UNW_VER (stamp) != 1)
8034 {
2b692964 8035 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8036 continue;
8037 }
8038
8039 in_body = 0;
53774b7e
NC
8040 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8041 /* PR 17531: file: 16ceda89. */
8042 if (end > aux->info + aux->info_size)
8043 end = aux->info + aux->info_size;
8044 for (dp = head + 8; dp < end;)
b4477bc8 8045 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8046 }
948f632f
DA
8047
8048 free (aux->funtab);
32ec8896
NC
8049
8050 return res;
4d6ed7c8
NC
8051}
8052
015dc7e1 8053static bool
dda8d76d
NC
8054slurp_ia64_unwind_table (Filedata * filedata,
8055 struct ia64_unw_aux_info * aux,
8056 Elf_Internal_Shdr * sec)
4d6ed7c8 8057{
89fac5e3 8058 unsigned long size, nrelas, i;
2cf0635d
NC
8059 Elf_Internal_Phdr * seg;
8060 struct ia64_unw_table_entry * tep;
8061 Elf_Internal_Shdr * relsec;
8062 Elf_Internal_Rela * rela;
8063 Elf_Internal_Rela * rp;
8064 unsigned char * table;
8065 unsigned char * tp;
8066 Elf_Internal_Sym * sym;
8067 const char * relname;
4d6ed7c8 8068
53774b7e
NC
8069 aux->table_len = 0;
8070
4d6ed7c8
NC
8071 /* First, find the starting address of the segment that includes
8072 this section: */
8073
dda8d76d 8074 if (filedata->file_header.e_phnum)
4d6ed7c8 8075 {
dda8d76d 8076 if (! get_program_headers (filedata))
015dc7e1 8077 return false;
4d6ed7c8 8078
dda8d76d
NC
8079 for (seg = filedata->program_headers;
8080 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8081 ++seg)
4d6ed7c8
NC
8082 {
8083 if (seg->p_type != PT_LOAD)
8084 continue;
8085
8086 if (sec->sh_addr >= seg->p_vaddr
8087 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8088 {
8089 aux->seg_base = seg->p_vaddr;
8090 break;
8091 }
8092 }
4d6ed7c8
NC
8093 }
8094
8095 /* Second, build the unwind table from the contents of the unwind section: */
8096 size = sec->sh_size;
dda8d76d 8097 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8098 _("unwind table"));
a6e9f9df 8099 if (!table)
015dc7e1 8100 return false;
4d6ed7c8 8101
53774b7e 8102 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8103 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8104 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8105 tep = aux->table;
53774b7e
NC
8106
8107 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8108 {
8109 tep->start.section = SHN_UNDEF;
8110 tep->end.section = SHN_UNDEF;
8111 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8112 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8113 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8114 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8115 tep->start.offset += aux->seg_base;
8116 tep->end.offset += aux->seg_base;
8117 tep->info.offset += aux->seg_base;
8118 }
8119 free (table);
8120
41e92641 8121 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8122 for (relsec = filedata->section_headers;
8123 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8124 ++relsec)
8125 {
8126 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8127 || relsec->sh_info >= filedata->file_header.e_shnum
8128 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8129 continue;
8130
dda8d76d 8131 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8132 & rela, & nrelas))
53774b7e
NC
8133 {
8134 free (aux->table);
8135 aux->table = NULL;
8136 aux->table_len = 0;
015dc7e1 8137 return false;
53774b7e 8138 }
4d6ed7c8
NC
8139
8140 for (rp = rela; rp < rela + nrelas; ++rp)
8141 {
4770fb94 8142 unsigned int sym_ndx;
726bd37d
AM
8143 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8144 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8145
82b1b41b
NC
8146 /* PR 17531: file: 9fa67536. */
8147 if (relname == NULL)
8148 {
726bd37d 8149 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8150 continue;
8151 }
948f632f 8152
24d127aa 8153 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8154 {
82b1b41b 8155 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8156 continue;
8157 }
8158
89fac5e3 8159 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8160
53774b7e
NC
8161 /* PR 17531: file: 5bc8d9bf. */
8162 if (i >= aux->table_len)
8163 {
8164 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8165 continue;
8166 }
8167
4770fb94
AM
8168 sym_ndx = get_reloc_symindex (rp->r_info);
8169 if (sym_ndx >= aux->nsyms)
8170 {
8171 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8172 sym_ndx);
8173 continue;
8174 }
8175 sym = aux->symtab + sym_ndx;
8176
53774b7e 8177 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8178 {
8179 case 0:
8180 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8181 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8182 break;
8183 case 1:
8184 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8185 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8186 break;
8187 case 2:
8188 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8189 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8190 break;
8191 default:
8192 break;
8193 }
8194 }
8195
8196 free (rela);
8197 }
8198
015dc7e1 8199 return true;
4d6ed7c8
NC
8200}
8201
015dc7e1 8202static bool
dda8d76d 8203ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8204{
2cf0635d
NC
8205 Elf_Internal_Shdr * sec;
8206 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8207 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8208 struct ia64_unw_aux_info aux;
015dc7e1 8209 bool res = true;
f1467e33 8210
4d6ed7c8
NC
8211 memset (& aux, 0, sizeof (aux));
8212
dda8d76d 8213 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8214 {
28d13567 8215 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8216 {
28d13567 8217 if (aux.symtab)
4082ef84 8218 {
28d13567
AM
8219 error (_("Multiple symbol tables encountered\n"));
8220 free (aux.symtab);
8221 aux.symtab = NULL;
4082ef84 8222 free (aux.strtab);
28d13567 8223 aux.strtab = NULL;
4082ef84 8224 }
28d13567
AM
8225 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8226 &aux.strtab, &aux.strtab_size))
015dc7e1 8227 return false;
4d6ed7c8
NC
8228 }
8229 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8230 unwcount++;
8231 }
8232
8233 if (!unwcount)
8234 printf (_("\nThere are no unwind sections in this file.\n"));
8235
8236 while (unwcount-- > 0)
8237 {
2cf0635d 8238 char * suffix;
579f31ac
JJ
8239 size_t len, len2;
8240
dda8d76d
NC
8241 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8242 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8243 if (sec->sh_type == SHT_IA_64_UNWIND)
8244 {
8245 unwsec = sec;
8246 break;
8247 }
4082ef84
NC
8248 /* We have already counted the number of SHT_IA64_UNWIND
8249 sections so the loop above should never fail. */
8250 assert (unwsec != NULL);
579f31ac
JJ
8251
8252 unwstart = i + 1;
8253 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8254
e4b17d5c
L
8255 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8256 {
8257 /* We need to find which section group it is in. */
4082ef84 8258 struct group_list * g;
e4b17d5c 8259
978c4450
AM
8260 if (filedata->section_headers_groups == NULL
8261 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8262 i = filedata->file_header.e_shnum;
4082ef84 8263 else
e4b17d5c 8264 {
978c4450 8265 g = filedata->section_headers_groups[i]->root;
18bd398b 8266
4082ef84
NC
8267 for (; g != NULL; g = g->next)
8268 {
dda8d76d 8269 sec = filedata->section_headers + g->section_index;
e4b17d5c 8270
b9e920ec
AM
8271 if (SECTION_NAME_VALID (sec)
8272 && streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
4082ef84
NC
8273 break;
8274 }
8275
8276 if (g == NULL)
dda8d76d 8277 i = filedata->file_header.e_shnum;
4082ef84 8278 }
e4b17d5c 8279 }
b9e920ec 8280 else if (SECTION_NAME_VALID (unwsec)
e9b095a5
ML
8281 && startswith (SECTION_NAME (unwsec),
8282 ELF_STRING_ia64_unwind_once))
579f31ac 8283 {
18bd398b 8284 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
8285 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
8286 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8287 for (i = 0, sec = filedata->section_headers;
8288 i < filedata->file_header.e_shnum;
579f31ac 8289 ++i, ++sec)
b9e920ec 8290 if (SECTION_NAME_VALID (sec)
e9b095a5
ML
8291 && startswith (SECTION_NAME (sec),
8292 ELF_STRING_ia64_unwind_info_once)
18bd398b 8293 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8294 break;
8295 }
8296 else
8297 {
8298 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8299 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8300 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8301 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8302 suffix = "";
b9e920ec 8303 if (SECTION_NAME_VALID (unwsec)
e9b095a5 8304 && startswith (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind))
579f31ac 8305 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8306 for (i = 0, sec = filedata->section_headers;
8307 i < filedata->file_header.e_shnum;
579f31ac 8308 ++i, ++sec)
b9e920ec 8309 if (SECTION_NAME_VALID (sec)
e9b095a5 8310 && startswith (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info)
18bd398b 8311 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8312 break;
8313 }
8314
dda8d76d 8315 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8316 {
8317 printf (_("\nCould not find unwind info section for "));
8318
dda8d76d 8319 if (filedata->string_table == NULL)
579f31ac
JJ
8320 printf ("%d", unwsec->sh_name);
8321 else
dda8d76d 8322 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8323 }
8324 else
4d6ed7c8 8325 {
4d6ed7c8 8326 aux.info_addr = sec->sh_addr;
dda8d76d 8327 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8328 sec->sh_size,
8329 _("unwind info"));
59245841 8330 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8331
579f31ac 8332 printf (_("\nUnwind section "));
4d6ed7c8 8333
dda8d76d 8334 if (filedata->string_table == NULL)
579f31ac
JJ
8335 printf ("%d", unwsec->sh_name);
8336 else
dda8d76d 8337 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8338
579f31ac 8339 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8340 (unsigned long) unwsec->sh_offset,
89fac5e3 8341 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8342
dda8d76d 8343 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8344 && aux.table_len > 0)
dda8d76d 8345 dump_ia64_unwind (filedata, & aux);
579f31ac 8346
9db70fc3
AM
8347 free ((char *) aux.table);
8348 free ((char *) aux.info);
579f31ac
JJ
8349 aux.table = NULL;
8350 aux.info = NULL;
8351 }
4d6ed7c8 8352 }
4d6ed7c8 8353
9db70fc3
AM
8354 free (aux.symtab);
8355 free ((char *) aux.strtab);
32ec8896
NC
8356
8357 return res;
4d6ed7c8
NC
8358}
8359
3f5e193b 8360struct hppa_unw_table_entry
32ec8896
NC
8361{
8362 struct absaddr start;
8363 struct absaddr end;
8364 unsigned int Cannot_unwind:1; /* 0 */
8365 unsigned int Millicode:1; /* 1 */
8366 unsigned int Millicode_save_sr0:1; /* 2 */
8367 unsigned int Region_description:2; /* 3..4 */
8368 unsigned int reserved1:1; /* 5 */
8369 unsigned int Entry_SR:1; /* 6 */
8370 unsigned int Entry_FR:4; /* Number saved 7..10 */
8371 unsigned int Entry_GR:5; /* Number saved 11..15 */
8372 unsigned int Args_stored:1; /* 16 */
8373 unsigned int Variable_Frame:1; /* 17 */
8374 unsigned int Separate_Package_Body:1; /* 18 */
8375 unsigned int Frame_Extension_Millicode:1; /* 19 */
8376 unsigned int Stack_Overflow_Check:1; /* 20 */
8377 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8378 unsigned int Ada_Region:1; /* 22 */
8379 unsigned int cxx_info:1; /* 23 */
8380 unsigned int cxx_try_catch:1; /* 24 */
8381 unsigned int sched_entry_seq:1; /* 25 */
8382 unsigned int reserved2:1; /* 26 */
8383 unsigned int Save_SP:1; /* 27 */
8384 unsigned int Save_RP:1; /* 28 */
8385 unsigned int Save_MRP_in_frame:1; /* 29 */
8386 unsigned int extn_ptr_defined:1; /* 30 */
8387 unsigned int Cleanup_defined:1; /* 31 */
8388
8389 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8390 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8391 unsigned int Large_frame:1; /* 2 */
8392 unsigned int Pseudo_SP_Set:1; /* 3 */
8393 unsigned int reserved4:1; /* 4 */
8394 unsigned int Total_frame_size:27; /* 5..31 */
8395};
3f5e193b 8396
57346661 8397struct hppa_unw_aux_info
948f632f 8398{
32ec8896
NC
8399 struct hppa_unw_table_entry * table; /* Unwind table. */
8400 unsigned long table_len; /* Length of unwind table. */
8401 bfd_vma seg_base; /* Starting address of segment. */
8402 Elf_Internal_Sym * symtab; /* The symbol table. */
8403 unsigned long nsyms; /* Number of symbols. */
8404 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8405 unsigned long nfuns; /* Number of entries in funtab. */
8406 char * strtab; /* The string table. */
8407 unsigned long strtab_size; /* Size of string table. */
948f632f 8408};
57346661 8409
015dc7e1 8410static bool
dda8d76d 8411dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8412{
2cf0635d 8413 struct hppa_unw_table_entry * tp;
948f632f 8414 unsigned long j, nfuns;
015dc7e1 8415 bool res = true;
948f632f
DA
8416
8417 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8418 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8419 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8420 aux->funtab[nfuns++] = aux->symtab[j];
8421 aux->nfuns = nfuns;
8422 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8423
57346661
AM
8424 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8425 {
8426 bfd_vma offset;
2cf0635d 8427 const char * procname;
57346661 8428
dda8d76d 8429 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8430 aux->strtab_size, tp->start, &procname,
8431 &offset);
8432
8433 fputs ("\n<", stdout);
8434
8435 if (procname)
8436 {
8437 fputs (procname, stdout);
8438
8439 if (offset)
8440 printf ("+%lx", (unsigned long) offset);
8441 }
8442
8443 fputs (">: [", stdout);
8444 print_vma (tp->start.offset, PREFIX_HEX);
8445 fputc ('-', stdout);
8446 print_vma (tp->end.offset, PREFIX_HEX);
8447 printf ("]\n\t");
8448
18bd398b
NC
8449#define PF(_m) if (tp->_m) printf (#_m " ");
8450#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8451 PF(Cannot_unwind);
8452 PF(Millicode);
8453 PF(Millicode_save_sr0);
18bd398b 8454 /* PV(Region_description); */
57346661
AM
8455 PF(Entry_SR);
8456 PV(Entry_FR);
8457 PV(Entry_GR);
8458 PF(Args_stored);
8459 PF(Variable_Frame);
8460 PF(Separate_Package_Body);
8461 PF(Frame_Extension_Millicode);
8462 PF(Stack_Overflow_Check);
8463 PF(Two_Instruction_SP_Increment);
8464 PF(Ada_Region);
8465 PF(cxx_info);
8466 PF(cxx_try_catch);
8467 PF(sched_entry_seq);
8468 PF(Save_SP);
8469 PF(Save_RP);
8470 PF(Save_MRP_in_frame);
8471 PF(extn_ptr_defined);
8472 PF(Cleanup_defined);
8473 PF(MPE_XL_interrupt_marker);
8474 PF(HP_UX_interrupt_marker);
8475 PF(Large_frame);
8476 PF(Pseudo_SP_Set);
8477 PV(Total_frame_size);
8478#undef PF
8479#undef PV
8480 }
8481
18bd398b 8482 printf ("\n");
948f632f
DA
8483
8484 free (aux->funtab);
32ec8896
NC
8485
8486 return res;
57346661
AM
8487}
8488
015dc7e1 8489static bool
dda8d76d
NC
8490slurp_hppa_unwind_table (Filedata * filedata,
8491 struct hppa_unw_aux_info * aux,
8492 Elf_Internal_Shdr * sec)
57346661 8493{
1c0751b2 8494 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8495 Elf_Internal_Phdr * seg;
8496 struct hppa_unw_table_entry * tep;
8497 Elf_Internal_Shdr * relsec;
8498 Elf_Internal_Rela * rela;
8499 Elf_Internal_Rela * rp;
8500 unsigned char * table;
8501 unsigned char * tp;
8502 Elf_Internal_Sym * sym;
8503 const char * relname;
57346661 8504
57346661
AM
8505 /* First, find the starting address of the segment that includes
8506 this section. */
dda8d76d 8507 if (filedata->file_header.e_phnum)
57346661 8508 {
dda8d76d 8509 if (! get_program_headers (filedata))
015dc7e1 8510 return false;
57346661 8511
dda8d76d
NC
8512 for (seg = filedata->program_headers;
8513 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8514 ++seg)
8515 {
8516 if (seg->p_type != PT_LOAD)
8517 continue;
8518
8519 if (sec->sh_addr >= seg->p_vaddr
8520 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8521 {
8522 aux->seg_base = seg->p_vaddr;
8523 break;
8524 }
8525 }
8526 }
8527
8528 /* Second, build the unwind table from the contents of the unwind
8529 section. */
8530 size = sec->sh_size;
dda8d76d 8531 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8532 _("unwind table"));
57346661 8533 if (!table)
015dc7e1 8534 return false;
57346661 8535
1c0751b2
DA
8536 unw_ent_size = 16;
8537 nentries = size / unw_ent_size;
8538 size = unw_ent_size * nentries;
57346661 8539
e3fdc001 8540 aux->table_len = nentries;
3f5e193b
NC
8541 tep = aux->table = (struct hppa_unw_table_entry *)
8542 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8543
1c0751b2 8544 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8545 {
8546 unsigned int tmp1, tmp2;
8547
8548 tep->start.section = SHN_UNDEF;
8549 tep->end.section = SHN_UNDEF;
8550
1c0751b2
DA
8551 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8552 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8553 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8554 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8555
8556 tep->start.offset += aux->seg_base;
8557 tep->end.offset += aux->seg_base;
57346661
AM
8558
8559 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8560 tep->Millicode = (tmp1 >> 30) & 0x1;
8561 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8562 tep->Region_description = (tmp1 >> 27) & 0x3;
8563 tep->reserved1 = (tmp1 >> 26) & 0x1;
8564 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8565 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8566 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8567 tep->Args_stored = (tmp1 >> 15) & 0x1;
8568 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8569 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8570 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8571 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8572 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8573 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8574 tep->cxx_info = (tmp1 >> 8) & 0x1;
8575 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8576 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8577 tep->reserved2 = (tmp1 >> 5) & 0x1;
8578 tep->Save_SP = (tmp1 >> 4) & 0x1;
8579 tep->Save_RP = (tmp1 >> 3) & 0x1;
8580 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8581 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8582 tep->Cleanup_defined = tmp1 & 0x1;
8583
8584 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8585 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8586 tep->Large_frame = (tmp2 >> 29) & 0x1;
8587 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8588 tep->reserved4 = (tmp2 >> 27) & 0x1;
8589 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8590 }
8591 free (table);
8592
8593 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8594 for (relsec = filedata->section_headers;
8595 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8596 ++relsec)
8597 {
8598 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8599 || relsec->sh_info >= filedata->file_header.e_shnum
8600 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8601 continue;
8602
dda8d76d 8603 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8604 & rela, & nrelas))
015dc7e1 8605 return false;
57346661
AM
8606
8607 for (rp = rela; rp < rela + nrelas; ++rp)
8608 {
4770fb94 8609 unsigned int sym_ndx;
726bd37d
AM
8610 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8611 relname = elf_hppa_reloc_type (r_type);
57346661 8612
726bd37d
AM
8613 if (relname == NULL)
8614 {
8615 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8616 continue;
8617 }
8618
57346661 8619 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 8620 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 8621 {
726bd37d 8622 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8623 continue;
8624 }
8625
8626 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8627 if (i >= aux->table_len)
8628 {
8629 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8630 continue;
8631 }
57346661 8632
4770fb94
AM
8633 sym_ndx = get_reloc_symindex (rp->r_info);
8634 if (sym_ndx >= aux->nsyms)
8635 {
8636 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8637 sym_ndx);
8638 continue;
8639 }
8640 sym = aux->symtab + sym_ndx;
8641
43f6cd05 8642 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8643 {
8644 case 0:
8645 aux->table[i].start.section = sym->st_shndx;
1e456d54 8646 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8647 break;
8648 case 1:
8649 aux->table[i].end.section = sym->st_shndx;
1e456d54 8650 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8651 break;
8652 default:
8653 break;
8654 }
8655 }
8656
8657 free (rela);
8658 }
8659
015dc7e1 8660 return true;
57346661
AM
8661}
8662
015dc7e1 8663static bool
dda8d76d 8664hppa_process_unwind (Filedata * filedata)
57346661 8665{
57346661 8666 struct hppa_unw_aux_info aux;
2cf0635d 8667 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8668 Elf_Internal_Shdr * sec;
18bd398b 8669 unsigned long i;
015dc7e1 8670 bool res = true;
57346661 8671
dda8d76d 8672 if (filedata->string_table == NULL)
015dc7e1 8673 return false;
1b31d05e
NC
8674
8675 memset (& aux, 0, sizeof (aux));
57346661 8676
dda8d76d 8677 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8678 {
28d13567 8679 if (sec->sh_type == SHT_SYMTAB)
57346661 8680 {
28d13567 8681 if (aux.symtab)
4082ef84 8682 {
28d13567
AM
8683 error (_("Multiple symbol tables encountered\n"));
8684 free (aux.symtab);
8685 aux.symtab = NULL;
4082ef84 8686 free (aux.strtab);
28d13567 8687 aux.strtab = NULL;
4082ef84 8688 }
28d13567
AM
8689 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8690 &aux.strtab, &aux.strtab_size))
015dc7e1 8691 return false;
57346661 8692 }
b9e920ec
AM
8693 else if (SECTION_NAME_VALID (sec)
8694 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8695 unwsec = sec;
8696 }
8697
8698 if (!unwsec)
8699 printf (_("\nThere are no unwind sections in this file.\n"));
8700
dda8d76d 8701 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8702 {
b9e920ec
AM
8703 if (SECTION_NAME_VALID (sec)
8704 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8705 {
43f6cd05 8706 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8707
d3a49aa8
AM
8708 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8709 "contains %lu entry:\n",
8710 "\nUnwind section '%s' at offset 0x%lx "
8711 "contains %lu entries:\n",
8712 num_unwind),
dda8d76d 8713 printable_section_name (filedata, sec),
57346661 8714 (unsigned long) sec->sh_offset,
d3a49aa8 8715 num_unwind);
57346661 8716
dda8d76d 8717 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 8718 res = false;
66b09c7e
S
8719
8720 if (res && aux.table_len > 0)
32ec8896 8721 {
dda8d76d 8722 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 8723 res = false;
32ec8896 8724 }
57346661 8725
9db70fc3 8726 free ((char *) aux.table);
57346661
AM
8727 aux.table = NULL;
8728 }
8729 }
8730
9db70fc3
AM
8731 free (aux.symtab);
8732 free ((char *) aux.strtab);
32ec8896
NC
8733
8734 return res;
57346661
AM
8735}
8736
0b6ae522
DJ
8737struct arm_section
8738{
a734115a
NC
8739 unsigned char * data; /* The unwind data. */
8740 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8741 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8742 unsigned long nrelas; /* The number of relocations. */
8743 unsigned int rel_type; /* REL or RELA ? */
8744 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8745};
8746
8747struct arm_unw_aux_info
8748{
dda8d76d 8749 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8750 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8751 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8752 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8753 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8754 char * strtab; /* The file's string table. */
8755 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8756};
8757
8758static const char *
dda8d76d
NC
8759arm_print_vma_and_name (Filedata * filedata,
8760 struct arm_unw_aux_info * aux,
8761 bfd_vma fn,
8762 struct absaddr addr)
0b6ae522
DJ
8763{
8764 const char *procname;
8765 bfd_vma sym_offset;
8766
8767 if (addr.section == SHN_UNDEF)
8768 addr.offset = fn;
8769
dda8d76d 8770 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8771 aux->strtab_size, addr, &procname,
8772 &sym_offset);
8773
8774 print_vma (fn, PREFIX_HEX);
8775
8776 if (procname)
8777 {
8778 fputs (" <", stdout);
8779 fputs (procname, stdout);
8780
8781 if (sym_offset)
8782 printf ("+0x%lx", (unsigned long) sym_offset);
8783 fputc ('>', stdout);
8784 }
8785
8786 return procname;
8787}
8788
8789static void
8790arm_free_section (struct arm_section *arm_sec)
8791{
9db70fc3
AM
8792 free (arm_sec->data);
8793 free (arm_sec->rela);
0b6ae522
DJ
8794}
8795
a734115a
NC
8796/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8797 cached section and install SEC instead.
8798 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8799 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8800 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8801 relocation's offset in ADDR.
1b31d05e
NC
8802 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8803 into the string table of the symbol associated with the reloc. If no
8804 reloc was applied store -1 there.
8805 5) Return TRUE upon success, FALSE otherwise. */
a734115a 8806
015dc7e1 8807static bool
dda8d76d
NC
8808get_unwind_section_word (Filedata * filedata,
8809 struct arm_unw_aux_info * aux,
1b31d05e
NC
8810 struct arm_section * arm_sec,
8811 Elf_Internal_Shdr * sec,
8812 bfd_vma word_offset,
8813 unsigned int * wordp,
8814 struct absaddr * addr,
8815 bfd_vma * sym_name)
0b6ae522
DJ
8816{
8817 Elf_Internal_Rela *rp;
8818 Elf_Internal_Sym *sym;
8819 const char * relname;
8820 unsigned int word;
015dc7e1 8821 bool wrapped;
0b6ae522 8822
e0a31db1 8823 if (sec == NULL || arm_sec == NULL)
015dc7e1 8824 return false;
e0a31db1 8825
0b6ae522
DJ
8826 addr->section = SHN_UNDEF;
8827 addr->offset = 0;
8828
1b31d05e
NC
8829 if (sym_name != NULL)
8830 *sym_name = (bfd_vma) -1;
8831
a734115a 8832 /* If necessary, update the section cache. */
0b6ae522
DJ
8833 if (sec != arm_sec->sec)
8834 {
8835 Elf_Internal_Shdr *relsec;
8836
8837 arm_free_section (arm_sec);
8838
8839 arm_sec->sec = sec;
dda8d76d 8840 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8841 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8842 arm_sec->rela = NULL;
8843 arm_sec->nrelas = 0;
8844
dda8d76d
NC
8845 for (relsec = filedata->section_headers;
8846 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8847 ++relsec)
8848 {
dda8d76d
NC
8849 if (relsec->sh_info >= filedata->file_header.e_shnum
8850 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8851 /* PR 15745: Check the section type as well. */
8852 || (relsec->sh_type != SHT_REL
8853 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8854 continue;
8855
a734115a 8856 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8857 if (relsec->sh_type == SHT_REL)
8858 {
dda8d76d 8859 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8860 relsec->sh_size,
8861 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 8862 return false;
0b6ae522 8863 }
1ae40aa4 8864 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8865 {
dda8d76d 8866 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8867 relsec->sh_size,
8868 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 8869 return false;
0b6ae522 8870 }
1ae40aa4 8871 break;
0b6ae522
DJ
8872 }
8873
8874 arm_sec->next_rela = arm_sec->rela;
8875 }
8876
a734115a 8877 /* If there is no unwind data we can do nothing. */
0b6ae522 8878 if (arm_sec->data == NULL)
015dc7e1 8879 return false;
0b6ae522 8880
e0a31db1 8881 /* If the offset is invalid then fail. */
f32ba729
NC
8882 if (/* PR 21343 *//* PR 18879 */
8883 sec->sh_size < 4
8884 || word_offset > (sec->sh_size - 4)
1a915552 8885 || ((bfd_signed_vma) word_offset) < 0)
015dc7e1 8886 return false;
e0a31db1 8887
a734115a 8888 /* Get the word at the required offset. */
0b6ae522
DJ
8889 word = byte_get (arm_sec->data + word_offset, 4);
8890
0eff7165
NC
8891 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8892 if (arm_sec->rela == NULL)
8893 {
8894 * wordp = word;
015dc7e1 8895 return true;
0eff7165
NC
8896 }
8897
a734115a 8898 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 8899 wrapped = false;
0b6ae522
DJ
8900 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8901 {
8902 bfd_vma prelval, offset;
8903
8904 if (rp->r_offset > word_offset && !wrapped)
8905 {
8906 rp = arm_sec->rela;
015dc7e1 8907 wrapped = true;
0b6ae522
DJ
8908 }
8909 if (rp->r_offset > word_offset)
8910 break;
8911
8912 if (rp->r_offset & 3)
8913 {
8914 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8915 (unsigned long) rp->r_offset);
8916 continue;
8917 }
8918
8919 if (rp->r_offset < word_offset)
8920 continue;
8921
74e1a04b
NC
8922 /* PR 17531: file: 027-161405-0.004 */
8923 if (aux->symtab == NULL)
8924 continue;
8925
0b6ae522
DJ
8926 if (arm_sec->rel_type == SHT_REL)
8927 {
8928 offset = word & 0x7fffffff;
8929 if (offset & 0x40000000)
8930 offset |= ~ (bfd_vma) 0x7fffffff;
8931 }
a734115a 8932 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8933 offset = rp->r_addend;
a734115a 8934 else
74e1a04b
NC
8935 {
8936 error (_("Unknown section relocation type %d encountered\n"),
8937 arm_sec->rel_type);
8938 break;
8939 }
0b6ae522 8940
071436c6
NC
8941 /* PR 17531 file: 027-1241568-0.004. */
8942 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8943 {
8944 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8945 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8946 break;
8947 }
8948
8949 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8950 offset += sym->st_value;
8951 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8952
a734115a 8953 /* Check that we are processing the expected reloc type. */
dda8d76d 8954 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8955 {
8956 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8957 if (relname == NULL)
8958 {
8959 warn (_("Skipping unknown ARM relocation type: %d\n"),
8960 (int) ELF32_R_TYPE (rp->r_info));
8961 continue;
8962 }
a734115a
NC
8963
8964 if (streq (relname, "R_ARM_NONE"))
8965 continue;
0b4362b0 8966
a734115a
NC
8967 if (! streq (relname, "R_ARM_PREL31"))
8968 {
071436c6 8969 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8970 continue;
8971 }
8972 }
dda8d76d 8973 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8974 {
8975 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8976 if (relname == NULL)
8977 {
8978 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8979 (int) ELF32_R_TYPE (rp->r_info));
8980 continue;
8981 }
0b4362b0 8982
a734115a
NC
8983 if (streq (relname, "R_C6000_NONE"))
8984 continue;
8985
8986 if (! streq (relname, "R_C6000_PREL31"))
8987 {
071436c6 8988 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8989 continue;
8990 }
8991
8992 prelval >>= 1;
8993 }
8994 else
74e1a04b
NC
8995 {
8996 /* This function currently only supports ARM and TI unwinders. */
8997 warn (_("Only TI and ARM unwinders are currently supported\n"));
8998 break;
8999 }
fa197c1c 9000
0b6ae522
DJ
9001 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
9002 addr->section = sym->st_shndx;
9003 addr->offset = offset;
74e1a04b 9004
1b31d05e
NC
9005 if (sym_name)
9006 * sym_name = sym->st_name;
0b6ae522
DJ
9007 break;
9008 }
9009
9010 *wordp = word;
9011 arm_sec->next_rela = rp;
9012
015dc7e1 9013 return true;
0b6ae522
DJ
9014}
9015
a734115a
NC
9016static const char *tic6x_unwind_regnames[16] =
9017{
0b4362b0
RM
9018 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9019 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9020 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9021};
fa197c1c 9022
0b6ae522 9023static void
fa197c1c 9024decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9025{
fa197c1c
PB
9026 int i;
9027
9028 for (i = 12; mask; mask >>= 1, i--)
9029 {
9030 if (mask & 1)
9031 {
9032 fputs (tic6x_unwind_regnames[i], stdout);
9033 if (mask > 1)
9034 fputs (", ", stdout);
9035 }
9036 }
9037}
0b6ae522
DJ
9038
9039#define ADVANCE \
9040 if (remaining == 0 && more_words) \
9041 { \
9042 data_offset += 4; \
dda8d76d 9043 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9044 data_offset, & word, & addr, NULL)) \
015dc7e1 9045 return false; \
0b6ae522
DJ
9046 remaining = 4; \
9047 more_words--; \
9048 } \
9049
9050#define GET_OP(OP) \
9051 ADVANCE; \
9052 if (remaining) \
9053 { \
9054 remaining--; \
9055 (OP) = word >> 24; \
9056 word <<= 8; \
9057 } \
9058 else \
9059 { \
2b692964 9060 printf (_("[Truncated opcode]\n")); \
015dc7e1 9061 return false; \
0b6ae522 9062 } \
cc5914eb 9063 printf ("0x%02x ", OP)
0b6ae522 9064
015dc7e1 9065static bool
dda8d76d
NC
9066decode_arm_unwind_bytecode (Filedata * filedata,
9067 struct arm_unw_aux_info * aux,
948f632f
DA
9068 unsigned int word,
9069 unsigned int remaining,
9070 unsigned int more_words,
9071 bfd_vma data_offset,
9072 Elf_Internal_Shdr * data_sec,
9073 struct arm_section * data_arm_sec)
fa197c1c
PB
9074{
9075 struct absaddr addr;
015dc7e1 9076 bool res = true;
0b6ae522
DJ
9077
9078 /* Decode the unwinding instructions. */
9079 while (1)
9080 {
9081 unsigned int op, op2;
9082
9083 ADVANCE;
9084 if (remaining == 0)
9085 break;
9086 remaining--;
9087 op = word >> 24;
9088 word <<= 8;
9089
cc5914eb 9090 printf (" 0x%02x ", op);
0b6ae522
DJ
9091
9092 if ((op & 0xc0) == 0x00)
9093 {
9094 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9095
cc5914eb 9096 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9097 }
9098 else if ((op & 0xc0) == 0x40)
9099 {
9100 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9101
cc5914eb 9102 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9103 }
9104 else if ((op & 0xf0) == 0x80)
9105 {
9106 GET_OP (op2);
9107 if (op == 0x80 && op2 == 0)
9108 printf (_("Refuse to unwind"));
9109 else
9110 {
9111 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9112 bool first = true;
0b6ae522 9113 int i;
2b692964 9114
0b6ae522
DJ
9115 printf ("pop {");
9116 for (i = 0; i < 12; i++)
9117 if (mask & (1 << i))
9118 {
9119 if (first)
015dc7e1 9120 first = false;
0b6ae522
DJ
9121 else
9122 printf (", ");
9123 printf ("r%d", 4 + i);
9124 }
9125 printf ("}");
9126 }
9127 }
9128 else if ((op & 0xf0) == 0x90)
9129 {
9130 if (op == 0x9d || op == 0x9f)
9131 printf (_(" [Reserved]"));
9132 else
cc5914eb 9133 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9134 }
9135 else if ((op & 0xf0) == 0xa0)
9136 {
9137 int end = 4 + (op & 0x07);
015dc7e1 9138 bool first = true;
0b6ae522 9139 int i;
61865e30 9140
0b6ae522
DJ
9141 printf (" pop {");
9142 for (i = 4; i <= end; i++)
9143 {
9144 if (first)
015dc7e1 9145 first = false;
0b6ae522
DJ
9146 else
9147 printf (", ");
9148 printf ("r%d", i);
9149 }
9150 if (op & 0x08)
9151 {
1b31d05e 9152 if (!first)
0b6ae522
DJ
9153 printf (", ");
9154 printf ("r14");
9155 }
9156 printf ("}");
9157 }
9158 else if (op == 0xb0)
9159 printf (_(" finish"));
9160 else if (op == 0xb1)
9161 {
9162 GET_OP (op2);
9163 if (op2 == 0 || (op2 & 0xf0) != 0)
9164 printf (_("[Spare]"));
9165 else
9166 {
9167 unsigned int mask = op2 & 0x0f;
015dc7e1 9168 bool first = true;
0b6ae522 9169 int i;
61865e30 9170
0b6ae522
DJ
9171 printf ("pop {");
9172 for (i = 0; i < 12; i++)
9173 if (mask & (1 << i))
9174 {
9175 if (first)
015dc7e1 9176 first = false;
0b6ae522
DJ
9177 else
9178 printf (", ");
9179 printf ("r%d", i);
9180 }
9181 printf ("}");
9182 }
9183 }
9184 else if (op == 0xb2)
9185 {
b115cf96 9186 unsigned char buf[9];
0b6ae522
DJ
9187 unsigned int i, len;
9188 unsigned long offset;
61865e30 9189
b115cf96 9190 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9191 {
9192 GET_OP (buf[i]);
9193 if ((buf[i] & 0x80) == 0)
9194 break;
9195 }
4082ef84 9196 if (i == sizeof (buf))
32ec8896 9197 {
27a45f42 9198 error (_("corrupt change to vsp\n"));
015dc7e1 9199 res = false;
32ec8896 9200 }
4082ef84
NC
9201 else
9202 {
015dc7e1 9203 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9204 assert (len == i + 1);
9205 offset = offset * 4 + 0x204;
9206 printf ("vsp = vsp + %ld", offset);
9207 }
0b6ae522 9208 }
61865e30 9209 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9210 {
61865e30
NC
9211 unsigned int first, last;
9212
9213 GET_OP (op2);
9214 first = op2 >> 4;
9215 last = op2 & 0x0f;
9216 if (op == 0xc8)
9217 first = first + 16;
9218 printf ("pop {D%d", first);
9219 if (last)
9220 printf ("-D%d", first + last);
9221 printf ("}");
9222 }
9223 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9224 {
9225 unsigned int count = op & 0x07;
9226
9227 printf ("pop {D8");
9228 if (count)
9229 printf ("-D%d", 8 + count);
9230 printf ("}");
9231 }
9232 else if (op >= 0xc0 && op <= 0xc5)
9233 {
9234 unsigned int count = op & 0x07;
9235
9236 printf (" pop {wR10");
9237 if (count)
9238 printf ("-wR%d", 10 + count);
9239 printf ("}");
9240 }
9241 else if (op == 0xc6)
9242 {
9243 unsigned int first, last;
9244
9245 GET_OP (op2);
9246 first = op2 >> 4;
9247 last = op2 & 0x0f;
9248 printf ("pop {wR%d", first);
9249 if (last)
9250 printf ("-wR%d", first + last);
9251 printf ("}");
9252 }
9253 else if (op == 0xc7)
9254 {
9255 GET_OP (op2);
9256 if (op2 == 0 || (op2 & 0xf0) != 0)
9257 printf (_("[Spare]"));
0b6ae522
DJ
9258 else
9259 {
61865e30 9260 unsigned int mask = op2 & 0x0f;
015dc7e1 9261 bool first = true;
61865e30
NC
9262 int i;
9263
9264 printf ("pop {");
9265 for (i = 0; i < 4; i++)
9266 if (mask & (1 << i))
9267 {
9268 if (first)
015dc7e1 9269 first = false;
61865e30
NC
9270 else
9271 printf (", ");
9272 printf ("wCGR%d", i);
9273 }
9274 printf ("}");
0b6ae522
DJ
9275 }
9276 }
61865e30 9277 else
32ec8896
NC
9278 {
9279 printf (_(" [unsupported opcode]"));
015dc7e1 9280 res = false;
32ec8896
NC
9281 }
9282
0b6ae522
DJ
9283 printf ("\n");
9284 }
32ec8896
NC
9285
9286 return res;
fa197c1c
PB
9287}
9288
015dc7e1 9289static bool
dda8d76d
NC
9290decode_tic6x_unwind_bytecode (Filedata * filedata,
9291 struct arm_unw_aux_info * aux,
948f632f
DA
9292 unsigned int word,
9293 unsigned int remaining,
9294 unsigned int more_words,
9295 bfd_vma data_offset,
9296 Elf_Internal_Shdr * data_sec,
9297 struct arm_section * data_arm_sec)
fa197c1c
PB
9298{
9299 struct absaddr addr;
9300
9301 /* Decode the unwinding instructions. */
9302 while (1)
9303 {
9304 unsigned int op, op2;
9305
9306 ADVANCE;
9307 if (remaining == 0)
9308 break;
9309 remaining--;
9310 op = word >> 24;
9311 word <<= 8;
9312
9cf03b7e 9313 printf (" 0x%02x ", op);
fa197c1c
PB
9314
9315 if ((op & 0xc0) == 0x00)
9316 {
9317 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9318 printf (" sp = sp + %d", offset);
fa197c1c
PB
9319 }
9320 else if ((op & 0xc0) == 0x80)
9321 {
9322 GET_OP (op2);
9323 if (op == 0x80 && op2 == 0)
9324 printf (_("Refuse to unwind"));
9325 else
9326 {
9327 unsigned int mask = ((op & 0x1f) << 8) | op2;
9328 if (op & 0x20)
9329 printf ("pop compact {");
9330 else
9331 printf ("pop {");
9332
9333 decode_tic6x_unwind_regmask (mask);
9334 printf("}");
9335 }
9336 }
9337 else if ((op & 0xf0) == 0xc0)
9338 {
9339 unsigned int reg;
9340 unsigned int nregs;
9341 unsigned int i;
9342 const char *name;
a734115a
NC
9343 struct
9344 {
32ec8896
NC
9345 unsigned int offset;
9346 unsigned int reg;
fa197c1c
PB
9347 } regpos[16];
9348
9349 /* Scan entire instruction first so that GET_OP output is not
9350 interleaved with disassembly. */
9351 nregs = 0;
9352 for (i = 0; nregs < (op & 0xf); i++)
9353 {
9354 GET_OP (op2);
9355 reg = op2 >> 4;
9356 if (reg != 0xf)
9357 {
9358 regpos[nregs].offset = i * 2;
9359 regpos[nregs].reg = reg;
9360 nregs++;
9361 }
9362
9363 reg = op2 & 0xf;
9364 if (reg != 0xf)
9365 {
9366 regpos[nregs].offset = i * 2 + 1;
9367 regpos[nregs].reg = reg;
9368 nregs++;
9369 }
9370 }
9371
9372 printf (_("pop frame {"));
18344509 9373 if (nregs == 0)
fa197c1c 9374 {
18344509
NC
9375 printf (_("*corrupt* - no registers specified"));
9376 }
9377 else
9378 {
9379 reg = nregs - 1;
9380 for (i = i * 2; i > 0; i--)
fa197c1c 9381 {
18344509
NC
9382 if (regpos[reg].offset == i - 1)
9383 {
9384 name = tic6x_unwind_regnames[regpos[reg].reg];
9385 if (reg > 0)
9386 reg--;
9387 }
9388 else
9389 name = _("[pad]");
fa197c1c 9390
18344509
NC
9391 fputs (name, stdout);
9392 if (i > 1)
9393 printf (", ");
9394 }
fa197c1c
PB
9395 }
9396
9397 printf ("}");
9398 }
9399 else if (op == 0xd0)
9400 printf (" MOV FP, SP");
9401 else if (op == 0xd1)
9402 printf (" __c6xabi_pop_rts");
9403 else if (op == 0xd2)
9404 {
9405 unsigned char buf[9];
9406 unsigned int i, len;
9407 unsigned long offset;
a734115a 9408
fa197c1c
PB
9409 for (i = 0; i < sizeof (buf); i++)
9410 {
9411 GET_OP (buf[i]);
9412 if ((buf[i] & 0x80) == 0)
9413 break;
9414 }
0eff7165
NC
9415 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9416 if (i == sizeof (buf))
9417 {
0eff7165 9418 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 9419 return false;
0eff7165 9420 }
948f632f 9421
015dc7e1 9422 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
9423 assert (len == i + 1);
9424 offset = offset * 8 + 0x408;
9425 printf (_("sp = sp + %ld"), offset);
9426 }
9427 else if ((op & 0xf0) == 0xe0)
9428 {
9429 if ((op & 0x0f) == 7)
9430 printf (" RETURN");
9431 else
9432 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9433 }
9434 else
9435 {
9436 printf (_(" [unsupported opcode]"));
9437 }
9438 putchar ('\n');
9439 }
32ec8896 9440
015dc7e1 9441 return true;
fa197c1c
PB
9442}
9443
9444static bfd_vma
dda8d76d 9445arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9446{
9447 bfd_vma offset;
9448
9449 offset = word & 0x7fffffff;
9450 if (offset & 0x40000000)
9451 offset |= ~ (bfd_vma) 0x7fffffff;
9452
dda8d76d 9453 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9454 offset <<= 1;
9455
9456 return offset + where;
9457}
9458
015dc7e1 9459static bool
dda8d76d
NC
9460decode_arm_unwind (Filedata * filedata,
9461 struct arm_unw_aux_info * aux,
1b31d05e
NC
9462 unsigned int word,
9463 unsigned int remaining,
9464 bfd_vma data_offset,
9465 Elf_Internal_Shdr * data_sec,
9466 struct arm_section * data_arm_sec)
fa197c1c
PB
9467{
9468 int per_index;
9469 unsigned int more_words = 0;
37e14bc3 9470 struct absaddr addr;
1b31d05e 9471 bfd_vma sym_name = (bfd_vma) -1;
015dc7e1 9472 bool res = true;
fa197c1c
PB
9473
9474 if (remaining == 0)
9475 {
1b31d05e
NC
9476 /* Fetch the first word.
9477 Note - when decoding an object file the address extracted
9478 here will always be 0. So we also pass in the sym_name
9479 parameter so that we can find the symbol associated with
9480 the personality routine. */
dda8d76d 9481 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9482 & word, & addr, & sym_name))
015dc7e1 9483 return false;
1b31d05e 9484
fa197c1c
PB
9485 remaining = 4;
9486 }
c93dbb25
CZ
9487 else
9488 {
9489 addr.section = SHN_UNDEF;
9490 addr.offset = 0;
9491 }
fa197c1c
PB
9492
9493 if ((word & 0x80000000) == 0)
9494 {
9495 /* Expand prel31 for personality routine. */
9496 bfd_vma fn;
9497 const char *procname;
9498
dda8d76d 9499 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9500 printf (_(" Personality routine: "));
1b31d05e
NC
9501 if (fn == 0
9502 && addr.section == SHN_UNDEF && addr.offset == 0
9503 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9504 {
9505 procname = aux->strtab + sym_name;
9506 print_vma (fn, PREFIX_HEX);
9507 if (procname)
9508 {
9509 fputs (" <", stdout);
9510 fputs (procname, stdout);
9511 fputc ('>', stdout);
9512 }
9513 }
9514 else
dda8d76d 9515 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9516 fputc ('\n', stdout);
9517
9518 /* The GCC personality routines use the standard compact
9519 encoding, starting with one byte giving the number of
9520 words. */
9521 if (procname != NULL
24d127aa
ML
9522 && (startswith (procname, "__gcc_personality_v0")
9523 || startswith (procname, "__gxx_personality_v0")
9524 || startswith (procname, "__gcj_personality_v0")
9525 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
9526 {
9527 remaining = 0;
9528 more_words = 1;
9529 ADVANCE;
9530 if (!remaining)
9531 {
9532 printf (_(" [Truncated data]\n"));
015dc7e1 9533 return false;
fa197c1c
PB
9534 }
9535 more_words = word >> 24;
9536 word <<= 8;
9537 remaining--;
9538 per_index = -1;
9539 }
9540 else
015dc7e1 9541 return true;
fa197c1c
PB
9542 }
9543 else
9544 {
1b31d05e 9545 /* ARM EHABI Section 6.3:
0b4362b0 9546
1b31d05e 9547 An exception-handling table entry for the compact model looks like:
0b4362b0 9548
1b31d05e
NC
9549 31 30-28 27-24 23-0
9550 -- ----- ----- ----
9551 1 0 index Data for personalityRoutine[index] */
9552
dda8d76d 9553 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9554 && (word & 0x70000000))
32ec8896
NC
9555 {
9556 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 9557 res = false;
32ec8896 9558 }
1b31d05e 9559
fa197c1c 9560 per_index = (word >> 24) & 0x7f;
1b31d05e 9561 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9562 if (per_index == 0)
9563 {
9564 more_words = 0;
9565 word <<= 8;
9566 remaining--;
9567 }
9568 else if (per_index < 3)
9569 {
9570 more_words = (word >> 16) & 0xff;
9571 word <<= 16;
9572 remaining -= 2;
9573 }
9574 }
9575
dda8d76d 9576 switch (filedata->file_header.e_machine)
fa197c1c
PB
9577 {
9578 case EM_ARM:
9579 if (per_index < 3)
9580 {
dda8d76d 9581 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 9582 data_offset, data_sec, data_arm_sec))
015dc7e1 9583 res = false;
fa197c1c
PB
9584 }
9585 else
1b31d05e
NC
9586 {
9587 warn (_("Unknown ARM compact model index encountered\n"));
9588 printf (_(" [reserved]\n"));
015dc7e1 9589 res = false;
1b31d05e 9590 }
fa197c1c
PB
9591 break;
9592
9593 case EM_TI_C6000:
9594 if (per_index < 3)
9595 {
dda8d76d 9596 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 9597 data_offset, data_sec, data_arm_sec))
015dc7e1 9598 res = false;
fa197c1c
PB
9599 }
9600 else if (per_index < 5)
9601 {
9602 if (((word >> 17) & 0x7f) == 0x7f)
9603 printf (_(" Restore stack from frame pointer\n"));
9604 else
9605 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9606 printf (_(" Registers restored: "));
9607 if (per_index == 4)
9608 printf (" (compact) ");
9609 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9610 putchar ('\n');
9611 printf (_(" Return register: %s\n"),
9612 tic6x_unwind_regnames[word & 0xf]);
9613 }
9614 else
1b31d05e 9615 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9616 break;
9617
9618 default:
74e1a04b 9619 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9620 filedata->file_header.e_machine);
015dc7e1 9621 res = false;
fa197c1c 9622 }
0b6ae522
DJ
9623
9624 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9625
9626 return res;
0b6ae522
DJ
9627}
9628
015dc7e1 9629static bool
dda8d76d
NC
9630dump_arm_unwind (Filedata * filedata,
9631 struct arm_unw_aux_info * aux,
9632 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9633{
9634 struct arm_section exidx_arm_sec, extab_arm_sec;
9635 unsigned int i, exidx_len;
948f632f 9636 unsigned long j, nfuns;
015dc7e1 9637 bool res = true;
0b6ae522
DJ
9638
9639 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9640 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9641 exidx_len = exidx_sec->sh_size / 8;
9642
948f632f
DA
9643 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9644 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9645 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9646 aux->funtab[nfuns++] = aux->symtab[j];
9647 aux->nfuns = nfuns;
9648 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9649
0b6ae522
DJ
9650 for (i = 0; i < exidx_len; i++)
9651 {
9652 unsigned int exidx_fn, exidx_entry;
9653 struct absaddr fn_addr, entry_addr;
9654 bfd_vma fn;
9655
9656 fputc ('\n', stdout);
9657
dda8d76d 9658 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9659 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9660 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9661 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9662 {
948f632f 9663 free (aux->funtab);
1b31d05e
NC
9664 arm_free_section (& exidx_arm_sec);
9665 arm_free_section (& extab_arm_sec);
015dc7e1 9666 return false;
0b6ae522
DJ
9667 }
9668
83c257ca
NC
9669 /* ARM EHABI, Section 5:
9670 An index table entry consists of 2 words.
9671 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9672 if (exidx_fn & 0x80000000)
32ec8896
NC
9673 {
9674 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 9675 res = false;
32ec8896 9676 }
83c257ca 9677
dda8d76d 9678 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9679
dda8d76d 9680 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9681 fputs (": ", stdout);
9682
9683 if (exidx_entry == 1)
9684 {
9685 print_vma (exidx_entry, PREFIX_HEX);
9686 fputs (" [cantunwind]\n", stdout);
9687 }
9688 else if (exidx_entry & 0x80000000)
9689 {
9690 print_vma (exidx_entry, PREFIX_HEX);
9691 fputc ('\n', stdout);
dda8d76d 9692 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9693 }
9694 else
9695 {
8f73510c 9696 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9697 Elf_Internal_Shdr *table_sec;
9698
9699 fputs ("@", stdout);
dda8d76d 9700 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9701 print_vma (table, PREFIX_HEX);
9702 printf ("\n");
9703
9704 /* Locate the matching .ARM.extab. */
9705 if (entry_addr.section != SHN_UNDEF
dda8d76d 9706 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9707 {
dda8d76d 9708 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9709 table_offset = entry_addr.offset;
1a915552
NC
9710 /* PR 18879 */
9711 if (table_offset > table_sec->sh_size
9712 || ((bfd_signed_vma) table_offset) < 0)
9713 {
9714 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9715 (unsigned long) table_offset,
dda8d76d 9716 printable_section_name (filedata, table_sec));
015dc7e1 9717 res = false;
1a915552
NC
9718 continue;
9719 }
0b6ae522
DJ
9720 }
9721 else
9722 {
dda8d76d 9723 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9724 if (table_sec != NULL)
9725 table_offset = table - table_sec->sh_addr;
9726 }
32ec8896 9727
0b6ae522
DJ
9728 if (table_sec == NULL)
9729 {
9730 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9731 (unsigned long) table);
015dc7e1 9732 res = false;
0b6ae522
DJ
9733 continue;
9734 }
32ec8896 9735
dda8d76d 9736 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 9737 &extab_arm_sec))
015dc7e1 9738 res = false;
0b6ae522
DJ
9739 }
9740 }
9741
9742 printf ("\n");
9743
948f632f 9744 free (aux->funtab);
0b6ae522
DJ
9745 arm_free_section (&exidx_arm_sec);
9746 arm_free_section (&extab_arm_sec);
32ec8896
NC
9747
9748 return res;
0b6ae522
DJ
9749}
9750
fa197c1c 9751/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9752
015dc7e1 9753static bool
dda8d76d 9754arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9755{
9756 struct arm_unw_aux_info aux;
9757 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9758 Elf_Internal_Shdr *sec;
9759 unsigned long i;
fa197c1c 9760 unsigned int sec_type;
015dc7e1 9761 bool res = true;
0b6ae522 9762
dda8d76d 9763 switch (filedata->file_header.e_machine)
fa197c1c
PB
9764 {
9765 case EM_ARM:
9766 sec_type = SHT_ARM_EXIDX;
9767 break;
9768
9769 case EM_TI_C6000:
9770 sec_type = SHT_C6000_UNWIND;
9771 break;
9772
0b4362b0 9773 default:
74e1a04b 9774 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9775 filedata->file_header.e_machine);
015dc7e1 9776 return false;
fa197c1c
PB
9777 }
9778
dda8d76d 9779 if (filedata->string_table == NULL)
015dc7e1 9780 return false;
1b31d05e
NC
9781
9782 memset (& aux, 0, sizeof (aux));
dda8d76d 9783 aux.filedata = filedata;
0b6ae522 9784
dda8d76d 9785 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9786 {
28d13567 9787 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9788 {
28d13567 9789 if (aux.symtab)
74e1a04b 9790 {
28d13567
AM
9791 error (_("Multiple symbol tables encountered\n"));
9792 free (aux.symtab);
9793 aux.symtab = NULL;
74e1a04b 9794 free (aux.strtab);
28d13567 9795 aux.strtab = NULL;
74e1a04b 9796 }
28d13567
AM
9797 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9798 &aux.strtab, &aux.strtab_size))
015dc7e1 9799 return false;
0b6ae522 9800 }
fa197c1c 9801 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9802 unwsec = sec;
9803 }
9804
1b31d05e 9805 if (unwsec == NULL)
0b6ae522 9806 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9807 else
dda8d76d 9808 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9809 {
9810 if (sec->sh_type == sec_type)
9811 {
d3a49aa8
AM
9812 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9813 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9814 "contains %lu entry:\n",
9815 "\nUnwind section '%s' at offset 0x%lx "
9816 "contains %lu entries:\n",
9817 num_unwind),
dda8d76d 9818 printable_section_name (filedata, sec),
1b31d05e 9819 (unsigned long) sec->sh_offset,
d3a49aa8 9820 num_unwind);
0b6ae522 9821
dda8d76d 9822 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 9823 res = false;
1b31d05e
NC
9824 }
9825 }
0b6ae522 9826
9db70fc3
AM
9827 free (aux.symtab);
9828 free ((char *) aux.strtab);
32ec8896
NC
9829
9830 return res;
0b6ae522
DJ
9831}
9832
015dc7e1 9833static bool
dda8d76d 9834process_unwind (Filedata * filedata)
57346661 9835{
2cf0635d
NC
9836 struct unwind_handler
9837 {
32ec8896 9838 unsigned int machtype;
015dc7e1 9839 bool (* handler)(Filedata *);
2cf0635d
NC
9840 } handlers[] =
9841 {
0b6ae522 9842 { EM_ARM, arm_process_unwind },
57346661
AM
9843 { EM_IA_64, ia64_process_unwind },
9844 { EM_PARISC, hppa_process_unwind },
fa197c1c 9845 { EM_TI_C6000, arm_process_unwind },
32ec8896 9846 { 0, NULL }
57346661
AM
9847 };
9848 int i;
9849
9850 if (!do_unwind)
015dc7e1 9851 return true;
57346661
AM
9852
9853 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9854 if (filedata->file_header.e_machine == handlers[i].machtype)
9855 return handlers[i].handler (filedata);
57346661 9856
1b31d05e 9857 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9858 get_machine_name (filedata->file_header.e_machine));
015dc7e1 9859 return true;
57346661
AM
9860}
9861
37c18eed
SD
9862static void
9863dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
9864{
9865 switch (entry->d_tag)
9866 {
9867 case DT_AARCH64_BTI_PLT:
1dbade74 9868 case DT_AARCH64_PAC_PLT:
37c18eed
SD
9869 break;
9870 default:
9871 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9872 break;
9873 }
9874 putchar ('\n');
9875}
9876
252b5132 9877static void
978c4450 9878dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
9879{
9880 switch (entry->d_tag)
9881 {
9882 case DT_MIPS_FLAGS:
9883 if (entry->d_un.d_val == 0)
4b68bca3 9884 printf (_("NONE"));
252b5132
RH
9885 else
9886 {
9887 static const char * opts[] =
9888 {
9889 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9890 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9891 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9892 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9893 "RLD_ORDER_SAFE"
9894 };
9895 unsigned int cnt;
015dc7e1 9896 bool first = true;
2b692964 9897
60bca95a 9898 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9899 if (entry->d_un.d_val & (1 << cnt))
9900 {
9901 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 9902 first = false;
252b5132 9903 }
252b5132
RH
9904 }
9905 break;
103f02d3 9906
252b5132 9907 case DT_MIPS_IVERSION:
978c4450
AM
9908 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
9909 printf (_("Interface Version: %s"),
9910 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 9911 else
76ca31c0
NC
9912 {
9913 char buf[40];
9914 sprintf_vma (buf, entry->d_un.d_ptr);
9915 /* Note: coded this way so that there is a single string for translation. */
9916 printf (_("<corrupt: %s>"), buf);
9917 }
252b5132 9918 break;
103f02d3 9919
252b5132
RH
9920 case DT_MIPS_TIME_STAMP:
9921 {
d5b07ef4 9922 char timebuf[128];
2cf0635d 9923 struct tm * tmp;
91d6fa6a 9924 time_t atime = entry->d_un.d_val;
82b1b41b 9925
91d6fa6a 9926 tmp = gmtime (&atime);
82b1b41b
NC
9927 /* PR 17531: file: 6accc532. */
9928 if (tmp == NULL)
9929 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9930 else
9931 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9932 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9933 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9934 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9935 }
9936 break;
103f02d3 9937
252b5132
RH
9938 case DT_MIPS_RLD_VERSION:
9939 case DT_MIPS_LOCAL_GOTNO:
9940 case DT_MIPS_CONFLICTNO:
9941 case DT_MIPS_LIBLISTNO:
9942 case DT_MIPS_SYMTABNO:
9943 case DT_MIPS_UNREFEXTNO:
9944 case DT_MIPS_HIPAGENO:
9945 case DT_MIPS_DELTA_CLASS_NO:
9946 case DT_MIPS_DELTA_INSTANCE_NO:
9947 case DT_MIPS_DELTA_RELOC_NO:
9948 case DT_MIPS_DELTA_SYM_NO:
9949 case DT_MIPS_DELTA_CLASSSYM_NO:
9950 case DT_MIPS_COMPACT_SIZE:
c69075ac 9951 print_vma (entry->d_un.d_val, DEC);
252b5132 9952 break;
103f02d3 9953
f16a9783 9954 case DT_MIPS_XHASH:
978c4450
AM
9955 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
9956 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
9957 /* Falls through. */
9958
103f02d3 9959 default:
4b68bca3 9960 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9961 }
4b68bca3 9962 putchar ('\n');
103f02d3
UD
9963}
9964
103f02d3 9965static void
2cf0635d 9966dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9967{
9968 switch (entry->d_tag)
9969 {
9970 case DT_HP_DLD_FLAGS:
9971 {
9972 static struct
9973 {
9974 long int bit;
2cf0635d 9975 const char * str;
5e220199
NC
9976 }
9977 flags[] =
9978 {
9979 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9980 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9981 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9982 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9983 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9984 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9985 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9986 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9987 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9988 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9989 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9990 { DT_HP_GST, "HP_GST" },
9991 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
9992 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
9993 { DT_HP_NODELETE, "HP_NODELETE" },
9994 { DT_HP_GROUP, "HP_GROUP" },
9995 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 9996 };
015dc7e1 9997 bool first = true;
5e220199 9998 size_t cnt;
f7a99963 9999 bfd_vma val = entry->d_un.d_val;
103f02d3 10000
60bca95a 10001 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10002 if (val & flags[cnt].bit)
30800947
NC
10003 {
10004 if (! first)
10005 putchar (' ');
10006 fputs (flags[cnt].str, stdout);
015dc7e1 10007 first = false;
30800947
NC
10008 val ^= flags[cnt].bit;
10009 }
76da6bbe 10010
103f02d3 10011 if (val != 0 || first)
f7a99963
NC
10012 {
10013 if (! first)
10014 putchar (' ');
10015 print_vma (val, HEX);
10016 }
103f02d3
UD
10017 }
10018 break;
76da6bbe 10019
252b5132 10020 default:
f7a99963
NC
10021 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10022 break;
252b5132 10023 }
35b1837e 10024 putchar ('\n');
252b5132
RH
10025}
10026
28f997cf
TG
10027#ifdef BFD64
10028
10029/* VMS vs Unix time offset and factor. */
10030
10031#define VMS_EPOCH_OFFSET 35067168000000000LL
10032#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10033#ifndef INT64_MIN
10034#define INT64_MIN (-9223372036854775807LL - 1)
10035#endif
28f997cf
TG
10036
10037/* Display a VMS time in a human readable format. */
10038
10039static void
10040print_vms_time (bfd_int64_t vmstime)
10041{
dccc31de 10042 struct tm *tm = NULL;
28f997cf
TG
10043 time_t unxtime;
10044
dccc31de
AM
10045 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10046 {
10047 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10048 unxtime = vmstime;
10049 if (unxtime == vmstime)
10050 tm = gmtime (&unxtime);
10051 }
10052 if (tm != NULL)
10053 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10054 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10055 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
10056}
10057#endif /* BFD64 */
10058
ecc51f48 10059static void
2cf0635d 10060dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10061{
10062 switch (entry->d_tag)
10063 {
0de14b54 10064 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10065 /* First 3 slots reserved. */
ecc51f48
NC
10066 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10067 printf (" -- ");
10068 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10069 break;
10070
28f997cf
TG
10071 case DT_IA_64_VMS_LINKTIME:
10072#ifdef BFD64
10073 print_vms_time (entry->d_un.d_val);
10074#endif
10075 break;
10076
10077 case DT_IA_64_VMS_LNKFLAGS:
10078 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10079 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10080 printf (" CALL_DEBUG");
10081 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10082 printf (" NOP0BUFS");
10083 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10084 printf (" P0IMAGE");
10085 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10086 printf (" MKTHREADS");
10087 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10088 printf (" UPCALLS");
10089 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10090 printf (" IMGSTA");
10091 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10092 printf (" INITIALIZE");
10093 if (entry->d_un.d_val & VMS_LF_MAIN)
10094 printf (" MAIN");
10095 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10096 printf (" EXE_INIT");
10097 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10098 printf (" TBK_IN_IMG");
10099 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10100 printf (" DBG_IN_IMG");
10101 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10102 printf (" TBK_IN_DSF");
10103 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10104 printf (" DBG_IN_DSF");
10105 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10106 printf (" SIGNATURES");
10107 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10108 printf (" REL_SEG_OFF");
10109 break;
10110
bdf4d63a
JJ
10111 default:
10112 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10113 break;
ecc51f48 10114 }
bdf4d63a 10115 putchar ('\n');
ecc51f48
NC
10116}
10117
015dc7e1 10118static bool
dda8d76d 10119get_32bit_dynamic_section (Filedata * filedata)
252b5132 10120{
2cf0635d
NC
10121 Elf32_External_Dyn * edyn;
10122 Elf32_External_Dyn * ext;
10123 Elf_Internal_Dyn * entry;
103f02d3 10124
978c4450
AM
10125 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10126 filedata->dynamic_addr, 1,
10127 filedata->dynamic_size,
10128 _("dynamic section"));
a6e9f9df 10129 if (!edyn)
015dc7e1 10130 return false;
103f02d3 10131
071436c6
NC
10132 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10133 might not have the luxury of section headers. Look for the DT_NULL
10134 terminator to determine the number of entries. */
978c4450
AM
10135 for (ext = edyn, filedata->dynamic_nent = 0;
10136 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10137 ext++)
10138 {
978c4450 10139 filedata->dynamic_nent++;
ba2685cc
AM
10140 if (BYTE_GET (ext->d_tag) == DT_NULL)
10141 break;
10142 }
252b5132 10143
978c4450
AM
10144 filedata->dynamic_section
10145 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10146 if (filedata->dynamic_section == NULL)
252b5132 10147 {
8b73c356 10148 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10149 (unsigned long) filedata->dynamic_nent);
9ea033b2 10150 free (edyn);
015dc7e1 10151 return false;
9ea033b2 10152 }
252b5132 10153
978c4450
AM
10154 for (ext = edyn, entry = filedata->dynamic_section;
10155 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10156 ext++, entry++)
9ea033b2 10157 {
fb514b26
AM
10158 entry->d_tag = BYTE_GET (ext->d_tag);
10159 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10160 }
10161
9ea033b2
NC
10162 free (edyn);
10163
015dc7e1 10164 return true;
9ea033b2
NC
10165}
10166
015dc7e1 10167static bool
dda8d76d 10168get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10169{
2cf0635d
NC
10170 Elf64_External_Dyn * edyn;
10171 Elf64_External_Dyn * ext;
10172 Elf_Internal_Dyn * entry;
103f02d3 10173
071436c6 10174 /* Read in the data. */
978c4450
AM
10175 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10176 filedata->dynamic_addr, 1,
10177 filedata->dynamic_size,
10178 _("dynamic section"));
a6e9f9df 10179 if (!edyn)
015dc7e1 10180 return false;
103f02d3 10181
071436c6
NC
10182 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10183 might not have the luxury of section headers. Look for the DT_NULL
10184 terminator to determine the number of entries. */
978c4450 10185 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10186 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10187 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10188 ext++)
10189 {
978c4450 10190 filedata->dynamic_nent++;
66543521 10191 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10192 break;
10193 }
252b5132 10194
978c4450
AM
10195 filedata->dynamic_section
10196 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10197 if (filedata->dynamic_section == NULL)
252b5132 10198 {
8b73c356 10199 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10200 (unsigned long) filedata->dynamic_nent);
252b5132 10201 free (edyn);
015dc7e1 10202 return false;
252b5132
RH
10203 }
10204
071436c6 10205 /* Convert from external to internal formats. */
978c4450
AM
10206 for (ext = edyn, entry = filedata->dynamic_section;
10207 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10208 ext++, entry++)
252b5132 10209 {
66543521
AM
10210 entry->d_tag = BYTE_GET (ext->d_tag);
10211 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10212 }
10213
10214 free (edyn);
10215
015dc7e1 10216 return true;
9ea033b2
NC
10217}
10218
e9e44622
JJ
10219static void
10220print_dynamic_flags (bfd_vma flags)
d1133906 10221{
015dc7e1 10222 bool first = true;
13ae64f3 10223
d1133906
NC
10224 while (flags)
10225 {
10226 bfd_vma flag;
10227
10228 flag = flags & - flags;
10229 flags &= ~ flag;
10230
e9e44622 10231 if (first)
015dc7e1 10232 first = false;
e9e44622
JJ
10233 else
10234 putc (' ', stdout);
13ae64f3 10235
d1133906
NC
10236 switch (flag)
10237 {
e9e44622
JJ
10238 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10239 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10240 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10241 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10242 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10243 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10244 }
10245 }
e9e44622 10246 puts ("");
d1133906
NC
10247}
10248
10ca4b04
L
10249static bfd_vma *
10250get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10251{
10252 unsigned char * e_data;
10253 bfd_vma * i_data;
10254
10255 /* If the size_t type is smaller than the bfd_size_type, eg because
10256 you are building a 32-bit tool on a 64-bit host, then make sure
10257 that when (number) is cast to (size_t) no information is lost. */
10258 if (sizeof (size_t) < sizeof (bfd_size_type)
10259 && (bfd_size_type) ((size_t) number) != number)
10260 {
10261 error (_("Size truncation prevents reading %s elements of size %u\n"),
10262 bfd_vmatoa ("u", number), ent_size);
10263 return NULL;
10264 }
10265
10266 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10267 attempting to allocate memory when the read is bound to fail. */
10268 if (ent_size * number > filedata->file_size)
10269 {
10270 error (_("Invalid number of dynamic entries: %s\n"),
10271 bfd_vmatoa ("u", number));
10272 return NULL;
10273 }
10274
10275 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10276 if (e_data == NULL)
10277 {
10278 error (_("Out of memory reading %s dynamic entries\n"),
10279 bfd_vmatoa ("u", number));
10280 return NULL;
10281 }
10282
10283 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10284 {
10285 error (_("Unable to read in %s bytes of dynamic data\n"),
10286 bfd_vmatoa ("u", number * ent_size));
10287 free (e_data);
10288 return NULL;
10289 }
10290
10291 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10292 if (i_data == NULL)
10293 {
10294 error (_("Out of memory allocating space for %s dynamic entries\n"),
10295 bfd_vmatoa ("u", number));
10296 free (e_data);
10297 return NULL;
10298 }
10299
10300 while (number--)
10301 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10302
10303 free (e_data);
10304
10305 return i_data;
10306}
10307
10308static unsigned long
10309get_num_dynamic_syms (Filedata * filedata)
10310{
10311 unsigned long num_of_syms = 0;
10312
10313 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10314 return num_of_syms;
10315
978c4450 10316 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10317 {
10318 unsigned char nb[8];
10319 unsigned char nc[8];
10320 unsigned int hash_ent_size = 4;
10321
10322 if ((filedata->file_header.e_machine == EM_ALPHA
10323 || filedata->file_header.e_machine == EM_S390
10324 || filedata->file_header.e_machine == EM_S390_OLD)
10325 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10326 hash_ent_size = 8;
10327
10328 if (fseek (filedata->handle,
978c4450
AM
10329 (filedata->archive_file_offset
10330 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10331 sizeof nb + sizeof nc)),
10332 SEEK_SET))
10333 {
10334 error (_("Unable to seek to start of dynamic information\n"));
10335 goto no_hash;
10336 }
10337
10338 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10339 {
10340 error (_("Failed to read in number of buckets\n"));
10341 goto no_hash;
10342 }
10343
10344 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10345 {
10346 error (_("Failed to read in number of chains\n"));
10347 goto no_hash;
10348 }
10349
978c4450
AM
10350 filedata->nbuckets = byte_get (nb, hash_ent_size);
10351 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10352
2482f306
AM
10353 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10354 {
10355 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10356 hash_ent_size);
10357 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10358 hash_ent_size);
001890e1 10359
2482f306
AM
10360 if (filedata->buckets != NULL && filedata->chains != NULL)
10361 num_of_syms = filedata->nchains;
10362 }
ceb9bf11 10363 no_hash:
10ca4b04
L
10364 if (num_of_syms == 0)
10365 {
9db70fc3
AM
10366 free (filedata->buckets);
10367 filedata->buckets = NULL;
10368 free (filedata->chains);
10369 filedata->chains = NULL;
978c4450 10370 filedata->nbuckets = 0;
10ca4b04
L
10371 }
10372 }
10373
978c4450 10374 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10375 {
10376 unsigned char nb[16];
10377 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10378 bfd_vma buckets_vma;
10379 unsigned long hn;
10ca4b04
L
10380
10381 if (fseek (filedata->handle,
978c4450
AM
10382 (filedata->archive_file_offset
10383 + offset_from_vma (filedata,
10384 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10385 sizeof nb)),
10386 SEEK_SET))
10387 {
10388 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10389 goto no_gnu_hash;
10390 }
10391
10392 if (fread (nb, 16, 1, filedata->handle) != 1)
10393 {
10394 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10395 goto no_gnu_hash;
10396 }
10397
978c4450
AM
10398 filedata->ngnubuckets = byte_get (nb, 4);
10399 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10400 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10401 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10402 if (is_32bit_elf)
10403 buckets_vma += bitmaskwords * 4;
10404 else
10405 buckets_vma += bitmaskwords * 8;
10406
10407 if (fseek (filedata->handle,
978c4450 10408 (filedata->archive_file_offset
10ca4b04
L
10409 + offset_from_vma (filedata, buckets_vma, 4)),
10410 SEEK_SET))
10411 {
10412 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10413 goto no_gnu_hash;
10414 }
10415
978c4450
AM
10416 filedata->gnubuckets
10417 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10418
978c4450 10419 if (filedata->gnubuckets == NULL)
90837ea7 10420 goto no_gnu_hash;
10ca4b04 10421
978c4450
AM
10422 for (i = 0; i < filedata->ngnubuckets; i++)
10423 if (filedata->gnubuckets[i] != 0)
10ca4b04 10424 {
978c4450 10425 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10426 goto no_gnu_hash;
10ca4b04 10427
978c4450
AM
10428 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10429 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10430 }
10431
10432 if (maxchain == 0xffffffff)
90837ea7 10433 goto no_gnu_hash;
10ca4b04 10434
978c4450 10435 maxchain -= filedata->gnusymidx;
10ca4b04
L
10436
10437 if (fseek (filedata->handle,
978c4450
AM
10438 (filedata->archive_file_offset
10439 + offset_from_vma (filedata,
10440 buckets_vma + 4 * (filedata->ngnubuckets
10441 + maxchain),
10442 4)),
10ca4b04
L
10443 SEEK_SET))
10444 {
10445 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10446 goto no_gnu_hash;
10447 }
10448
10449 do
10450 {
10451 if (fread (nb, 4, 1, filedata->handle) != 1)
10452 {
10453 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10454 goto no_gnu_hash;
10455 }
10456
10457 if (maxchain + 1 == 0)
90837ea7 10458 goto no_gnu_hash;
10ca4b04
L
10459
10460 ++maxchain;
10461 }
10462 while ((byte_get (nb, 4) & 1) == 0);
10463
10464 if (fseek (filedata->handle,
978c4450
AM
10465 (filedata->archive_file_offset
10466 + offset_from_vma (filedata, (buckets_vma
10467 + 4 * filedata->ngnubuckets),
10468 4)),
10ca4b04
L
10469 SEEK_SET))
10470 {
10471 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10472 goto no_gnu_hash;
10473 }
10474
978c4450
AM
10475 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10476 filedata->ngnuchains = maxchain;
10ca4b04 10477
978c4450 10478 if (filedata->gnuchains == NULL)
90837ea7 10479 goto no_gnu_hash;
10ca4b04 10480
978c4450 10481 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10482 {
10483 if (fseek (filedata->handle,
978c4450 10484 (filedata->archive_file_offset
10ca4b04 10485 + offset_from_vma (filedata, (buckets_vma
978c4450 10486 + 4 * (filedata->ngnubuckets
10ca4b04
L
10487 + maxchain)), 4)),
10488 SEEK_SET))
10489 {
10490 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10491 goto no_gnu_hash;
10492 }
10493
978c4450 10494 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10495 if (filedata->mipsxlat == NULL)
10496 goto no_gnu_hash;
10ca4b04
L
10497 }
10498
978c4450
AM
10499 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10500 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10501 {
978c4450
AM
10502 bfd_vma si = filedata->gnubuckets[hn];
10503 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10504
10505 do
10506 {
978c4450 10507 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 10508 {
c31ab5a0
AM
10509 if (off < filedata->ngnuchains
10510 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 10511 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
10512 }
10513 else
10514 {
10515 if (si >= num_of_syms)
10516 num_of_syms = si + 1;
10517 }
10518 si++;
10519 }
978c4450
AM
10520 while (off < filedata->ngnuchains
10521 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
10522 }
10523
90837ea7 10524 if (num_of_syms == 0)
10ca4b04 10525 {
90837ea7 10526 no_gnu_hash:
9db70fc3
AM
10527 free (filedata->mipsxlat);
10528 filedata->mipsxlat = NULL;
10529 free (filedata->gnuchains);
10530 filedata->gnuchains = NULL;
10531 free (filedata->gnubuckets);
10532 filedata->gnubuckets = NULL;
978c4450
AM
10533 filedata->ngnubuckets = 0;
10534 filedata->ngnuchains = 0;
10ca4b04
L
10535 }
10536 }
10537
10538 return num_of_syms;
10539}
10540
b2d38a17
NC
10541/* Parse and display the contents of the dynamic section. */
10542
015dc7e1 10543static bool
dda8d76d 10544process_dynamic_section (Filedata * filedata)
9ea033b2 10545{
2cf0635d 10546 Elf_Internal_Dyn * entry;
9ea033b2 10547
978c4450 10548 if (filedata->dynamic_size == 0)
9ea033b2
NC
10549 {
10550 if (do_dynamic)
ca0e11aa
NC
10551 {
10552 if (filedata->is_separate)
10553 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
10554 filedata->file_name);
10555 else
10556 printf (_("\nThere is no dynamic section in this file.\n"));
10557 }
9ea033b2 10558
015dc7e1 10559 return true;
9ea033b2
NC
10560 }
10561
10562 if (is_32bit_elf)
10563 {
dda8d76d 10564 if (! get_32bit_dynamic_section (filedata))
015dc7e1 10565 return false;
32ec8896
NC
10566 }
10567 else
10568 {
dda8d76d 10569 if (! get_64bit_dynamic_section (filedata))
015dc7e1 10570 return false;
9ea033b2 10571 }
9ea033b2 10572
252b5132 10573 /* Find the appropriate symbol table. */
978c4450 10574 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 10575 {
2482f306
AM
10576 unsigned long num_of_syms;
10577
978c4450
AM
10578 for (entry = filedata->dynamic_section;
10579 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10580 ++entry)
10ca4b04 10581 if (entry->d_tag == DT_SYMTAB)
978c4450 10582 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 10583 else if (entry->d_tag == DT_SYMENT)
978c4450 10584 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 10585 else if (entry->d_tag == DT_HASH)
978c4450 10586 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 10587 else if (entry->d_tag == DT_GNU_HASH)
978c4450 10588 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
10589 else if ((filedata->file_header.e_machine == EM_MIPS
10590 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10591 && entry->d_tag == DT_MIPS_XHASH)
10592 {
978c4450
AM
10593 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10594 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 10595 }
252b5132 10596
2482f306
AM
10597 num_of_syms = get_num_dynamic_syms (filedata);
10598
10599 if (num_of_syms != 0
10600 && filedata->dynamic_symbols == NULL
10601 && filedata->dynamic_info[DT_SYMTAB]
978c4450 10602 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
10603 {
10604 Elf_Internal_Phdr *seg;
2482f306 10605 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 10606
2482f306
AM
10607 if (! get_program_headers (filedata))
10608 {
10609 error (_("Cannot interpret virtual addresses "
10610 "without program headers.\n"));
015dc7e1 10611 return false;
2482f306 10612 }
252b5132 10613
2482f306
AM
10614 for (seg = filedata->program_headers;
10615 seg < filedata->program_headers + filedata->file_header.e_phnum;
10616 ++seg)
10617 {
10618 if (seg->p_type != PT_LOAD)
10619 continue;
252b5132 10620
2482f306
AM
10621 if (seg->p_offset + seg->p_filesz > filedata->file_size)
10622 {
10623 /* See PR 21379 for a reproducer. */
10624 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 10625 return false;
2482f306 10626 }
252b5132 10627
2482f306
AM
10628 if (vma >= (seg->p_vaddr & -seg->p_align)
10629 && vma < seg->p_vaddr + seg->p_filesz)
10630 {
10631 /* Since we do not know how big the symbol table is,
10632 we default to reading in up to the end of PT_LOAD
10633 segment and processing that. This is overkill, I
10634 know, but it should work. */
10635 Elf_Internal_Shdr section;
10636 section.sh_offset = (vma - seg->p_vaddr
10637 + seg->p_offset);
10638 section.sh_size = (num_of_syms
10639 * filedata->dynamic_info[DT_SYMENT]);
10640 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
10641
10642 if (do_checks
10643 && filedata->dynamic_symtab_section != NULL
10644 && ((filedata->dynamic_symtab_section->sh_offset
10645 != section.sh_offset)
10646 || (filedata->dynamic_symtab_section->sh_size
10647 != section.sh_size)
10648 || (filedata->dynamic_symtab_section->sh_entsize
10649 != section.sh_entsize)))
10650 warn (_("\
10651the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
10652
2482f306
AM
10653 section.sh_name = filedata->string_table_length;
10654 filedata->dynamic_symbols
10655 = GET_ELF_SYMBOLS (filedata, &section,
10656 &filedata->num_dynamic_syms);
10657 if (filedata->dynamic_symbols == NULL
10658 || filedata->num_dynamic_syms != num_of_syms)
10659 {
10660 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 10661 return false;
2482f306
AM
10662 }
10663 break;
10664 }
10665 }
10666 }
10667 }
252b5132
RH
10668
10669 /* Similarly find a string table. */
978c4450
AM
10670 if (filedata->dynamic_strings == NULL)
10671 for (entry = filedata->dynamic_section;
10672 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
10673 ++entry)
10674 {
10675 if (entry->d_tag == DT_STRTAB)
978c4450 10676 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 10677
10ca4b04 10678 if (entry->d_tag == DT_STRSZ)
978c4450 10679 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10680
978c4450
AM
10681 if (filedata->dynamic_info[DT_STRTAB]
10682 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
10683 {
10684 unsigned long offset;
978c4450 10685 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
10686
10687 offset = offset_from_vma (filedata,
978c4450 10688 filedata->dynamic_info[DT_STRTAB],
10ca4b04 10689 str_tab_len);
8ac10c5b
L
10690 if (do_checks
10691 && filedata->dynamic_strtab_section
10692 && ((filedata->dynamic_strtab_section->sh_offset
10693 != (file_ptr) offset)
10694 || (filedata->dynamic_strtab_section->sh_size
10695 != str_tab_len)))
10696 warn (_("\
10697the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
10698
978c4450
AM
10699 filedata->dynamic_strings
10700 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
10701 _("dynamic string table"));
10702 if (filedata->dynamic_strings == NULL)
10ca4b04
L
10703 {
10704 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10705 break;
10706 }
e3d39609 10707
978c4450 10708 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
10709 break;
10710 }
10711 }
252b5132
RH
10712
10713 /* And find the syminfo section if available. */
978c4450 10714 if (filedata->dynamic_syminfo == NULL)
252b5132 10715 {
3e8bba36 10716 unsigned long syminsz = 0;
252b5132 10717
978c4450
AM
10718 for (entry = filedata->dynamic_section;
10719 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10720 ++entry)
252b5132
RH
10721 {
10722 if (entry->d_tag == DT_SYMINENT)
10723 {
10724 /* Note: these braces are necessary to avoid a syntax
10725 error from the SunOS4 C compiler. */
049b0c3a
NC
10726 /* PR binutils/17531: A corrupt file can trigger this test.
10727 So do not use an assert, instead generate an error message. */
10728 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10729 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10730 (int) entry->d_un.d_val);
252b5132
RH
10731 }
10732 else if (entry->d_tag == DT_SYMINSZ)
10733 syminsz = entry->d_un.d_val;
10734 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
10735 filedata->dynamic_syminfo_offset
10736 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
10737 }
10738
978c4450 10739 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 10740 {
2cf0635d
NC
10741 Elf_External_Syminfo * extsyminfo;
10742 Elf_External_Syminfo * extsym;
10743 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10744
10745 /* There is a syminfo section. Read the data. */
3f5e193b 10746 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
10747 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
10748 1, syminsz, _("symbol information"));
a6e9f9df 10749 if (!extsyminfo)
015dc7e1 10750 return false;
252b5132 10751
978c4450 10752 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
10753 {
10754 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 10755 free (filedata->dynamic_syminfo);
e3d39609 10756 }
978c4450
AM
10757 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
10758 if (filedata->dynamic_syminfo == NULL)
252b5132 10759 {
2482f306
AM
10760 error (_("Out of memory allocating %lu bytes "
10761 "for dynamic symbol info\n"),
8b73c356 10762 (unsigned long) syminsz);
015dc7e1 10763 return false;
252b5132
RH
10764 }
10765
2482f306
AM
10766 filedata->dynamic_syminfo_nent
10767 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 10768 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
10769 syminfo < (filedata->dynamic_syminfo
10770 + filedata->dynamic_syminfo_nent);
86dba8ee 10771 ++syminfo, ++extsym)
252b5132 10772 {
86dba8ee
AM
10773 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10774 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10775 }
10776
10777 free (extsyminfo);
10778 }
10779 }
10780
978c4450 10781 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa
NC
10782 {
10783 if (filedata->dynamic_nent == 1)
10784 {
10785 if (filedata->is_separate)
10786 printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains 1 entry:\n"),
10787 filedata->file_name,
10788 filedata->dynamic_addr);
10789 else
10790 printf (_("\nDynamic section at offset 0x%lx contains 1 entry:\n"),
10791 filedata->dynamic_addr);
10792 }
10793 else
10794 {
10795 if (filedata->is_separate)
10796 printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n"),
10797 filedata->file_name,
10798 filedata->dynamic_addr,
10799 (unsigned long) filedata->dynamic_nent);
10800 else
10801 printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
10802 filedata->dynamic_addr,
10803 (unsigned long) filedata->dynamic_nent);
10804 }
10805 }
252b5132
RH
10806 if (do_dynamic)
10807 printf (_(" Tag Type Name/Value\n"));
10808
978c4450
AM
10809 for (entry = filedata->dynamic_section;
10810 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10811 entry++)
252b5132
RH
10812 {
10813 if (do_dynamic)
f7a99963 10814 {
2cf0635d 10815 const char * dtype;
e699b9ff 10816
f7a99963
NC
10817 putchar (' ');
10818 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10819 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10820 printf (" (%s)%*s", dtype,
32ec8896 10821 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10822 }
252b5132
RH
10823
10824 switch (entry->d_tag)
10825 {
d1133906
NC
10826 case DT_FLAGS:
10827 if (do_dynamic)
e9e44622 10828 print_dynamic_flags (entry->d_un.d_val);
d1133906 10829 break;
76da6bbe 10830
252b5132
RH
10831 case DT_AUXILIARY:
10832 case DT_FILTER:
019148e4
L
10833 case DT_CONFIG:
10834 case DT_DEPAUDIT:
10835 case DT_AUDIT:
252b5132
RH
10836 if (do_dynamic)
10837 {
019148e4 10838 switch (entry->d_tag)
b34976b6 10839 {
019148e4
L
10840 case DT_AUXILIARY:
10841 printf (_("Auxiliary library"));
10842 break;
10843
10844 case DT_FILTER:
10845 printf (_("Filter library"));
10846 break;
10847
b34976b6 10848 case DT_CONFIG:
019148e4
L
10849 printf (_("Configuration file"));
10850 break;
10851
10852 case DT_DEPAUDIT:
10853 printf (_("Dependency audit library"));
10854 break;
10855
10856 case DT_AUDIT:
10857 printf (_("Audit library"));
10858 break;
10859 }
252b5132 10860
978c4450
AM
10861 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10862 printf (": [%s]\n",
10863 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 10864 else
f7a99963
NC
10865 {
10866 printf (": ");
10867 print_vma (entry->d_un.d_val, PREFIX_HEX);
10868 putchar ('\n');
10869 }
252b5132
RH
10870 }
10871 break;
10872
dcefbbbd 10873 case DT_FEATURE:
252b5132
RH
10874 if (do_dynamic)
10875 {
10876 printf (_("Flags:"));
86f55779 10877
252b5132
RH
10878 if (entry->d_un.d_val == 0)
10879 printf (_(" None\n"));
10880 else
10881 {
10882 unsigned long int val = entry->d_un.d_val;
86f55779 10883
252b5132
RH
10884 if (val & DTF_1_PARINIT)
10885 {
10886 printf (" PARINIT");
10887 val ^= DTF_1_PARINIT;
10888 }
dcefbbbd
L
10889 if (val & DTF_1_CONFEXP)
10890 {
10891 printf (" CONFEXP");
10892 val ^= DTF_1_CONFEXP;
10893 }
252b5132
RH
10894 if (val != 0)
10895 printf (" %lx", val);
10896 puts ("");
10897 }
10898 }
10899 break;
10900
10901 case DT_POSFLAG_1:
10902 if (do_dynamic)
10903 {
10904 printf (_("Flags:"));
86f55779 10905
252b5132
RH
10906 if (entry->d_un.d_val == 0)
10907 printf (_(" None\n"));
10908 else
10909 {
10910 unsigned long int val = entry->d_un.d_val;
86f55779 10911
252b5132
RH
10912 if (val & DF_P1_LAZYLOAD)
10913 {
10914 printf (" LAZYLOAD");
10915 val ^= DF_P1_LAZYLOAD;
10916 }
10917 if (val & DF_P1_GROUPPERM)
10918 {
10919 printf (" GROUPPERM");
10920 val ^= DF_P1_GROUPPERM;
10921 }
10922 if (val != 0)
10923 printf (" %lx", val);
10924 puts ("");
10925 }
10926 }
10927 break;
10928
10929 case DT_FLAGS_1:
10930 if (do_dynamic)
10931 {
10932 printf (_("Flags:"));
10933 if (entry->d_un.d_val == 0)
10934 printf (_(" None\n"));
10935 else
10936 {
10937 unsigned long int val = entry->d_un.d_val;
86f55779 10938
252b5132
RH
10939 if (val & DF_1_NOW)
10940 {
10941 printf (" NOW");
10942 val ^= DF_1_NOW;
10943 }
10944 if (val & DF_1_GLOBAL)
10945 {
10946 printf (" GLOBAL");
10947 val ^= DF_1_GLOBAL;
10948 }
10949 if (val & DF_1_GROUP)
10950 {
10951 printf (" GROUP");
10952 val ^= DF_1_GROUP;
10953 }
10954 if (val & DF_1_NODELETE)
10955 {
10956 printf (" NODELETE");
10957 val ^= DF_1_NODELETE;
10958 }
10959 if (val & DF_1_LOADFLTR)
10960 {
10961 printf (" LOADFLTR");
10962 val ^= DF_1_LOADFLTR;
10963 }
10964 if (val & DF_1_INITFIRST)
10965 {
10966 printf (" INITFIRST");
10967 val ^= DF_1_INITFIRST;
10968 }
10969 if (val & DF_1_NOOPEN)
10970 {
10971 printf (" NOOPEN");
10972 val ^= DF_1_NOOPEN;
10973 }
10974 if (val & DF_1_ORIGIN)
10975 {
10976 printf (" ORIGIN");
10977 val ^= DF_1_ORIGIN;
10978 }
10979 if (val & DF_1_DIRECT)
10980 {
10981 printf (" DIRECT");
10982 val ^= DF_1_DIRECT;
10983 }
10984 if (val & DF_1_TRANS)
10985 {
10986 printf (" TRANS");
10987 val ^= DF_1_TRANS;
10988 }
10989 if (val & DF_1_INTERPOSE)
10990 {
10991 printf (" INTERPOSE");
10992 val ^= DF_1_INTERPOSE;
10993 }
f7db6139 10994 if (val & DF_1_NODEFLIB)
dcefbbbd 10995 {
f7db6139
L
10996 printf (" NODEFLIB");
10997 val ^= DF_1_NODEFLIB;
dcefbbbd
L
10998 }
10999 if (val & DF_1_NODUMP)
11000 {
11001 printf (" NODUMP");
11002 val ^= DF_1_NODUMP;
11003 }
34b60028 11004 if (val & DF_1_CONFALT)
dcefbbbd 11005 {
34b60028
L
11006 printf (" CONFALT");
11007 val ^= DF_1_CONFALT;
11008 }
11009 if (val & DF_1_ENDFILTEE)
11010 {
11011 printf (" ENDFILTEE");
11012 val ^= DF_1_ENDFILTEE;
11013 }
11014 if (val & DF_1_DISPRELDNE)
11015 {
11016 printf (" DISPRELDNE");
11017 val ^= DF_1_DISPRELDNE;
11018 }
11019 if (val & DF_1_DISPRELPND)
11020 {
11021 printf (" DISPRELPND");
11022 val ^= DF_1_DISPRELPND;
11023 }
11024 if (val & DF_1_NODIRECT)
11025 {
11026 printf (" NODIRECT");
11027 val ^= DF_1_NODIRECT;
11028 }
11029 if (val & DF_1_IGNMULDEF)
11030 {
11031 printf (" IGNMULDEF");
11032 val ^= DF_1_IGNMULDEF;
11033 }
11034 if (val & DF_1_NOKSYMS)
11035 {
11036 printf (" NOKSYMS");
11037 val ^= DF_1_NOKSYMS;
11038 }
11039 if (val & DF_1_NOHDR)
11040 {
11041 printf (" NOHDR");
11042 val ^= DF_1_NOHDR;
11043 }
11044 if (val & DF_1_EDITED)
11045 {
11046 printf (" EDITED");
11047 val ^= DF_1_EDITED;
11048 }
11049 if (val & DF_1_NORELOC)
11050 {
11051 printf (" NORELOC");
11052 val ^= DF_1_NORELOC;
11053 }
11054 if (val & DF_1_SYMINTPOSE)
11055 {
11056 printf (" SYMINTPOSE");
11057 val ^= DF_1_SYMINTPOSE;
11058 }
11059 if (val & DF_1_GLOBAUDIT)
11060 {
11061 printf (" GLOBAUDIT");
11062 val ^= DF_1_GLOBAUDIT;
11063 }
11064 if (val & DF_1_SINGLETON)
11065 {
11066 printf (" SINGLETON");
11067 val ^= DF_1_SINGLETON;
dcefbbbd 11068 }
5c383f02
RO
11069 if (val & DF_1_STUB)
11070 {
11071 printf (" STUB");
11072 val ^= DF_1_STUB;
11073 }
11074 if (val & DF_1_PIE)
11075 {
11076 printf (" PIE");
11077 val ^= DF_1_PIE;
11078 }
b1202ffa
L
11079 if (val & DF_1_KMOD)
11080 {
11081 printf (" KMOD");
11082 val ^= DF_1_KMOD;
11083 }
11084 if (val & DF_1_WEAKFILTER)
11085 {
11086 printf (" WEAKFILTER");
11087 val ^= DF_1_WEAKFILTER;
11088 }
11089 if (val & DF_1_NOCOMMON)
11090 {
11091 printf (" NOCOMMON");
11092 val ^= DF_1_NOCOMMON;
11093 }
252b5132
RH
11094 if (val != 0)
11095 printf (" %lx", val);
11096 puts ("");
11097 }
11098 }
11099 break;
11100
11101 case DT_PLTREL:
978c4450 11102 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11103 if (do_dynamic)
dda8d76d 11104 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11105 break;
11106
11107 case DT_NULL :
11108 case DT_NEEDED :
11109 case DT_PLTGOT :
11110 case DT_HASH :
11111 case DT_STRTAB :
11112 case DT_SYMTAB :
11113 case DT_RELA :
11114 case DT_INIT :
11115 case DT_FINI :
11116 case DT_SONAME :
11117 case DT_RPATH :
11118 case DT_SYMBOLIC:
11119 case DT_REL :
11120 case DT_DEBUG :
11121 case DT_TEXTREL :
11122 case DT_JMPREL :
019148e4 11123 case DT_RUNPATH :
978c4450 11124 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11125
11126 if (do_dynamic)
11127 {
2cf0635d 11128 char * name;
252b5132 11129
978c4450
AM
11130 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
11131 name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11132 else
d79b3d50 11133 name = NULL;
252b5132
RH
11134
11135 if (name)
11136 {
11137 switch (entry->d_tag)
11138 {
11139 case DT_NEEDED:
11140 printf (_("Shared library: [%s]"), name);
11141
13acb58d
AM
11142 if (filedata->program_interpreter
11143 && streq (name, filedata->program_interpreter))
f7a99963 11144 printf (_(" program interpreter"));
252b5132
RH
11145 break;
11146
11147 case DT_SONAME:
f7a99963 11148 printf (_("Library soname: [%s]"), name);
252b5132
RH
11149 break;
11150
11151 case DT_RPATH:
f7a99963 11152 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11153 break;
11154
019148e4
L
11155 case DT_RUNPATH:
11156 printf (_("Library runpath: [%s]"), name);
11157 break;
11158
252b5132 11159 default:
f7a99963
NC
11160 print_vma (entry->d_un.d_val, PREFIX_HEX);
11161 break;
252b5132
RH
11162 }
11163 }
11164 else
f7a99963
NC
11165 print_vma (entry->d_un.d_val, PREFIX_HEX);
11166
11167 putchar ('\n');
252b5132
RH
11168 }
11169 break;
11170
11171 case DT_PLTRELSZ:
11172 case DT_RELASZ :
11173 case DT_STRSZ :
11174 case DT_RELSZ :
11175 case DT_RELAENT :
11176 case DT_SYMENT :
11177 case DT_RELENT :
978c4450 11178 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11179 /* Fall through. */
252b5132
RH
11180 case DT_PLTPADSZ:
11181 case DT_MOVEENT :
11182 case DT_MOVESZ :
11183 case DT_INIT_ARRAYSZ:
11184 case DT_FINI_ARRAYSZ:
047b2264
JJ
11185 case DT_GNU_CONFLICTSZ:
11186 case DT_GNU_LIBLISTSZ:
252b5132 11187 if (do_dynamic)
f7a99963
NC
11188 {
11189 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11190 printf (_(" (bytes)\n"));
f7a99963 11191 }
252b5132
RH
11192 break;
11193
11194 case DT_VERDEFNUM:
11195 case DT_VERNEEDNUM:
11196 case DT_RELACOUNT:
11197 case DT_RELCOUNT:
11198 if (do_dynamic)
f7a99963
NC
11199 {
11200 print_vma (entry->d_un.d_val, UNSIGNED);
11201 putchar ('\n');
11202 }
252b5132
RH
11203 break;
11204
11205 case DT_SYMINSZ:
11206 case DT_SYMINENT:
11207 case DT_SYMINFO:
11208 case DT_USED:
11209 case DT_INIT_ARRAY:
11210 case DT_FINI_ARRAY:
11211 if (do_dynamic)
11212 {
d79b3d50 11213 if (entry->d_tag == DT_USED
978c4450 11214 && VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
252b5132 11215 {
978c4450 11216 char * name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11217
b34976b6 11218 if (*name)
252b5132
RH
11219 {
11220 printf (_("Not needed object: [%s]\n"), name);
11221 break;
11222 }
11223 }
103f02d3 11224
f7a99963
NC
11225 print_vma (entry->d_un.d_val, PREFIX_HEX);
11226 putchar ('\n');
252b5132
RH
11227 }
11228 break;
11229
11230 case DT_BIND_NOW:
11231 /* The value of this entry is ignored. */
35b1837e
AM
11232 if (do_dynamic)
11233 putchar ('\n');
252b5132 11234 break;
103f02d3 11235
047b2264
JJ
11236 case DT_GNU_PRELINKED:
11237 if (do_dynamic)
11238 {
2cf0635d 11239 struct tm * tmp;
91d6fa6a 11240 time_t atime = entry->d_un.d_val;
047b2264 11241
91d6fa6a 11242 tmp = gmtime (&atime);
071436c6
NC
11243 /* PR 17533 file: 041-1244816-0.004. */
11244 if (tmp == NULL)
5a2cbcf4
L
11245 printf (_("<corrupt time val: %lx"),
11246 (unsigned long) atime);
071436c6
NC
11247 else
11248 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11249 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11250 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11251
11252 }
11253 break;
11254
fdc90cb4 11255 case DT_GNU_HASH:
978c4450 11256 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11257 if (do_dynamic)
11258 {
11259 print_vma (entry->d_un.d_val, PREFIX_HEX);
11260 putchar ('\n');
11261 }
11262 break;
11263
a5da3dee
VDM
11264 case DT_GNU_FLAGS_1:
11265 if (do_dynamic)
11266 {
11267 printf (_("Flags:"));
11268 if (entry->d_un.d_val == 0)
11269 printf (_(" None\n"));
11270 else
11271 {
11272 unsigned long int val = entry->d_un.d_val;
11273
11274 if (val & DF_GNU_1_UNIQUE)
11275 {
11276 printf (" UNIQUE");
11277 val ^= DF_GNU_1_UNIQUE;
11278 }
11279 if (val != 0)
11280 printf (" %lx", val);
11281 puts ("");
11282 }
11283 }
11284 break;
11285
252b5132
RH
11286 default:
11287 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11288 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11289 = entry->d_un.d_val;
252b5132
RH
11290
11291 if (do_dynamic)
11292 {
dda8d76d 11293 switch (filedata->file_header.e_machine)
252b5132 11294 {
37c18eed
SD
11295 case EM_AARCH64:
11296 dynamic_section_aarch64_val (entry);
11297 break;
252b5132 11298 case EM_MIPS:
4fe85591 11299 case EM_MIPS_RS3_LE:
978c4450 11300 dynamic_section_mips_val (filedata, entry);
252b5132 11301 break;
103f02d3 11302 case EM_PARISC:
b2d38a17 11303 dynamic_section_parisc_val (entry);
103f02d3 11304 break;
ecc51f48 11305 case EM_IA_64:
b2d38a17 11306 dynamic_section_ia64_val (entry);
ecc51f48 11307 break;
252b5132 11308 default:
f7a99963
NC
11309 print_vma (entry->d_un.d_val, PREFIX_HEX);
11310 putchar ('\n');
252b5132
RH
11311 }
11312 }
11313 break;
11314 }
11315 }
11316
015dc7e1 11317 return true;
252b5132
RH
11318}
11319
11320static char *
d3ba0551 11321get_ver_flags (unsigned int flags)
252b5132 11322{
6d4f21f6 11323 static char buff[128];
252b5132
RH
11324
11325 buff[0] = 0;
11326
11327 if (flags == 0)
11328 return _("none");
11329
11330 if (flags & VER_FLG_BASE)
7bb1ad17 11331 strcat (buff, "BASE");
252b5132
RH
11332
11333 if (flags & VER_FLG_WEAK)
11334 {
11335 if (flags & VER_FLG_BASE)
7bb1ad17 11336 strcat (buff, " | ");
252b5132 11337
7bb1ad17 11338 strcat (buff, "WEAK");
252b5132
RH
11339 }
11340
44ec90b9
RO
11341 if (flags & VER_FLG_INFO)
11342 {
11343 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11344 strcat (buff, " | ");
44ec90b9 11345
7bb1ad17 11346 strcat (buff, "INFO");
44ec90b9
RO
11347 }
11348
11349 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11350 {
11351 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11352 strcat (buff, " | ");
11353
11354 strcat (buff, _("<unknown>"));
11355 }
252b5132
RH
11356
11357 return buff;
11358}
11359
11360/* Display the contents of the version sections. */
98fb390a 11361
015dc7e1 11362static bool
dda8d76d 11363process_version_sections (Filedata * filedata)
252b5132 11364{
2cf0635d 11365 Elf_Internal_Shdr * section;
b34976b6 11366 unsigned i;
015dc7e1 11367 bool found = false;
252b5132
RH
11368
11369 if (! do_version)
015dc7e1 11370 return true;
252b5132 11371
dda8d76d
NC
11372 for (i = 0, section = filedata->section_headers;
11373 i < filedata->file_header.e_shnum;
b34976b6 11374 i++, section++)
252b5132
RH
11375 {
11376 switch (section->sh_type)
11377 {
11378 case SHT_GNU_verdef:
11379 {
2cf0635d 11380 Elf_External_Verdef * edefs;
452bf675
AM
11381 unsigned long idx;
11382 unsigned long cnt;
2cf0635d 11383 char * endbuf;
252b5132 11384
015dc7e1 11385 found = true;
252b5132 11386
ca0e11aa
NC
11387 if (filedata->is_separate)
11388 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
11389 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
11390 section->sh_info),
11391 filedata->file_name,
11392 printable_section_name (filedata, section),
11393 section->sh_info);
11394 else
11395 printf (ngettext ("\nVersion definition section '%s' "
11396 "contains %u entry:\n",
11397 "\nVersion definition section '%s' "
11398 "contains %u entries:\n",
11399 section->sh_info),
11400 printable_section_name (filedata, section),
11401 section->sh_info);
047c3dbf 11402
ae9ac79e 11403 printf (_(" Addr: 0x"));
252b5132 11404 printf_vma (section->sh_addr);
233f82cf 11405 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11406 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11407 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11408
3f5e193b 11409 edefs = (Elf_External_Verdef *)
dda8d76d 11410 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11411 _("version definition section"));
a6e9f9df
AM
11412 if (!edefs)
11413 break;
59245841 11414 endbuf = (char *) edefs + section->sh_size;
252b5132 11415
1445030f 11416 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11417 {
2cf0635d
NC
11418 char * vstart;
11419 Elf_External_Verdef * edef;
b34976b6 11420 Elf_Internal_Verdef ent;
2cf0635d 11421 Elf_External_Verdaux * eaux;
b34976b6 11422 Elf_Internal_Verdaux aux;
452bf675 11423 unsigned long isum;
b34976b6 11424 int j;
103f02d3 11425
252b5132 11426 vstart = ((char *) edefs) + idx;
54806181
AM
11427 if (vstart + sizeof (*edef) > endbuf)
11428 break;
252b5132
RH
11429
11430 edef = (Elf_External_Verdef *) vstart;
11431
11432 ent.vd_version = BYTE_GET (edef->vd_version);
11433 ent.vd_flags = BYTE_GET (edef->vd_flags);
11434 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11435 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11436 ent.vd_hash = BYTE_GET (edef->vd_hash);
11437 ent.vd_aux = BYTE_GET (edef->vd_aux);
11438 ent.vd_next = BYTE_GET (edef->vd_next);
11439
452bf675 11440 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11441 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11442
11443 printf (_(" Index: %d Cnt: %d "),
11444 ent.vd_ndx, ent.vd_cnt);
11445
452bf675 11446 /* Check for overflow. */
1445030f 11447 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11448 break;
11449
252b5132
RH
11450 vstart += ent.vd_aux;
11451
1445030f
AM
11452 if (vstart + sizeof (*eaux) > endbuf)
11453 break;
252b5132
RH
11454 eaux = (Elf_External_Verdaux *) vstart;
11455
11456 aux.vda_name = BYTE_GET (eaux->vda_name);
11457 aux.vda_next = BYTE_GET (eaux->vda_next);
11458
978c4450
AM
11459 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
11460 printf (_("Name: %s\n"),
11461 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132
RH
11462 else
11463 printf (_("Name index: %ld\n"), aux.vda_name);
11464
11465 isum = idx + ent.vd_aux;
11466
b34976b6 11467 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11468 {
1445030f
AM
11469 if (aux.vda_next < sizeof (*eaux)
11470 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11471 {
11472 warn (_("Invalid vda_next field of %lx\n"),
11473 aux.vda_next);
11474 j = ent.vd_cnt;
11475 break;
11476 }
dd24e3da 11477 /* Check for overflow. */
7e26601c 11478 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11479 break;
11480
252b5132
RH
11481 isum += aux.vda_next;
11482 vstart += aux.vda_next;
11483
54806181
AM
11484 if (vstart + sizeof (*eaux) > endbuf)
11485 break;
1445030f 11486 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11487
11488 aux.vda_name = BYTE_GET (eaux->vda_name);
11489 aux.vda_next = BYTE_GET (eaux->vda_next);
11490
978c4450 11491 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
452bf675 11492 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450
AM
11493 isum, j,
11494 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132 11495 else
452bf675 11496 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11497 isum, j, aux.vda_name);
11498 }
dd24e3da 11499
54806181
AM
11500 if (j < ent.vd_cnt)
11501 printf (_(" Version def aux past end of section\n"));
252b5132 11502
c9f02c3e
MR
11503 /* PR 17531:
11504 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11505 if (ent.vd_next < sizeof (*edef)
11506 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11507 {
11508 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11509 cnt = section->sh_info;
11510 break;
11511 }
452bf675 11512 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11513 break;
11514
252b5132
RH
11515 idx += ent.vd_next;
11516 }
dd24e3da 11517
54806181
AM
11518 if (cnt < section->sh_info)
11519 printf (_(" Version definition past end of section\n"));
252b5132
RH
11520
11521 free (edefs);
11522 }
11523 break;
103f02d3 11524
252b5132
RH
11525 case SHT_GNU_verneed:
11526 {
2cf0635d 11527 Elf_External_Verneed * eneed;
452bf675
AM
11528 unsigned long idx;
11529 unsigned long cnt;
2cf0635d 11530 char * endbuf;
252b5132 11531
015dc7e1 11532 found = true;
252b5132 11533
ca0e11aa
NC
11534 if (filedata->is_separate)
11535 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
11536 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
11537 section->sh_info),
11538 filedata->file_name,
11539 printable_section_name (filedata, section),
11540 section->sh_info);
11541 else
11542 printf (ngettext ("\nVersion needs section '%s' "
11543 "contains %u entry:\n",
11544 "\nVersion needs section '%s' "
11545 "contains %u entries:\n",
11546 section->sh_info),
11547 printable_section_name (filedata, section),
11548 section->sh_info);
047c3dbf 11549
252b5132
RH
11550 printf (_(" Addr: 0x"));
11551 printf_vma (section->sh_addr);
72de5009 11552 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11553 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11554 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11555
dda8d76d 11556 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11557 section->sh_offset, 1,
11558 section->sh_size,
9cf03b7e 11559 _("Version Needs section"));
a6e9f9df
AM
11560 if (!eneed)
11561 break;
59245841 11562 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11563
11564 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11565 {
2cf0635d 11566 Elf_External_Verneed * entry;
b34976b6 11567 Elf_Internal_Verneed ent;
452bf675 11568 unsigned long isum;
b34976b6 11569 int j;
2cf0635d 11570 char * vstart;
252b5132
RH
11571
11572 vstart = ((char *) eneed) + idx;
54806181
AM
11573 if (vstart + sizeof (*entry) > endbuf)
11574 break;
252b5132
RH
11575
11576 entry = (Elf_External_Verneed *) vstart;
11577
11578 ent.vn_version = BYTE_GET (entry->vn_version);
11579 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11580 ent.vn_file = BYTE_GET (entry->vn_file);
11581 ent.vn_aux = BYTE_GET (entry->vn_aux);
11582 ent.vn_next = BYTE_GET (entry->vn_next);
11583
452bf675 11584 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11585
978c4450
AM
11586 if (VALID_DYNAMIC_NAME (filedata, ent.vn_file))
11587 printf (_(" File: %s"),
11588 GET_DYNAMIC_NAME (filedata, ent.vn_file));
252b5132
RH
11589 else
11590 printf (_(" File: %lx"), ent.vn_file);
11591
11592 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11593
dd24e3da 11594 /* Check for overflow. */
7e26601c 11595 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11596 break;
252b5132
RH
11597 vstart += ent.vn_aux;
11598
11599 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11600 {
2cf0635d 11601 Elf_External_Vernaux * eaux;
b34976b6 11602 Elf_Internal_Vernaux aux;
252b5132 11603
54806181
AM
11604 if (vstart + sizeof (*eaux) > endbuf)
11605 break;
252b5132
RH
11606 eaux = (Elf_External_Vernaux *) vstart;
11607
11608 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11609 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11610 aux.vna_other = BYTE_GET (eaux->vna_other);
11611 aux.vna_name = BYTE_GET (eaux->vna_name);
11612 aux.vna_next = BYTE_GET (eaux->vna_next);
11613
978c4450 11614 if (VALID_DYNAMIC_NAME (filedata, aux.vna_name))
452bf675 11615 printf (_(" %#06lx: Name: %s"),
978c4450 11616 isum, GET_DYNAMIC_NAME (filedata, aux.vna_name));
252b5132 11617 else
452bf675 11618 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11619 isum, aux.vna_name);
11620
11621 printf (_(" Flags: %s Version: %d\n"),
11622 get_ver_flags (aux.vna_flags), aux.vna_other);
11623
1445030f
AM
11624 if (aux.vna_next < sizeof (*eaux)
11625 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11626 {
11627 warn (_("Invalid vna_next field of %lx\n"),
11628 aux.vna_next);
11629 j = ent.vn_cnt;
11630 break;
11631 }
1445030f
AM
11632 /* Check for overflow. */
11633 if (aux.vna_next > (size_t) (endbuf - vstart))
11634 break;
252b5132
RH
11635 isum += aux.vna_next;
11636 vstart += aux.vna_next;
11637 }
9cf03b7e 11638
54806181 11639 if (j < ent.vn_cnt)
f9a6a8f0 11640 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 11641
1445030f
AM
11642 if (ent.vn_next < sizeof (*entry)
11643 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11644 {
452bf675 11645 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11646 cnt = section->sh_info;
11647 break;
11648 }
1445030f
AM
11649 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11650 break;
252b5132
RH
11651 idx += ent.vn_next;
11652 }
9cf03b7e 11653
54806181 11654 if (cnt < section->sh_info)
9cf03b7e 11655 warn (_("Missing Version Needs information\n"));
103f02d3 11656
252b5132
RH
11657 free (eneed);
11658 }
11659 break;
11660
11661 case SHT_GNU_versym:
11662 {
2cf0635d 11663 Elf_Internal_Shdr * link_section;
8b73c356
NC
11664 size_t total;
11665 unsigned int cnt;
2cf0635d
NC
11666 unsigned char * edata;
11667 unsigned short * data;
11668 char * strtab;
11669 Elf_Internal_Sym * symbols;
11670 Elf_Internal_Shdr * string_sec;
ba5cdace 11671 unsigned long num_syms;
d3ba0551 11672 long off;
252b5132 11673
dda8d76d 11674 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11675 break;
11676
dda8d76d 11677 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11678 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11679
dda8d76d 11680 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11681 break;
11682
015dc7e1 11683 found = true;
252b5132 11684
dda8d76d 11685 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
11686 if (symbols == NULL)
11687 break;
252b5132 11688
dda8d76d 11689 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11690
dda8d76d 11691 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11692 string_sec->sh_size,
11693 _("version string table"));
a6e9f9df 11694 if (!strtab)
0429c154
MS
11695 {
11696 free (symbols);
11697 break;
11698 }
252b5132 11699
ca0e11aa
NC
11700 if (filedata->is_separate)
11701 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
11702 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
11703 total),
11704 filedata->file_name,
11705 printable_section_name (filedata, section),
11706 (unsigned long) total);
11707 else
11708 printf (ngettext ("\nVersion symbols section '%s' "
11709 "contains %lu entry:\n",
11710 "\nVersion symbols section '%s' "
11711 "contains %lu entries:\n",
11712 total),
11713 printable_section_name (filedata, section),
11714 (unsigned long) total);
252b5132 11715
ae9ac79e 11716 printf (_(" Addr: 0x"));
252b5132 11717 printf_vma (section->sh_addr);
72de5009 11718 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11719 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11720 printable_section_name (filedata, link_section));
252b5132 11721
dda8d76d 11722 off = offset_from_vma (filedata,
978c4450 11723 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11724 total * sizeof (short));
95099889
AM
11725 edata = (unsigned char *) get_data (NULL, filedata, off,
11726 sizeof (short), total,
11727 _("version symbol data"));
a6e9f9df
AM
11728 if (!edata)
11729 {
11730 free (strtab);
0429c154 11731 free (symbols);
a6e9f9df
AM
11732 break;
11733 }
252b5132 11734
3f5e193b 11735 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11736
11737 for (cnt = total; cnt --;)
b34976b6
AM
11738 data[cnt] = byte_get (edata + cnt * sizeof (short),
11739 sizeof (short));
252b5132
RH
11740
11741 free (edata);
11742
11743 for (cnt = 0; cnt < total; cnt += 4)
11744 {
11745 int j, nn;
ab273396
AM
11746 char *name;
11747 char *invalid = _("*invalid*");
252b5132
RH
11748
11749 printf (" %03x:", cnt);
11750
11751 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11752 switch (data[cnt + j])
252b5132
RH
11753 {
11754 case 0:
11755 fputs (_(" 0 (*local*) "), stdout);
11756 break;
11757
11758 case 1:
11759 fputs (_(" 1 (*global*) "), stdout);
11760 break;
11761
11762 default:
c244d050
NC
11763 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11764 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11765
dd24e3da 11766 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11767 array, break to avoid an out-of-bounds read. */
11768 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11769 {
11770 warn (_("invalid index into symbol array\n"));
11771 break;
11772 }
11773
ab273396 11774 name = NULL;
978c4450 11775 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11776 {
b34976b6
AM
11777 Elf_Internal_Verneed ivn;
11778 unsigned long offset;
252b5132 11779
d93f0186 11780 offset = offset_from_vma
978c4450
AM
11781 (filedata,
11782 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11783 sizeof (Elf_External_Verneed));
252b5132 11784
b34976b6 11785 do
252b5132 11786 {
b34976b6
AM
11787 Elf_Internal_Vernaux ivna;
11788 Elf_External_Verneed evn;
11789 Elf_External_Vernaux evna;
11790 unsigned long a_off;
252b5132 11791
dda8d76d 11792 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11793 _("version need")) == NULL)
11794 break;
0b4362b0 11795
252b5132
RH
11796 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11797 ivn.vn_next = BYTE_GET (evn.vn_next);
11798
11799 a_off = offset + ivn.vn_aux;
11800
11801 do
11802 {
dda8d76d 11803 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11804 1, _("version need aux (2)")) == NULL)
11805 {
11806 ivna.vna_next = 0;
11807 ivna.vna_other = 0;
11808 }
11809 else
11810 {
11811 ivna.vna_next = BYTE_GET (evna.vna_next);
11812 ivna.vna_other = BYTE_GET (evna.vna_other);
11813 }
252b5132
RH
11814
11815 a_off += ivna.vna_next;
11816 }
b34976b6 11817 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11818 && ivna.vna_next != 0);
11819
b34976b6 11820 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11821 {
11822 ivna.vna_name = BYTE_GET (evna.vna_name);
11823
54806181 11824 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11825 name = invalid;
54806181
AM
11826 else
11827 name = strtab + ivna.vna_name;
252b5132
RH
11828 break;
11829 }
11830
11831 offset += ivn.vn_next;
11832 }
11833 while (ivn.vn_next);
11834 }
00d93f34 11835
ab273396 11836 if (data[cnt + j] != 0x8001
978c4450 11837 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 11838 {
b34976b6
AM
11839 Elf_Internal_Verdef ivd;
11840 Elf_External_Verdef evd;
11841 unsigned long offset;
252b5132 11842
d93f0186 11843 offset = offset_from_vma
978c4450
AM
11844 (filedata,
11845 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 11846 sizeof evd);
252b5132
RH
11847
11848 do
11849 {
dda8d76d 11850 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
11851 _("version def")) == NULL)
11852 {
11853 ivd.vd_next = 0;
948f632f 11854 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
11855 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
11856 break;
59245841
NC
11857 }
11858 else
11859 {
11860 ivd.vd_next = BYTE_GET (evd.vd_next);
11861 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11862 }
252b5132
RH
11863
11864 offset += ivd.vd_next;
11865 }
c244d050 11866 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
11867 && ivd.vd_next != 0);
11868
c244d050 11869 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 11870 {
b34976b6
AM
11871 Elf_External_Verdaux evda;
11872 Elf_Internal_Verdaux ivda;
252b5132
RH
11873
11874 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11875
dda8d76d 11876 if (get_data (&evda, filedata,
59245841
NC
11877 offset - ivd.vd_next + ivd.vd_aux,
11878 sizeof (evda), 1,
11879 _("version def aux")) == NULL)
11880 break;
252b5132
RH
11881
11882 ivda.vda_name = BYTE_GET (evda.vda_name);
11883
54806181 11884 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
11885 name = invalid;
11886 else if (name != NULL && name != invalid)
11887 name = _("*both*");
54806181
AM
11888 else
11889 name = strtab + ivda.vda_name;
252b5132
RH
11890 }
11891 }
ab273396
AM
11892 if (name != NULL)
11893 nn += printf ("(%s%-*s",
11894 name,
11895 12 - (int) strlen (name),
11896 ")");
252b5132
RH
11897
11898 if (nn < 18)
11899 printf ("%*c", 18 - nn, ' ');
11900 }
11901
11902 putchar ('\n');
11903 }
11904
11905 free (data);
11906 free (strtab);
11907 free (symbols);
11908 }
11909 break;
103f02d3 11910
252b5132
RH
11911 default:
11912 break;
11913 }
11914 }
11915
11916 if (! found)
ca0e11aa
NC
11917 {
11918 if (filedata->is_separate)
11919 printf (_("\nNo version information found in linked file '%s'.\n"),
11920 filedata->file_name);
11921 else
11922 printf (_("\nNo version information found in this file.\n"));
11923 }
252b5132 11924
015dc7e1 11925 return true;
252b5132
RH
11926}
11927
d1133906 11928static const char *
dda8d76d 11929get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 11930{
89246a0e 11931 static char buff[64];
252b5132
RH
11932
11933 switch (binding)
11934 {
b34976b6
AM
11935 case STB_LOCAL: return "LOCAL";
11936 case STB_GLOBAL: return "GLOBAL";
11937 case STB_WEAK: return "WEAK";
252b5132
RH
11938 default:
11939 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
11940 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
11941 binding);
252b5132 11942 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
11943 {
11944 if (binding == STB_GNU_UNIQUE
df3a023b 11945 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
11946 return "UNIQUE";
11947 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
11948 }
252b5132 11949 else
e9e44622 11950 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
11951 return buff;
11952 }
11953}
11954
d1133906 11955static const char *
dda8d76d 11956get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 11957{
89246a0e 11958 static char buff[64];
252b5132
RH
11959
11960 switch (type)
11961 {
b34976b6
AM
11962 case STT_NOTYPE: return "NOTYPE";
11963 case STT_OBJECT: return "OBJECT";
11964 case STT_FUNC: return "FUNC";
11965 case STT_SECTION: return "SECTION";
11966 case STT_FILE: return "FILE";
11967 case STT_COMMON: return "COMMON";
11968 case STT_TLS: return "TLS";
15ab5209
DB
11969 case STT_RELC: return "RELC";
11970 case STT_SRELC: return "SRELC";
252b5132
RH
11971 default:
11972 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 11973 {
dda8d76d 11974 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 11975 return "THUMB_FUNC";
103f02d3 11976
dda8d76d 11977 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
11978 return "REGISTER";
11979
dda8d76d 11980 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
11981 return "PARISC_MILLI";
11982
e9e44622 11983 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 11984 }
252b5132 11985 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 11986 {
dda8d76d 11987 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
11988 {
11989 if (type == STT_HP_OPAQUE)
11990 return "HP_OPAQUE";
11991 if (type == STT_HP_STUB)
11992 return "HP_STUB";
11993 }
11994
d8045f23 11995 if (type == STT_GNU_IFUNC
dda8d76d 11996 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 11997 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
11998 return "IFUNC";
11999
e9e44622 12000 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12001 }
252b5132 12002 else
e9e44622 12003 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12004 return buff;
12005 }
12006}
12007
d1133906 12008static const char *
d3ba0551 12009get_symbol_visibility (unsigned int visibility)
d1133906
NC
12010{
12011 switch (visibility)
12012 {
b34976b6
AM
12013 case STV_DEFAULT: return "DEFAULT";
12014 case STV_INTERNAL: return "INTERNAL";
12015 case STV_HIDDEN: return "HIDDEN";
d1133906 12016 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12017 default:
27a45f42 12018 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12019 return _("<unknown>");
d1133906
NC
12020 }
12021}
12022
2057d69d
CZ
12023static const char *
12024get_alpha_symbol_other (unsigned int other)
9abca702 12025{
2057d69d
CZ
12026 switch (other)
12027 {
12028 case STO_ALPHA_NOPV: return "NOPV";
12029 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12030 default:
27a45f42 12031 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12032 return _("<unknown>");
9abca702 12033 }
2057d69d
CZ
12034}
12035
fd85a6a1
NC
12036static const char *
12037get_solaris_symbol_visibility (unsigned int visibility)
12038{
12039 switch (visibility)
12040 {
12041 case 4: return "EXPORTED";
12042 case 5: return "SINGLETON";
12043 case 6: return "ELIMINATE";
12044 default: return get_symbol_visibility (visibility);
12045 }
12046}
12047
2301ed1c
SN
12048static const char *
12049get_aarch64_symbol_other (unsigned int other)
12050{
12051 static char buf[32];
12052
12053 if (other & STO_AARCH64_VARIANT_PCS)
12054 {
12055 other &= ~STO_AARCH64_VARIANT_PCS;
12056 if (other == 0)
12057 return "VARIANT_PCS";
12058 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12059 return buf;
12060 }
12061 return NULL;
12062}
12063
5e2b0d47
NC
12064static const char *
12065get_mips_symbol_other (unsigned int other)
12066{
12067 switch (other)
12068 {
32ec8896
NC
12069 case STO_OPTIONAL: return "OPTIONAL";
12070 case STO_MIPS_PLT: return "MIPS PLT";
12071 case STO_MIPS_PIC: return "MIPS PIC";
12072 case STO_MICROMIPS: return "MICROMIPS";
12073 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12074 case STO_MIPS16: return "MIPS16";
12075 default: return NULL;
5e2b0d47
NC
12076 }
12077}
12078
28f997cf 12079static const char *
dda8d76d 12080get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12081{
dda8d76d 12082 if (is_ia64_vms (filedata))
28f997cf
TG
12083 {
12084 static char res[32];
12085
12086 res[0] = 0;
12087
12088 /* Function types is for images and .STB files only. */
dda8d76d 12089 switch (filedata->file_header.e_type)
28f997cf
TG
12090 {
12091 case ET_DYN:
12092 case ET_EXEC:
12093 switch (VMS_ST_FUNC_TYPE (other))
12094 {
12095 case VMS_SFT_CODE_ADDR:
12096 strcat (res, " CA");
12097 break;
12098 case VMS_SFT_SYMV_IDX:
12099 strcat (res, " VEC");
12100 break;
12101 case VMS_SFT_FD:
12102 strcat (res, " FD");
12103 break;
12104 case VMS_SFT_RESERVE:
12105 strcat (res, " RSV");
12106 break;
12107 default:
bee0ee85
NC
12108 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12109 VMS_ST_FUNC_TYPE (other));
12110 strcat (res, " <unknown>");
12111 break;
28f997cf
TG
12112 }
12113 break;
12114 default:
12115 break;
12116 }
12117 switch (VMS_ST_LINKAGE (other))
12118 {
12119 case VMS_STL_IGNORE:
12120 strcat (res, " IGN");
12121 break;
12122 case VMS_STL_RESERVE:
12123 strcat (res, " RSV");
12124 break;
12125 case VMS_STL_STD:
12126 strcat (res, " STD");
12127 break;
12128 case VMS_STL_LNK:
12129 strcat (res, " LNK");
12130 break;
12131 default:
bee0ee85
NC
12132 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12133 VMS_ST_LINKAGE (other));
12134 strcat (res, " <unknown>");
12135 break;
28f997cf
TG
12136 }
12137
12138 if (res[0] != 0)
12139 return res + 1;
12140 else
12141 return res;
12142 }
12143 return NULL;
12144}
12145
6911b7dc
AM
12146static const char *
12147get_ppc64_symbol_other (unsigned int other)
12148{
14732552
AM
12149 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12150 return NULL;
12151
12152 other >>= STO_PPC64_LOCAL_BIT;
12153 if (other <= 6)
6911b7dc 12154 {
89246a0e 12155 static char buf[64];
14732552
AM
12156 if (other >= 2)
12157 other = ppc64_decode_local_entry (other);
12158 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12159 return buf;
12160 }
12161 return NULL;
12162}
12163
5e2b0d47 12164static const char *
dda8d76d 12165get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12166{
12167 const char * result = NULL;
89246a0e 12168 static char buff [64];
5e2b0d47
NC
12169
12170 if (other == 0)
12171 return "";
12172
dda8d76d 12173 switch (filedata->file_header.e_machine)
5e2b0d47 12174 {
2057d69d
CZ
12175 case EM_ALPHA:
12176 result = get_alpha_symbol_other (other);
12177 break;
2301ed1c
SN
12178 case EM_AARCH64:
12179 result = get_aarch64_symbol_other (other);
12180 break;
5e2b0d47
NC
12181 case EM_MIPS:
12182 result = get_mips_symbol_other (other);
28f997cf
TG
12183 break;
12184 case EM_IA_64:
dda8d76d 12185 result = get_ia64_symbol_other (filedata, other);
28f997cf 12186 break;
6911b7dc
AM
12187 case EM_PPC64:
12188 result = get_ppc64_symbol_other (other);
12189 break;
5e2b0d47 12190 default:
fd85a6a1 12191 result = NULL;
5e2b0d47
NC
12192 break;
12193 }
12194
12195 if (result)
12196 return result;
12197
12198 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12199 return buff;
12200}
12201
d1133906 12202static const char *
dda8d76d 12203get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12204{
b34976b6 12205 static char buff[32];
5cf1065c 12206
252b5132
RH
12207 switch (type)
12208 {
b34976b6
AM
12209 case SHN_UNDEF: return "UND";
12210 case SHN_ABS: return "ABS";
12211 case SHN_COMMON: return "COM";
252b5132 12212 default:
9ce701e2 12213 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12214 && filedata->file_header.e_machine == EM_IA_64
12215 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12216 return "ANSI_COM";
12217 else if ((filedata->file_header.e_machine == EM_X86_64
12218 || filedata->file_header.e_machine == EM_L1OM
12219 || filedata->file_header.e_machine == EM_K1OM)
12220 && type == SHN_X86_64_LCOMMON)
12221 return "LARGE_COM";
12222 else if ((type == SHN_MIPS_SCOMMON
12223 && filedata->file_header.e_machine == EM_MIPS)
12224 || (type == SHN_TIC6X_SCOMMON
12225 && filedata->file_header.e_machine == EM_TI_C6000))
12226 return "SCOM";
12227 else if (type == SHN_MIPS_SUNDEFINED
12228 && filedata->file_header.e_machine == EM_MIPS)
12229 return "SUND";
12230 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12231 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12232 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12233 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12234 else if (type >= SHN_LORESERVE)
12235 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12236 else if (filedata->file_header.e_shnum != 0
12237 && type >= filedata->file_header.e_shnum)
12238 sprintf (buff, _("bad section index[%3d]"), type);
12239 else
12240 sprintf (buff, "%3d", type);
12241 break;
fd85a6a1
NC
12242 }
12243
10ca4b04 12244 return buff;
6bd1a22c
L
12245}
12246
bb4d2ac2 12247static const char *
dda8d76d 12248get_symbol_version_string (Filedata * filedata,
015dc7e1 12249 bool is_dynsym,
1449284b
NC
12250 const char * strtab,
12251 unsigned long int strtab_size,
12252 unsigned int si,
12253 Elf_Internal_Sym * psym,
12254 enum versioned_symbol_info * sym_info,
12255 unsigned short * vna_other)
bb4d2ac2 12256{
ab273396
AM
12257 unsigned char data[2];
12258 unsigned short vers_data;
12259 unsigned long offset;
7a815dd5 12260 unsigned short max_vd_ndx;
bb4d2ac2 12261
ab273396 12262 if (!is_dynsym
978c4450 12263 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12264 return NULL;
bb4d2ac2 12265
978c4450
AM
12266 offset = offset_from_vma (filedata,
12267 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12268 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12269
dda8d76d 12270 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12271 sizeof (data), 1, _("version data")) == NULL)
12272 return NULL;
12273
12274 vers_data = byte_get (data, 2);
bb4d2ac2 12275
1f6f5dba 12276 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12277 return NULL;
bb4d2ac2 12278
0b8b7609 12279 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12280 max_vd_ndx = 0;
12281
ab273396
AM
12282 /* Usually we'd only see verdef for defined symbols, and verneed for
12283 undefined symbols. However, symbols defined by the linker in
12284 .dynbss for variables copied from a shared library in order to
12285 avoid text relocations are defined yet have verneed. We could
12286 use a heuristic to detect the special case, for example, check
12287 for verneed first on symbols defined in SHT_NOBITS sections, but
12288 it is simpler and more reliable to just look for both verdef and
12289 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12290
ab273396
AM
12291 if (psym->st_shndx != SHN_UNDEF
12292 && vers_data != 0x8001
978c4450 12293 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12294 {
12295 Elf_Internal_Verdef ivd;
12296 Elf_Internal_Verdaux ivda;
12297 Elf_External_Verdaux evda;
12298 unsigned long off;
bb4d2ac2 12299
dda8d76d 12300 off = offset_from_vma (filedata,
978c4450 12301 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12302 sizeof (Elf_External_Verdef));
12303
12304 do
bb4d2ac2 12305 {
ab273396
AM
12306 Elf_External_Verdef evd;
12307
dda8d76d 12308 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12309 _("version def")) == NULL)
12310 {
12311 ivd.vd_ndx = 0;
12312 ivd.vd_aux = 0;
12313 ivd.vd_next = 0;
1f6f5dba 12314 ivd.vd_flags = 0;
ab273396
AM
12315 }
12316 else
bb4d2ac2 12317 {
ab273396
AM
12318 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12319 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12320 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12321 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12322 }
bb4d2ac2 12323
7a815dd5
L
12324 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12325 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12326
ab273396
AM
12327 off += ivd.vd_next;
12328 }
12329 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12330
ab273396
AM
12331 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12332 {
9abca702 12333 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12334 return NULL;
12335
ab273396
AM
12336 off -= ivd.vd_next;
12337 off += ivd.vd_aux;
bb4d2ac2 12338
dda8d76d 12339 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12340 _("version def aux")) != NULL)
12341 {
12342 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12343
ab273396 12344 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12345 return (ivda.vda_name < strtab_size
12346 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12347 }
12348 }
12349 }
bb4d2ac2 12350
978c4450 12351 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12352 {
12353 Elf_External_Verneed evn;
12354 Elf_Internal_Verneed ivn;
12355 Elf_Internal_Vernaux ivna;
bb4d2ac2 12356
dda8d76d 12357 offset = offset_from_vma (filedata,
978c4450 12358 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12359 sizeof evn);
12360 do
12361 {
12362 unsigned long vna_off;
bb4d2ac2 12363
dda8d76d 12364 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12365 _("version need")) == NULL)
12366 {
12367 ivna.vna_next = 0;
12368 ivna.vna_other = 0;
12369 ivna.vna_name = 0;
12370 break;
12371 }
bb4d2ac2 12372
ab273396
AM
12373 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12374 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12375
ab273396 12376 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12377
ab273396
AM
12378 do
12379 {
12380 Elf_External_Vernaux evna;
bb4d2ac2 12381
dda8d76d 12382 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12383 _("version need aux (3)")) == NULL)
bb4d2ac2 12384 {
ab273396
AM
12385 ivna.vna_next = 0;
12386 ivna.vna_other = 0;
12387 ivna.vna_name = 0;
bb4d2ac2 12388 }
bb4d2ac2 12389 else
bb4d2ac2 12390 {
ab273396
AM
12391 ivna.vna_other = BYTE_GET (evna.vna_other);
12392 ivna.vna_next = BYTE_GET (evna.vna_next);
12393 ivna.vna_name = BYTE_GET (evna.vna_name);
12394 }
bb4d2ac2 12395
ab273396
AM
12396 vna_off += ivna.vna_next;
12397 }
12398 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12399
ab273396
AM
12400 if (ivna.vna_other == vers_data)
12401 break;
bb4d2ac2 12402
ab273396
AM
12403 offset += ivn.vn_next;
12404 }
12405 while (ivn.vn_next != 0);
bb4d2ac2 12406
ab273396
AM
12407 if (ivna.vna_other == vers_data)
12408 {
12409 *sym_info = symbol_undefined;
12410 *vna_other = ivna.vna_other;
12411 return (ivna.vna_name < strtab_size
12412 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12413 }
7a815dd5
L
12414 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12415 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12416 return _("<corrupt>");
bb4d2ac2 12417 }
ab273396 12418 return NULL;
bb4d2ac2
L
12419}
12420
047c3dbf
NL
12421/* Display a symbol size on stdout. Format is based on --sym-base setting. */
12422
12423static unsigned int
12424print_dynamic_symbol_size (bfd_vma vma, int base)
12425{
12426 switch (base)
12427 {
12428 case 8:
12429 return print_vma (vma, OCTAL_5);
12430
12431 case 10:
12432 return print_vma (vma, UNSIGNED_5);
12433
12434 case 16:
12435 return print_vma (vma, PREFIX_HEX_5);
12436
12437 case 0:
12438 default:
12439 return print_vma (vma, DEC_5);
12440 }
12441}
12442
10ca4b04
L
12443static void
12444print_dynamic_symbol (Filedata *filedata, unsigned long si,
12445 Elf_Internal_Sym *symtab,
12446 Elf_Internal_Shdr *section,
12447 char *strtab, size_t strtab_size)
252b5132 12448{
10ca4b04
L
12449 const char *version_string;
12450 enum versioned_symbol_info sym_info;
12451 unsigned short vna_other;
23356397
NC
12452 bool is_valid;
12453 const char * sstr;
10ca4b04 12454 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 12455
10ca4b04
L
12456 printf ("%6ld: ", si);
12457 print_vma (psym->st_value, LONG_HEX);
12458 putchar (' ');
047c3dbf 12459 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
12460 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12461 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12462 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12463 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12464 else
252b5132 12465 {
10ca4b04 12466 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12467
10ca4b04
L
12468 printf (" %-7s", get_symbol_visibility (vis));
12469 /* Check to see if any other bits in the st_other field are set.
12470 Note - displaying this information disrupts the layout of the
12471 table being generated, but for the moment this case is very rare. */
12472 if (psym->st_other ^ vis)
12473 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12474 }
10ca4b04 12475 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 12476
23356397
NC
12477 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
12478 && psym->st_shndx < filedata->file_header.e_shnum
12479 && psym->st_name == 0)
12480 {
12481 is_valid = SECTION_NAME_VALID (filedata->section_headers + psym->st_shndx);
12482 sstr = is_valid ?
12483 SECTION_NAME_PRINT (filedata->section_headers + psym->st_shndx)
12484 : _("<corrupt>");
12485 }
12486 else
12487 {
12488 is_valid = VALID_SYMBOL_NAME (strtab, strtab_size, psym->st_name);
12489 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
12490 }
10ca4b04
L
12491
12492 version_string
12493 = get_symbol_version_string (filedata,
12494 (section == NULL
12495 || section->sh_type == SHT_DYNSYM),
12496 strtab, strtab_size, si,
12497 psym, &sym_info, &vna_other);
b9e920ec 12498
0942c7ab
NC
12499 int len_avail = 21;
12500 if (! do_wide && version_string != NULL)
12501 {
ddb43bab 12502 char buffer[16];
0942c7ab 12503
ddb43bab 12504 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
12505
12506 if (sym_info == symbol_undefined)
12507 len_avail -= sprintf (buffer," (%d)", vna_other);
12508 else if (sym_info != symbol_hidden)
12509 len_avail -= 1;
12510 }
12511
12512 print_symbol (len_avail, sstr);
b9e920ec 12513
10ca4b04
L
12514 if (version_string)
12515 {
12516 if (sym_info == symbol_undefined)
12517 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12518 else
10ca4b04
L
12519 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12520 version_string);
12521 }
6bd1a22c 12522
10ca4b04 12523 putchar ('\n');
6bd1a22c 12524
10ca4b04
L
12525 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12526 && section != NULL
12527 && si >= section->sh_info
12528 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12529 && filedata->file_header.e_machine != EM_MIPS
12530 /* Solaris binaries have been found to violate this requirement as
12531 well. Not sure if this is a bug or an ABI requirement. */
12532 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12533 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12534 si, printable_section_name (filedata, section), section->sh_info);
12535}
f16a9783 12536
0f03783c
NC
12537static const char *
12538get_lto_kind (unsigned int kind)
12539{
12540 switch (kind)
12541 {
12542 case 0: return "DEF";
12543 case 1: return "WEAKDEF";
12544 case 2: return "UNDEF";
12545 case 3: return "WEAKUNDEF";
12546 case 4: return "COMMON";
12547 default:
12548 break;
12549 }
12550
12551 static char buffer[30];
12552 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
12553 sprintf (buffer, "<unknown: %u>", kind);
12554 return buffer;
12555}
12556
12557static const char *
12558get_lto_visibility (unsigned int visibility)
12559{
12560 switch (visibility)
12561 {
12562 case 0: return "DEFAULT";
12563 case 1: return "PROTECTED";
12564 case 2: return "INTERNAL";
12565 case 3: return "HIDDEN";
12566 default:
12567 break;
12568 }
12569
12570 static char buffer[30];
12571 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
12572 sprintf (buffer, "<unknown: %u>", visibility);
12573 return buffer;
12574}
12575
12576static const char *
12577get_lto_sym_type (unsigned int sym_type)
12578{
12579 switch (sym_type)
12580 {
12581 case 0: return "UNKNOWN";
12582 case 1: return "FUNCTION";
12583 case 2: return "VARIABLE";
12584 default:
12585 break;
12586 }
12587
12588 static char buffer[30];
12589 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
12590 sprintf (buffer, "<unknown: %u>", sym_type);
12591 return buffer;
12592}
12593
12594/* Display an LTO format symbol table.
12595 FIXME: The format of LTO symbol tables is not formalized.
12596 So this code could need changing in the future. */
12597
015dc7e1 12598static bool
0f03783c
NC
12599display_lto_symtab (Filedata * filedata,
12600 Elf_Internal_Shdr * section)
12601{
12602 if (section->sh_size == 0)
12603 {
ca0e11aa
NC
12604 if (filedata->is_separate)
12605 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
12606 printable_section_name (filedata, section),
12607 filedata->file_name);
12608 else
12609 printf (_("\nLTO Symbol table '%s' is empty!\n"),
12610 printable_section_name (filedata, section));
047c3dbf 12611
015dc7e1 12612 return true;
0f03783c
NC
12613 }
12614
12615 if (section->sh_size > filedata->file_size)
12616 {
12617 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
12618 printable_section_name (filedata, section),
12619 (unsigned long) section->sh_size);
015dc7e1 12620 return false;
0f03783c
NC
12621 }
12622
12623 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
12624 section->sh_size, 1, _("LTO symbols"));
12625 if (alloced_data == NULL)
015dc7e1 12626 return false;
0f03783c
NC
12627
12628 /* Look for extended data for the symbol table. */
12629 Elf_Internal_Shdr * ext;
12630 void * ext_data_orig = NULL;
12631 char * ext_data = NULL;
12632 char * ext_data_end = NULL;
12633 char * ext_name = NULL;
12634
12635 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
b9e920ec 12636 SECTION_NAME (section) + sizeof (".gnu.lto_.symtab.") - 1) > 0
0f03783c
NC
12637 && ext_name != NULL /* Paranoia. */
12638 && (ext = find_section (filedata, ext_name)) != NULL)
12639 {
12640 if (ext->sh_size < 3)
12641 error (_("LTO Symbol extension table '%s' is empty!\n"),
12642 printable_section_name (filedata, ext));
12643 else
12644 {
12645 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
12646 ext->sh_size, 1,
12647 _("LTO ext symbol data"));
12648 if (ext_data != NULL)
12649 {
12650 ext_data_end = ext_data + ext->sh_size;
12651 if (* ext_data++ != 1)
12652 error (_("Unexpected version number in symbol extension table\n"));
12653 }
12654 }
12655 }
b9e920ec 12656
0f03783c
NC
12657 const unsigned char * data = (const unsigned char *) alloced_data;
12658 const unsigned char * end = data + section->sh_size;
12659
ca0e11aa
NC
12660 if (filedata->is_separate)
12661 printf (_("\nIn linked file '%s': "), filedata->file_name);
12662 else
12663 printf ("\n");
12664
0f03783c
NC
12665 if (ext_data_orig != NULL)
12666 {
12667 if (do_wide)
ca0e11aa 12668 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
12669 printable_section_name (filedata, section),
12670 printable_section_name (filedata, ext));
12671 else
12672 {
ca0e11aa 12673 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
12674 printable_section_name (filedata, section));
12675 printf (_(" and extension table '%s' contain:\n"),
12676 printable_section_name (filedata, ext));
12677 }
12678 }
12679 else
ca0e11aa 12680 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 12681 printable_section_name (filedata, section));
b9e920ec 12682
0f03783c 12683 /* FIXME: Add a wide version. */
b9e920ec 12684 if (ext_data_orig != NULL)
0f03783c
NC
12685 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
12686 else
12687 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
12688
12689 /* FIXME: We do not handle style prefixes. */
12690
12691 while (data < end)
12692 {
12693 const unsigned char * sym_name = data;
12694 data += strnlen ((const char *) sym_name, end - data) + 1;
12695 if (data >= end)
12696 goto fail;
12697
12698 const unsigned char * comdat_key = data;
12699 data += strnlen ((const char *) comdat_key, end - data) + 1;
12700 if (data >= end)
12701 goto fail;
12702
12703 if (data + 2 + 8 + 4 > end)
12704 goto fail;
12705
12706 unsigned int kind = *data++;
12707 unsigned int visibility = *data++;
12708
12709 elf_vma size = byte_get (data, 8);
12710 data += 8;
12711
12712 elf_vma slot = byte_get (data, 4);
12713 data += 4;
12714
12715 if (ext_data != NULL)
12716 {
12717 if (ext_data < (ext_data_end - 1))
12718 {
12719 unsigned int sym_type = * ext_data ++;
12720 unsigned int sec_kind = * ext_data ++;
12721
12722 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
12723 * comdat_key == 0 ? "-" : (char *) comdat_key,
12724 get_lto_kind (kind),
12725 get_lto_visibility (visibility),
12726 (long) size,
12727 (long) slot,
12728 get_lto_sym_type (sym_type),
12729 (long) sec_kind);
12730 print_symbol (6, (const char *) sym_name);
12731 }
12732 else
12733 {
12734 error (_("Ran out of LTO symbol extension data\n"));
12735 ext_data = NULL;
12736 /* FIXME: return FAIL result ? */
12737 }
12738 }
12739 else
12740 {
12741 printf (" %10s %10s %11s %08lx %08lx _",
12742 * comdat_key == 0 ? "-" : (char *) comdat_key,
12743 get_lto_kind (kind),
12744 get_lto_visibility (visibility),
12745 (long) size,
12746 (long) slot);
12747 print_symbol (21, (const char *) sym_name);
12748 }
12749 putchar ('\n');
12750 }
12751
12752 if (ext_data != NULL && ext_data < ext_data_end)
12753 {
12754 error (_("Data remains in the LTO symbol extension table\n"));
12755 goto fail;
12756 }
12757
12758 free (alloced_data);
12759 free (ext_data_orig);
12760 free (ext_name);
015dc7e1 12761 return true;
b9e920ec 12762
0f03783c
NC
12763 fail:
12764 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
12765 free (alloced_data);
12766 free (ext_data_orig);
12767 free (ext_name);
015dc7e1 12768 return false;
0f03783c
NC
12769}
12770
12771/* Display LTO symbol tables. */
12772
015dc7e1 12773static bool
0f03783c
NC
12774process_lto_symbol_tables (Filedata * filedata)
12775{
12776 Elf_Internal_Shdr * section;
12777 unsigned int i;
015dc7e1 12778 bool res = true;
0f03783c
NC
12779
12780 if (!do_lto_syms)
015dc7e1 12781 return true;
0f03783c
NC
12782
12783 if (filedata->section_headers == NULL)
015dc7e1 12784 return true;
0f03783c
NC
12785
12786 for (i = 0, section = filedata->section_headers;
12787 i < filedata->file_header.e_shnum;
12788 i++, section++)
b9e920ec 12789 if (SECTION_NAME_VALID (section)
08dedd66 12790 && startswith (SECTION_NAME (section), ".gnu.lto_.symtab."))
0f03783c
NC
12791 res &= display_lto_symtab (filedata, section);
12792
b9e920ec 12793 return res;
0f03783c
NC
12794}
12795
10ca4b04 12796/* Dump the symbol table. */
0f03783c 12797
015dc7e1 12798static bool
10ca4b04
L
12799process_symbol_table (Filedata * filedata)
12800{
12801 Elf_Internal_Shdr * section;
f16a9783 12802
10ca4b04 12803 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 12804 return true;
6bd1a22c 12805
978c4450 12806 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
12807 && do_syms
12808 && do_using_dynamic
978c4450
AM
12809 && filedata->dynamic_strings != NULL
12810 && filedata->dynamic_symbols != NULL)
6bd1a22c 12811 {
10ca4b04 12812 unsigned long si;
6bd1a22c 12813
ca0e11aa
NC
12814 if (filedata->is_separate)
12815 {
12816 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
12817 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
12818 filedata->num_dynamic_syms),
12819 filedata->file_name,
12820 filedata->num_dynamic_syms);
12821 }
12822 else
12823 {
12824 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12825 "\nSymbol table for image contains %lu entries:\n",
12826 filedata->num_dynamic_syms),
12827 filedata->num_dynamic_syms);
12828 }
10ca4b04
L
12829 if (is_32bit_elf)
12830 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12831 else
12832 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12833
978c4450
AM
12834 for (si = 0; si < filedata->num_dynamic_syms; si++)
12835 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
12836 filedata->dynamic_strings,
12837 filedata->dynamic_strings_length);
252b5132 12838 }
8b73c356 12839 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 12840 && filedata->section_headers != NULL)
252b5132 12841 {
b34976b6 12842 unsigned int i;
252b5132 12843
dda8d76d
NC
12844 for (i = 0, section = filedata->section_headers;
12845 i < filedata->file_header.e_shnum;
252b5132
RH
12846 i++, section++)
12847 {
2cf0635d 12848 char * strtab = NULL;
c256ffe7 12849 unsigned long int strtab_size = 0;
2cf0635d 12850 Elf_Internal_Sym * symtab;
ef3df110 12851 unsigned long si, num_syms;
252b5132 12852
2c610e4b
L
12853 if ((section->sh_type != SHT_SYMTAB
12854 && section->sh_type != SHT_DYNSYM)
12855 || (!do_syms
12856 && section->sh_type == SHT_SYMTAB))
252b5132
RH
12857 continue;
12858
dd24e3da
NC
12859 if (section->sh_entsize == 0)
12860 {
12861 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 12862 printable_section_name (filedata, section));
dd24e3da
NC
12863 continue;
12864 }
12865
d3a49aa8 12866 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
12867
12868 if (filedata->is_separate)
12869 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
12870 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
12871 num_syms),
12872 filedata->file_name,
12873 printable_section_name (filedata, section),
12874 num_syms);
12875 else
12876 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
12877 "\nSymbol table '%s' contains %lu entries:\n",
12878 num_syms),
12879 printable_section_name (filedata, section),
12880 num_syms);
dd24e3da 12881
f7a99963 12882 if (is_32bit_elf)
ca47b30c 12883 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 12884 else
ca47b30c 12885 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 12886
dda8d76d 12887 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
12888 if (symtab == NULL)
12889 continue;
12890
dda8d76d 12891 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 12892 {
dda8d76d
NC
12893 strtab = filedata->string_table;
12894 strtab_size = filedata->string_table_length;
c256ffe7 12895 }
dda8d76d 12896 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 12897 {
2cf0635d 12898 Elf_Internal_Shdr * string_sec;
252b5132 12899
dda8d76d 12900 string_sec = filedata->section_headers + section->sh_link;
252b5132 12901
dda8d76d 12902 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
12903 1, string_sec->sh_size,
12904 _("string table"));
c256ffe7 12905 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
12906 }
12907
10ca4b04
L
12908 for (si = 0; si < num_syms; si++)
12909 print_dynamic_symbol (filedata, si, symtab, section,
12910 strtab, strtab_size);
252b5132
RH
12911
12912 free (symtab);
dda8d76d 12913 if (strtab != filedata->string_table)
252b5132
RH
12914 free (strtab);
12915 }
12916 }
12917 else if (do_syms)
12918 printf
12919 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
12920
978c4450 12921 if (do_histogram && filedata->buckets != NULL)
252b5132 12922 {
2cf0635d
NC
12923 unsigned long * lengths;
12924 unsigned long * counts;
66543521
AM
12925 unsigned long hn;
12926 bfd_vma si;
12927 unsigned long maxlength = 0;
12928 unsigned long nzero_counts = 0;
12929 unsigned long nsyms = 0;
6bd6a03d 12930 char *visited;
252b5132 12931
d3a49aa8
AM
12932 printf (ngettext ("\nHistogram for bucket list length "
12933 "(total of %lu bucket):\n",
12934 "\nHistogram for bucket list length "
12935 "(total of %lu buckets):\n",
978c4450
AM
12936 (unsigned long) filedata->nbuckets),
12937 (unsigned long) filedata->nbuckets);
252b5132 12938
978c4450
AM
12939 lengths = (unsigned long *) calloc (filedata->nbuckets,
12940 sizeof (*lengths));
252b5132
RH
12941 if (lengths == NULL)
12942 {
8b73c356 12943 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 12944 goto err_out;
252b5132 12945 }
978c4450
AM
12946 visited = xcmalloc (filedata->nchains, 1);
12947 memset (visited, 0, filedata->nchains);
8b73c356
NC
12948
12949 printf (_(" Length Number %% of total Coverage\n"));
978c4450 12950 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 12951 {
978c4450 12952 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 12953 {
b34976b6 12954 ++nsyms;
252b5132 12955 if (maxlength < ++lengths[hn])
b34976b6 12956 ++maxlength;
978c4450 12957 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
12958 {
12959 error (_("histogram chain is corrupt\n"));
12960 break;
12961 }
12962 visited[si] = 1;
252b5132
RH
12963 }
12964 }
6bd6a03d 12965 free (visited);
252b5132 12966
3f5e193b 12967 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
12968 if (counts == NULL)
12969 {
b2e951ec 12970 free (lengths);
8b73c356 12971 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 12972 goto err_out;
252b5132
RH
12973 }
12974
978c4450 12975 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 12976 ++counts[lengths[hn]];
252b5132 12977
978c4450 12978 if (filedata->nbuckets > 0)
252b5132 12979 {
66543521
AM
12980 unsigned long i;
12981 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12982 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 12983 for (i = 1; i <= maxlength; ++i)
103f02d3 12984 {
66543521
AM
12985 nzero_counts += counts[i] * i;
12986 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12987 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
12988 (nzero_counts * 100.0) / nsyms);
12989 }
252b5132
RH
12990 }
12991
12992 free (counts);
12993 free (lengths);
12994 }
12995
978c4450
AM
12996 free (filedata->buckets);
12997 filedata->buckets = NULL;
12998 filedata->nbuckets = 0;
12999 free (filedata->chains);
13000 filedata->chains = NULL;
252b5132 13001
978c4450 13002 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13003 {
2cf0635d
NC
13004 unsigned long * lengths;
13005 unsigned long * counts;
fdc90cb4
JJ
13006 unsigned long hn;
13007 unsigned long maxlength = 0;
13008 unsigned long nzero_counts = 0;
13009 unsigned long nsyms = 0;
fdc90cb4 13010
f16a9783 13011 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13012 "(total of %lu bucket):\n",
f16a9783 13013 "\nHistogram for `%s' bucket list length "
d3a49aa8 13014 "(total of %lu buckets):\n",
978c4450
AM
13015 (unsigned long) filedata->ngnubuckets),
13016 GNU_HASH_SECTION_NAME (filedata),
13017 (unsigned long) filedata->ngnubuckets);
8b73c356 13018
978c4450
AM
13019 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13020 sizeof (*lengths));
fdc90cb4
JJ
13021 if (lengths == NULL)
13022 {
8b73c356 13023 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13024 goto err_out;
fdc90cb4
JJ
13025 }
13026
fdc90cb4
JJ
13027 printf (_(" Length Number %% of total Coverage\n"));
13028
978c4450
AM
13029 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13030 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
13031 {
13032 bfd_vma off, length = 1;
13033
978c4450 13034 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13035 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13036 off < filedata->ngnuchains
13037 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13038 ++off)
fdc90cb4
JJ
13039 ++length;
13040 lengths[hn] = length;
13041 if (length > maxlength)
13042 maxlength = length;
13043 nsyms += length;
13044 }
13045
3f5e193b 13046 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13047 if (counts == NULL)
13048 {
b2e951ec 13049 free (lengths);
8b73c356 13050 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13051 goto err_out;
fdc90cb4
JJ
13052 }
13053
978c4450 13054 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13055 ++counts[lengths[hn]];
13056
978c4450 13057 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13058 {
13059 unsigned long j;
13060 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13061 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13062 for (j = 1; j <= maxlength; ++j)
13063 {
13064 nzero_counts += counts[j] * j;
13065 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13066 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13067 (nzero_counts * 100.0) / nsyms);
13068 }
13069 }
13070
13071 free (counts);
13072 free (lengths);
fdc90cb4 13073 }
978c4450
AM
13074 free (filedata->gnubuckets);
13075 filedata->gnubuckets = NULL;
13076 filedata->ngnubuckets = 0;
13077 free (filedata->gnuchains);
13078 filedata->gnuchains = NULL;
13079 filedata->ngnuchains = 0;
13080 free (filedata->mipsxlat);
13081 filedata->mipsxlat = NULL;
015dc7e1 13082 return true;
fd486f32
AM
13083
13084 err_out:
978c4450
AM
13085 free (filedata->gnubuckets);
13086 filedata->gnubuckets = NULL;
13087 filedata->ngnubuckets = 0;
13088 free (filedata->gnuchains);
13089 filedata->gnuchains = NULL;
13090 filedata->ngnuchains = 0;
13091 free (filedata->mipsxlat);
13092 filedata->mipsxlat = NULL;
13093 free (filedata->buckets);
13094 filedata->buckets = NULL;
13095 filedata->nbuckets = 0;
13096 free (filedata->chains);
13097 filedata->chains = NULL;
015dc7e1 13098 return false;
252b5132
RH
13099}
13100
015dc7e1 13101static bool
ca0e11aa 13102process_syminfo (Filedata * filedata)
252b5132 13103{
b4c96d0d 13104 unsigned int i;
252b5132 13105
978c4450 13106 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13107 || !do_dynamic)
13108 /* No syminfo, this is ok. */
015dc7e1 13109 return true;
252b5132
RH
13110
13111 /* There better should be a dynamic symbol section. */
978c4450 13112 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13113 return false;
252b5132 13114
ca0e11aa
NC
13115 if (filedata->is_separate)
13116 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13117 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13118 filedata->dynamic_syminfo_nent),
13119 filedata->file_name,
13120 filedata->dynamic_syminfo_offset,
13121 filedata->dynamic_syminfo_nent);
13122 else
d3a49aa8
AM
13123 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13124 "contains %d entry:\n",
13125 "\nDynamic info segment at offset 0x%lx "
13126 "contains %d entries:\n",
978c4450 13127 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13128 filedata->dynamic_syminfo_offset,
13129 filedata->dynamic_syminfo_nent);
252b5132
RH
13130
13131 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13132 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13133 {
978c4450 13134 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13135
31104126 13136 printf ("%4d: ", i);
978c4450 13137 if (i >= filedata->num_dynamic_syms)
4082ef84 13138 printf (_("<corrupt index>"));
978c4450
AM
13139 else if (VALID_DYNAMIC_NAME (filedata, filedata->dynamic_symbols[i].st_name))
13140 print_symbol (30, GET_DYNAMIC_NAME (filedata,
13141 filedata->dynamic_symbols[i].st_name));
d79b3d50 13142 else
978c4450 13143 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13144 putchar (' ');
252b5132 13145
978c4450 13146 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13147 {
13148 case SYMINFO_BT_SELF:
13149 fputs ("SELF ", stdout);
13150 break;
13151 case SYMINFO_BT_PARENT:
13152 fputs ("PARENT ", stdout);
13153 break;
13154 default:
978c4450
AM
13155 if (filedata->dynamic_syminfo[i].si_boundto > 0
13156 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
13157 && VALID_DYNAMIC_NAME (filedata,
13158 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13159 {
978c4450
AM
13160 print_symbol (10, GET_DYNAMIC_NAME (filedata,
13161 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13162 putchar (' ' );
13163 }
252b5132 13164 else
978c4450 13165 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13166 break;
13167 }
13168
13169 if (flags & SYMINFO_FLG_DIRECT)
13170 printf (" DIRECT");
13171 if (flags & SYMINFO_FLG_PASSTHRU)
13172 printf (" PASSTHRU");
13173 if (flags & SYMINFO_FLG_COPY)
13174 printf (" COPY");
13175 if (flags & SYMINFO_FLG_LAZYLOAD)
13176 printf (" LAZYLOAD");
13177
13178 puts ("");
13179 }
13180
015dc7e1 13181 return true;
252b5132
RH
13182}
13183
75802ccb
CE
13184/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13185 is contained by the region START .. END. The types of ADDR, START
13186 and END should all be the same. Note both ADDR + NELEM and END
13187 point to just beyond the end of the regions that are being tested. */
13188#define IN_RANGE(START,END,ADDR,NELEM) \
13189 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13190
cf13d699
NC
13191/* Check to see if the given reloc needs to be handled in a target specific
13192 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13193 FALSE.
13194
13195 If called with reloc == NULL, then this is a signal that reloc processing
13196 for the current section has finished, and any saved state should be
13197 discarded. */
09c11c86 13198
015dc7e1 13199static bool
dda8d76d
NC
13200target_specific_reloc_handling (Filedata * filedata,
13201 Elf_Internal_Rela * reloc,
13202 unsigned char * start,
13203 unsigned char * end,
13204 Elf_Internal_Sym * symtab,
13205 unsigned long num_syms)
252b5132 13206{
f84ce13b
NC
13207 unsigned int reloc_type = 0;
13208 unsigned long sym_index = 0;
13209
13210 if (reloc)
13211 {
dda8d76d 13212 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13213 sym_index = get_reloc_symindex (reloc->r_info);
13214 }
252b5132 13215
dda8d76d 13216 switch (filedata->file_header.e_machine)
252b5132 13217 {
13761a11
NC
13218 case EM_MSP430:
13219 case EM_MSP430_OLD:
13220 {
13221 static Elf_Internal_Sym * saved_sym = NULL;
13222
f84ce13b
NC
13223 if (reloc == NULL)
13224 {
13225 saved_sym = NULL;
015dc7e1 13226 return true;
f84ce13b
NC
13227 }
13228
13761a11
NC
13229 switch (reloc_type)
13230 {
13231 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13232 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13233 if (uses_msp430x_relocs (filedata))
13761a11 13234 break;
1a0670f3 13235 /* Fall through. */
13761a11 13236 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13237 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13238 /* PR 21139. */
13239 if (sym_index >= num_syms)
13240 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13241 sym_index);
13242 else
13243 saved_sym = symtab + sym_index;
015dc7e1 13244 return true;
13761a11
NC
13245
13246 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13247 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13248 goto handle_sym_diff;
0b4362b0 13249
13761a11
NC
13250 case 5: /* R_MSP430_16_BYTE */
13251 case 9: /* R_MSP430_8 */
7d81bc93 13252 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13253 if (uses_msp430x_relocs (filedata))
13761a11
NC
13254 break;
13255 goto handle_sym_diff;
13256
13257 case 2: /* R_MSP430_ABS16 */
13258 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13259 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13260 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13261 break;
13262 goto handle_sym_diff;
0b4362b0 13263
13761a11
NC
13264 handle_sym_diff:
13265 if (saved_sym != NULL)
13266 {
13267 bfd_vma value;
5a805384 13268 unsigned int reloc_size = 0;
7d81bc93
JL
13269 int leb_ret = 0;
13270 switch (reloc_type)
13271 {
13272 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13273 reloc_size = 4;
13274 break;
13275 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13276 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13277 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13278 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13279 &reloc_size, &leb_ret);
7d81bc93
JL
13280 break;
13281 default:
13282 reloc_size = 2;
13283 break;
13284 }
13761a11 13285
5a805384 13286 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13287 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13288 "ULEB128 value\n"),
13289 (long) reloc->r_offset);
13290 else if (sym_index >= num_syms)
f84ce13b
NC
13291 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13292 sym_index);
03f7786e 13293 else
f84ce13b
NC
13294 {
13295 value = reloc->r_addend + (symtab[sym_index].st_value
13296 - saved_sym->st_value);
13297
b32e566b 13298 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13299 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13300 else
13301 /* PR 21137 */
13302 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13303 (long) reloc->r_offset);
f84ce13b 13304 }
13761a11
NC
13305
13306 saved_sym = NULL;
015dc7e1 13307 return true;
13761a11
NC
13308 }
13309 break;
13310
13311 default:
13312 if (saved_sym != NULL)
071436c6 13313 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
13314 break;
13315 }
13316 break;
13317 }
13318
cf13d699
NC
13319 case EM_MN10300:
13320 case EM_CYGNUS_MN10300:
13321 {
13322 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 13323
f84ce13b
NC
13324 if (reloc == NULL)
13325 {
13326 saved_sym = NULL;
015dc7e1 13327 return true;
f84ce13b
NC
13328 }
13329
cf13d699
NC
13330 switch (reloc_type)
13331 {
13332 case 34: /* R_MN10300_ALIGN */
015dc7e1 13333 return true;
cf13d699 13334 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
13335 if (sym_index >= num_syms)
13336 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
13337 sym_index);
13338 else
13339 saved_sym = symtab + sym_index;
015dc7e1 13340 return true;
f84ce13b 13341
cf13d699
NC
13342 case 1: /* R_MN10300_32 */
13343 case 2: /* R_MN10300_16 */
13344 if (saved_sym != NULL)
13345 {
03f7786e 13346 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 13347 bfd_vma value;
252b5132 13348
f84ce13b
NC
13349 if (sym_index >= num_syms)
13350 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
13351 sym_index);
03f7786e 13352 else
f84ce13b
NC
13353 {
13354 value = reloc->r_addend + (symtab[sym_index].st_value
13355 - saved_sym->st_value);
13356
b32e566b 13357 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13358 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13359 else
13360 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
13361 (long) reloc->r_offset);
f84ce13b 13362 }
252b5132 13363
cf13d699 13364 saved_sym = NULL;
015dc7e1 13365 return true;
cf13d699
NC
13366 }
13367 break;
13368 default:
13369 if (saved_sym != NULL)
071436c6 13370 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
13371 break;
13372 }
13373 break;
13374 }
6ff71e76
NC
13375
13376 case EM_RL78:
13377 {
13378 static bfd_vma saved_sym1 = 0;
13379 static bfd_vma saved_sym2 = 0;
13380 static bfd_vma value;
13381
f84ce13b
NC
13382 if (reloc == NULL)
13383 {
13384 saved_sym1 = saved_sym2 = 0;
015dc7e1 13385 return true;
f84ce13b
NC
13386 }
13387
6ff71e76
NC
13388 switch (reloc_type)
13389 {
13390 case 0x80: /* R_RL78_SYM. */
13391 saved_sym1 = saved_sym2;
f84ce13b
NC
13392 if (sym_index >= num_syms)
13393 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
13394 sym_index);
13395 else
13396 {
13397 saved_sym2 = symtab[sym_index].st_value;
13398 saved_sym2 += reloc->r_addend;
13399 }
015dc7e1 13400 return true;
6ff71e76
NC
13401
13402 case 0x83: /* R_RL78_OPsub. */
13403 value = saved_sym1 - saved_sym2;
13404 saved_sym2 = saved_sym1 = 0;
015dc7e1 13405 return true;
6ff71e76
NC
13406 break;
13407
13408 case 0x41: /* R_RL78_ABS32. */
b32e566b 13409 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 13410 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
13411 else
13412 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13413 (long) reloc->r_offset);
6ff71e76 13414 value = 0;
015dc7e1 13415 return true;
6ff71e76
NC
13416
13417 case 0x43: /* R_RL78_ABS16. */
b32e566b 13418 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 13419 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
13420 else
13421 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13422 (long) reloc->r_offset);
6ff71e76 13423 value = 0;
015dc7e1 13424 return true;
6ff71e76
NC
13425
13426 default:
13427 break;
13428 }
13429 break;
13430 }
252b5132
RH
13431 }
13432
015dc7e1 13433 return false;
252b5132
RH
13434}
13435
aca88567
NC
13436/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
13437 DWARF debug sections. This is a target specific test. Note - we do not
13438 go through the whole including-target-headers-multiple-times route, (as
13439 we have already done with <elf/h8.h>) because this would become very
13440 messy and even then this function would have to contain target specific
13441 information (the names of the relocs instead of their numeric values).
13442 FIXME: This is not the correct way to solve this problem. The proper way
13443 is to have target specific reloc sizing and typing functions created by
13444 the reloc-macros.h header, in the same way that it already creates the
13445 reloc naming functions. */
13446
015dc7e1 13447static bool
dda8d76d 13448is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13449{
d347c9df 13450 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13451 switch (filedata->file_header.e_machine)
aca88567 13452 {
41e92641 13453 case EM_386:
22abe556 13454 case EM_IAMCU:
41e92641 13455 return reloc_type == 1; /* R_386_32. */
aca88567
NC
13456 case EM_68K:
13457 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
13458 case EM_860:
13459 return reloc_type == 1; /* R_860_32. */
13460 case EM_960:
13461 return reloc_type == 2; /* R_960_32. */
a06ea964 13462 case EM_AARCH64:
9282b95a
JW
13463 return (reloc_type == 258
13464 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
13465 case EM_BPF:
13466 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
13467 case EM_ADAPTEVA_EPIPHANY:
13468 return reloc_type == 3;
aca88567 13469 case EM_ALPHA:
137b6b5f 13470 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
13471 case EM_ARC:
13472 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
13473 case EM_ARC_COMPACT:
13474 case EM_ARC_COMPACT2:
13475 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
13476 case EM_ARM:
13477 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 13478 case EM_AVR_OLD:
aca88567
NC
13479 case EM_AVR:
13480 return reloc_type == 1;
13481 case EM_BLACKFIN:
13482 return reloc_type == 0x12; /* R_byte4_data. */
13483 case EM_CRIS:
13484 return reloc_type == 3; /* R_CRIS_32. */
13485 case EM_CR16:
13486 return reloc_type == 3; /* R_CR16_NUM32. */
13487 case EM_CRX:
13488 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
13489 case EM_CSKY:
13490 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
13491 case EM_CYGNUS_FRV:
13492 return reloc_type == 1;
41e92641
NC
13493 case EM_CYGNUS_D10V:
13494 case EM_D10V:
13495 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
13496 case EM_CYGNUS_D30V:
13497 case EM_D30V:
13498 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
13499 case EM_DLX:
13500 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
13501 case EM_CYGNUS_FR30:
13502 case EM_FR30:
13503 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
13504 case EM_FT32:
13505 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
13506 case EM_H8S:
13507 case EM_H8_300:
13508 case EM_H8_300H:
13509 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 13510 case EM_IA_64:
262cdac7
AM
13511 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
13512 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
13513 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
13514 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
13515 case EM_IP2K_OLD:
13516 case EM_IP2K:
13517 return reloc_type == 2; /* R_IP2K_32. */
13518 case EM_IQ2000:
13519 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
13520 case EM_LATTICEMICO32:
13521 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 13522 case EM_M32C_OLD:
aca88567
NC
13523 case EM_M32C:
13524 return reloc_type == 3; /* R_M32C_32. */
13525 case EM_M32R:
13526 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
13527 case EM_68HC11:
13528 case EM_68HC12:
13529 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 13530 case EM_S12Z:
2849d19f
JD
13531 return reloc_type == 7 || /* R_S12Z_EXT32 */
13532 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
13533 case EM_MCORE:
13534 return reloc_type == 1; /* R_MCORE_ADDR32. */
13535 case EM_CYGNUS_MEP:
13536 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
13537 case EM_METAG:
13538 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
13539 case EM_MICROBLAZE:
13540 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
13541 case EM_MIPS:
13542 return reloc_type == 2; /* R_MIPS_32. */
13543 case EM_MMIX:
13544 return reloc_type == 4; /* R_MMIX_32. */
13545 case EM_CYGNUS_MN10200:
13546 case EM_MN10200:
13547 return reloc_type == 1; /* R_MN10200_32. */
13548 case EM_CYGNUS_MN10300:
13549 case EM_MN10300:
13550 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
13551 case EM_MOXIE:
13552 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
13553 case EM_MSP430_OLD:
13554 case EM_MSP430:
13761a11 13555 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
13556 case EM_MT:
13557 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
13558 case EM_NDS32:
13559 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 13560 case EM_ALTERA_NIOS2:
36591ba1 13561 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
13562 case EM_NIOS32:
13563 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
13564 case EM_OR1K:
13565 return reloc_type == 1; /* R_OR1K_32. */
aca88567 13566 case EM_PARISC:
9abca702 13567 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 13568 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 13569 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
13570 case EM_PJ:
13571 case EM_PJ_OLD:
13572 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
13573 case EM_PPC64:
13574 return reloc_type == 1; /* R_PPC64_ADDR32. */
13575 case EM_PPC:
13576 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
13577 case EM_TI_PRU:
13578 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
13579 case EM_RISCV:
13580 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
13581 case EM_RL78:
13582 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
13583 case EM_RX:
13584 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
13585 case EM_S370:
13586 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
13587 case EM_S390_OLD:
13588 case EM_S390:
13589 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
13590 case EM_SCORE:
13591 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
13592 case EM_SH:
13593 return reloc_type == 1; /* R_SH_DIR32. */
13594 case EM_SPARC32PLUS:
13595 case EM_SPARCV9:
13596 case EM_SPARC:
13597 return reloc_type == 3 /* R_SPARC_32. */
13598 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
13599 case EM_SPU:
13600 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
13601 case EM_TI_C6000:
13602 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
13603 case EM_TILEGX:
13604 return reloc_type == 2; /* R_TILEGX_32. */
13605 case EM_TILEPRO:
13606 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
13607 case EM_CYGNUS_V850:
13608 case EM_V850:
13609 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
13610 case EM_V800:
13611 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
13612 case EM_VAX:
13613 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
13614 case EM_VISIUM:
13615 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
13616 case EM_WEBASSEMBLY:
13617 return reloc_type == 1; /* R_WASM32_32. */
aca88567 13618 case EM_X86_64:
8a9036a4 13619 case EM_L1OM:
7a9068fe 13620 case EM_K1OM:
aca88567 13621 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
13622 case EM_XC16X:
13623 case EM_C166:
13624 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
13625 case EM_XGATE:
13626 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
13627 case EM_XSTORMY16:
13628 return reloc_type == 1; /* R_XSTROMY16_32. */
13629 case EM_XTENSA_OLD:
13630 case EM_XTENSA:
13631 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
13632 case EM_Z80:
13633 return reloc_type == 6; /* R_Z80_32. */
aca88567 13634 default:
bee0ee85
NC
13635 {
13636 static unsigned int prev_warn = 0;
13637
13638 /* Avoid repeating the same warning multiple times. */
dda8d76d 13639 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 13640 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
13641 filedata->file_header.e_machine);
13642 prev_warn = filedata->file_header.e_machine;
015dc7e1 13643 return false;
bee0ee85 13644 }
aca88567
NC
13645 }
13646}
13647
13648/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13649 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
13650
015dc7e1 13651static bool
dda8d76d 13652is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13653{
dda8d76d 13654 switch (filedata->file_header.e_machine)
d347c9df 13655 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 13656 {
41e92641 13657 case EM_386:
22abe556 13658 case EM_IAMCU:
3e0873ac 13659 return reloc_type == 2; /* R_386_PC32. */
aca88567 13660 case EM_68K:
3e0873ac 13661 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
13662 case EM_AARCH64:
13663 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
13664 case EM_ADAPTEVA_EPIPHANY:
13665 return reloc_type == 6;
aca88567
NC
13666 case EM_ALPHA:
13667 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
13668 case EM_ARC_COMPACT:
13669 case EM_ARC_COMPACT2:
13670 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 13671 case EM_ARM:
3e0873ac 13672 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
13673 case EM_AVR_OLD:
13674 case EM_AVR:
13675 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
13676 case EM_MICROBLAZE:
13677 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
13678 case EM_OR1K:
13679 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 13680 case EM_PARISC:
85acf597 13681 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
13682 case EM_PPC:
13683 return reloc_type == 26; /* R_PPC_REL32. */
13684 case EM_PPC64:
3e0873ac 13685 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
13686 case EM_RISCV:
13687 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
13688 case EM_S390_OLD:
13689 case EM_S390:
3e0873ac 13690 return reloc_type == 5; /* R_390_PC32. */
aca88567 13691 case EM_SH:
3e0873ac 13692 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
13693 case EM_SPARC32PLUS:
13694 case EM_SPARCV9:
13695 case EM_SPARC:
3e0873ac 13696 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
13697 case EM_SPU:
13698 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
13699 case EM_TILEGX:
13700 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
13701 case EM_TILEPRO:
13702 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
13703 case EM_VISIUM:
13704 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 13705 case EM_X86_64:
8a9036a4 13706 case EM_L1OM:
7a9068fe 13707 case EM_K1OM:
3e0873ac 13708 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
13709 case EM_VAX:
13710 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
13711 case EM_XTENSA_OLD:
13712 case EM_XTENSA:
13713 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
13714 default:
13715 /* Do not abort or issue an error message here. Not all targets use
13716 pc-relative 32-bit relocs in their DWARF debug information and we
13717 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
13718 more helpful warning message will be generated by apply_relocations
13719 anyway, so just return. */
015dc7e1 13720 return false;
aca88567
NC
13721 }
13722}
13723
13724/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13725 a 64-bit absolute RELA relocation used in DWARF debug sections. */
13726
015dc7e1 13727static bool
dda8d76d 13728is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13729{
dda8d76d 13730 switch (filedata->file_header.e_machine)
aca88567 13731 {
a06ea964
NC
13732 case EM_AARCH64:
13733 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
13734 case EM_ALPHA:
13735 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 13736 case EM_IA_64:
262cdac7
AM
13737 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
13738 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
13739 case EM_PARISC:
13740 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
13741 case EM_PPC64:
13742 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
13743 case EM_RISCV:
13744 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
13745 case EM_SPARC32PLUS:
13746 case EM_SPARCV9:
13747 case EM_SPARC:
714da62f
NC
13748 return reloc_type == 32 /* R_SPARC_64. */
13749 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 13750 case EM_X86_64:
8a9036a4 13751 case EM_L1OM:
7a9068fe 13752 case EM_K1OM:
aca88567 13753 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
13754 case EM_S390_OLD:
13755 case EM_S390:
aa137e4d
NC
13756 return reloc_type == 22; /* R_S390_64. */
13757 case EM_TILEGX:
13758 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 13759 case EM_MIPS:
aa137e4d 13760 return reloc_type == 18; /* R_MIPS_64. */
aca88567 13761 default:
015dc7e1 13762 return false;
aca88567
NC
13763 }
13764}
13765
85acf597
RH
13766/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
13767 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
13768
015dc7e1 13769static bool
dda8d76d 13770is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 13771{
dda8d76d 13772 switch (filedata->file_header.e_machine)
85acf597 13773 {
a06ea964
NC
13774 case EM_AARCH64:
13775 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 13776 case EM_ALPHA:
aa137e4d 13777 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 13778 case EM_IA_64:
262cdac7
AM
13779 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
13780 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 13781 case EM_PARISC:
aa137e4d 13782 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 13783 case EM_PPC64:
aa137e4d 13784 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
13785 case EM_SPARC32PLUS:
13786 case EM_SPARCV9:
13787 case EM_SPARC:
aa137e4d 13788 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 13789 case EM_X86_64:
8a9036a4 13790 case EM_L1OM:
7a9068fe 13791 case EM_K1OM:
aa137e4d 13792 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
13793 case EM_S390_OLD:
13794 case EM_S390:
aa137e4d
NC
13795 return reloc_type == 23; /* R_S390_PC64. */
13796 case EM_TILEGX:
13797 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 13798 default:
015dc7e1 13799 return false;
85acf597
RH
13800 }
13801}
13802
4dc3c23d
AM
13803/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13804 a 24-bit absolute RELA relocation used in DWARF debug sections. */
13805
015dc7e1 13806static bool
dda8d76d 13807is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 13808{
dda8d76d 13809 switch (filedata->file_header.e_machine)
4dc3c23d
AM
13810 {
13811 case EM_CYGNUS_MN10200:
13812 case EM_MN10200:
13813 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
13814 case EM_FT32:
13815 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
13816 case EM_Z80:
13817 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 13818 default:
015dc7e1 13819 return false;
4dc3c23d
AM
13820 }
13821}
13822
aca88567
NC
13823/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13824 a 16-bit absolute RELA relocation used in DWARF debug sections. */
13825
015dc7e1 13826static bool
dda8d76d 13827is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 13828{
d347c9df 13829 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13830 switch (filedata->file_header.e_machine)
4b78141a 13831 {
886a2506
NC
13832 case EM_ARC:
13833 case EM_ARC_COMPACT:
13834 case EM_ARC_COMPACT2:
13835 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
13836 case EM_ADAPTEVA_EPIPHANY:
13837 return reloc_type == 5;
aca88567
NC
13838 case EM_AVR_OLD:
13839 case EM_AVR:
13840 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
13841 case EM_CYGNUS_D10V:
13842 case EM_D10V:
13843 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
13844 case EM_FT32:
13845 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
13846 case EM_H8S:
13847 case EM_H8_300:
13848 case EM_H8_300H:
aca88567
NC
13849 return reloc_type == R_H8_DIR16;
13850 case EM_IP2K_OLD:
13851 case EM_IP2K:
13852 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 13853 case EM_M32C_OLD:
f4236fe4
DD
13854 case EM_M32C:
13855 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
13856 case EM_CYGNUS_MN10200:
13857 case EM_MN10200:
13858 return reloc_type == 2; /* R_MN10200_16. */
13859 case EM_CYGNUS_MN10300:
13860 case EM_MN10300:
13861 return reloc_type == 2; /* R_MN10300_16. */
aca88567 13862 case EM_MSP430:
dda8d76d 13863 if (uses_msp430x_relocs (filedata))
13761a11 13864 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 13865 /* Fall through. */
78c8d46c 13866 case EM_MSP430_OLD:
aca88567 13867 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
13868 case EM_NDS32:
13869 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 13870 case EM_ALTERA_NIOS2:
36591ba1 13871 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
13872 case EM_NIOS32:
13873 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
13874 case EM_OR1K:
13875 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
13876 case EM_RISCV:
13877 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
13878 case EM_TI_PRU:
13879 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
13880 case EM_TI_C6000:
13881 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
13882 case EM_VISIUM:
13883 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
13884 case EM_XC16X:
13885 case EM_C166:
13886 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
13887 case EM_XGATE:
13888 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
13889 case EM_Z80:
13890 return reloc_type == 4; /* R_Z80_16. */
4b78141a 13891 default:
015dc7e1 13892 return false;
4b78141a
NC
13893 }
13894}
13895
39e07931
AS
13896/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13897 a 8-bit absolute RELA relocation used in DWARF debug sections. */
13898
015dc7e1 13899static bool
39e07931
AS
13900is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13901{
13902 switch (filedata->file_header.e_machine)
13903 {
13904 case EM_RISCV:
13905 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
13906 case EM_Z80:
13907 return reloc_type == 1; /* R_Z80_8. */
39e07931 13908 default:
015dc7e1 13909 return false;
39e07931
AS
13910 }
13911}
13912
13913/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13914 a 6-bit absolute RELA relocation used in DWARF debug sections. */
13915
015dc7e1 13916static bool
39e07931
AS
13917is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13918{
13919 switch (filedata->file_header.e_machine)
13920 {
13921 case EM_RISCV:
13922 return reloc_type == 53; /* R_RISCV_SET6. */
13923 default:
015dc7e1 13924 return false;
39e07931
AS
13925 }
13926}
13927
03336641
JW
13928/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13929 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
13930
015dc7e1 13931static bool
03336641
JW
13932is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13933{
13934 /* Please keep this table alpha-sorted for ease of visual lookup. */
13935 switch (filedata->file_header.e_machine)
13936 {
13937 case EM_RISCV:
13938 return reloc_type == 35; /* R_RISCV_ADD32. */
13939 default:
015dc7e1 13940 return false;
03336641
JW
13941 }
13942}
13943
13944/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13945 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
13946
015dc7e1 13947static bool
03336641
JW
13948is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13949{
13950 /* Please keep this table alpha-sorted for ease of visual lookup. */
13951 switch (filedata->file_header.e_machine)
13952 {
13953 case EM_RISCV:
13954 return reloc_type == 39; /* R_RISCV_SUB32. */
13955 default:
015dc7e1 13956 return false;
03336641
JW
13957 }
13958}
13959
13960/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13961 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
13962
015dc7e1 13963static bool
03336641
JW
13964is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13965{
13966 /* Please keep this table alpha-sorted for ease of visual lookup. */
13967 switch (filedata->file_header.e_machine)
13968 {
13969 case EM_RISCV:
13970 return reloc_type == 36; /* R_RISCV_ADD64. */
13971 default:
015dc7e1 13972 return false;
03336641
JW
13973 }
13974}
13975
13976/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13977 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
13978
015dc7e1 13979static bool
03336641
JW
13980is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13981{
13982 /* Please keep this table alpha-sorted for ease of visual lookup. */
13983 switch (filedata->file_header.e_machine)
13984 {
13985 case EM_RISCV:
13986 return reloc_type == 40; /* R_RISCV_SUB64. */
13987 default:
015dc7e1 13988 return false;
03336641
JW
13989 }
13990}
13991
13992/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13993 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
13994
015dc7e1 13995static bool
03336641
JW
13996is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13997{
13998 /* Please keep this table alpha-sorted for ease of visual lookup. */
13999 switch (filedata->file_header.e_machine)
14000 {
14001 case EM_RISCV:
14002 return reloc_type == 34; /* R_RISCV_ADD16. */
14003 default:
015dc7e1 14004 return false;
03336641
JW
14005 }
14006}
14007
14008/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14009 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14010
015dc7e1 14011static bool
03336641
JW
14012is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14013{
14014 /* Please keep this table alpha-sorted for ease of visual lookup. */
14015 switch (filedata->file_header.e_machine)
14016 {
14017 case EM_RISCV:
14018 return reloc_type == 38; /* R_RISCV_SUB16. */
14019 default:
015dc7e1 14020 return false;
03336641
JW
14021 }
14022}
14023
14024/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14025 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14026
015dc7e1 14027static bool
03336641
JW
14028is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14029{
14030 /* Please keep this table alpha-sorted for ease of visual lookup. */
14031 switch (filedata->file_header.e_machine)
14032 {
14033 case EM_RISCV:
14034 return reloc_type == 33; /* R_RISCV_ADD8. */
14035 default:
015dc7e1 14036 return false;
03336641
JW
14037 }
14038}
14039
14040/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14041 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14042
015dc7e1 14043static bool
03336641
JW
14044is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14045{
14046 /* Please keep this table alpha-sorted for ease of visual lookup. */
14047 switch (filedata->file_header.e_machine)
14048 {
14049 case EM_RISCV:
14050 return reloc_type == 37; /* R_RISCV_SUB8. */
14051 default:
015dc7e1 14052 return false;
03336641
JW
14053 }
14054}
14055
39e07931
AS
14056/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14057 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14058
015dc7e1 14059static bool
39e07931
AS
14060is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14061{
14062 switch (filedata->file_header.e_machine)
14063 {
14064 case EM_RISCV:
14065 return reloc_type == 52; /* R_RISCV_SUB6. */
14066 default:
015dc7e1 14067 return false;
39e07931
AS
14068 }
14069}
14070
2a7b2e88
JK
14071/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14072 relocation entries (possibly formerly used for SHT_GROUP sections). */
14073
015dc7e1 14074static bool
dda8d76d 14075is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14076{
dda8d76d 14077 switch (filedata->file_header.e_machine)
2a7b2e88 14078 {
cb8f3167 14079 case EM_386: /* R_386_NONE. */
d347c9df 14080 case EM_68K: /* R_68K_NONE. */
cfb8c092 14081 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14082 case EM_ALPHA: /* R_ALPHA_NONE. */
14083 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14084 case EM_ARC: /* R_ARC_NONE. */
886a2506 14085 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14086 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14087 case EM_ARM: /* R_ARM_NONE. */
d347c9df 14088 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 14089 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14090 case EM_FT32: /* R_FT32_NONE. */
14091 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14092 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14093 case EM_L1OM: /* R_X86_64_NONE. */
14094 case EM_M32R: /* R_M32R_NONE. */
14095 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14096 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14097 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14098 case EM_NIOS32: /* R_NIOS_NONE. */
14099 case EM_OR1K: /* R_OR1K_NONE. */
14100 case EM_PARISC: /* R_PARISC_NONE. */
14101 case EM_PPC64: /* R_PPC64_NONE. */
14102 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14103 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14104 case EM_S390: /* R_390_NONE. */
14105 case EM_S390_OLD:
14106 case EM_SH: /* R_SH_NONE. */
14107 case EM_SPARC32PLUS:
14108 case EM_SPARC: /* R_SPARC_NONE. */
14109 case EM_SPARCV9:
aa137e4d
NC
14110 case EM_TILEGX: /* R_TILEGX_NONE. */
14111 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14112 case EM_TI_C6000:/* R_C6000_NONE. */
14113 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 14114 case EM_XC16X:
6655dba2 14115 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14116 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14117 return reloc_type == 0;
d347c9df 14118
a06ea964
NC
14119 case EM_AARCH64:
14120 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14121 case EM_AVR_OLD:
14122 case EM_AVR:
14123 return (reloc_type == 0 /* R_AVR_NONE. */
14124 || reloc_type == 30 /* R_AVR_DIFF8. */
14125 || reloc_type == 31 /* R_AVR_DIFF16. */
14126 || reloc_type == 32 /* R_AVR_DIFF32. */);
14127 case EM_METAG:
14128 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
14129 case EM_NDS32:
14130 return (reloc_type == 0 /* R_XTENSA_NONE. */
14131 || reloc_type == 204 /* R_NDS32_DIFF8. */
14132 || reloc_type == 205 /* R_NDS32_DIFF16. */
14133 || reloc_type == 206 /* R_NDS32_DIFF32. */
14134 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
14135 case EM_TI_PRU:
14136 return (reloc_type == 0 /* R_PRU_NONE. */
14137 || reloc_type == 65 /* R_PRU_DIFF8. */
14138 || reloc_type == 66 /* R_PRU_DIFF16. */
14139 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14140 case EM_XTENSA_OLD:
14141 case EM_XTENSA:
4dc3c23d
AM
14142 return (reloc_type == 0 /* R_XTENSA_NONE. */
14143 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14144 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14145 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14146 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14147 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14148 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14149 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14150 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14151 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14152 }
015dc7e1 14153 return false;
2a7b2e88
JK
14154}
14155
d1c4b12b
NC
14156/* Returns TRUE if there is a relocation against
14157 section NAME at OFFSET bytes. */
14158
015dc7e1 14159bool
d1c4b12b
NC
14160reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14161{
14162 Elf_Internal_Rela * relocs;
14163 Elf_Internal_Rela * rp;
14164
14165 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14166 return false;
d1c4b12b
NC
14167
14168 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14169
14170 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14171 if (rp->r_offset == offset)
015dc7e1 14172 return true;
d1c4b12b 14173
015dc7e1 14174 return false;
d1c4b12b
NC
14175}
14176
cf13d699 14177/* Apply relocations to a section.
32ec8896
NC
14178 Returns TRUE upon success, FALSE otherwise.
14179 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14180 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14181 will be set to the number of relocs loaded.
14182
cf13d699 14183 Note: So far support has been added only for those relocations
32ec8896
NC
14184 which can be found in debug sections. FIXME: Add support for
14185 more relocations ? */
1b315056 14186
015dc7e1 14187static bool
dda8d76d 14188apply_relocations (Filedata * filedata,
d1c4b12b
NC
14189 const Elf_Internal_Shdr * section,
14190 unsigned char * start,
14191 bfd_size_type size,
1449284b 14192 void ** relocs_return,
d1c4b12b 14193 unsigned long * num_relocs_return)
1b315056 14194{
cf13d699 14195 Elf_Internal_Shdr * relsec;
0d2a7a93 14196 unsigned char * end = start + size;
cb8f3167 14197
d1c4b12b
NC
14198 if (relocs_return != NULL)
14199 {
14200 * (Elf_Internal_Rela **) relocs_return = NULL;
14201 * num_relocs_return = 0;
14202 }
14203
dda8d76d 14204 if (filedata->file_header.e_type != ET_REL)
32ec8896 14205 /* No relocs to apply. */
015dc7e1 14206 return true;
1b315056 14207
cf13d699 14208 /* Find the reloc section associated with the section. */
dda8d76d
NC
14209 for (relsec = filedata->section_headers;
14210 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14211 ++relsec)
252b5132 14212 {
015dc7e1 14213 bool is_rela;
41e92641 14214 unsigned long num_relocs;
2cf0635d
NC
14215 Elf_Internal_Rela * relocs;
14216 Elf_Internal_Rela * rp;
14217 Elf_Internal_Shdr * symsec;
14218 Elf_Internal_Sym * symtab;
ba5cdace 14219 unsigned long num_syms;
2cf0635d 14220 Elf_Internal_Sym * sym;
252b5132 14221
41e92641 14222 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14223 || relsec->sh_info >= filedata->file_header.e_shnum
14224 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14225 || relsec->sh_size == 0
dda8d76d 14226 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14227 continue;
428409d5 14228
a788aedd
AM
14229 symsec = filedata->section_headers + relsec->sh_link;
14230 if (symsec->sh_type != SHT_SYMTAB
14231 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14232 return false;
a788aedd 14233
41e92641
NC
14234 is_rela = relsec->sh_type == SHT_RELA;
14235
14236 if (is_rela)
14237 {
dda8d76d 14238 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14239 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14240 return false;
41e92641
NC
14241 }
14242 else
14243 {
dda8d76d 14244 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14245 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14246 return false;
41e92641
NC
14247 }
14248
14249 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14250 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14251 is_rela = false;
428409d5 14252
dda8d76d 14253 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 14254
41e92641 14255 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14256 {
015dc7e1
AM
14257 bfd_vma addend;
14258 unsigned int reloc_type;
14259 unsigned int reloc_size;
14260 bool reloc_inplace = false;
14261 bool reloc_subtract = false;
14262 unsigned char *rloc;
14263 unsigned long sym_index;
4b78141a 14264
dda8d76d 14265 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14266
dda8d76d 14267 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14268 continue;
dda8d76d 14269 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14270 continue;
dda8d76d
NC
14271 else if (is_32bit_abs_reloc (filedata, reloc_type)
14272 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14273 reloc_size = 4;
dda8d76d
NC
14274 else if (is_64bit_abs_reloc (filedata, reloc_type)
14275 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14276 reloc_size = 8;
dda8d76d 14277 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14278 reloc_size = 3;
dda8d76d 14279 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14280 reloc_size = 2;
39e07931
AS
14281 else if (is_8bit_abs_reloc (filedata, reloc_type)
14282 || is_6bit_abs_reloc (filedata, reloc_type))
14283 reloc_size = 1;
03336641
JW
14284 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14285 reloc_type))
14286 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14287 {
14288 reloc_size = 4;
015dc7e1 14289 reloc_inplace = true;
03336641
JW
14290 }
14291 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14292 reloc_type))
14293 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14294 {
14295 reloc_size = 8;
015dc7e1 14296 reloc_inplace = true;
03336641
JW
14297 }
14298 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14299 reloc_type))
14300 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14301 {
14302 reloc_size = 2;
015dc7e1 14303 reloc_inplace = true;
03336641
JW
14304 }
14305 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14306 reloc_type))
14307 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14308 {
14309 reloc_size = 1;
015dc7e1 14310 reloc_inplace = true;
03336641 14311 }
39e07931
AS
14312 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
14313 reloc_type)))
14314 {
14315 reloc_size = 1;
015dc7e1 14316 reloc_inplace = true;
39e07931 14317 }
aca88567 14318 else
4b78141a 14319 {
bee0ee85 14320 static unsigned int prev_reloc = 0;
dda8d76d 14321
bee0ee85
NC
14322 if (reloc_type != prev_reloc)
14323 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 14324 reloc_type, printable_section_name (filedata, section));
bee0ee85 14325 prev_reloc = reloc_type;
4b78141a
NC
14326 continue;
14327 }
103f02d3 14328
91d6fa6a 14329 rloc = start + rp->r_offset;
75802ccb 14330 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
14331 {
14332 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
14333 (unsigned long) rp->r_offset,
dda8d76d 14334 printable_section_name (filedata, section));
700dd8b7
L
14335 continue;
14336 }
103f02d3 14337
ba5cdace
NC
14338 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
14339 if (sym_index >= num_syms)
14340 {
14341 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 14342 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
14343 continue;
14344 }
14345 sym = symtab + sym_index;
41e92641
NC
14346
14347 /* If the reloc has a symbol associated with it,
55f25fc3
L
14348 make sure that it is of an appropriate type.
14349
14350 Relocations against symbols without type can happen.
14351 Gcc -feliminate-dwarf2-dups may generate symbols
14352 without type for debug info.
14353
14354 Icc generates relocations against function symbols
14355 instead of local labels.
14356
14357 Relocations against object symbols can happen, eg when
14358 referencing a global array. For an example of this see
14359 the _clz.o binary in libgcc.a. */
aca88567 14360 if (sym != symtab
b8871f35 14361 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 14362 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 14363 {
d3a49aa8 14364 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
14365 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
14366 printable_section_name (filedata, relsec),
d3a49aa8 14367 (long int)(rp - relocs));
aca88567 14368 continue;
5b18a4bc 14369 }
252b5132 14370
4dc3c23d
AM
14371 addend = 0;
14372 if (is_rela)
14373 addend += rp->r_addend;
c47320c3
AM
14374 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
14375 partial_inplace. */
4dc3c23d 14376 if (!is_rela
dda8d76d 14377 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 14378 && reloc_type == 1)
dda8d76d
NC
14379 || ((filedata->file_header.e_machine == EM_PJ
14380 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 14381 && reloc_type == 1)
dda8d76d
NC
14382 || ((filedata->file_header.e_machine == EM_D30V
14383 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
14384 && reloc_type == 12)
14385 || reloc_inplace)
39e07931
AS
14386 {
14387 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
14388 addend += byte_get (rloc, reloc_size) & 0x3f;
14389 else
14390 addend += byte_get (rloc, reloc_size);
14391 }
cb8f3167 14392
dda8d76d
NC
14393 if (is_32bit_pcrel_reloc (filedata, reloc_type)
14394 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
14395 {
14396 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 14397 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 14398 addend -= 8;
91d6fa6a 14399 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
14400 reloc_size);
14401 }
39e07931
AS
14402 else if (is_6bit_abs_reloc (filedata, reloc_type)
14403 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
14404 {
14405 if (reloc_subtract)
14406 addend -= sym->st_value;
14407 else
14408 addend += sym->st_value;
14409 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
14410 byte_put (rloc, addend, reloc_size);
14411 }
03336641
JW
14412 else if (reloc_subtract)
14413 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 14414 else
91d6fa6a 14415 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 14416 }
252b5132 14417
5b18a4bc 14418 free (symtab);
f84ce13b
NC
14419 /* Let the target specific reloc processing code know that
14420 we have finished with these relocs. */
dda8d76d 14421 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
14422
14423 if (relocs_return)
14424 {
14425 * (Elf_Internal_Rela **) relocs_return = relocs;
14426 * num_relocs_return = num_relocs;
14427 }
14428 else
14429 free (relocs);
14430
5b18a4bc
NC
14431 break;
14432 }
32ec8896 14433
015dc7e1 14434 return true;
5b18a4bc 14435}
103f02d3 14436
cf13d699 14437#ifdef SUPPORT_DISASSEMBLY
015dc7e1 14438static bool
dda8d76d 14439disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14440{
dda8d76d 14441 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 14442
74e1a04b 14443 /* FIXME: XXX -- to be done --- XXX */
cf13d699 14444
015dc7e1 14445 return true;
cf13d699
NC
14446}
14447#endif
14448
14449/* Reads in the contents of SECTION from FILE, returning a pointer
14450 to a malloc'ed buffer or NULL if something went wrong. */
14451
14452static char *
dda8d76d 14453get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14454{
dda8d76d 14455 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
14456
14457 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
14458 {
c6b78c96 14459 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 14460 printable_section_name (filedata, section));
cf13d699
NC
14461 return NULL;
14462 }
14463
dda8d76d 14464 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 14465 _("section contents"));
cf13d699
NC
14466}
14467
0e602686
NC
14468/* Uncompresses a section that was compressed using zlib, in place. */
14469
015dc7e1 14470static bool
dda8d76d
NC
14471uncompress_section_contents (unsigned char ** buffer,
14472 dwarf_size_type uncompressed_size,
14473 dwarf_size_type * size)
0e602686
NC
14474{
14475 dwarf_size_type compressed_size = *size;
14476 unsigned char * compressed_buffer = *buffer;
14477 unsigned char * uncompressed_buffer;
14478 z_stream strm;
14479 int rc;
14480
14481 /* It is possible the section consists of several compressed
14482 buffers concatenated together, so we uncompress in a loop. */
14483 /* PR 18313: The state field in the z_stream structure is supposed
14484 to be invisible to the user (ie us), but some compilers will
14485 still complain about it being used without initialisation. So
14486 we first zero the entire z_stream structure and then set the fields
14487 that we need. */
14488 memset (& strm, 0, sizeof strm);
14489 strm.avail_in = compressed_size;
14490 strm.next_in = (Bytef *) compressed_buffer;
14491 strm.avail_out = uncompressed_size;
14492 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
14493
14494 rc = inflateInit (& strm);
14495 while (strm.avail_in > 0)
14496 {
14497 if (rc != Z_OK)
3624a6c1 14498 break;
0e602686
NC
14499 strm.next_out = ((Bytef *) uncompressed_buffer
14500 + (uncompressed_size - strm.avail_out));
14501 rc = inflate (&strm, Z_FINISH);
14502 if (rc != Z_STREAM_END)
3624a6c1 14503 break;
0e602686
NC
14504 rc = inflateReset (& strm);
14505 }
ad92f33d
AM
14506 if (inflateEnd (& strm) != Z_OK
14507 || rc != Z_OK
0e602686
NC
14508 || strm.avail_out != 0)
14509 goto fail;
14510
14511 *buffer = uncompressed_buffer;
14512 *size = uncompressed_size;
015dc7e1 14513 return true;
0e602686
NC
14514
14515 fail:
14516 free (uncompressed_buffer);
14517 /* Indicate decompression failure. */
14518 *buffer = NULL;
015dc7e1 14519 return false;
0e602686 14520}
dd24e3da 14521
015dc7e1 14522static bool
dda8d76d 14523dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14524{
015dc7e1
AM
14525 Elf_Internal_Shdr *relsec;
14526 bfd_size_type num_bytes;
14527 unsigned char *data;
14528 unsigned char *end;
14529 unsigned char *real_start;
14530 unsigned char *start;
14531 bool some_strings_shown;
cf13d699 14532
dda8d76d 14533 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14534 if (start == NULL)
c6b78c96 14535 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 14536 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 14537
0e602686 14538 num_bytes = section->sh_size;
cf13d699 14539
835f2fae
NC
14540 if (filedata->is_separate)
14541 printf (_("\nString dump of section '%s' in linked file %s:\n"),
14542 printable_section_name (filedata, section),
14543 filedata->file_name);
14544 else
14545 printf (_("\nString dump of section '%s':\n"),
14546 printable_section_name (filedata, section));
cf13d699 14547
0e602686
NC
14548 if (decompress_dumps)
14549 {
14550 dwarf_size_type new_size = num_bytes;
14551 dwarf_size_type uncompressed_size = 0;
14552
14553 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14554 {
14555 Elf_Internal_Chdr chdr;
14556 unsigned int compression_header_size
ebdf1ebf
NC
14557 = get_compression_header (& chdr, (unsigned char *) start,
14558 num_bytes);
5844b465
NC
14559 if (compression_header_size == 0)
14560 /* An error message will have already been generated
14561 by get_compression_header. */
14562 goto error_out;
0e602686 14563
813dabb9 14564 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14565 {
813dabb9 14566 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14567 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14568 goto error_out;
813dabb9 14569 }
813dabb9
L
14570 uncompressed_size = chdr.ch_size;
14571 start += compression_header_size;
14572 new_size -= compression_header_size;
0e602686
NC
14573 }
14574 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14575 {
14576 /* Read the zlib header. In this case, it should be "ZLIB"
14577 followed by the uncompressed section size, 8 bytes in
14578 big-endian order. */
14579 uncompressed_size = start[4]; uncompressed_size <<= 8;
14580 uncompressed_size += start[5]; uncompressed_size <<= 8;
14581 uncompressed_size += start[6]; uncompressed_size <<= 8;
14582 uncompressed_size += start[7]; uncompressed_size <<= 8;
14583 uncompressed_size += start[8]; uncompressed_size <<= 8;
14584 uncompressed_size += start[9]; uncompressed_size <<= 8;
14585 uncompressed_size += start[10]; uncompressed_size <<= 8;
14586 uncompressed_size += start[11];
14587 start += 12;
14588 new_size -= 12;
14589 }
14590
1835f746
NC
14591 if (uncompressed_size)
14592 {
14593 if (uncompress_section_contents (& start,
14594 uncompressed_size, & new_size))
14595 num_bytes = new_size;
14596 else
14597 {
14598 error (_("Unable to decompress section %s\n"),
dda8d76d 14599 printable_section_name (filedata, section));
f761cb13 14600 goto error_out;
1835f746
NC
14601 }
14602 }
bc303e5d
NC
14603 else
14604 start = real_start;
0e602686 14605 }
fd8008d8 14606
cf13d699
NC
14607 /* If the section being dumped has relocations against it the user might
14608 be expecting these relocations to have been applied. Check for this
14609 case and issue a warning message in order to avoid confusion.
14610 FIXME: Maybe we ought to have an option that dumps a section with
14611 relocs applied ? */
dda8d76d
NC
14612 for (relsec = filedata->section_headers;
14613 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14614 ++relsec)
14615 {
14616 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14617 || relsec->sh_info >= filedata->file_header.e_shnum
14618 || filedata->section_headers + relsec->sh_info != section
cf13d699 14619 || relsec->sh_size == 0
dda8d76d 14620 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14621 continue;
14622
14623 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14624 break;
14625 }
14626
cf13d699
NC
14627 data = start;
14628 end = start + num_bytes;
015dc7e1 14629 some_strings_shown = false;
cf13d699 14630
ba3265d0
NC
14631#ifdef HAVE_MBSTATE_T
14632 mbstate_t state;
14633 /* Initialise the multibyte conversion state. */
14634 memset (& state, 0, sizeof (state));
14635#endif
14636
015dc7e1 14637 bool continuing = false;
ba3265d0 14638
cf13d699
NC
14639 while (data < end)
14640 {
14641 while (!ISPRINT (* data))
14642 if (++ data >= end)
14643 break;
14644
14645 if (data < end)
14646 {
071436c6
NC
14647 size_t maxlen = end - data;
14648
ba3265d0
NC
14649 if (continuing)
14650 {
14651 printf (" ");
015dc7e1 14652 continuing = false;
ba3265d0
NC
14653 }
14654 else
14655 {
d1ce973e 14656 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
14657 }
14658
4082ef84
NC
14659 if (maxlen > 0)
14660 {
f3da8a96 14661 char c = 0;
ba3265d0
NC
14662
14663 while (maxlen)
14664 {
14665 c = *data++;
14666
14667 if (c == 0)
14668 break;
14669
14670 /* PR 25543: Treat new-lines as string-ending characters. */
14671 if (c == '\n')
14672 {
14673 printf ("\\n\n");
14674 if (*data != 0)
015dc7e1 14675 continuing = true;
ba3265d0
NC
14676 break;
14677 }
14678
14679 /* Do not print control characters directly as they can affect terminal
14680 settings. Such characters usually appear in the names generated
14681 by the assembler for local labels. */
14682 if (ISCNTRL (c))
14683 {
14684 printf ("^%c", c + 0x40);
14685 }
14686 else if (ISPRINT (c))
14687 {
14688 putchar (c);
14689 }
14690 else
14691 {
14692 size_t n;
14693#ifdef HAVE_MBSTATE_T
14694 wchar_t w;
14695#endif
14696 /* Let printf do the hard work of displaying multibyte characters. */
14697 printf ("%.1s", data - 1);
14698#ifdef HAVE_MBSTATE_T
14699 /* Try to find out how many bytes made up the character that was
14700 just printed. Advance the symbol pointer past the bytes that
14701 were displayed. */
14702 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
14703#else
14704 n = 1;
14705#endif
14706 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
14707 data += (n - 1);
14708 }
14709 }
14710
14711 if (c != '\n')
14712 putchar ('\n');
4082ef84
NC
14713 }
14714 else
14715 {
14716 printf (_("<corrupt>\n"));
14717 data = end;
14718 }
015dc7e1 14719 some_strings_shown = true;
cf13d699
NC
14720 }
14721 }
14722
14723 if (! some_strings_shown)
14724 printf (_(" No strings found in this section."));
14725
0e602686 14726 free (real_start);
cf13d699
NC
14727
14728 putchar ('\n');
015dc7e1 14729 return true;
f761cb13
AM
14730
14731error_out:
14732 free (real_start);
015dc7e1 14733 return false;
cf13d699
NC
14734}
14735
015dc7e1
AM
14736static bool
14737dump_section_as_bytes (Elf_Internal_Shdr *section,
14738 Filedata *filedata,
14739 bool relocate)
cf13d699
NC
14740{
14741 Elf_Internal_Shdr * relsec;
0e602686
NC
14742 bfd_size_type bytes;
14743 bfd_size_type section_size;
14744 bfd_vma addr;
14745 unsigned char * data;
14746 unsigned char * real_start;
14747 unsigned char * start;
14748
dda8d76d 14749 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14750 if (start == NULL)
c6b78c96 14751 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 14752 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 14753
0e602686 14754 section_size = section->sh_size;
cf13d699 14755
835f2fae
NC
14756 if (filedata->is_separate)
14757 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
14758 printable_section_name (filedata, section),
14759 filedata->file_name);
14760 else
14761 printf (_("\nHex dump of section '%s':\n"),
14762 printable_section_name (filedata, section));
cf13d699 14763
0e602686
NC
14764 if (decompress_dumps)
14765 {
14766 dwarf_size_type new_size = section_size;
14767 dwarf_size_type uncompressed_size = 0;
14768
14769 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14770 {
14771 Elf_Internal_Chdr chdr;
14772 unsigned int compression_header_size
ebdf1ebf 14773 = get_compression_header (& chdr, start, section_size);
0e602686 14774
5844b465
NC
14775 if (compression_header_size == 0)
14776 /* An error message will have already been generated
14777 by get_compression_header. */
14778 goto error_out;
14779
813dabb9 14780 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14781 {
813dabb9 14782 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14783 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14784 goto error_out;
0e602686 14785 }
813dabb9
L
14786 uncompressed_size = chdr.ch_size;
14787 start += compression_header_size;
14788 new_size -= compression_header_size;
0e602686
NC
14789 }
14790 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14791 {
14792 /* Read the zlib header. In this case, it should be "ZLIB"
14793 followed by the uncompressed section size, 8 bytes in
14794 big-endian order. */
14795 uncompressed_size = start[4]; uncompressed_size <<= 8;
14796 uncompressed_size += start[5]; uncompressed_size <<= 8;
14797 uncompressed_size += start[6]; uncompressed_size <<= 8;
14798 uncompressed_size += start[7]; uncompressed_size <<= 8;
14799 uncompressed_size += start[8]; uncompressed_size <<= 8;
14800 uncompressed_size += start[9]; uncompressed_size <<= 8;
14801 uncompressed_size += start[10]; uncompressed_size <<= 8;
14802 uncompressed_size += start[11];
14803 start += 12;
14804 new_size -= 12;
14805 }
14806
f055032e
NC
14807 if (uncompressed_size)
14808 {
14809 if (uncompress_section_contents (& start, uncompressed_size,
14810 & new_size))
bc303e5d
NC
14811 {
14812 section_size = new_size;
14813 }
f055032e
NC
14814 else
14815 {
14816 error (_("Unable to decompress section %s\n"),
dda8d76d 14817 printable_section_name (filedata, section));
bc303e5d 14818 /* FIXME: Print the section anyway ? */
f761cb13 14819 goto error_out;
f055032e
NC
14820 }
14821 }
bc303e5d
NC
14822 else
14823 start = real_start;
0e602686 14824 }
14ae95f2 14825
cf13d699
NC
14826 if (relocate)
14827 {
dda8d76d 14828 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 14829 goto error_out;
cf13d699
NC
14830 }
14831 else
14832 {
14833 /* If the section being dumped has relocations against it the user might
14834 be expecting these relocations to have been applied. Check for this
14835 case and issue a warning message in order to avoid confusion.
14836 FIXME: Maybe we ought to have an option that dumps a section with
14837 relocs applied ? */
dda8d76d
NC
14838 for (relsec = filedata->section_headers;
14839 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14840 ++relsec)
14841 {
14842 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14843 || relsec->sh_info >= filedata->file_header.e_shnum
14844 || filedata->section_headers + relsec->sh_info != section
cf13d699 14845 || relsec->sh_size == 0
dda8d76d 14846 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14847 continue;
14848
14849 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14850 break;
14851 }
14852 }
14853
14854 addr = section->sh_addr;
0e602686 14855 bytes = section_size;
cf13d699
NC
14856 data = start;
14857
14858 while (bytes)
14859 {
14860 int j;
14861 int k;
14862 int lbytes;
14863
14864 lbytes = (bytes > 16 ? 16 : bytes);
14865
14866 printf (" 0x%8.8lx ", (unsigned long) addr);
14867
14868 for (j = 0; j < 16; j++)
14869 {
14870 if (j < lbytes)
14871 printf ("%2.2x", data[j]);
14872 else
14873 printf (" ");
14874
14875 if ((j & 3) == 3)
14876 printf (" ");
14877 }
14878
14879 for (j = 0; j < lbytes; j++)
14880 {
14881 k = data[j];
14882 if (k >= ' ' && k < 0x7f)
14883 printf ("%c", k);
14884 else
14885 printf (".");
14886 }
14887
14888 putchar ('\n');
14889
14890 data += lbytes;
14891 addr += lbytes;
14892 bytes -= lbytes;
14893 }
14894
0e602686 14895 free (real_start);
cf13d699
NC
14896
14897 putchar ('\n');
015dc7e1 14898 return true;
f761cb13
AM
14899
14900 error_out:
14901 free (real_start);
015dc7e1 14902 return false;
cf13d699
NC
14903}
14904
094e34f2 14905#ifdef ENABLE_LIBCTF
7d9813f1
NA
14906static ctf_sect_t *
14907shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
14908{
b9e920ec 14909 buf->cts_name = SECTION_NAME_PRINT (shdr);
7d9813f1
NA
14910 buf->cts_size = shdr->sh_size;
14911 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
14912
14913 return buf;
14914}
14915
14916/* Formatting callback function passed to ctf_dump. Returns either the pointer
14917 it is passed, or a pointer to newly-allocated storage, in which case
14918 dump_ctf() will free it when it no longer needs it. */
14919
2f6ecaed
NA
14920static char *
14921dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14922 char *s, void *arg)
7d9813f1 14923{
3e50a591 14924 const char *blanks = arg;
7d9813f1
NA
14925 char *new_s;
14926
3e50a591 14927 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
14928 return s;
14929 return new_s;
14930}
14931
926c9e76
NA
14932/* Dump CTF errors/warnings. */
14933static void
139633c3 14934dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
14935{
14936 ctf_next_t *it = NULL;
14937 char *errtext;
14938 int is_warning;
14939 int err;
14940
14941 /* Dump accumulated errors and warnings. */
14942 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
14943 {
5e9b84f7 14944 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
14945 errtext);
14946 free (errtext);
14947 }
14948 if (err != ECTF_NEXT_END)
14949 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
14950}
14951
2f6ecaed
NA
14952/* Dump one CTF archive member. */
14953
14954static int
139633c3 14955dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
2f6ecaed 14956{
139633c3 14957 ctf_dict_t *parent = (ctf_dict_t *) arg;
2f6ecaed
NA
14958 const char *things[] = {"Header", "Labels", "Data objects",
14959 "Function objects", "Variables", "Types", "Strings",
14960 ""};
14961 const char **thing;
14962 size_t i;
8b37e7b6 14963 int err = 0;
2f6ecaed
NA
14964
14965 /* Only print out the name of non-default-named archive members.
14966 The name .ctf appears everywhere, even for things that aren't
14967 really archives, so printing it out is liable to be confusing.
14968
14969 The parent, if there is one, is the default-owned archive member:
14970 avoid importing it into itself. (This does no harm, but looks
14971 confusing.) */
14972
14973 if (strcmp (name, ".ctf") != 0)
14974 {
14975 printf (_("\nCTF archive member: %s:\n"), name);
14976 ctf_import (ctf, parent);
14977 }
14978
14979 for (i = 0, thing = things; *thing[0]; thing++, i++)
14980 {
14981 ctf_dump_state_t *s = NULL;
14982 char *item;
14983
14984 printf ("\n %s:\n", *thing);
14985 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
14986 (void *) " ")) != NULL)
14987 {
14988 printf ("%s\n", item);
14989 free (item);
14990 }
14991
14992 if (ctf_errno (ctf))
14993 {
14994 error (_("Iteration failed: %s, %s\n"), *thing,
14995 ctf_errmsg (ctf_errno (ctf)));
8b37e7b6
NA
14996 err = 1;
14997 goto out;
2f6ecaed
NA
14998 }
14999 }
8b37e7b6
NA
15000
15001 out:
926c9e76 15002 dump_ctf_errs (ctf);
8b37e7b6 15003 return err;
2f6ecaed
NA
15004}
15005
015dc7e1 15006static bool
7d9813f1
NA
15007dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15008{
15009 Elf_Internal_Shdr * parent_sec = NULL;
15010 Elf_Internal_Shdr * symtab_sec = NULL;
15011 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15012 void * data = NULL;
15013 void * symdata = NULL;
15014 void * strdata = NULL;
15015 void * parentdata = NULL;
15016 ctf_sect_t ctfsect, symsect, strsect, parentsect;
15017 ctf_sect_t * symsectp = NULL;
15018 ctf_sect_t * strsectp = NULL;
2f6ecaed
NA
15019 ctf_archive_t * ctfa = NULL;
15020 ctf_archive_t * parenta = NULL, *lookparent;
139633c3 15021 ctf_dict_t * parent = NULL;
7d9813f1 15022
7d9813f1 15023 int err;
015dc7e1 15024 bool ret = false;
7d9813f1
NA
15025
15026 shdr_to_ctf_sect (&ctfsect, section, filedata);
15027 data = get_section_contents (section, filedata);
15028 ctfsect.cts_data = data;
15029
616febde 15030 if (!dump_ctf_symtab_name)
3d16b64e 15031 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15032
15033 if (!dump_ctf_strtab_name)
3d16b64e 15034 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15035
15036 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15037 {
15038 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15039 {
15040 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15041 goto fail;
15042 }
15043 if ((symdata = (void *) get_data (NULL, filedata,
15044 symtab_sec->sh_offset, 1,
15045 symtab_sec->sh_size,
15046 _("symbols"))) == NULL)
15047 goto fail;
15048 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15049 symsect.cts_data = symdata;
15050 }
835f2fae 15051
df16e041 15052 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15053 {
15054 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15055 {
15056 error (_("No string table section named %s\n"),
15057 dump_ctf_strtab_name);
15058 goto fail;
15059 }
15060 if ((strdata = (void *) get_data (NULL, filedata,
15061 strtab_sec->sh_offset, 1,
15062 strtab_sec->sh_size,
15063 _("strings"))) == NULL)
15064 goto fail;
15065 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15066 strsect.cts_data = strdata;
15067 }
835f2fae 15068
7d9813f1
NA
15069 if (dump_ctf_parent_name)
15070 {
15071 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
15072 {
15073 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
15074 goto fail;
15075 }
15076 if ((parentdata = (void *) get_data (NULL, filedata,
15077 parent_sec->sh_offset, 1,
15078 parent_sec->sh_size,
15079 _("CTF parent"))) == NULL)
15080 goto fail;
15081 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
15082 parentsect.cts_data = parentdata;
15083 }
15084
2f6ecaed
NA
15085 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15086 libctf papers over the difference, so we can pretend it is always an
15087 archive. Possibly open the parent as well, if one was specified. */
7d9813f1 15088
2f6ecaed 15089 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15090 {
926c9e76 15091 dump_ctf_errs (NULL);
7d9813f1
NA
15092 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15093 goto fail;
15094 }
15095
96c61be5
NA
15096 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15097 != ELFDATA2MSB);
15098
7d9813f1
NA
15099 if (parentdata)
15100 {
2f6ecaed
NA
15101 if ((parenta = ctf_arc_bufopen (&parentsect, symsectp, strsectp,
15102 &err)) == NULL)
7d9813f1 15103 {
926c9e76 15104 dump_ctf_errs (NULL);
7d9813f1
NA
15105 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15106 goto fail;
15107 }
2f6ecaed
NA
15108 lookparent = parenta;
15109 }
15110 else
15111 lookparent = ctfa;
7d9813f1 15112
2f6ecaed
NA
15113 /* Assume that the applicable parent archive member is the default one.
15114 (This is what all known implementations are expected to do, if they
15115 put CTFs and their parents in archives together.) */
ae41200b 15116 if ((parent = ctf_dict_open (lookparent, NULL, &err)) == NULL)
2f6ecaed 15117 {
926c9e76 15118 dump_ctf_errs (NULL);
2f6ecaed
NA
15119 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15120 goto fail;
7d9813f1
NA
15121 }
15122
015dc7e1 15123 ret = true;
7d9813f1 15124
835f2fae
NC
15125 if (filedata->is_separate)
15126 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15127 printable_section_name (filedata, section),
15128 filedata->file_name);
15129 else
15130 printf (_("\nDump of CTF section '%s':\n"),
15131 printable_section_name (filedata, section));
7d9813f1 15132
83d59285
NA
15133 if ((err = ctf_archive_iter (ctfa, dump_ctf_archive_member, parent)) != 0)
15134 {
15135 dump_ctf_errs (NULL);
15136 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
015dc7e1 15137 ret = false;
83d59285 15138 }
7d9813f1
NA
15139
15140 fail:
139633c3 15141 ctf_dict_close (parent);
2f6ecaed
NA
15142 ctf_close (ctfa);
15143 ctf_close (parenta);
7d9813f1
NA
15144 free (parentdata);
15145 free (data);
15146 free (symdata);
15147 free (strdata);
15148 return ret;
15149}
094e34f2 15150#endif
7d9813f1 15151
015dc7e1 15152static bool
dda8d76d
NC
15153load_specific_debug_section (enum dwarf_section_display_enum debug,
15154 const Elf_Internal_Shdr * sec,
15155 void * data)
1007acb3 15156{
2cf0635d 15157 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15158 char buf [64];
dda8d76d 15159 Filedata * filedata = (Filedata *) data;
9abca702 15160
19e6b90e 15161 if (section->start != NULL)
dda8d76d
NC
15162 {
15163 /* If it is already loaded, do nothing. */
15164 if (streq (section->filename, filedata->file_name))
015dc7e1 15165 return true;
dda8d76d
NC
15166 free (section->start);
15167 }
1007acb3 15168
19e6b90e
L
15169 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15170 section->address = sec->sh_addr;
dda8d76d
NC
15171 section->filename = filedata->file_name;
15172 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15173 sec->sh_offset, 1,
15174 sec->sh_size, buf);
59245841
NC
15175 if (section->start == NULL)
15176 section->size = 0;
15177 else
15178 {
77115a4a
L
15179 unsigned char *start = section->start;
15180 dwarf_size_type size = sec->sh_size;
dab394de 15181 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15182
15183 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15184 {
15185 Elf_Internal_Chdr chdr;
d8024a91
NC
15186 unsigned int compression_header_size;
15187
f53be977
L
15188 if (size < (is_32bit_elf
15189 ? sizeof (Elf32_External_Chdr)
15190 : sizeof (Elf64_External_Chdr)))
d8024a91 15191 {
55be8fd0 15192 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15193 section->name);
015dc7e1 15194 return false;
d8024a91
NC
15195 }
15196
ebdf1ebf 15197 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15198 if (compression_header_size == 0)
15199 /* An error message will have already been generated
15200 by get_compression_header. */
015dc7e1 15201 return false;
d8024a91 15202
813dabb9
L
15203 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15204 {
15205 warn (_("section '%s' has unsupported compress type: %d\n"),
15206 section->name, chdr.ch_type);
015dc7e1 15207 return false;
813dabb9 15208 }
dab394de 15209 uncompressed_size = chdr.ch_size;
77115a4a
L
15210 start += compression_header_size;
15211 size -= compression_header_size;
15212 }
dab394de
L
15213 else if (size > 12 && streq ((char *) start, "ZLIB"))
15214 {
15215 /* Read the zlib header. In this case, it should be "ZLIB"
15216 followed by the uncompressed section size, 8 bytes in
15217 big-endian order. */
15218 uncompressed_size = start[4]; uncompressed_size <<= 8;
15219 uncompressed_size += start[5]; uncompressed_size <<= 8;
15220 uncompressed_size += start[6]; uncompressed_size <<= 8;
15221 uncompressed_size += start[7]; uncompressed_size <<= 8;
15222 uncompressed_size += start[8]; uncompressed_size <<= 8;
15223 uncompressed_size += start[9]; uncompressed_size <<= 8;
15224 uncompressed_size += start[10]; uncompressed_size <<= 8;
15225 uncompressed_size += start[11];
15226 start += 12;
15227 size -= 12;
15228 }
15229
1835f746 15230 if (uncompressed_size)
77115a4a 15231 {
1835f746
NC
15232 if (uncompress_section_contents (&start, uncompressed_size,
15233 &size))
15234 {
15235 /* Free the compressed buffer, update the section buffer
15236 and the section size if uncompress is successful. */
15237 free (section->start);
15238 section->start = start;
15239 }
15240 else
15241 {
15242 error (_("Unable to decompress section %s\n"),
dda8d76d 15243 printable_section_name (filedata, sec));
015dc7e1 15244 return false;
1835f746 15245 }
77115a4a 15246 }
bc303e5d 15247
77115a4a 15248 section->size = size;
59245841 15249 }
4a114e3e 15250
1b315056 15251 if (section->start == NULL)
015dc7e1 15252 return false;
1b315056 15253
19e6b90e 15254 if (debug_displays [debug].relocate)
32ec8896 15255 {
dda8d76d 15256 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15257 & section->reloc_info, & section->num_relocs))
015dc7e1 15258 return false;
32ec8896 15259 }
d1c4b12b
NC
15260 else
15261 {
15262 section->reloc_info = NULL;
15263 section->num_relocs = 0;
15264 }
1007acb3 15265
015dc7e1 15266 return true;
1007acb3
L
15267}
15268
301a9420
AM
15269#if HAVE_LIBDEBUGINFOD
15270/* Return a hex string representation of the build-id. */
15271unsigned char *
15272get_build_id (void * data)
15273{
ca0e11aa 15274 Filedata * filedata = (Filedata *) data;
301a9420
AM
15275 Elf_Internal_Shdr * shdr;
15276 unsigned long i;
15277
55be8fd0
NC
15278 /* Iterate through notes to find note.gnu.build-id.
15279 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15280 for (i = 0, shdr = filedata->section_headers;
15281 i < filedata->file_header.e_shnum && shdr != NULL;
15282 i++, shdr++)
15283 {
15284 if (shdr->sh_type != SHT_NOTE)
15285 continue;
15286
15287 char * next;
15288 char * end;
15289 size_t data_remaining;
15290 size_t min_notesz;
15291 Elf_External_Note * enote;
15292 Elf_Internal_Note inote;
15293
15294 bfd_vma offset = shdr->sh_offset;
15295 bfd_vma align = shdr->sh_addralign;
15296 bfd_vma length = shdr->sh_size;
15297
15298 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15299 if (enote == NULL)
15300 continue;
15301
15302 if (align < 4)
15303 align = 4;
15304 else if (align != 4 && align != 8)
f761cb13
AM
15305 {
15306 free (enote);
15307 continue;
15308 }
301a9420
AM
15309
15310 end = (char *) enote + length;
15311 data_remaining = end - (char *) enote;
15312
15313 if (!is_ia64_vms (filedata))
15314 {
15315 min_notesz = offsetof (Elf_External_Note, name);
15316 if (data_remaining < min_notesz)
15317 {
55be8fd0
NC
15318 warn (_("\
15319malformed note encountered in section %s whilst scanning for build-id note\n"),
15320 printable_section_name (filedata, shdr));
f761cb13 15321 free (enote);
55be8fd0 15322 continue;
301a9420
AM
15323 }
15324 data_remaining -= min_notesz;
15325
15326 inote.type = BYTE_GET (enote->type);
15327 inote.namesz = BYTE_GET (enote->namesz);
15328 inote.namedata = enote->name;
15329 inote.descsz = BYTE_GET (enote->descsz);
15330 inote.descdata = ((char *) enote
15331 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15332 inote.descpos = offset + (inote.descdata - (char *) enote);
15333 next = ((char *) enote
15334 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15335 }
15336 else
15337 {
15338 Elf64_External_VMS_Note *vms_enote;
15339
15340 /* PR binutils/15191
15341 Make sure that there is enough data to read. */
15342 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15343 if (data_remaining < min_notesz)
15344 {
55be8fd0
NC
15345 warn (_("\
15346malformed note encountered in section %s whilst scanning for build-id note\n"),
15347 printable_section_name (filedata, shdr));
f761cb13 15348 free (enote);
55be8fd0 15349 continue;
301a9420
AM
15350 }
15351 data_remaining -= min_notesz;
15352
15353 vms_enote = (Elf64_External_VMS_Note *) enote;
15354 inote.type = BYTE_GET (vms_enote->type);
15355 inote.namesz = BYTE_GET (vms_enote->namesz);
15356 inote.namedata = vms_enote->name;
15357 inote.descsz = BYTE_GET (vms_enote->descsz);
15358 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15359 inote.descpos = offset + (inote.descdata - (char *) enote);
15360 next = inote.descdata + align_power (inote.descsz, 3);
15361 }
15362
15363 /* Skip malformed notes. */
15364 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
15365 || (size_t) (inote.descdata - inote.namedata) > data_remaining
15366 || (size_t) (next - inote.descdata) < inote.descsz
15367 || ((size_t) (next - inote.descdata)
15368 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
15369 {
55be8fd0
NC
15370 warn (_("\
15371malformed note encountered in section %s whilst scanning for build-id note\n"),
15372 printable_section_name (filedata, shdr));
f761cb13 15373 free (enote);
301a9420
AM
15374 continue;
15375 }
15376
15377 /* Check if this is the build-id note. If so then convert the build-id
15378 bytes to a hex string. */
15379 if (inote.namesz > 0
24d127aa 15380 && startswith (inote.namedata, "GNU")
301a9420
AM
15381 && inote.type == NT_GNU_BUILD_ID)
15382 {
15383 unsigned long j;
15384 char * build_id;
15385
15386 build_id = malloc (inote.descsz * 2 + 1);
15387 if (build_id == NULL)
f761cb13
AM
15388 {
15389 free (enote);
15390 return NULL;
15391 }
301a9420
AM
15392
15393 for (j = 0; j < inote.descsz; ++j)
15394 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
15395 build_id[inote.descsz * 2] = '\0';
f761cb13 15396 free (enote);
301a9420 15397
55be8fd0 15398 return (unsigned char *) build_id;
301a9420 15399 }
f761cb13 15400 free (enote);
301a9420
AM
15401 }
15402
15403 return NULL;
15404}
15405#endif /* HAVE_LIBDEBUGINFOD */
15406
657d0d47
CC
15407/* If this is not NULL, load_debug_section will only look for sections
15408 within the list of sections given here. */
32ec8896 15409static unsigned int * section_subset = NULL;
657d0d47 15410
015dc7e1 15411bool
dda8d76d 15412load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 15413{
2cf0635d
NC
15414 struct dwarf_section * section = &debug_displays [debug].section;
15415 Elf_Internal_Shdr * sec;
dda8d76d
NC
15416 Filedata * filedata = (Filedata *) data;
15417
f425ec66
NC
15418 /* Without section headers we cannot find any sections. */
15419 if (filedata->section_headers == NULL)
015dc7e1 15420 return false;
f425ec66 15421
9c1ce108
AM
15422 if (filedata->string_table == NULL
15423 && filedata->file_header.e_shstrndx != SHN_UNDEF
15424 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
15425 {
15426 Elf_Internal_Shdr * strs;
15427
15428 /* Read in the string table, so that we have section names to scan. */
15429 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
15430
4dff97b2 15431 if (strs != NULL && strs->sh_size != 0)
dda8d76d 15432 {
9c1ce108
AM
15433 filedata->string_table
15434 = (char *) get_data (NULL, filedata, strs->sh_offset,
15435 1, strs->sh_size, _("string table"));
dda8d76d 15436
9c1ce108
AM
15437 filedata->string_table_length
15438 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
15439 }
15440 }
d966045b
DJ
15441
15442 /* Locate the debug section. */
dda8d76d 15443 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
15444 if (sec != NULL)
15445 section->name = section->uncompressed_name;
15446 else
15447 {
dda8d76d 15448 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
15449 if (sec != NULL)
15450 section->name = section->compressed_name;
15451 }
15452 if (sec == NULL)
015dc7e1 15453 return false;
d966045b 15454
657d0d47
CC
15455 /* If we're loading from a subset of sections, and we've loaded
15456 a section matching this name before, it's likely that it's a
15457 different one. */
15458 if (section_subset != NULL)
15459 free_debug_section (debug);
15460
dda8d76d 15461 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
15462}
15463
19e6b90e
L
15464void
15465free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 15466{
2cf0635d 15467 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 15468
19e6b90e
L
15469 if (section->start == NULL)
15470 return;
1007acb3 15471
19e6b90e
L
15472 free ((char *) section->start);
15473 section->start = NULL;
15474 section->address = 0;
15475 section->size = 0;
a788aedd 15476
9db70fc3
AM
15477 free (section->reloc_info);
15478 section->reloc_info = NULL;
15479 section->num_relocs = 0;
1007acb3
L
15480}
15481
015dc7e1 15482static bool
dda8d76d 15483display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 15484{
b9e920ec 15485 char * name = SECTION_NAME_VALID (section) ? SECTION_NAME (section) : "";
dda8d76d 15486 const char * print_name = printable_section_name (filedata, section);
19e6b90e 15487 bfd_size_type length;
015dc7e1 15488 bool result = true;
3f5e193b 15489 int i;
1007acb3 15490
19e6b90e
L
15491 length = section->sh_size;
15492 if (length == 0)
1007acb3 15493 {
74e1a04b 15494 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 15495 return true;
1007acb3 15496 }
5dff79d8
NC
15497 if (section->sh_type == SHT_NOBITS)
15498 {
15499 /* There is no point in dumping the contents of a debugging section
15500 which has the NOBITS type - the bits in the file will be random.
15501 This can happen when a file containing a .eh_frame section is
15502 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
15503 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
15504 print_name);
015dc7e1 15505 return false;
5dff79d8 15506 }
1007acb3 15507
24d127aa 15508 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 15509 name = ".debug_info";
1007acb3 15510
19e6b90e
L
15511 /* See if we know how to display the contents of this section. */
15512 for (i = 0; i < max; i++)
d85bf2ba
NC
15513 {
15514 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
15515 struct dwarf_section_display * display = debug_displays + i;
15516 struct dwarf_section * sec = & display->section;
d966045b 15517
d85bf2ba 15518 if (streq (sec->uncompressed_name, name)
24d127aa 15519 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15520 || streq (sec->compressed_name, name))
15521 {
015dc7e1 15522 bool secondary = (section != find_section (filedata, name));
1007acb3 15523
d85bf2ba
NC
15524 if (secondary)
15525 free_debug_section (id);
dda8d76d 15526
24d127aa 15527 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15528 sec->name = name;
15529 else if (streq (sec->uncompressed_name, name))
15530 sec->name = sec->uncompressed_name;
15531 else
15532 sec->name = sec->compressed_name;
657d0d47 15533
d85bf2ba
NC
15534 if (load_specific_debug_section (id, section, filedata))
15535 {
15536 /* If this debug section is part of a CU/TU set in a .dwp file,
15537 restrict load_debug_section to the sections in that set. */
15538 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 15539
d85bf2ba 15540 result &= display->display (sec, filedata);
657d0d47 15541
d85bf2ba 15542 section_subset = NULL;
1007acb3 15543
44266f36 15544 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
15545 free_debug_section (id);
15546 }
15547 break;
15548 }
15549 }
1007acb3 15550
19e6b90e 15551 if (i == max)
1007acb3 15552 {
74e1a04b 15553 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 15554 result = false;
1007acb3
L
15555 }
15556
19e6b90e 15557 return result;
5b18a4bc 15558}
103f02d3 15559
aef1f6d0
DJ
15560/* Set DUMP_SECTS for all sections where dumps were requested
15561 based on section name. */
15562
15563static void
dda8d76d 15564initialise_dumps_byname (Filedata * filedata)
aef1f6d0 15565{
2cf0635d 15566 struct dump_list_entry * cur;
aef1f6d0
DJ
15567
15568 for (cur = dump_sects_byname; cur; cur = cur->next)
15569 {
15570 unsigned int i;
015dc7e1 15571 bool any = false;
aef1f6d0 15572
dda8d76d 15573 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
15574 if (SECTION_NAME_VALID (filedata->section_headers + i)
15575 && streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 15576 {
6431e409 15577 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 15578 any = true;
aef1f6d0
DJ
15579 }
15580
835f2fae
NC
15581 if (!any && !filedata->is_separate)
15582 warn (_("Section '%s' was not dumped because it does not exist\n"),
15583 cur->name);
aef1f6d0
DJ
15584 }
15585}
15586
015dc7e1 15587static bool
dda8d76d 15588process_section_contents (Filedata * filedata)
5b18a4bc 15589{
2cf0635d 15590 Elf_Internal_Shdr * section;
19e6b90e 15591 unsigned int i;
015dc7e1 15592 bool res = true;
103f02d3 15593
19e6b90e 15594 if (! do_dump)
015dc7e1 15595 return true;
103f02d3 15596
dda8d76d 15597 initialise_dumps_byname (filedata);
aef1f6d0 15598
dda8d76d 15599 for (i = 0, section = filedata->section_headers;
6431e409 15600 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
15601 i++, section++)
15602 {
6431e409 15603 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 15604
d6bfbc39
NC
15605 if (filedata->is_separate && ! process_links)
15606 dump &= DEBUG_DUMP;
047c3dbf 15607
19e6b90e 15608#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
15609 if (dump & DISASS_DUMP)
15610 {
15611 if (! disassemble_section (section, filedata))
015dc7e1 15612 res = false;
dda8d76d 15613 }
19e6b90e 15614#endif
dda8d76d 15615 if (dump & HEX_DUMP)
32ec8896 15616 {
015dc7e1
AM
15617 if (! dump_section_as_bytes (section, filedata, false))
15618 res = false;
32ec8896 15619 }
103f02d3 15620
dda8d76d 15621 if (dump & RELOC_DUMP)
32ec8896 15622 {
015dc7e1
AM
15623 if (! dump_section_as_bytes (section, filedata, true))
15624 res = false;
32ec8896 15625 }
09c11c86 15626
dda8d76d 15627 if (dump & STRING_DUMP)
32ec8896 15628 {
dda8d76d 15629 if (! dump_section_as_strings (section, filedata))
015dc7e1 15630 res = false;
32ec8896 15631 }
cf13d699 15632
dda8d76d 15633 if (dump & DEBUG_DUMP)
32ec8896 15634 {
dda8d76d 15635 if (! display_debug_section (i, section, filedata))
015dc7e1 15636 res = false;
32ec8896 15637 }
7d9813f1 15638
094e34f2 15639#ifdef ENABLE_LIBCTF
7d9813f1
NA
15640 if (dump & CTF_DUMP)
15641 {
15642 if (! dump_section_as_ctf (section, filedata))
015dc7e1 15643 res = false;
7d9813f1 15644 }
094e34f2 15645#endif
5b18a4bc 15646 }
103f02d3 15647
835f2fae 15648 if (! filedata->is_separate)
0ee3043f 15649 {
835f2fae
NC
15650 /* Check to see if the user requested a
15651 dump of a section that does not exist. */
15652 for (; i < filedata->dump.num_dump_sects; i++)
15653 if (filedata->dump.dump_sects[i])
15654 {
ca0e11aa 15655 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 15656 res = false;
835f2fae 15657 }
0ee3043f 15658 }
32ec8896
NC
15659
15660 return res;
5b18a4bc 15661}
103f02d3 15662
5b18a4bc 15663static void
19e6b90e 15664process_mips_fpe_exception (int mask)
5b18a4bc 15665{
19e6b90e
L
15666 if (mask)
15667 {
015dc7e1 15668 bool first = true;
32ec8896 15669
19e6b90e 15670 if (mask & OEX_FPU_INEX)
015dc7e1 15671 fputs ("INEX", stdout), first = false;
19e6b90e 15672 if (mask & OEX_FPU_UFLO)
015dc7e1 15673 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 15674 if (mask & OEX_FPU_OFLO)
015dc7e1 15675 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 15676 if (mask & OEX_FPU_DIV0)
015dc7e1 15677 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
15678 if (mask & OEX_FPU_INVAL)
15679 printf ("%sINVAL", first ? "" : "|");
15680 }
5b18a4bc 15681 else
19e6b90e 15682 fputs ("0", stdout);
5b18a4bc 15683}
103f02d3 15684
f6f0e17b
NC
15685/* Display's the value of TAG at location P. If TAG is
15686 greater than 0 it is assumed to be an unknown tag, and
15687 a message is printed to this effect. Otherwise it is
15688 assumed that a message has already been printed.
15689
15690 If the bottom bit of TAG is set it assumed to have a
15691 string value, otherwise it is assumed to have an integer
15692 value.
15693
15694 Returns an updated P pointing to the first unread byte
15695 beyond the end of TAG's value.
15696
15697 Reads at or beyond END will not be made. */
15698
15699static unsigned char *
60abdbed 15700display_tag_value (signed int tag,
f6f0e17b
NC
15701 unsigned char * p,
15702 const unsigned char * const end)
15703{
15704 unsigned long val;
15705
15706 if (tag > 0)
15707 printf (" Tag_unknown_%d: ", tag);
15708
15709 if (p >= end)
15710 {
4082ef84 15711 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
15712 }
15713 else if (tag & 1)
15714 {
071436c6
NC
15715 /* PR 17531 file: 027-19978-0.004. */
15716 size_t maxlen = (end - p) - 1;
15717
15718 putchar ('"');
4082ef84
NC
15719 if (maxlen > 0)
15720 {
15721 print_symbol ((int) maxlen, (const char *) p);
15722 p += strnlen ((char *) p, maxlen) + 1;
15723 }
15724 else
15725 {
15726 printf (_("<corrupt string tag>"));
15727 p = (unsigned char *) end;
15728 }
071436c6 15729 printf ("\"\n");
f6f0e17b
NC
15730 }
15731 else
15732 {
cd30bcef 15733 READ_ULEB (val, p, end);
f6f0e17b
NC
15734 printf ("%ld (0x%lx)\n", val, val);
15735 }
15736
4082ef84 15737 assert (p <= end);
f6f0e17b
NC
15738 return p;
15739}
15740
53a346d8
CZ
15741/* ARC ABI attributes section. */
15742
15743static unsigned char *
15744display_arc_attribute (unsigned char * p,
15745 const unsigned char * const end)
15746{
15747 unsigned int tag;
53a346d8
CZ
15748 unsigned int val;
15749
cd30bcef 15750 READ_ULEB (tag, p, end);
53a346d8
CZ
15751
15752 switch (tag)
15753 {
15754 case Tag_ARC_PCS_config:
cd30bcef 15755 READ_ULEB (val, p, end);
53a346d8
CZ
15756 printf (" Tag_ARC_PCS_config: ");
15757 switch (val)
15758 {
15759 case 0:
15760 printf (_("Absent/Non standard\n"));
15761 break;
15762 case 1:
15763 printf (_("Bare metal/mwdt\n"));
15764 break;
15765 case 2:
15766 printf (_("Bare metal/newlib\n"));
15767 break;
15768 case 3:
15769 printf (_("Linux/uclibc\n"));
15770 break;
15771 case 4:
15772 printf (_("Linux/glibc\n"));
15773 break;
15774 default:
15775 printf (_("Unknown\n"));
15776 break;
15777 }
15778 break;
15779
15780 case Tag_ARC_CPU_base:
cd30bcef 15781 READ_ULEB (val, p, end);
53a346d8
CZ
15782 printf (" Tag_ARC_CPU_base: ");
15783 switch (val)
15784 {
15785 default:
15786 case TAG_CPU_NONE:
15787 printf (_("Absent\n"));
15788 break;
15789 case TAG_CPU_ARC6xx:
15790 printf ("ARC6xx\n");
15791 break;
15792 case TAG_CPU_ARC7xx:
15793 printf ("ARC7xx\n");
15794 break;
15795 case TAG_CPU_ARCEM:
15796 printf ("ARCEM\n");
15797 break;
15798 case TAG_CPU_ARCHS:
15799 printf ("ARCHS\n");
15800 break;
15801 }
15802 break;
15803
15804 case Tag_ARC_CPU_variation:
cd30bcef 15805 READ_ULEB (val, p, end);
53a346d8
CZ
15806 printf (" Tag_ARC_CPU_variation: ");
15807 switch (val)
15808 {
15809 default:
15810 if (val > 0 && val < 16)
53a346d8 15811 printf ("Core%d\n", val);
d8cbc93b
JL
15812 else
15813 printf ("Unknown\n");
15814 break;
15815
53a346d8
CZ
15816 case 0:
15817 printf (_("Absent\n"));
15818 break;
15819 }
15820 break;
15821
15822 case Tag_ARC_CPU_name:
15823 printf (" Tag_ARC_CPU_name: ");
15824 p = display_tag_value (-1, p, end);
15825 break;
15826
15827 case Tag_ARC_ABI_rf16:
cd30bcef 15828 READ_ULEB (val, p, end);
53a346d8
CZ
15829 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
15830 break;
15831
15832 case Tag_ARC_ABI_osver:
cd30bcef 15833 READ_ULEB (val, p, end);
53a346d8
CZ
15834 printf (" Tag_ARC_ABI_osver: v%d\n", val);
15835 break;
15836
15837 case Tag_ARC_ABI_pic:
15838 case Tag_ARC_ABI_sda:
cd30bcef 15839 READ_ULEB (val, p, end);
53a346d8
CZ
15840 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
15841 : " Tag_ARC_ABI_pic: ");
15842 switch (val)
15843 {
15844 case 0:
15845 printf (_("Absent\n"));
15846 break;
15847 case 1:
15848 printf ("MWDT\n");
15849 break;
15850 case 2:
15851 printf ("GNU\n");
15852 break;
15853 default:
15854 printf (_("Unknown\n"));
15855 break;
15856 }
15857 break;
15858
15859 case Tag_ARC_ABI_tls:
cd30bcef 15860 READ_ULEB (val, p, end);
53a346d8
CZ
15861 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
15862 break;
15863
15864 case Tag_ARC_ABI_enumsize:
cd30bcef 15865 READ_ULEB (val, p, end);
53a346d8
CZ
15866 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
15867 _("smallest"));
15868 break;
15869
15870 case Tag_ARC_ABI_exceptions:
cd30bcef 15871 READ_ULEB (val, p, end);
53a346d8
CZ
15872 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
15873 : _("default"));
15874 break;
15875
15876 case Tag_ARC_ABI_double_size:
cd30bcef 15877 READ_ULEB (val, p, end);
53a346d8
CZ
15878 printf (" Tag_ARC_ABI_double_size: %d\n", val);
15879 break;
15880
15881 case Tag_ARC_ISA_config:
15882 printf (" Tag_ARC_ISA_config: ");
15883 p = display_tag_value (-1, p, end);
15884 break;
15885
15886 case Tag_ARC_ISA_apex:
15887 printf (" Tag_ARC_ISA_apex: ");
15888 p = display_tag_value (-1, p, end);
15889 break;
15890
15891 case Tag_ARC_ISA_mpy_option:
cd30bcef 15892 READ_ULEB (val, p, end);
53a346d8
CZ
15893 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
15894 break;
15895
db1e1b45 15896 case Tag_ARC_ATR_version:
cd30bcef 15897 READ_ULEB (val, p, end);
db1e1b45 15898 printf (" Tag_ARC_ATR_version: %d\n", val);
15899 break;
15900
53a346d8
CZ
15901 default:
15902 return display_tag_value (tag & 1, p, end);
15903 }
15904
15905 return p;
15906}
15907
11c1ff18
PB
15908/* ARM EABI attributes section. */
15909typedef struct
15910{
70e99720 15911 unsigned int tag;
2cf0635d 15912 const char * name;
11c1ff18 15913 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 15914 unsigned int type;
288f0ba2 15915 const char *const *table;
11c1ff18
PB
15916} arm_attr_public_tag;
15917
288f0ba2 15918static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 15919 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 15920 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 15921 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
288f0ba2
AM
15922static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
15923static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 15924 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 15925static const char *const arm_attr_tag_FP_arch[] =
bca38921 15926 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 15927 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
15928static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
15929static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
15930 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
15931 "NEON for ARMv8.1"};
288f0ba2 15932static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
15933 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
15934 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 15935static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 15936 {"V6", "SB", "TLS", "Unused"};
288f0ba2 15937static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 15938 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 15939static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 15940 {"Absolute", "PC-relative", "None"};
288f0ba2 15941static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 15942 {"None", "direct", "GOT-indirect"};
288f0ba2 15943static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 15944 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
15945static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
15946static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 15947 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
15948static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
15949static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
15950static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 15951 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 15952static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 15953 {"Unused", "small", "int", "forced to int"};
288f0ba2 15954static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 15955 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 15956static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 15957 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 15958static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 15959 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 15960static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
15961 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15962 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 15963static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
15964 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15965 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
15966static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
15967static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 15968 {"Not Allowed", "Allowed"};
288f0ba2 15969static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 15970 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 15971static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 15972 {"Follow architecture", "Allowed"};
288f0ba2 15973static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 15974 {"Not Allowed", "Allowed"};
288f0ba2 15975static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 15976 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 15977 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
15978static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
15979static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 15980 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 15981 "TrustZone and Virtualization Extensions"};
288f0ba2 15982static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 15983 {"Not Allowed", "Allowed"};
11c1ff18 15984
288f0ba2 15985static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
15986 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
15987
11c1ff18
PB
15988#define LOOKUP(id, name) \
15989 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 15990static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
15991{
15992 {4, "CPU_raw_name", 1, NULL},
15993 {5, "CPU_name", 1, NULL},
15994 LOOKUP(6, CPU_arch),
15995 {7, "CPU_arch_profile", 0, NULL},
15996 LOOKUP(8, ARM_ISA_use),
15997 LOOKUP(9, THUMB_ISA_use),
75375b3e 15998 LOOKUP(10, FP_arch),
11c1ff18 15999 LOOKUP(11, WMMX_arch),
f5f53991
AS
16000 LOOKUP(12, Advanced_SIMD_arch),
16001 LOOKUP(13, PCS_config),
11c1ff18
PB
16002 LOOKUP(14, ABI_PCS_R9_use),
16003 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16004 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16005 LOOKUP(17, ABI_PCS_GOT_use),
16006 LOOKUP(18, ABI_PCS_wchar_t),
16007 LOOKUP(19, ABI_FP_rounding),
16008 LOOKUP(20, ABI_FP_denormal),
16009 LOOKUP(21, ABI_FP_exceptions),
16010 LOOKUP(22, ABI_FP_user_exceptions),
16011 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16012 {24, "ABI_align_needed", 0, NULL},
16013 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16014 LOOKUP(26, ABI_enum_size),
16015 LOOKUP(27, ABI_HardFP_use),
16016 LOOKUP(28, ABI_VFP_args),
16017 LOOKUP(29, ABI_WMMX_args),
16018 LOOKUP(30, ABI_optimization_goals),
16019 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16020 {32, "compatibility", 0, NULL},
f5f53991 16021 LOOKUP(34, CPU_unaligned_access),
75375b3e 16022 LOOKUP(36, FP_HP_extension),
8e79c3df 16023 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16024 LOOKUP(42, MPextension_use),
16025 LOOKUP(44, DIV_use),
15afaa63 16026 LOOKUP(46, DSP_extension),
a7ad558c 16027 LOOKUP(48, MVE_arch),
f5f53991
AS
16028 {64, "nodefaults", 0, NULL},
16029 {65, "also_compatible_with", 0, NULL},
16030 LOOKUP(66, T2EE_use),
16031 {67, "conformance", 1, NULL},
16032 LOOKUP(68, Virtualization_use),
cd21e546 16033 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16034};
16035#undef LOOKUP
16036
11c1ff18 16037static unsigned char *
f6f0e17b
NC
16038display_arm_attribute (unsigned char * p,
16039 const unsigned char * const end)
11c1ff18 16040{
70e99720 16041 unsigned int tag;
70e99720 16042 unsigned int val;
2cf0635d 16043 arm_attr_public_tag * attr;
11c1ff18 16044 unsigned i;
70e99720 16045 unsigned int type;
11c1ff18 16046
cd30bcef 16047 READ_ULEB (tag, p, end);
11c1ff18 16048 attr = NULL;
2cf0635d 16049 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16050 {
16051 if (arm_attr_public_tags[i].tag == tag)
16052 {
16053 attr = &arm_attr_public_tags[i];
16054 break;
16055 }
16056 }
16057
16058 if (attr)
16059 {
16060 printf (" Tag_%s: ", attr->name);
16061 switch (attr->type)
16062 {
16063 case 0:
16064 switch (tag)
16065 {
16066 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16067 READ_ULEB (val, p, end);
11c1ff18
PB
16068 switch (val)
16069 {
2b692964
NC
16070 case 0: printf (_("None\n")); break;
16071 case 'A': printf (_("Application\n")); break;
16072 case 'R': printf (_("Realtime\n")); break;
16073 case 'M': printf (_("Microcontroller\n")); break;
16074 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16075 default: printf ("??? (%d)\n", val); break;
16076 }
16077 break;
16078
75375b3e 16079 case 24: /* Tag_align_needed. */
cd30bcef 16080 READ_ULEB (val, p, end);
75375b3e
MGD
16081 switch (val)
16082 {
2b692964
NC
16083 case 0: printf (_("None\n")); break;
16084 case 1: printf (_("8-byte\n")); break;
16085 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16086 case 3: printf ("??? 3\n"); break;
16087 default:
16088 if (val <= 12)
dd24e3da 16089 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16090 1 << val);
16091 else
16092 printf ("??? (%d)\n", val);
16093 break;
16094 }
16095 break;
16096
16097 case 25: /* Tag_align_preserved. */
cd30bcef 16098 READ_ULEB (val, p, end);
75375b3e
MGD
16099 switch (val)
16100 {
2b692964
NC
16101 case 0: printf (_("None\n")); break;
16102 case 1: printf (_("8-byte, except leaf SP\n")); break;
16103 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16104 case 3: printf ("??? 3\n"); break;
16105 default:
16106 if (val <= 12)
dd24e3da 16107 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16108 1 << val);
16109 else
16110 printf ("??? (%d)\n", val);
16111 break;
16112 }
16113 break;
16114
11c1ff18 16115 case 32: /* Tag_compatibility. */
071436c6 16116 {
cd30bcef 16117 READ_ULEB (val, p, end);
071436c6 16118 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16119 if (p < end - 1)
16120 {
16121 size_t maxlen = (end - p) - 1;
16122
16123 print_symbol ((int) maxlen, (const char *) p);
16124 p += strnlen ((char *) p, maxlen) + 1;
16125 }
16126 else
16127 {
16128 printf (_("<corrupt>"));
16129 p = (unsigned char *) end;
16130 }
071436c6 16131 putchar ('\n');
071436c6 16132 }
11c1ff18
PB
16133 break;
16134
f5f53991 16135 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16136 /* PR 17531: file: 001-505008-0.01. */
16137 if (p < end)
16138 p++;
2b692964 16139 printf (_("True\n"));
f5f53991
AS
16140 break;
16141
16142 case 65: /* Tag_also_compatible_with. */
cd30bcef 16143 READ_ULEB (val, p, end);
f5f53991
AS
16144 if (val == 6 /* Tag_CPU_arch. */)
16145 {
cd30bcef 16146 READ_ULEB (val, p, end);
071436c6 16147 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16148 printf ("??? (%d)\n", val);
16149 else
16150 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16151 }
16152 else
16153 printf ("???\n");
071436c6
NC
16154 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16155 ;
f5f53991
AS
16156 break;
16157
11c1ff18 16158 default:
bee0ee85
NC
16159 printf (_("<unknown: %d>\n"), tag);
16160 break;
11c1ff18
PB
16161 }
16162 return p;
16163
16164 case 1:
f6f0e17b 16165 return display_tag_value (-1, p, end);
11c1ff18 16166 case 2:
f6f0e17b 16167 return display_tag_value (0, p, end);
11c1ff18
PB
16168
16169 default:
16170 assert (attr->type & 0x80);
cd30bcef 16171 READ_ULEB (val, p, end);
11c1ff18
PB
16172 type = attr->type & 0x7f;
16173 if (val >= type)
16174 printf ("??? (%d)\n", val);
16175 else
16176 printf ("%s\n", attr->table[val]);
16177 return p;
16178 }
16179 }
11c1ff18 16180
f6f0e17b 16181 return display_tag_value (tag, p, end);
11c1ff18
PB
16182}
16183
104d59d1 16184static unsigned char *
60bca95a 16185display_gnu_attribute (unsigned char * p,
60abdbed 16186 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16187 const unsigned char * const end)
104d59d1 16188{
cd30bcef 16189 unsigned int tag;
60abdbed 16190 unsigned int val;
104d59d1 16191
cd30bcef 16192 READ_ULEB (tag, p, end);
104d59d1
JM
16193
16194 /* Tag_compatibility is the only generic GNU attribute defined at
16195 present. */
16196 if (tag == 32)
16197 {
cd30bcef 16198 READ_ULEB (val, p, end);
071436c6
NC
16199
16200 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16201 if (p == end)
16202 {
071436c6 16203 printf (_("<corrupt>\n"));
f6f0e17b
NC
16204 warn (_("corrupt vendor attribute\n"));
16205 }
16206 else
16207 {
4082ef84
NC
16208 if (p < end - 1)
16209 {
16210 size_t maxlen = (end - p) - 1;
071436c6 16211
4082ef84
NC
16212 print_symbol ((int) maxlen, (const char *) p);
16213 p += strnlen ((char *) p, maxlen) + 1;
16214 }
16215 else
16216 {
16217 printf (_("<corrupt>"));
16218 p = (unsigned char *) end;
16219 }
071436c6 16220 putchar ('\n');
f6f0e17b 16221 }
104d59d1
JM
16222 return p;
16223 }
16224
16225 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16226 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16227
f6f0e17b 16228 return display_tag_value (tag, p, end);
104d59d1
JM
16229}
16230
85f7484a
PB
16231static unsigned char *
16232display_m68k_gnu_attribute (unsigned char * p,
16233 unsigned int tag,
16234 const unsigned char * const end)
16235{
16236 unsigned int val;
16237
16238 if (tag == Tag_GNU_M68K_ABI_FP)
16239 {
16240 printf (" Tag_GNU_M68K_ABI_FP: ");
16241 if (p == end)
16242 {
16243 printf (_("<corrupt>\n"));
16244 return p;
16245 }
16246 READ_ULEB (val, p, end);
16247
16248 if (val > 3)
16249 printf ("(%#x), ", val);
16250
16251 switch (val & 3)
16252 {
16253 case 0:
16254 printf (_("unspecified hard/soft float\n"));
16255 break;
16256 case 1:
16257 printf (_("hard float\n"));
16258 break;
16259 case 2:
16260 printf (_("soft float\n"));
16261 break;
16262 }
16263 return p;
16264 }
16265
16266 return display_tag_value (tag & 1, p, end);
16267}
16268
34c8bcba 16269static unsigned char *
f6f0e17b 16270display_power_gnu_attribute (unsigned char * p,
60abdbed 16271 unsigned int tag,
f6f0e17b 16272 const unsigned char * const end)
34c8bcba 16273{
005d79fd 16274 unsigned int val;
34c8bcba
JM
16275
16276 if (tag == Tag_GNU_Power_ABI_FP)
16277 {
34c8bcba 16278 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16279 if (p == end)
005d79fd
AM
16280 {
16281 printf (_("<corrupt>\n"));
16282 return p;
16283 }
cd30bcef 16284 READ_ULEB (val, p, end);
60bca95a 16285
005d79fd
AM
16286 if (val > 15)
16287 printf ("(%#x), ", val);
16288
16289 switch (val & 3)
34c8bcba
JM
16290 {
16291 case 0:
005d79fd 16292 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16293 break;
16294 case 1:
005d79fd 16295 printf (_("hard float, "));
34c8bcba
JM
16296 break;
16297 case 2:
005d79fd 16298 printf (_("soft float, "));
34c8bcba 16299 break;
3c7b9897 16300 case 3:
005d79fd 16301 printf (_("single-precision hard float, "));
3c7b9897 16302 break;
005d79fd
AM
16303 }
16304
16305 switch (val & 0xC)
16306 {
16307 case 0:
16308 printf (_("unspecified long double\n"));
16309 break;
16310 case 4:
16311 printf (_("128-bit IBM long double\n"));
16312 break;
16313 case 8:
16314 printf (_("64-bit long double\n"));
16315 break;
16316 case 12:
16317 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16318 break;
16319 }
16320 return p;
005d79fd 16321 }
34c8bcba 16322
c6e65352
DJ
16323 if (tag == Tag_GNU_Power_ABI_Vector)
16324 {
c6e65352 16325 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 16326 if (p == end)
005d79fd
AM
16327 {
16328 printf (_("<corrupt>\n"));
16329 return p;
16330 }
cd30bcef 16331 READ_ULEB (val, p, end);
005d79fd
AM
16332
16333 if (val > 3)
16334 printf ("(%#x), ", val);
16335
16336 switch (val & 3)
c6e65352
DJ
16337 {
16338 case 0:
005d79fd 16339 printf (_("unspecified\n"));
c6e65352
DJ
16340 break;
16341 case 1:
005d79fd 16342 printf (_("generic\n"));
c6e65352
DJ
16343 break;
16344 case 2:
16345 printf ("AltiVec\n");
16346 break;
16347 case 3:
16348 printf ("SPE\n");
16349 break;
c6e65352
DJ
16350 }
16351 return p;
005d79fd 16352 }
c6e65352 16353
f82e0623
NF
16354 if (tag == Tag_GNU_Power_ABI_Struct_Return)
16355 {
005d79fd 16356 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 16357 if (p == end)
f6f0e17b 16358 {
005d79fd 16359 printf (_("<corrupt>\n"));
f6f0e17b
NC
16360 return p;
16361 }
cd30bcef 16362 READ_ULEB (val, p, end);
0b4362b0 16363
005d79fd
AM
16364 if (val > 2)
16365 printf ("(%#x), ", val);
16366
16367 switch (val & 3)
16368 {
16369 case 0:
16370 printf (_("unspecified\n"));
16371 break;
16372 case 1:
16373 printf ("r3/r4\n");
16374 break;
16375 case 2:
16376 printf (_("memory\n"));
16377 break;
16378 case 3:
16379 printf ("???\n");
16380 break;
16381 }
f82e0623
NF
16382 return p;
16383 }
16384
f6f0e17b 16385 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
16386}
16387
643f7afb
AK
16388static unsigned char *
16389display_s390_gnu_attribute (unsigned char * p,
60abdbed 16390 unsigned int tag,
643f7afb
AK
16391 const unsigned char * const end)
16392{
cd30bcef 16393 unsigned int val;
643f7afb
AK
16394
16395 if (tag == Tag_GNU_S390_ABI_Vector)
16396 {
643f7afb 16397 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 16398 READ_ULEB (val, p, end);
643f7afb
AK
16399
16400 switch (val)
16401 {
16402 case 0:
16403 printf (_("any\n"));
16404 break;
16405 case 1:
16406 printf (_("software\n"));
16407 break;
16408 case 2:
16409 printf (_("hardware\n"));
16410 break;
16411 default:
16412 printf ("??? (%d)\n", val);
16413 break;
16414 }
16415 return p;
16416 }
16417
16418 return display_tag_value (tag & 1, p, end);
16419}
16420
9e8c70f9 16421static void
60abdbed 16422display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
16423{
16424 if (mask)
16425 {
015dc7e1 16426 bool first = true;
071436c6 16427
9e8c70f9 16428 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 16429 fputs ("mul32", stdout), first = false;
9e8c70f9 16430 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 16431 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 16432 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 16433 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 16434 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 16435 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 16436 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 16437 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 16438 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 16439 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 16440 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 16441 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 16442 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 16443 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 16444 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 16445 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 16446 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 16447 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 16448 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 16449 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 16450 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 16451 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 16452 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 16453 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 16454 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 16455 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 16456 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 16457 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 16458 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 16459 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
16460 }
16461 else
071436c6
NC
16462 fputc ('0', stdout);
16463 fputc ('\n', stdout);
9e8c70f9
DM
16464}
16465
3d68f91c 16466static void
60abdbed 16467display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
16468{
16469 if (mask)
16470 {
015dc7e1 16471 bool first = true;
071436c6 16472
3d68f91c 16473 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 16474 fputs ("fjathplus", stdout), first = false;
3d68f91c 16475 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 16476 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 16477 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 16478 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 16479 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 16480 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 16481 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 16482 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 16483 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 16484 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 16485 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 16486 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 16487 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 16488 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 16489 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 16490 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 16491 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 16492 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 16493 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 16494 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
16495 }
16496 else
071436c6
NC
16497 fputc ('0', stdout);
16498 fputc ('\n', stdout);
3d68f91c
JM
16499}
16500
9e8c70f9 16501static unsigned char *
f6f0e17b 16502display_sparc_gnu_attribute (unsigned char * p,
60abdbed 16503 unsigned int tag,
f6f0e17b 16504 const unsigned char * const end)
9e8c70f9 16505{
cd30bcef 16506 unsigned int val;
3d68f91c 16507
9e8c70f9
DM
16508 if (tag == Tag_GNU_Sparc_HWCAPS)
16509 {
cd30bcef 16510 READ_ULEB (val, p, end);
9e8c70f9 16511 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
16512 display_sparc_hwcaps (val);
16513 return p;
3d68f91c
JM
16514 }
16515 if (tag == Tag_GNU_Sparc_HWCAPS2)
16516 {
cd30bcef 16517 READ_ULEB (val, p, end);
3d68f91c
JM
16518 printf (" Tag_GNU_Sparc_HWCAPS2: ");
16519 display_sparc_hwcaps2 (val);
16520 return p;
16521 }
9e8c70f9 16522
f6f0e17b 16523 return display_tag_value (tag, p, end);
9e8c70f9
DM
16524}
16525
351cdf24 16526static void
32ec8896 16527print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
16528{
16529 switch (val)
16530 {
16531 case Val_GNU_MIPS_ABI_FP_ANY:
16532 printf (_("Hard or soft float\n"));
16533 break;
16534 case Val_GNU_MIPS_ABI_FP_DOUBLE:
16535 printf (_("Hard float (double precision)\n"));
16536 break;
16537 case Val_GNU_MIPS_ABI_FP_SINGLE:
16538 printf (_("Hard float (single precision)\n"));
16539 break;
16540 case Val_GNU_MIPS_ABI_FP_SOFT:
16541 printf (_("Soft float\n"));
16542 break;
16543 case Val_GNU_MIPS_ABI_FP_OLD_64:
16544 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
16545 break;
16546 case Val_GNU_MIPS_ABI_FP_XX:
16547 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
16548 break;
16549 case Val_GNU_MIPS_ABI_FP_64:
16550 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
16551 break;
16552 case Val_GNU_MIPS_ABI_FP_64A:
16553 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
16554 break;
3350cc01
CM
16555 case Val_GNU_MIPS_ABI_FP_NAN2008:
16556 printf (_("NaN 2008 compatibility\n"));
16557 break;
351cdf24
MF
16558 default:
16559 printf ("??? (%d)\n", val);
16560 break;
16561 }
16562}
16563
2cf19d5c 16564static unsigned char *
f6f0e17b 16565display_mips_gnu_attribute (unsigned char * p,
60abdbed 16566 unsigned int tag,
f6f0e17b 16567 const unsigned char * const end)
2cf19d5c 16568{
2cf19d5c
JM
16569 if (tag == Tag_GNU_MIPS_ABI_FP)
16570 {
32ec8896 16571 unsigned int val;
f6f0e17b 16572
2cf19d5c 16573 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 16574 READ_ULEB (val, p, end);
351cdf24 16575 print_mips_fp_abi_value (val);
2cf19d5c
JM
16576 return p;
16577 }
16578
a9f58168
CF
16579 if (tag == Tag_GNU_MIPS_ABI_MSA)
16580 {
32ec8896 16581 unsigned int val;
a9f58168 16582
a9f58168 16583 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 16584 READ_ULEB (val, p, end);
a9f58168
CF
16585
16586 switch (val)
16587 {
16588 case Val_GNU_MIPS_ABI_MSA_ANY:
16589 printf (_("Any MSA or not\n"));
16590 break;
16591 case Val_GNU_MIPS_ABI_MSA_128:
16592 printf (_("128-bit MSA\n"));
16593 break;
16594 default:
16595 printf ("??? (%d)\n", val);
16596 break;
16597 }
16598 return p;
16599 }
16600
f6f0e17b 16601 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
16602}
16603
59e6276b 16604static unsigned char *
f6f0e17b
NC
16605display_tic6x_attribute (unsigned char * p,
16606 const unsigned char * const end)
59e6276b 16607{
60abdbed 16608 unsigned int tag;
cd30bcef 16609 unsigned int val;
59e6276b 16610
cd30bcef 16611 READ_ULEB (tag, p, end);
59e6276b
JM
16612
16613 switch (tag)
16614 {
75fa6dc1 16615 case Tag_ISA:
75fa6dc1 16616 printf (" Tag_ISA: ");
cd30bcef 16617 READ_ULEB (val, p, end);
59e6276b
JM
16618
16619 switch (val)
16620 {
75fa6dc1 16621 case C6XABI_Tag_ISA_none:
59e6276b
JM
16622 printf (_("None\n"));
16623 break;
75fa6dc1 16624 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
16625 printf ("C62x\n");
16626 break;
75fa6dc1 16627 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
16628 printf ("C67x\n");
16629 break;
75fa6dc1 16630 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
16631 printf ("C67x+\n");
16632 break;
75fa6dc1 16633 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
16634 printf ("C64x\n");
16635 break;
75fa6dc1 16636 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
16637 printf ("C64x+\n");
16638 break;
75fa6dc1 16639 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
16640 printf ("C674x\n");
16641 break;
16642 default:
16643 printf ("??? (%d)\n", val);
16644 break;
16645 }
16646 return p;
16647
87779176 16648 case Tag_ABI_wchar_t:
87779176 16649 printf (" Tag_ABI_wchar_t: ");
cd30bcef 16650 READ_ULEB (val, p, end);
87779176
JM
16651 switch (val)
16652 {
16653 case 0:
16654 printf (_("Not used\n"));
16655 break;
16656 case 1:
16657 printf (_("2 bytes\n"));
16658 break;
16659 case 2:
16660 printf (_("4 bytes\n"));
16661 break;
16662 default:
16663 printf ("??? (%d)\n", val);
16664 break;
16665 }
16666 return p;
16667
16668 case Tag_ABI_stack_align_needed:
87779176 16669 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 16670 READ_ULEB (val, p, end);
87779176
JM
16671 switch (val)
16672 {
16673 case 0:
16674 printf (_("8-byte\n"));
16675 break;
16676 case 1:
16677 printf (_("16-byte\n"));
16678 break;
16679 default:
16680 printf ("??? (%d)\n", val);
16681 break;
16682 }
16683 return p;
16684
16685 case Tag_ABI_stack_align_preserved:
cd30bcef 16686 READ_ULEB (val, p, end);
87779176
JM
16687 printf (" Tag_ABI_stack_align_preserved: ");
16688 switch (val)
16689 {
16690 case 0:
16691 printf (_("8-byte\n"));
16692 break;
16693 case 1:
16694 printf (_("16-byte\n"));
16695 break;
16696 default:
16697 printf ("??? (%d)\n", val);
16698 break;
16699 }
16700 return p;
16701
b5593623 16702 case Tag_ABI_DSBT:
cd30bcef 16703 READ_ULEB (val, p, end);
b5593623
JM
16704 printf (" Tag_ABI_DSBT: ");
16705 switch (val)
16706 {
16707 case 0:
16708 printf (_("DSBT addressing not used\n"));
16709 break;
16710 case 1:
16711 printf (_("DSBT addressing used\n"));
16712 break;
16713 default:
16714 printf ("??? (%d)\n", val);
16715 break;
16716 }
16717 return p;
16718
87779176 16719 case Tag_ABI_PID:
cd30bcef 16720 READ_ULEB (val, p, end);
87779176
JM
16721 printf (" Tag_ABI_PID: ");
16722 switch (val)
16723 {
16724 case 0:
16725 printf (_("Data addressing position-dependent\n"));
16726 break;
16727 case 1:
16728 printf (_("Data addressing position-independent, GOT near DP\n"));
16729 break;
16730 case 2:
16731 printf (_("Data addressing position-independent, GOT far from DP\n"));
16732 break;
16733 default:
16734 printf ("??? (%d)\n", val);
16735 break;
16736 }
16737 return p;
16738
16739 case Tag_ABI_PIC:
cd30bcef 16740 READ_ULEB (val, p, end);
87779176
JM
16741 printf (" Tag_ABI_PIC: ");
16742 switch (val)
16743 {
16744 case 0:
16745 printf (_("Code addressing position-dependent\n"));
16746 break;
16747 case 1:
16748 printf (_("Code addressing position-independent\n"));
16749 break;
16750 default:
16751 printf ("??? (%d)\n", val);
16752 break;
16753 }
16754 return p;
16755
16756 case Tag_ABI_array_object_alignment:
cd30bcef 16757 READ_ULEB (val, p, end);
87779176
JM
16758 printf (" Tag_ABI_array_object_alignment: ");
16759 switch (val)
16760 {
16761 case 0:
16762 printf (_("8-byte\n"));
16763 break;
16764 case 1:
16765 printf (_("4-byte\n"));
16766 break;
16767 case 2:
16768 printf (_("16-byte\n"));
16769 break;
16770 default:
16771 printf ("??? (%d)\n", val);
16772 break;
16773 }
16774 return p;
16775
16776 case Tag_ABI_array_object_align_expected:
cd30bcef 16777 READ_ULEB (val, p, end);
87779176
JM
16778 printf (" Tag_ABI_array_object_align_expected: ");
16779 switch (val)
16780 {
16781 case 0:
16782 printf (_("8-byte\n"));
16783 break;
16784 case 1:
16785 printf (_("4-byte\n"));
16786 break;
16787 case 2:
16788 printf (_("16-byte\n"));
16789 break;
16790 default:
16791 printf ("??? (%d)\n", val);
16792 break;
16793 }
16794 return p;
16795
3cbd1c06 16796 case Tag_ABI_compatibility:
071436c6 16797 {
cd30bcef 16798 READ_ULEB (val, p, end);
071436c6 16799 printf (" Tag_ABI_compatibility: ");
071436c6 16800 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16801 if (p < end - 1)
16802 {
16803 size_t maxlen = (end - p) - 1;
16804
16805 print_symbol ((int) maxlen, (const char *) p);
16806 p += strnlen ((char *) p, maxlen) + 1;
16807 }
16808 else
16809 {
16810 printf (_("<corrupt>"));
16811 p = (unsigned char *) end;
16812 }
071436c6 16813 putchar ('\n');
071436c6
NC
16814 return p;
16815 }
87779176
JM
16816
16817 case Tag_ABI_conformance:
071436c6 16818 {
4082ef84
NC
16819 printf (" Tag_ABI_conformance: \"");
16820 if (p < end - 1)
16821 {
16822 size_t maxlen = (end - p) - 1;
071436c6 16823
4082ef84
NC
16824 print_symbol ((int) maxlen, (const char *) p);
16825 p += strnlen ((char *) p, maxlen) + 1;
16826 }
16827 else
16828 {
16829 printf (_("<corrupt>"));
16830 p = (unsigned char *) end;
16831 }
071436c6 16832 printf ("\"\n");
071436c6
NC
16833 return p;
16834 }
59e6276b
JM
16835 }
16836
f6f0e17b
NC
16837 return display_tag_value (tag, p, end);
16838}
59e6276b 16839
f6f0e17b 16840static void
60abdbed 16841display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
16842{
16843 unsigned long addr = 0;
16844 size_t bytes = end - p;
16845
feceaa59 16846 assert (end >= p);
f6f0e17b 16847 while (bytes)
87779176 16848 {
f6f0e17b
NC
16849 int j;
16850 int k;
16851 int lbytes = (bytes > 16 ? 16 : bytes);
16852
16853 printf (" 0x%8.8lx ", addr);
16854
16855 for (j = 0; j < 16; j++)
16856 {
16857 if (j < lbytes)
16858 printf ("%2.2x", p[j]);
16859 else
16860 printf (" ");
16861
16862 if ((j & 3) == 3)
16863 printf (" ");
16864 }
16865
16866 for (j = 0; j < lbytes; j++)
16867 {
16868 k = p[j];
16869 if (k >= ' ' && k < 0x7f)
16870 printf ("%c", k);
16871 else
16872 printf (".");
16873 }
16874
16875 putchar ('\n');
16876
16877 p += lbytes;
16878 bytes -= lbytes;
16879 addr += lbytes;
87779176 16880 }
59e6276b 16881
f6f0e17b 16882 putchar ('\n');
59e6276b
JM
16883}
16884
13761a11 16885static unsigned char *
b0191216 16886display_msp430_attribute (unsigned char * p,
13761a11
NC
16887 const unsigned char * const end)
16888{
60abdbed
NC
16889 unsigned int val;
16890 unsigned int tag;
13761a11 16891
cd30bcef 16892 READ_ULEB (tag, p, end);
0b4362b0 16893
13761a11
NC
16894 switch (tag)
16895 {
16896 case OFBA_MSPABI_Tag_ISA:
13761a11 16897 printf (" Tag_ISA: ");
cd30bcef 16898 READ_ULEB (val, p, end);
13761a11
NC
16899 switch (val)
16900 {
16901 case 0: printf (_("None\n")); break;
16902 case 1: printf (_("MSP430\n")); break;
16903 case 2: printf (_("MSP430X\n")); break;
16904 default: printf ("??? (%d)\n", val); break;
16905 }
16906 break;
16907
16908 case OFBA_MSPABI_Tag_Code_Model:
13761a11 16909 printf (" Tag_Code_Model: ");
cd30bcef 16910 READ_ULEB (val, p, end);
13761a11
NC
16911 switch (val)
16912 {
16913 case 0: printf (_("None\n")); break;
16914 case 1: printf (_("Small\n")); break;
16915 case 2: printf (_("Large\n")); break;
16916 default: printf ("??? (%d)\n", val); break;
16917 }
16918 break;
16919
16920 case OFBA_MSPABI_Tag_Data_Model:
13761a11 16921 printf (" Tag_Data_Model: ");
cd30bcef 16922 READ_ULEB (val, p, end);
13761a11
NC
16923 switch (val)
16924 {
16925 case 0: printf (_("None\n")); break;
16926 case 1: printf (_("Small\n")); break;
16927 case 2: printf (_("Large\n")); break;
16928 case 3: printf (_("Restricted Large\n")); break;
16929 default: printf ("??? (%d)\n", val); break;
16930 }
16931 break;
16932
16933 default:
16934 printf (_(" <unknown tag %d>: "), tag);
16935
16936 if (tag & 1)
16937 {
071436c6 16938 putchar ('"');
4082ef84
NC
16939 if (p < end - 1)
16940 {
16941 size_t maxlen = (end - p) - 1;
16942
16943 print_symbol ((int) maxlen, (const char *) p);
16944 p += strnlen ((char *) p, maxlen) + 1;
16945 }
16946 else
16947 {
16948 printf (_("<corrupt>"));
16949 p = (unsigned char *) end;
16950 }
071436c6 16951 printf ("\"\n");
13761a11
NC
16952 }
16953 else
16954 {
cd30bcef 16955 READ_ULEB (val, p, end);
13761a11
NC
16956 printf ("%d (0x%x)\n", val, val);
16957 }
16958 break;
16959 }
16960
4082ef84 16961 assert (p <= end);
13761a11
NC
16962 return p;
16963}
16964
c0ea7c52
JL
16965static unsigned char *
16966display_msp430_gnu_attribute (unsigned char * p,
16967 unsigned int tag,
16968 const unsigned char * const end)
16969{
16970 if (tag == Tag_GNU_MSP430_Data_Region)
16971 {
cd30bcef 16972 unsigned int val;
c0ea7c52 16973
c0ea7c52 16974 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 16975 READ_ULEB (val, p, end);
c0ea7c52
JL
16976
16977 switch (val)
16978 {
16979 case Val_GNU_MSP430_Data_Region_Any:
16980 printf (_("Any Region\n"));
16981 break;
16982 case Val_GNU_MSP430_Data_Region_Lower:
16983 printf (_("Lower Region Only\n"));
16984 break;
16985 default:
cd30bcef 16986 printf ("??? (%u)\n", val);
c0ea7c52
JL
16987 }
16988 return p;
16989 }
16990 return display_tag_value (tag & 1, p, end);
16991}
16992
2dc8dd17
JW
16993struct riscv_attr_tag_t {
16994 const char *name;
cd30bcef 16995 unsigned int tag;
2dc8dd17
JW
16996};
16997
16998static struct riscv_attr_tag_t riscv_attr_tag[] =
16999{
17000#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17001 T(arch),
17002 T(priv_spec),
17003 T(priv_spec_minor),
17004 T(priv_spec_revision),
17005 T(unaligned_access),
17006 T(stack_align),
17007#undef T
17008};
17009
17010static unsigned char *
17011display_riscv_attribute (unsigned char *p,
17012 const unsigned char * const end)
17013{
cd30bcef
AM
17014 unsigned int val;
17015 unsigned int tag;
2dc8dd17
JW
17016 struct riscv_attr_tag_t *attr = NULL;
17017 unsigned i;
17018
cd30bcef 17019 READ_ULEB (tag, p, end);
2dc8dd17
JW
17020
17021 /* Find the name of attribute. */
17022 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17023 {
17024 if (riscv_attr_tag[i].tag == tag)
17025 {
17026 attr = &riscv_attr_tag[i];
17027 break;
17028 }
17029 }
17030
17031 if (attr)
17032 printf (" %s: ", attr->name);
17033 else
17034 return display_tag_value (tag, p, end);
17035
17036 switch (tag)
17037 {
17038 case Tag_RISCV_priv_spec:
17039 case Tag_RISCV_priv_spec_minor:
17040 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17041 READ_ULEB (val, p, end);
17042 printf (_("%u\n"), val);
2dc8dd17
JW
17043 break;
17044 case Tag_RISCV_unaligned_access:
cd30bcef 17045 READ_ULEB (val, p, end);
2dc8dd17
JW
17046 switch (val)
17047 {
17048 case 0:
17049 printf (_("No unaligned access\n"));
17050 break;
17051 case 1:
17052 printf (_("Unaligned access\n"));
17053 break;
17054 }
17055 break;
17056 case Tag_RISCV_stack_align:
cd30bcef
AM
17057 READ_ULEB (val, p, end);
17058 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17059 break;
17060 case Tag_RISCV_arch:
17061 p = display_tag_value (-1, p, end);
17062 break;
17063 default:
17064 return display_tag_value (tag, p, end);
17065 }
17066
17067 return p;
17068}
17069
0861f561
CQ
17070static unsigned char *
17071display_csky_attribute (unsigned char * p,
17072 const unsigned char * const end)
17073{
17074 unsigned int tag;
17075 unsigned int val;
17076 READ_ULEB (tag, p, end);
17077
17078 if (tag >= Tag_CSKY_MAX)
17079 {
17080 return display_tag_value (-1, p, end);
17081 }
17082
17083 switch (tag)
17084 {
17085 case Tag_CSKY_ARCH_NAME:
17086 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17087 return display_tag_value (-1, p, end);
17088 case Tag_CSKY_CPU_NAME:
17089 printf (" Tag_CSKY_CPU_NAME:\t\t");
17090 return display_tag_value (-1, p, end);
17091
17092 case Tag_CSKY_ISA_FLAGS:
17093 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17094 return display_tag_value (0, p, end);
17095 case Tag_CSKY_ISA_EXT_FLAGS:
17096 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17097 return display_tag_value (0, p, end);
17098
17099 case Tag_CSKY_DSP_VERSION:
17100 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17101 READ_ULEB (val, p, end);
17102 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17103 printf ("DSP Extension\n");
17104 else if (val == VAL_CSKY_DSP_VERSION_2)
17105 printf ("DSP 2.0\n");
17106 break;
17107
17108 case Tag_CSKY_VDSP_VERSION:
17109 printf (" Tag_CSKY_VDSP_VERSION:\t");
17110 READ_ULEB (val, p, end);
17111 printf ("VDSP Version %d\n", val);
17112 break;
17113
17114 case Tag_CSKY_FPU_VERSION:
17115 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17116 READ_ULEB (val, p, end);
17117 if (val == VAL_CSKY_FPU_VERSION_1)
17118 printf ("ABIV1 FPU Version 1\n");
17119 else if (val == VAL_CSKY_FPU_VERSION_2)
17120 printf ("FPU Version 2\n");
17121 break;
17122
17123 case Tag_CSKY_FPU_ABI:
17124 printf (" Tag_CSKY_FPU_ABI:\t\t");
17125 READ_ULEB (val, p, end);
17126 if (val == VAL_CSKY_FPU_ABI_HARD)
17127 printf ("Hard\n");
17128 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17129 printf ("SoftFP\n");
17130 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17131 printf ("Soft\n");
17132 break;
17133 case Tag_CSKY_FPU_ROUNDING:
17134 READ_ULEB (val, p, end);
17135 if (val == 1) {
17136 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17137 printf ("Needed\n");
17138 }
17139 break;
17140 case Tag_CSKY_FPU_DENORMAL:
17141 READ_ULEB (val, p, end);
17142 if (val == 1) {
17143 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17144 printf ("Needed\n");
17145 }
17146 break;
17147 case Tag_CSKY_FPU_Exception:
17148 READ_ULEB (val, p, end);
17149 if (val == 1) {
17150 printf (" Tag_CSKY_FPU_Exception:\t");
17151 printf ("Needed\n");
17152 }
17153 break;
17154 case Tag_CSKY_FPU_NUMBER_MODULE:
17155 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17156 return display_tag_value (-1, p, end);
17157 case Tag_CSKY_FPU_HARDFP:
17158 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17159 READ_ULEB (val, p, end);
17160 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17161 printf (" Half");
17162 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17163 printf (" Single");
17164 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17165 printf (" Double");
17166 printf ("\n");
17167 break;
17168 default:
17169 return display_tag_value (tag, p, end);
17170 }
17171 return p;
17172}
17173
015dc7e1 17174static bool
dda8d76d 17175process_attributes (Filedata * filedata,
60bca95a 17176 const char * public_name,
104d59d1 17177 unsigned int proc_type,
f6f0e17b 17178 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17179 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17180{
2cf0635d 17181 Elf_Internal_Shdr * sect;
11c1ff18 17182 unsigned i;
015dc7e1 17183 bool res = true;
11c1ff18
PB
17184
17185 /* Find the section header so that we get the size. */
dda8d76d
NC
17186 for (i = 0, sect = filedata->section_headers;
17187 i < filedata->file_header.e_shnum;
11c1ff18
PB
17188 i++, sect++)
17189 {
071436c6
NC
17190 unsigned char * contents;
17191 unsigned char * p;
17192
104d59d1 17193 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17194 continue;
17195
dda8d76d 17196 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17197 sect->sh_size, _("attributes"));
60bca95a 17198 if (contents == NULL)
32ec8896 17199 {
015dc7e1 17200 res = false;
32ec8896
NC
17201 continue;
17202 }
60bca95a 17203
11c1ff18 17204 p = contents;
60abdbed
NC
17205 /* The first character is the version of the attributes.
17206 Currently only version 1, (aka 'A') is recognised here. */
17207 if (*p != 'A')
32ec8896
NC
17208 {
17209 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17210 res = false;
32ec8896 17211 }
60abdbed 17212 else
11c1ff18 17213 {
071436c6
NC
17214 bfd_vma section_len;
17215
17216 section_len = sect->sh_size - 1;
11c1ff18 17217 p++;
60bca95a 17218
071436c6 17219 while (section_len > 0)
11c1ff18 17220 {
071436c6 17221 bfd_vma attr_len;
e9847026 17222 unsigned int namelen;
015dc7e1
AM
17223 bool public_section;
17224 bool gnu_section;
11c1ff18 17225
071436c6 17226 if (section_len <= 4)
e0a31db1
NC
17227 {
17228 error (_("Tag section ends prematurely\n"));
015dc7e1 17229 res = false;
e0a31db1
NC
17230 break;
17231 }
071436c6 17232 attr_len = byte_get (p, 4);
11c1ff18 17233 p += 4;
60bca95a 17234
071436c6 17235 if (attr_len > section_len)
11c1ff18 17236 {
071436c6
NC
17237 error (_("Bad attribute length (%u > %u)\n"),
17238 (unsigned) attr_len, (unsigned) section_len);
17239 attr_len = section_len;
015dc7e1 17240 res = false;
11c1ff18 17241 }
74e1a04b 17242 /* PR 17531: file: 001-101425-0.004 */
071436c6 17243 else if (attr_len < 5)
74e1a04b 17244 {
071436c6 17245 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17246 res = false;
74e1a04b
NC
17247 break;
17248 }
e9847026 17249
071436c6
NC
17250 section_len -= attr_len;
17251 attr_len -= 4;
17252
17253 namelen = strnlen ((char *) p, attr_len) + 1;
17254 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17255 {
17256 error (_("Corrupt attribute section name\n"));
015dc7e1 17257 res = false;
e9847026
NC
17258 break;
17259 }
17260
071436c6
NC
17261 printf (_("Attribute Section: "));
17262 print_symbol (INT_MAX, (const char *) p);
17263 putchar ('\n');
60bca95a
NC
17264
17265 if (public_name && streq ((char *) p, public_name))
015dc7e1 17266 public_section = true;
11c1ff18 17267 else
015dc7e1 17268 public_section = false;
60bca95a
NC
17269
17270 if (streq ((char *) p, "gnu"))
015dc7e1 17271 gnu_section = true;
104d59d1 17272 else
015dc7e1 17273 gnu_section = false;
60bca95a 17274
11c1ff18 17275 p += namelen;
071436c6 17276 attr_len -= namelen;
e0a31db1 17277
071436c6 17278 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17279 {
e0a31db1 17280 int tag;
cd30bcef 17281 unsigned int val;
11c1ff18 17282 bfd_vma size;
071436c6 17283 unsigned char * end;
60bca95a 17284
e0a31db1 17285 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17286 if (attr_len < 6)
e0a31db1
NC
17287 {
17288 error (_("Unused bytes at end of section\n"));
015dc7e1 17289 res = false;
e0a31db1
NC
17290 section_len = 0;
17291 break;
17292 }
17293
17294 tag = *(p++);
11c1ff18 17295 size = byte_get (p, 4);
071436c6 17296 if (size > attr_len)
11c1ff18 17297 {
e9847026 17298 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17299 (unsigned) size, (unsigned) attr_len);
015dc7e1 17300 res = false;
071436c6 17301 size = attr_len;
11c1ff18 17302 }
e0a31db1
NC
17303 /* PR binutils/17531: Safe handling of corrupt files. */
17304 if (size < 6)
17305 {
17306 error (_("Bad subsection length (%u < 6)\n"),
17307 (unsigned) size);
015dc7e1 17308 res = false;
e0a31db1
NC
17309 section_len = 0;
17310 break;
17311 }
60bca95a 17312
071436c6 17313 attr_len -= size;
11c1ff18 17314 end = p + size - 1;
071436c6 17315 assert (end <= contents + sect->sh_size);
11c1ff18 17316 p += 4;
60bca95a 17317
11c1ff18
PB
17318 switch (tag)
17319 {
17320 case 1:
2b692964 17321 printf (_("File Attributes\n"));
11c1ff18
PB
17322 break;
17323 case 2:
2b692964 17324 printf (_("Section Attributes:"));
11c1ff18
PB
17325 goto do_numlist;
17326 case 3:
2b692964 17327 printf (_("Symbol Attributes:"));
1a0670f3 17328 /* Fall through. */
11c1ff18
PB
17329 do_numlist:
17330 for (;;)
17331 {
cd30bcef 17332 READ_ULEB (val, p, end);
11c1ff18
PB
17333 if (val == 0)
17334 break;
17335 printf (" %d", val);
17336 }
17337 printf ("\n");
17338 break;
17339 default:
2b692964 17340 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 17341 public_section = false;
11c1ff18
PB
17342 break;
17343 }
60bca95a 17344
071436c6 17345 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
17346 {
17347 while (p < end)
f6f0e17b 17348 p = display_pub_attribute (p, end);
60abdbed 17349 assert (p == end);
104d59d1 17350 }
071436c6 17351 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
17352 {
17353 while (p < end)
17354 p = display_gnu_attribute (p,
f6f0e17b
NC
17355 display_proc_gnu_attribute,
17356 end);
60abdbed 17357 assert (p == end);
11c1ff18 17358 }
071436c6 17359 else if (p < end)
11c1ff18 17360 {
071436c6 17361 printf (_(" Unknown attribute:\n"));
f6f0e17b 17362 display_raw_attribute (p, end);
11c1ff18
PB
17363 p = end;
17364 }
071436c6
NC
17365 else
17366 attr_len = 0;
11c1ff18
PB
17367 }
17368 }
17369 }
d70c5fc7 17370
60bca95a 17371 free (contents);
11c1ff18 17372 }
32ec8896
NC
17373
17374 return res;
11c1ff18
PB
17375}
17376
ccb4c951
RS
17377/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
17378 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
17379 and return the VMA of the next entry, or -1 if there was a problem.
17380 Does not read from DATA_END or beyond. */
ccb4c951
RS
17381
17382static bfd_vma
82b1b41b
NC
17383print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
17384 unsigned char * data_end)
ccb4c951
RS
17385{
17386 printf (" ");
17387 print_vma (addr, LONG_HEX);
17388 printf (" ");
17389 if (addr < pltgot + 0xfff0)
17390 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
17391 else
17392 printf ("%10s", "");
17393 printf (" ");
17394 if (data == NULL)
2b692964 17395 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
17396 else
17397 {
17398 bfd_vma entry;
82b1b41b 17399 unsigned char * from = data + addr - pltgot;
ccb4c951 17400
82b1b41b
NC
17401 if (from + (is_32bit_elf ? 4 : 8) > data_end)
17402 {
17403 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
17404 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
17405 return (bfd_vma) -1;
17406 }
17407 else
17408 {
17409 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17410 print_vma (entry, LONG_HEX);
17411 }
ccb4c951
RS
17412 }
17413 return addr + (is_32bit_elf ? 4 : 8);
17414}
17415
861fb55a
DJ
17416/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
17417 PLTGOT. Print the Address and Initial fields of an entry at VMA
17418 ADDR and return the VMA of the next entry. */
17419
17420static bfd_vma
2cf0635d 17421print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
17422{
17423 printf (" ");
17424 print_vma (addr, LONG_HEX);
17425 printf (" ");
17426 if (data == NULL)
2b692964 17427 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
17428 else
17429 {
17430 bfd_vma entry;
17431
17432 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17433 print_vma (entry, LONG_HEX);
17434 }
17435 return addr + (is_32bit_elf ? 4 : 8);
17436}
17437
351cdf24
MF
17438static void
17439print_mips_ases (unsigned int mask)
17440{
17441 if (mask & AFL_ASE_DSP)
17442 fputs ("\n\tDSP ASE", stdout);
17443 if (mask & AFL_ASE_DSPR2)
17444 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
17445 if (mask & AFL_ASE_DSPR3)
17446 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
17447 if (mask & AFL_ASE_EVA)
17448 fputs ("\n\tEnhanced VA Scheme", stdout);
17449 if (mask & AFL_ASE_MCU)
17450 fputs ("\n\tMCU (MicroController) ASE", stdout);
17451 if (mask & AFL_ASE_MDMX)
17452 fputs ("\n\tMDMX ASE", stdout);
17453 if (mask & AFL_ASE_MIPS3D)
17454 fputs ("\n\tMIPS-3D ASE", stdout);
17455 if (mask & AFL_ASE_MT)
17456 fputs ("\n\tMT ASE", stdout);
17457 if (mask & AFL_ASE_SMARTMIPS)
17458 fputs ("\n\tSmartMIPS ASE", stdout);
17459 if (mask & AFL_ASE_VIRT)
17460 fputs ("\n\tVZ ASE", stdout);
17461 if (mask & AFL_ASE_MSA)
17462 fputs ("\n\tMSA ASE", stdout);
17463 if (mask & AFL_ASE_MIPS16)
17464 fputs ("\n\tMIPS16 ASE", stdout);
17465 if (mask & AFL_ASE_MICROMIPS)
17466 fputs ("\n\tMICROMIPS ASE", stdout);
17467 if (mask & AFL_ASE_XPA)
17468 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
17469 if (mask & AFL_ASE_MIPS16E2)
17470 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
17471 if (mask & AFL_ASE_CRC)
17472 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
17473 if (mask & AFL_ASE_GINV)
17474 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
17475 if (mask & AFL_ASE_LOONGSON_MMI)
17476 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
17477 if (mask & AFL_ASE_LOONGSON_CAM)
17478 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
17479 if (mask & AFL_ASE_LOONGSON_EXT)
17480 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
17481 if (mask & AFL_ASE_LOONGSON_EXT2)
17482 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
17483 if (mask == 0)
17484 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
17485 else if ((mask & ~AFL_ASE_MASK) != 0)
17486 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
17487}
17488
17489static void
17490print_mips_isa_ext (unsigned int isa_ext)
17491{
17492 switch (isa_ext)
17493 {
17494 case 0:
17495 fputs (_("None"), stdout);
17496 break;
17497 case AFL_EXT_XLR:
17498 fputs ("RMI XLR", stdout);
17499 break;
2c629856
N
17500 case AFL_EXT_OCTEON3:
17501 fputs ("Cavium Networks Octeon3", stdout);
17502 break;
351cdf24
MF
17503 case AFL_EXT_OCTEON2:
17504 fputs ("Cavium Networks Octeon2", stdout);
17505 break;
17506 case AFL_EXT_OCTEONP:
17507 fputs ("Cavium Networks OcteonP", stdout);
17508 break;
351cdf24
MF
17509 case AFL_EXT_OCTEON:
17510 fputs ("Cavium Networks Octeon", stdout);
17511 break;
17512 case AFL_EXT_5900:
17513 fputs ("Toshiba R5900", stdout);
17514 break;
17515 case AFL_EXT_4650:
17516 fputs ("MIPS R4650", stdout);
17517 break;
17518 case AFL_EXT_4010:
17519 fputs ("LSI R4010", stdout);
17520 break;
17521 case AFL_EXT_4100:
17522 fputs ("NEC VR4100", stdout);
17523 break;
17524 case AFL_EXT_3900:
17525 fputs ("Toshiba R3900", stdout);
17526 break;
17527 case AFL_EXT_10000:
17528 fputs ("MIPS R10000", stdout);
17529 break;
17530 case AFL_EXT_SB1:
17531 fputs ("Broadcom SB-1", stdout);
17532 break;
17533 case AFL_EXT_4111:
17534 fputs ("NEC VR4111/VR4181", stdout);
17535 break;
17536 case AFL_EXT_4120:
17537 fputs ("NEC VR4120", stdout);
17538 break;
17539 case AFL_EXT_5400:
17540 fputs ("NEC VR5400", stdout);
17541 break;
17542 case AFL_EXT_5500:
17543 fputs ("NEC VR5500", stdout);
17544 break;
17545 case AFL_EXT_LOONGSON_2E:
17546 fputs ("ST Microelectronics Loongson 2E", stdout);
17547 break;
17548 case AFL_EXT_LOONGSON_2F:
17549 fputs ("ST Microelectronics Loongson 2F", stdout);
17550 break;
38bf472a
MR
17551 case AFL_EXT_INTERAPTIV_MR2:
17552 fputs ("Imagination interAptiv MR2", stdout);
17553 break;
351cdf24 17554 default:
00ac7aa0 17555 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
17556 }
17557}
17558
32ec8896 17559static signed int
351cdf24
MF
17560get_mips_reg_size (int reg_size)
17561{
17562 return (reg_size == AFL_REG_NONE) ? 0
17563 : (reg_size == AFL_REG_32) ? 32
17564 : (reg_size == AFL_REG_64) ? 64
17565 : (reg_size == AFL_REG_128) ? 128
17566 : -1;
17567}
17568
015dc7e1 17569static bool
dda8d76d 17570process_mips_specific (Filedata * filedata)
5b18a4bc 17571{
2cf0635d 17572 Elf_Internal_Dyn * entry;
351cdf24 17573 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
17574 size_t liblist_offset = 0;
17575 size_t liblistno = 0;
17576 size_t conflictsno = 0;
17577 size_t options_offset = 0;
17578 size_t conflicts_offset = 0;
861fb55a
DJ
17579 size_t pltrelsz = 0;
17580 size_t pltrel = 0;
ccb4c951 17581 bfd_vma pltgot = 0;
861fb55a
DJ
17582 bfd_vma mips_pltgot = 0;
17583 bfd_vma jmprel = 0;
ccb4c951
RS
17584 bfd_vma local_gotno = 0;
17585 bfd_vma gotsym = 0;
17586 bfd_vma symtabno = 0;
015dc7e1 17587 bool res = true;
103f02d3 17588
dda8d76d 17589 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 17590 display_mips_gnu_attribute))
015dc7e1 17591 res = false;
2cf19d5c 17592
dda8d76d 17593 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
17594
17595 if (sect != NULL)
17596 {
17597 Elf_External_ABIFlags_v0 *abiflags_ext;
17598 Elf_Internal_ABIFlags_v0 abiflags_in;
17599
17600 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
17601 {
17602 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 17603 res = false;
32ec8896 17604 }
351cdf24
MF
17605 else
17606 {
dda8d76d 17607 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
17608 sect->sh_size, _("MIPS ABI Flags section"));
17609 if (abiflags_ext)
17610 {
17611 abiflags_in.version = BYTE_GET (abiflags_ext->version);
17612 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
17613 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
17614 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
17615 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
17616 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
17617 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
17618 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
17619 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
17620 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
17621 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
17622
17623 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
17624 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
17625 if (abiflags_in.isa_rev > 1)
17626 printf ("r%d", abiflags_in.isa_rev);
17627 printf ("\nGPR size: %d",
17628 get_mips_reg_size (abiflags_in.gpr_size));
17629 printf ("\nCPR1 size: %d",
17630 get_mips_reg_size (abiflags_in.cpr1_size));
17631 printf ("\nCPR2 size: %d",
17632 get_mips_reg_size (abiflags_in.cpr2_size));
17633 fputs ("\nFP ABI: ", stdout);
17634 print_mips_fp_abi_value (abiflags_in.fp_abi);
17635 fputs ("ISA Extension: ", stdout);
17636 print_mips_isa_ext (abiflags_in.isa_ext);
17637 fputs ("\nASEs:", stdout);
17638 print_mips_ases (abiflags_in.ases);
17639 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
17640 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
17641 fputc ('\n', stdout);
17642 free (abiflags_ext);
17643 }
17644 }
17645 }
17646
19e6b90e 17647 /* We have a lot of special sections. Thanks SGI! */
978c4450 17648 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
17649 {
17650 /* No dynamic information available. See if there is static GOT. */
dda8d76d 17651 sect = find_section (filedata, ".got");
bbdd9a68
MR
17652 if (sect != NULL)
17653 {
17654 unsigned char *data_end;
17655 unsigned char *data;
17656 bfd_vma ent, end;
17657 int addr_size;
17658
17659 pltgot = sect->sh_addr;
17660
17661 ent = pltgot;
17662 addr_size = (is_32bit_elf ? 4 : 8);
17663 end = pltgot + sect->sh_size;
17664
dda8d76d 17665 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
17666 end - pltgot, 1,
17667 _("Global Offset Table data"));
17668 /* PR 12855: Null data is handled gracefully throughout. */
17669 data_end = data + (end - pltgot);
17670
17671 printf (_("\nStatic GOT:\n"));
17672 printf (_(" Canonical gp value: "));
17673 print_vma (ent + 0x7ff0, LONG_HEX);
17674 printf ("\n\n");
17675
17676 /* In a dynamic binary GOT[0] is reserved for the dynamic
17677 loader to store the lazy resolver pointer, however in
17678 a static binary it may well have been omitted and GOT
17679 reduced to a table of addresses.
17680 PR 21344: Check for the entry being fully available
17681 before fetching it. */
17682 if (data
17683 && data + ent - pltgot + addr_size <= data_end
17684 && byte_get (data + ent - pltgot, addr_size) == 0)
17685 {
17686 printf (_(" Reserved entries:\n"));
17687 printf (_(" %*s %10s %*s\n"),
17688 addr_size * 2, _("Address"), _("Access"),
17689 addr_size * 2, _("Value"));
17690 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17691 printf ("\n");
17692 if (ent == (bfd_vma) -1)
17693 goto sgot_print_fail;
17694
17695 /* Check for the MSB of GOT[1] being set, identifying a
17696 GNU object. This entry will be used by some runtime
17697 loaders, to store the module pointer. Otherwise this
17698 is an ordinary local entry.
17699 PR 21344: Check for the entry being fully available
17700 before fetching it. */
17701 if (data
17702 && data + ent - pltgot + addr_size <= data_end
17703 && (byte_get (data + ent - pltgot, addr_size)
17704 >> (addr_size * 8 - 1)) != 0)
17705 {
17706 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17707 printf ("\n");
17708 if (ent == (bfd_vma) -1)
17709 goto sgot_print_fail;
17710 }
17711 printf ("\n");
17712 }
17713
f17e9d8a 17714 if (data != NULL && ent < end)
bbdd9a68
MR
17715 {
17716 printf (_(" Local entries:\n"));
17717 printf (" %*s %10s %*s\n",
17718 addr_size * 2, _("Address"), _("Access"),
17719 addr_size * 2, _("Value"));
17720 while (ent < end)
17721 {
17722 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17723 printf ("\n");
17724 if (ent == (bfd_vma) -1)
17725 goto sgot_print_fail;
17726 }
17727 printf ("\n");
17728 }
17729
17730 sgot_print_fail:
9db70fc3 17731 free (data);
bbdd9a68
MR
17732 }
17733 return res;
17734 }
252b5132 17735
978c4450 17736 for (entry = filedata->dynamic_section;
071436c6 17737 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
17738 (entry < filedata->dynamic_section + filedata->dynamic_nent
17739 && entry->d_tag != DT_NULL);
071436c6 17740 ++entry)
252b5132
RH
17741 switch (entry->d_tag)
17742 {
17743 case DT_MIPS_LIBLIST:
d93f0186 17744 liblist_offset
dda8d76d 17745 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17746 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
17747 break;
17748 case DT_MIPS_LIBLISTNO:
17749 liblistno = entry->d_un.d_val;
17750 break;
17751 case DT_MIPS_OPTIONS:
dda8d76d 17752 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
17753 break;
17754 case DT_MIPS_CONFLICT:
d93f0186 17755 conflicts_offset
dda8d76d 17756 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17757 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
17758 break;
17759 case DT_MIPS_CONFLICTNO:
17760 conflictsno = entry->d_un.d_val;
17761 break;
ccb4c951 17762 case DT_PLTGOT:
861fb55a
DJ
17763 pltgot = entry->d_un.d_ptr;
17764 break;
ccb4c951
RS
17765 case DT_MIPS_LOCAL_GOTNO:
17766 local_gotno = entry->d_un.d_val;
17767 break;
17768 case DT_MIPS_GOTSYM:
17769 gotsym = entry->d_un.d_val;
17770 break;
17771 case DT_MIPS_SYMTABNO:
17772 symtabno = entry->d_un.d_val;
17773 break;
861fb55a
DJ
17774 case DT_MIPS_PLTGOT:
17775 mips_pltgot = entry->d_un.d_ptr;
17776 break;
17777 case DT_PLTREL:
17778 pltrel = entry->d_un.d_val;
17779 break;
17780 case DT_PLTRELSZ:
17781 pltrelsz = entry->d_un.d_val;
17782 break;
17783 case DT_JMPREL:
17784 jmprel = entry->d_un.d_ptr;
17785 break;
252b5132
RH
17786 default:
17787 break;
17788 }
17789
17790 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
17791 {
2cf0635d 17792 Elf32_External_Lib * elib;
252b5132
RH
17793 size_t cnt;
17794
dda8d76d 17795 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
17796 sizeof (Elf32_External_Lib),
17797 liblistno,
17798 _("liblist section data"));
a6e9f9df 17799 if (elib)
252b5132 17800 {
d3a49aa8
AM
17801 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
17802 "\nSection '.liblist' contains %lu entries:\n",
17803 (unsigned long) liblistno),
a6e9f9df 17804 (unsigned long) liblistno);
2b692964 17805 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
17806 stdout);
17807
17808 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 17809 {
a6e9f9df 17810 Elf32_Lib liblist;
91d6fa6a 17811 time_t atime;
d5b07ef4 17812 char timebuf[128];
2cf0635d 17813 struct tm * tmp;
a6e9f9df
AM
17814
17815 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17816 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
17817 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17818 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17819 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17820
91d6fa6a 17821 tmp = gmtime (&atime);
e9e44622
JJ
17822 snprintf (timebuf, sizeof (timebuf),
17823 "%04u-%02u-%02uT%02u:%02u:%02u",
17824 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17825 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 17826
31104126 17827 printf ("%3lu: ", (unsigned long) cnt);
978c4450
AM
17828 if (VALID_DYNAMIC_NAME (filedata, liblist.l_name))
17829 print_symbol (20, GET_DYNAMIC_NAME (filedata, liblist.l_name));
d79b3d50 17830 else
2b692964 17831 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
17832 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
17833 liblist.l_version);
a6e9f9df
AM
17834
17835 if (liblist.l_flags == 0)
2b692964 17836 puts (_(" NONE"));
a6e9f9df
AM
17837 else
17838 {
17839 static const struct
252b5132 17840 {
2cf0635d 17841 const char * name;
a6e9f9df 17842 int bit;
252b5132 17843 }
a6e9f9df
AM
17844 l_flags_vals[] =
17845 {
17846 { " EXACT_MATCH", LL_EXACT_MATCH },
17847 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
17848 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
17849 { " EXPORTS", LL_EXPORTS },
17850 { " DELAY_LOAD", LL_DELAY_LOAD },
17851 { " DELTA", LL_DELTA }
17852 };
17853 int flags = liblist.l_flags;
17854 size_t fcnt;
17855
60bca95a 17856 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
17857 if ((flags & l_flags_vals[fcnt].bit) != 0)
17858 {
17859 fputs (l_flags_vals[fcnt].name, stdout);
17860 flags ^= l_flags_vals[fcnt].bit;
17861 }
17862 if (flags != 0)
17863 printf (" %#x", (unsigned int) flags);
252b5132 17864
a6e9f9df
AM
17865 puts ("");
17866 }
252b5132 17867 }
252b5132 17868
a6e9f9df
AM
17869 free (elib);
17870 }
32ec8896 17871 else
015dc7e1 17872 res = false;
252b5132
RH
17873 }
17874
17875 if (options_offset != 0)
17876 {
2cf0635d 17877 Elf_External_Options * eopt;
252b5132
RH
17878 size_t offset;
17879 int cnt;
dda8d76d 17880 sect = filedata->section_headers;
252b5132
RH
17881
17882 /* Find the section header so that we get the size. */
dda8d76d 17883 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 17884 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
17885 if (sect == NULL)
17886 {
17887 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 17888 return false;
071436c6 17889 }
7fc0c668
NC
17890 /* PR 24243 */
17891 if (sect->sh_size < sizeof (* eopt))
17892 {
17893 error (_("The MIPS options section is too small.\n"));
015dc7e1 17894 return false;
7fc0c668 17895 }
252b5132 17896
dda8d76d 17897 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 17898 sect->sh_size, _("options"));
a6e9f9df 17899 if (eopt)
252b5132 17900 {
fd17d1e6 17901 Elf_Internal_Options option;
76da6bbe 17902
a6e9f9df 17903 offset = cnt = 0;
82b1b41b 17904 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 17905 {
2cf0635d 17906 Elf_External_Options * eoption;
fd17d1e6 17907 unsigned int optsize;
252b5132 17908
a6e9f9df 17909 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 17910
fd17d1e6 17911 optsize = BYTE_GET (eoption->size);
76da6bbe 17912
82b1b41b 17913 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
17914 if (optsize < sizeof (* eopt)
17915 || optsize > sect->sh_size - offset)
82b1b41b 17916 {
645f43a8 17917 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 17918 optsize);
645f43a8 17919 free (eopt);
015dc7e1 17920 return false;
82b1b41b 17921 }
fd17d1e6 17922 offset += optsize;
a6e9f9df
AM
17923 ++cnt;
17924 }
252b5132 17925
d3a49aa8
AM
17926 printf (ngettext ("\nSection '%s' contains %d entry:\n",
17927 "\nSection '%s' contains %d entries:\n",
17928 cnt),
dda8d76d 17929 printable_section_name (filedata, sect), cnt);
76da6bbe 17930
82b1b41b 17931 offset = 0;
a6e9f9df 17932 while (cnt-- > 0)
252b5132 17933 {
a6e9f9df 17934 size_t len;
fd17d1e6
AM
17935 Elf_External_Options * eoption;
17936
17937 eoption = (Elf_External_Options *) ((char *) eopt + offset);
17938
17939 option.kind = BYTE_GET (eoption->kind);
17940 option.size = BYTE_GET (eoption->size);
17941 option.section = BYTE_GET (eoption->section);
17942 option.info = BYTE_GET (eoption->info);
a6e9f9df 17943
fd17d1e6 17944 switch (option.kind)
252b5132 17945 {
a6e9f9df
AM
17946 case ODK_NULL:
17947 /* This shouldn't happen. */
d0c4e780 17948 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 17949 option.section, option.info);
a6e9f9df 17950 break;
2e6be59c 17951
a6e9f9df
AM
17952 case ODK_REGINFO:
17953 printf (" REGINFO ");
dda8d76d 17954 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 17955 {
2cf0635d 17956 Elf32_External_RegInfo * ereg;
b34976b6 17957 Elf32_RegInfo reginfo;
a6e9f9df 17958
2e6be59c 17959 /* 32bit form. */
fd17d1e6
AM
17960 if (option.size < (sizeof (Elf_External_Options)
17961 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
17962 {
17963 printf (_("<corrupt>\n"));
17964 error (_("Truncated MIPS REGINFO option\n"));
17965 cnt = 0;
17966 break;
17967 }
17968
fd17d1e6 17969 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 17970
a6e9f9df
AM
17971 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17972 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17973 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17974 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17975 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
17976 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
17977
d0c4e780
AM
17978 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
17979 reginfo.ri_gprmask, reginfo.ri_gp_value);
17980 printf (" "
17981 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
17982 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
17983 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17984 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17985 }
17986 else
17987 {
17988 /* 64 bit form. */
2cf0635d 17989 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
17990 Elf64_Internal_RegInfo reginfo;
17991
fd17d1e6
AM
17992 if (option.size < (sizeof (Elf_External_Options)
17993 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
17994 {
17995 printf (_("<corrupt>\n"));
17996 error (_("Truncated MIPS REGINFO option\n"));
17997 cnt = 0;
17998 break;
17999 }
18000
fd17d1e6 18001 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18002 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18003 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18004 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18005 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18006 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18007 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18008
d0c4e780
AM
18009 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18010 reginfo.ri_gprmask, reginfo.ri_gp_value);
18011 printf (" "
18012 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18013 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18014 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18015 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18016 }
fd17d1e6 18017 offset += option.size;
a6e9f9df 18018 continue;
2e6be59c 18019
a6e9f9df
AM
18020 case ODK_EXCEPTIONS:
18021 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18022 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18023 fputs (") fpe_max(", stdout);
fd17d1e6 18024 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18025 fputs (")", stdout);
18026
fd17d1e6 18027 if (option.info & OEX_PAGE0)
a6e9f9df 18028 fputs (" PAGE0", stdout);
fd17d1e6 18029 if (option.info & OEX_SMM)
a6e9f9df 18030 fputs (" SMM", stdout);
fd17d1e6 18031 if (option.info & OEX_FPDBUG)
a6e9f9df 18032 fputs (" FPDBUG", stdout);
fd17d1e6 18033 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18034 fputs (" DISMISS", stdout);
18035 break;
2e6be59c 18036
a6e9f9df
AM
18037 case ODK_PAD:
18038 fputs (" PAD ", stdout);
fd17d1e6 18039 if (option.info & OPAD_PREFIX)
a6e9f9df 18040 fputs (" PREFIX", stdout);
fd17d1e6 18041 if (option.info & OPAD_POSTFIX)
a6e9f9df 18042 fputs (" POSTFIX", stdout);
fd17d1e6 18043 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18044 fputs (" SYMBOL", stdout);
18045 break;
2e6be59c 18046
a6e9f9df
AM
18047 case ODK_HWPATCH:
18048 fputs (" HWPATCH ", stdout);
fd17d1e6 18049 if (option.info & OHW_R4KEOP)
a6e9f9df 18050 fputs (" R4KEOP", stdout);
fd17d1e6 18051 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18052 fputs (" R8KPFETCH", stdout);
fd17d1e6 18053 if (option.info & OHW_R5KEOP)
a6e9f9df 18054 fputs (" R5KEOP", stdout);
fd17d1e6 18055 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18056 fputs (" R5KCVTL", stdout);
18057 break;
2e6be59c 18058
a6e9f9df
AM
18059 case ODK_FILL:
18060 fputs (" FILL ", stdout);
18061 /* XXX Print content of info word? */
18062 break;
2e6be59c 18063
a6e9f9df
AM
18064 case ODK_TAGS:
18065 fputs (" TAGS ", stdout);
18066 /* XXX Print content of info word? */
18067 break;
2e6be59c 18068
a6e9f9df
AM
18069 case ODK_HWAND:
18070 fputs (" HWAND ", stdout);
fd17d1e6 18071 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18072 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18073 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18074 fputs (" R4KEOP_CLEAN", stdout);
18075 break;
2e6be59c 18076
a6e9f9df
AM
18077 case ODK_HWOR:
18078 fputs (" HWOR ", 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 18085 case ODK_GP_GROUP:
d0c4e780 18086 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18087 option.info & OGP_GROUP,
18088 (option.info & OGP_SELF) >> 16);
a6e9f9df 18089 break;
2e6be59c 18090
a6e9f9df 18091 case ODK_IDENT:
d0c4e780 18092 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18093 option.info & OGP_GROUP,
18094 (option.info & OGP_SELF) >> 16);
a6e9f9df 18095 break;
2e6be59c 18096
a6e9f9df
AM
18097 default:
18098 /* This shouldn't happen. */
d0c4e780 18099 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18100 option.kind, option.section, option.info);
a6e9f9df 18101 break;
252b5132 18102 }
a6e9f9df 18103
2cf0635d 18104 len = sizeof (* eopt);
fd17d1e6 18105 while (len < option.size)
82b1b41b 18106 {
fd17d1e6 18107 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18108
82b1b41b
NC
18109 if (ISPRINT (datum))
18110 printf ("%c", datum);
18111 else
18112 printf ("\\%03o", datum);
18113 len ++;
18114 }
a6e9f9df 18115 fputs ("\n", stdout);
82b1b41b 18116
fd17d1e6 18117 offset += option.size;
252b5132 18118 }
a6e9f9df 18119 free (eopt);
252b5132 18120 }
32ec8896 18121 else
015dc7e1 18122 res = false;
252b5132
RH
18123 }
18124
18125 if (conflicts_offset != 0 && conflictsno != 0)
18126 {
2cf0635d 18127 Elf32_Conflict * iconf;
252b5132
RH
18128 size_t cnt;
18129
978c4450 18130 if (filedata->dynamic_symbols == NULL)
252b5132 18131 {
591a748a 18132 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18133 return false;
252b5132
RH
18134 }
18135
7296a62a
NC
18136 /* PR 21345 - print a slightly more helpful error message
18137 if we are sure that the cmalloc will fail. */
645f43a8 18138 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18139 {
18140 error (_("Overlarge number of conflicts detected: %lx\n"),
18141 (long) conflictsno);
015dc7e1 18142 return false;
7296a62a
NC
18143 }
18144
3f5e193b 18145 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18146 if (iconf == NULL)
18147 {
8b73c356 18148 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18149 return false;
252b5132
RH
18150 }
18151
9ea033b2 18152 if (is_32bit_elf)
252b5132 18153 {
2cf0635d 18154 Elf32_External_Conflict * econf32;
a6e9f9df 18155
3f5e193b 18156 econf32 = (Elf32_External_Conflict *)
95099889
AM
18157 get_data (NULL, filedata, conflicts_offset,
18158 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18159 if (!econf32)
5a814d6d
AM
18160 {
18161 free (iconf);
015dc7e1 18162 return false;
5a814d6d 18163 }
252b5132
RH
18164
18165 for (cnt = 0; cnt < conflictsno; ++cnt)
18166 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18167
18168 free (econf32);
252b5132
RH
18169 }
18170 else
18171 {
2cf0635d 18172 Elf64_External_Conflict * econf64;
a6e9f9df 18173
3f5e193b 18174 econf64 = (Elf64_External_Conflict *)
95099889
AM
18175 get_data (NULL, filedata, conflicts_offset,
18176 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18177 if (!econf64)
5a814d6d
AM
18178 {
18179 free (iconf);
015dc7e1 18180 return false;
5a814d6d 18181 }
252b5132
RH
18182
18183 for (cnt = 0; cnt < conflictsno; ++cnt)
18184 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18185
18186 free (econf64);
252b5132
RH
18187 }
18188
d3a49aa8
AM
18189 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18190 "\nSection '.conflict' contains %lu entries:\n",
18191 (unsigned long) conflictsno),
c7e7ca54 18192 (unsigned long) conflictsno);
252b5132
RH
18193 puts (_(" Num: Index Value Name"));
18194
18195 for (cnt = 0; cnt < conflictsno; ++cnt)
18196 {
b34976b6 18197 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18198
978c4450 18199 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18200 printf (_("<corrupt symbol index>"));
d79b3d50 18201 else
e0a31db1
NC
18202 {
18203 Elf_Internal_Sym * psym;
18204
978c4450 18205 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18206 print_vma (psym->st_value, FULL_HEX);
18207 putchar (' ');
978c4450
AM
18208 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18209 print_symbol (25, GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18210 else
18211 printf (_("<corrupt: %14ld>"), psym->st_name);
18212 }
31104126 18213 putchar ('\n');
252b5132
RH
18214 }
18215
252b5132
RH
18216 free (iconf);
18217 }
18218
ccb4c951
RS
18219 if (pltgot != 0 && local_gotno != 0)
18220 {
91d6fa6a 18221 bfd_vma ent, local_end, global_end;
bbeee7ea 18222 size_t i, offset;
2cf0635d 18223 unsigned char * data;
82b1b41b 18224 unsigned char * data_end;
bbeee7ea 18225 int addr_size;
ccb4c951 18226
91d6fa6a 18227 ent = pltgot;
ccb4c951
RS
18228 addr_size = (is_32bit_elf ? 4 : 8);
18229 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18230
74e1a04b
NC
18231 /* PR binutils/17533 file: 012-111227-0.004 */
18232 if (symtabno < gotsym)
18233 {
18234 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18235 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18236 return false;
74e1a04b 18237 }
82b1b41b 18238
74e1a04b 18239 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18240 /* PR 17531: file: 54c91a34. */
18241 if (global_end < local_end)
18242 {
18243 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18244 return false;
82b1b41b 18245 }
948f632f 18246
dda8d76d
NC
18247 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18248 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18249 global_end - pltgot, 1,
18250 _("Global Offset Table data"));
919383ac 18251 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18252 data_end = data + (global_end - pltgot);
59245841 18253
ccb4c951
RS
18254 printf (_("\nPrimary GOT:\n"));
18255 printf (_(" Canonical gp value: "));
18256 print_vma (pltgot + 0x7ff0, LONG_HEX);
18257 printf ("\n\n");
18258
18259 printf (_(" Reserved entries:\n"));
18260 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18261 addr_size * 2, _("Address"), _("Access"),
18262 addr_size * 2, _("Initial"));
82b1b41b 18263 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18264 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18265 if (ent == (bfd_vma) -1)
18266 goto got_print_fail;
75ec1fdb 18267
c4ab9505
MR
18268 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18269 This entry will be used by some runtime loaders, to store the
18270 module pointer. Otherwise this is an ordinary local entry.
18271 PR 21344: Check for the entry being fully available before
18272 fetching it. */
18273 if (data
18274 && data + ent - pltgot + addr_size <= data_end
18275 && (byte_get (data + ent - pltgot, addr_size)
18276 >> (addr_size * 8 - 1)) != 0)
18277 {
18278 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18279 printf (_(" Module pointer (GNU extension)\n"));
18280 if (ent == (bfd_vma) -1)
18281 goto got_print_fail;
ccb4c951
RS
18282 }
18283 printf ("\n");
18284
f17e9d8a 18285 if (data != NULL && ent < local_end)
ccb4c951
RS
18286 {
18287 printf (_(" Local entries:\n"));
cc5914eb 18288 printf (" %*s %10s %*s\n",
2b692964
NC
18289 addr_size * 2, _("Address"), _("Access"),
18290 addr_size * 2, _("Initial"));
91d6fa6a 18291 while (ent < local_end)
ccb4c951 18292 {
82b1b41b 18293 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18294 printf ("\n");
82b1b41b
NC
18295 if (ent == (bfd_vma) -1)
18296 goto got_print_fail;
ccb4c951
RS
18297 }
18298 printf ("\n");
18299 }
18300
f17e9d8a 18301 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18302 {
18303 int sym_width;
18304
18305 printf (_(" Global entries:\n"));
cc5914eb 18306 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18307 addr_size * 2, _("Address"),
18308 _("Access"),
2b692964 18309 addr_size * 2, _("Initial"),
9cf03b7e
NC
18310 addr_size * 2, _("Sym.Val."),
18311 _("Type"),
18312 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18313 _("Ndx"), _("Name"));
0b4362b0 18314
ccb4c951 18315 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18316
ccb4c951
RS
18317 for (i = gotsym; i < symtabno; i++)
18318 {
82b1b41b 18319 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18320 printf (" ");
e0a31db1 18321
978c4450 18322 if (filedata->dynamic_symbols == NULL)
e0a31db1 18323 printf (_("<no dynamic symbols>"));
978c4450 18324 else if (i < filedata->num_dynamic_syms)
e0a31db1 18325 {
978c4450 18326 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
18327
18328 print_vma (psym->st_value, LONG_HEX);
18329 printf (" %-7s %3s ",
dda8d76d
NC
18330 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18331 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 18332
978c4450
AM
18333 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18334 print_symbol (sym_width,
18335 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18336 else
18337 printf (_("<corrupt: %14ld>"), psym->st_name);
18338 }
ccb4c951 18339 else
7fc5ac57
JBG
18340 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
18341 (unsigned long) i);
e0a31db1 18342
ccb4c951 18343 printf ("\n");
82b1b41b
NC
18344 if (ent == (bfd_vma) -1)
18345 break;
ccb4c951
RS
18346 }
18347 printf ("\n");
18348 }
18349
82b1b41b 18350 got_print_fail:
9db70fc3 18351 free (data);
ccb4c951
RS
18352 }
18353
861fb55a
DJ
18354 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
18355 {
91d6fa6a 18356 bfd_vma ent, end;
861fb55a
DJ
18357 size_t offset, rel_offset;
18358 unsigned long count, i;
2cf0635d 18359 unsigned char * data;
861fb55a 18360 int addr_size, sym_width;
2cf0635d 18361 Elf_Internal_Rela * rels;
861fb55a 18362
dda8d76d 18363 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
18364 if (pltrel == DT_RELA)
18365 {
dda8d76d 18366 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18367 return false;
861fb55a
DJ
18368 }
18369 else
18370 {
dda8d76d 18371 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18372 return false;
861fb55a
DJ
18373 }
18374
91d6fa6a 18375 ent = mips_pltgot;
861fb55a
DJ
18376 addr_size = (is_32bit_elf ? 4 : 8);
18377 end = mips_pltgot + (2 + count) * addr_size;
18378
dda8d76d
NC
18379 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
18380 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 18381 1, _("Procedure Linkage Table data"));
59245841 18382 if (data == NULL)
288f0ba2
AM
18383 {
18384 free (rels);
015dc7e1 18385 return false;
288f0ba2 18386 }
59245841 18387
9cf03b7e 18388 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
18389 printf (_(" Reserved entries:\n"));
18390 printf (_(" %*s %*s Purpose\n"),
2b692964 18391 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 18392 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18393 printf (_(" PLT lazy resolver\n"));
91d6fa6a 18394 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18395 printf (_(" Module pointer\n"));
861fb55a
DJ
18396 printf ("\n");
18397
18398 printf (_(" Entries:\n"));
cc5914eb 18399 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
18400 addr_size * 2, _("Address"),
18401 addr_size * 2, _("Initial"),
18402 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
18403 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
18404 for (i = 0; i < count; i++)
18405 {
df97ab2a 18406 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 18407
91d6fa6a 18408 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 18409 printf (" ");
e0a31db1 18410
978c4450 18411 if (idx >= filedata->num_dynamic_syms)
df97ab2a 18412 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 18413 else
e0a31db1 18414 {
978c4450 18415 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
18416
18417 print_vma (psym->st_value, LONG_HEX);
18418 printf (" %-7s %3s ",
dda8d76d
NC
18419 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18420 get_symbol_index_type (filedata, psym->st_shndx));
978c4450
AM
18421 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18422 print_symbol (sym_width,
18423 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18424 else
18425 printf (_("<corrupt: %14ld>"), psym->st_name);
18426 }
861fb55a
DJ
18427 printf ("\n");
18428 }
18429 printf ("\n");
18430
9db70fc3 18431 free (data);
861fb55a
DJ
18432 free (rels);
18433 }
18434
32ec8896 18435 return res;
252b5132
RH
18436}
18437
015dc7e1 18438static bool
dda8d76d 18439process_nds32_specific (Filedata * filedata)
35c08157
KLC
18440{
18441 Elf_Internal_Shdr *sect = NULL;
18442
dda8d76d 18443 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 18444 if (sect != NULL && sect->sh_size >= 4)
35c08157 18445 {
9c7b8e9b
AM
18446 unsigned char *buf;
18447 unsigned int flag;
35c08157
KLC
18448
18449 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
18450 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
18451 _("NDS32 elf flags section"));
35c08157 18452
9c7b8e9b 18453 if (buf == NULL)
015dc7e1 18454 return false;
32ec8896 18455
9c7b8e9b
AM
18456 flag = byte_get (buf, 4);
18457 free (buf);
18458 switch (flag & 0x3)
35c08157
KLC
18459 {
18460 case 0:
18461 printf ("(VEC_SIZE):\tNo entry.\n");
18462 break;
18463 case 1:
18464 printf ("(VEC_SIZE):\t4 bytes\n");
18465 break;
18466 case 2:
18467 printf ("(VEC_SIZE):\t16 bytes\n");
18468 break;
18469 case 3:
18470 printf ("(VEC_SIZE):\treserved\n");
18471 break;
18472 }
18473 }
18474
015dc7e1 18475 return true;
35c08157
KLC
18476}
18477
015dc7e1 18478static bool
dda8d76d 18479process_gnu_liblist (Filedata * filedata)
047b2264 18480{
2cf0635d
NC
18481 Elf_Internal_Shdr * section;
18482 Elf_Internal_Shdr * string_sec;
18483 Elf32_External_Lib * elib;
18484 char * strtab;
c256ffe7 18485 size_t strtab_size;
047b2264 18486 size_t cnt;
d3a49aa8 18487 unsigned long num_liblist;
047b2264 18488 unsigned i;
015dc7e1 18489 bool res = true;
047b2264
JJ
18490
18491 if (! do_arch)
015dc7e1 18492 return true;
047b2264 18493
dda8d76d
NC
18494 for (i = 0, section = filedata->section_headers;
18495 i < filedata->file_header.e_shnum;
b34976b6 18496 i++, section++)
047b2264
JJ
18497 {
18498 switch (section->sh_type)
18499 {
18500 case SHT_GNU_LIBLIST:
dda8d76d 18501 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
18502 break;
18503
3f5e193b 18504 elib = (Elf32_External_Lib *)
dda8d76d 18505 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 18506 _("liblist section data"));
047b2264
JJ
18507
18508 if (elib == NULL)
32ec8896 18509 {
015dc7e1 18510 res = false;
32ec8896
NC
18511 break;
18512 }
047b2264 18513
dda8d76d
NC
18514 string_sec = filedata->section_headers + section->sh_link;
18515 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
18516 string_sec->sh_size,
18517 _("liblist string table"));
047b2264
JJ
18518 if (strtab == NULL
18519 || section->sh_entsize != sizeof (Elf32_External_Lib))
18520 {
18521 free (elib);
2842702f 18522 free (strtab);
015dc7e1 18523 res = false;
047b2264
JJ
18524 break;
18525 }
59245841 18526 strtab_size = string_sec->sh_size;
047b2264 18527
d3a49aa8
AM
18528 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
18529 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
18530 "\nLibrary list section '%s' contains %lu entries:\n",
18531 num_liblist),
dda8d76d 18532 printable_section_name (filedata, section),
d3a49aa8 18533 num_liblist);
047b2264 18534
2b692964 18535 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
18536
18537 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
18538 ++cnt)
18539 {
18540 Elf32_Lib liblist;
91d6fa6a 18541 time_t atime;
d5b07ef4 18542 char timebuf[128];
2cf0635d 18543 struct tm * tmp;
047b2264
JJ
18544
18545 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18546 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
18547 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18548 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18549 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18550
91d6fa6a 18551 tmp = gmtime (&atime);
e9e44622
JJ
18552 snprintf (timebuf, sizeof (timebuf),
18553 "%04u-%02u-%02uT%02u:%02u:%02u",
18554 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18555 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
18556
18557 printf ("%3lu: ", (unsigned long) cnt);
18558 if (do_wide)
c256ffe7 18559 printf ("%-20s", liblist.l_name < strtab_size
2b692964 18560 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 18561 else
c256ffe7 18562 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 18563 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
18564 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
18565 liblist.l_version, liblist.l_flags);
18566 }
18567
18568 free (elib);
2842702f 18569 free (strtab);
047b2264
JJ
18570 }
18571 }
18572
32ec8896 18573 return res;
047b2264
JJ
18574}
18575
9437c45b 18576static const char *
dda8d76d 18577get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
18578{
18579 static char buff[64];
103f02d3 18580
dda8d76d 18581 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
18582 switch (e_type)
18583 {
57346661 18584 case NT_AUXV:
1ec5cd37 18585 return _("NT_AUXV (auxiliary vector)");
57346661 18586 case NT_PRSTATUS:
1ec5cd37 18587 return _("NT_PRSTATUS (prstatus structure)");
57346661 18588 case NT_FPREGSET:
1ec5cd37 18589 return _("NT_FPREGSET (floating point registers)");
57346661 18590 case NT_PRPSINFO:
1ec5cd37 18591 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 18592 case NT_TASKSTRUCT:
1ec5cd37 18593 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
18594 case NT_GDB_TDESC:
18595 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 18596 case NT_PRXFPREG:
1ec5cd37 18597 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
18598 case NT_PPC_VMX:
18599 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
18600 case NT_PPC_VSX:
18601 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
18602 case NT_PPC_TAR:
18603 return _("NT_PPC_TAR (ppc TAR register)");
18604 case NT_PPC_PPR:
18605 return _("NT_PPC_PPR (ppc PPR register)");
18606 case NT_PPC_DSCR:
18607 return _("NT_PPC_DSCR (ppc DSCR register)");
18608 case NT_PPC_EBB:
18609 return _("NT_PPC_EBB (ppc EBB registers)");
18610 case NT_PPC_PMU:
18611 return _("NT_PPC_PMU (ppc PMU registers)");
18612 case NT_PPC_TM_CGPR:
18613 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
18614 case NT_PPC_TM_CFPR:
18615 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
18616 case NT_PPC_TM_CVMX:
18617 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
18618 case NT_PPC_TM_CVSX:
3fd21718 18619 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
18620 case NT_PPC_TM_SPR:
18621 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
18622 case NT_PPC_TM_CTAR:
18623 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
18624 case NT_PPC_TM_CPPR:
18625 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
18626 case NT_PPC_TM_CDSCR:
18627 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
18628 case NT_386_TLS:
18629 return _("NT_386_TLS (x86 TLS information)");
18630 case NT_386_IOPERM:
18631 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
18632 case NT_X86_XSTATE:
18633 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
18634 case NT_X86_CET:
18635 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
18636 case NT_S390_HIGH_GPRS:
18637 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
18638 case NT_S390_TIMER:
18639 return _("NT_S390_TIMER (s390 timer register)");
18640 case NT_S390_TODCMP:
18641 return _("NT_S390_TODCMP (s390 TOD comparator register)");
18642 case NT_S390_TODPREG:
18643 return _("NT_S390_TODPREG (s390 TOD programmable register)");
18644 case NT_S390_CTRS:
18645 return _("NT_S390_CTRS (s390 control registers)");
18646 case NT_S390_PREFIX:
18647 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
18648 case NT_S390_LAST_BREAK:
18649 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
18650 case NT_S390_SYSTEM_CALL:
18651 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
18652 case NT_S390_TDB:
18653 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
18654 case NT_S390_VXRS_LOW:
18655 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
18656 case NT_S390_VXRS_HIGH:
18657 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
18658 case NT_S390_GS_CB:
18659 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
18660 case NT_S390_GS_BC:
18661 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
18662 case NT_ARM_VFP:
18663 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
18664 case NT_ARM_TLS:
18665 return _("NT_ARM_TLS (AArch TLS registers)");
18666 case NT_ARM_HW_BREAK:
18667 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
18668 case NT_ARM_HW_WATCH:
18669 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
27456742
AK
18670 case NT_ARC_V2:
18671 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
18672 case NT_RISCV_CSR:
18673 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 18674 case NT_PSTATUS:
1ec5cd37 18675 return _("NT_PSTATUS (pstatus structure)");
57346661 18676 case NT_FPREGS:
1ec5cd37 18677 return _("NT_FPREGS (floating point registers)");
57346661 18678 case NT_PSINFO:
1ec5cd37 18679 return _("NT_PSINFO (psinfo structure)");
57346661 18680 case NT_LWPSTATUS:
1ec5cd37 18681 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 18682 case NT_LWPSINFO:
1ec5cd37 18683 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 18684 case NT_WIN32PSTATUS:
1ec5cd37 18685 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
18686 case NT_SIGINFO:
18687 return _("NT_SIGINFO (siginfo_t data)");
18688 case NT_FILE:
18689 return _("NT_FILE (mapped files)");
1ec5cd37
NC
18690 default:
18691 break;
18692 }
18693 else
18694 switch (e_type)
18695 {
18696 case NT_VERSION:
18697 return _("NT_VERSION (version)");
18698 case NT_ARCH:
18699 return _("NT_ARCH (architecture)");
9ef920e9 18700 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 18701 return _("OPEN");
9ef920e9 18702 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 18703 return _("func");
1ec5cd37
NC
18704 default:
18705 break;
18706 }
18707
e9e44622 18708 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 18709 return buff;
779fe533
NC
18710}
18711
015dc7e1 18712static bool
9ece1fa9
TT
18713print_core_note (Elf_Internal_Note *pnote)
18714{
18715 unsigned int addr_size = is_32bit_elf ? 4 : 8;
18716 bfd_vma count, page_size;
18717 unsigned char *descdata, *filenames, *descend;
18718
18719 if (pnote->type != NT_FILE)
04ac15ab
AS
18720 {
18721 if (do_wide)
18722 printf ("\n");
015dc7e1 18723 return true;
04ac15ab 18724 }
9ece1fa9
TT
18725
18726#ifndef BFD64
18727 if (!is_32bit_elf)
18728 {
18729 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
18730 /* Still "successful". */
015dc7e1 18731 return true;
9ece1fa9
TT
18732 }
18733#endif
18734
18735 if (pnote->descsz < 2 * addr_size)
18736 {
32ec8896 18737 error (_(" Malformed note - too short for header\n"));
015dc7e1 18738 return false;
9ece1fa9
TT
18739 }
18740
18741 descdata = (unsigned char *) pnote->descdata;
18742 descend = descdata + pnote->descsz;
18743
18744 if (descdata[pnote->descsz - 1] != '\0')
18745 {
32ec8896 18746 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 18747 return false;
9ece1fa9
TT
18748 }
18749
18750 count = byte_get (descdata, addr_size);
18751 descdata += addr_size;
18752
18753 page_size = byte_get (descdata, addr_size);
18754 descdata += addr_size;
18755
5396a86e
AM
18756 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
18757 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 18758 {
32ec8896 18759 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 18760 return false;
9ece1fa9
TT
18761 }
18762
18763 printf (_(" Page size: "));
18764 print_vma (page_size, DEC);
18765 printf ("\n");
18766
18767 printf (_(" %*s%*s%*s\n"),
18768 (int) (2 + 2 * addr_size), _("Start"),
18769 (int) (4 + 2 * addr_size), _("End"),
18770 (int) (4 + 2 * addr_size), _("Page Offset"));
18771 filenames = descdata + count * 3 * addr_size;
595712bb 18772 while (count-- > 0)
9ece1fa9
TT
18773 {
18774 bfd_vma start, end, file_ofs;
18775
18776 if (filenames == descend)
18777 {
32ec8896 18778 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 18779 return false;
9ece1fa9
TT
18780 }
18781
18782 start = byte_get (descdata, addr_size);
18783 descdata += addr_size;
18784 end = byte_get (descdata, addr_size);
18785 descdata += addr_size;
18786 file_ofs = byte_get (descdata, addr_size);
18787 descdata += addr_size;
18788
18789 printf (" ");
18790 print_vma (start, FULL_HEX);
18791 printf (" ");
18792 print_vma (end, FULL_HEX);
18793 printf (" ");
18794 print_vma (file_ofs, FULL_HEX);
18795 printf ("\n %s\n", filenames);
18796
18797 filenames += 1 + strlen ((char *) filenames);
18798 }
18799
015dc7e1 18800 return true;
9ece1fa9
TT
18801}
18802
1118d252
RM
18803static const char *
18804get_gnu_elf_note_type (unsigned e_type)
18805{
1449284b 18806 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
18807 switch (e_type)
18808 {
18809 case NT_GNU_ABI_TAG:
18810 return _("NT_GNU_ABI_TAG (ABI version tag)");
18811 case NT_GNU_HWCAP:
18812 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
18813 case NT_GNU_BUILD_ID:
18814 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
18815 case NT_GNU_GOLD_VERSION:
18816 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
18817 case NT_GNU_PROPERTY_TYPE_0:
18818 return _("NT_GNU_PROPERTY_TYPE_0");
18819 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
18820 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
18821 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
18822 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 18823 default:
1449284b
NC
18824 {
18825 static char buff[64];
1118d252 18826
1449284b
NC
18827 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18828 return buff;
18829 }
18830 }
1118d252
RM
18831}
18832
a9eafb08
L
18833static void
18834decode_x86_compat_isa (unsigned int bitmask)
18835{
18836 while (bitmask)
18837 {
18838 unsigned int bit = bitmask & (- bitmask);
18839
18840 bitmask &= ~ bit;
18841 switch (bit)
18842 {
18843 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
18844 printf ("i486");
18845 break;
18846 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
18847 printf ("586");
18848 break;
18849 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
18850 printf ("686");
18851 break;
18852 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
18853 printf ("SSE");
18854 break;
18855 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
18856 printf ("SSE2");
18857 break;
18858 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
18859 printf ("SSE3");
18860 break;
18861 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
18862 printf ("SSSE3");
18863 break;
18864 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
18865 printf ("SSE4_1");
18866 break;
18867 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
18868 printf ("SSE4_2");
18869 break;
18870 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
18871 printf ("AVX");
18872 break;
18873 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
18874 printf ("AVX2");
18875 break;
18876 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
18877 printf ("AVX512F");
18878 break;
18879 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
18880 printf ("AVX512CD");
18881 break;
18882 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
18883 printf ("AVX512ER");
18884 break;
18885 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
18886 printf ("AVX512PF");
18887 break;
18888 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
18889 printf ("AVX512VL");
18890 break;
18891 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
18892 printf ("AVX512DQ");
18893 break;
18894 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
18895 printf ("AVX512BW");
18896 break;
65b3d26e
L
18897 default:
18898 printf (_("<unknown: %x>"), bit);
18899 break;
a9eafb08
L
18900 }
18901 if (bitmask)
18902 printf (", ");
18903 }
18904}
18905
9ef920e9 18906static void
32930e4e 18907decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 18908{
0a59decb 18909 if (!bitmask)
90c745dc
L
18910 {
18911 printf (_("<None>"));
18912 return;
18913 }
90c745dc 18914
9ef920e9
NC
18915 while (bitmask)
18916 {
1fc87489 18917 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
18918
18919 bitmask &= ~ bit;
18920 switch (bit)
18921 {
32930e4e 18922 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
18923 printf ("CMOV");
18924 break;
32930e4e 18925 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
18926 printf ("SSE");
18927 break;
32930e4e 18928 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
18929 printf ("SSE2");
18930 break;
32930e4e 18931 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
18932 printf ("SSE3");
18933 break;
32930e4e 18934 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
18935 printf ("SSSE3");
18936 break;
32930e4e 18937 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
18938 printf ("SSE4_1");
18939 break;
32930e4e 18940 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
18941 printf ("SSE4_2");
18942 break;
32930e4e 18943 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
18944 printf ("AVX");
18945 break;
32930e4e 18946 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
18947 printf ("AVX2");
18948 break;
32930e4e 18949 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
18950 printf ("FMA");
18951 break;
32930e4e 18952 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
18953 printf ("AVX512F");
18954 break;
32930e4e 18955 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
18956 printf ("AVX512CD");
18957 break;
32930e4e 18958 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
18959 printf ("AVX512ER");
18960 break;
32930e4e 18961 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
18962 printf ("AVX512PF");
18963 break;
32930e4e 18964 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
18965 printf ("AVX512VL");
18966 break;
32930e4e 18967 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
18968 printf ("AVX512DQ");
18969 break;
32930e4e 18970 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
18971 printf ("AVX512BW");
18972 break;
32930e4e 18973 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
18974 printf ("AVX512_4FMAPS");
18975 break;
32930e4e 18976 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
18977 printf ("AVX512_4VNNIW");
18978 break;
32930e4e 18979 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
18980 printf ("AVX512_BITALG");
18981 break;
32930e4e 18982 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
18983 printf ("AVX512_IFMA");
18984 break;
32930e4e 18985 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
18986 printf ("AVX512_VBMI");
18987 break;
32930e4e 18988 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
18989 printf ("AVX512_VBMI2");
18990 break;
32930e4e 18991 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
18992 printf ("AVX512_VNNI");
18993 break;
32930e4e 18994 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
18995 printf ("AVX512_BF16");
18996 break;
65b3d26e
L
18997 default:
18998 printf (_("<unknown: %x>"), bit);
18999 break;
9ef920e9
NC
19000 }
19001 if (bitmask)
19002 printf (", ");
19003 }
19004}
19005
32930e4e
L
19006static void
19007decode_x86_isa (unsigned int bitmask)
19008{
32930e4e
L
19009 while (bitmask)
19010 {
19011 unsigned int bit = bitmask & (- bitmask);
19012
19013 bitmask &= ~ bit;
19014 switch (bit)
19015 {
b0ab0693
L
19016 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19017 printf ("x86-64-baseline");
19018 break;
32930e4e
L
19019 case GNU_PROPERTY_X86_ISA_1_V2:
19020 printf ("x86-64-v2");
19021 break;
19022 case GNU_PROPERTY_X86_ISA_1_V3:
19023 printf ("x86-64-v3");
19024 break;
19025 case GNU_PROPERTY_X86_ISA_1_V4:
19026 printf ("x86-64-v4");
19027 break;
19028 default:
19029 printf (_("<unknown: %x>"), bit);
19030 break;
19031 }
19032 if (bitmask)
19033 printf (", ");
19034 }
19035}
19036
ee2fdd6f 19037static void
a9eafb08 19038decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19039{
0a59decb 19040 if (!bitmask)
90c745dc
L
19041 {
19042 printf (_("<None>"));
19043 return;
19044 }
90c745dc 19045
ee2fdd6f
L
19046 while (bitmask)
19047 {
19048 unsigned int bit = bitmask & (- bitmask);
19049
19050 bitmask &= ~ bit;
19051 switch (bit)
19052 {
19053 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19054 printf ("IBT");
ee2fdd6f 19055 break;
48580982 19056 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19057 printf ("SHSTK");
48580982 19058 break;
279d901e
L
19059 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19060 printf ("LAM_U48");
19061 break;
19062 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19063 printf ("LAM_U57");
19064 break;
ee2fdd6f
L
19065 default:
19066 printf (_("<unknown: %x>"), bit);
19067 break;
19068 }
19069 if (bitmask)
19070 printf (", ");
19071 }
19072}
19073
a9eafb08
L
19074static void
19075decode_x86_feature_2 (unsigned int bitmask)
19076{
0a59decb 19077 if (!bitmask)
90c745dc
L
19078 {
19079 printf (_("<None>"));
19080 return;
19081 }
90c745dc 19082
a9eafb08
L
19083 while (bitmask)
19084 {
19085 unsigned int bit = bitmask & (- bitmask);
19086
19087 bitmask &= ~ bit;
19088 switch (bit)
19089 {
19090 case GNU_PROPERTY_X86_FEATURE_2_X86:
19091 printf ("x86");
19092 break;
19093 case GNU_PROPERTY_X86_FEATURE_2_X87:
19094 printf ("x87");
19095 break;
19096 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19097 printf ("MMX");
19098 break;
19099 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19100 printf ("XMM");
19101 break;
19102 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19103 printf ("YMM");
19104 break;
19105 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19106 printf ("ZMM");
19107 break;
a308b89d
L
19108 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19109 printf ("TMM");
19110 break;
32930e4e
L
19111 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19112 printf ("MASK");
19113 break;
a9eafb08
L
19114 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19115 printf ("FXSR");
19116 break;
19117 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19118 printf ("XSAVE");
19119 break;
19120 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19121 printf ("XSAVEOPT");
19122 break;
19123 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19124 printf ("XSAVEC");
19125 break;
65b3d26e
L
19126 default:
19127 printf (_("<unknown: %x>"), bit);
19128 break;
a9eafb08
L
19129 }
19130 if (bitmask)
19131 printf (", ");
19132 }
19133}
19134
cd702818
SD
19135static void
19136decode_aarch64_feature_1_and (unsigned int bitmask)
19137{
19138 while (bitmask)
19139 {
19140 unsigned int bit = bitmask & (- bitmask);
19141
19142 bitmask &= ~ bit;
19143 switch (bit)
19144 {
19145 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19146 printf ("BTI");
19147 break;
19148
19149 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19150 printf ("PAC");
19151 break;
19152
19153 default:
19154 printf (_("<unknown: %x>"), bit);
19155 break;
19156 }
19157 if (bitmask)
19158 printf (", ");
19159 }
19160}
19161
9ef920e9 19162static void
dda8d76d 19163print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19164{
19165 unsigned char * ptr = (unsigned char *) pnote->descdata;
19166 unsigned char * ptr_end = ptr + pnote->descsz;
19167 unsigned int size = is_32bit_elf ? 4 : 8;
19168
19169 printf (_(" Properties: "));
19170
1fc87489 19171 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19172 {
19173 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19174 return;
19175 }
19176
6ab2c4ed 19177 while (ptr < ptr_end)
9ef920e9 19178 {
1fc87489 19179 unsigned int j;
6ab2c4ed
MC
19180 unsigned int type;
19181 unsigned int datasz;
19182
19183 if ((size_t) (ptr_end - ptr) < 8)
19184 {
19185 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19186 break;
19187 }
19188
19189 type = byte_get (ptr, 4);
19190 datasz = byte_get (ptr + 4, 4);
9ef920e9 19191
1fc87489 19192 ptr += 8;
9ef920e9 19193
6ab2c4ed 19194 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19195 {
1fc87489
L
19196 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19197 type, datasz);
9ef920e9 19198 break;
1fc87489 19199 }
9ef920e9 19200
1fc87489
L
19201 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19202 {
dda8d76d
NC
19203 if (filedata->file_header.e_machine == EM_X86_64
19204 || filedata->file_header.e_machine == EM_IAMCU
19205 || filedata->file_header.e_machine == EM_386)
1fc87489 19206 {
aa7bca9b
L
19207 unsigned int bitmask;
19208
19209 if (datasz == 4)
0a59decb 19210 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19211 else
19212 bitmask = 0;
19213
1fc87489
L
19214 switch (type)
19215 {
19216 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19217 if (datasz != 4)
aa7bca9b
L
19218 printf (_("x86 ISA used: <corrupt length: %#x> "),
19219 datasz);
1fc87489 19220 else
aa7bca9b
L
19221 {
19222 printf ("x86 ISA used: ");
19223 decode_x86_isa (bitmask);
19224 }
1fc87489 19225 goto next;
9ef920e9 19226
1fc87489 19227 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19228 if (datasz != 4)
aa7bca9b
L
19229 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19230 datasz);
1fc87489 19231 else
aa7bca9b
L
19232 {
19233 printf ("x86 ISA needed: ");
19234 decode_x86_isa (bitmask);
19235 }
1fc87489 19236 goto next;
9ef920e9 19237
ee2fdd6f 19238 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19239 if (datasz != 4)
aa7bca9b
L
19240 printf (_("x86 feature: <corrupt length: %#x> "),
19241 datasz);
ee2fdd6f 19242 else
aa7bca9b
L
19243 {
19244 printf ("x86 feature: ");
a9eafb08
L
19245 decode_x86_feature_1 (bitmask);
19246 }
19247 goto next;
19248
19249 case GNU_PROPERTY_X86_FEATURE_2_USED:
19250 if (datasz != 4)
19251 printf (_("x86 feature used: <corrupt length: %#x> "),
19252 datasz);
19253 else
19254 {
19255 printf ("x86 feature used: ");
19256 decode_x86_feature_2 (bitmask);
19257 }
19258 goto next;
19259
19260 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
19261 if (datasz != 4)
19262 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
19263 else
19264 {
19265 printf ("x86 feature needed: ");
19266 decode_x86_feature_2 (bitmask);
19267 }
19268 goto next;
19269
19270 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
19271 if (datasz != 4)
19272 printf (_("x86 ISA used: <corrupt length: %#x> "),
19273 datasz);
19274 else
19275 {
19276 printf ("x86 ISA used: ");
19277 decode_x86_compat_isa (bitmask);
19278 }
19279 goto next;
19280
19281 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
19282 if (datasz != 4)
19283 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19284 datasz);
19285 else
19286 {
19287 printf ("x86 ISA needed: ");
19288 decode_x86_compat_isa (bitmask);
aa7bca9b 19289 }
ee2fdd6f
L
19290 goto next;
19291
32930e4e
L
19292 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
19293 if (datasz != 4)
19294 printf (_("x86 ISA used: <corrupt length: %#x> "),
19295 datasz);
19296 else
19297 {
19298 printf ("x86 ISA used: ");
19299 decode_x86_compat_2_isa (bitmask);
19300 }
19301 goto next;
19302
19303 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
19304 if (datasz != 4)
19305 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19306 datasz);
19307 else
19308 {
19309 printf ("x86 ISA needed: ");
19310 decode_x86_compat_2_isa (bitmask);
19311 }
19312 goto next;
19313
1fc87489
L
19314 default:
19315 break;
19316 }
19317 }
cd702818
SD
19318 else if (filedata->file_header.e_machine == EM_AARCH64)
19319 {
19320 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
19321 {
19322 printf ("AArch64 feature: ");
19323 if (datasz != 4)
19324 printf (_("<corrupt length: %#x> "), datasz);
19325 else
19326 decode_aarch64_feature_1_and (byte_get (ptr, 4));
19327 goto next;
19328 }
19329 }
1fc87489
L
19330 }
19331 else
19332 {
19333 switch (type)
9ef920e9 19334 {
1fc87489
L
19335 case GNU_PROPERTY_STACK_SIZE:
19336 printf (_("stack size: "));
19337 if (datasz != size)
19338 printf (_("<corrupt length: %#x> "), datasz);
19339 else
19340 printf ("%#lx", (unsigned long) byte_get (ptr, size));
19341 goto next;
19342
19343 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
19344 printf ("no copy on protected ");
19345 if (datasz)
19346 printf (_("<corrupt length: %#x> "), datasz);
19347 goto next;
19348
19349 default:
9ef920e9
NC
19350 break;
19351 }
9ef920e9
NC
19352 }
19353
1fc87489
L
19354 if (type < GNU_PROPERTY_LOPROC)
19355 printf (_("<unknown type %#x data: "), type);
19356 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 19357 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
19358 else
19359 printf (_("<application-specific type %#x data: "), type);
19360 for (j = 0; j < datasz; ++j)
19361 printf ("%02x ", ptr[j] & 0xff);
19362 printf (">");
19363
dc1e8a47 19364 next:
9ef920e9 19365 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
19366 if (ptr == ptr_end)
19367 break;
1fc87489 19368
6ab2c4ed
MC
19369 if (do_wide)
19370 printf (", ");
19371 else
19372 printf ("\n\t");
9ef920e9
NC
19373 }
19374
19375 printf ("\n");
19376}
19377
015dc7e1 19378static bool
dda8d76d 19379print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 19380{
1449284b 19381 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
19382 switch (pnote->type)
19383 {
19384 case NT_GNU_BUILD_ID:
19385 {
19386 unsigned long i;
19387
19388 printf (_(" Build ID: "));
19389 for (i = 0; i < pnote->descsz; ++i)
19390 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 19391 printf ("\n");
664f90a3
TT
19392 }
19393 break;
19394
19395 case NT_GNU_ABI_TAG:
19396 {
19397 unsigned long os, major, minor, subminor;
19398 const char *osname;
19399
3102e897
NC
19400 /* PR 17531: file: 030-599401-0.004. */
19401 if (pnote->descsz < 16)
19402 {
19403 printf (_(" <corrupt GNU_ABI_TAG>\n"));
19404 break;
19405 }
19406
664f90a3
TT
19407 os = byte_get ((unsigned char *) pnote->descdata, 4);
19408 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19409 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
19410 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
19411
19412 switch (os)
19413 {
19414 case GNU_ABI_TAG_LINUX:
19415 osname = "Linux";
19416 break;
19417 case GNU_ABI_TAG_HURD:
19418 osname = "Hurd";
19419 break;
19420 case GNU_ABI_TAG_SOLARIS:
19421 osname = "Solaris";
19422 break;
19423 case GNU_ABI_TAG_FREEBSD:
19424 osname = "FreeBSD";
19425 break;
19426 case GNU_ABI_TAG_NETBSD:
19427 osname = "NetBSD";
19428 break;
14ae95f2
RM
19429 case GNU_ABI_TAG_SYLLABLE:
19430 osname = "Syllable";
19431 break;
19432 case GNU_ABI_TAG_NACL:
19433 osname = "NaCl";
19434 break;
664f90a3
TT
19435 default:
19436 osname = "Unknown";
19437 break;
19438 }
19439
19440 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
19441 major, minor, subminor);
19442 }
19443 break;
926c5385
CC
19444
19445 case NT_GNU_GOLD_VERSION:
19446 {
19447 unsigned long i;
19448
19449 printf (_(" Version: "));
19450 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
19451 printf ("%c", pnote->descdata[i]);
19452 printf ("\n");
19453 }
19454 break;
1449284b
NC
19455
19456 case NT_GNU_HWCAP:
19457 {
19458 unsigned long num_entries, mask;
19459
19460 /* Hardware capabilities information. Word 0 is the number of entries.
19461 Word 1 is a bitmask of enabled entries. The rest of the descriptor
19462 is a series of entries, where each entry is a single byte followed
19463 by a nul terminated string. The byte gives the bit number to test
19464 if enabled in the bitmask. */
19465 printf (_(" Hardware Capabilities: "));
19466 if (pnote->descsz < 8)
19467 {
32ec8896 19468 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 19469 return false;
1449284b
NC
19470 }
19471 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
19472 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19473 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
19474 /* FIXME: Add code to display the entries... */
19475 }
19476 break;
19477
9ef920e9 19478 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 19479 print_gnu_property_note (filedata, pnote);
9ef920e9 19480 break;
9abca702 19481
1449284b
NC
19482 default:
19483 /* Handle unrecognised types. An error message should have already been
19484 created by get_gnu_elf_note_type(), so all that we need to do is to
19485 display the data. */
19486 {
19487 unsigned long i;
19488
19489 printf (_(" Description data: "));
19490 for (i = 0; i < pnote->descsz; ++i)
19491 printf ("%02x ", pnote->descdata[i] & 0xff);
19492 printf ("\n");
19493 }
19494 break;
664f90a3
TT
19495 }
19496
015dc7e1 19497 return true;
664f90a3
TT
19498}
19499
685080f2
NC
19500static const char *
19501get_v850_elf_note_type (enum v850_notes n_type)
19502{
19503 static char buff[64];
19504
19505 switch (n_type)
19506 {
19507 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
19508 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
19509 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
19510 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
19511 case V850_NOTE_CACHE_INFO: return _("Use of cache");
19512 case V850_NOTE_MMU_INFO: return _("Use of MMU");
19513 default:
19514 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
19515 return buff;
19516 }
19517}
19518
015dc7e1 19519static bool
685080f2
NC
19520print_v850_note (Elf_Internal_Note * pnote)
19521{
19522 unsigned int val;
19523
19524 if (pnote->descsz != 4)
015dc7e1 19525 return false;
32ec8896 19526
685080f2
NC
19527 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
19528
19529 if (val == 0)
19530 {
19531 printf (_("not set\n"));
015dc7e1 19532 return true;
685080f2
NC
19533 }
19534
19535 switch (pnote->type)
19536 {
19537 case V850_NOTE_ALIGNMENT:
19538 switch (val)
19539 {
015dc7e1
AM
19540 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
19541 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
19542 }
19543 break;
14ae95f2 19544
685080f2
NC
19545 case V850_NOTE_DATA_SIZE:
19546 switch (val)
19547 {
015dc7e1
AM
19548 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
19549 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
19550 }
19551 break;
14ae95f2 19552
685080f2
NC
19553 case V850_NOTE_FPU_INFO:
19554 switch (val)
19555 {
015dc7e1
AM
19556 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
19557 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
19558 }
19559 break;
14ae95f2 19560
685080f2
NC
19561 case V850_NOTE_MMU_INFO:
19562 case V850_NOTE_CACHE_INFO:
19563 case V850_NOTE_SIMD_INFO:
19564 if (val == EF_RH850_SIMD)
19565 {
19566 printf (_("yes\n"));
015dc7e1 19567 return true;
685080f2
NC
19568 }
19569 break;
19570
19571 default:
19572 /* An 'unknown note type' message will already have been displayed. */
19573 break;
19574 }
19575
19576 printf (_("unknown value: %x\n"), val);
015dc7e1 19577 return false;
685080f2
NC
19578}
19579
015dc7e1 19580static bool
c6056a74
SF
19581process_netbsd_elf_note (Elf_Internal_Note * pnote)
19582{
19583 unsigned int version;
19584
19585 switch (pnote->type)
19586 {
19587 case NT_NETBSD_IDENT:
b966f55f
AM
19588 if (pnote->descsz < 1)
19589 break;
c6056a74
SF
19590 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19591 if ((version / 10000) % 100)
b966f55f 19592 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
19593 version, version / 100000000, (version / 1000000) % 100,
19594 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 19595 'A' + (version / 10000) % 26);
c6056a74
SF
19596 else
19597 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 19598 version, version / 100000000, (version / 1000000) % 100,
15f205b1 19599 (version / 100) % 100);
015dc7e1 19600 return true;
c6056a74
SF
19601
19602 case NT_NETBSD_MARCH:
9abca702 19603 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 19604 pnote->descdata);
015dc7e1 19605 return true;
c6056a74 19606
9abca702 19607 case NT_NETBSD_PAX:
b966f55f
AM
19608 if (pnote->descsz < 1)
19609 break;
9abca702
CZ
19610 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19611 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
19612 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
19613 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
19614 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
19615 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
19616 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
19617 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 19618 return true;
c6056a74 19619 }
b966f55f
AM
19620
19621 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
19622 pnote->descsz, pnote->type);
015dc7e1 19623 return false;
c6056a74
SF
19624}
19625
f4ddf30f 19626static const char *
dda8d76d 19627get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 19628{
f4ddf30f
JB
19629 switch (e_type)
19630 {
19631 case NT_FREEBSD_THRMISC:
19632 return _("NT_THRMISC (thrmisc structure)");
19633 case NT_FREEBSD_PROCSTAT_PROC:
19634 return _("NT_PROCSTAT_PROC (proc data)");
19635 case NT_FREEBSD_PROCSTAT_FILES:
19636 return _("NT_PROCSTAT_FILES (files data)");
19637 case NT_FREEBSD_PROCSTAT_VMMAP:
19638 return _("NT_PROCSTAT_VMMAP (vmmap data)");
19639 case NT_FREEBSD_PROCSTAT_GROUPS:
19640 return _("NT_PROCSTAT_GROUPS (groups data)");
19641 case NT_FREEBSD_PROCSTAT_UMASK:
19642 return _("NT_PROCSTAT_UMASK (umask data)");
19643 case NT_FREEBSD_PROCSTAT_RLIMIT:
19644 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
19645 case NT_FREEBSD_PROCSTAT_OSREL:
19646 return _("NT_PROCSTAT_OSREL (osreldate data)");
19647 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
19648 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
19649 case NT_FREEBSD_PROCSTAT_AUXV:
19650 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
19651 case NT_FREEBSD_PTLWPINFO:
19652 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 19653 }
dda8d76d 19654 return get_note_type (filedata, e_type);
f4ddf30f
JB
19655}
19656
9437c45b 19657static const char *
dda8d76d 19658get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
19659{
19660 static char buff[64];
19661
540e6170
CZ
19662 switch (e_type)
19663 {
19664 case NT_NETBSDCORE_PROCINFO:
19665 /* NetBSD core "procinfo" structure. */
19666 return _("NetBSD procinfo structure");
9437c45b 19667
540e6170
CZ
19668 case NT_NETBSDCORE_AUXV:
19669 return _("NetBSD ELF auxiliary vector data");
9437c45b 19670
06d949ec
KR
19671 case NT_NETBSDCORE_LWPSTATUS:
19672 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 19673
540e6170 19674 default:
06d949ec 19675 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
19676 defined for NetBSD core files. If the note type is less
19677 than the start of the machine-dependent note types, we don't
19678 understand it. */
19679
19680 if (e_type < NT_NETBSDCORE_FIRSTMACH)
19681 {
19682 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19683 return buff;
19684 }
19685 break;
9437c45b
JT
19686 }
19687
dda8d76d 19688 switch (filedata->file_header.e_machine)
9437c45b
JT
19689 {
19690 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
19691 and PT_GETFPREGS == mach+2. */
19692
19693 case EM_OLD_ALPHA:
19694 case EM_ALPHA:
19695 case EM_SPARC:
19696 case EM_SPARC32PLUS:
19697 case EM_SPARCV9:
19698 switch (e_type)
19699 {
2b692964 19700 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 19701 return _("PT_GETREGS (reg structure)");
2b692964 19702 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 19703 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19704 default:
19705 break;
19706 }
19707 break;
19708
c0d38b0e
CZ
19709 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
19710 There's also old PT___GETREGS40 == mach + 1 for old reg
19711 structure which lacks GBR. */
19712 case EM_SH:
19713 switch (e_type)
19714 {
19715 case NT_NETBSDCORE_FIRSTMACH + 1:
19716 return _("PT___GETREGS40 (old reg structure)");
19717 case NT_NETBSDCORE_FIRSTMACH + 3:
19718 return _("PT_GETREGS (reg structure)");
19719 case NT_NETBSDCORE_FIRSTMACH + 5:
19720 return _("PT_GETFPREGS (fpreg structure)");
19721 default:
19722 break;
19723 }
19724 break;
19725
9437c45b
JT
19726 /* On all other arch's, PT_GETREGS == mach+1 and
19727 PT_GETFPREGS == mach+3. */
19728 default:
19729 switch (e_type)
19730 {
2b692964 19731 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 19732 return _("PT_GETREGS (reg structure)");
2b692964 19733 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 19734 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19735 default:
19736 break;
19737 }
19738 }
19739
9cf03b7e 19740 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 19741 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
19742 return buff;
19743}
19744
70616151
TT
19745static const char *
19746get_stapsdt_note_type (unsigned e_type)
19747{
19748 static char buff[64];
19749
19750 switch (e_type)
19751 {
19752 case NT_STAPSDT:
19753 return _("NT_STAPSDT (SystemTap probe descriptors)");
19754
19755 default:
19756 break;
19757 }
19758
19759 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19760 return buff;
19761}
19762
015dc7e1 19763static bool
c6a9fc58
TT
19764print_stapsdt_note (Elf_Internal_Note *pnote)
19765{
3ca60c57
NC
19766 size_t len, maxlen;
19767 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
19768 char *data = pnote->descdata;
19769 char *data_end = pnote->descdata + pnote->descsz;
19770 bfd_vma pc, base_addr, semaphore;
19771 char *provider, *probe, *arg_fmt;
19772
3ca60c57
NC
19773 if (pnote->descsz < (addr_size * 3))
19774 goto stapdt_note_too_small;
19775
c6a9fc58
TT
19776 pc = byte_get ((unsigned char *) data, addr_size);
19777 data += addr_size;
3ca60c57 19778
c6a9fc58
TT
19779 base_addr = byte_get ((unsigned char *) data, addr_size);
19780 data += addr_size;
3ca60c57 19781
c6a9fc58
TT
19782 semaphore = byte_get ((unsigned char *) data, addr_size);
19783 data += addr_size;
19784
3ca60c57
NC
19785 if (data >= data_end)
19786 goto stapdt_note_too_small;
19787 maxlen = data_end - data;
19788 len = strnlen (data, maxlen);
19789 if (len < maxlen)
19790 {
19791 provider = data;
19792 data += len + 1;
19793 }
19794 else
19795 goto stapdt_note_too_small;
19796
19797 if (data >= data_end)
19798 goto stapdt_note_too_small;
19799 maxlen = data_end - data;
19800 len = strnlen (data, maxlen);
19801 if (len < maxlen)
19802 {
19803 probe = data;
19804 data += len + 1;
19805 }
19806 else
19807 goto stapdt_note_too_small;
9abca702 19808
3ca60c57
NC
19809 if (data >= data_end)
19810 goto stapdt_note_too_small;
19811 maxlen = data_end - data;
19812 len = strnlen (data, maxlen);
19813 if (len < maxlen)
19814 {
19815 arg_fmt = data;
19816 data += len + 1;
19817 }
19818 else
19819 goto stapdt_note_too_small;
c6a9fc58
TT
19820
19821 printf (_(" Provider: %s\n"), provider);
19822 printf (_(" Name: %s\n"), probe);
19823 printf (_(" Location: "));
19824 print_vma (pc, FULL_HEX);
19825 printf (_(", Base: "));
19826 print_vma (base_addr, FULL_HEX);
19827 printf (_(", Semaphore: "));
19828 print_vma (semaphore, FULL_HEX);
9cf03b7e 19829 printf ("\n");
c6a9fc58
TT
19830 printf (_(" Arguments: %s\n"), arg_fmt);
19831
19832 return data == data_end;
3ca60c57
NC
19833
19834 stapdt_note_too_small:
19835 printf (_(" <corrupt - note is too small>\n"));
19836 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 19837 return false;
c6a9fc58
TT
19838}
19839
00e98fc7
TG
19840static const char *
19841get_ia64_vms_note_type (unsigned e_type)
19842{
19843 static char buff[64];
19844
19845 switch (e_type)
19846 {
19847 case NT_VMS_MHD:
19848 return _("NT_VMS_MHD (module header)");
19849 case NT_VMS_LNM:
19850 return _("NT_VMS_LNM (language name)");
19851 case NT_VMS_SRC:
19852 return _("NT_VMS_SRC (source files)");
19853 case NT_VMS_TITLE:
9cf03b7e 19854 return "NT_VMS_TITLE";
00e98fc7
TG
19855 case NT_VMS_EIDC:
19856 return _("NT_VMS_EIDC (consistency check)");
19857 case NT_VMS_FPMODE:
19858 return _("NT_VMS_FPMODE (FP mode)");
19859 case NT_VMS_LINKTIME:
9cf03b7e 19860 return "NT_VMS_LINKTIME";
00e98fc7
TG
19861 case NT_VMS_IMGNAM:
19862 return _("NT_VMS_IMGNAM (image name)");
19863 case NT_VMS_IMGID:
19864 return _("NT_VMS_IMGID (image id)");
19865 case NT_VMS_LINKID:
19866 return _("NT_VMS_LINKID (link id)");
19867 case NT_VMS_IMGBID:
19868 return _("NT_VMS_IMGBID (build id)");
19869 case NT_VMS_GSTNAM:
19870 return _("NT_VMS_GSTNAM (sym table name)");
19871 case NT_VMS_ORIG_DYN:
9cf03b7e 19872 return "NT_VMS_ORIG_DYN";
00e98fc7 19873 case NT_VMS_PATCHTIME:
9cf03b7e 19874 return "NT_VMS_PATCHTIME";
00e98fc7
TG
19875 default:
19876 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19877 return buff;
19878 }
19879}
19880
015dc7e1 19881static bool
00e98fc7
TG
19882print_ia64_vms_note (Elf_Internal_Note * pnote)
19883{
8d18bf79
NC
19884 int maxlen = pnote->descsz;
19885
19886 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
19887 goto desc_size_fail;
19888
00e98fc7
TG
19889 switch (pnote->type)
19890 {
19891 case NT_VMS_MHD:
8d18bf79
NC
19892 if (maxlen <= 36)
19893 goto desc_size_fail;
19894
19895 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
19896
19897 printf (_(" Creation date : %.17s\n"), pnote->descdata);
19898 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
19899 if (l + 34 < maxlen)
19900 {
19901 printf (_(" Module name : %s\n"), pnote->descdata + 34);
19902 if (l + 35 < maxlen)
19903 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
19904 else
19905 printf (_(" Module version : <missing>\n"));
19906 }
00e98fc7 19907 else
8d18bf79
NC
19908 {
19909 printf (_(" Module name : <missing>\n"));
19910 printf (_(" Module version : <missing>\n"));
19911 }
00e98fc7 19912 break;
8d18bf79 19913
00e98fc7 19914 case NT_VMS_LNM:
8d18bf79 19915 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19916 break;
8d18bf79 19917
00e98fc7
TG
19918#ifdef BFD64
19919 case NT_VMS_FPMODE:
9cf03b7e 19920 printf (_(" Floating Point mode: "));
8d18bf79
NC
19921 if (maxlen < 8)
19922 goto desc_size_fail;
19923 /* FIXME: Generate an error if descsz > 8 ? */
19924
4a5cb34f 19925 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 19926 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 19927 break;
8d18bf79 19928
00e98fc7
TG
19929 case NT_VMS_LINKTIME:
19930 printf (_(" Link time: "));
8d18bf79
NC
19931 if (maxlen < 8)
19932 goto desc_size_fail;
19933 /* FIXME: Generate an error if descsz > 8 ? */
19934
00e98fc7 19935 print_vms_time
8d18bf79 19936 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19937 printf ("\n");
19938 break;
8d18bf79 19939
00e98fc7
TG
19940 case NT_VMS_PATCHTIME:
19941 printf (_(" Patch time: "));
8d18bf79
NC
19942 if (maxlen < 8)
19943 goto desc_size_fail;
19944 /* FIXME: Generate an error if descsz > 8 ? */
19945
00e98fc7 19946 print_vms_time
8d18bf79 19947 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19948 printf ("\n");
19949 break;
8d18bf79 19950
00e98fc7 19951 case NT_VMS_ORIG_DYN:
8d18bf79
NC
19952 if (maxlen < 34)
19953 goto desc_size_fail;
19954
00e98fc7
TG
19955 printf (_(" Major id: %u, minor id: %u\n"),
19956 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
19957 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 19958 printf (_(" Last modified : "));
00e98fc7
TG
19959 print_vms_time
19960 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 19961 printf (_("\n Link flags : "));
4a5cb34f 19962 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 19963 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 19964 printf (_(" Header flags: 0x%08x\n"),
948f632f 19965 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 19966 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
19967 break;
19968#endif
8d18bf79 19969
00e98fc7 19970 case NT_VMS_IMGNAM:
8d18bf79 19971 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19972 break;
8d18bf79 19973
00e98fc7 19974 case NT_VMS_GSTNAM:
8d18bf79 19975 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19976 break;
8d18bf79 19977
00e98fc7 19978 case NT_VMS_IMGID:
8d18bf79 19979 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19980 break;
8d18bf79 19981
00e98fc7 19982 case NT_VMS_LINKID:
8d18bf79 19983 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19984 break;
8d18bf79 19985
00e98fc7 19986 default:
015dc7e1 19987 return false;
00e98fc7 19988 }
8d18bf79 19989
015dc7e1 19990 return true;
8d18bf79
NC
19991
19992 desc_size_fail:
19993 printf (_(" <corrupt - data size is too small>\n"));
19994 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 19995 return false;
00e98fc7
TG
19996}
19997
fd486f32
AM
19998struct build_attr_cache {
19999 Filedata *filedata;
20000 char *strtab;
20001 unsigned long strtablen;
20002 Elf_Internal_Sym *symtab;
20003 unsigned long nsyms;
20004} ba_cache;
20005
6f156d7a
NC
20006/* Find the symbol associated with a build attribute that is attached
20007 to address OFFSET. If PNAME is non-NULL then store the name of
20008 the symbol (if found) in the provided pointer, Returns NULL if a
20009 symbol could not be found. */
c799a79d 20010
6f156d7a 20011static Elf_Internal_Sym *
015dc7e1
AM
20012get_symbol_for_build_attribute (Filedata *filedata,
20013 unsigned long offset,
20014 bool is_open_attr,
20015 const char **pname)
9ef920e9 20016{
fd486f32
AM
20017 Elf_Internal_Sym *saved_sym = NULL;
20018 Elf_Internal_Sym *sym;
9ef920e9 20019
dda8d76d 20020 if (filedata->section_headers != NULL
fd486f32 20021 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20022 {
c799a79d 20023 Elf_Internal_Shdr * symsec;
9ef920e9 20024
fd486f32
AM
20025 free (ba_cache.strtab);
20026 ba_cache.strtab = NULL;
20027 free (ba_cache.symtab);
20028 ba_cache.symtab = NULL;
20029
c799a79d 20030 /* Load the symbol and string sections. */
dda8d76d
NC
20031 for (symsec = filedata->section_headers;
20032 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20033 symsec ++)
9ef920e9 20034 {
28d13567
AM
20035 if (symsec->sh_type == SHT_SYMTAB
20036 && get_symtab (filedata, symsec,
20037 &ba_cache.symtab, &ba_cache.nsyms,
20038 &ba_cache.strtab, &ba_cache.strtablen))
20039 break;
9ef920e9 20040 }
fd486f32 20041 ba_cache.filedata = filedata;
9ef920e9
NC
20042 }
20043
fd486f32 20044 if (ba_cache.symtab == NULL)
6f156d7a 20045 return NULL;
9ef920e9 20046
c799a79d 20047 /* Find a symbol whose value matches offset. */
fd486f32 20048 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20049 if (sym->st_value == offset)
20050 {
fd486f32 20051 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20052 /* Huh ? This should not happen. */
20053 continue;
9ef920e9 20054
fd486f32 20055 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20056 continue;
9ef920e9 20057
8fd75781
NC
20058 /* The AArch64 and ARM architectures define mapping symbols
20059 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20060 if (ba_cache.strtab[sym->st_name] == '$'
20061 && ba_cache.strtab[sym->st_name + 1] != 0
20062 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20063 continue;
20064
c799a79d
NC
20065 if (is_open_attr)
20066 {
20067 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20068 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20069 FUNC symbols entirely. */
20070 switch (ELF_ST_TYPE (sym->st_info))
20071 {
c799a79d 20072 case STT_OBJECT:
6f156d7a 20073 case STT_FILE:
c799a79d 20074 saved_sym = sym;
6f156d7a
NC
20075 if (sym->st_size)
20076 {
20077 /* If the symbol has a size associated
20078 with it then we can stop searching. */
fd486f32 20079 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20080 }
c799a79d 20081 continue;
9ef920e9 20082
c799a79d
NC
20083 case STT_FUNC:
20084 /* Ignore function symbols. */
20085 continue;
20086
20087 default:
20088 break;
20089 }
20090
20091 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20092 {
c799a79d
NC
20093 case STB_GLOBAL:
20094 if (saved_sym == NULL
20095 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20096 saved_sym = sym;
20097 break;
c871dade 20098
c799a79d
NC
20099 case STB_LOCAL:
20100 if (saved_sym == NULL)
20101 saved_sym = sym;
20102 break;
20103
20104 default:
9ef920e9
NC
20105 break;
20106 }
20107 }
c799a79d
NC
20108 else
20109 {
20110 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20111 continue;
20112
20113 saved_sym = sym;
20114 break;
20115 }
20116 }
20117
6f156d7a 20118 if (saved_sym && pname)
fd486f32 20119 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20120
20121 return saved_sym;
c799a79d
NC
20122}
20123
d20e98ab
NC
20124/* Returns true iff addr1 and addr2 are in the same section. */
20125
015dc7e1 20126static bool
d20e98ab
NC
20127same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20128{
20129 Elf_Internal_Shdr * a1;
20130 Elf_Internal_Shdr * a2;
20131
20132 a1 = find_section_by_address (filedata, addr1);
20133 a2 = find_section_by_address (filedata, addr2);
9abca702 20134
d20e98ab
NC
20135 return a1 == a2 && a1 != NULL;
20136}
20137
015dc7e1 20138static bool
dda8d76d
NC
20139print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20140 Filedata * filedata)
c799a79d 20141{
015dc7e1
AM
20142 static unsigned long global_offset = 0;
20143 static unsigned long global_end = 0;
20144 static unsigned long func_offset = 0;
20145 static unsigned long func_end = 0;
c871dade 20146
015dc7e1
AM
20147 Elf_Internal_Sym *sym;
20148 const char *name;
20149 unsigned long start;
20150 unsigned long end;
20151 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20152
20153 switch (pnote->descsz)
c799a79d 20154 {
6f156d7a
NC
20155 case 0:
20156 /* A zero-length description means that the range of
20157 the previous note of the same type should be used. */
c799a79d 20158 if (is_open_attr)
c871dade 20159 {
6f156d7a
NC
20160 if (global_end > global_offset)
20161 printf (_(" Applies to region from %#lx to %#lx\n"),
20162 global_offset, global_end);
20163 else
20164 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20165 }
20166 else
20167 {
6f156d7a
NC
20168 if (func_end > func_offset)
20169 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20170 else
20171 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20172 }
015dc7e1 20173 return true;
9ef920e9 20174
6f156d7a
NC
20175 case 4:
20176 start = byte_get ((unsigned char *) pnote->descdata, 4);
20177 end = 0;
20178 break;
20179
20180 case 8:
c74147bb
NC
20181 start = byte_get ((unsigned char *) pnote->descdata, 4);
20182 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20183 break;
20184
20185 case 16:
20186 start = byte_get ((unsigned char *) pnote->descdata, 8);
20187 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20188 break;
9abca702 20189
6f156d7a 20190 default:
c799a79d
NC
20191 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
20192 printf (_(" <invalid descsz>"));
015dc7e1 20193 return false;
c799a79d
NC
20194 }
20195
6f156d7a
NC
20196 name = NULL;
20197 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
20198 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
20199 in order to avoid them being confused with the start address of the
20200 first function in the file... */
20201 if (sym == NULL && is_open_attr)
20202 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
20203 & name);
6f156d7a
NC
20204
20205 if (end == 0 && sym != NULL && sym->st_size > 0)
20206 end = start + sym->st_size;
c799a79d
NC
20207
20208 if (is_open_attr)
20209 {
d20e98ab
NC
20210 /* FIXME: Need to properly allow for section alignment.
20211 16 is just the alignment used on x86_64. */
20212 if (global_end > 0
20213 && start > BFD_ALIGN (global_end, 16)
20214 /* Build notes are not guaranteed to be organised in order of
20215 increasing address, but we should find the all of the notes
20216 for one section in the same place. */
20217 && same_section (filedata, start, global_end))
6f156d7a
NC
20218 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
20219 global_end + 1, start - 1);
20220
20221 printf (_(" Applies to region from %#lx"), start);
20222 global_offset = start;
20223
20224 if (end)
20225 {
20226 printf (_(" to %#lx"), end);
20227 global_end = end;
20228 }
c799a79d
NC
20229 }
20230 else
20231 {
6f156d7a
NC
20232 printf (_(" Applies to region from %#lx"), start);
20233 func_offset = start;
20234
20235 if (end)
20236 {
20237 printf (_(" to %#lx"), end);
20238 func_end = end;
20239 }
c799a79d
NC
20240 }
20241
6f156d7a
NC
20242 if (sym && name)
20243 printf (_(" (%s)"), name);
20244
20245 printf ("\n");
015dc7e1 20246 return true;
9ef920e9
NC
20247}
20248
015dc7e1 20249static bool
9ef920e9
NC
20250print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
20251{
1d15e434
NC
20252 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
20253 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
20254 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
20255 char name_type;
20256 char name_attribute;
1d15e434 20257 const char * expected_types;
9ef920e9
NC
20258 const char * name = pnote->namedata;
20259 const char * text;
88305e1b 20260 signed int left;
9ef920e9
NC
20261
20262 if (name == NULL || pnote->namesz < 2)
20263 {
20264 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 20265 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20266 return false;
9ef920e9
NC
20267 }
20268
6f156d7a
NC
20269 if (do_wide)
20270 left = 28;
20271 else
20272 left = 20;
88305e1b
NC
20273
20274 /* Version 2 of the spec adds a "GA" prefix to the name field. */
20275 if (name[0] == 'G' && name[1] == 'A')
20276 {
6f156d7a
NC
20277 if (pnote->namesz < 4)
20278 {
20279 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
20280 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20281 return false;
6f156d7a
NC
20282 }
20283
88305e1b
NC
20284 printf ("GA");
20285 name += 2;
20286 left -= 2;
20287 }
20288
9ef920e9
NC
20289 switch ((name_type = * name))
20290 {
20291 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20292 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20293 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20294 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20295 printf ("%c", * name);
88305e1b 20296 left --;
9ef920e9
NC
20297 break;
20298 default:
20299 error (_("unrecognised attribute type in name field: %d\n"), name_type);
20300 print_symbol (-20, _("<unknown name type>"));
015dc7e1 20301 return false;
9ef920e9
NC
20302 }
20303
9ef920e9
NC
20304 ++ name;
20305 text = NULL;
20306
20307 switch ((name_attribute = * name))
20308 {
20309 case GNU_BUILD_ATTRIBUTE_VERSION:
20310 text = _("<version>");
1d15e434 20311 expected_types = string_expected;
9ef920e9
NC
20312 ++ name;
20313 break;
20314 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20315 text = _("<stack prot>");
75d7d298 20316 expected_types = "!+*";
9ef920e9
NC
20317 ++ name;
20318 break;
20319 case GNU_BUILD_ATTRIBUTE_RELRO:
20320 text = _("<relro>");
1d15e434 20321 expected_types = bool_expected;
9ef920e9
NC
20322 ++ name;
20323 break;
20324 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
20325 text = _("<stack size>");
1d15e434 20326 expected_types = number_expected;
9ef920e9
NC
20327 ++ name;
20328 break;
20329 case GNU_BUILD_ATTRIBUTE_TOOL:
20330 text = _("<tool>");
1d15e434 20331 expected_types = string_expected;
9ef920e9
NC
20332 ++ name;
20333 break;
20334 case GNU_BUILD_ATTRIBUTE_ABI:
20335 text = _("<ABI>");
20336 expected_types = "$*";
20337 ++ name;
20338 break;
20339 case GNU_BUILD_ATTRIBUTE_PIC:
20340 text = _("<PIC>");
1d15e434 20341 expected_types = number_expected;
9ef920e9
NC
20342 ++ name;
20343 break;
a8be5506
NC
20344 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
20345 text = _("<short enum>");
1d15e434 20346 expected_types = bool_expected;
a8be5506
NC
20347 ++ name;
20348 break;
9ef920e9
NC
20349 default:
20350 if (ISPRINT (* name))
20351 {
20352 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
20353
20354 if (len > left && ! do_wide)
20355 len = left;
75d7d298 20356 printf ("%.*s:", len, name);
9ef920e9 20357 left -= len;
0dd6ae21 20358 name += len;
9ef920e9
NC
20359 }
20360 else
20361 {
3e6b6445 20362 static char tmpbuf [128];
88305e1b 20363
3e6b6445
NC
20364 error (_("unrecognised byte in name field: %d\n"), * name);
20365 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
20366 text = tmpbuf;
20367 name ++;
9ef920e9
NC
20368 }
20369 expected_types = "*$!+";
20370 break;
20371 }
20372
20373 if (text)
88305e1b 20374 left -= printf ("%s", text);
9ef920e9
NC
20375
20376 if (strchr (expected_types, name_type) == NULL)
75d7d298 20377 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
20378
20379 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
20380 {
20381 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
20382 (unsigned long) pnote->namesz,
20383 (long) (name - pnote->namedata));
015dc7e1 20384 return false;
9ef920e9
NC
20385 }
20386
20387 if (left < 1 && ! do_wide)
015dc7e1 20388 return true;
9ef920e9
NC
20389
20390 switch (name_type)
20391 {
20392 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20393 {
b06b2c92 20394 unsigned int bytes;
ddef72cd
NC
20395 unsigned long long val = 0;
20396 unsigned int shift = 0;
20397 char * decoded = NULL;
20398
b06b2c92
NC
20399 bytes = pnote->namesz - (name - pnote->namedata);
20400 if (bytes > 0)
20401 /* The -1 is because the name field is always 0 terminated, and we
20402 want to be able to ensure that the shift in the while loop below
20403 will not overflow. */
20404 -- bytes;
20405
ddef72cd
NC
20406 if (bytes > sizeof (val))
20407 {
3e6b6445
NC
20408 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
20409 bytes);
20410 bytes = sizeof (val);
ddef72cd 20411 }
3e6b6445
NC
20412 /* We do not bother to warn if bytes == 0 as this can
20413 happen with some early versions of the gcc plugin. */
9ef920e9
NC
20414
20415 while (bytes --)
20416 {
54b8331d 20417 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
20418
20419 val |= byte << shift;
9ef920e9
NC
20420 shift += 8;
20421 }
20422
75d7d298 20423 switch (name_attribute)
9ef920e9 20424 {
75d7d298 20425 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
20426 switch (val)
20427 {
75d7d298
NC
20428 case 0: decoded = "static"; break;
20429 case 1: decoded = "pic"; break;
20430 case 2: decoded = "PIC"; break;
20431 case 3: decoded = "pie"; break;
20432 case 4: decoded = "PIE"; break;
20433 default: break;
9ef920e9 20434 }
75d7d298
NC
20435 break;
20436 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20437 switch (val)
9ef920e9 20438 {
75d7d298
NC
20439 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
20440 case 0: decoded = "off"; break;
20441 case 1: decoded = "on"; break;
20442 case 2: decoded = "all"; break;
20443 case 3: decoded = "strong"; break;
20444 case 4: decoded = "explicit"; break;
20445 default: break;
9ef920e9 20446 }
75d7d298
NC
20447 break;
20448 default:
20449 break;
9ef920e9
NC
20450 }
20451
75d7d298 20452 if (decoded != NULL)
3e6b6445
NC
20453 {
20454 print_symbol (-left, decoded);
20455 left = 0;
20456 }
20457 else if (val == 0)
20458 {
20459 printf ("0x0");
20460 left -= 3;
20461 }
9ef920e9 20462 else
75d7d298
NC
20463 {
20464 if (do_wide)
ddef72cd 20465 left -= printf ("0x%llx", val);
75d7d298 20466 else
ddef72cd 20467 left -= printf ("0x%-.*llx", left, val);
75d7d298 20468 }
9ef920e9
NC
20469 }
20470 break;
20471 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20472 left -= print_symbol (- left, name);
20473 break;
20474 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20475 left -= print_symbol (- left, "true");
20476 break;
20477 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20478 left -= print_symbol (- left, "false");
20479 break;
20480 }
20481
20482 if (do_wide && left > 0)
20483 printf ("%-*s", left, " ");
9abca702 20484
015dc7e1 20485 return true;
9ef920e9
NC
20486}
20487
6d118b09
NC
20488/* Note that by the ELF standard, the name field is already null byte
20489 terminated, and namesz includes the terminating null byte.
20490 I.E. the value of namesz for the name "FSF" is 4.
20491
e3c8793a 20492 If the value of namesz is zero, there is no name present. */
9ef920e9 20493
015dc7e1 20494static bool
9ef920e9 20495process_note (Elf_Internal_Note * pnote,
dda8d76d 20496 Filedata * filedata)
779fe533 20497{
2cf0635d
NC
20498 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
20499 const char * nt;
9437c45b
JT
20500
20501 if (pnote->namesz == 0)
1ec5cd37
NC
20502 /* If there is no note name, then use the default set of
20503 note type strings. */
dda8d76d 20504 nt = get_note_type (filedata, pnote->type);
1ec5cd37 20505
24d127aa 20506 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
20507 /* GNU-specific object file notes. */
20508 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 20509
24d127aa 20510 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 20511 /* FreeBSD-specific core file notes. */
dda8d76d 20512 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 20513
24d127aa 20514 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 20515 /* NetBSD-specific core file notes. */
dda8d76d 20516 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 20517
24d127aa 20518 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
20519 /* NetBSD-specific core file notes. */
20520 return process_netbsd_elf_note (pnote);
20521
24d127aa 20522 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
20523 /* NetBSD-specific core file notes. */
20524 return process_netbsd_elf_note (pnote);
20525
e9b095a5 20526 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
20527 {
20528 /* SPU-specific core file notes. */
20529 nt = pnote->namedata + 4;
20530 name = "SPU";
20531 }
20532
24d127aa 20533 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
20534 /* VMS/ia64-specific file notes. */
20535 nt = get_ia64_vms_note_type (pnote->type);
20536
24d127aa 20537 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
20538 nt = get_stapsdt_note_type (pnote->type);
20539
9437c45b 20540 else
1ec5cd37
NC
20541 /* Don't recognize this note name; just use the default set of
20542 note type strings. */
dda8d76d 20543 nt = get_note_type (filedata, pnote->type);
9437c45b 20544
1449284b 20545 printf (" ");
9ef920e9 20546
24d127aa 20547 if (((startswith (pnote->namedata, "GA")
483767a3
AM
20548 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20549 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20550 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20551 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
20552 print_gnu_build_attribute_name (pnote);
20553 else
20554 print_symbol (-20, name);
20555
20556 if (do_wide)
20557 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
20558 else
20559 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 20560
24d127aa 20561 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 20562 return print_ia64_vms_note (pnote);
24d127aa 20563 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 20564 return print_gnu_note (filedata, pnote);
24d127aa 20565 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 20566 return print_stapsdt_note (pnote);
24d127aa 20567 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 20568 return print_core_note (pnote);
24d127aa 20569 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
20570 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20571 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20572 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20573 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 20574 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 20575
9ef920e9 20576 if (pnote->descsz)
1449284b
NC
20577 {
20578 unsigned long i;
20579
20580 printf (_(" description data: "));
20581 for (i = 0; i < pnote->descsz; i++)
178d8719 20582 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
20583 if (!do_wide)
20584 printf ("\n");
1449284b
NC
20585 }
20586
9ef920e9
NC
20587 if (do_wide)
20588 printf ("\n");
20589
015dc7e1 20590 return true;
1449284b 20591}
6d118b09 20592
015dc7e1 20593static bool
dda8d76d
NC
20594process_notes_at (Filedata * filedata,
20595 Elf_Internal_Shdr * section,
20596 bfd_vma offset,
82ed9683
L
20597 bfd_vma length,
20598 bfd_vma align)
779fe533 20599{
015dc7e1
AM
20600 Elf_External_Note *pnotes;
20601 Elf_External_Note *external;
20602 char *end;
20603 bool res = true;
103f02d3 20604
779fe533 20605 if (length <= 0)
015dc7e1 20606 return false;
103f02d3 20607
1449284b
NC
20608 if (section)
20609 {
dda8d76d 20610 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 20611 if (pnotes)
32ec8896 20612 {
dda8d76d 20613 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
20614 {
20615 free (pnotes);
015dc7e1 20616 return false;
f761cb13 20617 }
32ec8896 20618 }
1449284b
NC
20619 }
20620 else
82ed9683 20621 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 20622 _("notes"));
4dff97b2 20623
dd24e3da 20624 if (pnotes == NULL)
015dc7e1 20625 return false;
779fe533 20626
103f02d3 20627 external = pnotes;
103f02d3 20628
ca0e11aa
NC
20629 if (filedata->is_separate)
20630 printf (_("In linked file '%s': "), filedata->file_name);
20631 else
20632 printf ("\n");
1449284b 20633 if (section)
ca0e11aa 20634 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 20635 else
ca0e11aa 20636 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
20637 (unsigned long) offset, (unsigned long) length);
20638
82ed9683
L
20639 /* NB: Some note sections may have alignment value of 0 or 1. gABI
20640 specifies that notes should be aligned to 4 bytes in 32-bit
20641 objects and to 8 bytes in 64-bit objects. As a Linux extension,
20642 we also support 4 byte alignment in 64-bit objects. If section
20643 alignment is less than 4, we treate alignment as 4 bytes. */
20644 if (align < 4)
20645 align = 4;
20646 else if (align != 4 && align != 8)
20647 {
20648 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
20649 (long) align);
a788aedd 20650 free (pnotes);
015dc7e1 20651 return false;
82ed9683
L
20652 }
20653
dbe15e4e 20654 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 20655
c8071705
NC
20656 end = (char *) pnotes + length;
20657 while ((char *) external < end)
779fe533 20658 {
b34976b6 20659 Elf_Internal_Note inote;
15b42fb0 20660 size_t min_notesz;
4dff97b2 20661 char * next;
2cf0635d 20662 char * temp = NULL;
c8071705 20663 size_t data_remaining = end - (char *) external;
6d118b09 20664
dda8d76d 20665 if (!is_ia64_vms (filedata))
15b42fb0 20666 {
9dd3a467
NC
20667 /* PR binutils/15191
20668 Make sure that there is enough data to read. */
15b42fb0
AM
20669 min_notesz = offsetof (Elf_External_Note, name);
20670 if (data_remaining < min_notesz)
9dd3a467 20671 {
d3a49aa8
AM
20672 warn (ngettext ("Corrupt note: only %ld byte remains, "
20673 "not enough for a full note\n",
20674 "Corrupt note: only %ld bytes remain, "
20675 "not enough for a full note\n",
20676 data_remaining),
20677 (long) data_remaining);
9dd3a467
NC
20678 break;
20679 }
5396a86e
AM
20680 data_remaining -= min_notesz;
20681
15b42fb0
AM
20682 inote.type = BYTE_GET (external->type);
20683 inote.namesz = BYTE_GET (external->namesz);
20684 inote.namedata = external->name;
20685 inote.descsz = BYTE_GET (external->descsz);
276da9b3 20686 inote.descdata = ((char *) external
4dff97b2 20687 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 20688 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 20689 next = ((char *) external
4dff97b2 20690 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 20691 }
00e98fc7 20692 else
15b42fb0
AM
20693 {
20694 Elf64_External_VMS_Note *vms_external;
00e98fc7 20695
9dd3a467
NC
20696 /* PR binutils/15191
20697 Make sure that there is enough data to read. */
15b42fb0
AM
20698 min_notesz = offsetof (Elf64_External_VMS_Note, name);
20699 if (data_remaining < min_notesz)
9dd3a467 20700 {
d3a49aa8
AM
20701 warn (ngettext ("Corrupt note: only %ld byte remains, "
20702 "not enough for a full note\n",
20703 "Corrupt note: only %ld bytes remain, "
20704 "not enough for a full note\n",
20705 data_remaining),
20706 (long) data_remaining);
9dd3a467
NC
20707 break;
20708 }
5396a86e 20709 data_remaining -= min_notesz;
3e55a963 20710
15b42fb0
AM
20711 vms_external = (Elf64_External_VMS_Note *) external;
20712 inote.type = BYTE_GET (vms_external->type);
20713 inote.namesz = BYTE_GET (vms_external->namesz);
20714 inote.namedata = vms_external->name;
20715 inote.descsz = BYTE_GET (vms_external->descsz);
20716 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
20717 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20718 next = inote.descdata + align_power (inote.descsz, 3);
20719 }
20720
5396a86e
AM
20721 /* PR 17531: file: 3443835e. */
20722 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
20723 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
20724 || (size_t) (inote.descdata - inote.namedata) > data_remaining
20725 || (size_t) (next - inote.descdata) < inote.descsz
20726 || ((size_t) (next - inote.descdata)
20727 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 20728 {
15b42fb0 20729 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 20730 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
20731 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
20732 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
20733 break;
20734 }
20735
15b42fb0 20736 external = (Elf_External_Note *) next;
dd24e3da 20737
6d118b09
NC
20738 /* Verify that name is null terminated. It appears that at least
20739 one version of Linux (RedHat 6.0) generates corefiles that don't
20740 comply with the ELF spec by failing to include the null byte in
20741 namesz. */
18344509 20742 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 20743 {
5396a86e 20744 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 20745 {
5396a86e
AM
20746 temp = (char *) malloc (inote.namesz + 1);
20747 if (temp == NULL)
20748 {
20749 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 20750 res = false;
5396a86e
AM
20751 break;
20752 }
76da6bbe 20753
5396a86e
AM
20754 memcpy (temp, inote.namedata, inote.namesz);
20755 inote.namedata = temp;
20756 }
20757 inote.namedata[inote.namesz] = 0;
6d118b09
NC
20758 }
20759
dda8d76d 20760 if (! process_note (& inote, filedata))
015dc7e1 20761 res = false;
103f02d3 20762
9db70fc3
AM
20763 free (temp);
20764 temp = NULL;
779fe533
NC
20765 }
20766
20767 free (pnotes);
103f02d3 20768
779fe533
NC
20769 return res;
20770}
20771
015dc7e1 20772static bool
dda8d76d 20773process_corefile_note_segments (Filedata * filedata)
779fe533 20774{
015dc7e1 20775 Elf_Internal_Phdr *segment;
b34976b6 20776 unsigned int i;
015dc7e1 20777 bool res = true;
103f02d3 20778
dda8d76d 20779 if (! get_program_headers (filedata))
015dc7e1 20780 return true;
103f02d3 20781
dda8d76d
NC
20782 for (i = 0, segment = filedata->program_headers;
20783 i < filedata->file_header.e_phnum;
b34976b6 20784 i++, segment++)
779fe533
NC
20785 {
20786 if (segment->p_type == PT_NOTE)
dda8d76d 20787 if (! process_notes_at (filedata, NULL,
32ec8896 20788 (bfd_vma) segment->p_offset,
82ed9683
L
20789 (bfd_vma) segment->p_filesz,
20790 (bfd_vma) segment->p_align))
015dc7e1 20791 res = false;
779fe533 20792 }
103f02d3 20793
779fe533
NC
20794 return res;
20795}
20796
015dc7e1 20797static bool
dda8d76d 20798process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
20799{
20800 Elf_External_Note * pnotes;
20801 Elf_External_Note * external;
c8071705 20802 char * end;
015dc7e1 20803 bool res = true;
685080f2
NC
20804
20805 if (length <= 0)
015dc7e1 20806 return false;
685080f2 20807
dda8d76d 20808 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
20809 _("v850 notes"));
20810 if (pnotes == NULL)
015dc7e1 20811 return false;
685080f2
NC
20812
20813 external = pnotes;
c8071705 20814 end = (char*) pnotes + length;
685080f2
NC
20815
20816 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
20817 (unsigned long) offset, (unsigned long) length);
20818
c8071705 20819 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
20820 {
20821 Elf_External_Note * next;
20822 Elf_Internal_Note inote;
20823
20824 inote.type = BYTE_GET (external->type);
20825 inote.namesz = BYTE_GET (external->namesz);
20826 inote.namedata = external->name;
20827 inote.descsz = BYTE_GET (external->descsz);
20828 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
20829 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20830
c8071705
NC
20831 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
20832 {
20833 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
20834 inote.descdata = inote.namedata;
20835 inote.namesz = 0;
20836 }
20837
685080f2
NC
20838 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
20839
c8071705 20840 if ( ((char *) next > end)
685080f2
NC
20841 || ((char *) next < (char *) pnotes))
20842 {
20843 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
20844 (unsigned long) ((char *) external - (char *) pnotes));
20845 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20846 inote.type, inote.namesz, inote.descsz);
20847 break;
20848 }
20849
20850 external = next;
20851
20852 /* Prevent out-of-bounds indexing. */
c8071705 20853 if ( inote.namedata + inote.namesz > end
685080f2
NC
20854 || inote.namedata + inote.namesz < inote.namedata)
20855 {
20856 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
20857 (unsigned long) ((char *) external - (char *) pnotes));
20858 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20859 inote.type, inote.namesz, inote.descsz);
20860 break;
20861 }
20862
20863 printf (" %s: ", get_v850_elf_note_type (inote.type));
20864
20865 if (! print_v850_note (& inote))
20866 {
015dc7e1 20867 res = false;
685080f2
NC
20868 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
20869 inote.namesz, inote.descsz);
20870 }
20871 }
20872
20873 free (pnotes);
20874
20875 return res;
20876}
20877
015dc7e1 20878static bool
dda8d76d 20879process_note_sections (Filedata * filedata)
1ec5cd37 20880{
015dc7e1 20881 Elf_Internal_Shdr *section;
1ec5cd37 20882 unsigned long i;
32ec8896 20883 unsigned int n = 0;
015dc7e1 20884 bool res = true;
1ec5cd37 20885
dda8d76d
NC
20886 for (i = 0, section = filedata->section_headers;
20887 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 20888 i++, section++)
685080f2
NC
20889 {
20890 if (section->sh_type == SHT_NOTE)
20891 {
dda8d76d 20892 if (! process_notes_at (filedata, section,
32ec8896 20893 (bfd_vma) section->sh_offset,
82ed9683
L
20894 (bfd_vma) section->sh_size,
20895 (bfd_vma) section->sh_addralign))
015dc7e1 20896 res = false;
685080f2
NC
20897 n++;
20898 }
20899
dda8d76d
NC
20900 if (( filedata->file_header.e_machine == EM_V800
20901 || filedata->file_header.e_machine == EM_V850
20902 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
20903 && section->sh_type == SHT_RENESAS_INFO)
20904 {
dda8d76d 20905 if (! process_v850_notes (filedata,
32ec8896
NC
20906 (bfd_vma) section->sh_offset,
20907 (bfd_vma) section->sh_size))
015dc7e1 20908 res = false;
685080f2
NC
20909 n++;
20910 }
20911 }
df565f32
NC
20912
20913 if (n == 0)
20914 /* Try processing NOTE segments instead. */
dda8d76d 20915 return process_corefile_note_segments (filedata);
1ec5cd37
NC
20916
20917 return res;
20918}
20919
015dc7e1 20920static bool
dda8d76d 20921process_notes (Filedata * filedata)
779fe533
NC
20922{
20923 /* If we have not been asked to display the notes then do nothing. */
20924 if (! do_notes)
015dc7e1 20925 return true;
103f02d3 20926
dda8d76d
NC
20927 if (filedata->file_header.e_type != ET_CORE)
20928 return process_note_sections (filedata);
103f02d3 20929
779fe533 20930 /* No program headers means no NOTE segment. */
dda8d76d
NC
20931 if (filedata->file_header.e_phnum > 0)
20932 return process_corefile_note_segments (filedata);
779fe533 20933
ca0e11aa
NC
20934 if (filedata->is_separate)
20935 printf (_("No notes found in linked file '%s'.\n"),
20936 filedata->file_name);
20937 else
20938 printf (_("No notes found file.\n"));
20939
015dc7e1 20940 return true;
779fe533
NC
20941}
20942
60abdbed
NC
20943static unsigned char *
20944display_public_gnu_attributes (unsigned char * start,
20945 const unsigned char * const end)
20946{
20947 printf (_(" Unknown GNU attribute: %s\n"), start);
20948
20949 start += strnlen ((char *) start, end - start);
20950 display_raw_attribute (start, end);
20951
20952 return (unsigned char *) end;
20953}
20954
20955static unsigned char *
20956display_generic_attribute (unsigned char * start,
20957 unsigned int tag,
20958 const unsigned char * const end)
20959{
20960 if (tag == 0)
20961 return (unsigned char *) end;
20962
20963 return display_tag_value (tag, start, end);
20964}
20965
015dc7e1 20966static bool
dda8d76d 20967process_arch_specific (Filedata * filedata)
252b5132 20968{
a952a375 20969 if (! do_arch)
015dc7e1 20970 return true;
a952a375 20971
dda8d76d 20972 switch (filedata->file_header.e_machine)
252b5132 20973 {
53a346d8
CZ
20974 case EM_ARC:
20975 case EM_ARC_COMPACT:
20976 case EM_ARC_COMPACT2:
dda8d76d 20977 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
20978 display_arc_attribute,
20979 display_generic_attribute);
11c1ff18 20980 case EM_ARM:
dda8d76d 20981 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
20982 display_arm_attribute,
20983 display_generic_attribute);
20984
252b5132 20985 case EM_MIPS:
4fe85591 20986 case EM_MIPS_RS3_LE:
dda8d76d 20987 return process_mips_specific (filedata);
60abdbed
NC
20988
20989 case EM_MSP430:
dda8d76d 20990 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 20991 display_msp430_attribute,
c0ea7c52 20992 display_msp430_gnu_attribute);
60abdbed 20993
2dc8dd17
JW
20994 case EM_RISCV:
20995 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
20996 display_riscv_attribute,
20997 display_generic_attribute);
20998
35c08157 20999 case EM_NDS32:
dda8d76d 21000 return process_nds32_specific (filedata);
60abdbed 21001
85f7484a
PB
21002 case EM_68K:
21003 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21004 display_m68k_gnu_attribute);
21005
34c8bcba 21006 case EM_PPC:
b82317dd 21007 case EM_PPC64:
dda8d76d 21008 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21009 display_power_gnu_attribute);
21010
643f7afb
AK
21011 case EM_S390:
21012 case EM_S390_OLD:
dda8d76d 21013 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21014 display_s390_gnu_attribute);
21015
9e8c70f9
DM
21016 case EM_SPARC:
21017 case EM_SPARC32PLUS:
21018 case EM_SPARCV9:
dda8d76d 21019 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21020 display_sparc_gnu_attribute);
21021
59e6276b 21022 case EM_TI_C6000:
dda8d76d 21023 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
21024 display_tic6x_attribute,
21025 display_generic_attribute);
21026
0861f561
CQ
21027 case EM_CSKY:
21028 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
21029 display_csky_attribute, NULL);
21030
252b5132 21031 default:
dda8d76d 21032 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
21033 display_public_gnu_attributes,
21034 display_generic_attribute);
252b5132 21035 }
252b5132
RH
21036}
21037
015dc7e1 21038static bool
dda8d76d 21039get_file_header (Filedata * filedata)
252b5132 21040{
9ea033b2 21041 /* Read in the identity array. */
dda8d76d 21042 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21043 return false;
252b5132 21044
9ea033b2 21045 /* Determine how to read the rest of the header. */
dda8d76d 21046 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 21047 {
1a0670f3
AM
21048 default:
21049 case ELFDATANONE:
adab8cdc
AO
21050 case ELFDATA2LSB:
21051 byte_get = byte_get_little_endian;
21052 byte_put = byte_put_little_endian;
21053 break;
21054 case ELFDATA2MSB:
21055 byte_get = byte_get_big_endian;
21056 byte_put = byte_put_big_endian;
21057 break;
9ea033b2
NC
21058 }
21059
21060 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 21061 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
21062
21063 /* Read in the rest of the header. */
21064 if (is_32bit_elf)
21065 {
21066 Elf32_External_Ehdr ehdr32;
252b5132 21067
dda8d76d 21068 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21069 return false;
103f02d3 21070
dda8d76d
NC
21071 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
21072 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
21073 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
21074 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
21075 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
21076 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
21077 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
21078 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
21079 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
21080 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
21081 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
21082 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
21083 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 21084 }
252b5132 21085 else
9ea033b2
NC
21086 {
21087 Elf64_External_Ehdr ehdr64;
a952a375
NC
21088
21089 /* If we have been compiled with sizeof (bfd_vma) == 4, then
21090 we will not be able to cope with the 64bit data found in
21091 64 ELF files. Detect this now and abort before we start
50c2245b 21092 overwriting things. */
a952a375
NC
21093 if (sizeof (bfd_vma) < 8)
21094 {
e3c8793a
NC
21095 error (_("This instance of readelf has been built without support for a\n\
2109664 bit data type and so it cannot read 64 bit ELF files.\n"));
015dc7e1 21097 return false;
a952a375 21098 }
103f02d3 21099
dda8d76d 21100 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21101 return false;
103f02d3 21102
dda8d76d
NC
21103 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
21104 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
21105 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
21106 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
21107 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
21108 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
21109 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
21110 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
21111 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
21112 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
21113 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
21114 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
21115 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 21116 }
252b5132 21117
dda8d76d 21118 if (filedata->file_header.e_shoff)
7ece0d85
JJ
21119 {
21120 /* There may be some extensions in the first section header. Don't
21121 bomb if we can't read it. */
21122 if (is_32bit_elf)
015dc7e1 21123 get_32bit_section_headers (filedata, true);
7ece0d85 21124 else
015dc7e1 21125 get_64bit_section_headers (filedata, true);
7ece0d85 21126 }
560f3c1c 21127
015dc7e1 21128 return true;
252b5132
RH
21129}
21130
13acb58d
AM
21131static void
21132free_filedata (Filedata *filedata)
21133{
21134 free (filedata->program_interpreter);
21135 filedata->program_interpreter = NULL;
21136
21137 free (filedata->program_headers);
21138 filedata->program_headers = NULL;
21139
21140 free (filedata->section_headers);
21141 filedata->section_headers = NULL;
21142
21143 free (filedata->string_table);
21144 filedata->string_table = NULL;
21145 filedata->string_table_length = 0;
21146
21147 free (filedata->dump.dump_sects);
21148 filedata->dump.dump_sects = NULL;
21149 filedata->dump.num_dump_sects = 0;
21150
21151 free (filedata->dynamic_strings);
21152 filedata->dynamic_strings = NULL;
21153 filedata->dynamic_strings_length = 0;
21154
21155 free (filedata->dynamic_symbols);
21156 filedata->dynamic_symbols = NULL;
21157 filedata->num_dynamic_syms = 0;
21158
21159 free (filedata->dynamic_syminfo);
21160 filedata->dynamic_syminfo = NULL;
21161
21162 free (filedata->dynamic_section);
21163 filedata->dynamic_section = NULL;
21164
21165 while (filedata->symtab_shndx_list != NULL)
21166 {
21167 elf_section_list *next = filedata->symtab_shndx_list->next;
21168 free (filedata->symtab_shndx_list);
21169 filedata->symtab_shndx_list = next;
21170 }
21171
21172 free (filedata->section_headers_groups);
21173 filedata->section_headers_groups = NULL;
21174
21175 if (filedata->section_groups)
21176 {
21177 size_t i;
21178 struct group_list * g;
21179 struct group_list * next;
21180
21181 for (i = 0; i < filedata->group_count; i++)
21182 {
21183 for (g = filedata->section_groups [i].root; g != NULL; g = next)
21184 {
21185 next = g->next;
21186 free (g);
21187 }
21188 }
21189
21190 free (filedata->section_groups);
21191 filedata->section_groups = NULL;
21192 }
21193}
21194
dda8d76d
NC
21195static void
21196close_file (Filedata * filedata)
21197{
21198 if (filedata)
21199 {
21200 if (filedata->handle)
21201 fclose (filedata->handle);
21202 free (filedata);
21203 }
21204}
21205
21206void
21207close_debug_file (void * data)
21208{
13acb58d 21209 free_filedata ((Filedata *) data);
dda8d76d
NC
21210 close_file ((Filedata *) data);
21211}
21212
21213static Filedata *
015dc7e1 21214open_file (const char * pathname, bool is_separate)
dda8d76d
NC
21215{
21216 struct stat statbuf;
21217 Filedata * filedata = NULL;
21218
21219 if (stat (pathname, & statbuf) < 0
21220 || ! S_ISREG (statbuf.st_mode))
21221 goto fail;
21222
21223 filedata = calloc (1, sizeof * filedata);
21224 if (filedata == NULL)
21225 goto fail;
21226
21227 filedata->handle = fopen (pathname, "rb");
21228 if (filedata->handle == NULL)
21229 goto fail;
21230
21231 filedata->file_size = (bfd_size_type) statbuf.st_size;
21232 filedata->file_name = pathname;
ca0e11aa 21233 filedata->is_separate = is_separate;
dda8d76d
NC
21234
21235 if (! get_file_header (filedata))
21236 goto fail;
21237
21238 if (filedata->file_header.e_shoff)
21239 {
015dc7e1 21240 bool res;
dda8d76d
NC
21241
21242 /* Read the section headers again, this time for real. */
21243 if (is_32bit_elf)
015dc7e1 21244 res = get_32bit_section_headers (filedata, false);
dda8d76d 21245 else
015dc7e1 21246 res = get_64bit_section_headers (filedata, false);
dda8d76d
NC
21247
21248 if (!res)
21249 goto fail;
21250 }
21251
21252 return filedata;
21253
21254 fail:
21255 if (filedata)
21256 {
21257 if (filedata->handle)
21258 fclose (filedata->handle);
21259 free (filedata);
21260 }
21261 return NULL;
21262}
21263
21264void *
21265open_debug_file (const char * pathname)
21266{
015dc7e1 21267 return open_file (pathname, true);
dda8d76d
NC
21268}
21269
835f2fae
NC
21270static void
21271initialise_dump_sects (Filedata * filedata)
21272{
21273 /* Initialise the dump_sects array from the cmdline_dump_sects array.
21274 Note we do this even if cmdline_dump_sects is empty because we
21275 must make sure that the dump_sets array is zeroed out before each
21276 object file is processed. */
21277 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
21278 memset (filedata->dump.dump_sects, 0,
21279 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21280
21281 if (cmdline.num_dump_sects > 0)
21282 {
21283 if (filedata->dump.num_dump_sects == 0)
21284 /* A sneaky way of allocating the dump_sects array. */
21285 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
21286
21287 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
21288 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
21289 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21290 }
21291}
21292
fb52b2f4
NC
21293/* Process one ELF object file according to the command line options.
21294 This file may actually be stored in an archive. The file is
32ec8896
NC
21295 positioned at the start of the ELF object. Returns TRUE if no
21296 problems were encountered, FALSE otherwise. */
fb52b2f4 21297
015dc7e1 21298static bool
dda8d76d 21299process_object (Filedata * filedata)
252b5132 21300{
015dc7e1 21301 bool have_separate_files;
252b5132 21302 unsigned int i;
015dc7e1 21303 bool res;
252b5132 21304
dda8d76d 21305 if (! get_file_header (filedata))
252b5132 21306 {
dda8d76d 21307 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 21308 return false;
252b5132
RH
21309 }
21310
21311 /* Initialise per file variables. */
978c4450
AM
21312 for (i = ARRAY_SIZE (filedata->version_info); i--;)
21313 filedata->version_info[i] = 0;
252b5132 21314
978c4450
AM
21315 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
21316 filedata->dynamic_info[i] = 0;
21317 filedata->dynamic_info_DT_GNU_HASH = 0;
21318 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
21319
21320 /* Process the file. */
21321 if (show_name)
dda8d76d 21322 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 21323
835f2fae 21324 initialise_dump_sects (filedata);
d70c5fc7 21325
dda8d76d 21326 if (! process_file_header (filedata))
015dc7e1 21327 return false;
252b5132 21328
dda8d76d 21329 if (! process_section_headers (filedata))
2f62977e 21330 {
32ec8896 21331 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 21332 do_unwind = do_version = do_dump = do_arch = false;
252b5132 21333
2f62977e 21334 if (! do_using_dynamic)
015dc7e1 21335 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 21336 }
252b5132 21337
dda8d76d 21338 if (! process_section_groups (filedata))
32ec8896 21339 /* Without loaded section groups we cannot process unwind. */
015dc7e1 21340 do_unwind = false;
d1f5c6e3 21341
2482f306
AM
21342 res = process_program_headers (filedata);
21343 if (res)
21344 res = process_dynamic_section (filedata);
252b5132 21345
dda8d76d 21346 if (! process_relocs (filedata))
015dc7e1 21347 res = false;
252b5132 21348
dda8d76d 21349 if (! process_unwind (filedata))
015dc7e1 21350 res = false;
4d6ed7c8 21351
dda8d76d 21352 if (! process_symbol_table (filedata))
015dc7e1 21353 res = false;
252b5132 21354
0f03783c 21355 if (! process_lto_symbol_tables (filedata))
015dc7e1 21356 res = false;
b9e920ec 21357
dda8d76d 21358 if (! process_syminfo (filedata))
015dc7e1 21359 res = false;
252b5132 21360
dda8d76d 21361 if (! process_version_sections (filedata))
015dc7e1 21362 res = false;
252b5132 21363
82ed9683 21364 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 21365 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 21366 else
015dc7e1 21367 have_separate_files = false;
dda8d76d
NC
21368
21369 if (! process_section_contents (filedata))
015dc7e1 21370 res = false;
f5842774 21371
24841daa 21372 if (have_separate_files)
dda8d76d 21373 {
24841daa
NC
21374 separate_info * d;
21375
21376 for (d = first_separate_info; d != NULL; d = d->next)
21377 {
835f2fae
NC
21378 initialise_dump_sects (d->handle);
21379
ca0e11aa 21380 if (process_links && ! process_file_header (d->handle))
015dc7e1 21381 res = false;
ca0e11aa 21382 else if (! process_section_headers (d->handle))
015dc7e1 21383 res = false;
d6bfbc39 21384 else if (! process_section_contents (d->handle))
015dc7e1 21385 res = false;
ca0e11aa
NC
21386 else if (process_links)
21387 {
ca0e11aa 21388 if (! process_section_groups (d->handle))
015dc7e1 21389 res = false;
ca0e11aa 21390 if (! process_program_headers (d->handle))
015dc7e1 21391 res = false;
ca0e11aa 21392 if (! process_dynamic_section (d->handle))
015dc7e1 21393 res = false;
ca0e11aa 21394 if (! process_relocs (d->handle))
015dc7e1 21395 res = false;
ca0e11aa 21396 if (! process_unwind (d->handle))
015dc7e1 21397 res = false;
ca0e11aa 21398 if (! process_symbol_table (d->handle))
015dc7e1 21399 res = false;
ca0e11aa 21400 if (! process_lto_symbol_tables (d->handle))
015dc7e1 21401 res = false;
ca0e11aa 21402 if (! process_syminfo (d->handle))
015dc7e1 21403 res = false;
ca0e11aa 21404 if (! process_version_sections (d->handle))
015dc7e1 21405 res = false;
ca0e11aa 21406 if (! process_notes (d->handle))
015dc7e1 21407 res = false;
ca0e11aa 21408 }
24841daa
NC
21409 }
21410
21411 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
21412 }
21413
21414 if (! process_notes (filedata))
015dc7e1 21415 res = false;
103f02d3 21416
dda8d76d 21417 if (! process_gnu_liblist (filedata))
015dc7e1 21418 res = false;
047b2264 21419
dda8d76d 21420 if (! process_arch_specific (filedata))
015dc7e1 21421 res = false;
252b5132 21422
13acb58d 21423 free_filedata (filedata);
e4b17d5c 21424
19e6b90e 21425 free_debug_memory ();
18bd398b 21426
32ec8896 21427 return res;
252b5132
RH
21428}
21429
2cf0635d 21430/* Process an ELF archive.
32ec8896
NC
21431 On entry the file is positioned just after the ARMAG string.
21432 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 21433
015dc7e1
AM
21434static bool
21435process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
21436{
21437 struct archive_info arch;
21438 struct archive_info nested_arch;
21439 size_t got;
015dc7e1 21440 bool ret = true;
2cf0635d 21441
015dc7e1 21442 show_name = true;
2cf0635d
NC
21443
21444 /* The ARCH structure is used to hold information about this archive. */
21445 arch.file_name = NULL;
21446 arch.file = NULL;
21447 arch.index_array = NULL;
21448 arch.sym_table = NULL;
21449 arch.longnames = NULL;
21450
21451 /* The NESTED_ARCH structure is used as a single-item cache of information
21452 about a nested archive (when members of a thin archive reside within
21453 another regular archive file). */
21454 nested_arch.file_name = NULL;
21455 nested_arch.file = NULL;
21456 nested_arch.index_array = NULL;
21457 nested_arch.sym_table = NULL;
21458 nested_arch.longnames = NULL;
21459
dda8d76d 21460 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
21461 filedata->file_size, is_thin_archive,
21462 do_archive_index) != 0)
2cf0635d 21463 {
015dc7e1 21464 ret = false;
2cf0635d 21465 goto out;
4145f1d5 21466 }
fb52b2f4 21467
4145f1d5
NC
21468 if (do_archive_index)
21469 {
2cf0635d 21470 if (arch.sym_table == NULL)
1cb7d8b1
AM
21471 error (_("%s: unable to dump the index as none was found\n"),
21472 filedata->file_name);
4145f1d5
NC
21473 else
21474 {
591f7597 21475 unsigned long i, l;
4145f1d5
NC
21476 unsigned long current_pos;
21477
1cb7d8b1
AM
21478 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
21479 "in the symbol table)\n"),
21480 filedata->file_name, (unsigned long) arch.index_num,
21481 arch.sym_size);
dda8d76d
NC
21482
21483 current_pos = ftell (filedata->handle);
4145f1d5 21484
2cf0635d 21485 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 21486 {
1cb7d8b1
AM
21487 if (i == 0
21488 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
21489 {
21490 char * member_name
21491 = get_archive_member_name_at (&arch, arch.index_array[i],
21492 &nested_arch);
2cf0635d 21493
1cb7d8b1
AM
21494 if (member_name != NULL)
21495 {
21496 char * qualified_name
21497 = make_qualified_name (&arch, &nested_arch,
21498 member_name);
2cf0635d 21499
1cb7d8b1
AM
21500 if (qualified_name != NULL)
21501 {
21502 printf (_("Contents of binary %s at offset "),
21503 qualified_name);
c2a7d3f5
NC
21504 (void) print_vma (arch.index_array[i], PREFIX_HEX);
21505 putchar ('\n');
1cb7d8b1
AM
21506 free (qualified_name);
21507 }
fd486f32 21508 free (member_name);
4145f1d5
NC
21509 }
21510 }
2cf0635d
NC
21511
21512 if (l >= arch.sym_size)
4145f1d5 21513 {
1cb7d8b1
AM
21514 error (_("%s: end of the symbol table reached "
21515 "before the end of the index\n"),
dda8d76d 21516 filedata->file_name);
015dc7e1 21517 ret = false;
cb8f3167 21518 break;
4145f1d5 21519 }
591f7597 21520 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
21521 printf ("\t%.*s\n",
21522 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 21523 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
21524 }
21525
67ce483b 21526 if (arch.uses_64bit_indices)
c2a7d3f5
NC
21527 l = (l + 7) & ~ 7;
21528 else
21529 l += l & 1;
21530
2cf0635d 21531 if (l < arch.sym_size)
32ec8896 21532 {
d3a49aa8
AM
21533 error (ngettext ("%s: %ld byte remains in the symbol table, "
21534 "but without corresponding entries in "
21535 "the index table\n",
21536 "%s: %ld bytes remain in the symbol table, "
21537 "but without corresponding entries in "
21538 "the index table\n",
21539 arch.sym_size - l),
dda8d76d 21540 filedata->file_name, arch.sym_size - l);
015dc7e1 21541 ret = false;
32ec8896 21542 }
4145f1d5 21543
dda8d76d 21544 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 21545 {
1cb7d8b1
AM
21546 error (_("%s: failed to seek back to start of object files "
21547 "in the archive\n"),
dda8d76d 21548 filedata->file_name);
015dc7e1 21549 ret = false;
2cf0635d 21550 goto out;
4145f1d5 21551 }
fb52b2f4 21552 }
4145f1d5
NC
21553
21554 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
21555 && !do_segments && !do_header && !do_dump && !do_version
21556 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 21557 && !do_section_groups && !do_dyn_syms)
2cf0635d 21558 {
015dc7e1 21559 ret = true; /* Archive index only. */
2cf0635d
NC
21560 goto out;
21561 }
fb52b2f4
NC
21562 }
21563
fb52b2f4
NC
21564 while (1)
21565 {
2cf0635d
NC
21566 char * name;
21567 size_t namelen;
21568 char * qualified_name;
21569
21570 /* Read the next archive header. */
dda8d76d 21571 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
21572 {
21573 error (_("%s: failed to seek to next archive header\n"),
21574 arch.file_name);
015dc7e1 21575 ret = false;
1cb7d8b1
AM
21576 break;
21577 }
dda8d76d 21578 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 21579 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
21580 {
21581 if (got == 0)
2cf0635d 21582 break;
28e817cc
NC
21583 /* PR 24049 - we cannot use filedata->file_name as this will
21584 have already been freed. */
21585 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 21586
015dc7e1 21587 ret = false;
1cb7d8b1
AM
21588 break;
21589 }
2cf0635d 21590 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
21591 {
21592 error (_("%s: did not find a valid archive header\n"),
21593 arch.file_name);
015dc7e1 21594 ret = false;
1cb7d8b1
AM
21595 break;
21596 }
2cf0635d
NC
21597
21598 arch.next_arhdr_offset += sizeof arch.arhdr;
21599
978c4450
AM
21600 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
21601 if (filedata->archive_file_size & 01)
21602 ++filedata->archive_file_size;
2cf0635d
NC
21603
21604 name = get_archive_member_name (&arch, &nested_arch);
21605 if (name == NULL)
fb52b2f4 21606 {
28e817cc 21607 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 21608 ret = false;
d989285c 21609 break;
fb52b2f4 21610 }
2cf0635d 21611 namelen = strlen (name);
fb52b2f4 21612
2cf0635d
NC
21613 qualified_name = make_qualified_name (&arch, &nested_arch, name);
21614 if (qualified_name == NULL)
fb52b2f4 21615 {
28e817cc 21616 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 21617 free (name);
015dc7e1 21618 ret = false;
d989285c 21619 break;
fb52b2f4
NC
21620 }
21621
2cf0635d 21622 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
21623 {
21624 /* This is a proxy for an external member of a thin archive. */
21625 Filedata * member_filedata;
21626 char * member_file_name = adjust_relative_path
dda8d76d 21627 (filedata->file_name, name, namelen);
32ec8896 21628
fd486f32 21629 free (name);
1cb7d8b1
AM
21630 if (member_file_name == NULL)
21631 {
fd486f32 21632 free (qualified_name);
015dc7e1 21633 ret = false;
1cb7d8b1
AM
21634 break;
21635 }
2cf0635d 21636
015dc7e1 21637 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
21638 if (member_filedata == NULL)
21639 {
21640 error (_("Input file '%s' is not readable.\n"), member_file_name);
21641 free (member_file_name);
fd486f32 21642 free (qualified_name);
015dc7e1 21643 ret = false;
1cb7d8b1
AM
21644 break;
21645 }
2cf0635d 21646
978c4450 21647 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 21648 member_filedata->file_name = qualified_name;
2cf0635d 21649
1cb7d8b1 21650 if (! process_object (member_filedata))
015dc7e1 21651 ret = false;
2cf0635d 21652
1cb7d8b1
AM
21653 close_file (member_filedata);
21654 free (member_file_name);
1cb7d8b1 21655 }
2cf0635d 21656 else if (is_thin_archive)
1cb7d8b1
AM
21657 {
21658 Filedata thin_filedata;
eb02c04d 21659
1cb7d8b1 21660 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 21661
a043396b
NC
21662 /* PR 15140: Allow for corrupt thin archives. */
21663 if (nested_arch.file == NULL)
21664 {
21665 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 21666 qualified_name, name);
fd486f32
AM
21667 free (qualified_name);
21668 free (name);
015dc7e1 21669 ret = false;
a043396b
NC
21670 break;
21671 }
fd486f32 21672 free (name);
a043396b 21673
1cb7d8b1 21674 /* This is a proxy for a member of a nested archive. */
978c4450
AM
21675 filedata->archive_file_offset
21676 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 21677
1cb7d8b1
AM
21678 /* The nested archive file will have been opened and setup by
21679 get_archive_member_name. */
978c4450
AM
21680 if (fseek (nested_arch.file, filedata->archive_file_offset,
21681 SEEK_SET) != 0)
1cb7d8b1
AM
21682 {
21683 error (_("%s: failed to seek to archive member.\n"),
21684 nested_arch.file_name);
fd486f32 21685 free (qualified_name);
015dc7e1 21686 ret = false;
1cb7d8b1
AM
21687 break;
21688 }
2cf0635d 21689
dda8d76d
NC
21690 thin_filedata.handle = nested_arch.file;
21691 thin_filedata.file_name = qualified_name;
9abca702 21692
1cb7d8b1 21693 if (! process_object (& thin_filedata))
015dc7e1 21694 ret = false;
1cb7d8b1 21695 }
2cf0635d 21696 else
1cb7d8b1 21697 {
fd486f32 21698 free (name);
978c4450 21699 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 21700 filedata->file_name = qualified_name;
1cb7d8b1 21701 if (! process_object (filedata))
015dc7e1 21702 ret = false;
978c4450 21703 arch.next_arhdr_offset += filedata->archive_file_size;
4c836627 21704 /* Stop looping with "negative" archive_file_size. */
978c4450 21705 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 21706 arch.next_arhdr_offset = -1ul;
1cb7d8b1 21707 }
fb52b2f4 21708
2cf0635d 21709 free (qualified_name);
fb52b2f4
NC
21710 }
21711
4145f1d5 21712 out:
2cf0635d
NC
21713 if (nested_arch.file != NULL)
21714 fclose (nested_arch.file);
21715 release_archive (&nested_arch);
21716 release_archive (&arch);
fb52b2f4 21717
d989285c 21718 return ret;
fb52b2f4
NC
21719}
21720
015dc7e1 21721static bool
2cf0635d 21722process_file (char * file_name)
fb52b2f4 21723{
dda8d76d 21724 Filedata * filedata = NULL;
fb52b2f4
NC
21725 struct stat statbuf;
21726 char armag[SARMAG];
015dc7e1 21727 bool ret = true;
fb52b2f4
NC
21728
21729 if (stat (file_name, &statbuf) < 0)
21730 {
f24ddbdd
NC
21731 if (errno == ENOENT)
21732 error (_("'%s': No such file\n"), file_name);
21733 else
21734 error (_("Could not locate '%s'. System error message: %s\n"),
21735 file_name, strerror (errno));
015dc7e1 21736 return false;
f24ddbdd
NC
21737 }
21738
21739 if (! S_ISREG (statbuf.st_mode))
21740 {
21741 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 21742 return false;
fb52b2f4
NC
21743 }
21744
dda8d76d
NC
21745 filedata = calloc (1, sizeof * filedata);
21746 if (filedata == NULL)
21747 {
21748 error (_("Out of memory allocating file data structure\n"));
015dc7e1 21749 return false;
dda8d76d
NC
21750 }
21751
21752 filedata->file_name = file_name;
21753 filedata->handle = fopen (file_name, "rb");
21754 if (filedata->handle == NULL)
fb52b2f4 21755 {
f24ddbdd 21756 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 21757 free (filedata);
015dc7e1 21758 return false;
fb52b2f4
NC
21759 }
21760
dda8d76d 21761 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 21762 {
4145f1d5 21763 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
21764 fclose (filedata->handle);
21765 free (filedata);
015dc7e1 21766 return false;
fb52b2f4
NC
21767 }
21768
dda8d76d 21769 filedata->file_size = (bfd_size_type) statbuf.st_size;
015dc7e1 21770 filedata->is_separate = false;
f54498b4 21771
fb52b2f4 21772 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 21773 {
015dc7e1
AM
21774 if (! process_archive (filedata, false))
21775 ret = false;
32ec8896 21776 }
2cf0635d 21777 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 21778 {
015dc7e1
AM
21779 if ( ! process_archive (filedata, true))
21780 ret = false;
32ec8896 21781 }
fb52b2f4
NC
21782 else
21783 {
1b513401 21784 if (do_archive_index && !check_all)
4145f1d5
NC
21785 error (_("File %s is not an archive so its index cannot be displayed.\n"),
21786 file_name);
21787
dda8d76d 21788 rewind (filedata->handle);
978c4450 21789 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 21790
dda8d76d 21791 if (! process_object (filedata))
015dc7e1 21792 ret = false;
fb52b2f4
NC
21793 }
21794
dda8d76d 21795 fclose (filedata->handle);
8fb879cd
AM
21796 free (filedata->section_headers);
21797 free (filedata->program_headers);
21798 free (filedata->string_table);
6431e409 21799 free (filedata->dump.dump_sects);
dda8d76d 21800 free (filedata);
32ec8896 21801
fd486f32 21802 free (ba_cache.strtab);
1bd6175a 21803 ba_cache.strtab = NULL;
fd486f32 21804 free (ba_cache.symtab);
1bd6175a 21805 ba_cache.symtab = NULL;
fd486f32
AM
21806 ba_cache.filedata = NULL;
21807
fb52b2f4
NC
21808 return ret;
21809}
21810
252b5132
RH
21811#ifdef SUPPORT_DISASSEMBLY
21812/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 21813 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 21814 symbols. */
252b5132
RH
21815
21816void
2cf0635d 21817print_address (unsigned int addr, FILE * outfile)
252b5132
RH
21818{
21819 fprintf (outfile,"0x%8.8x", addr);
21820}
21821
e3c8793a 21822/* Needed by the i386 disassembler. */
dda8d76d 21823
252b5132
RH
21824void
21825db_task_printsym (unsigned int addr)
21826{
21827 print_address (addr, stderr);
21828}
21829#endif
21830
21831int
2cf0635d 21832main (int argc, char ** argv)
252b5132 21833{
ff78d6d6
L
21834 int err;
21835
87b9f255 21836#ifdef HAVE_LC_MESSAGES
252b5132 21837 setlocale (LC_MESSAGES, "");
3882b010 21838#endif
3882b010 21839 setlocale (LC_CTYPE, "");
252b5132
RH
21840 bindtextdomain (PACKAGE, LOCALEDIR);
21841 textdomain (PACKAGE);
21842
869b9d07
MM
21843 expandargv (&argc, &argv);
21844
dda8d76d 21845 parse_args (& cmdline, argc, argv);
59f14fc0 21846
18bd398b 21847 if (optind < (argc - 1))
1b513401
NC
21848 /* When displaying information for more than one file,
21849 prefix the information with the file name. */
015dc7e1 21850 show_name = true;
5656ba2c
L
21851 else if (optind >= argc)
21852 {
1b513401 21853 /* Ensure that the warning is always displayed. */
015dc7e1 21854 do_checks = true;
1b513401 21855
5656ba2c
L
21856 warn (_("Nothing to do.\n"));
21857 usage (stderr);
21858 }
18bd398b 21859
015dc7e1 21860 err = false;
252b5132 21861 while (optind < argc)
32ec8896 21862 if (! process_file (argv[optind++]))
015dc7e1 21863 err = true;
252b5132 21864
9db70fc3 21865 free (cmdline.dump_sects);
252b5132 21866
7d9813f1
NA
21867 free (dump_ctf_symtab_name);
21868 free (dump_ctf_strtab_name);
21869 free (dump_ctf_parent_name);
21870
32ec8896 21871 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 21872}