PR27952, Disallow ET_DYN DF_1_PIE linker input
[deliverable/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
250d07de 2 Copyright (C) 1998-2021 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056 46#include <zlib.h>
7bfd842d 47#include <wchar.h>
252b5132 48
a952a375 49#if __GNUC__ >= 2
19936277 50/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 51 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 52 Only do this if we believe that the compiler can support a 64 bit
a952a375 53 data type. For now we only rely on GCC being able to do this. */
19936277 54#define BFD64
a952a375
NC
55#endif
56
3db64b00
AM
57#include "bfd.h"
58#include "bucomm.h"
3284fe0c 59#include "elfcomm.h"
19e6b90e 60#include "dwarf.h"
7d9813f1 61#include "ctf-api.h"
79bc120c 62#include "demangle.h"
252b5132
RH
63
64#include "elf/common.h"
65#include "elf/external.h"
66#include "elf/internal.h"
252b5132 67
4b78141a
NC
68
69/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
70 we can obtain the H8 reloc numbers. We need these for the
71 get_reloc_size() function. We include h8.h again after defining
72 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
73
74#include "elf/h8.h"
75#undef _ELF_H8_H
76
77/* Undo the effects of #including reloc-macros.h. */
78
79#undef START_RELOC_NUMBERS
80#undef RELOC_NUMBER
81#undef FAKE_RELOC
82#undef EMPTY_RELOC
83#undef END_RELOC_NUMBERS
84#undef _RELOC_MACROS_H
85
252b5132
RH
86/* The following headers use the elf/reloc-macros.h file to
87 automatically generate relocation recognition functions
88 such as elf_mips_reloc_type() */
89
90#define RELOC_MACROS_GEN_FUNC
91
a06ea964 92#include "elf/aarch64.h"
252b5132 93#include "elf/alpha.h"
3b16e843 94#include "elf/arc.h"
252b5132 95#include "elf/arm.h"
3b16e843 96#include "elf/avr.h"
1d65ded4 97#include "elf/bfin.h"
60bca95a 98#include "elf/cr16.h"
3b16e843 99#include "elf/cris.h"
1c0d3aa6 100#include "elf/crx.h"
b8891f8d 101#include "elf/csky.h"
252b5132
RH
102#include "elf/d10v.h"
103#include "elf/d30v.h"
d172d4ba 104#include "elf/dlx.h"
aca4efc7 105#include "elf/bpf.h"
cfb8c092 106#include "elf/epiphany.h"
252b5132 107#include "elf/fr30.h"
5c70f934 108#include "elf/frv.h"
3f8107ab 109#include "elf/ft32.h"
3b16e843
NC
110#include "elf/h8.h"
111#include "elf/hppa.h"
112#include "elf/i386.h"
f954747f
AM
113#include "elf/i370.h"
114#include "elf/i860.h"
115#include "elf/i960.h"
3b16e843 116#include "elf/ia64.h"
1e4cf259 117#include "elf/ip2k.h"
84e94c90 118#include "elf/lm32.h"
1c0d3aa6 119#include "elf/iq2000.h"
49f58d10 120#include "elf/m32c.h"
3b16e843
NC
121#include "elf/m32r.h"
122#include "elf/m68k.h"
75751cd9 123#include "elf/m68hc11.h"
7b4ae824 124#include "elf/s12z.h"
252b5132 125#include "elf/mcore.h"
15ab5209 126#include "elf/mep.h"
a3c62988 127#include "elf/metag.h"
7ba29e2a 128#include "elf/microblaze.h"
3b16e843 129#include "elf/mips.h"
3c3bdf30 130#include "elf/mmix.h"
3b16e843
NC
131#include "elf/mn10200.h"
132#include "elf/mn10300.h"
5506d11a 133#include "elf/moxie.h"
4970f871 134#include "elf/mt.h"
2469cfa2 135#include "elf/msp430.h"
35c08157 136#include "elf/nds32.h"
fe944acf 137#include "elf/nfp.h"
13761a11 138#include "elf/nios2.h"
73589c9d 139#include "elf/or1k.h"
7d466069 140#include "elf/pj.h"
3b16e843 141#include "elf/ppc.h"
c833c019 142#include "elf/ppc64.h"
2b100bb5 143#include "elf/pru.h"
03336641 144#include "elf/riscv.h"
99c513f6 145#include "elf/rl78.h"
c7927a3c 146#include "elf/rx.h"
a85d7ed0 147#include "elf/s390.h"
1c0d3aa6 148#include "elf/score.h"
3b16e843
NC
149#include "elf/sh.h"
150#include "elf/sparc.h"
e9f53129 151#include "elf/spu.h"
40b36596 152#include "elf/tic6x.h"
aa137e4d
NC
153#include "elf/tilegx.h"
154#include "elf/tilepro.h"
3b16e843 155#include "elf/v850.h"
179d3252 156#include "elf/vax.h"
619ed720 157#include "elf/visium.h"
f96bd6c2 158#include "elf/wasm32.h"
3b16e843 159#include "elf/x86-64.h"
c29aca4a 160#include "elf/xc16x.h"
f6c1a2d5 161#include "elf/xgate.h"
93fbbb04 162#include "elf/xstormy16.h"
88da6820 163#include "elf/xtensa.h"
6655dba2 164#include "elf/z80.h"
252b5132 165
252b5132 166#include "getopt.h"
566b0d53 167#include "libiberty.h"
09c11c86 168#include "safe-ctype.h"
2cf0635d 169#include "filenames.h"
252b5132 170
15b42fb0
AM
171#ifndef offsetof
172#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
173#endif
174
6a40cf0c
NC
175typedef struct elf_section_list
176{
dda8d76d
NC
177 Elf_Internal_Shdr * hdr;
178 struct elf_section_list * next;
6a40cf0c
NC
179} elf_section_list;
180
dda8d76d
NC
181/* Flag bits indicating particular types of dump. */
182#define HEX_DUMP (1 << 0) /* The -x command line switch. */
183#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
184#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
185#define STRING_DUMP (1 << 3) /* The -p command line switch. */
186#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 187#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
188
189typedef unsigned char dump_type;
190
191/* A linked list of the section names for which dumps were requested. */
192struct dump_list_entry
193{
194 char * name;
195 dump_type type;
196 struct dump_list_entry * next;
197};
198
6431e409
AM
199/* A dynamic array of flags indicating for which sections a dump
200 has been requested via command line switches. */
1b513401
NC
201struct dump_data
202{
6431e409
AM
203 dump_type * dump_sects;
204 unsigned int num_dump_sects;
205};
206
207static struct dump_data cmdline;
208
209static struct dump_list_entry * dump_sects_byname;
210
2cf0635d 211char * program_name = "readelf";
dda8d76d 212
015dc7e1
AM
213static bool show_name = false;
214static bool do_dynamic = false;
215static bool do_syms = false;
216static bool do_dyn_syms = false;
217static bool do_lto_syms = false;
218static bool do_reloc = false;
219static bool do_sections = false;
220static bool do_section_groups = false;
221static bool do_section_details = false;
222static bool do_segments = false;
223static bool do_unwind = false;
224static bool do_using_dynamic = false;
225static bool do_header = false;
226static bool do_dump = false;
227static bool do_version = false;
228static bool do_histogram = false;
229static bool do_debugging = false;
230static bool do_ctf = false;
231static bool do_arch = false;
232static bool do_notes = false;
233static bool do_archive_index = false;
234static bool check_all = false;
235static bool is_32bit_elf = false;
236static bool decompress_dumps = false;
237static bool do_not_show_symbol_truncation = false;
238static bool do_demangle = false; /* Pretty print C++ symbol names. */
239static bool process_links = false;
79bc120c 240static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 241static int sym_base = 0;
252b5132 242
7d9813f1
NA
243static char *dump_ctf_parent_name;
244static char *dump_ctf_symtab_name;
245static char *dump_ctf_strtab_name;
246
e4b17d5c
L
247struct group_list
248{
dda8d76d
NC
249 struct group_list * next;
250 unsigned int section_index;
e4b17d5c
L
251};
252
253struct group
254{
dda8d76d
NC
255 struct group_list * root;
256 unsigned int group_index;
e4b17d5c
L
257};
258
978c4450
AM
259typedef struct filedata
260{
261 const char * file_name;
015dc7e1 262 bool is_separate;
978c4450
AM
263 FILE * handle;
264 bfd_size_type file_size;
265 Elf_Internal_Ehdr file_header;
266 Elf_Internal_Shdr * section_headers;
267 Elf_Internal_Phdr * program_headers;
268 char * string_table;
269 unsigned long string_table_length;
270 unsigned long archive_file_offset;
271 unsigned long archive_file_size;
272 unsigned long dynamic_addr;
273 bfd_size_type dynamic_size;
274 size_t dynamic_nent;
275 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 276 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450
AM
277 char * dynamic_strings;
278 unsigned long dynamic_strings_length;
8ac10c5b 279 Elf_Internal_Shdr * dynamic_symtab_section;
978c4450
AM
280 unsigned long num_dynamic_syms;
281 Elf_Internal_Sym * dynamic_symbols;
282 bfd_vma version_info[16];
283 unsigned int dynamic_syminfo_nent;
284 Elf_Internal_Syminfo * dynamic_syminfo;
285 unsigned long dynamic_syminfo_offset;
286 bfd_size_type nbuckets;
287 bfd_size_type nchains;
288 bfd_vma * buckets;
289 bfd_vma * chains;
290 bfd_size_type ngnubuckets;
291 bfd_size_type ngnuchains;
292 bfd_vma * gnubuckets;
293 bfd_vma * gnuchains;
294 bfd_vma * mipsxlat;
295 bfd_vma gnusymidx;
13acb58d 296 char * program_interpreter;
978c4450
AM
297 bfd_vma dynamic_info[DT_ENCODING];
298 bfd_vma dynamic_info_DT_GNU_HASH;
299 bfd_vma dynamic_info_DT_MIPS_XHASH;
300 elf_section_list * symtab_shndx_list;
301 size_t group_count;
302 struct group * section_groups;
303 struct group ** section_headers_groups;
304 /* A dynamic array of flags indicating for which sections a dump of
305 some kind has been requested. It is reset on a per-object file
306 basis and then initialised from the cmdline_dump_sects array,
307 the results of interpreting the -w switch, and the
308 dump_sects_byname list. */
309 struct dump_data dump;
310} Filedata;
aef1f6d0 311
c256ffe7 312/* How to print a vma value. */
843dd992
NC
313typedef enum print_mode
314{
315 HEX,
047c3dbf 316 HEX_5,
843dd992
NC
317 DEC,
318 DEC_5,
319 UNSIGNED,
047c3dbf 320 UNSIGNED_5,
843dd992 321 PREFIX_HEX,
047c3dbf 322 PREFIX_HEX_5,
843dd992 323 FULL_HEX,
047c3dbf
NL
324 LONG_HEX,
325 OCTAL,
326 OCTAL_5
843dd992
NC
327}
328print_mode;
329
bb4d2ac2
L
330/* Versioned symbol info. */
331enum versioned_symbol_info
332{
333 symbol_undefined,
334 symbol_hidden,
335 symbol_public
336};
337
32ec8896 338static const char * get_symbol_version_string
015dc7e1 339 (Filedata *, bool, const char *, unsigned long, unsigned,
32ec8896 340 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 341
9c19a809
NC
342#define UNKNOWN -1
343
b9e920ec
AM
344#define SECTION_NAME(X) \
345 (filedata->string_table + (X)->sh_name)
346
347#define SECTION_NAME_VALID(X) \
348 ((X) != NULL \
349 && filedata->string_table != NULL \
350 && (X)->sh_name < filedata->string_table_length)
351
352#define SECTION_NAME_PRINT(X) \
353 ((X) == NULL ? _("<none>") \
354 : filedata->string_table == NULL ? _("<no-strings>") \
355 : (X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
356 : filedata->string_table + (X)->sh_name)
252b5132 357
ee42cf8c 358#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 359
ba5cdace
NC
360#define GET_ELF_SYMBOLS(file, section, sym_count) \
361 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
362 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 363
10ca4b04
L
364#define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
365 (strtab != NULL && offset < strtab_size)
978c4450
AM
366#define VALID_DYNAMIC_NAME(filedata, offset) \
367 VALID_SYMBOL_NAME (filedata->dynamic_strings, \
368 filedata->dynamic_strings_length, offset)
d79b3d50
NC
369/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
370 already been called and verified that the string exists. */
978c4450
AM
371#define GET_DYNAMIC_NAME(filedata, offset) \
372 (filedata->dynamic_strings + offset)
18bd398b 373
61865e30
NC
374#define REMOVE_ARCH_BITS(ADDR) \
375 do \
376 { \
dda8d76d 377 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
378 (ADDR) &= ~1; \
379 } \
380 while (0)
f16a9783
MS
381
382/* Get the correct GNU hash section name. */
978c4450
AM
383#define GNU_HASH_SECTION_NAME(filedata) \
384 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 385\f
66cfc0fd
AM
386/* Print a BFD_VMA to an internal buffer, for use in error messages.
387 BFD_FMA_FMT can't be used in translated strings. */
388
389static const char *
390bfd_vmatoa (char *fmtch, bfd_vma value)
391{
392 /* bfd_vmatoa is used more then once in a printf call for output.
393 Cycle through an array of buffers. */
394 static int buf_pos = 0;
395 static struct bfd_vmatoa_buf
396 {
397 char place[64];
398 } buf[4];
399 char *ret;
400 char fmt[32];
401
402 ret = buf[buf_pos++].place;
403 buf_pos %= ARRAY_SIZE (buf);
404
405 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
406 snprintf (ret, sizeof (buf[0].place), fmt, value);
407 return ret;
408}
409
dda8d76d
NC
410/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
411 OFFSET + the offset of the current archive member, if we are examining an
412 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
413 allocate a buffer using malloc and fill that. In either case return the
414 pointer to the start of the retrieved data or NULL if something went wrong.
415 If something does go wrong and REASON is not NULL then emit an error
416 message using REASON as part of the context. */
59245841 417
c256ffe7 418static void *
dda8d76d
NC
419get_data (void * var,
420 Filedata * filedata,
421 unsigned long offset,
422 bfd_size_type size,
423 bfd_size_type nmemb,
424 const char * reason)
a6e9f9df 425{
2cf0635d 426 void * mvar;
57028622 427 bfd_size_type amt = size * nmemb;
a6e9f9df 428
c256ffe7 429 if (size == 0 || nmemb == 0)
a6e9f9df
AM
430 return NULL;
431
57028622
NC
432 /* If the size_t type is smaller than the bfd_size_type, eg because
433 you are building a 32-bit tool on a 64-bit host, then make sure
434 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
435 if ((size_t) size != size
436 || (size_t) nmemb != nmemb
437 || (size_t) amt != amt)
57028622
NC
438 {
439 if (reason)
66cfc0fd
AM
440 error (_("Size truncation prevents reading %s"
441 " elements of size %s for %s\n"),
442 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
443 return NULL;
444 }
445
446 /* Check for size overflow. */
7c1c1904 447 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
448 {
449 if (reason)
66cfc0fd
AM
450 error (_("Size overflow prevents reading %s"
451 " elements of size %s for %s\n"),
452 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
453 return NULL;
454 }
455
c22b42ce 456 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 457 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
458 if (filedata->archive_file_offset > filedata->file_size
459 || offset > filedata->file_size - filedata->archive_file_offset
460 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 461 {
049b0c3a 462 if (reason)
66cfc0fd
AM
463 error (_("Reading %s bytes extends past end of file for %s\n"),
464 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
465 return NULL;
466 }
467
978c4450
AM
468 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
469 SEEK_SET))
071436c6
NC
470 {
471 if (reason)
c9c1d674 472 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 473 filedata->archive_file_offset + offset, reason);
071436c6
NC
474 return NULL;
475 }
476
a6e9f9df
AM
477 mvar = var;
478 if (mvar == NULL)
479 {
7c1c1904
AM
480 /* + 1 so that we can '\0' terminate invalid string table sections. */
481 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
482
483 if (mvar == NULL)
484 {
049b0c3a 485 if (reason)
66cfc0fd
AM
486 error (_("Out of memory allocating %s bytes for %s\n"),
487 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
488 return NULL;
489 }
c256ffe7 490
c9c1d674 491 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
492 }
493
dda8d76d 494 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 495 {
049b0c3a 496 if (reason)
66cfc0fd
AM
497 error (_("Unable to read in %s bytes of %s\n"),
498 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
499 if (mvar != var)
500 free (mvar);
501 return NULL;
502 }
503
504 return mvar;
505}
506
32ec8896
NC
507/* Print a VMA value in the MODE specified.
508 Returns the number of characters displayed. */
cb8f3167 509
32ec8896 510static unsigned int
14a91970 511print_vma (bfd_vma vma, print_mode mode)
66543521 512{
32ec8896 513 unsigned int nc = 0;
66543521 514
14a91970 515 switch (mode)
66543521 516 {
14a91970
AM
517 case FULL_HEX:
518 nc = printf ("0x");
1a0670f3 519 /* Fall through. */
14a91970 520 case LONG_HEX:
f7a99963 521#ifdef BFD64
14a91970 522 if (is_32bit_elf)
437c2fb7 523 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 524#endif
14a91970
AM
525 printf_vma (vma);
526 return nc + 16;
b19aac67 527
14a91970
AM
528 case DEC_5:
529 if (vma <= 99999)
530 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 531 /* Fall through. */
14a91970
AM
532 case PREFIX_HEX:
533 nc = printf ("0x");
1a0670f3 534 /* Fall through. */
14a91970
AM
535 case HEX:
536 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 537
047c3dbf
NL
538 case PREFIX_HEX_5:
539 nc = printf ("0x");
540 /* Fall through. */
541 case HEX_5:
542 return nc + printf ("%05" BFD_VMA_FMT "x", vma);
543
14a91970
AM
544 case DEC:
545 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 546
14a91970
AM
547 case UNSIGNED:
548 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896 549
047c3dbf
NL
550 case UNSIGNED_5:
551 return printf ("%5" BFD_VMA_FMT "u", vma);
552
553 case OCTAL:
554 return printf ("%" BFD_VMA_FMT "o", vma);
555
556 case OCTAL_5:
557 return printf ("%5" BFD_VMA_FMT "o", vma);
558
32ec8896
NC
559 default:
560 /* FIXME: Report unrecognised mode ? */
561 return 0;
f7a99963 562 }
f7a99963
NC
563}
564
047c3dbf 565
7bfd842d 566/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 567 multibye characters (assuming the host environment supports them).
31104126 568
7bfd842d
NC
569 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
570
0942c7ab
NC
571 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
572 abs(WIDTH) - 5 characters followed by "[...]".
573
7bfd842d
NC
574 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
575 padding as necessary.
171191ba
NC
576
577 Returns the number of emitted characters. */
578
579static unsigned int
0942c7ab 580print_symbol (signed int width, const char * symbol)
31104126 581{
015dc7e1
AM
582 bool extra_padding = false;
583 bool do_dots = false;
32ec8896 584 signed int num_printed = 0;
3bfcb652 585#ifdef HAVE_MBSTATE_T
7bfd842d 586 mbstate_t state;
3bfcb652 587#endif
32ec8896 588 unsigned int width_remaining;
79bc120c 589 const void * alloced_symbol = NULL;
961c521f 590
7bfd842d 591 if (width < 0)
961c521f 592 {
88305e1b 593 /* Keep the width positive. This helps the code below. */
961c521f 594 width = - width;
015dc7e1 595 extra_padding = true;
0b4362b0 596 }
56d8f8a9
NC
597 else if (width == 0)
598 return 0;
961c521f 599
7bfd842d
NC
600 if (do_wide)
601 /* Set the remaining width to a very large value.
602 This simplifies the code below. */
603 width_remaining = INT_MAX;
604 else
0942c7ab
NC
605 {
606 width_remaining = width;
607 if (! do_not_show_symbol_truncation
608 && (int) strlen (symbol) > width)
609 {
610 width_remaining -= 5;
611 if ((int) width_remaining < 0)
612 width_remaining = 0;
015dc7e1 613 do_dots = true;
0942c7ab
NC
614 }
615 }
cb8f3167 616
3bfcb652 617#ifdef HAVE_MBSTATE_T
7bfd842d
NC
618 /* Initialise the multibyte conversion state. */
619 memset (& state, 0, sizeof (state));
3bfcb652 620#endif
961c521f 621
79bc120c
NC
622 if (do_demangle && *symbol)
623 {
624 const char * res = cplus_demangle (symbol, demangle_flags);
625
626 if (res != NULL)
627 alloced_symbol = symbol = res;
628 }
629
7bfd842d
NC
630 while (width_remaining)
631 {
632 size_t n;
7bfd842d 633 const char c = *symbol++;
961c521f 634
7bfd842d 635 if (c == 0)
961c521f
NC
636 break;
637
7bfd842d
NC
638 /* Do not print control characters directly as they can affect terminal
639 settings. Such characters usually appear in the names generated
640 by the assembler for local labels. */
641 if (ISCNTRL (c))
961c521f 642 {
7bfd842d 643 if (width_remaining < 2)
961c521f
NC
644 break;
645
7bfd842d
NC
646 printf ("^%c", c + 0x40);
647 width_remaining -= 2;
171191ba 648 num_printed += 2;
961c521f 649 }
7bfd842d
NC
650 else if (ISPRINT (c))
651 {
652 putchar (c);
653 width_remaining --;
654 num_printed ++;
655 }
961c521f
NC
656 else
657 {
3bfcb652
NC
658#ifdef HAVE_MBSTATE_T
659 wchar_t w;
660#endif
7bfd842d
NC
661 /* Let printf do the hard work of displaying multibyte characters. */
662 printf ("%.1s", symbol - 1);
663 width_remaining --;
664 num_printed ++;
665
3bfcb652 666#ifdef HAVE_MBSTATE_T
7bfd842d
NC
667 /* Try to find out how many bytes made up the character that was
668 just printed. Advance the symbol pointer past the bytes that
669 were displayed. */
670 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
671#else
672 n = 1;
673#endif
7bfd842d
NC
674 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
675 symbol += (n - 1);
961c521f 676 }
961c521f 677 }
171191ba 678
0942c7ab
NC
679 if (do_dots)
680 num_printed += printf ("[...]");
681
7bfd842d 682 if (extra_padding && num_printed < width)
171191ba
NC
683 {
684 /* Fill in the remaining spaces. */
7bfd842d
NC
685 printf ("%-*s", width - num_printed, " ");
686 num_printed = width;
171191ba
NC
687 }
688
79bc120c 689 free ((void *) alloced_symbol);
171191ba 690 return num_printed;
31104126
NC
691}
692
1449284b 693/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
694 the given section's name. Like print_symbol, except that it does not try
695 to print multibyte characters, it just interprets them as hex values. */
696
697static const char *
dda8d76d 698printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 699{
ca0e11aa 700#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 701 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
b9e920ec 702 const char * name = SECTION_NAME_PRINT (sec);
74e1a04b
NC
703 char * buf = sec_name_buf;
704 char c;
705 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
706
707 while ((c = * name ++) != 0)
708 {
709 if (ISCNTRL (c))
710 {
711 if (remaining < 2)
712 break;
948f632f 713
74e1a04b
NC
714 * buf ++ = '^';
715 * buf ++ = c + 0x40;
716 remaining -= 2;
717 }
718 else if (ISPRINT (c))
719 {
720 * buf ++ = c;
721 remaining -= 1;
722 }
723 else
724 {
725 static char hex[17] = "0123456789ABCDEF";
726
727 if (remaining < 4)
728 break;
729 * buf ++ = '<';
730 * buf ++ = hex[(c & 0xf0) >> 4];
731 * buf ++ = hex[c & 0x0f];
732 * buf ++ = '>';
733 remaining -= 4;
734 }
735
736 if (remaining == 0)
737 break;
738 }
739
740 * buf = 0;
741 return sec_name_buf;
742}
743
744static const char *
dda8d76d 745printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 746{
dda8d76d 747 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
748 return _("<corrupt>");
749
dda8d76d 750 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
751}
752
89fac5e3
RS
753/* Return a pointer to section NAME, or NULL if no such section exists. */
754
755static Elf_Internal_Shdr *
dda8d76d 756find_section (Filedata * filedata, const char * name)
89fac5e3
RS
757{
758 unsigned int i;
759
68807c3c
NC
760 if (filedata->section_headers == NULL)
761 return NULL;
dda8d76d
NC
762
763 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
764 if (SECTION_NAME_VALID (filedata->section_headers + i)
765 && streq (SECTION_NAME (filedata->section_headers + i), name))
dda8d76d 766 return filedata->section_headers + i;
89fac5e3
RS
767
768 return NULL;
769}
770
0b6ae522
DJ
771/* Return a pointer to a section containing ADDR, or NULL if no such
772 section exists. */
773
774static Elf_Internal_Shdr *
dda8d76d 775find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
776{
777 unsigned int i;
778
68807c3c
NC
779 if (filedata->section_headers == NULL)
780 return NULL;
781
dda8d76d 782 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 783 {
dda8d76d
NC
784 Elf_Internal_Shdr *sec = filedata->section_headers + i;
785
0b6ae522
DJ
786 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
787 return sec;
788 }
789
790 return NULL;
791}
792
071436c6 793static Elf_Internal_Shdr *
dda8d76d 794find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
795{
796 unsigned int i;
797
68807c3c
NC
798 if (filedata->section_headers == NULL)
799 return NULL;
800
dda8d76d 801 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 802 {
dda8d76d
NC
803 Elf_Internal_Shdr *sec = filedata->section_headers + i;
804
071436c6
NC
805 if (sec->sh_type == type)
806 return sec;
807 }
808
809 return NULL;
810}
811
657d0d47
CC
812/* Return a pointer to section NAME, or NULL if no such section exists,
813 restricted to the list of sections given in SET. */
814
815static Elf_Internal_Shdr *
dda8d76d 816find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
817{
818 unsigned int i;
819
68807c3c
NC
820 if (filedata->section_headers == NULL)
821 return NULL;
822
657d0d47
CC
823 if (set != NULL)
824 {
825 while ((i = *set++) > 0)
b814a36d
NC
826 {
827 /* See PR 21156 for a reproducer. */
dda8d76d 828 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
829 continue; /* FIXME: Should we issue an error message ? */
830
b9e920ec
AM
831 if (SECTION_NAME_VALID (filedata->section_headers + i)
832 && streq (SECTION_NAME (filedata->section_headers + i), name))
dda8d76d 833 return filedata->section_headers + i;
b814a36d 834 }
657d0d47
CC
835 }
836
dda8d76d 837 return find_section (filedata, name);
657d0d47
CC
838}
839
32ec8896 840/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
841 This OS has so many departures from the ELF standard that we test it at
842 many places. */
843
015dc7e1 844static inline bool
dda8d76d 845is_ia64_vms (Filedata * filedata)
28f997cf 846{
dda8d76d
NC
847 return filedata->file_header.e_machine == EM_IA_64
848 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
849}
850
bcedfee6 851/* Guess the relocation size commonly used by the specific machines. */
252b5132 852
015dc7e1 853static bool
2dc4cec1 854guess_is_rela (unsigned int e_machine)
252b5132 855{
9c19a809 856 switch (e_machine)
252b5132
RH
857 {
858 /* Targets that use REL relocations. */
252b5132 859 case EM_386:
22abe556 860 case EM_IAMCU:
f954747f 861 case EM_960:
e9f53129 862 case EM_ARM:
2b0337b0 863 case EM_D10V:
252b5132 864 case EM_CYGNUS_D10V:
e9f53129 865 case EM_DLX:
252b5132 866 case EM_MIPS:
4fe85591 867 case EM_MIPS_RS3_LE:
e9f53129 868 case EM_CYGNUS_M32R:
1c0d3aa6 869 case EM_SCORE:
f6c1a2d5 870 case EM_XGATE:
fe944acf 871 case EM_NFP:
aca4efc7 872 case EM_BPF:
015dc7e1 873 return false;
103f02d3 874
252b5132
RH
875 /* Targets that use RELA relocations. */
876 case EM_68K:
f954747f 877 case EM_860:
a06ea964 878 case EM_AARCH64:
cfb8c092 879 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
880 case EM_ALPHA:
881 case EM_ALTERA_NIOS2:
886a2506
NC
882 case EM_ARC:
883 case EM_ARC_COMPACT:
884 case EM_ARC_COMPACT2:
e9f53129
AM
885 case EM_AVR:
886 case EM_AVR_OLD:
887 case EM_BLACKFIN:
60bca95a 888 case EM_CR16:
e9f53129
AM
889 case EM_CRIS:
890 case EM_CRX:
b8891f8d 891 case EM_CSKY:
2b0337b0 892 case EM_D30V:
252b5132 893 case EM_CYGNUS_D30V:
2b0337b0 894 case EM_FR30:
3f8107ab 895 case EM_FT32:
252b5132 896 case EM_CYGNUS_FR30:
5c70f934 897 case EM_CYGNUS_FRV:
e9f53129
AM
898 case EM_H8S:
899 case EM_H8_300:
900 case EM_H8_300H:
800eeca4 901 case EM_IA_64:
1e4cf259
NC
902 case EM_IP2K:
903 case EM_IP2K_OLD:
3b36097d 904 case EM_IQ2000:
84e94c90 905 case EM_LATTICEMICO32:
ff7eeb89 906 case EM_M32C_OLD:
49f58d10 907 case EM_M32C:
e9f53129
AM
908 case EM_M32R:
909 case EM_MCORE:
15ab5209 910 case EM_CYGNUS_MEP:
a3c62988 911 case EM_METAG:
e9f53129
AM
912 case EM_MMIX:
913 case EM_MN10200:
914 case EM_CYGNUS_MN10200:
915 case EM_MN10300:
916 case EM_CYGNUS_MN10300:
5506d11a 917 case EM_MOXIE:
e9f53129
AM
918 case EM_MSP430:
919 case EM_MSP430_OLD:
d031aafb 920 case EM_MT:
35c08157 921 case EM_NDS32:
64fd6348 922 case EM_NIOS32:
73589c9d 923 case EM_OR1K:
e9f53129
AM
924 case EM_PPC64:
925 case EM_PPC:
2b100bb5 926 case EM_TI_PRU:
e23eba97 927 case EM_RISCV:
99c513f6 928 case EM_RL78:
c7927a3c 929 case EM_RX:
e9f53129
AM
930 case EM_S390:
931 case EM_S390_OLD:
932 case EM_SH:
933 case EM_SPARC:
934 case EM_SPARC32PLUS:
935 case EM_SPARCV9:
936 case EM_SPU:
40b36596 937 case EM_TI_C6000:
aa137e4d
NC
938 case EM_TILEGX:
939 case EM_TILEPRO:
708e2187 940 case EM_V800:
e9f53129
AM
941 case EM_V850:
942 case EM_CYGNUS_V850:
943 case EM_VAX:
619ed720 944 case EM_VISIUM:
e9f53129 945 case EM_X86_64:
8a9036a4 946 case EM_L1OM:
7a9068fe 947 case EM_K1OM:
e9f53129
AM
948 case EM_XSTORMY16:
949 case EM_XTENSA:
950 case EM_XTENSA_OLD:
7ba29e2a
NC
951 case EM_MICROBLAZE:
952 case EM_MICROBLAZE_OLD:
f96bd6c2 953 case EM_WEBASSEMBLY:
015dc7e1 954 return true;
103f02d3 955
e9f53129
AM
956 case EM_68HC05:
957 case EM_68HC08:
958 case EM_68HC11:
959 case EM_68HC16:
960 case EM_FX66:
961 case EM_ME16:
d1133906 962 case EM_MMA:
d1133906
NC
963 case EM_NCPU:
964 case EM_NDR1:
e9f53129 965 case EM_PCP:
d1133906 966 case EM_ST100:
e9f53129 967 case EM_ST19:
d1133906 968 case EM_ST7:
e9f53129
AM
969 case EM_ST9PLUS:
970 case EM_STARCORE:
d1133906 971 case EM_SVX:
e9f53129 972 case EM_TINYJ:
9c19a809
NC
973 default:
974 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 975 return false;
9c19a809
NC
976 }
977}
252b5132 978
dda8d76d 979/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
980 Returns TRUE upon success, FALSE otherwise. If successful then a
981 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
982 and the number of relocs loaded is placed in *NRELASP. It is the caller's
983 responsibility to free the allocated buffer. */
984
015dc7e1 985static bool
dda8d76d
NC
986slurp_rela_relocs (Filedata * filedata,
987 unsigned long rel_offset,
988 unsigned long rel_size,
989 Elf_Internal_Rela ** relasp,
990 unsigned long * nrelasp)
9c19a809 991{
2cf0635d 992 Elf_Internal_Rela * relas;
8b73c356 993 size_t nrelas;
4d6ed7c8 994 unsigned int i;
252b5132 995
4d6ed7c8
NC
996 if (is_32bit_elf)
997 {
2cf0635d 998 Elf32_External_Rela * erelas;
103f02d3 999
dda8d76d 1000 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1001 rel_size, _("32-bit relocation data"));
a6e9f9df 1002 if (!erelas)
015dc7e1 1003 return false;
252b5132 1004
4d6ed7c8 1005 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1006
3f5e193b
NC
1007 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1008 sizeof (Elf_Internal_Rela));
103f02d3 1009
4d6ed7c8
NC
1010 if (relas == NULL)
1011 {
c256ffe7 1012 free (erelas);
591a748a 1013 error (_("out of memory parsing relocs\n"));
015dc7e1 1014 return false;
4d6ed7c8 1015 }
103f02d3 1016
4d6ed7c8
NC
1017 for (i = 0; i < nrelas; i++)
1018 {
1019 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1020 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1021 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1022 }
103f02d3 1023
4d6ed7c8
NC
1024 free (erelas);
1025 }
1026 else
1027 {
2cf0635d 1028 Elf64_External_Rela * erelas;
103f02d3 1029
dda8d76d 1030 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1031 rel_size, _("64-bit relocation data"));
a6e9f9df 1032 if (!erelas)
015dc7e1 1033 return false;
4d6ed7c8
NC
1034
1035 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1036
3f5e193b
NC
1037 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1038 sizeof (Elf_Internal_Rela));
103f02d3 1039
4d6ed7c8
NC
1040 if (relas == NULL)
1041 {
c256ffe7 1042 free (erelas);
591a748a 1043 error (_("out of memory parsing relocs\n"));
015dc7e1 1044 return false;
9c19a809 1045 }
4d6ed7c8
NC
1046
1047 for (i = 0; i < nrelas; i++)
9c19a809 1048 {
66543521
AM
1049 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1050 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1051 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1052
1053 /* The #ifdef BFD64 below is to prevent a compile time
1054 warning. We know that if we do not have a 64 bit data
1055 type that we will never execute this code anyway. */
1056#ifdef BFD64
dda8d76d
NC
1057 if (filedata->file_header.e_machine == EM_MIPS
1058 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1059 {
1060 /* In little-endian objects, r_info isn't really a
1061 64-bit little-endian value: it has a 32-bit
1062 little-endian symbol index followed by four
1063 individual byte fields. Reorder INFO
1064 accordingly. */
91d6fa6a
NC
1065 bfd_vma inf = relas[i].r_info;
1066 inf = (((inf & 0xffffffff) << 32)
1067 | ((inf >> 56) & 0xff)
1068 | ((inf >> 40) & 0xff00)
1069 | ((inf >> 24) & 0xff0000)
1070 | ((inf >> 8) & 0xff000000));
1071 relas[i].r_info = inf;
861fb55a
DJ
1072 }
1073#endif /* BFD64 */
4d6ed7c8 1074 }
103f02d3 1075
4d6ed7c8
NC
1076 free (erelas);
1077 }
32ec8896 1078
4d6ed7c8
NC
1079 *relasp = relas;
1080 *nrelasp = nrelas;
015dc7e1 1081 return true;
4d6ed7c8 1082}
103f02d3 1083
dda8d76d 1084/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1085 Returns TRUE upon success, FALSE otherwise. If successful then a
1086 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1087 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1088 responsibility to free the allocated buffer. */
1089
015dc7e1 1090static bool
dda8d76d
NC
1091slurp_rel_relocs (Filedata * filedata,
1092 unsigned long rel_offset,
1093 unsigned long rel_size,
1094 Elf_Internal_Rela ** relsp,
1095 unsigned long * nrelsp)
4d6ed7c8 1096{
2cf0635d 1097 Elf_Internal_Rela * rels;
8b73c356 1098 size_t nrels;
4d6ed7c8 1099 unsigned int i;
103f02d3 1100
4d6ed7c8
NC
1101 if (is_32bit_elf)
1102 {
2cf0635d 1103 Elf32_External_Rel * erels;
103f02d3 1104
dda8d76d 1105 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1106 rel_size, _("32-bit relocation data"));
a6e9f9df 1107 if (!erels)
015dc7e1 1108 return false;
103f02d3 1109
4d6ed7c8 1110 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1111
3f5e193b 1112 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1113
4d6ed7c8
NC
1114 if (rels == NULL)
1115 {
c256ffe7 1116 free (erels);
591a748a 1117 error (_("out of memory parsing relocs\n"));
015dc7e1 1118 return false;
4d6ed7c8
NC
1119 }
1120
1121 for (i = 0; i < nrels; i++)
1122 {
1123 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1124 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1125 rels[i].r_addend = 0;
9ea033b2 1126 }
4d6ed7c8
NC
1127
1128 free (erels);
9c19a809
NC
1129 }
1130 else
1131 {
2cf0635d 1132 Elf64_External_Rel * erels;
9ea033b2 1133
dda8d76d 1134 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1135 rel_size, _("64-bit relocation data"));
a6e9f9df 1136 if (!erels)
015dc7e1 1137 return false;
103f02d3 1138
4d6ed7c8 1139 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1140
3f5e193b 1141 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1142
4d6ed7c8 1143 if (rels == NULL)
9c19a809 1144 {
c256ffe7 1145 free (erels);
591a748a 1146 error (_("out of memory parsing relocs\n"));
015dc7e1 1147 return false;
4d6ed7c8 1148 }
103f02d3 1149
4d6ed7c8
NC
1150 for (i = 0; i < nrels; i++)
1151 {
66543521
AM
1152 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1153 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1154 rels[i].r_addend = 0;
861fb55a
DJ
1155
1156 /* The #ifdef BFD64 below is to prevent a compile time
1157 warning. We know that if we do not have a 64 bit data
1158 type that we will never execute this code anyway. */
1159#ifdef BFD64
dda8d76d
NC
1160 if (filedata->file_header.e_machine == EM_MIPS
1161 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1162 {
1163 /* In little-endian objects, r_info isn't really a
1164 64-bit little-endian value: it has a 32-bit
1165 little-endian symbol index followed by four
1166 individual byte fields. Reorder INFO
1167 accordingly. */
91d6fa6a
NC
1168 bfd_vma inf = rels[i].r_info;
1169 inf = (((inf & 0xffffffff) << 32)
1170 | ((inf >> 56) & 0xff)
1171 | ((inf >> 40) & 0xff00)
1172 | ((inf >> 24) & 0xff0000)
1173 | ((inf >> 8) & 0xff000000));
1174 rels[i].r_info = inf;
861fb55a
DJ
1175 }
1176#endif /* BFD64 */
4d6ed7c8 1177 }
103f02d3 1178
4d6ed7c8
NC
1179 free (erels);
1180 }
32ec8896 1181
4d6ed7c8
NC
1182 *relsp = rels;
1183 *nrelsp = nrels;
015dc7e1 1184 return true;
4d6ed7c8 1185}
103f02d3 1186
aca88567
NC
1187/* Returns the reloc type extracted from the reloc info field. */
1188
1189static unsigned int
dda8d76d 1190get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1191{
1192 if (is_32bit_elf)
1193 return ELF32_R_TYPE (reloc_info);
1194
dda8d76d 1195 switch (filedata->file_header.e_machine)
aca88567
NC
1196 {
1197 case EM_MIPS:
1198 /* Note: We assume that reloc_info has already been adjusted for us. */
1199 return ELF64_MIPS_R_TYPE (reloc_info);
1200
1201 case EM_SPARCV9:
1202 return ELF64_R_TYPE_ID (reloc_info);
1203
1204 default:
1205 return ELF64_R_TYPE (reloc_info);
1206 }
1207}
1208
1209/* Return the symbol index extracted from the reloc info field. */
1210
1211static bfd_vma
1212get_reloc_symindex (bfd_vma reloc_info)
1213{
1214 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1215}
1216
015dc7e1 1217static inline bool
dda8d76d 1218uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1219{
1220 return
dda8d76d 1221 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1222 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1223 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1224 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1225 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1226}
1227
d3ba0551
AM
1228/* Display the contents of the relocation data found at the specified
1229 offset. */
ee42cf8c 1230
015dc7e1 1231static bool
dda8d76d
NC
1232dump_relocations (Filedata * filedata,
1233 unsigned long rel_offset,
1234 unsigned long rel_size,
1235 Elf_Internal_Sym * symtab,
1236 unsigned long nsyms,
1237 char * strtab,
1238 unsigned long strtablen,
1239 int is_rela,
015dc7e1 1240 bool is_dynsym)
4d6ed7c8 1241{
32ec8896 1242 unsigned long i;
2cf0635d 1243 Elf_Internal_Rela * rels;
015dc7e1 1244 bool res = true;
103f02d3 1245
4d6ed7c8 1246 if (is_rela == UNKNOWN)
dda8d76d 1247 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1248
4d6ed7c8
NC
1249 if (is_rela)
1250 {
dda8d76d 1251 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1252 return false;
4d6ed7c8
NC
1253 }
1254 else
1255 {
dda8d76d 1256 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1257 return false;
252b5132
RH
1258 }
1259
410f7a12
L
1260 if (is_32bit_elf)
1261 {
1262 if (is_rela)
2c71103e
NC
1263 {
1264 if (do_wide)
1265 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1266 else
1267 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1268 }
410f7a12 1269 else
2c71103e
NC
1270 {
1271 if (do_wide)
1272 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1273 else
1274 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1275 }
410f7a12 1276 }
252b5132 1277 else
410f7a12
L
1278 {
1279 if (is_rela)
2c71103e
NC
1280 {
1281 if (do_wide)
8beeaeb7 1282 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1283 else
1284 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1285 }
410f7a12 1286 else
2c71103e
NC
1287 {
1288 if (do_wide)
8beeaeb7 1289 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1290 else
1291 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1292 }
410f7a12 1293 }
252b5132
RH
1294
1295 for (i = 0; i < rel_size; i++)
1296 {
2cf0635d 1297 const char * rtype;
b34976b6 1298 bfd_vma offset;
91d6fa6a 1299 bfd_vma inf;
b34976b6
AM
1300 bfd_vma symtab_index;
1301 bfd_vma type;
103f02d3 1302
b34976b6 1303 offset = rels[i].r_offset;
91d6fa6a 1304 inf = rels[i].r_info;
103f02d3 1305
dda8d76d 1306 type = get_reloc_type (filedata, inf);
91d6fa6a 1307 symtab_index = get_reloc_symindex (inf);
252b5132 1308
410f7a12
L
1309 if (is_32bit_elf)
1310 {
39dbeff8
AM
1311 printf ("%8.8lx %8.8lx ",
1312 (unsigned long) offset & 0xffffffff,
91d6fa6a 1313 (unsigned long) inf & 0xffffffff);
410f7a12
L
1314 }
1315 else
1316 {
39dbeff8 1317 printf (do_wide
d1ce973e
AM
1318 ? "%16.16" BFD_VMA_FMT "x %16.16" BFD_VMA_FMT "x "
1319 : "%12.12" BFD_VMA_FMT "x %12.12" BFD_VMA_FMT "x ",
91d6fa6a 1320 offset, inf);
410f7a12 1321 }
103f02d3 1322
dda8d76d 1323 switch (filedata->file_header.e_machine)
252b5132
RH
1324 {
1325 default:
1326 rtype = NULL;
1327 break;
1328
a06ea964
NC
1329 case EM_AARCH64:
1330 rtype = elf_aarch64_reloc_type (type);
1331 break;
1332
2b0337b0 1333 case EM_M32R:
252b5132 1334 case EM_CYGNUS_M32R:
9ea033b2 1335 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1336 break;
1337
1338 case EM_386:
22abe556 1339 case EM_IAMCU:
9ea033b2 1340 rtype = elf_i386_reloc_type (type);
252b5132
RH
1341 break;
1342
ba2685cc
AM
1343 case EM_68HC11:
1344 case EM_68HC12:
1345 rtype = elf_m68hc11_reloc_type (type);
1346 break;
75751cd9 1347
7b4ae824
JD
1348 case EM_S12Z:
1349 rtype = elf_s12z_reloc_type (type);
1350 break;
1351
252b5132 1352 case EM_68K:
9ea033b2 1353 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1354 break;
1355
f954747f
AM
1356 case EM_960:
1357 rtype = elf_i960_reloc_type (type);
1358 break;
1359
adde6300 1360 case EM_AVR:
2b0337b0 1361 case EM_AVR_OLD:
adde6300
AM
1362 rtype = elf_avr_reloc_type (type);
1363 break;
1364
9ea033b2
NC
1365 case EM_OLD_SPARCV9:
1366 case EM_SPARC32PLUS:
1367 case EM_SPARCV9:
252b5132 1368 case EM_SPARC:
9ea033b2 1369 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1370 break;
1371
e9f53129
AM
1372 case EM_SPU:
1373 rtype = elf_spu_reloc_type (type);
1374 break;
1375
708e2187
NC
1376 case EM_V800:
1377 rtype = v800_reloc_type (type);
1378 break;
2b0337b0 1379 case EM_V850:
252b5132 1380 case EM_CYGNUS_V850:
9ea033b2 1381 rtype = v850_reloc_type (type);
252b5132
RH
1382 break;
1383
2b0337b0 1384 case EM_D10V:
252b5132 1385 case EM_CYGNUS_D10V:
9ea033b2 1386 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1387 break;
1388
2b0337b0 1389 case EM_D30V:
252b5132 1390 case EM_CYGNUS_D30V:
9ea033b2 1391 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1392 break;
1393
d172d4ba
NC
1394 case EM_DLX:
1395 rtype = elf_dlx_reloc_type (type);
1396 break;
1397
252b5132 1398 case EM_SH:
9ea033b2 1399 rtype = elf_sh_reloc_type (type);
252b5132
RH
1400 break;
1401
2b0337b0 1402 case EM_MN10300:
252b5132 1403 case EM_CYGNUS_MN10300:
9ea033b2 1404 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1405 break;
1406
2b0337b0 1407 case EM_MN10200:
252b5132 1408 case EM_CYGNUS_MN10200:
9ea033b2 1409 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1410 break;
1411
2b0337b0 1412 case EM_FR30:
252b5132 1413 case EM_CYGNUS_FR30:
9ea033b2 1414 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1415 break;
1416
ba2685cc
AM
1417 case EM_CYGNUS_FRV:
1418 rtype = elf_frv_reloc_type (type);
1419 break;
5c70f934 1420
b8891f8d
AJ
1421 case EM_CSKY:
1422 rtype = elf_csky_reloc_type (type);
1423 break;
1424
3f8107ab
AM
1425 case EM_FT32:
1426 rtype = elf_ft32_reloc_type (type);
1427 break;
1428
252b5132 1429 case EM_MCORE:
9ea033b2 1430 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1431 break;
1432
3c3bdf30
NC
1433 case EM_MMIX:
1434 rtype = elf_mmix_reloc_type (type);
1435 break;
1436
5506d11a
AM
1437 case EM_MOXIE:
1438 rtype = elf_moxie_reloc_type (type);
1439 break;
1440
2469cfa2 1441 case EM_MSP430:
dda8d76d 1442 if (uses_msp430x_relocs (filedata))
13761a11
NC
1443 {
1444 rtype = elf_msp430x_reloc_type (type);
1445 break;
1446 }
1a0670f3 1447 /* Fall through. */
2469cfa2
NC
1448 case EM_MSP430_OLD:
1449 rtype = elf_msp430_reloc_type (type);
1450 break;
1451
35c08157
KLC
1452 case EM_NDS32:
1453 rtype = elf_nds32_reloc_type (type);
1454 break;
1455
252b5132 1456 case EM_PPC:
9ea033b2 1457 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1458 break;
1459
c833c019
AM
1460 case EM_PPC64:
1461 rtype = elf_ppc64_reloc_type (type);
1462 break;
1463
252b5132 1464 case EM_MIPS:
4fe85591 1465 case EM_MIPS_RS3_LE:
9ea033b2 1466 rtype = elf_mips_reloc_type (type);
252b5132
RH
1467 break;
1468
e23eba97
NC
1469 case EM_RISCV:
1470 rtype = elf_riscv_reloc_type (type);
1471 break;
1472
252b5132 1473 case EM_ALPHA:
9ea033b2 1474 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1475 break;
1476
1477 case EM_ARM:
9ea033b2 1478 rtype = elf_arm_reloc_type (type);
252b5132
RH
1479 break;
1480
584da044 1481 case EM_ARC:
886a2506
NC
1482 case EM_ARC_COMPACT:
1483 case EM_ARC_COMPACT2:
9ea033b2 1484 rtype = elf_arc_reloc_type (type);
252b5132
RH
1485 break;
1486
1487 case EM_PARISC:
69e617ca 1488 rtype = elf_hppa_reloc_type (type);
252b5132 1489 break;
7d466069 1490
b8720f9d
JL
1491 case EM_H8_300:
1492 case EM_H8_300H:
1493 case EM_H8S:
1494 rtype = elf_h8_reloc_type (type);
1495 break;
1496
73589c9d
CS
1497 case EM_OR1K:
1498 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1499 break;
1500
7d466069 1501 case EM_PJ:
2b0337b0 1502 case EM_PJ_OLD:
7d466069
ILT
1503 rtype = elf_pj_reloc_type (type);
1504 break;
800eeca4
JW
1505 case EM_IA_64:
1506 rtype = elf_ia64_reloc_type (type);
1507 break;
1b61cf92
HPN
1508
1509 case EM_CRIS:
1510 rtype = elf_cris_reloc_type (type);
1511 break;
535c37ff 1512
f954747f
AM
1513 case EM_860:
1514 rtype = elf_i860_reloc_type (type);
1515 break;
1516
bcedfee6 1517 case EM_X86_64:
8a9036a4 1518 case EM_L1OM:
7a9068fe 1519 case EM_K1OM:
bcedfee6
NC
1520 rtype = elf_x86_64_reloc_type (type);
1521 break;
a85d7ed0 1522
f954747f
AM
1523 case EM_S370:
1524 rtype = i370_reloc_type (type);
1525 break;
1526
53c7db4b
KH
1527 case EM_S390_OLD:
1528 case EM_S390:
1529 rtype = elf_s390_reloc_type (type);
1530 break;
93fbbb04 1531
1c0d3aa6
NC
1532 case EM_SCORE:
1533 rtype = elf_score_reloc_type (type);
1534 break;
1535
93fbbb04
GK
1536 case EM_XSTORMY16:
1537 rtype = elf_xstormy16_reloc_type (type);
1538 break;
179d3252 1539
1fe1f39c
NC
1540 case EM_CRX:
1541 rtype = elf_crx_reloc_type (type);
1542 break;
1543
179d3252
JT
1544 case EM_VAX:
1545 rtype = elf_vax_reloc_type (type);
1546 break;
1e4cf259 1547
619ed720
EB
1548 case EM_VISIUM:
1549 rtype = elf_visium_reloc_type (type);
1550 break;
1551
aca4efc7
JM
1552 case EM_BPF:
1553 rtype = elf_bpf_reloc_type (type);
1554 break;
1555
cfb8c092
NC
1556 case EM_ADAPTEVA_EPIPHANY:
1557 rtype = elf_epiphany_reloc_type (type);
1558 break;
1559
1e4cf259
NC
1560 case EM_IP2K:
1561 case EM_IP2K_OLD:
1562 rtype = elf_ip2k_reloc_type (type);
1563 break;
3b36097d
SC
1564
1565 case EM_IQ2000:
1566 rtype = elf_iq2000_reloc_type (type);
1567 break;
88da6820
NC
1568
1569 case EM_XTENSA_OLD:
1570 case EM_XTENSA:
1571 rtype = elf_xtensa_reloc_type (type);
1572 break;
a34e3ecb 1573
84e94c90
NC
1574 case EM_LATTICEMICO32:
1575 rtype = elf_lm32_reloc_type (type);
1576 break;
1577
ff7eeb89 1578 case EM_M32C_OLD:
49f58d10
JB
1579 case EM_M32C:
1580 rtype = elf_m32c_reloc_type (type);
1581 break;
1582
d031aafb
NS
1583 case EM_MT:
1584 rtype = elf_mt_reloc_type (type);
a34e3ecb 1585 break;
1d65ded4
CM
1586
1587 case EM_BLACKFIN:
1588 rtype = elf_bfin_reloc_type (type);
1589 break;
15ab5209
DB
1590
1591 case EM_CYGNUS_MEP:
1592 rtype = elf_mep_reloc_type (type);
1593 break;
60bca95a
NC
1594
1595 case EM_CR16:
1596 rtype = elf_cr16_reloc_type (type);
1597 break;
dd24e3da 1598
7ba29e2a
NC
1599 case EM_MICROBLAZE:
1600 case EM_MICROBLAZE_OLD:
1601 rtype = elf_microblaze_reloc_type (type);
1602 break;
c7927a3c 1603
99c513f6
DD
1604 case EM_RL78:
1605 rtype = elf_rl78_reloc_type (type);
1606 break;
1607
c7927a3c
NC
1608 case EM_RX:
1609 rtype = elf_rx_reloc_type (type);
1610 break;
c29aca4a 1611
a3c62988
NC
1612 case EM_METAG:
1613 rtype = elf_metag_reloc_type (type);
1614 break;
1615
c29aca4a
NC
1616 case EM_XC16X:
1617 case EM_C166:
1618 rtype = elf_xc16x_reloc_type (type);
1619 break;
40b36596
JM
1620
1621 case EM_TI_C6000:
1622 rtype = elf_tic6x_reloc_type (type);
1623 break;
aa137e4d
NC
1624
1625 case EM_TILEGX:
1626 rtype = elf_tilegx_reloc_type (type);
1627 break;
1628
1629 case EM_TILEPRO:
1630 rtype = elf_tilepro_reloc_type (type);
1631 break;
f6c1a2d5 1632
f96bd6c2
PC
1633 case EM_WEBASSEMBLY:
1634 rtype = elf_wasm32_reloc_type (type);
1635 break;
1636
f6c1a2d5
NC
1637 case EM_XGATE:
1638 rtype = elf_xgate_reloc_type (type);
1639 break;
36591ba1
SL
1640
1641 case EM_ALTERA_NIOS2:
1642 rtype = elf_nios2_reloc_type (type);
1643 break;
2b100bb5
DD
1644
1645 case EM_TI_PRU:
1646 rtype = elf_pru_reloc_type (type);
1647 break;
fe944acf
FT
1648
1649 case EM_NFP:
1650 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1651 rtype = elf_nfp3200_reloc_type (type);
1652 else
1653 rtype = elf_nfp_reloc_type (type);
1654 break;
6655dba2
SB
1655
1656 case EM_Z80:
1657 rtype = elf_z80_reloc_type (type);
1658 break;
252b5132
RH
1659 }
1660
1661 if (rtype == NULL)
39dbeff8 1662 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1663 else
5c144731 1664 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1665
dda8d76d 1666 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1667 && rtype != NULL
7ace3541
RH
1668 && streq (rtype, "R_ALPHA_LITUSE")
1669 && is_rela)
1670 {
1671 switch (rels[i].r_addend)
1672 {
1673 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1674 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1675 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1676 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1677 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1678 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1679 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1680 default: rtype = NULL;
1681 }
32ec8896 1682
7ace3541
RH
1683 if (rtype)
1684 printf (" (%s)", rtype);
1685 else
1686 {
1687 putchar (' ');
1688 printf (_("<unknown addend: %lx>"),
1689 (unsigned long) rels[i].r_addend);
015dc7e1 1690 res = false;
7ace3541
RH
1691 }
1692 }
1693 else if (symtab_index)
252b5132 1694 {
af3fc3bc 1695 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1696 {
27a45f42
AS
1697 error (_(" bad symbol index: %08lx in reloc\n"),
1698 (unsigned long) symtab_index);
015dc7e1 1699 res = false;
32ec8896 1700 }
af3fc3bc 1701 else
19936277 1702 {
2cf0635d 1703 Elf_Internal_Sym * psym;
bb4d2ac2
L
1704 const char * version_string;
1705 enum versioned_symbol_info sym_info;
1706 unsigned short vna_other;
19936277 1707
af3fc3bc 1708 psym = symtab + symtab_index;
103f02d3 1709
bb4d2ac2 1710 version_string
dda8d76d 1711 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1712 strtab, strtablen,
1713 symtab_index,
1714 psym,
1715 &sym_info,
1716 &vna_other);
1717
af3fc3bc 1718 printf (" ");
171191ba 1719
d8045f23
NC
1720 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1721 {
1722 const char * name;
1723 unsigned int len;
1724 unsigned int width = is_32bit_elf ? 8 : 14;
1725
1726 /* Relocations against GNU_IFUNC symbols do not use the value
1727 of the symbol as the address to relocate against. Instead
1728 they invoke the function named by the symbol and use its
1729 result as the address for relocation.
1730
1731 To indicate this to the user, do not display the value of
1732 the symbol in the "Symbols's Value" field. Instead show
1733 its name followed by () as a hint that the symbol is
1734 invoked. */
1735
1736 if (strtab == NULL
1737 || psym->st_name == 0
1738 || psym->st_name >= strtablen)
1739 name = "??";
1740 else
1741 name = strtab + psym->st_name;
1742
1743 len = print_symbol (width, name);
bb4d2ac2
L
1744 if (version_string)
1745 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1746 version_string);
d8045f23
NC
1747 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1748 }
1749 else
1750 {
1751 print_vma (psym->st_value, LONG_HEX);
171191ba 1752
d8045f23
NC
1753 printf (is_32bit_elf ? " " : " ");
1754 }
103f02d3 1755
af3fc3bc 1756 if (psym->st_name == 0)
f1ef08cb 1757 {
2cf0635d 1758 const char * sec_name = "<null>";
f1ef08cb
AM
1759 char name_buf[40];
1760
1761 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1762 {
dda8d76d 1763 if (psym->st_shndx < filedata->file_header.e_shnum)
b9e920ec
AM
1764 sec_name = SECTION_NAME_PRINT (filedata->section_headers
1765 + psym->st_shndx);
f1ef08cb
AM
1766 else if (psym->st_shndx == SHN_ABS)
1767 sec_name = "ABS";
1768 else if (psym->st_shndx == SHN_COMMON)
1769 sec_name = "COMMON";
dda8d76d 1770 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1771 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1772 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1773 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1774 sec_name = "SCOMMON";
dda8d76d 1775 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1776 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1777 sec_name = "SUNDEF";
dda8d76d
NC
1778 else if ((filedata->file_header.e_machine == EM_X86_64
1779 || filedata->file_header.e_machine == EM_L1OM
1780 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1781 && psym->st_shndx == SHN_X86_64_LCOMMON)
1782 sec_name = "LARGE_COMMON";
dda8d76d
NC
1783 else if (filedata->file_header.e_machine == EM_IA_64
1784 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1785 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1786 sec_name = "ANSI_COM";
dda8d76d 1787 else if (is_ia64_vms (filedata)
148b93f2
NC
1788 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1789 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1790 else
1791 {
1792 sprintf (name_buf, "<section 0x%x>",
1793 (unsigned int) psym->st_shndx);
1794 sec_name = name_buf;
1795 }
1796 }
1797 print_symbol (22, sec_name);
1798 }
af3fc3bc 1799 else if (strtab == NULL)
d79b3d50 1800 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1801 else if (psym->st_name >= strtablen)
32ec8896 1802 {
27a45f42
AS
1803 error (_("<corrupt string table index: %3ld>\n"),
1804 psym->st_name);
015dc7e1 1805 res = false;
32ec8896 1806 }
af3fc3bc 1807 else
bb4d2ac2
L
1808 {
1809 print_symbol (22, strtab + psym->st_name);
1810 if (version_string)
1811 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1812 version_string);
1813 }
103f02d3 1814
af3fc3bc 1815 if (is_rela)
171191ba 1816 {
7360e63f 1817 bfd_vma off = rels[i].r_addend;
171191ba 1818
7360e63f 1819 if ((bfd_signed_vma) off < 0)
598aaa76 1820 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1821 else
598aaa76 1822 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1823 }
19936277 1824 }
252b5132 1825 }
1b228002 1826 else if (is_rela)
f7a99963 1827 {
7360e63f 1828 bfd_vma off = rels[i].r_addend;
e04d7088
L
1829
1830 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1831 if ((bfd_signed_vma) off < 0)
e04d7088
L
1832 printf ("-%" BFD_VMA_FMT "x", - off);
1833 else
1834 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1835 }
252b5132 1836
dda8d76d 1837 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1838 && rtype != NULL
1839 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1840 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1841
252b5132 1842 putchar ('\n');
2c71103e 1843
aca88567 1844#ifdef BFD64
dda8d76d 1845 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1846 {
91d6fa6a
NC
1847 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1848 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1849 const char * rtype2 = elf_mips_reloc_type (type2);
1850 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1851
2c71103e
NC
1852 printf (" Type2: ");
1853
1854 if (rtype2 == NULL)
39dbeff8
AM
1855 printf (_("unrecognized: %-7lx"),
1856 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1857 else
1858 printf ("%-17.17s", rtype2);
1859
18bd398b 1860 printf ("\n Type3: ");
2c71103e
NC
1861
1862 if (rtype3 == NULL)
39dbeff8
AM
1863 printf (_("unrecognized: %-7lx"),
1864 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1865 else
1866 printf ("%-17.17s", rtype3);
1867
53c7db4b 1868 putchar ('\n');
2c71103e 1869 }
aca88567 1870#endif /* BFD64 */
252b5132
RH
1871 }
1872
c8286bd1 1873 free (rels);
32ec8896
NC
1874
1875 return res;
252b5132
RH
1876}
1877
37c18eed
SD
1878static const char *
1879get_aarch64_dynamic_type (unsigned long type)
1880{
1881 switch (type)
1882 {
1883 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 1884 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 1885 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
1886 default:
1887 return NULL;
1888 }
1889}
1890
252b5132 1891static const char *
d3ba0551 1892get_mips_dynamic_type (unsigned long type)
252b5132
RH
1893{
1894 switch (type)
1895 {
1896 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1897 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1898 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1899 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1900 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1901 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1902 case DT_MIPS_MSYM: return "MIPS_MSYM";
1903 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1904 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1905 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1906 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1907 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1908 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1909 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1910 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1911 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1912 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1913 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1914 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1915 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1916 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1917 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1918 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1919 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1920 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1921 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1922 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1923 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1924 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1925 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1926 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1927 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1928 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1929 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1930 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1931 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1932 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1933 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1934 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1935 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1936 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1937 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1938 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1939 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1940 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1941 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 1942 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
1943 default:
1944 return NULL;
1945 }
1946}
1947
9a097730 1948static const char *
d3ba0551 1949get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1950{
1951 switch (type)
1952 {
1953 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1954 default:
1955 return NULL;
1956 }
103f02d3
UD
1957}
1958
7490d522
AM
1959static const char *
1960get_ppc_dynamic_type (unsigned long type)
1961{
1962 switch (type)
1963 {
a7f2871e 1964 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1965 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1966 default:
1967 return NULL;
1968 }
1969}
1970
f1cb7e17 1971static const char *
d3ba0551 1972get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1973{
1974 switch (type)
1975 {
a7f2871e
AM
1976 case DT_PPC64_GLINK: return "PPC64_GLINK";
1977 case DT_PPC64_OPD: return "PPC64_OPD";
1978 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1979 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1980 default:
1981 return NULL;
1982 }
1983}
1984
103f02d3 1985static const char *
d3ba0551 1986get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1987{
1988 switch (type)
1989 {
1990 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1991 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1992 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1993 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1994 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1995 case DT_HP_PREINIT: return "HP_PREINIT";
1996 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1997 case DT_HP_NEEDED: return "HP_NEEDED";
1998 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1999 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2000 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2001 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2002 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2003 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2004 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2005 case DT_HP_FILTERED: return "HP_FILTERED";
2006 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2007 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2008 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2009 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2010 case DT_PLT: return "PLT";
2011 case DT_PLT_SIZE: return "PLT_SIZE";
2012 case DT_DLT: return "DLT";
2013 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2014 default:
2015 return NULL;
2016 }
2017}
9a097730 2018
ecc51f48 2019static const char *
d3ba0551 2020get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2021{
2022 switch (type)
2023 {
148b93f2
NC
2024 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2025 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2026 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2027 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2028 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2029 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2030 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2031 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2032 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2033 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2034 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2035 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2036 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2037 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2038 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2039 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2040 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2041 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2042 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2043 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2044 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2045 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2046 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2047 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2048 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2049 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2050 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2051 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2052 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2053 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2054 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2055 default:
2056 return NULL;
2057 }
2058}
2059
fd85a6a1
NC
2060static const char *
2061get_solaris_section_type (unsigned long type)
2062{
2063 switch (type)
2064 {
2065 case 0x6fffffee: return "SUNW_ancillary";
2066 case 0x6fffffef: return "SUNW_capchain";
2067 case 0x6ffffff0: return "SUNW_capinfo";
2068 case 0x6ffffff1: return "SUNW_symsort";
2069 case 0x6ffffff2: return "SUNW_tlssort";
2070 case 0x6ffffff3: return "SUNW_LDYNSYM";
2071 case 0x6ffffff4: return "SUNW_dof";
2072 case 0x6ffffff5: return "SUNW_cap";
2073 case 0x6ffffff6: return "SUNW_SIGNATURE";
2074 case 0x6ffffff7: return "SUNW_ANNOTATE";
2075 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2076 case 0x6ffffff9: return "SUNW_DEBUG";
2077 case 0x6ffffffa: return "SUNW_move";
2078 case 0x6ffffffb: return "SUNW_COMDAT";
2079 case 0x6ffffffc: return "SUNW_syminfo";
2080 case 0x6ffffffd: return "SUNW_verdef";
2081 case 0x6ffffffe: return "SUNW_verneed";
2082 case 0x6fffffff: return "SUNW_versym";
2083 case 0x70000000: return "SPARC_GOTDATA";
2084 default: return NULL;
2085 }
2086}
2087
fabcb361
RH
2088static const char *
2089get_alpha_dynamic_type (unsigned long type)
2090{
2091 switch (type)
2092 {
2093 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2094 default: return NULL;
fabcb361
RH
2095 }
2096}
2097
1c0d3aa6
NC
2098static const char *
2099get_score_dynamic_type (unsigned long type)
2100{
2101 switch (type)
2102 {
2103 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2104 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2105 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2106 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2107 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2108 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2109 default: return NULL;
1c0d3aa6
NC
2110 }
2111}
2112
40b36596
JM
2113static const char *
2114get_tic6x_dynamic_type (unsigned long type)
2115{
2116 switch (type)
2117 {
2118 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2119 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2120 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2121 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2122 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2123 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2124 default: return NULL;
40b36596
JM
2125 }
2126}
1c0d3aa6 2127
36591ba1
SL
2128static const char *
2129get_nios2_dynamic_type (unsigned long type)
2130{
2131 switch (type)
2132 {
2133 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2134 default: return NULL;
36591ba1
SL
2135 }
2136}
2137
fd85a6a1
NC
2138static const char *
2139get_solaris_dynamic_type (unsigned long type)
2140{
2141 switch (type)
2142 {
2143 case 0x6000000d: return "SUNW_AUXILIARY";
2144 case 0x6000000e: return "SUNW_RTLDINF";
2145 case 0x6000000f: return "SUNW_FILTER";
2146 case 0x60000010: return "SUNW_CAP";
2147 case 0x60000011: return "SUNW_SYMTAB";
2148 case 0x60000012: return "SUNW_SYMSZ";
2149 case 0x60000013: return "SUNW_SORTENT";
2150 case 0x60000014: return "SUNW_SYMSORT";
2151 case 0x60000015: return "SUNW_SYMSORTSZ";
2152 case 0x60000016: return "SUNW_TLSSORT";
2153 case 0x60000017: return "SUNW_TLSSORTSZ";
2154 case 0x60000018: return "SUNW_CAPINFO";
2155 case 0x60000019: return "SUNW_STRPAD";
2156 case 0x6000001a: return "SUNW_CAPCHAIN";
2157 case 0x6000001b: return "SUNW_LDMACH";
2158 case 0x6000001d: return "SUNW_CAPCHAINENT";
2159 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2160 case 0x60000021: return "SUNW_PARENT";
2161 case 0x60000023: return "SUNW_ASLR";
2162 case 0x60000025: return "SUNW_RELAX";
2163 case 0x60000029: return "SUNW_NXHEAP";
2164 case 0x6000002b: return "SUNW_NXSTACK";
2165
2166 case 0x70000001: return "SPARC_REGISTER";
2167 case 0x7ffffffd: return "AUXILIARY";
2168 case 0x7ffffffe: return "USED";
2169 case 0x7fffffff: return "FILTER";
2170
15f205b1 2171 default: return NULL;
fd85a6a1
NC
2172 }
2173}
2174
252b5132 2175static const char *
dda8d76d 2176get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2177{
e9e44622 2178 static char buff[64];
252b5132
RH
2179
2180 switch (type)
2181 {
2182 case DT_NULL: return "NULL";
2183 case DT_NEEDED: return "NEEDED";
2184 case DT_PLTRELSZ: return "PLTRELSZ";
2185 case DT_PLTGOT: return "PLTGOT";
2186 case DT_HASH: return "HASH";
2187 case DT_STRTAB: return "STRTAB";
2188 case DT_SYMTAB: return "SYMTAB";
2189 case DT_RELA: return "RELA";
2190 case DT_RELASZ: return "RELASZ";
2191 case DT_RELAENT: return "RELAENT";
2192 case DT_STRSZ: return "STRSZ";
2193 case DT_SYMENT: return "SYMENT";
2194 case DT_INIT: return "INIT";
2195 case DT_FINI: return "FINI";
2196 case DT_SONAME: return "SONAME";
2197 case DT_RPATH: return "RPATH";
2198 case DT_SYMBOLIC: return "SYMBOLIC";
2199 case DT_REL: return "REL";
2200 case DT_RELSZ: return "RELSZ";
2201 case DT_RELENT: return "RELENT";
2202 case DT_PLTREL: return "PLTREL";
2203 case DT_DEBUG: return "DEBUG";
2204 case DT_TEXTREL: return "TEXTREL";
2205 case DT_JMPREL: return "JMPREL";
2206 case DT_BIND_NOW: return "BIND_NOW";
2207 case DT_INIT_ARRAY: return "INIT_ARRAY";
2208 case DT_FINI_ARRAY: return "FINI_ARRAY";
2209 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2210 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2211 case DT_RUNPATH: return "RUNPATH";
2212 case DT_FLAGS: return "FLAGS";
2d0e6f43 2213
d1133906
NC
2214 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2215 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2216 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2217
05107a46 2218 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2219 case DT_PLTPADSZ: return "PLTPADSZ";
2220 case DT_MOVEENT: return "MOVEENT";
2221 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2222 case DT_FEATURE: return "FEATURE";
252b5132
RH
2223 case DT_POSFLAG_1: return "POSFLAG_1";
2224 case DT_SYMINSZ: return "SYMINSZ";
2225 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2226
252b5132 2227 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2228 case DT_CONFIG: return "CONFIG";
2229 case DT_DEPAUDIT: return "DEPAUDIT";
2230 case DT_AUDIT: return "AUDIT";
2231 case DT_PLTPAD: return "PLTPAD";
2232 case DT_MOVETAB: return "MOVETAB";
252b5132 2233 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2234
252b5132 2235 case DT_VERSYM: return "VERSYM";
103f02d3 2236
67a4f2b7
AO
2237 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2238 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2239 case DT_RELACOUNT: return "RELACOUNT";
2240 case DT_RELCOUNT: return "RELCOUNT";
2241 case DT_FLAGS_1: return "FLAGS_1";
2242 case DT_VERDEF: return "VERDEF";
2243 case DT_VERDEFNUM: return "VERDEFNUM";
2244 case DT_VERNEED: return "VERNEED";
2245 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2246
019148e4 2247 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2248 case DT_USED: return "USED";
2249 case DT_FILTER: return "FILTER";
103f02d3 2250
047b2264
JJ
2251 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2252 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2253 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2254 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2255 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2256 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2257 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2258
252b5132
RH
2259 default:
2260 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2261 {
2cf0635d 2262 const char * result;
103f02d3 2263
dda8d76d 2264 switch (filedata->file_header.e_machine)
252b5132 2265 {
37c18eed
SD
2266 case EM_AARCH64:
2267 result = get_aarch64_dynamic_type (type);
2268 break;
252b5132 2269 case EM_MIPS:
4fe85591 2270 case EM_MIPS_RS3_LE:
252b5132
RH
2271 result = get_mips_dynamic_type (type);
2272 break;
9a097730
RH
2273 case EM_SPARCV9:
2274 result = get_sparc64_dynamic_type (type);
2275 break;
7490d522
AM
2276 case EM_PPC:
2277 result = get_ppc_dynamic_type (type);
2278 break;
f1cb7e17
AM
2279 case EM_PPC64:
2280 result = get_ppc64_dynamic_type (type);
2281 break;
ecc51f48
NC
2282 case EM_IA_64:
2283 result = get_ia64_dynamic_type (type);
2284 break;
fabcb361
RH
2285 case EM_ALPHA:
2286 result = get_alpha_dynamic_type (type);
2287 break;
1c0d3aa6
NC
2288 case EM_SCORE:
2289 result = get_score_dynamic_type (type);
2290 break;
40b36596
JM
2291 case EM_TI_C6000:
2292 result = get_tic6x_dynamic_type (type);
2293 break;
36591ba1
SL
2294 case EM_ALTERA_NIOS2:
2295 result = get_nios2_dynamic_type (type);
2296 break;
252b5132 2297 default:
dda8d76d 2298 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2299 result = get_solaris_dynamic_type (type);
2300 else
2301 result = NULL;
252b5132
RH
2302 break;
2303 }
2304
2305 if (result != NULL)
2306 return result;
2307
e9e44622 2308 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2309 }
eec8f817 2310 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2311 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2312 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2313 {
2cf0635d 2314 const char * result;
103f02d3 2315
dda8d76d 2316 switch (filedata->file_header.e_machine)
103f02d3
UD
2317 {
2318 case EM_PARISC:
2319 result = get_parisc_dynamic_type (type);
2320 break;
148b93f2
NC
2321 case EM_IA_64:
2322 result = get_ia64_dynamic_type (type);
2323 break;
103f02d3 2324 default:
dda8d76d 2325 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2326 result = get_solaris_dynamic_type (type);
2327 else
2328 result = NULL;
103f02d3
UD
2329 break;
2330 }
2331
2332 if (result != NULL)
2333 return result;
2334
e9e44622
JJ
2335 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2336 type);
103f02d3 2337 }
252b5132 2338 else
e9e44622 2339 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2340
252b5132
RH
2341 return buff;
2342 }
2343}
2344
2345static char *
d3ba0551 2346get_file_type (unsigned e_type)
252b5132 2347{
89246a0e 2348 static char buff[64];
252b5132
RH
2349
2350 switch (e_type)
2351 {
32ec8896
NC
2352 case ET_NONE: return _("NONE (None)");
2353 case ET_REL: return _("REL (Relocatable file)");
2354 case ET_EXEC: return _("EXEC (Executable file)");
2355 case ET_DYN: return _("DYN (Shared object file)");
2356 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2357
2358 default:
2359 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2360 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2361 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2362 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2363 else
e9e44622 2364 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2365 return buff;
2366 }
2367}
2368
2369static char *
d3ba0551 2370get_machine_name (unsigned e_machine)
252b5132 2371{
b34976b6 2372 static char buff[64]; /* XXX */
252b5132
RH
2373
2374 switch (e_machine)
2375 {
55e22ca8
NC
2376 /* Please keep this switch table sorted by increasing EM_ value. */
2377 /* 0 */
c45021f2
NC
2378 case EM_NONE: return _("None");
2379 case EM_M32: return "WE32100";
2380 case EM_SPARC: return "Sparc";
2381 case EM_386: return "Intel 80386";
2382 case EM_68K: return "MC68000";
2383 case EM_88K: return "MC88000";
22abe556 2384 case EM_IAMCU: return "Intel MCU";
fb70ec17 2385 case EM_860: return "Intel 80860";
c45021f2
NC
2386 case EM_MIPS: return "MIPS R3000";
2387 case EM_S370: return "IBM System/370";
55e22ca8 2388 /* 10 */
7036c0e1 2389 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2390 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2391 case EM_PARISC: return "HPPA";
55e22ca8 2392 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2393 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2394 case EM_960: return "Intel 80960";
c45021f2 2395 case EM_PPC: return "PowerPC";
55e22ca8 2396 /* 20 */
285d1771 2397 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2398 case EM_S390_OLD:
2399 case EM_S390: return "IBM S/390";
2400 case EM_SPU: return "SPU";
2401 /* 30 */
2402 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2403 case EM_FR20: return "Fujitsu FR20";
2404 case EM_RH32: return "TRW RH32";
b34976b6 2405 case EM_MCORE: return "MCORE";
55e22ca8 2406 /* 40 */
7036c0e1
AJ
2407 case EM_ARM: return "ARM";
2408 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2409 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2410 case EM_SPARCV9: return "Sparc v9";
2411 case EM_TRICORE: return "Siemens Tricore";
584da044 2412 case EM_ARC: return "ARC";
c2dcd04e
NC
2413 case EM_H8_300: return "Renesas H8/300";
2414 case EM_H8_300H: return "Renesas H8/300H";
2415 case EM_H8S: return "Renesas H8S";
2416 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2417 /* 50 */
30800947 2418 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2419 case EM_MIPS_X: return "Stanford MIPS-X";
2420 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2421 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2422 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2423 case EM_PCP: return "Siemens PCP";
2424 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2425 case EM_NDR1: return "Denso NDR1 microprocesspr";
2426 case EM_STARCORE: return "Motorola Star*Core processor";
2427 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2428 /* 60 */
7036c0e1
AJ
2429 case EM_ST100: return "STMicroelectronics ST100 processor";
2430 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2431 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2432 case EM_PDSP: return "Sony DSP processor";
2433 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2434 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2435 case EM_FX66: return "Siemens FX66 microcontroller";
2436 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2437 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2438 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2439 /* 70 */
7036c0e1
AJ
2440 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2441 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2442 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2443 case EM_SVX: return "Silicon Graphics SVx";
2444 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2445 case EM_VAX: return "Digital VAX";
1b61cf92 2446 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2447 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2448 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2449 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2450 /* 80 */
b34976b6 2451 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2452 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2453 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2454 case EM_AVR_OLD:
2455 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2456 case EM_CYGNUS_FR30:
2457 case EM_FR30: return "Fujitsu FR30";
2458 case EM_CYGNUS_D10V:
2459 case EM_D10V: return "d10v";
2460 case EM_CYGNUS_D30V:
2461 case EM_D30V: return "d30v";
2462 case EM_CYGNUS_V850:
2463 case EM_V850: return "Renesas V850";
2464 case EM_CYGNUS_M32R:
2465 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2466 case EM_CYGNUS_MN10300:
2467 case EM_MN10300: return "mn10300";
2468 /* 90 */
2469 case EM_CYGNUS_MN10200:
2470 case EM_MN10200: return "mn10200";
2471 case EM_PJ: return "picoJava";
73589c9d 2472 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2473 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2474 case EM_XTENSA_OLD:
2475 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2476 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2477 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2478 case EM_NS32K: return "National Semiconductor 32000 series";
2479 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2480 case EM_SNP1K: return "Trebia SNP 1000 processor";
2481 /* 100 */
9abca702 2482 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2483 case EM_IP2K_OLD:
2484 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2485 case EM_MAX: return "MAX Processor";
2486 case EM_CR: return "National Semiconductor CompactRISC";
2487 case EM_F2MC16: return "Fujitsu F2MC16";
2488 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2489 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2490 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2491 case EM_SEP: return "Sharp embedded microprocessor";
2492 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2493 /* 110 */
11636f9e
JM
2494 case EM_UNICORE: return "Unicore";
2495 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2496 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2497 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2498 case EM_CRX: return "National Semiconductor CRX microprocessor";
2499 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2500 case EM_C166:
d70c5fc7 2501 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2502 case EM_M16C: return "Renesas M16C series microprocessors";
2503 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2504 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2505 /* 120 */
2506 case EM_M32C: return "Renesas M32c";
2507 /* 130 */
11636f9e
JM
2508 case EM_TSK3000: return "Altium TSK3000 core";
2509 case EM_RS08: return "Freescale RS08 embedded processor";
2510 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2511 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2512 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2513 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2514 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2515 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2516 /* 140 */
11636f9e
JM
2517 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2518 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2519 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2520 case EM_TI_PRU: return "TI PRU I/O processor";
2521 /* 160 */
11636f9e
JM
2522 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2523 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2524 case EM_R32C: return "Renesas R32C series microprocessors";
2525 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2526 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2527 case EM_8051: return "Intel 8051 and variants";
2528 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2529 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2530 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2531 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2532 /* 170 */
11636f9e
JM
2533 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2534 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2535 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2536 case EM_RX: return "Renesas RX";
a3c62988 2537 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2538 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2539 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2540 case EM_CR16:
2541 case EM_MICROBLAZE:
2542 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2543 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2544 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2545 /* 180 */
2546 case EM_L1OM: return "Intel L1OM";
2547 case EM_K1OM: return "Intel K1OM";
2548 case EM_INTEL182: return "Intel (reserved)";
2549 case EM_AARCH64: return "AArch64";
2550 case EM_ARM184: return "ARM (reserved)";
2551 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2552 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2553 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2554 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2555 /* 190 */
11636f9e 2556 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2557 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2558 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2559 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2560 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2561 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2562 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2563 case EM_RL78: return "Renesas RL78";
6d913794 2564 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2565 case EM_78K0R: return "Renesas 78K0R";
2566 /* 200 */
6d913794 2567 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2568 case EM_BA1: return "Beyond BA1 CPU architecture";
2569 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2570 case EM_XCORE: return "XMOS xCORE processor family";
2571 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2572 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2573 /* 210 */
6d913794
NC
2574 case EM_KM32: return "KM211 KM32 32-bit processor";
2575 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2576 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2577 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2578 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2579 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2580 case EM_COGE: return "Cognitive Smart Memory Processor";
2581 case EM_COOL: return "Bluechip Systems CoolEngine";
2582 case EM_NORC: return "Nanoradio Optimized RISC";
2583 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2584 /* 220 */
15f205b1 2585 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2586 case EM_VISIUM: return "CDS VISIUMcore processor";
2587 case EM_FT32: return "FTDI Chip FT32";
2588 case EM_MOXIE: return "Moxie";
2589 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2590 /* 230 (all reserved) */
2591 /* 240 */
55e22ca8
NC
2592 case EM_RISCV: return "RISC-V";
2593 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2594 case EM_CEVA: return "CEVA Processor Architecture Family";
2595 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2596 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2597 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2598 case EM_IMG1: return "Imagination Technologies";
2599 /* 250 */
fe944acf 2600 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2601 case EM_VE: return "NEC Vector Engine";
2602 case EM_CSKY: return "C-SKY";
2603 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2604 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2605 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2606 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2607 case EM_65816: return "WDC 65816/65C816";
01a8c731 2608 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2609 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2610
2611 /* Large numbers... */
2612 case EM_MT: return "Morpho Techologies MT processor";
2613 case EM_ALPHA: return "Alpha";
2614 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2615 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2616 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2617 case EM_IQ2000: return "Vitesse IQ2000";
2618 case EM_M32C_OLD:
2619 case EM_NIOS32: return "Altera Nios";
2620 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2621 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2622 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2623 case EM_S12Z: return "Freescale S12Z";
55e22ca8 2624
252b5132 2625 default:
35d9dd2f 2626 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2627 return buff;
2628 }
2629}
2630
a9522a21
AB
2631static void
2632decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2633{
2634 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 2635 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
2636 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2637 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2638 architectures.
2639
2640 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2641 but also sets a specific architecture type in the e_flags field.
2642
2643 However, when decoding the flags we don't worry if we see an
2644 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2645 ARCEM architecture type. */
2646
2647 switch (e_flags & EF_ARC_MACH_MSK)
2648 {
2649 /* We only expect these to occur for EM_ARC_COMPACT2. */
2650 case EF_ARC_CPU_ARCV2EM:
2651 strcat (buf, ", ARC EM");
2652 break;
2653 case EF_ARC_CPU_ARCV2HS:
2654 strcat (buf, ", ARC HS");
2655 break;
2656
2657 /* We only expect these to occur for EM_ARC_COMPACT. */
2658 case E_ARC_MACH_ARC600:
2659 strcat (buf, ", ARC600");
2660 break;
2661 case E_ARC_MACH_ARC601:
2662 strcat (buf, ", ARC601");
2663 break;
2664 case E_ARC_MACH_ARC700:
2665 strcat (buf, ", ARC700");
2666 break;
2667
2668 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2669 new ELF with new architecture being read by an old version of
2670 readelf, or (c) An ELF built with non-GNU compiler that does not
2671 set the architecture in the e_flags. */
2672 default:
2673 if (e_machine == EM_ARC_COMPACT)
2674 strcat (buf, ", Unknown ARCompact");
2675 else
2676 strcat (buf, ", Unknown ARC");
2677 break;
2678 }
2679
2680 switch (e_flags & EF_ARC_OSABI_MSK)
2681 {
2682 case E_ARC_OSABI_ORIG:
2683 strcat (buf, ", (ABI:legacy)");
2684 break;
2685 case E_ARC_OSABI_V2:
2686 strcat (buf, ", (ABI:v2)");
2687 break;
2688 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2689 case E_ARC_OSABI_V3:
2690 strcat (buf, ", v3 no-legacy-syscalls ABI");
2691 break;
53a346d8
CZ
2692 case E_ARC_OSABI_V4:
2693 strcat (buf, ", v4 ABI");
2694 break;
a9522a21
AB
2695 default:
2696 strcat (buf, ", unrecognised ARC OSABI flag");
2697 break;
2698 }
2699}
2700
f3485b74 2701static void
d3ba0551 2702decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2703{
2704 unsigned eabi;
015dc7e1 2705 bool unknown = false;
f3485b74
NC
2706
2707 eabi = EF_ARM_EABI_VERSION (e_flags);
2708 e_flags &= ~ EF_ARM_EABIMASK;
2709
2710 /* Handle "generic" ARM flags. */
2711 if (e_flags & EF_ARM_RELEXEC)
2712 {
2713 strcat (buf, ", relocatable executable");
2714 e_flags &= ~ EF_ARM_RELEXEC;
2715 }
76da6bbe 2716
18a20338
CL
2717 if (e_flags & EF_ARM_PIC)
2718 {
2719 strcat (buf, ", position independent");
2720 e_flags &= ~ EF_ARM_PIC;
2721 }
2722
f3485b74
NC
2723 /* Now handle EABI specific flags. */
2724 switch (eabi)
2725 {
2726 default:
2c71103e 2727 strcat (buf, ", <unrecognized EABI>");
f3485b74 2728 if (e_flags)
015dc7e1 2729 unknown = true;
f3485b74
NC
2730 break;
2731
2732 case EF_ARM_EABI_VER1:
a5bcd848 2733 strcat (buf, ", Version1 EABI");
f3485b74
NC
2734 while (e_flags)
2735 {
2736 unsigned flag;
76da6bbe 2737
f3485b74
NC
2738 /* Process flags one bit at a time. */
2739 flag = e_flags & - e_flags;
2740 e_flags &= ~ flag;
76da6bbe 2741
f3485b74
NC
2742 switch (flag)
2743 {
a5bcd848 2744 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2745 strcat (buf, ", sorted symbol tables");
2746 break;
76da6bbe 2747
f3485b74 2748 default:
015dc7e1 2749 unknown = true;
f3485b74
NC
2750 break;
2751 }
2752 }
2753 break;
76da6bbe 2754
a5bcd848
PB
2755 case EF_ARM_EABI_VER2:
2756 strcat (buf, ", Version2 EABI");
2757 while (e_flags)
2758 {
2759 unsigned flag;
2760
2761 /* Process flags one bit at a time. */
2762 flag = e_flags & - e_flags;
2763 e_flags &= ~ flag;
2764
2765 switch (flag)
2766 {
2767 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2768 strcat (buf, ", sorted symbol tables");
2769 break;
2770
2771 case EF_ARM_DYNSYMSUSESEGIDX:
2772 strcat (buf, ", dynamic symbols use segment index");
2773 break;
2774
2775 case EF_ARM_MAPSYMSFIRST:
2776 strcat (buf, ", mapping symbols precede others");
2777 break;
2778
2779 default:
015dc7e1 2780 unknown = true;
a5bcd848
PB
2781 break;
2782 }
2783 }
2784 break;
2785
d507cf36
PB
2786 case EF_ARM_EABI_VER3:
2787 strcat (buf, ", Version3 EABI");
8cb51566
PB
2788 break;
2789
2790 case EF_ARM_EABI_VER4:
2791 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2792 while (e_flags)
2793 {
2794 unsigned flag;
2795
2796 /* Process flags one bit at a time. */
2797 flag = e_flags & - e_flags;
2798 e_flags &= ~ flag;
2799
2800 switch (flag)
2801 {
2802 case EF_ARM_BE8:
2803 strcat (buf, ", BE8");
2804 break;
2805
2806 case EF_ARM_LE8:
2807 strcat (buf, ", LE8");
2808 break;
2809
2810 default:
015dc7e1 2811 unknown = true;
3bfcb652
NC
2812 break;
2813 }
3bfcb652
NC
2814 }
2815 break;
3a4a14e9
PB
2816
2817 case EF_ARM_EABI_VER5:
2818 strcat (buf, ", Version5 EABI");
d507cf36
PB
2819 while (e_flags)
2820 {
2821 unsigned flag;
2822
2823 /* Process flags one bit at a time. */
2824 flag = e_flags & - e_flags;
2825 e_flags &= ~ flag;
2826
2827 switch (flag)
2828 {
2829 case EF_ARM_BE8:
2830 strcat (buf, ", BE8");
2831 break;
2832
2833 case EF_ARM_LE8:
2834 strcat (buf, ", LE8");
2835 break;
2836
3bfcb652
NC
2837 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2838 strcat (buf, ", soft-float ABI");
2839 break;
2840
2841 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2842 strcat (buf, ", hard-float ABI");
2843 break;
2844
d507cf36 2845 default:
015dc7e1 2846 unknown = true;
d507cf36
PB
2847 break;
2848 }
2849 }
2850 break;
2851
f3485b74 2852 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2853 strcat (buf, ", GNU EABI");
f3485b74
NC
2854 while (e_flags)
2855 {
2856 unsigned flag;
76da6bbe 2857
f3485b74
NC
2858 /* Process flags one bit at a time. */
2859 flag = e_flags & - e_flags;
2860 e_flags &= ~ flag;
76da6bbe 2861
f3485b74
NC
2862 switch (flag)
2863 {
a5bcd848 2864 case EF_ARM_INTERWORK:
f3485b74
NC
2865 strcat (buf, ", interworking enabled");
2866 break;
76da6bbe 2867
a5bcd848 2868 case EF_ARM_APCS_26:
f3485b74
NC
2869 strcat (buf, ", uses APCS/26");
2870 break;
76da6bbe 2871
a5bcd848 2872 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2873 strcat (buf, ", uses APCS/float");
2874 break;
76da6bbe 2875
a5bcd848 2876 case EF_ARM_PIC:
f3485b74
NC
2877 strcat (buf, ", position independent");
2878 break;
76da6bbe 2879
a5bcd848 2880 case EF_ARM_ALIGN8:
f3485b74
NC
2881 strcat (buf, ", 8 bit structure alignment");
2882 break;
76da6bbe 2883
a5bcd848 2884 case EF_ARM_NEW_ABI:
f3485b74
NC
2885 strcat (buf, ", uses new ABI");
2886 break;
76da6bbe 2887
a5bcd848 2888 case EF_ARM_OLD_ABI:
f3485b74
NC
2889 strcat (buf, ", uses old ABI");
2890 break;
76da6bbe 2891
a5bcd848 2892 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2893 strcat (buf, ", software FP");
2894 break;
76da6bbe 2895
90e01f86
ILT
2896 case EF_ARM_VFP_FLOAT:
2897 strcat (buf, ", VFP");
2898 break;
2899
fde78edd
NC
2900 case EF_ARM_MAVERICK_FLOAT:
2901 strcat (buf, ", Maverick FP");
2902 break;
2903
f3485b74 2904 default:
015dc7e1 2905 unknown = true;
f3485b74
NC
2906 break;
2907 }
2908 }
2909 }
f3485b74
NC
2910
2911 if (unknown)
2b692964 2912 strcat (buf,_(", <unknown>"));
f3485b74
NC
2913}
2914
343433df
AB
2915static void
2916decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2917{
2918 --size; /* Leave space for null terminator. */
2919
2920 switch (e_flags & EF_AVR_MACH)
2921 {
2922 case E_AVR_MACH_AVR1:
2923 strncat (buf, ", avr:1", size);
2924 break;
2925 case E_AVR_MACH_AVR2:
2926 strncat (buf, ", avr:2", size);
2927 break;
2928 case E_AVR_MACH_AVR25:
2929 strncat (buf, ", avr:25", size);
2930 break;
2931 case E_AVR_MACH_AVR3:
2932 strncat (buf, ", avr:3", size);
2933 break;
2934 case E_AVR_MACH_AVR31:
2935 strncat (buf, ", avr:31", size);
2936 break;
2937 case E_AVR_MACH_AVR35:
2938 strncat (buf, ", avr:35", size);
2939 break;
2940 case E_AVR_MACH_AVR4:
2941 strncat (buf, ", avr:4", size);
2942 break;
2943 case E_AVR_MACH_AVR5:
2944 strncat (buf, ", avr:5", size);
2945 break;
2946 case E_AVR_MACH_AVR51:
2947 strncat (buf, ", avr:51", size);
2948 break;
2949 case E_AVR_MACH_AVR6:
2950 strncat (buf, ", avr:6", size);
2951 break;
2952 case E_AVR_MACH_AVRTINY:
2953 strncat (buf, ", avr:100", size);
2954 break;
2955 case E_AVR_MACH_XMEGA1:
2956 strncat (buf, ", avr:101", size);
2957 break;
2958 case E_AVR_MACH_XMEGA2:
2959 strncat (buf, ", avr:102", size);
2960 break;
2961 case E_AVR_MACH_XMEGA3:
2962 strncat (buf, ", avr:103", size);
2963 break;
2964 case E_AVR_MACH_XMEGA4:
2965 strncat (buf, ", avr:104", size);
2966 break;
2967 case E_AVR_MACH_XMEGA5:
2968 strncat (buf, ", avr:105", size);
2969 break;
2970 case E_AVR_MACH_XMEGA6:
2971 strncat (buf, ", avr:106", size);
2972 break;
2973 case E_AVR_MACH_XMEGA7:
2974 strncat (buf, ", avr:107", size);
2975 break;
2976 default:
2977 strncat (buf, ", avr:<unknown>", size);
2978 break;
2979 }
2980
2981 size -= strlen (buf);
2982 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2983 strncat (buf, ", link-relax", size);
2984}
2985
35c08157
KLC
2986static void
2987decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2988{
2989 unsigned abi;
2990 unsigned arch;
2991 unsigned config;
2992 unsigned version;
015dc7e1 2993 bool has_fpu = false;
32ec8896 2994 unsigned int r = 0;
35c08157
KLC
2995
2996 static const char *ABI_STRINGS[] =
2997 {
2998 "ABI v0", /* use r5 as return register; only used in N1213HC */
2999 "ABI v1", /* use r0 as return register */
3000 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3001 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3002 "AABI",
3003 "ABI2 FP+"
35c08157
KLC
3004 };
3005 static const char *VER_STRINGS[] =
3006 {
3007 "Andes ELF V1.3 or older",
3008 "Andes ELF V1.3.1",
3009 "Andes ELF V1.4"
3010 };
3011 static const char *ARCH_STRINGS[] =
3012 {
3013 "",
3014 "Andes Star v1.0",
3015 "Andes Star v2.0",
3016 "Andes Star v3.0",
3017 "Andes Star v3.0m"
3018 };
3019
3020 abi = EF_NDS_ABI & e_flags;
3021 arch = EF_NDS_ARCH & e_flags;
3022 config = EF_NDS_INST & e_flags;
3023 version = EF_NDS32_ELF_VERSION & e_flags;
3024
3025 memset (buf, 0, size);
3026
3027 switch (abi)
3028 {
3029 case E_NDS_ABI_V0:
3030 case E_NDS_ABI_V1:
3031 case E_NDS_ABI_V2:
3032 case E_NDS_ABI_V2FP:
3033 case E_NDS_ABI_AABI:
40c7a7cb 3034 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3035 /* In case there are holes in the array. */
3036 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3037 break;
3038
3039 default:
3040 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3041 break;
3042 }
3043
3044 switch (version)
3045 {
3046 case E_NDS32_ELF_VER_1_2:
3047 case E_NDS32_ELF_VER_1_3:
3048 case E_NDS32_ELF_VER_1_4:
3049 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3050 break;
3051
3052 default:
3053 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3054 break;
3055 }
3056
3057 if (E_NDS_ABI_V0 == abi)
3058 {
3059 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3060 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3061 if (arch == E_NDS_ARCH_STAR_V1_0)
3062 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3063 return;
3064 }
3065
3066 switch (arch)
3067 {
3068 case E_NDS_ARCH_STAR_V1_0:
3069 case E_NDS_ARCH_STAR_V2_0:
3070 case E_NDS_ARCH_STAR_V3_0:
3071 case E_NDS_ARCH_STAR_V3_M:
3072 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3073 break;
3074
3075 default:
3076 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3077 /* ARCH version determines how the e_flags are interpreted.
3078 If it is unknown, we cannot proceed. */
3079 return;
3080 }
3081
3082 /* Newer ABI; Now handle architecture specific flags. */
3083 if (arch == E_NDS_ARCH_STAR_V1_0)
3084 {
3085 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3086 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3087
3088 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3089 r += snprintf (buf + r, size -r, ", MAC");
3090
3091 if (config & E_NDS32_HAS_DIV_INST)
3092 r += snprintf (buf + r, size -r, ", DIV");
3093
3094 if (config & E_NDS32_HAS_16BIT_INST)
3095 r += snprintf (buf + r, size -r, ", 16b");
3096 }
3097 else
3098 {
3099 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3100 {
3101 if (version <= E_NDS32_ELF_VER_1_3)
3102 r += snprintf (buf + r, size -r, ", [B8]");
3103 else
3104 r += snprintf (buf + r, size -r, ", EX9");
3105 }
3106
3107 if (config & E_NDS32_HAS_MAC_DX_INST)
3108 r += snprintf (buf + r, size -r, ", MAC_DX");
3109
3110 if (config & E_NDS32_HAS_DIV_DX_INST)
3111 r += snprintf (buf + r, size -r, ", DIV_DX");
3112
3113 if (config & E_NDS32_HAS_16BIT_INST)
3114 {
3115 if (version <= E_NDS32_ELF_VER_1_3)
3116 r += snprintf (buf + r, size -r, ", 16b");
3117 else
3118 r += snprintf (buf + r, size -r, ", IFC");
3119 }
3120 }
3121
3122 if (config & E_NDS32_HAS_EXT_INST)
3123 r += snprintf (buf + r, size -r, ", PERF1");
3124
3125 if (config & E_NDS32_HAS_EXT2_INST)
3126 r += snprintf (buf + r, size -r, ", PERF2");
3127
3128 if (config & E_NDS32_HAS_FPU_INST)
3129 {
015dc7e1 3130 has_fpu = true;
35c08157
KLC
3131 r += snprintf (buf + r, size -r, ", FPU_SP");
3132 }
3133
3134 if (config & E_NDS32_HAS_FPU_DP_INST)
3135 {
015dc7e1 3136 has_fpu = true;
35c08157
KLC
3137 r += snprintf (buf + r, size -r, ", FPU_DP");
3138 }
3139
3140 if (config & E_NDS32_HAS_FPU_MAC_INST)
3141 {
015dc7e1 3142 has_fpu = true;
35c08157
KLC
3143 r += snprintf (buf + r, size -r, ", FPU_MAC");
3144 }
3145
3146 if (has_fpu)
3147 {
3148 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3149 {
3150 case E_NDS32_FPU_REG_8SP_4DP:
3151 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3152 break;
3153 case E_NDS32_FPU_REG_16SP_8DP:
3154 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3155 break;
3156 case E_NDS32_FPU_REG_32SP_16DP:
3157 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3158 break;
3159 case E_NDS32_FPU_REG_32SP_32DP:
3160 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3161 break;
3162 }
3163 }
3164
3165 if (config & E_NDS32_HAS_AUDIO_INST)
3166 r += snprintf (buf + r, size -r, ", AUDIO");
3167
3168 if (config & E_NDS32_HAS_STRING_INST)
3169 r += snprintf (buf + r, size -r, ", STR");
3170
3171 if (config & E_NDS32_HAS_REDUCED_REGS)
3172 r += snprintf (buf + r, size -r, ", 16REG");
3173
3174 if (config & E_NDS32_HAS_VIDEO_INST)
3175 {
3176 if (version <= E_NDS32_ELF_VER_1_3)
3177 r += snprintf (buf + r, size -r, ", VIDEO");
3178 else
3179 r += snprintf (buf + r, size -r, ", SATURATION");
3180 }
3181
3182 if (config & E_NDS32_HAS_ENCRIPT_INST)
3183 r += snprintf (buf + r, size -r, ", ENCRP");
3184
3185 if (config & E_NDS32_HAS_L2C_INST)
3186 r += snprintf (buf + r, size -r, ", L2C");
3187}
3188
252b5132 3189static char *
dda8d76d 3190get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3191{
b34976b6 3192 static char buf[1024];
252b5132
RH
3193
3194 buf[0] = '\0';
76da6bbe 3195
252b5132
RH
3196 if (e_flags)
3197 {
3198 switch (e_machine)
3199 {
3200 default:
3201 break;
3202
886a2506 3203 case EM_ARC_COMPACT2:
886a2506 3204 case EM_ARC_COMPACT:
a9522a21
AB
3205 decode_ARC_machine_flags (e_flags, e_machine, buf);
3206 break;
886a2506 3207
f3485b74
NC
3208 case EM_ARM:
3209 decode_ARM_machine_flags (e_flags, buf);
3210 break;
76da6bbe 3211
343433df
AB
3212 case EM_AVR:
3213 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3214 break;
3215
781303ce
MF
3216 case EM_BLACKFIN:
3217 if (e_flags & EF_BFIN_PIC)
3218 strcat (buf, ", PIC");
3219
3220 if (e_flags & EF_BFIN_FDPIC)
3221 strcat (buf, ", FDPIC");
3222
3223 if (e_flags & EF_BFIN_CODE_IN_L1)
3224 strcat (buf, ", code in L1");
3225
3226 if (e_flags & EF_BFIN_DATA_IN_L1)
3227 strcat (buf, ", data in L1");
3228
3229 break;
3230
ec2dfb42
AO
3231 case EM_CYGNUS_FRV:
3232 switch (e_flags & EF_FRV_CPU_MASK)
3233 {
3234 case EF_FRV_CPU_GENERIC:
3235 break;
3236
3237 default:
3238 strcat (buf, ", fr???");
3239 break;
57346661 3240
ec2dfb42
AO
3241 case EF_FRV_CPU_FR300:
3242 strcat (buf, ", fr300");
3243 break;
3244
3245 case EF_FRV_CPU_FR400:
3246 strcat (buf, ", fr400");
3247 break;
3248 case EF_FRV_CPU_FR405:
3249 strcat (buf, ", fr405");
3250 break;
3251
3252 case EF_FRV_CPU_FR450:
3253 strcat (buf, ", fr450");
3254 break;
3255
3256 case EF_FRV_CPU_FR500:
3257 strcat (buf, ", fr500");
3258 break;
3259 case EF_FRV_CPU_FR550:
3260 strcat (buf, ", fr550");
3261 break;
3262
3263 case EF_FRV_CPU_SIMPLE:
3264 strcat (buf, ", simple");
3265 break;
3266 case EF_FRV_CPU_TOMCAT:
3267 strcat (buf, ", tomcat");
3268 break;
3269 }
1c877e87 3270 break;
ec2dfb42 3271
53c7db4b 3272 case EM_68K:
425c6cb0 3273 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3274 strcat (buf, ", m68000");
425c6cb0 3275 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3276 strcat (buf, ", cpu32");
3277 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3278 strcat (buf, ", fido_a");
425c6cb0 3279 else
266abb8f 3280 {
2cf0635d
NC
3281 char const * isa = _("unknown");
3282 char const * mac = _("unknown mac");
3283 char const * additional = NULL;
0112cd26 3284
c694fd50 3285 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3286 {
c694fd50 3287 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3288 isa = "A";
3289 additional = ", nodiv";
3290 break;
c694fd50 3291 case EF_M68K_CF_ISA_A:
266abb8f
NS
3292 isa = "A";
3293 break;
c694fd50 3294 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3295 isa = "A+";
3296 break;
c694fd50 3297 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3298 isa = "B";
3299 additional = ", nousp";
3300 break;
c694fd50 3301 case EF_M68K_CF_ISA_B:
266abb8f
NS
3302 isa = "B";
3303 break;
f608cd77
NS
3304 case EF_M68K_CF_ISA_C:
3305 isa = "C";
3306 break;
3307 case EF_M68K_CF_ISA_C_NODIV:
3308 isa = "C";
3309 additional = ", nodiv";
3310 break;
266abb8f
NS
3311 }
3312 strcat (buf, ", cf, isa ");
3313 strcat (buf, isa);
0b2e31dc
NS
3314 if (additional)
3315 strcat (buf, additional);
c694fd50 3316 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3317 strcat (buf, ", float");
c694fd50 3318 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3319 {
3320 case 0:
3321 mac = NULL;
3322 break;
c694fd50 3323 case EF_M68K_CF_MAC:
266abb8f
NS
3324 mac = "mac";
3325 break;
c694fd50 3326 case EF_M68K_CF_EMAC:
266abb8f
NS
3327 mac = "emac";
3328 break;
f608cd77
NS
3329 case EF_M68K_CF_EMAC_B:
3330 mac = "emac_b";
3331 break;
266abb8f
NS
3332 }
3333 if (mac)
3334 {
3335 strcat (buf, ", ");
3336 strcat (buf, mac);
3337 }
266abb8f 3338 }
53c7db4b 3339 break;
33c63f9d 3340
153a2776
NC
3341 case EM_CYGNUS_MEP:
3342 switch (e_flags & EF_MEP_CPU_MASK)
3343 {
3344 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3345 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3346 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3347 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3348 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3349 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3350 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3351 }
3352
3353 switch (e_flags & EF_MEP_COP_MASK)
3354 {
3355 case EF_MEP_COP_NONE: break;
3356 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3357 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3358 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3359 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3360 default: strcat (buf, _("<unknown MeP copro type>")); break;
3361 }
3362
3363 if (e_flags & EF_MEP_LIBRARY)
3364 strcat (buf, ", Built for Library");
3365
3366 if (e_flags & EF_MEP_INDEX_MASK)
3367 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3368 e_flags & EF_MEP_INDEX_MASK);
3369
3370 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3371 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3372 e_flags & ~ EF_MEP_ALL_FLAGS);
3373 break;
3374
252b5132
RH
3375 case EM_PPC:
3376 if (e_flags & EF_PPC_EMB)
3377 strcat (buf, ", emb");
3378
3379 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3380 strcat (buf, _(", relocatable"));
252b5132
RH
3381
3382 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3383 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3384 break;
3385
ee67d69a
AM
3386 case EM_PPC64:
3387 if (e_flags & EF_PPC64_ABI)
3388 {
3389 char abi[] = ", abiv0";
3390
3391 abi[6] += e_flags & EF_PPC64_ABI;
3392 strcat (buf, abi);
3393 }
3394 break;
3395
708e2187
NC
3396 case EM_V800:
3397 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3398 strcat (buf, ", RH850 ABI");
0b4362b0 3399
708e2187
NC
3400 if (e_flags & EF_V800_850E3)
3401 strcat (buf, ", V3 architecture");
3402
3403 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3404 strcat (buf, ", FPU not used");
3405
3406 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3407 strcat (buf, ", regmode: COMMON");
3408
3409 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3410 strcat (buf, ", r4 not used");
3411
3412 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3413 strcat (buf, ", r30 not used");
3414
3415 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3416 strcat (buf, ", r5 not used");
3417
3418 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3419 strcat (buf, ", r2 not used");
3420
3421 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3422 {
3423 switch (e_flags & - e_flags)
3424 {
3425 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3426 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3427 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3428 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3429 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3430 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3431 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3432 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3433 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3434 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3435 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3436 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3437 default: break;
3438 }
3439 }
3440 break;
3441
2b0337b0 3442 case EM_V850:
252b5132
RH
3443 case EM_CYGNUS_V850:
3444 switch (e_flags & EF_V850_ARCH)
3445 {
78c8d46c
NC
3446 case E_V850E3V5_ARCH:
3447 strcat (buf, ", v850e3v5");
3448 break;
1cd986c5
NC
3449 case E_V850E2V3_ARCH:
3450 strcat (buf, ", v850e2v3");
3451 break;
3452 case E_V850E2_ARCH:
3453 strcat (buf, ", v850e2");
3454 break;
3455 case E_V850E1_ARCH:
3456 strcat (buf, ", v850e1");
8ad30312 3457 break;
252b5132
RH
3458 case E_V850E_ARCH:
3459 strcat (buf, ", v850e");
3460 break;
252b5132
RH
3461 case E_V850_ARCH:
3462 strcat (buf, ", v850");
3463 break;
3464 default:
2b692964 3465 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3466 break;
3467 }
3468 break;
3469
2b0337b0 3470 case EM_M32R:
252b5132
RH
3471 case EM_CYGNUS_M32R:
3472 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3473 strcat (buf, ", m32r");
252b5132
RH
3474 break;
3475
3476 case EM_MIPS:
4fe85591 3477 case EM_MIPS_RS3_LE:
252b5132
RH
3478 if (e_flags & EF_MIPS_NOREORDER)
3479 strcat (buf, ", noreorder");
3480
3481 if (e_flags & EF_MIPS_PIC)
3482 strcat (buf, ", pic");
3483
3484 if (e_flags & EF_MIPS_CPIC)
3485 strcat (buf, ", cpic");
3486
d1bdd336
TS
3487 if (e_flags & EF_MIPS_UCODE)
3488 strcat (buf, ", ugen_reserved");
3489
252b5132
RH
3490 if (e_flags & EF_MIPS_ABI2)
3491 strcat (buf, ", abi2");
3492
43521d43
TS
3493 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3494 strcat (buf, ", odk first");
3495
a5d22d2a
TS
3496 if (e_flags & EF_MIPS_32BITMODE)
3497 strcat (buf, ", 32bitmode");
3498
ba92f887
MR
3499 if (e_flags & EF_MIPS_NAN2008)
3500 strcat (buf, ", nan2008");
3501
fef1b0b3
SE
3502 if (e_flags & EF_MIPS_FP64)
3503 strcat (buf, ", fp64");
3504
156c2f8b
NC
3505 switch ((e_flags & EF_MIPS_MACH))
3506 {
3507 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3508 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3509 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3510 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3511 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3512 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3513 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3514 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3515 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3516 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3517 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3518 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3519 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3520 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3521 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3522 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3523 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3524 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3525 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3526 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3527 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3528 case 0:
3529 /* We simply ignore the field in this case to avoid confusion:
3530 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3531 extension. */
3532 break;
2b692964 3533 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3534 }
43521d43
TS
3535
3536 switch ((e_flags & EF_MIPS_ABI))
3537 {
3538 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3539 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3540 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3541 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3542 case 0:
3543 /* We simply ignore the field in this case to avoid confusion:
3544 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3545 This means it is likely to be an o32 file, but not for
3546 sure. */
3547 break;
2b692964 3548 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3549 }
3550
3551 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3552 strcat (buf, ", mdmx");
3553
3554 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3555 strcat (buf, ", mips16");
3556
df58fc94
RS
3557 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3558 strcat (buf, ", micromips");
3559
43521d43
TS
3560 switch ((e_flags & EF_MIPS_ARCH))
3561 {
3562 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3563 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3564 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3565 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3566 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3567 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3568 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3569 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3570 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3571 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3572 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3573 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3574 }
252b5132 3575 break;
351b4b40 3576
35c08157
KLC
3577 case EM_NDS32:
3578 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3579 break;
3580
fe944acf
FT
3581 case EM_NFP:
3582 switch (EF_NFP_MACH (e_flags))
3583 {
3584 case E_NFP_MACH_3200:
3585 strcat (buf, ", NFP-32xx");
3586 break;
3587 case E_NFP_MACH_6000:
3588 strcat (buf, ", NFP-6xxx");
3589 break;
3590 }
3591 break;
3592
e23eba97
NC
3593 case EM_RISCV:
3594 if (e_flags & EF_RISCV_RVC)
3595 strcat (buf, ", RVC");
2922d21d 3596
7f999549
JW
3597 if (e_flags & EF_RISCV_RVE)
3598 strcat (buf, ", RVE");
3599
2922d21d
AW
3600 switch (e_flags & EF_RISCV_FLOAT_ABI)
3601 {
3602 case EF_RISCV_FLOAT_ABI_SOFT:
3603 strcat (buf, ", soft-float ABI");
3604 break;
3605
3606 case EF_RISCV_FLOAT_ABI_SINGLE:
3607 strcat (buf, ", single-float ABI");
3608 break;
3609
3610 case EF_RISCV_FLOAT_ABI_DOUBLE:
3611 strcat (buf, ", double-float ABI");
3612 break;
3613
3614 case EF_RISCV_FLOAT_ABI_QUAD:
3615 strcat (buf, ", quad-float ABI");
3616 break;
3617 }
e23eba97
NC
3618 break;
3619
ccde1100
AO
3620 case EM_SH:
3621 switch ((e_flags & EF_SH_MACH_MASK))
3622 {
3623 case EF_SH1: strcat (buf, ", sh1"); break;
3624 case EF_SH2: strcat (buf, ", sh2"); break;
3625 case EF_SH3: strcat (buf, ", sh3"); break;
3626 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3627 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3628 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3629 case EF_SH3E: strcat (buf, ", sh3e"); break;
3630 case EF_SH4: strcat (buf, ", sh4"); break;
3631 case EF_SH5: strcat (buf, ", sh5"); break;
3632 case EF_SH2E: strcat (buf, ", sh2e"); break;
3633 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3634 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3635 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3636 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3637 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3638 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3639 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3640 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3641 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3642 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3643 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3644 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3645 }
3646
cec6a5b8
MR
3647 if (e_flags & EF_SH_PIC)
3648 strcat (buf, ", pic");
3649
3650 if (e_flags & EF_SH_FDPIC)
3651 strcat (buf, ", fdpic");
ccde1100 3652 break;
948f632f 3653
73589c9d
CS
3654 case EM_OR1K:
3655 if (e_flags & EF_OR1K_NODELAY)
3656 strcat (buf, ", no delay");
3657 break;
57346661 3658
351b4b40
RH
3659 case EM_SPARCV9:
3660 if (e_flags & EF_SPARC_32PLUS)
3661 strcat (buf, ", v8+");
3662
3663 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3664 strcat (buf, ", ultrasparcI");
3665
3666 if (e_flags & EF_SPARC_SUN_US3)
3667 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3668
3669 if (e_flags & EF_SPARC_HAL_R1)
3670 strcat (buf, ", halr1");
3671
3672 if (e_flags & EF_SPARC_LEDATA)
3673 strcat (buf, ", ledata");
3674
3675 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3676 strcat (buf, ", tso");
3677
3678 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3679 strcat (buf, ", pso");
3680
3681 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3682 strcat (buf, ", rmo");
3683 break;
7d466069 3684
103f02d3
UD
3685 case EM_PARISC:
3686 switch (e_flags & EF_PARISC_ARCH)
3687 {
3688 case EFA_PARISC_1_0:
3689 strcpy (buf, ", PA-RISC 1.0");
3690 break;
3691 case EFA_PARISC_1_1:
3692 strcpy (buf, ", PA-RISC 1.1");
3693 break;
3694 case EFA_PARISC_2_0:
3695 strcpy (buf, ", PA-RISC 2.0");
3696 break;
3697 default:
3698 break;
3699 }
3700 if (e_flags & EF_PARISC_TRAPNIL)
3701 strcat (buf, ", trapnil");
3702 if (e_flags & EF_PARISC_EXT)
3703 strcat (buf, ", ext");
3704 if (e_flags & EF_PARISC_LSB)
3705 strcat (buf, ", lsb");
3706 if (e_flags & EF_PARISC_WIDE)
3707 strcat (buf, ", wide");
3708 if (e_flags & EF_PARISC_NO_KABP)
3709 strcat (buf, ", no kabp");
3710 if (e_flags & EF_PARISC_LAZYSWAP)
3711 strcat (buf, ", lazyswap");
30800947 3712 break;
76da6bbe 3713
7d466069 3714 case EM_PJ:
2b0337b0 3715 case EM_PJ_OLD:
7d466069
ILT
3716 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3717 strcat (buf, ", new calling convention");
3718
3719 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3720 strcat (buf, ", gnu calling convention");
3721 break;
4d6ed7c8
NC
3722
3723 case EM_IA_64:
3724 if ((e_flags & EF_IA_64_ABI64))
3725 strcat (buf, ", 64-bit");
3726 else
3727 strcat (buf, ", 32-bit");
3728 if ((e_flags & EF_IA_64_REDUCEDFP))
3729 strcat (buf, ", reduced fp model");
3730 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3731 strcat (buf, ", no function descriptors, constant gp");
3732 else if ((e_flags & EF_IA_64_CONS_GP))
3733 strcat (buf, ", constant gp");
3734 if ((e_flags & EF_IA_64_ABSOLUTE))
3735 strcat (buf, ", absolute");
dda8d76d 3736 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3737 {
3738 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3739 strcat (buf, ", vms_linkages");
3740 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3741 {
3742 case EF_IA_64_VMS_COMCOD_SUCCESS:
3743 break;
3744 case EF_IA_64_VMS_COMCOD_WARNING:
3745 strcat (buf, ", warning");
3746 break;
3747 case EF_IA_64_VMS_COMCOD_ERROR:
3748 strcat (buf, ", error");
3749 break;
3750 case EF_IA_64_VMS_COMCOD_ABORT:
3751 strcat (buf, ", abort");
3752 break;
3753 default:
bee0ee85
NC
3754 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3755 e_flags & EF_IA_64_VMS_COMCOD);
3756 strcat (buf, ", <unknown>");
28f997cf
TG
3757 }
3758 }
4d6ed7c8 3759 break;
179d3252
JT
3760
3761 case EM_VAX:
3762 if ((e_flags & EF_VAX_NONPIC))
3763 strcat (buf, ", non-PIC");
3764 if ((e_flags & EF_VAX_DFLOAT))
3765 strcat (buf, ", D-Float");
3766 if ((e_flags & EF_VAX_GFLOAT))
3767 strcat (buf, ", G-Float");
3768 break;
c7927a3c 3769
619ed720
EB
3770 case EM_VISIUM:
3771 if (e_flags & EF_VISIUM_ARCH_MCM)
3772 strcat (buf, ", mcm");
3773 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3774 strcat (buf, ", mcm24");
3775 if (e_flags & EF_VISIUM_ARCH_GR6)
3776 strcat (buf, ", gr6");
3777 break;
3778
4046d87a 3779 case EM_RL78:
1740ba0c
NC
3780 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3781 {
3782 case E_FLAG_RL78_ANY_CPU: break;
3783 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3784 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3785 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3786 }
856ea05c
KP
3787 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3788 strcat (buf, ", 64-bit doubles");
4046d87a 3789 break;
0b4362b0 3790
c7927a3c
NC
3791 case EM_RX:
3792 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3793 strcat (buf, ", 64-bit doubles");
3794 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3795 strcat (buf, ", dsp");
d4cb0ea0 3796 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3797 strcat (buf, ", pid");
708e2187
NC
3798 if (e_flags & E_FLAG_RX_ABI)
3799 strcat (buf, ", RX ABI");
3525236c
NC
3800 if (e_flags & E_FLAG_RX_SINSNS_SET)
3801 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3802 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3803 if (e_flags & E_FLAG_RX_V2)
3804 strcat (buf, ", V2");
f87673e0
YS
3805 if (e_flags & E_FLAG_RX_V3)
3806 strcat (buf, ", V3");
d4cb0ea0 3807 break;
55786da2
AK
3808
3809 case EM_S390:
3810 if (e_flags & EF_S390_HIGH_GPRS)
3811 strcat (buf, ", highgprs");
d4cb0ea0 3812 break;
40b36596
JM
3813
3814 case EM_TI_C6000:
3815 if ((e_flags & EF_C6000_REL))
3816 strcat (buf, ", relocatable module");
d4cb0ea0 3817 break;
13761a11
NC
3818
3819 case EM_MSP430:
3820 strcat (buf, _(": architecture variant: "));
3821 switch (e_flags & EF_MSP430_MACH)
3822 {
3823 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3824 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3825 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3826 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3827 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3828 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3829 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3830 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3831 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3832 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3833 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3834 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3835 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3836 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3837 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3838 default:
3839 strcat (buf, _(": unknown")); break;
3840 }
3841
3842 if (e_flags & ~ EF_MSP430_MACH)
3843 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
3844 break;
3845
3846 case EM_Z80:
3847 switch (e_flags & EF_Z80_MACH_MSK)
3848 {
3849 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
3850 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
3851 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
3852 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
3853 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
3854 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 3855 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
3856 default:
3857 strcat (buf, _(", unknown")); break;
3858 }
3859 break;
252b5132
RH
3860 }
3861 }
3862
3863 return buf;
3864}
3865
252b5132 3866static const char *
dda8d76d 3867get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3868{
3869 static char buff[32];
3870
3871 switch (osabi)
3872 {
3873 case ELFOSABI_NONE: return "UNIX - System V";
3874 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3875 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3876 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3877 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3878 case ELFOSABI_AIX: return "UNIX - AIX";
3879 case ELFOSABI_IRIX: return "UNIX - IRIX";
3880 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3881 case ELFOSABI_TRU64: return "UNIX - TRU64";
3882 case ELFOSABI_MODESTO: return "Novell - Modesto";
3883 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3884 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3885 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3886 case ELFOSABI_AROS: return "AROS";
11636f9e 3887 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3888 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3889 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3890 default:
40b36596 3891 if (osabi >= 64)
dda8d76d 3892 switch (filedata->file_header.e_machine)
40b36596
JM
3893 {
3894 case EM_ARM:
3895 switch (osabi)
3896 {
3897 case ELFOSABI_ARM: return "ARM";
18a20338 3898 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3899 default:
3900 break;
3901 }
3902 break;
3903
3904 case EM_MSP430:
3905 case EM_MSP430_OLD:
619ed720 3906 case EM_VISIUM:
40b36596
JM
3907 switch (osabi)
3908 {
3909 case ELFOSABI_STANDALONE: return _("Standalone App");
3910 default:
3911 break;
3912 }
3913 break;
3914
3915 case EM_TI_C6000:
3916 switch (osabi)
3917 {
3918 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3919 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3920 default:
3921 break;
3922 }
3923 break;
3924
3925 default:
3926 break;
3927 }
e9e44622 3928 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3929 return buff;
3930 }
3931}
3932
a06ea964
NC
3933static const char *
3934get_aarch64_segment_type (unsigned long type)
3935{
3936 switch (type)
3937 {
32ec8896
NC
3938 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3939 default: return NULL;
a06ea964 3940 }
a06ea964
NC
3941}
3942
b294bdf8
MM
3943static const char *
3944get_arm_segment_type (unsigned long type)
3945{
3946 switch (type)
3947 {
32ec8896
NC
3948 case PT_ARM_EXIDX: return "EXIDX";
3949 default: return NULL;
b294bdf8 3950 }
b294bdf8
MM
3951}
3952
b4cbbe8f
AK
3953static const char *
3954get_s390_segment_type (unsigned long type)
3955{
3956 switch (type)
3957 {
3958 case PT_S390_PGSTE: return "S390_PGSTE";
3959 default: return NULL;
3960 }
3961}
3962
d3ba0551
AM
3963static const char *
3964get_mips_segment_type (unsigned long type)
252b5132
RH
3965{
3966 switch (type)
3967 {
32ec8896
NC
3968 case PT_MIPS_REGINFO: return "REGINFO";
3969 case PT_MIPS_RTPROC: return "RTPROC";
3970 case PT_MIPS_OPTIONS: return "OPTIONS";
3971 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3972 default: return NULL;
252b5132 3973 }
252b5132
RH
3974}
3975
103f02d3 3976static const char *
d3ba0551 3977get_parisc_segment_type (unsigned long type)
103f02d3
UD
3978{
3979 switch (type)
3980 {
103f02d3
UD
3981 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3982 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3983 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3984 default: return NULL;
103f02d3 3985 }
103f02d3
UD
3986}
3987
4d6ed7c8 3988static const char *
d3ba0551 3989get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3990{
3991 switch (type)
3992 {
3993 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3994 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 3995 default: return NULL;
4d6ed7c8 3996 }
4d6ed7c8
NC
3997}
3998
40b36596
JM
3999static const char *
4000get_tic6x_segment_type (unsigned long type)
4001{
4002 switch (type)
4003 {
32ec8896
NC
4004 case PT_C6000_PHATTR: return "C6000_PHATTR";
4005 default: return NULL;
40b36596 4006 }
40b36596
JM
4007}
4008
df3a023b
AM
4009static const char *
4010get_hpux_segment_type (unsigned long type, unsigned e_machine)
4011{
4012 if (e_machine == EM_PARISC)
4013 switch (type)
4014 {
4015 case PT_HP_TLS: return "HP_TLS";
4016 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4017 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4018 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4019 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4020 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4021 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4022 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4023 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4024 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4025 case PT_HP_PARALLEL: return "HP_PARALLEL";
4026 case PT_HP_FASTBIND: return "HP_FASTBIND";
4027 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4028 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4029 case PT_HP_STACK: return "HP_STACK";
4030 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4031 default: return NULL;
4032 }
4033
4034 if (e_machine == EM_IA_64)
4035 switch (type)
4036 {
4037 case PT_HP_TLS: return "HP_TLS";
4038 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4039 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4040 case PT_IA_64_HP_STACK: return "HP_STACK";
4041 default: return NULL;
4042 }
4043
4044 return NULL;
4045}
4046
5522f910
NC
4047static const char *
4048get_solaris_segment_type (unsigned long type)
4049{
4050 switch (type)
4051 {
4052 case 0x6464e550: return "PT_SUNW_UNWIND";
4053 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4054 case 0x6ffffff7: return "PT_LOSUNW";
4055 case 0x6ffffffa: return "PT_SUNWBSS";
4056 case 0x6ffffffb: return "PT_SUNWSTACK";
4057 case 0x6ffffffc: return "PT_SUNWDTRACE";
4058 case 0x6ffffffd: return "PT_SUNWCAP";
4059 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4060 default: return NULL;
5522f910
NC
4061 }
4062}
4063
252b5132 4064static const char *
dda8d76d 4065get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4066{
b34976b6 4067 static char buff[32];
252b5132
RH
4068
4069 switch (p_type)
4070 {
b34976b6
AM
4071 case PT_NULL: return "NULL";
4072 case PT_LOAD: return "LOAD";
252b5132 4073 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4074 case PT_INTERP: return "INTERP";
4075 case PT_NOTE: return "NOTE";
4076 case PT_SHLIB: return "SHLIB";
4077 case PT_PHDR: return "PHDR";
13ae64f3 4078 case PT_TLS: return "TLS";
32ec8896 4079 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4080 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4081 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4082 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4083
3eba3ef3
NC
4084 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4085 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4086 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4087
252b5132 4088 default:
df3a023b 4089 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4090 {
2cf0635d 4091 const char * result;
103f02d3 4092
dda8d76d 4093 switch (filedata->file_header.e_machine)
252b5132 4094 {
a06ea964
NC
4095 case EM_AARCH64:
4096 result = get_aarch64_segment_type (p_type);
4097 break;
b294bdf8
MM
4098 case EM_ARM:
4099 result = get_arm_segment_type (p_type);
4100 break;
252b5132 4101 case EM_MIPS:
4fe85591 4102 case EM_MIPS_RS3_LE:
252b5132
RH
4103 result = get_mips_segment_type (p_type);
4104 break;
103f02d3
UD
4105 case EM_PARISC:
4106 result = get_parisc_segment_type (p_type);
4107 break;
4d6ed7c8
NC
4108 case EM_IA_64:
4109 result = get_ia64_segment_type (p_type);
4110 break;
40b36596
JM
4111 case EM_TI_C6000:
4112 result = get_tic6x_segment_type (p_type);
4113 break;
b4cbbe8f
AK
4114 case EM_S390:
4115 case EM_S390_OLD:
4116 result = get_s390_segment_type (p_type);
4117 break;
252b5132
RH
4118 default:
4119 result = NULL;
4120 break;
4121 }
103f02d3 4122
252b5132
RH
4123 if (result != NULL)
4124 return result;
103f02d3 4125
1a9ccd70 4126 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4127 }
4128 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4129 {
df3a023b 4130 const char * result = NULL;
103f02d3 4131
df3a023b 4132 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4133 {
df3a023b
AM
4134 case ELFOSABI_GNU:
4135 case ELFOSABI_FREEBSD:
4136 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4137 {
4138 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4139 result = buff;
4140 }
103f02d3 4141 break;
df3a023b
AM
4142 case ELFOSABI_HPUX:
4143 result = get_hpux_segment_type (p_type,
4144 filedata->file_header.e_machine);
4145 break;
4146 case ELFOSABI_SOLARIS:
4147 result = get_solaris_segment_type (p_type);
00428cca 4148 break;
103f02d3 4149 default:
103f02d3
UD
4150 break;
4151 }
103f02d3
UD
4152 if (result != NULL)
4153 return result;
4154
1a9ccd70 4155 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4156 }
252b5132 4157 else
e9e44622 4158 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4159
4160 return buff;
4161 }
4162}
4163
53a346d8
CZ
4164static const char *
4165get_arc_section_type_name (unsigned int sh_type)
4166{
4167 switch (sh_type)
4168 {
4169 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4170 default:
4171 break;
4172 }
4173 return NULL;
4174}
4175
252b5132 4176static const char *
d3ba0551 4177get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4178{
4179 switch (sh_type)
4180 {
b34976b6
AM
4181 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4182 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4183 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4184 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4185 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4186 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4187 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4188 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4189 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4190 case SHT_MIPS_RELD: return "MIPS_RELD";
4191 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4192 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4193 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4194 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4195 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4196 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4197 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4198 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4199 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4200 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4201 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4202 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4203 case SHT_MIPS_LINE: return "MIPS_LINE";
4204 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4205 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4206 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4207 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4208 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4209 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4210 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4211 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4212 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4213 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4214 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4215 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4216 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4217 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4218 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4219 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4220 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4221 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4222 default:
4223 break;
4224 }
4225 return NULL;
4226}
4227
103f02d3 4228static const char *
d3ba0551 4229get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4230{
4231 switch (sh_type)
4232 {
4233 case SHT_PARISC_EXT: return "PARISC_EXT";
4234 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4235 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4236 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4237 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4238 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4239 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4240 default: return NULL;
103f02d3 4241 }
103f02d3
UD
4242}
4243
4d6ed7c8 4244static const char *
dda8d76d 4245get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4246{
18bd398b 4247 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4248 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4249 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4250
4d6ed7c8
NC
4251 switch (sh_type)
4252 {
148b93f2
NC
4253 case SHT_IA_64_EXT: return "IA_64_EXT";
4254 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4255 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4256 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4257 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4258 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4259 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4260 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4261 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4262 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4263 default:
4264 break;
4265 }
4266 return NULL;
4267}
4268
d2b2c203
DJ
4269static const char *
4270get_x86_64_section_type_name (unsigned int sh_type)
4271{
4272 switch (sh_type)
4273 {
4274 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4275 default: return NULL;
d2b2c203 4276 }
d2b2c203
DJ
4277}
4278
a06ea964
NC
4279static const char *
4280get_aarch64_section_type_name (unsigned int sh_type)
4281{
4282 switch (sh_type)
4283 {
32ec8896
NC
4284 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4285 default: return NULL;
a06ea964 4286 }
a06ea964
NC
4287}
4288
40a18ebd
NC
4289static const char *
4290get_arm_section_type_name (unsigned int sh_type)
4291{
4292 switch (sh_type)
4293 {
7f6fed87
NC
4294 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4295 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4296 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4297 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4298 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4299 default: return NULL;
40a18ebd 4300 }
40a18ebd
NC
4301}
4302
40b36596
JM
4303static const char *
4304get_tic6x_section_type_name (unsigned int sh_type)
4305{
4306 switch (sh_type)
4307 {
32ec8896
NC
4308 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4309 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4310 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4311 case SHT_TI_ICODE: return "TI_ICODE";
4312 case SHT_TI_XREF: return "TI_XREF";
4313 case SHT_TI_HANDLER: return "TI_HANDLER";
4314 case SHT_TI_INITINFO: return "TI_INITINFO";
4315 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4316 default: return NULL;
40b36596 4317 }
40b36596
JM
4318}
4319
13761a11 4320static const char *
b0191216 4321get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4322{
4323 switch (sh_type)
4324 {
32ec8896
NC
4325 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4326 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4327 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4328 default: return NULL;
13761a11
NC
4329 }
4330}
4331
fe944acf
FT
4332static const char *
4333get_nfp_section_type_name (unsigned int sh_type)
4334{
4335 switch (sh_type)
4336 {
4337 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4338 case SHT_NFP_INITREG: return "NFP_INITREG";
4339 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4340 default: return NULL;
4341 }
4342}
4343
685080f2
NC
4344static const char *
4345get_v850_section_type_name (unsigned int sh_type)
4346{
4347 switch (sh_type)
4348 {
32ec8896
NC
4349 case SHT_V850_SCOMMON: return "V850 Small Common";
4350 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4351 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4352 case SHT_RENESAS_IOP: return "RENESAS IOP";
4353 case SHT_RENESAS_INFO: return "RENESAS INFO";
4354 default: return NULL;
685080f2
NC
4355 }
4356}
4357
2dc8dd17
JW
4358static const char *
4359get_riscv_section_type_name (unsigned int sh_type)
4360{
4361 switch (sh_type)
4362 {
4363 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4364 default: return NULL;
4365 }
4366}
4367
0861f561
CQ
4368static const char *
4369get_csky_section_type_name (unsigned int sh_type)
4370{
4371 switch (sh_type)
4372 {
4373 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4374 default: return NULL;
4375 }
4376}
4377
252b5132 4378static const char *
dda8d76d 4379get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4380{
b34976b6 4381 static char buff[32];
9fb71ee4 4382 const char * result;
252b5132
RH
4383
4384 switch (sh_type)
4385 {
4386 case SHT_NULL: return "NULL";
4387 case SHT_PROGBITS: return "PROGBITS";
4388 case SHT_SYMTAB: return "SYMTAB";
4389 case SHT_STRTAB: return "STRTAB";
4390 case SHT_RELA: return "RELA";
4391 case SHT_HASH: return "HASH";
4392 case SHT_DYNAMIC: return "DYNAMIC";
4393 case SHT_NOTE: return "NOTE";
4394 case SHT_NOBITS: return "NOBITS";
4395 case SHT_REL: return "REL";
4396 case SHT_SHLIB: return "SHLIB";
4397 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4398 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4399 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4400 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4401 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4402 case SHT_GROUP: return "GROUP";
67ce483b 4403 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4404 case SHT_GNU_verdef: return "VERDEF";
4405 case SHT_GNU_verneed: return "VERNEED";
4406 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4407 case 0x6ffffff0: return "VERSYM";
4408 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4409 case 0x7ffffffd: return "AUXILIARY";
4410 case 0x7fffffff: return "FILTER";
047b2264 4411 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4412
4413 default:
4414 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4415 {
dda8d76d 4416 switch (filedata->file_header.e_machine)
252b5132 4417 {
53a346d8
CZ
4418 case EM_ARC:
4419 case EM_ARC_COMPACT:
4420 case EM_ARC_COMPACT2:
4421 result = get_arc_section_type_name (sh_type);
4422 break;
252b5132 4423 case EM_MIPS:
4fe85591 4424 case EM_MIPS_RS3_LE:
252b5132
RH
4425 result = get_mips_section_type_name (sh_type);
4426 break;
103f02d3
UD
4427 case EM_PARISC:
4428 result = get_parisc_section_type_name (sh_type);
4429 break;
4d6ed7c8 4430 case EM_IA_64:
dda8d76d 4431 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4432 break;
d2b2c203 4433 case EM_X86_64:
8a9036a4 4434 case EM_L1OM:
7a9068fe 4435 case EM_K1OM:
d2b2c203
DJ
4436 result = get_x86_64_section_type_name (sh_type);
4437 break;
a06ea964
NC
4438 case EM_AARCH64:
4439 result = get_aarch64_section_type_name (sh_type);
4440 break;
40a18ebd
NC
4441 case EM_ARM:
4442 result = get_arm_section_type_name (sh_type);
4443 break;
40b36596
JM
4444 case EM_TI_C6000:
4445 result = get_tic6x_section_type_name (sh_type);
4446 break;
13761a11 4447 case EM_MSP430:
b0191216 4448 result = get_msp430_section_type_name (sh_type);
13761a11 4449 break;
fe944acf
FT
4450 case EM_NFP:
4451 result = get_nfp_section_type_name (sh_type);
4452 break;
685080f2
NC
4453 case EM_V800:
4454 case EM_V850:
4455 case EM_CYGNUS_V850:
4456 result = get_v850_section_type_name (sh_type);
4457 break;
2dc8dd17
JW
4458 case EM_RISCV:
4459 result = get_riscv_section_type_name (sh_type);
4460 break;
0861f561
CQ
4461 case EM_CSKY:
4462 result = get_csky_section_type_name (sh_type);
4463 break;
252b5132
RH
4464 default:
4465 result = NULL;
4466 break;
4467 }
4468
4469 if (result != NULL)
4470 return result;
4471
9fb71ee4 4472 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4473 }
4474 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4475 {
dda8d76d 4476 switch (filedata->file_header.e_machine)
148b93f2
NC
4477 {
4478 case EM_IA_64:
dda8d76d 4479 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4480 break;
4481 default:
dda8d76d 4482 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4483 result = get_solaris_section_type (sh_type);
4484 else
1b4b80bf
NC
4485 {
4486 switch (sh_type)
4487 {
4488 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4489 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4490 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4491 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4492 default:
4493 result = NULL;
4494 break;
4495 }
4496 }
148b93f2
NC
4497 break;
4498 }
4499
4500 if (result != NULL)
4501 return result;
4502
9fb71ee4 4503 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4504 }
252b5132 4505 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4506 {
dda8d76d 4507 switch (filedata->file_header.e_machine)
685080f2
NC
4508 {
4509 case EM_V800:
4510 case EM_V850:
4511 case EM_CYGNUS_V850:
9fb71ee4 4512 result = get_v850_section_type_name (sh_type);
a9fb83be 4513 break;
685080f2 4514 default:
9fb71ee4 4515 result = NULL;
685080f2
NC
4516 break;
4517 }
4518
9fb71ee4
NC
4519 if (result != NULL)
4520 return result;
4521
4522 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4523 }
252b5132 4524 else
a7dbfd1c
NC
4525 /* This message is probably going to be displayed in a 15
4526 character wide field, so put the hex value first. */
4527 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4528
252b5132
RH
4529 return buff;
4530 }
4531}
4532
79bc120c
NC
4533enum long_option_values
4534{
4535 OPTION_DEBUG_DUMP = 512,
4536 OPTION_DYN_SYMS,
0f03783c 4537 OPTION_LTO_SYMS,
79bc120c
NC
4538 OPTION_DWARF_DEPTH,
4539 OPTION_DWARF_START,
4540 OPTION_DWARF_CHECK,
4541 OPTION_CTF_DUMP,
4542 OPTION_CTF_PARENT,
4543 OPTION_CTF_SYMBOLS,
4544 OPTION_CTF_STRINGS,
4545 OPTION_WITH_SYMBOL_VERSIONS,
4546 OPTION_RECURSE_LIMIT,
4547 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
4548 OPTION_NO_DEMANGLING,
4549 OPTION_SYM_BASE
79bc120c 4550};
2979dc34 4551
85b1c36d 4552static struct option options[] =
252b5132 4553{
79bc120c
NC
4554 /* Note - This table is alpha-sorted on the 'val'
4555 field in order to make adding new options easier. */
4556 {"arch-specific", no_argument, 0, 'A'},
b34976b6 4557 {"all", no_argument, 0, 'a'},
79bc120c
NC
4558 {"demangle", optional_argument, 0, 'C'},
4559 {"archive-index", no_argument, 0, 'c'},
4560 {"use-dynamic", no_argument, 0, 'D'},
4561 {"dynamic", no_argument, 0, 'd'},
b34976b6 4562 {"headers", no_argument, 0, 'e'},
79bc120c
NC
4563 {"section-groups", no_argument, 0, 'g'},
4564 {"help", no_argument, 0, 'H'},
4565 {"file-header", no_argument, 0, 'h'},
b34976b6 4566 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
4567 {"lint", no_argument, 0, 'L'},
4568 {"enable-checks", no_argument, 0, 'L'},
4569 {"program-headers", no_argument, 0, 'l'},
b34976b6 4570 {"segments", no_argument, 0, 'l'},
595cf52e 4571 {"full-section-name",no_argument, 0, 'N'},
79bc120c 4572 {"notes", no_argument, 0, 'n'},
ca0e11aa 4573 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
4574 {"string-dump", required_argument, 0, 'p'},
4575 {"relocated-dump", required_argument, 0, 'R'},
4576 {"relocs", no_argument, 0, 'r'},
4577 {"section-headers", no_argument, 0, 'S'},
4578 {"sections", no_argument, 0, 'S'},
b34976b6
AM
4579 {"symbols", no_argument, 0, 's'},
4580 {"syms", no_argument, 0, 's'},
79bc120c
NC
4581 {"silent-truncation",no_argument, 0, 'T'},
4582 {"section-details", no_argument, 0, 't'},
09c11c86 4583 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
4584 {"version-info", no_argument, 0, 'V'},
4585 {"version", no_argument, 0, 'v'},
4586 {"wide", no_argument, 0, 'W'},
b34976b6 4587 {"hex-dump", required_argument, 0, 'x'},
0e602686 4588 {"decompress", no_argument, 0, 'z'},
252b5132 4589
79bc120c
NC
4590 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
4591 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
4592 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4593 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4594 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 4595 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 4596 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
4597 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4598 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4599 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 4600#ifdef ENABLE_LIBCTF
d344b407 4601 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
4602 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
4603 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
4604 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 4605#endif
047c3dbf 4606 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 4607
b34976b6 4608 {0, no_argument, 0, 0}
252b5132
RH
4609};
4610
4611static void
2cf0635d 4612usage (FILE * stream)
252b5132 4613{
92f01d61
JM
4614 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4615 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
4616 fprintf (stream, _(" Options are:\n"));
4617 fprintf (stream, _("\
4618 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
4619 fprintf (stream, _("\
4620 -h --file-header Display the ELF file header\n"));
4621 fprintf (stream, _("\
4622 -l --program-headers Display the program headers\n"));
4623 fprintf (stream, _("\
4624 --segments An alias for --program-headers\n"));
4625 fprintf (stream, _("\
4626 -S --section-headers Display the sections' header\n"));
4627 fprintf (stream, _("\
4628 --sections An alias for --section-headers\n"));
4629 fprintf (stream, _("\
4630 -g --section-groups Display the section groups\n"));
4631 fprintf (stream, _("\
4632 -t --section-details Display the section details\n"));
4633 fprintf (stream, _("\
4634 -e --headers Equivalent to: -h -l -S\n"));
4635 fprintf (stream, _("\
4636 -s --syms Display the symbol table\n"));
4637 fprintf (stream, _("\
4638 --symbols An alias for --syms\n"));
4639 fprintf (stream, _("\
4640 --dyn-syms Display the dynamic symbol table\n"));
4641 fprintf (stream, _("\
4642 --lto-syms Display LTO symbol tables\n"));
4643 fprintf (stream, _("\
047c3dbf
NL
4644 --sym-base=[0|8|10|16] \n\
4645 Force base for symbol sizes. The options are \n\
d6249f5f
AM
4646 mixed (the default), octal, decimal, hexadecimal.\n"));
4647 fprintf (stream, _("\
79bc120c
NC
4648 -C --demangle[=STYLE] Decode low-level symbol names into user-level names\n\
4649 The STYLE, if specified, can be `auto' (the default),\n\
4650 `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
d6249f5f
AM
4651 or `gnat'\n"));
4652 fprintf (stream, _("\
4653 --no-demangle Do not demangle low-level symbol names. (default)\n"));
4654 fprintf (stream, _("\
4655 --recurse-limit Enable a demangling recursion limit. (default)\n"));
4656 fprintf (stream, _("\
4657 --no-recurse-limit Disable a demangling recursion limit\n"));
4658 fprintf (stream, _("\
4659 -n --notes Display the core notes (if present)\n"));
4660 fprintf (stream, _("\
4661 -r --relocs Display the relocations (if present)\n"));
4662 fprintf (stream, _("\
4663 -u --unwind Display the unwind info (if present)\n"));
4664 fprintf (stream, _("\
4665 -d --dynamic Display the dynamic section (if present)\n"));
4666 fprintf (stream, _("\
4667 -V --version-info Display the version sections (if present)\n"));
4668 fprintf (stream, _("\
4669 -A --arch-specific Display architecture specific information (if any)\n"));
4670 fprintf (stream, _("\
4671 -c --archive-index Display the symbol/file index in an archive\n"));
4672 fprintf (stream, _("\
4673 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
4674 fprintf (stream, _("\
4675 -L --lint|--enable-checks\n\
4676 Display warning messages for possible problems\n"));
4677 fprintf (stream, _("\
09c11c86 4678 -x --hex-dump=<number|name>\n\
d6249f5f
AM
4679 Dump the contents of section <number|name> as bytes\n"));
4680 fprintf (stream, _("\
09c11c86 4681 -p --string-dump=<number|name>\n\
d6249f5f
AM
4682 Dump the contents of section <number|name> as strings\n"));
4683 fprintf (stream, _("\
cf13d699 4684 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
4685 Dump the relocated contents of section <number|name>\n"));
4686 fprintf (stream, _("\
4687 -z --decompress Decompress section before dumping it\n"));
4688 fprintf (stream, _("\
4689 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
4690 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
4691 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
4692 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
4693 U/=trace_info]\n\
4694 Display the contents of DWARF debug sections\n"));
4695 fprintf (stream, _("\
4696 -wk --debug-dump=links Display the contents of sections that link to separate\n\
4697 debuginfo files\n"));
4698 fprintf (stream, _("\
4699 -P --process-links Display the contents of non-debug sections in separate\n\
4700 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
4701#if DEFAULT_FOR_FOLLOW_LINKS
4702 fprintf (stream, _("\
d6249f5f
AM
4703 -wK --debug-dump=follow-links\n\
4704 Follow links to separate debug info files (default)\n"));
4705 fprintf (stream, _("\
4706 -wN --debug-dump=no-follow-links\n\
4707 Do not follow links to separate debug info files\n"));
c46b7066
NC
4708#else
4709 fprintf (stream, _("\
d6249f5f
AM
4710 -wK --debug-dump=follow-links\n\
4711 Follow links to separate debug info files\n"));
4712 fprintf (stream, _("\
4713 -wN --debug-dump=no-follow-links\n\
4714 Do not follow links to separate debug info files\n\
4715 (default)\n"));
c46b7066 4716#endif
fd2f0033 4717 fprintf (stream, _("\
d6249f5f
AM
4718 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
4719 fprintf (stream, _("\
4720 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 4721#ifdef ENABLE_LIBCTF
7d9813f1 4722 fprintf (stream, _("\
d6249f5f
AM
4723 --ctf=<number|name> Display CTF info from section <number|name>\n"));
4724 fprintf (stream, _("\
7d9813f1 4725 --ctf-parent=<number|name>\n\
d6249f5f
AM
4726 Use section <number|name> as the CTF parent\n"));
4727 fprintf (stream, _("\
7d9813f1 4728 --ctf-symbols=<number|name>\n\
d6249f5f
AM
4729 Use section <number|name> as the CTF external symtab\n"));
4730 fprintf (stream, _("\
7d9813f1 4731 --ctf-strings=<number|name>\n\
d6249f5f 4732 Use section <number|name> as the CTF external strtab\n"));
094e34f2 4733#endif
7d9813f1 4734
252b5132 4735#ifdef SUPPORT_DISASSEMBLY
92f01d61 4736 fprintf (stream, _("\
09c11c86
NC
4737 -i --instruction-dump=<number|name>\n\
4738 Disassemble the contents of section <number|name>\n"));
252b5132 4739#endif
92f01d61 4740 fprintf (stream, _("\
d6249f5f
AM
4741 -I --histogram Display histogram of bucket list lengths\n"));
4742 fprintf (stream, _("\
4743 -W --wide Allow output width to exceed 80 characters\n"));
4744 fprintf (stream, _("\
4745 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
4746 fprintf (stream, _("\
4747 @<file> Read options from <file>\n"));
4748 fprintf (stream, _("\
4749 -H --help Display this information\n"));
4750 fprintf (stream, _("\
8b53311e 4751 -v --version Display the version number of readelf\n"));
1118d252 4752
92f01d61
JM
4753 if (REPORT_BUGS_TO[0] && stream == stdout)
4754 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4755
92f01d61 4756 exit (stream == stdout ? 0 : 1);
252b5132
RH
4757}
4758
18bd398b
NC
4759/* Record the fact that the user wants the contents of section number
4760 SECTION to be displayed using the method(s) encoded as flags bits
4761 in TYPE. Note, TYPE can be zero if we are creating the array for
4762 the first time. */
4763
252b5132 4764static void
6431e409
AM
4765request_dump_bynumber (struct dump_data *dumpdata,
4766 unsigned int section, dump_type type)
252b5132 4767{
6431e409 4768 if (section >= dumpdata->num_dump_sects)
252b5132 4769 {
2cf0635d 4770 dump_type * new_dump_sects;
252b5132 4771
3f5e193b 4772 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4773 sizeof (* new_dump_sects));
252b5132
RH
4774
4775 if (new_dump_sects == NULL)
591a748a 4776 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4777 else
4778 {
6431e409 4779 if (dumpdata->dump_sects)
21b65bac
NC
4780 {
4781 /* Copy current flag settings. */
6431e409
AM
4782 memcpy (new_dump_sects, dumpdata->dump_sects,
4783 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4784
6431e409 4785 free (dumpdata->dump_sects);
21b65bac 4786 }
252b5132 4787
6431e409
AM
4788 dumpdata->dump_sects = new_dump_sects;
4789 dumpdata->num_dump_sects = section + 1;
252b5132
RH
4790 }
4791 }
4792
6431e409
AM
4793 if (dumpdata->dump_sects)
4794 dumpdata->dump_sects[section] |= type;
252b5132
RH
4795}
4796
aef1f6d0
DJ
4797/* Request a dump by section name. */
4798
4799static void
2cf0635d 4800request_dump_byname (const char * section, dump_type type)
aef1f6d0 4801{
2cf0635d 4802 struct dump_list_entry * new_request;
aef1f6d0 4803
3f5e193b
NC
4804 new_request = (struct dump_list_entry *)
4805 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4806 if (!new_request)
591a748a 4807 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4808
4809 new_request->name = strdup (section);
4810 if (!new_request->name)
591a748a 4811 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4812
4813 new_request->type = type;
4814
4815 new_request->next = dump_sects_byname;
4816 dump_sects_byname = new_request;
4817}
4818
cf13d699 4819static inline void
6431e409 4820request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
4821{
4822 int section;
4823 char * cp;
4824
015dc7e1 4825 do_dump = true;
cf13d699
NC
4826 section = strtoul (optarg, & cp, 0);
4827
4828 if (! *cp && section >= 0)
6431e409 4829 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
4830 else
4831 request_dump_byname (optarg, type);
4832}
4833
252b5132 4834static void
6431e409 4835parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
4836{
4837 int c;
4838
4839 if (argc < 2)
92f01d61 4840 usage (stderr);
252b5132
RH
4841
4842 while ((c = getopt_long
ca0e11aa 4843 (argc, argv, "ACDHILNPR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4844 {
252b5132
RH
4845 switch (c)
4846 {
4847 case 0:
4848 /* Long options. */
4849 break;
4850 case 'H':
92f01d61 4851 usage (stdout);
252b5132
RH
4852 break;
4853
4854 case 'a':
015dc7e1
AM
4855 do_syms = true;
4856 do_reloc = true;
4857 do_unwind = true;
4858 do_dynamic = true;
4859 do_header = true;
4860 do_sections = true;
4861 do_section_groups = true;
4862 do_segments = true;
4863 do_version = true;
4864 do_histogram = true;
4865 do_arch = true;
4866 do_notes = true;
252b5132 4867 break;
79bc120c 4868
f5842774 4869 case 'g':
015dc7e1 4870 do_section_groups = true;
f5842774 4871 break;
5477e8a0 4872 case 't':
595cf52e 4873 case 'N':
015dc7e1
AM
4874 do_sections = true;
4875 do_section_details = true;
595cf52e 4876 break;
252b5132 4877 case 'e':
015dc7e1
AM
4878 do_header = true;
4879 do_sections = true;
4880 do_segments = true;
252b5132 4881 break;
a952a375 4882 case 'A':
015dc7e1 4883 do_arch = true;
a952a375 4884 break;
252b5132 4885 case 'D':
015dc7e1 4886 do_using_dynamic = true;
252b5132
RH
4887 break;
4888 case 'r':
015dc7e1 4889 do_reloc = true;
252b5132 4890 break;
4d6ed7c8 4891 case 'u':
015dc7e1 4892 do_unwind = true;
4d6ed7c8 4893 break;
252b5132 4894 case 'h':
015dc7e1 4895 do_header = true;
252b5132
RH
4896 break;
4897 case 'l':
015dc7e1 4898 do_segments = true;
252b5132
RH
4899 break;
4900 case 's':
015dc7e1 4901 do_syms = true;
252b5132
RH
4902 break;
4903 case 'S':
015dc7e1 4904 do_sections = true;
252b5132
RH
4905 break;
4906 case 'd':
015dc7e1 4907 do_dynamic = true;
252b5132 4908 break;
a952a375 4909 case 'I':
015dc7e1 4910 do_histogram = true;
a952a375 4911 break;
779fe533 4912 case 'n':
015dc7e1 4913 do_notes = true;
779fe533 4914 break;
4145f1d5 4915 case 'c':
015dc7e1 4916 do_archive_index = true;
4145f1d5 4917 break;
1b513401 4918 case 'L':
015dc7e1 4919 do_checks = true;
1b513401 4920 break;
ca0e11aa 4921 case 'P':
015dc7e1
AM
4922 process_links = true;
4923 do_follow_links = true;
ca0e11aa 4924 break;
252b5132 4925 case 'x':
6431e409 4926 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 4927 break;
09c11c86 4928 case 'p':
6431e409 4929 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
4930 break;
4931 case 'R':
6431e409 4932 request_dump (dumpdata, RELOC_DUMP);
09c11c86 4933 break;
0e602686 4934 case 'z':
015dc7e1 4935 decompress_dumps = true;
0e602686 4936 break;
252b5132 4937 case 'w':
015dc7e1 4938 do_dump = true;
0f03783c 4939 if (optarg == NULL)
613ff48b 4940 {
015dc7e1 4941 do_debugging = true;
613ff48b
CC
4942 dwarf_select_sections_all ();
4943 }
252b5132
RH
4944 else
4945 {
015dc7e1 4946 do_debugging = false;
4cb93e3b 4947 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4948 }
4949 break;
2979dc34 4950 case OPTION_DEBUG_DUMP:
015dc7e1 4951 do_dump = true;
0f03783c 4952 if (optarg == NULL)
d6249f5f
AM
4953 {
4954 do_debugging = true;
4955 dwarf_select_sections_all ();
4956 }
2979dc34
JJ
4957 else
4958 {
015dc7e1 4959 do_debugging = false;
4cb93e3b 4960 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4961 }
4962 break;
fd2f0033
TT
4963 case OPTION_DWARF_DEPTH:
4964 {
4965 char *cp;
4966
4967 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4968 }
4969 break;
4970 case OPTION_DWARF_START:
4971 {
4972 char *cp;
4973
4974 dwarf_start_die = strtoul (optarg, & cp, 0);
4975 }
4976 break;
4723351a 4977 case OPTION_DWARF_CHECK:
015dc7e1 4978 dwarf_check = true;
4723351a 4979 break;
7d9813f1 4980 case OPTION_CTF_DUMP:
015dc7e1 4981 do_ctf = true;
6431e409 4982 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
4983 break;
4984 case OPTION_CTF_SYMBOLS:
df16e041 4985 free (dump_ctf_symtab_name);
7d9813f1
NA
4986 dump_ctf_symtab_name = strdup (optarg);
4987 break;
4988 case OPTION_CTF_STRINGS:
df16e041 4989 free (dump_ctf_strtab_name);
7d9813f1
NA
4990 dump_ctf_strtab_name = strdup (optarg);
4991 break;
4992 case OPTION_CTF_PARENT:
df16e041 4993 free (dump_ctf_parent_name);
7d9813f1
NA
4994 dump_ctf_parent_name = strdup (optarg);
4995 break;
2c610e4b 4996 case OPTION_DYN_SYMS:
015dc7e1 4997 do_dyn_syms = true;
2c610e4b 4998 break;
0f03783c 4999 case OPTION_LTO_SYMS:
015dc7e1 5000 do_lto_syms = true;
0f03783c 5001 break;
252b5132
RH
5002#ifdef SUPPORT_DISASSEMBLY
5003 case 'i':
6431e409 5004 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5005 break;
252b5132
RH
5006#endif
5007 case 'v':
5008 print_version (program_name);
5009 break;
5010 case 'V':
015dc7e1 5011 do_version = true;
252b5132 5012 break;
d974e256 5013 case 'W':
015dc7e1 5014 do_wide = true;
d974e256 5015 break;
0942c7ab 5016 case 'T':
015dc7e1 5017 do_not_show_symbol_truncation = true;
0942c7ab 5018 break;
79bc120c 5019 case 'C':
015dc7e1 5020 do_demangle = true;
79bc120c
NC
5021 if (optarg != NULL)
5022 {
5023 enum demangling_styles style;
5024
5025 style = cplus_demangle_name_to_style (optarg);
5026 if (style == unknown_demangling)
5027 error (_("unknown demangling style `%s'"), optarg);
5028
5029 cplus_demangle_set_style (style);
5030 }
5031 break;
5032 case OPTION_NO_DEMANGLING:
015dc7e1 5033 do_demangle = false;
79bc120c
NC
5034 break;
5035 case OPTION_RECURSE_LIMIT:
5036 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5037 break;
5038 case OPTION_NO_RECURSE_LIMIT:
5039 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5040 break;
5041 case OPTION_WITH_SYMBOL_VERSIONS:
5042 /* Ignored for backward compatibility. */
5043 break;
b9e920ec 5044
047c3dbf
NL
5045 case OPTION_SYM_BASE:
5046 sym_base = 0;
5047 if (optarg != NULL)
5048 {
5049 sym_base = strtoul (optarg, NULL, 0);
5050 switch (sym_base)
5051 {
5052 case 0:
5053 case 8:
5054 case 10:
5055 case 16:
5056 break;
5057
5058 default:
5059 sym_base = 0;
5060 break;
5061 }
5062 }
5063 break;
5064
252b5132 5065 default:
252b5132
RH
5066 /* xgettext:c-format */
5067 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5068 /* Fall through. */
252b5132 5069 case '?':
92f01d61 5070 usage (stderr);
252b5132
RH
5071 }
5072 }
5073
4d6ed7c8 5074 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5075 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5076 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5077 && !do_section_groups && !do_archive_index
0f03783c 5078 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5079 {
5080 if (do_checks)
5081 {
015dc7e1
AM
5082 check_all = true;
5083 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5084 do_segments = do_header = do_dump = do_version = true;
5085 do_histogram = do_debugging = do_arch = do_notes = true;
5086 do_section_groups = do_archive_index = do_dyn_syms = true;
5087 do_lto_syms = true;
1b513401
NC
5088 }
5089 else
5090 usage (stderr);
5091 }
252b5132
RH
5092}
5093
5094static const char *
d3ba0551 5095get_elf_class (unsigned int elf_class)
252b5132 5096{
b34976b6 5097 static char buff[32];
103f02d3 5098
252b5132
RH
5099 switch (elf_class)
5100 {
5101 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5102 case ELFCLASS32: return "ELF32";
5103 case ELFCLASS64: return "ELF64";
ab5e7794 5104 default:
e9e44622 5105 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5106 return buff;
252b5132
RH
5107 }
5108}
5109
5110static const char *
d3ba0551 5111get_data_encoding (unsigned int encoding)
252b5132 5112{
b34976b6 5113 static char buff[32];
103f02d3 5114
252b5132
RH
5115 switch (encoding)
5116 {
5117 case ELFDATANONE: return _("none");
33c63f9d
CM
5118 case ELFDATA2LSB: return _("2's complement, little endian");
5119 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5120 default:
e9e44622 5121 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5122 return buff;
252b5132
RH
5123 }
5124}
5125
dda8d76d 5126/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5127
015dc7e1 5128static bool
dda8d76d 5129process_file_header (Filedata * filedata)
252b5132 5130{
dda8d76d
NC
5131 Elf_Internal_Ehdr * header = & filedata->file_header;
5132
5133 if ( header->e_ident[EI_MAG0] != ELFMAG0
5134 || header->e_ident[EI_MAG1] != ELFMAG1
5135 || header->e_ident[EI_MAG2] != ELFMAG2
5136 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5137 {
5138 error
5139 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
015dc7e1 5140 return false;
252b5132
RH
5141 }
5142
ca0e11aa
NC
5143 if (! filedata->is_separate)
5144 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5145
252b5132
RH
5146 if (do_header)
5147 {
32ec8896 5148 unsigned i;
252b5132 5149
ca0e11aa
NC
5150 if (filedata->is_separate)
5151 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5152 else
5153 printf (_("ELF Header:\n"));
252b5132 5154 printf (_(" Magic: "));
b34976b6 5155 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5156 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5157 printf ("\n");
5158 printf (_(" Class: %s\n"),
dda8d76d 5159 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5160 printf (_(" Data: %s\n"),
dda8d76d 5161 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5162 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5163 header->e_ident[EI_VERSION],
5164 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5165 ? _(" (current)")
dda8d76d 5166 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5167 ? _(" <unknown>")
789be9f7 5168 : "")));
252b5132 5169 printf (_(" OS/ABI: %s\n"),
dda8d76d 5170 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5171 printf (_(" ABI Version: %d\n"),
dda8d76d 5172 header->e_ident[EI_ABIVERSION]);
252b5132 5173 printf (_(" Type: %s\n"),
dda8d76d 5174 get_file_type (header->e_type));
252b5132 5175 printf (_(" Machine: %s\n"),
dda8d76d 5176 get_machine_name (header->e_machine));
252b5132 5177 printf (_(" Version: 0x%lx\n"),
e8a64888 5178 header->e_version);
76da6bbe 5179
f7a99963 5180 printf (_(" Entry point address: "));
e8a64888 5181 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5182 printf (_("\n Start of program headers: "));
e8a64888 5183 print_vma (header->e_phoff, DEC);
f7a99963 5184 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5185 print_vma (header->e_shoff, DEC);
f7a99963 5186 printf (_(" (bytes into file)\n"));
76da6bbe 5187
252b5132 5188 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5189 header->e_flags,
dda8d76d 5190 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5191 printf (_(" Size of this header: %u (bytes)\n"),
5192 header->e_ehsize);
5193 printf (_(" Size of program headers: %u (bytes)\n"),
5194 header->e_phentsize);
5195 printf (_(" Number of program headers: %u"),
5196 header->e_phnum);
dda8d76d
NC
5197 if (filedata->section_headers != NULL
5198 && header->e_phnum == PN_XNUM
5199 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
5200 {
5201 header->e_phnum = filedata->section_headers[0].sh_info;
5202 printf (" (%u)", header->e_phnum);
5203 }
2046a35d 5204 putc ('\n', stdout);
e8a64888
AM
5205 printf (_(" Size of section headers: %u (bytes)\n"),
5206 header->e_shentsize);
5207 printf (_(" Number of section headers: %u"),
5208 header->e_shnum);
dda8d76d 5209 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5210 {
5211 header->e_shnum = filedata->section_headers[0].sh_size;
5212 printf (" (%u)", header->e_shnum);
5213 }
560f3c1c 5214 putc ('\n', stdout);
e8a64888
AM
5215 printf (_(" Section header string table index: %u"),
5216 header->e_shstrndx);
dda8d76d
NC
5217 if (filedata->section_headers != NULL
5218 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5219 {
5220 header->e_shstrndx = filedata->section_headers[0].sh_link;
5221 printf (" (%u)", header->e_shstrndx);
5222 }
5223 if (header->e_shstrndx != SHN_UNDEF
5224 && header->e_shstrndx >= header->e_shnum)
5225 {
5226 header->e_shstrndx = SHN_UNDEF;
5227 printf (_(" <corrupt: out of range>"));
5228 }
560f3c1c
AM
5229 putc ('\n', stdout);
5230 }
5231
dda8d76d 5232 if (filedata->section_headers != NULL)
560f3c1c 5233 {
dda8d76d
NC
5234 if (header->e_phnum == PN_XNUM
5235 && filedata->section_headers[0].sh_info != 0)
5236 header->e_phnum = filedata->section_headers[0].sh_info;
5237 if (header->e_shnum == SHN_UNDEF)
5238 header->e_shnum = filedata->section_headers[0].sh_size;
5239 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5240 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5241 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
5242 header->e_shstrndx = SHN_UNDEF;
5243 free (filedata->section_headers);
5244 filedata->section_headers = NULL;
252b5132 5245 }
103f02d3 5246
015dc7e1 5247 return true;
9ea033b2
NC
5248}
5249
dda8d76d
NC
5250/* Read in the program headers from FILEDATA and store them in PHEADERS.
5251 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5252
015dc7e1 5253static bool
dda8d76d 5254get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5255{
2cf0635d
NC
5256 Elf32_External_Phdr * phdrs;
5257 Elf32_External_Phdr * external;
5258 Elf_Internal_Phdr * internal;
b34976b6 5259 unsigned int i;
dda8d76d
NC
5260 unsigned int size = filedata->file_header.e_phentsize;
5261 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5262
5263 /* PR binutils/17531: Cope with unexpected section header sizes. */
5264 if (size == 0 || num == 0)
015dc7e1 5265 return false;
e0a31db1
NC
5266 if (size < sizeof * phdrs)
5267 {
5268 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5269 return false;
e0a31db1
NC
5270 }
5271 if (size > sizeof * phdrs)
5272 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5273
dda8d76d 5274 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5275 size, num, _("program headers"));
5276 if (phdrs == NULL)
015dc7e1 5277 return false;
9ea033b2 5278
91d6fa6a 5279 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5280 i < filedata->file_header.e_phnum;
b34976b6 5281 i++, internal++, external++)
252b5132 5282 {
9ea033b2
NC
5283 internal->p_type = BYTE_GET (external->p_type);
5284 internal->p_offset = BYTE_GET (external->p_offset);
5285 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5286 internal->p_paddr = BYTE_GET (external->p_paddr);
5287 internal->p_filesz = BYTE_GET (external->p_filesz);
5288 internal->p_memsz = BYTE_GET (external->p_memsz);
5289 internal->p_flags = BYTE_GET (external->p_flags);
5290 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5291 }
5292
9ea033b2 5293 free (phdrs);
015dc7e1 5294 return true;
252b5132
RH
5295}
5296
dda8d76d
NC
5297/* Read in the program headers from FILEDATA and store them in PHEADERS.
5298 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5299
015dc7e1 5300static bool
dda8d76d 5301get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5302{
2cf0635d
NC
5303 Elf64_External_Phdr * phdrs;
5304 Elf64_External_Phdr * external;
5305 Elf_Internal_Phdr * internal;
b34976b6 5306 unsigned int i;
dda8d76d
NC
5307 unsigned int size = filedata->file_header.e_phentsize;
5308 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5309
5310 /* PR binutils/17531: Cope with unexpected section header sizes. */
5311 if (size == 0 || num == 0)
015dc7e1 5312 return false;
e0a31db1
NC
5313 if (size < sizeof * phdrs)
5314 {
5315 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5316 return false;
e0a31db1
NC
5317 }
5318 if (size > sizeof * phdrs)
5319 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5320
dda8d76d 5321 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5322 size, num, _("program headers"));
a6e9f9df 5323 if (!phdrs)
015dc7e1 5324 return false;
9ea033b2 5325
91d6fa6a 5326 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5327 i < filedata->file_header.e_phnum;
b34976b6 5328 i++, internal++, external++)
9ea033b2
NC
5329 {
5330 internal->p_type = BYTE_GET (external->p_type);
5331 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5332 internal->p_offset = BYTE_GET (external->p_offset);
5333 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5334 internal->p_paddr = BYTE_GET (external->p_paddr);
5335 internal->p_filesz = BYTE_GET (external->p_filesz);
5336 internal->p_memsz = BYTE_GET (external->p_memsz);
5337 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5338 }
5339
5340 free (phdrs);
015dc7e1 5341 return true;
9ea033b2 5342}
252b5132 5343
32ec8896 5344/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5345
015dc7e1 5346static bool
dda8d76d 5347get_program_headers (Filedata * filedata)
d93f0186 5348{
2cf0635d 5349 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5350
5351 /* Check cache of prior read. */
dda8d76d 5352 if (filedata->program_headers != NULL)
015dc7e1 5353 return true;
d93f0186 5354
82156ab7
NC
5355 /* Be kind to memory checkers by looking for
5356 e_phnum values which we know must be invalid. */
dda8d76d 5357 if (filedata->file_header.e_phnum
82156ab7 5358 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5359 >= filedata->file_size)
82156ab7
NC
5360 {
5361 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5362 filedata->file_header.e_phnum);
015dc7e1 5363 return false;
82156ab7 5364 }
d93f0186 5365
dda8d76d 5366 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5367 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5368 if (phdrs == NULL)
5369 {
8b73c356 5370 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5371 filedata->file_header.e_phnum);
015dc7e1 5372 return false;
d93f0186
NC
5373 }
5374
5375 if (is_32bit_elf
dda8d76d
NC
5376 ? get_32bit_program_headers (filedata, phdrs)
5377 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5378 {
dda8d76d 5379 filedata->program_headers = phdrs;
015dc7e1 5380 return true;
d93f0186
NC
5381 }
5382
5383 free (phdrs);
015dc7e1 5384 return false;
d93f0186
NC
5385}
5386
32ec8896 5387/* Returns TRUE if the program headers were loaded. */
2f62977e 5388
015dc7e1 5389static bool
dda8d76d 5390process_program_headers (Filedata * filedata)
252b5132 5391{
2cf0635d 5392 Elf_Internal_Phdr * segment;
b34976b6 5393 unsigned int i;
1a9ccd70 5394 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5395
978c4450
AM
5396 filedata->dynamic_addr = 0;
5397 filedata->dynamic_size = 0;
663f67df 5398
dda8d76d 5399 if (filedata->file_header.e_phnum == 0)
252b5132 5400 {
82f2dbf7 5401 /* PR binutils/12467. */
dda8d76d 5402 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5403 {
5404 warn (_("possibly corrupt ELF header - it has a non-zero program"
5405 " header offset, but no program headers\n"));
015dc7e1 5406 return false;
32ec8896 5407 }
82f2dbf7 5408 else if (do_segments)
ca0e11aa
NC
5409 {
5410 if (filedata->is_separate)
5411 printf (_("\nThere are no program headers in linked file '%s'.\n"),
5412 filedata->file_name);
5413 else
5414 printf (_("\nThere are no program headers in this file.\n"));
5415 }
015dc7e1 5416 return true;
252b5132
RH
5417 }
5418
5419 if (do_segments && !do_header)
5420 {
ca0e11aa
NC
5421 if (filedata->is_separate)
5422 printf ("\nIn linked file '%s' the ELF file type is %s\n",
5423 filedata->file_name,
5424 get_file_type (filedata->file_header.e_type));
5425 else
5426 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
dda8d76d 5427 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5428 printf (ngettext ("There is %d program header, starting at offset %s\n",
5429 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5430 filedata->file_header.e_phnum),
5431 filedata->file_header.e_phnum,
5432 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5433 }
5434
dda8d76d 5435 if (! get_program_headers (filedata))
015dc7e1 5436 return true;
103f02d3 5437
252b5132
RH
5438 if (do_segments)
5439 {
dda8d76d 5440 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5441 printf (_("\nProgram Headers:\n"));
5442 else
5443 printf (_("\nProgram Headers:\n"));
76da6bbe 5444
f7a99963
NC
5445 if (is_32bit_elf)
5446 printf
5447 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5448 else if (do_wide)
5449 printf
5450 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5451 else
5452 {
5453 printf
5454 (_(" Type Offset VirtAddr PhysAddr\n"));
5455 printf
5456 (_(" FileSiz MemSiz Flags Align\n"));
5457 }
252b5132
RH
5458 }
5459
dda8d76d
NC
5460 for (i = 0, segment = filedata->program_headers;
5461 i < filedata->file_header.e_phnum;
b34976b6 5462 i++, segment++)
252b5132
RH
5463 {
5464 if (do_segments)
5465 {
dda8d76d 5466 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5467
5468 if (is_32bit_elf)
5469 {
5470 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5471 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5472 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5473 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5474 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5475 printf ("%c%c%c ",
5476 (segment->p_flags & PF_R ? 'R' : ' '),
5477 (segment->p_flags & PF_W ? 'W' : ' '),
5478 (segment->p_flags & PF_X ? 'E' : ' '));
5479 printf ("%#lx", (unsigned long) segment->p_align);
5480 }
d974e256
JJ
5481 else if (do_wide)
5482 {
5483 if ((unsigned long) segment->p_offset == segment->p_offset)
5484 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5485 else
5486 {
5487 print_vma (segment->p_offset, FULL_HEX);
5488 putchar (' ');
5489 }
5490
5491 print_vma (segment->p_vaddr, FULL_HEX);
5492 putchar (' ');
5493 print_vma (segment->p_paddr, FULL_HEX);
5494 putchar (' ');
5495
5496 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5497 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5498 else
5499 {
5500 print_vma (segment->p_filesz, FULL_HEX);
5501 putchar (' ');
5502 }
5503
5504 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5505 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5506 else
5507 {
f48e6c45 5508 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5509 }
5510
5511 printf (" %c%c%c ",
5512 (segment->p_flags & PF_R ? 'R' : ' '),
5513 (segment->p_flags & PF_W ? 'W' : ' '),
5514 (segment->p_flags & PF_X ? 'E' : ' '));
5515
5516 if ((unsigned long) segment->p_align == segment->p_align)
5517 printf ("%#lx", (unsigned long) segment->p_align);
5518 else
5519 {
5520 print_vma (segment->p_align, PREFIX_HEX);
5521 }
5522 }
f7a99963
NC
5523 else
5524 {
5525 print_vma (segment->p_offset, FULL_HEX);
5526 putchar (' ');
5527 print_vma (segment->p_vaddr, FULL_HEX);
5528 putchar (' ');
5529 print_vma (segment->p_paddr, FULL_HEX);
5530 printf ("\n ");
5531 print_vma (segment->p_filesz, FULL_HEX);
5532 putchar (' ');
5533 print_vma (segment->p_memsz, FULL_HEX);
5534 printf (" %c%c%c ",
5535 (segment->p_flags & PF_R ? 'R' : ' '),
5536 (segment->p_flags & PF_W ? 'W' : ' '),
5537 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5538 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5539 }
252b5132 5540
1a9ccd70
NC
5541 putc ('\n', stdout);
5542 }
f54498b4 5543
252b5132
RH
5544 switch (segment->p_type)
5545 {
1a9ccd70 5546 case PT_LOAD:
502d895c
NC
5547#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5548 required by the ELF standard, several programs, including the Linux
5549 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5550 if (previous_load
5551 && previous_load->p_vaddr > segment->p_vaddr)
5552 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5553#endif
1a9ccd70
NC
5554 if (segment->p_memsz < segment->p_filesz)
5555 error (_("the segment's file size is larger than its memory size\n"));
5556 previous_load = segment;
5557 break;
5558
5559 case PT_PHDR:
5560 /* PR 20815 - Verify that the program header is loaded into memory. */
5561 if (i > 0 && previous_load != NULL)
5562 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5563 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5564 {
5565 unsigned int j;
5566
dda8d76d 5567 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5568 {
5569 Elf_Internal_Phdr *load = filedata->program_headers + j;
5570 if (load->p_type == PT_LOAD
5571 && load->p_offset <= segment->p_offset
5572 && (load->p_offset + load->p_filesz
5573 >= segment->p_offset + segment->p_filesz)
5574 && load->p_vaddr <= segment->p_vaddr
5575 && (load->p_vaddr + load->p_filesz
5576 >= segment->p_vaddr + segment->p_filesz))
5577 break;
5578 }
dda8d76d 5579 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5580 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5581 }
5582 break;
5583
252b5132 5584 case PT_DYNAMIC:
978c4450 5585 if (filedata->dynamic_addr)
252b5132
RH
5586 error (_("more than one dynamic segment\n"));
5587
20737c13
AM
5588 /* By default, assume that the .dynamic section is the first
5589 section in the DYNAMIC segment. */
978c4450
AM
5590 filedata->dynamic_addr = segment->p_offset;
5591 filedata->dynamic_size = segment->p_filesz;
20737c13 5592
b2d38a17
NC
5593 /* Try to locate the .dynamic section. If there is
5594 a section header table, we can easily locate it. */
dda8d76d 5595 if (filedata->section_headers != NULL)
b2d38a17 5596 {
2cf0635d 5597 Elf_Internal_Shdr * sec;
b2d38a17 5598
dda8d76d 5599 sec = find_section (filedata, ".dynamic");
89fac5e3 5600 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5601 {
28f997cf
TG
5602 /* A corresponding .dynamic section is expected, but on
5603 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5604 if (!is_ia64_vms (filedata))
28f997cf 5605 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5606 break;
5607 }
5608
42bb2e33 5609 if (sec->sh_type == SHT_NOBITS)
20737c13 5610 {
978c4450 5611 filedata->dynamic_size = 0;
20737c13
AM
5612 break;
5613 }
42bb2e33 5614
978c4450
AM
5615 filedata->dynamic_addr = sec->sh_offset;
5616 filedata->dynamic_size = sec->sh_size;
b2d38a17 5617
8ac10c5b
L
5618 /* The PT_DYNAMIC segment, which is used by the run-time
5619 loader, should exactly match the .dynamic section. */
5620 if (do_checks
5621 && (filedata->dynamic_addr != segment->p_offset
5622 || filedata->dynamic_size != segment->p_filesz))
5623 warn (_("\
5624the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 5625 }
39e224f6
MW
5626
5627 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5628 segment. Check this after matching against the section headers
5629 so we don't warn on debuginfo file (which have NOBITS .dynamic
5630 sections). */
978c4450
AM
5631 if (filedata->dynamic_addr > filedata->file_size
5632 || (filedata->dynamic_size
5633 > filedata->file_size - filedata->dynamic_addr))
39e224f6
MW
5634 {
5635 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
978c4450 5636 filedata->dynamic_addr = filedata->dynamic_size = 0;
39e224f6 5637 }
252b5132
RH
5638 break;
5639
5640 case PT_INTERP:
13acb58d
AM
5641 if (segment->p_offset >= filedata->file_size
5642 || segment->p_filesz > filedata->file_size - segment->p_offset
5643 || segment->p_filesz - 1 >= (size_t) -2
5644 || fseek (filedata->handle,
5645 filedata->archive_file_offset + (long) segment->p_offset,
5646 SEEK_SET))
252b5132
RH
5647 error (_("Unable to find program interpreter name\n"));
5648 else
5649 {
13acb58d
AM
5650 size_t len = segment->p_filesz;
5651 free (filedata->program_interpreter);
5652 filedata->program_interpreter = xmalloc (len + 1);
5653 len = fread (filedata->program_interpreter, 1, len,
5654 filedata->handle);
5655 filedata->program_interpreter[len] = 0;
252b5132
RH
5656
5657 if (do_segments)
f54498b4 5658 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 5659 filedata->program_interpreter);
252b5132
RH
5660 }
5661 break;
5662 }
252b5132
RH
5663 }
5664
dda8d76d
NC
5665 if (do_segments
5666 && filedata->section_headers != NULL
5667 && filedata->string_table != NULL)
252b5132
RH
5668 {
5669 printf (_("\n Section to Segment mapping:\n"));
5670 printf (_(" Segment Sections...\n"));
5671
dda8d76d 5672 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5673 {
9ad5cbcf 5674 unsigned int j;
2cf0635d 5675 Elf_Internal_Shdr * section;
252b5132 5676
dda8d76d
NC
5677 segment = filedata->program_headers + i;
5678 section = filedata->section_headers + 1;
252b5132
RH
5679
5680 printf (" %2.2d ", i);
5681
dda8d76d 5682 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5683 {
f4638467
AM
5684 if (!ELF_TBSS_SPECIAL (section, segment)
5685 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5686 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5687 }
5688
5689 putc ('\n',stdout);
5690 }
5691 }
5692
015dc7e1 5693 return true;
252b5132
RH
5694}
5695
5696
d93f0186
NC
5697/* Find the file offset corresponding to VMA by using the program headers. */
5698
5699static long
dda8d76d 5700offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5701{
2cf0635d 5702 Elf_Internal_Phdr * seg;
d93f0186 5703
dda8d76d 5704 if (! get_program_headers (filedata))
d93f0186
NC
5705 {
5706 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5707 return (long) vma;
5708 }
5709
dda8d76d
NC
5710 for (seg = filedata->program_headers;
5711 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5712 ++seg)
5713 {
5714 if (seg->p_type != PT_LOAD)
5715 continue;
5716
5717 if (vma >= (seg->p_vaddr & -seg->p_align)
5718 && vma + size <= seg->p_vaddr + seg->p_filesz)
5719 return vma - seg->p_vaddr + seg->p_offset;
5720 }
5721
5722 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5723 (unsigned long) vma);
d93f0186
NC
5724 return (long) vma;
5725}
5726
5727
dda8d76d
NC
5728/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5729 If PROBE is true, this is just a probe and we do not generate any error
5730 messages if the load fails. */
049b0c3a 5731
015dc7e1
AM
5732static bool
5733get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 5734{
2cf0635d
NC
5735 Elf32_External_Shdr * shdrs;
5736 Elf_Internal_Shdr * internal;
dda8d76d
NC
5737 unsigned int i;
5738 unsigned int size = filedata->file_header.e_shentsize;
5739 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5740
5741 /* PR binutils/17531: Cope with unexpected section header sizes. */
5742 if (size == 0 || num == 0)
015dc7e1 5743 return false;
049b0c3a
NC
5744 if (size < sizeof * shdrs)
5745 {
5746 if (! probe)
5747 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 5748 return false;
049b0c3a
NC
5749 }
5750 if (!probe && size > sizeof * shdrs)
5751 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5752
dda8d76d 5753 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5754 size, num,
5755 probe ? NULL : _("section headers"));
5756 if (shdrs == NULL)
015dc7e1 5757 return false;
252b5132 5758
dda8d76d
NC
5759 free (filedata->section_headers);
5760 filedata->section_headers = (Elf_Internal_Shdr *)
5761 cmalloc (num, sizeof (Elf_Internal_Shdr));
5762 if (filedata->section_headers == NULL)
252b5132 5763 {
049b0c3a 5764 if (!probe)
8b73c356 5765 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5766 free (shdrs);
015dc7e1 5767 return false;
252b5132
RH
5768 }
5769
dda8d76d 5770 for (i = 0, internal = filedata->section_headers;
560f3c1c 5771 i < num;
b34976b6 5772 i++, internal++)
252b5132
RH
5773 {
5774 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5775 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5776 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5777 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5778 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5779 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5780 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5781 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5782 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5783 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5784 if (!probe && internal->sh_link > num)
5785 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5786 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5787 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5788 }
5789
5790 free (shdrs);
015dc7e1 5791 return true;
252b5132
RH
5792}
5793
dda8d76d
NC
5794/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5795
015dc7e1
AM
5796static bool
5797get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 5798{
dda8d76d
NC
5799 Elf64_External_Shdr * shdrs;
5800 Elf_Internal_Shdr * internal;
5801 unsigned int i;
5802 unsigned int size = filedata->file_header.e_shentsize;
5803 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5804
5805 /* PR binutils/17531: Cope with unexpected section header sizes. */
5806 if (size == 0 || num == 0)
015dc7e1 5807 return false;
dda8d76d 5808
049b0c3a
NC
5809 if (size < sizeof * shdrs)
5810 {
5811 if (! probe)
5812 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 5813 return false;
049b0c3a 5814 }
dda8d76d 5815
049b0c3a
NC
5816 if (! probe && size > sizeof * shdrs)
5817 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5818
dda8d76d
NC
5819 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5820 filedata->file_header.e_shoff,
049b0c3a
NC
5821 size, num,
5822 probe ? NULL : _("section headers"));
5823 if (shdrs == NULL)
015dc7e1 5824 return false;
9ea033b2 5825
dda8d76d
NC
5826 free (filedata->section_headers);
5827 filedata->section_headers = (Elf_Internal_Shdr *)
5828 cmalloc (num, sizeof (Elf_Internal_Shdr));
5829 if (filedata->section_headers == NULL)
9ea033b2 5830 {
049b0c3a 5831 if (! probe)
8b73c356 5832 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5833 free (shdrs);
015dc7e1 5834 return false;
9ea033b2
NC
5835 }
5836
dda8d76d 5837 for (i = 0, internal = filedata->section_headers;
560f3c1c 5838 i < num;
b34976b6 5839 i++, internal++)
9ea033b2
NC
5840 {
5841 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5842 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5843 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5844 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5845 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5846 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5847 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5848 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5849 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5850 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5851 if (!probe && internal->sh_link > num)
5852 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5853 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5854 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5855 }
5856
5857 free (shdrs);
015dc7e1 5858 return true;
9ea033b2
NC
5859}
5860
252b5132 5861static Elf_Internal_Sym *
dda8d76d
NC
5862get_32bit_elf_symbols (Filedata * filedata,
5863 Elf_Internal_Shdr * section,
5864 unsigned long * num_syms_return)
252b5132 5865{
ba5cdace 5866 unsigned long number = 0;
dd24e3da 5867 Elf32_External_Sym * esyms = NULL;
ba5cdace 5868 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5869 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5870 Elf_Internal_Sym * psym;
b34976b6 5871 unsigned int j;
e3d39609 5872 elf_section_list * entry;
252b5132 5873
c9c1d674
EG
5874 if (section->sh_size == 0)
5875 {
5876 if (num_syms_return != NULL)
5877 * num_syms_return = 0;
5878 return NULL;
5879 }
5880
dd24e3da 5881 /* Run some sanity checks first. */
c9c1d674 5882 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5883 {
c9c1d674 5884 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5885 printable_section_name (filedata, section),
5886 (unsigned long) section->sh_entsize);
ba5cdace 5887 goto exit_point;
dd24e3da
NC
5888 }
5889
dda8d76d 5890 if (section->sh_size > filedata->file_size)
f54498b4
NC
5891 {
5892 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5893 printable_section_name (filedata, section),
5894 (unsigned long) section->sh_size);
f54498b4
NC
5895 goto exit_point;
5896 }
5897
dd24e3da
NC
5898 number = section->sh_size / section->sh_entsize;
5899
5900 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5901 {
c9c1d674 5902 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5903 (unsigned long) section->sh_size,
dda8d76d 5904 printable_section_name (filedata, section),
8066deb1 5905 (unsigned long) section->sh_entsize);
ba5cdace 5906 goto exit_point;
dd24e3da
NC
5907 }
5908
dda8d76d 5909 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5910 section->sh_size, _("symbols"));
dd24e3da 5911 if (esyms == NULL)
ba5cdace 5912 goto exit_point;
252b5132 5913
e3d39609 5914 shndx = NULL;
978c4450 5915 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5916 {
5917 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5918 continue;
5919
5920 if (shndx != NULL)
5921 {
5922 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5923 free (shndx);
5924 }
5925
5926 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5927 entry->hdr->sh_offset,
5928 1, entry->hdr->sh_size,
5929 _("symbol table section indices"));
5930 if (shndx == NULL)
5931 goto exit_point;
5932
5933 /* PR17531: file: heap-buffer-overflow */
5934 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5935 {
5936 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5937 printable_section_name (filedata, entry->hdr),
5938 (unsigned long) entry->hdr->sh_size,
5939 (unsigned long) section->sh_size);
5940 goto exit_point;
c9c1d674 5941 }
e3d39609 5942 }
9ad5cbcf 5943
3f5e193b 5944 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5945
5946 if (isyms == NULL)
5947 {
8b73c356
NC
5948 error (_("Out of memory reading %lu symbols\n"),
5949 (unsigned long) number);
dd24e3da 5950 goto exit_point;
252b5132
RH
5951 }
5952
dd24e3da 5953 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5954 {
5955 psym->st_name = BYTE_GET (esyms[j].st_name);
5956 psym->st_value = BYTE_GET (esyms[j].st_value);
5957 psym->st_size = BYTE_GET (esyms[j].st_size);
5958 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5959 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5960 psym->st_shndx
5961 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5962 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5963 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5964 psym->st_info = BYTE_GET (esyms[j].st_info);
5965 psym->st_other = BYTE_GET (esyms[j].st_other);
5966 }
5967
dd24e3da 5968 exit_point:
e3d39609
NC
5969 free (shndx);
5970 free (esyms);
252b5132 5971
ba5cdace
NC
5972 if (num_syms_return != NULL)
5973 * num_syms_return = isyms == NULL ? 0 : number;
5974
252b5132
RH
5975 return isyms;
5976}
5977
9ea033b2 5978static Elf_Internal_Sym *
dda8d76d
NC
5979get_64bit_elf_symbols (Filedata * filedata,
5980 Elf_Internal_Shdr * section,
5981 unsigned long * num_syms_return)
9ea033b2 5982{
ba5cdace
NC
5983 unsigned long number = 0;
5984 Elf64_External_Sym * esyms = NULL;
5985 Elf_External_Sym_Shndx * shndx = NULL;
5986 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5987 Elf_Internal_Sym * psym;
b34976b6 5988 unsigned int j;
e3d39609 5989 elf_section_list * entry;
9ea033b2 5990
c9c1d674
EG
5991 if (section->sh_size == 0)
5992 {
5993 if (num_syms_return != NULL)
5994 * num_syms_return = 0;
5995 return NULL;
5996 }
5997
dd24e3da 5998 /* Run some sanity checks first. */
c9c1d674 5999 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6000 {
c9c1d674 6001 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 6002 printable_section_name (filedata, section),
8066deb1 6003 (unsigned long) section->sh_entsize);
ba5cdace 6004 goto exit_point;
dd24e3da
NC
6005 }
6006
dda8d76d 6007 if (section->sh_size > filedata->file_size)
f54498b4
NC
6008 {
6009 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 6010 printable_section_name (filedata, section),
8066deb1 6011 (unsigned long) section->sh_size);
f54498b4
NC
6012 goto exit_point;
6013 }
6014
dd24e3da
NC
6015 number = section->sh_size / section->sh_entsize;
6016
6017 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6018 {
c9c1d674 6019 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6020 (unsigned long) section->sh_size,
dda8d76d 6021 printable_section_name (filedata, section),
8066deb1 6022 (unsigned long) section->sh_entsize);
ba5cdace 6023 goto exit_point;
dd24e3da
NC
6024 }
6025
dda8d76d 6026 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6027 section->sh_size, _("symbols"));
a6e9f9df 6028 if (!esyms)
ba5cdace 6029 goto exit_point;
9ea033b2 6030
e3d39609 6031 shndx = NULL;
978c4450 6032 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6033 {
6034 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6035 continue;
6036
6037 if (shndx != NULL)
6038 {
6039 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6040 free (shndx);
c9c1d674 6041 }
e3d39609
NC
6042
6043 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6044 entry->hdr->sh_offset,
6045 1, entry->hdr->sh_size,
6046 _("symbol table section indices"));
6047 if (shndx == NULL)
6048 goto exit_point;
6049
6050 /* PR17531: file: heap-buffer-overflow */
6051 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6052 {
6053 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6054 printable_section_name (filedata, entry->hdr),
6055 (unsigned long) entry->hdr->sh_size,
6056 (unsigned long) section->sh_size);
6057 goto exit_point;
6058 }
6059 }
9ad5cbcf 6060
3f5e193b 6061 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6062
6063 if (isyms == NULL)
6064 {
8b73c356
NC
6065 error (_("Out of memory reading %lu symbols\n"),
6066 (unsigned long) number);
ba5cdace 6067 goto exit_point;
9ea033b2
NC
6068 }
6069
ba5cdace 6070 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6071 {
6072 psym->st_name = BYTE_GET (esyms[j].st_name);
6073 psym->st_info = BYTE_GET (esyms[j].st_info);
6074 psym->st_other = BYTE_GET (esyms[j].st_other);
6075 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6076
4fbb74a6 6077 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6078 psym->st_shndx
6079 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6080 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6081 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6082
66543521
AM
6083 psym->st_value = BYTE_GET (esyms[j].st_value);
6084 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6085 }
6086
ba5cdace 6087 exit_point:
e3d39609
NC
6088 free (shndx);
6089 free (esyms);
ba5cdace
NC
6090
6091 if (num_syms_return != NULL)
6092 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6093
6094 return isyms;
6095}
6096
d1133906 6097static const char *
dda8d76d 6098get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 6099{
5477e8a0 6100 static char buff[1024];
2cf0635d 6101 char * p = buff;
32ec8896
NC
6102 unsigned int field_size = is_32bit_elf ? 8 : 16;
6103 signed int sindex;
6104 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
6105 bfd_vma os_flags = 0;
6106 bfd_vma proc_flags = 0;
6107 bfd_vma unknown_flags = 0;
148b93f2 6108 static const struct
5477e8a0 6109 {
2cf0635d 6110 const char * str;
32ec8896 6111 unsigned int len;
5477e8a0
L
6112 }
6113 flags [] =
6114 {
cfcac11d
NC
6115 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6116 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6117 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6118 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6119 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6120 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6121 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6122 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6123 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6124 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6125 /* IA-64 specific. */
6126 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6127 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6128 /* IA-64 OpenVMS specific. */
6129 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6130 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6131 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6132 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6133 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6134 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6135 /* Generic. */
cfcac11d 6136 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6137 /* SPARC specific. */
77115a4a 6138 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6139 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6140 /* ARM specific. */
6141 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6142 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6143 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6144 /* GNU specific. */
6145 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6146 /* VLE specific. */
6147 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6148 /* GNU specific. */
6149 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6150 };
6151
6152 if (do_section_details)
6153 {
8d5ff12c
L
6154 sprintf (buff, "[%*.*lx]: ",
6155 field_size, field_size, (unsigned long) sh_flags);
6156 p += field_size + 4;
5477e8a0 6157 }
76da6bbe 6158
d1133906
NC
6159 while (sh_flags)
6160 {
6161 bfd_vma flag;
6162
6163 flag = sh_flags & - sh_flags;
6164 sh_flags &= ~ flag;
76da6bbe 6165
5477e8a0 6166 if (do_section_details)
d1133906 6167 {
5477e8a0
L
6168 switch (flag)
6169 {
91d6fa6a
NC
6170 case SHF_WRITE: sindex = 0; break;
6171 case SHF_ALLOC: sindex = 1; break;
6172 case SHF_EXECINSTR: sindex = 2; break;
6173 case SHF_MERGE: sindex = 3; break;
6174 case SHF_STRINGS: sindex = 4; break;
6175 case SHF_INFO_LINK: sindex = 5; break;
6176 case SHF_LINK_ORDER: sindex = 6; break;
6177 case SHF_OS_NONCONFORMING: sindex = 7; break;
6178 case SHF_GROUP: sindex = 8; break;
6179 case SHF_TLS: sindex = 9; break;
18ae9cc1 6180 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6181 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6182
5477e8a0 6183 default:
91d6fa6a 6184 sindex = -1;
dda8d76d 6185 switch (filedata->file_header.e_machine)
148b93f2 6186 {
cfcac11d 6187 case EM_IA_64:
148b93f2 6188 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6189 sindex = 10;
148b93f2 6190 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6191 sindex = 11;
148b93f2 6192#ifdef BFD64
dda8d76d 6193 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6194 switch (flag)
6195 {
91d6fa6a
NC
6196 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6197 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6198 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6199 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6200 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6201 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6202 default: break;
6203 }
6204#endif
cfcac11d
NC
6205 break;
6206
caa83f8b 6207 case EM_386:
22abe556 6208 case EM_IAMCU:
caa83f8b 6209 case EM_X86_64:
7f502d6c 6210 case EM_L1OM:
7a9068fe 6211 case EM_K1OM:
cfcac11d
NC
6212 case EM_OLD_SPARCV9:
6213 case EM_SPARC32PLUS:
6214 case EM_SPARCV9:
6215 case EM_SPARC:
18ae9cc1 6216 if (flag == SHF_ORDERED)
91d6fa6a 6217 sindex = 19;
cfcac11d 6218 break;
ac4c9b04
MG
6219
6220 case EM_ARM:
6221 switch (flag)
6222 {
6223 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6224 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6225 case SHF_COMDEF: sindex = 23; break;
6226 default: break;
6227 }
6228 break;
83eef883
AFB
6229 case EM_PPC:
6230 if (flag == SHF_PPC_VLE)
6231 sindex = 25;
6232 break;
99fabbc9
JL
6233 default:
6234 break;
6235 }
ac4c9b04 6236
99fabbc9
JL
6237 switch (filedata->file_header.e_ident[EI_OSABI])
6238 {
6239 case ELFOSABI_GNU:
6240 case ELFOSABI_FREEBSD:
6241 if (flag == SHF_GNU_RETAIN)
6242 sindex = 26;
6243 /* Fall through */
6244 case ELFOSABI_NONE:
6245 if (flag == SHF_GNU_MBIND)
6246 /* We should not recognize SHF_GNU_MBIND for
6247 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6248 not set the EI_OSABI header byte. */
6249 sindex = 24;
6250 break;
cfcac11d
NC
6251 default:
6252 break;
148b93f2 6253 }
99fabbc9 6254 break;
5477e8a0
L
6255 }
6256
91d6fa6a 6257 if (sindex != -1)
5477e8a0 6258 {
8d5ff12c
L
6259 if (p != buff + field_size + 4)
6260 {
6261 if (size < (10 + 2))
bee0ee85
NC
6262 {
6263 warn (_("Internal error: not enough buffer room for section flag info"));
6264 return _("<unknown>");
6265 }
8d5ff12c
L
6266 size -= 2;
6267 *p++ = ',';
6268 *p++ = ' ';
6269 }
6270
91d6fa6a
NC
6271 size -= flags [sindex].len;
6272 p = stpcpy (p, flags [sindex].str);
5477e8a0 6273 }
3b22753a 6274 else if (flag & SHF_MASKOS)
8d5ff12c 6275 os_flags |= flag;
d1133906 6276 else if (flag & SHF_MASKPROC)
8d5ff12c 6277 proc_flags |= flag;
d1133906 6278 else
8d5ff12c 6279 unknown_flags |= flag;
5477e8a0
L
6280 }
6281 else
6282 {
6283 switch (flag)
6284 {
6285 case SHF_WRITE: *p = 'W'; break;
6286 case SHF_ALLOC: *p = 'A'; break;
6287 case SHF_EXECINSTR: *p = 'X'; break;
6288 case SHF_MERGE: *p = 'M'; break;
6289 case SHF_STRINGS: *p = 'S'; break;
6290 case SHF_INFO_LINK: *p = 'I'; break;
6291 case SHF_LINK_ORDER: *p = 'L'; break;
6292 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6293 case SHF_GROUP: *p = 'G'; break;
6294 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6295 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6296 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6297
6298 default:
dda8d76d
NC
6299 if ((filedata->file_header.e_machine == EM_X86_64
6300 || filedata->file_header.e_machine == EM_L1OM
6301 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6302 && flag == SHF_X86_64_LARGE)
6303 *p = 'l';
dda8d76d 6304 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6305 && flag == SHF_ARM_PURECODE)
99fabbc9 6306 *p = 'y';
dda8d76d 6307 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6308 && flag == SHF_PPC_VLE)
99fabbc9 6309 *p = 'v';
5477e8a0
L
6310 else if (flag & SHF_MASKOS)
6311 {
99fabbc9
JL
6312 switch (filedata->file_header.e_ident[EI_OSABI])
6313 {
6314 case ELFOSABI_GNU:
6315 case ELFOSABI_FREEBSD:
6316 if (flag == SHF_GNU_RETAIN)
6317 {
6318 *p = 'R';
6319 break;
6320 }
6321 /* Fall through */
6322 case ELFOSABI_NONE:
6323 if (flag == SHF_GNU_MBIND)
6324 {
6325 /* We should not recognize SHF_GNU_MBIND for
6326 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6327 not set the EI_OSABI header byte. */
6328 *p = 'D';
6329 break;
6330 }
6331 /* Fall through */
6332 default:
6333 *p = 'o';
6334 sh_flags &= ~SHF_MASKOS;
6335 break;
6336 }
5477e8a0
L
6337 }
6338 else if (flag & SHF_MASKPROC)
6339 {
6340 *p = 'p';
6341 sh_flags &= ~ SHF_MASKPROC;
6342 }
6343 else
6344 *p = 'x';
6345 break;
6346 }
6347 p++;
d1133906
NC
6348 }
6349 }
76da6bbe 6350
8d5ff12c
L
6351 if (do_section_details)
6352 {
6353 if (os_flags)
6354 {
6355 size -= 5 + field_size;
6356 if (p != buff + field_size + 4)
6357 {
6358 if (size < (2 + 1))
bee0ee85
NC
6359 {
6360 warn (_("Internal error: not enough buffer room for section flag info"));
6361 return _("<unknown>");
6362 }
8d5ff12c
L
6363 size -= 2;
6364 *p++ = ',';
6365 *p++ = ' ';
6366 }
6367 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6368 (unsigned long) os_flags);
6369 p += 5 + field_size;
6370 }
6371 if (proc_flags)
6372 {
6373 size -= 7 + field_size;
6374 if (p != buff + field_size + 4)
6375 {
6376 if (size < (2 + 1))
bee0ee85
NC
6377 {
6378 warn (_("Internal error: not enough buffer room for section flag info"));
6379 return _("<unknown>");
6380 }
8d5ff12c
L
6381 size -= 2;
6382 *p++ = ',';
6383 *p++ = ' ';
6384 }
6385 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6386 (unsigned long) proc_flags);
6387 p += 7 + field_size;
6388 }
6389 if (unknown_flags)
6390 {
6391 size -= 10 + field_size;
6392 if (p != buff + field_size + 4)
6393 {
6394 if (size < (2 + 1))
bee0ee85
NC
6395 {
6396 warn (_("Internal error: not enough buffer room for section flag info"));
6397 return _("<unknown>");
6398 }
8d5ff12c
L
6399 size -= 2;
6400 *p++ = ',';
6401 *p++ = ' ';
6402 }
2b692964 6403 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6404 (unsigned long) unknown_flags);
6405 p += 10 + field_size;
6406 }
6407 }
6408
e9e44622 6409 *p = '\0';
d1133906
NC
6410 return buff;
6411}
6412
5844b465 6413static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6414get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6415{
6416 if (is_32bit_elf)
6417 {
6418 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6419
ebdf1ebf
NC
6420 if (size < sizeof (* echdr))
6421 {
6422 error (_("Compressed section is too small even for a compression header\n"));
6423 return 0;
6424 }
6425
77115a4a
L
6426 chdr->ch_type = BYTE_GET (echdr->ch_type);
6427 chdr->ch_size = BYTE_GET (echdr->ch_size);
6428 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6429 return sizeof (*echdr);
6430 }
6431 else
6432 {
6433 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6434
ebdf1ebf
NC
6435 if (size < sizeof (* echdr))
6436 {
6437 error (_("Compressed section is too small even for a compression header\n"));
6438 return 0;
6439 }
6440
77115a4a
L
6441 chdr->ch_type = BYTE_GET (echdr->ch_type);
6442 chdr->ch_size = BYTE_GET (echdr->ch_size);
6443 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6444 return sizeof (*echdr);
6445 }
6446}
6447
015dc7e1 6448static bool
dda8d76d 6449process_section_headers (Filedata * filedata)
252b5132 6450{
2cf0635d 6451 Elf_Internal_Shdr * section;
b34976b6 6452 unsigned int i;
252b5132 6453
8fb879cd 6454 free (filedata->section_headers);
dda8d76d 6455 filedata->section_headers = NULL;
978c4450
AM
6456 free (filedata->dynamic_symbols);
6457 filedata->dynamic_symbols = NULL;
6458 filedata->num_dynamic_syms = 0;
6459 free (filedata->dynamic_strings);
6460 filedata->dynamic_strings = NULL;
6461 filedata->dynamic_strings_length = 0;
6462 free (filedata->dynamic_syminfo);
6463 filedata->dynamic_syminfo = NULL;
6464 while (filedata->symtab_shndx_list != NULL)
8ff66993 6465 {
978c4450
AM
6466 elf_section_list *next = filedata->symtab_shndx_list->next;
6467 free (filedata->symtab_shndx_list);
6468 filedata->symtab_shndx_list = next;
8ff66993 6469 }
252b5132 6470
dda8d76d 6471 if (filedata->file_header.e_shnum == 0)
252b5132 6472 {
82f2dbf7 6473 /* PR binutils/12467. */
dda8d76d 6474 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6475 {
6476 warn (_("possibly corrupt ELF file header - it has a non-zero"
6477 " section header offset, but no section headers\n"));
015dc7e1 6478 return false;
32ec8896 6479 }
82f2dbf7 6480 else if (do_sections)
252b5132
RH
6481 printf (_("\nThere are no sections in this file.\n"));
6482
015dc7e1 6483 return true;
252b5132
RH
6484 }
6485
6486 if (do_sections && !do_header)
ca0e11aa
NC
6487 {
6488 if (filedata->is_separate && process_links)
6489 printf (_("In linked file '%s': "), filedata->file_name);
6490 if (! filedata->is_separate || process_links)
6491 printf (ngettext ("There is %d section header, "
6492 "starting at offset 0x%lx:\n",
6493 "There are %d section headers, "
6494 "starting at offset 0x%lx:\n",
6495 filedata->file_header.e_shnum),
6496 filedata->file_header.e_shnum,
6497 (unsigned long) filedata->file_header.e_shoff);
6498 }
252b5132 6499
9ea033b2
NC
6500 if (is_32bit_elf)
6501 {
015dc7e1
AM
6502 if (! get_32bit_section_headers (filedata, false))
6503 return false;
32ec8896
NC
6504 }
6505 else
6506 {
015dc7e1
AM
6507 if (! get_64bit_section_headers (filedata, false))
6508 return false;
9ea033b2 6509 }
252b5132
RH
6510
6511 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6512 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6513 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6514 {
dda8d76d 6515 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6516
c256ffe7
JJ
6517 if (section->sh_size != 0)
6518 {
dda8d76d
NC
6519 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6520 1, section->sh_size,
6521 _("string table"));
0de14b54 6522
dda8d76d 6523 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6524 }
252b5132
RH
6525 }
6526
6527 /* Scan the sections for the dynamic symbol table
e3c8793a 6528 and dynamic string table and debug sections. */
89fac5e3 6529 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6530 switch (filedata->file_header.e_machine)
89fac5e3
RS
6531 {
6532 case EM_MIPS:
6533 case EM_MIPS_RS3_LE:
6534 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6535 FDE addresses. However, the ABI also has a semi-official ILP32
6536 variant for which the normal FDE address size rules apply.
6537
6538 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6539 section, where XX is the size of longs in bits. Unfortunately,
6540 earlier compilers provided no way of distinguishing ILP32 objects
6541 from LP64 objects, so if there's any doubt, we should assume that
6542 the official LP64 form is being used. */
dda8d76d
NC
6543 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6544 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6545 eh_addr_size = 8;
6546 break;
0f56a26a
DD
6547
6548 case EM_H8_300:
6549 case EM_H8_300H:
dda8d76d 6550 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6551 {
6552 case E_H8_MACH_H8300:
6553 case E_H8_MACH_H8300HN:
6554 case E_H8_MACH_H8300SN:
6555 case E_H8_MACH_H8300SXN:
6556 eh_addr_size = 2;
6557 break;
6558 case E_H8_MACH_H8300H:
6559 case E_H8_MACH_H8300S:
6560 case E_H8_MACH_H8300SX:
6561 eh_addr_size = 4;
6562 break;
6563 }
f4236fe4
DD
6564 break;
6565
ff7eeb89 6566 case EM_M32C_OLD:
f4236fe4 6567 case EM_M32C:
dda8d76d 6568 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6569 {
6570 case EF_M32C_CPU_M16C:
6571 eh_addr_size = 2;
6572 break;
6573 }
6574 break;
89fac5e3
RS
6575 }
6576
76ca31c0
NC
6577#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6578 do \
6579 { \
6580 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6581 if (section->sh_entsize != expected_entsize) \
9dd3a467 6582 { \
76ca31c0
NC
6583 char buf[40]; \
6584 sprintf_vma (buf, section->sh_entsize); \
6585 /* Note: coded this way so that there is a single string for \
6586 translation. */ \
6587 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6588 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6589 (unsigned) expected_entsize); \
9dd3a467 6590 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6591 } \
6592 } \
08d8fa11 6593 while (0)
9dd3a467
NC
6594
6595#define CHECK_ENTSIZE(section, i, type) \
1b513401 6596 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
6597 sizeof (Elf64_External_##type))
6598
dda8d76d
NC
6599 for (i = 0, section = filedata->section_headers;
6600 i < filedata->file_header.e_shnum;
b34976b6 6601 i++, section++)
252b5132 6602 {
b9e920ec 6603 char * name = SECTION_NAME_PRINT (section);
252b5132 6604
1b513401
NC
6605 /* Run some sanity checks on the headers and
6606 possibly fill in some file data as well. */
6607 switch (section->sh_type)
252b5132 6608 {
1b513401 6609 case SHT_DYNSYM:
978c4450 6610 if (filedata->dynamic_symbols != NULL)
252b5132
RH
6611 {
6612 error (_("File contains multiple dynamic symbol tables\n"));
6613 continue;
6614 }
6615
08d8fa11 6616 CHECK_ENTSIZE (section, i, Sym);
978c4450
AM
6617 filedata->dynamic_symbols
6618 = GET_ELF_SYMBOLS (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 6619 filedata->dynamic_symtab_section = section;
1b513401
NC
6620 break;
6621
6622 case SHT_STRTAB:
6623 if (streq (name, ".dynstr"))
252b5132 6624 {
1b513401
NC
6625 if (filedata->dynamic_strings != NULL)
6626 {
6627 error (_("File contains multiple dynamic string tables\n"));
6628 continue;
6629 }
6630
6631 filedata->dynamic_strings
6632 = (char *) get_data (NULL, filedata, section->sh_offset,
6633 1, section->sh_size, _("dynamic strings"));
6634 filedata->dynamic_strings_length
6635 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 6636 filedata->dynamic_strtab_section = section;
252b5132 6637 }
1b513401
NC
6638 break;
6639
6640 case SHT_SYMTAB_SHNDX:
6641 {
6642 elf_section_list * entry = xmalloc (sizeof * entry);
6643
6644 entry->hdr = section;
6645 entry->next = filedata->symtab_shndx_list;
6646 filedata->symtab_shndx_list = entry;
6647 }
6648 break;
6649
6650 case SHT_SYMTAB:
6651 CHECK_ENTSIZE (section, i, Sym);
6652 break;
6653
6654 case SHT_GROUP:
6655 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6656 break;
252b5132 6657
1b513401
NC
6658 case SHT_REL:
6659 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 6660 if (do_checks && section->sh_size == 0)
1b513401
NC
6661 warn (_("Section '%s': zero-sized relocation section\n"), name);
6662 break;
6663
6664 case SHT_RELA:
6665 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 6666 if (do_checks && section->sh_size == 0)
1b513401
NC
6667 warn (_("Section '%s': zero-sized relocation section\n"), name);
6668 break;
6669
6670 case SHT_NOTE:
6671 case SHT_PROGBITS:
546cb2d8
NC
6672 /* Having a zero sized section is not illegal according to the
6673 ELF standard, but it might be an indication that something
6674 is wrong. So issue a warning if we are running in lint mode. */
6675 if (do_checks && section->sh_size == 0)
1b513401
NC
6676 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
6677 break;
6678
6679 default:
6680 break;
6681 }
6682
6683 if ((do_debugging || do_debug_info || do_debug_abbrevs
6684 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
6685 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
6686 || do_debug_str || do_debug_str_offsets || do_debug_loc
6687 || do_debug_ranges
1b513401 6688 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
6689 && (startswith (name, ".debug_")
6690 || startswith (name, ".zdebug_")))
252b5132 6691 {
1b315056
CS
6692 if (name[1] == 'z')
6693 name += sizeof (".zdebug_") - 1;
6694 else
6695 name += sizeof (".debug_") - 1;
252b5132
RH
6696
6697 if (do_debugging
24d127aa
ML
6698 || (do_debug_info && startswith (name, "info"))
6699 || (do_debug_info && startswith (name, "types"))
6700 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 6701 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
6702 || (do_debug_lines && startswith (name, "line."))
6703 || (do_debug_pubnames && startswith (name, "pubnames"))
6704 || (do_debug_pubtypes && startswith (name, "pubtypes"))
6705 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
6706 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
6707 || (do_debug_aranges && startswith (name, "aranges"))
6708 || (do_debug_ranges && startswith (name, "ranges"))
6709 || (do_debug_ranges && startswith (name, "rnglists"))
6710 || (do_debug_frames && startswith (name, "frame"))
6711 || (do_debug_macinfo && startswith (name, "macinfo"))
6712 || (do_debug_macinfo && startswith (name, "macro"))
6713 || (do_debug_str && startswith (name, "str"))
6714 || (do_debug_links && startswith (name, "sup"))
6715 || (do_debug_str_offsets && startswith (name, "str_offsets"))
6716 || (do_debug_loc && startswith (name, "loc"))
6717 || (do_debug_loc && startswith (name, "loclists"))
6718 || (do_debug_addr && startswith (name, "addr"))
6719 || (do_debug_cu_index && startswith (name, "cu_index"))
6720 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 6721 )
6431e409 6722 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6723 }
a262ae96 6724 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6725 else if ((do_debugging || do_debug_info)
24d127aa 6726 && startswith (name, ".gnu.linkonce.wi."))
6431e409 6727 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6728 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6729 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6730 else if (do_gdb_index && (streq (name, ".gdb_index")
6731 || streq (name, ".debug_names")))
6431e409 6732 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6733 /* Trace sections for Itanium VMS. */
6734 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6735 || do_trace_aranges)
24d127aa 6736 && startswith (name, ".trace_"))
6f875884
TG
6737 {
6738 name += sizeof (".trace_") - 1;
6739
6740 if (do_debugging
6741 || (do_trace_info && streq (name, "info"))
6742 || (do_trace_abbrevs && streq (name, "abbrev"))
6743 || (do_trace_aranges && streq (name, "aranges"))
6744 )
6431e409 6745 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6746 }
dda8d76d 6747 else if ((do_debugging || do_debug_links)
24d127aa
ML
6748 && (startswith (name, ".gnu_debuglink")
6749 || startswith (name, ".gnu_debugaltlink")))
6431e409 6750 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6751 }
6752
6753 if (! do_sections)
015dc7e1 6754 return true;
252b5132 6755
ca0e11aa 6756 if (filedata->is_separate && ! process_links)
015dc7e1 6757 return true;
ca0e11aa
NC
6758
6759 if (filedata->is_separate)
6760 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
6761 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6762 printf (_("\nSection Headers:\n"));
6763 else
6764 printf (_("\nSection Header:\n"));
76da6bbe 6765
f7a99963 6766 if (is_32bit_elf)
595cf52e 6767 {
5477e8a0 6768 if (do_section_details)
595cf52e
L
6769 {
6770 printf (_(" [Nr] Name\n"));
5477e8a0 6771 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6772 }
6773 else
6774 printf
6775 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6776 }
d974e256 6777 else if (do_wide)
595cf52e 6778 {
5477e8a0 6779 if (do_section_details)
595cf52e
L
6780 {
6781 printf (_(" [Nr] Name\n"));
5477e8a0 6782 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6783 }
6784 else
6785 printf
6786 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6787 }
f7a99963
NC
6788 else
6789 {
5477e8a0 6790 if (do_section_details)
595cf52e
L
6791 {
6792 printf (_(" [Nr] Name\n"));
5477e8a0
L
6793 printf (_(" Type Address Offset Link\n"));
6794 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6795 }
6796 else
6797 {
6798 printf (_(" [Nr] Name Type Address Offset\n"));
6799 printf (_(" Size EntSize Flags Link Info Align\n"));
6800 }
f7a99963 6801 }
252b5132 6802
5477e8a0
L
6803 if (do_section_details)
6804 printf (_(" Flags\n"));
6805
dda8d76d
NC
6806 for (i = 0, section = filedata->section_headers;
6807 i < filedata->file_header.e_shnum;
b34976b6 6808 i++, section++)
252b5132 6809 {
dd905818
NC
6810 /* Run some sanity checks on the section header. */
6811
6812 /* Check the sh_link field. */
6813 switch (section->sh_type)
6814 {
285e3f99
AM
6815 case SHT_REL:
6816 case SHT_RELA:
6817 if (section->sh_link == 0
6818 && (filedata->file_header.e_type == ET_EXEC
6819 || filedata->file_header.e_type == ET_DYN))
6820 /* A dynamic relocation section where all entries use a
6821 zero symbol index need not specify a symtab section. */
6822 break;
6823 /* Fall through. */
dd905818
NC
6824 case SHT_SYMTAB_SHNDX:
6825 case SHT_GROUP:
6826 case SHT_HASH:
6827 case SHT_GNU_HASH:
6828 case SHT_GNU_versym:
285e3f99 6829 if (section->sh_link == 0
dda8d76d
NC
6830 || section->sh_link >= filedata->file_header.e_shnum
6831 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6832 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6833 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6834 i, section->sh_link);
6835 break;
6836
6837 case SHT_DYNAMIC:
6838 case SHT_SYMTAB:
6839 case SHT_DYNSYM:
6840 case SHT_GNU_verneed:
6841 case SHT_GNU_verdef:
6842 case SHT_GNU_LIBLIST:
285e3f99 6843 if (section->sh_link == 0
dda8d76d
NC
6844 || section->sh_link >= filedata->file_header.e_shnum
6845 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6846 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6847 i, section->sh_link);
6848 break;
6849
6850 case SHT_INIT_ARRAY:
6851 case SHT_FINI_ARRAY:
6852 case SHT_PREINIT_ARRAY:
6853 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6854 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6855 i, section->sh_link);
6856 break;
6857
6858 default:
6859 /* FIXME: Add support for target specific section types. */
6860#if 0 /* Currently we do not check other section types as there are too
6861 many special cases. Stab sections for example have a type
6862 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6863 section. */
6864 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6865 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6866 i, section->sh_link);
6867#endif
6868 break;
6869 }
6870
6871 /* Check the sh_info field. */
6872 switch (section->sh_type)
6873 {
6874 case SHT_REL:
6875 case SHT_RELA:
285e3f99
AM
6876 if (section->sh_info == 0
6877 && (filedata->file_header.e_type == ET_EXEC
6878 || filedata->file_header.e_type == ET_DYN))
6879 /* Dynamic relocations apply to segments, so they do not
6880 need to specify the section they relocate. */
6881 break;
6882 if (section->sh_info == 0
dda8d76d
NC
6883 || section->sh_info >= filedata->file_header.e_shnum
6884 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6885 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6886 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6887 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6888 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6889 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6890 /* FIXME: Are other section types valid ? */
dda8d76d 6891 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6892 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6893 i, section->sh_info);
dd905818
NC
6894 break;
6895
6896 case SHT_DYNAMIC:
6897 case SHT_HASH:
6898 case SHT_SYMTAB_SHNDX:
6899 case SHT_INIT_ARRAY:
6900 case SHT_FINI_ARRAY:
6901 case SHT_PREINIT_ARRAY:
6902 if (section->sh_info != 0)
6903 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6904 i, section->sh_info);
6905 break;
6906
6907 case SHT_GROUP:
6908 case SHT_SYMTAB:
6909 case SHT_DYNSYM:
6910 /* A symbol index - we assume that it is valid. */
6911 break;
6912
6913 default:
6914 /* FIXME: Add support for target specific section types. */
6915 if (section->sh_type == SHT_NOBITS)
6916 /* NOBITS section headers with non-zero sh_info fields can be
6917 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6918 information. The stripped sections have their headers
6919 preserved but their types set to SHT_NOBITS. So do not check
6920 this type of section. */
dd905818
NC
6921 ;
6922 else if (section->sh_flags & SHF_INFO_LINK)
6923 {
dda8d76d 6924 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6925 warn (_("[%2u]: Expected link to another section in info field"), i);
6926 }
a91e1603
L
6927 else if (section->sh_type < SHT_LOOS
6928 && (section->sh_flags & SHF_GNU_MBIND) == 0
6929 && section->sh_info != 0)
dd905818
NC
6930 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6931 i, section->sh_info);
6932 break;
6933 }
6934
3e6b6445 6935 /* Check the sh_size field. */
dda8d76d 6936 if (section->sh_size > filedata->file_size
3e6b6445
NC
6937 && section->sh_type != SHT_NOBITS
6938 && section->sh_type != SHT_NULL
6939 && section->sh_type < SHT_LOOS)
6940 warn (_("Size of section %u is larger than the entire file!\n"), i);
6941
7bfd842d 6942 printf (" [%2u] ", i);
5477e8a0 6943 if (do_section_details)
dda8d76d 6944 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6945 else
b9e920ec 6946 print_symbol (-17, SECTION_NAME_PRINT (section));
0b4362b0 6947
ea52a088 6948 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6949 get_section_type_name (filedata, section->sh_type));
0b4362b0 6950
f7a99963
NC
6951 if (is_32bit_elf)
6952 {
cfcac11d
NC
6953 const char * link_too_big = NULL;
6954
f7a99963 6955 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6956
f7a99963
NC
6957 printf ( " %6.6lx %6.6lx %2.2lx",
6958 (unsigned long) section->sh_offset,
6959 (unsigned long) section->sh_size,
6960 (unsigned long) section->sh_entsize);
d1133906 6961
5477e8a0
L
6962 if (do_section_details)
6963 fputs (" ", stdout);
6964 else
dda8d76d 6965 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6966
dda8d76d 6967 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6968 {
6969 link_too_big = "";
6970 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6971 an error but it can have special values in Solaris binaries. */
dda8d76d 6972 switch (filedata->file_header.e_machine)
cfcac11d 6973 {
caa83f8b 6974 case EM_386:
22abe556 6975 case EM_IAMCU:
caa83f8b 6976 case EM_X86_64:
7f502d6c 6977 case EM_L1OM:
7a9068fe 6978 case EM_K1OM:
cfcac11d
NC
6979 case EM_OLD_SPARCV9:
6980 case EM_SPARC32PLUS:
6981 case EM_SPARCV9:
6982 case EM_SPARC:
6983 if (section->sh_link == (SHN_BEFORE & 0xffff))
6984 link_too_big = "BEFORE";
6985 else if (section->sh_link == (SHN_AFTER & 0xffff))
6986 link_too_big = "AFTER";
6987 break;
6988 default:
6989 break;
6990 }
6991 }
6992
6993 if (do_section_details)
6994 {
6995 if (link_too_big != NULL && * link_too_big)
6996 printf ("<%s> ", link_too_big);
6997 else
6998 printf ("%2u ", section->sh_link);
6999 printf ("%3u %2lu\n", section->sh_info,
7000 (unsigned long) section->sh_addralign);
7001 }
7002 else
7003 printf ("%2u %3u %2lu\n",
7004 section->sh_link,
7005 section->sh_info,
7006 (unsigned long) section->sh_addralign);
7007
7008 if (link_too_big && ! * link_too_big)
7009 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7010 i, section->sh_link);
f7a99963 7011 }
d974e256
JJ
7012 else if (do_wide)
7013 {
7014 print_vma (section->sh_addr, LONG_HEX);
7015
7016 if ((long) section->sh_offset == section->sh_offset)
7017 printf (" %6.6lx", (unsigned long) section->sh_offset);
7018 else
7019 {
7020 putchar (' ');
7021 print_vma (section->sh_offset, LONG_HEX);
7022 }
7023
7024 if ((unsigned long) section->sh_size == section->sh_size)
7025 printf (" %6.6lx", (unsigned long) section->sh_size);
7026 else
7027 {
7028 putchar (' ');
7029 print_vma (section->sh_size, LONG_HEX);
7030 }
7031
7032 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7033 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7034 else
7035 {
7036 putchar (' ');
7037 print_vma (section->sh_entsize, LONG_HEX);
7038 }
7039
5477e8a0
L
7040 if (do_section_details)
7041 fputs (" ", stdout);
7042 else
dda8d76d 7043 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7044
72de5009 7045 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7046
7047 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7048 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7049 else
7050 {
7051 print_vma (section->sh_addralign, DEC);
7052 putchar ('\n');
7053 }
7054 }
5477e8a0 7055 else if (do_section_details)
595cf52e 7056 {
55cc53e9 7057 putchar (' ');
595cf52e
L
7058 print_vma (section->sh_addr, LONG_HEX);
7059 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7060 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7061 else
7062 {
7063 printf (" ");
7064 print_vma (section->sh_offset, LONG_HEX);
7065 }
72de5009 7066 printf (" %u\n ", section->sh_link);
595cf52e 7067 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7068 putchar (' ');
595cf52e
L
7069 print_vma (section->sh_entsize, LONG_HEX);
7070
72de5009
AM
7071 printf (" %-16u %lu\n",
7072 section->sh_info,
595cf52e
L
7073 (unsigned long) section->sh_addralign);
7074 }
f7a99963
NC
7075 else
7076 {
7077 putchar (' ');
7078 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7079 if ((long) section->sh_offset == section->sh_offset)
7080 printf (" %8.8lx", (unsigned long) section->sh_offset);
7081 else
7082 {
7083 printf (" ");
7084 print_vma (section->sh_offset, LONG_HEX);
7085 }
f7a99963
NC
7086 printf ("\n ");
7087 print_vma (section->sh_size, LONG_HEX);
7088 printf (" ");
7089 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7090
dda8d76d 7091 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7092
72de5009
AM
7093 printf (" %2u %3u %lu\n",
7094 section->sh_link,
7095 section->sh_info,
f7a99963
NC
7096 (unsigned long) section->sh_addralign);
7097 }
5477e8a0
L
7098
7099 if (do_section_details)
77115a4a 7100 {
dda8d76d 7101 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7102 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7103 {
7104 /* Minimum section size is 12 bytes for 32-bit compression
7105 header + 12 bytes for compressed data header. */
7106 unsigned char buf[24];
d8024a91 7107
77115a4a 7108 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7109 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7110 sizeof (buf), _("compression header")))
7111 {
7112 Elf_Internal_Chdr chdr;
d8024a91 7113
5844b465
NC
7114 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7115 printf (_(" [<corrupt>]\n"));
77115a4a 7116 else
5844b465
NC
7117 {
7118 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7119 printf (" ZLIB, ");
7120 else
7121 printf (_(" [<unknown>: 0x%x], "),
7122 chdr.ch_type);
7123 print_vma (chdr.ch_size, LONG_HEX);
7124 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7125 }
77115a4a
L
7126 }
7127 }
7128 }
252b5132
RH
7129 }
7130
5477e8a0 7131 if (!do_section_details)
3dbcc61d 7132 {
9fb71ee4
NC
7133 /* The ordering of the letters shown here matches the ordering of the
7134 corresponding SHF_xxx values, and hence the order in which these
7135 letters will be displayed to the user. */
7136 printf (_("Key to Flags:\n\
7137 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7138 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7139 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7140 switch (filedata->file_header.e_ident[EI_OSABI])
7141 {
7142 case ELFOSABI_GNU:
7143 case ELFOSABI_FREEBSD:
7144 printf (_("R (retain), "));
7145 /* Fall through */
7146 case ELFOSABI_NONE:
7147 printf (_("D (mbind), "));
7148 break;
7149 default:
7150 break;
7151 }
dda8d76d
NC
7152 if (filedata->file_header.e_machine == EM_X86_64
7153 || filedata->file_header.e_machine == EM_L1OM
7154 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7155 printf (_("l (large), "));
dda8d76d 7156 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7157 printf (_("y (purecode), "));
dda8d76d 7158 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7159 printf (_("v (VLE), "));
9fb71ee4 7160 printf ("p (processor specific)\n");
0b4362b0 7161 }
d1133906 7162
015dc7e1 7163 return true;
252b5132
RH
7164}
7165
015dc7e1 7166static bool
28d13567
AM
7167get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7168 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7169 char **strtab, unsigned long *strtablen)
7170{
7171 *strtab = NULL;
7172 *strtablen = 0;
7173 *symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms);
7174
7175 if (*symtab == NULL)
015dc7e1 7176 return false;
28d13567
AM
7177
7178 if (symsec->sh_link != 0)
7179 {
7180 Elf_Internal_Shdr *strsec;
7181
7182 if (symsec->sh_link >= filedata->file_header.e_shnum)
7183 {
7184 error (_("Bad sh_link in symbol table section\n"));
7185 free (*symtab);
7186 *symtab = NULL;
7187 *nsyms = 0;
015dc7e1 7188 return false;
28d13567
AM
7189 }
7190
7191 strsec = filedata->section_headers + symsec->sh_link;
7192
7193 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7194 1, strsec->sh_size, _("string table"));
7195 if (*strtab == NULL)
7196 {
7197 free (*symtab);
7198 *symtab = NULL;
7199 *nsyms = 0;
015dc7e1 7200 return false;
28d13567
AM
7201 }
7202 *strtablen = strsec->sh_size;
7203 }
015dc7e1 7204 return true;
28d13567
AM
7205}
7206
f5842774
L
7207static const char *
7208get_group_flags (unsigned int flags)
7209{
1449284b 7210 static char buff[128];
220453ec 7211
6d913794
NC
7212 if (flags == 0)
7213 return "";
7214 else if (flags == GRP_COMDAT)
7215 return "COMDAT ";
f5842774 7216
89246a0e
AM
7217 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7218 flags,
7219 flags & GRP_MASKOS ? _("<OS specific>") : "",
7220 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7221 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7222 ? _("<unknown>") : ""));
6d913794 7223
f5842774
L
7224 return buff;
7225}
7226
015dc7e1 7227static bool
dda8d76d 7228process_section_groups (Filedata * filedata)
f5842774 7229{
2cf0635d 7230 Elf_Internal_Shdr * section;
f5842774 7231 unsigned int i;
2cf0635d
NC
7232 struct group * group;
7233 Elf_Internal_Shdr * symtab_sec;
7234 Elf_Internal_Shdr * strtab_sec;
7235 Elf_Internal_Sym * symtab;
ba5cdace 7236 unsigned long num_syms;
2cf0635d 7237 char * strtab;
c256ffe7 7238 size_t strtab_size;
d1f5c6e3
L
7239
7240 /* Don't process section groups unless needed. */
7241 if (!do_unwind && !do_section_groups)
015dc7e1 7242 return true;
f5842774 7243
dda8d76d 7244 if (filedata->file_header.e_shnum == 0)
f5842774
L
7245 {
7246 if (do_section_groups)
ca0e11aa
NC
7247 {
7248 if (filedata->is_separate)
7249 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7250 filedata->file_name);
7251 else
7252 printf (_("\nThere are no section groups in this file.\n"));
7253 }
015dc7e1 7254 return true;
f5842774
L
7255 }
7256
dda8d76d 7257 if (filedata->section_headers == NULL)
f5842774
L
7258 {
7259 error (_("Section headers are not available!\n"));
fa1908fd 7260 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7261 return false;
f5842774
L
7262 }
7263
978c4450
AM
7264 filedata->section_headers_groups
7265 = (struct group **) calloc (filedata->file_header.e_shnum,
7266 sizeof (struct group *));
e4b17d5c 7267
978c4450 7268 if (filedata->section_headers_groups == NULL)
e4b17d5c 7269 {
8b73c356 7270 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7271 filedata->file_header.e_shnum);
015dc7e1 7272 return false;
e4b17d5c
L
7273 }
7274
f5842774 7275 /* Scan the sections for the group section. */
978c4450 7276 filedata->group_count = 0;
dda8d76d
NC
7277 for (i = 0, section = filedata->section_headers;
7278 i < filedata->file_header.e_shnum;
f5842774 7279 i++, section++)
e4b17d5c 7280 if (section->sh_type == SHT_GROUP)
978c4450 7281 filedata->group_count++;
e4b17d5c 7282
978c4450 7283 if (filedata->group_count == 0)
d1f5c6e3
L
7284 {
7285 if (do_section_groups)
ca0e11aa
NC
7286 {
7287 if (filedata->is_separate)
7288 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7289 filedata->file_name);
7290 else
7291 printf (_("\nThere are no section groups in this file.\n"));
7292 }
d1f5c6e3 7293
015dc7e1 7294 return true;
d1f5c6e3
L
7295 }
7296
978c4450
AM
7297 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7298 sizeof (struct group));
e4b17d5c 7299
978c4450 7300 if (filedata->section_groups == NULL)
e4b17d5c 7301 {
8b73c356 7302 error (_("Out of memory reading %lu groups\n"),
978c4450 7303 (unsigned long) filedata->group_count);
015dc7e1 7304 return false;
e4b17d5c
L
7305 }
7306
d1f5c6e3
L
7307 symtab_sec = NULL;
7308 strtab_sec = NULL;
7309 symtab = NULL;
ba5cdace 7310 num_syms = 0;
d1f5c6e3 7311 strtab = NULL;
c256ffe7 7312 strtab_size = 0;
ca0e11aa
NC
7313
7314 if (filedata->is_separate)
7315 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7316
978c4450 7317 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7318 i < filedata->file_header.e_shnum;
e4b17d5c 7319 i++, section++)
f5842774
L
7320 {
7321 if (section->sh_type == SHT_GROUP)
7322 {
dda8d76d 7323 const char * name = printable_section_name (filedata, section);
74e1a04b 7324 const char * group_name;
2cf0635d
NC
7325 unsigned char * start;
7326 unsigned char * indices;
f5842774 7327 unsigned int entry, j, size;
2cf0635d
NC
7328 Elf_Internal_Shdr * sec;
7329 Elf_Internal_Sym * sym;
f5842774
L
7330
7331 /* Get the symbol table. */
dda8d76d
NC
7332 if (section->sh_link >= filedata->file_header.e_shnum
7333 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7334 != SHT_SYMTAB))
f5842774
L
7335 {
7336 error (_("Bad sh_link in group section `%s'\n"), name);
7337 continue;
7338 }
d1f5c6e3
L
7339
7340 if (symtab_sec != sec)
7341 {
7342 symtab_sec = sec;
9db70fc3 7343 free (symtab);
dda8d76d 7344 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 7345 }
f5842774 7346
dd24e3da
NC
7347 if (symtab == NULL)
7348 {
7349 error (_("Corrupt header in group section `%s'\n"), name);
7350 continue;
7351 }
7352
ba5cdace
NC
7353 if (section->sh_info >= num_syms)
7354 {
7355 error (_("Bad sh_info in group section `%s'\n"), name);
7356 continue;
7357 }
7358
f5842774
L
7359 sym = symtab + section->sh_info;
7360
7361 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7362 {
4fbb74a6 7363 if (sym->st_shndx == 0
dda8d76d 7364 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7365 {
7366 error (_("Bad sh_info in group section `%s'\n"), name);
7367 continue;
7368 }
ba2685cc 7369
b9e920ec
AM
7370 group_name = SECTION_NAME_PRINT (filedata->section_headers
7371 + sym->st_shndx);
c256ffe7 7372 strtab_sec = NULL;
9db70fc3 7373 free (strtab);
f5842774 7374 strtab = NULL;
c256ffe7 7375 strtab_size = 0;
f5842774
L
7376 }
7377 else
7378 {
7379 /* Get the string table. */
dda8d76d 7380 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7381 {
7382 strtab_sec = NULL;
9db70fc3 7383 free (strtab);
c256ffe7
JJ
7384 strtab = NULL;
7385 strtab_size = 0;
7386 }
7387 else if (strtab_sec
dda8d76d 7388 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7389 {
7390 strtab_sec = sec;
9db70fc3 7391 free (strtab);
071436c6 7392
dda8d76d 7393 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7394 1, strtab_sec->sh_size,
7395 _("string table"));
c256ffe7 7396 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7397 }
c256ffe7 7398 group_name = sym->st_name < strtab_size
2b692964 7399 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7400 }
7401
c9c1d674
EG
7402 /* PR 17531: file: loop. */
7403 if (section->sh_entsize > section->sh_size)
7404 {
7405 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7406 printable_section_name (filedata, section),
8066deb1
AM
7407 (unsigned long) section->sh_entsize,
7408 (unsigned long) section->sh_size);
61dd8e19 7409 continue;
c9c1d674
EG
7410 }
7411
dda8d76d 7412 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7413 1, section->sh_size,
7414 _("section data"));
59245841
NC
7415 if (start == NULL)
7416 continue;
f5842774
L
7417
7418 indices = start;
7419 size = (section->sh_size / section->sh_entsize) - 1;
7420 entry = byte_get (indices, 4);
7421 indices += 4;
e4b17d5c
L
7422
7423 if (do_section_groups)
7424 {
2b692964 7425 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7426 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7427
e4b17d5c
L
7428 printf (_(" [Index] Name\n"));
7429 }
7430
7431 group->group_index = i;
7432
f5842774
L
7433 for (j = 0; j < size; j++)
7434 {
2cf0635d 7435 struct group_list * g;
e4b17d5c 7436
f5842774
L
7437 entry = byte_get (indices, 4);
7438 indices += 4;
7439
dda8d76d 7440 if (entry >= filedata->file_header.e_shnum)
391cb864 7441 {
57028622
NC
7442 static unsigned num_group_errors = 0;
7443
7444 if (num_group_errors ++ < 10)
7445 {
7446 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7447 entry, i, filedata->file_header.e_shnum - 1);
57028622 7448 if (num_group_errors == 10)
67ce483b 7449 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7450 }
391cb864
L
7451 continue;
7452 }
391cb864 7453
978c4450 7454 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7455 {
d1f5c6e3
L
7456 if (entry)
7457 {
57028622
NC
7458 static unsigned num_errs = 0;
7459
7460 if (num_errs ++ < 10)
7461 {
7462 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7463 entry, i,
978c4450 7464 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7465 if (num_errs == 10)
7466 warn (_("Further error messages about already contained group sections suppressed\n"));
7467 }
d1f5c6e3
L
7468 continue;
7469 }
7470 else
7471 {
7472 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7473 section group. We just warn it the first time
d1f5c6e3 7474 and ignore it afterwards. */
015dc7e1 7475 static bool warned = false;
d1f5c6e3
L
7476 if (!warned)
7477 {
7478 error (_("section 0 in group section [%5u]\n"),
978c4450 7479 filedata->section_headers_groups [entry]->group_index);
015dc7e1 7480 warned = true;
d1f5c6e3
L
7481 }
7482 }
e4b17d5c
L
7483 }
7484
978c4450 7485 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7486
7487 if (do_section_groups)
7488 {
dda8d76d
NC
7489 sec = filedata->section_headers + entry;
7490 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7491 }
7492
3f5e193b 7493 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7494 g->section_index = entry;
7495 g->next = group->root;
7496 group->root = g;
f5842774
L
7497 }
7498
9db70fc3 7499 free (start);
e4b17d5c
L
7500
7501 group++;
f5842774
L
7502 }
7503 }
7504
9db70fc3
AM
7505 free (symtab);
7506 free (strtab);
015dc7e1 7507 return true;
f5842774
L
7508}
7509
28f997cf
TG
7510/* Data used to display dynamic fixups. */
7511
7512struct ia64_vms_dynfixup
7513{
7514 bfd_vma needed_ident; /* Library ident number. */
7515 bfd_vma needed; /* Index in the dstrtab of the library name. */
7516 bfd_vma fixup_needed; /* Index of the library. */
7517 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7518 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7519};
7520
7521/* Data used to display dynamic relocations. */
7522
7523struct ia64_vms_dynimgrela
7524{
7525 bfd_vma img_rela_cnt; /* Number of relocations. */
7526 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7527};
7528
7529/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7530 library). */
7531
015dc7e1 7532static bool
dda8d76d
NC
7533dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7534 struct ia64_vms_dynfixup * fixup,
7535 const char * strtab,
7536 unsigned int strtab_sz)
28f997cf 7537{
32ec8896 7538 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7539 long i;
32ec8896 7540 const char * lib_name;
28f997cf 7541
978c4450
AM
7542 imfs = get_data (NULL, filedata,
7543 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7544 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7545 _("dynamic section image fixups"));
7546 if (!imfs)
015dc7e1 7547 return false;
28f997cf
TG
7548
7549 if (fixup->needed < strtab_sz)
7550 lib_name = strtab + fixup->needed;
7551 else
7552 {
32ec8896 7553 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7554 (unsigned long) fixup->needed);
28f997cf
TG
7555 lib_name = "???";
7556 }
736990c4 7557
28f997cf
TG
7558 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7559 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7560 printf
7561 (_("Seg Offset Type SymVec DataType\n"));
7562
7563 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7564 {
7565 unsigned int type;
7566 const char *rtype;
7567
7568 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7569 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7570 type = BYTE_GET (imfs [i].type);
7571 rtype = elf_ia64_reloc_type (type);
7572 if (rtype == NULL)
7573 printf (" 0x%08x ", type);
7574 else
7575 printf (" %-32s ", rtype);
7576 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7577 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7578 }
7579
7580 free (imfs);
015dc7e1 7581 return true;
28f997cf
TG
7582}
7583
7584/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7585
015dc7e1 7586static bool
dda8d76d 7587dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7588{
7589 Elf64_External_VMS_IMAGE_RELA *imrs;
7590 long i;
7591
978c4450
AM
7592 imrs = get_data (NULL, filedata,
7593 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 7594 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7595 _("dynamic section image relocations"));
28f997cf 7596 if (!imrs)
015dc7e1 7597 return false;
28f997cf
TG
7598
7599 printf (_("\nImage relocs\n"));
7600 printf
7601 (_("Seg Offset Type Addend Seg Sym Off\n"));
7602
7603 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7604 {
7605 unsigned int type;
7606 const char *rtype;
7607
7608 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7609 printf ("%08" BFD_VMA_FMT "x ",
7610 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7611 type = BYTE_GET (imrs [i].type);
7612 rtype = elf_ia64_reloc_type (type);
7613 if (rtype == NULL)
7614 printf ("0x%08x ", type);
7615 else
7616 printf ("%-31s ", rtype);
7617 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7618 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7619 printf ("%08" BFD_VMA_FMT "x\n",
7620 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7621 }
7622
7623 free (imrs);
015dc7e1 7624 return true;
28f997cf
TG
7625}
7626
7627/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7628
015dc7e1 7629static bool
dda8d76d 7630process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7631{
7632 struct ia64_vms_dynfixup fixup;
7633 struct ia64_vms_dynimgrela imgrela;
7634 Elf_Internal_Dyn *entry;
28f997cf
TG
7635 bfd_vma strtab_off = 0;
7636 bfd_vma strtab_sz = 0;
7637 char *strtab = NULL;
015dc7e1 7638 bool res = true;
28f997cf
TG
7639
7640 memset (&fixup, 0, sizeof (fixup));
7641 memset (&imgrela, 0, sizeof (imgrela));
7642
7643 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
7644 for (entry = filedata->dynamic_section;
7645 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
7646 entry++)
7647 {
7648 switch (entry->d_tag)
7649 {
7650 case DT_IA_64_VMS_STRTAB_OFFSET:
7651 strtab_off = entry->d_un.d_val;
7652 break;
7653 case DT_STRSZ:
7654 strtab_sz = entry->d_un.d_val;
7655 if (strtab == NULL)
978c4450
AM
7656 strtab = get_data (NULL, filedata,
7657 filedata->dynamic_addr + strtab_off,
28f997cf 7658 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7659 if (strtab == NULL)
7660 strtab_sz = 0;
28f997cf
TG
7661 break;
7662
7663 case DT_IA_64_VMS_NEEDED_IDENT:
7664 fixup.needed_ident = entry->d_un.d_val;
7665 break;
7666 case DT_NEEDED:
7667 fixup.needed = entry->d_un.d_val;
7668 break;
7669 case DT_IA_64_VMS_FIXUP_NEEDED:
7670 fixup.fixup_needed = entry->d_un.d_val;
7671 break;
7672 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7673 fixup.fixup_rela_cnt = entry->d_un.d_val;
7674 break;
7675 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7676 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7677 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 7678 res = false;
28f997cf 7679 break;
28f997cf
TG
7680 case DT_IA_64_VMS_IMG_RELA_CNT:
7681 imgrela.img_rela_cnt = entry->d_un.d_val;
7682 break;
7683 case DT_IA_64_VMS_IMG_RELA_OFF:
7684 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7685 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 7686 res = false;
28f997cf
TG
7687 break;
7688
7689 default:
7690 break;
7691 }
7692 }
7693
9db70fc3 7694 free (strtab);
28f997cf
TG
7695
7696 return res;
7697}
7698
85b1c36d 7699static struct
566b0d53 7700{
2cf0635d 7701 const char * name;
566b0d53
L
7702 int reloc;
7703 int size;
7704 int rela;
32ec8896
NC
7705}
7706 dynamic_relocations [] =
566b0d53 7707{
015dc7e1
AM
7708 { "REL", DT_REL, DT_RELSZ, false },
7709 { "RELA", DT_RELA, DT_RELASZ, true },
32ec8896 7710 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7711};
7712
252b5132 7713/* Process the reloc section. */
18bd398b 7714
015dc7e1 7715static bool
dda8d76d 7716process_relocs (Filedata * filedata)
252b5132 7717{
b34976b6
AM
7718 unsigned long rel_size;
7719 unsigned long rel_offset;
252b5132 7720
252b5132 7721 if (!do_reloc)
015dc7e1 7722 return true;
252b5132
RH
7723
7724 if (do_using_dynamic)
7725 {
32ec8896 7726 int is_rela;
2cf0635d 7727 const char * name;
015dc7e1 7728 bool has_dynamic_reloc;
566b0d53 7729 unsigned int i;
0de14b54 7730
015dc7e1 7731 has_dynamic_reloc = false;
252b5132 7732
566b0d53 7733 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7734 {
566b0d53
L
7735 is_rela = dynamic_relocations [i].rela;
7736 name = dynamic_relocations [i].name;
978c4450
AM
7737 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
7738 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 7739
32ec8896 7740 if (rel_size)
015dc7e1 7741 has_dynamic_reloc = true;
566b0d53
L
7742
7743 if (is_rela == UNKNOWN)
aa903cfb 7744 {
566b0d53 7745 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 7746 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
7747 {
7748 case DT_REL:
015dc7e1 7749 is_rela = false;
566b0d53
L
7750 break;
7751 case DT_RELA:
015dc7e1 7752 is_rela = true;
566b0d53
L
7753 break;
7754 }
aa903cfb 7755 }
252b5132 7756
566b0d53
L
7757 if (rel_size)
7758 {
ca0e11aa
NC
7759 if (filedata->is_separate)
7760 printf
7761 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
7762 filedata->file_name, name, rel_offset, rel_size);
7763 else
7764 printf
7765 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7766 name, rel_offset, rel_size);
252b5132 7767
dda8d76d
NC
7768 dump_relocations (filedata,
7769 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7770 rel_size,
978c4450
AM
7771 filedata->dynamic_symbols,
7772 filedata->num_dynamic_syms,
7773 filedata->dynamic_strings,
7774 filedata->dynamic_strings_length,
015dc7e1 7775 is_rela, true /* is_dynamic */);
566b0d53 7776 }
252b5132 7777 }
566b0d53 7778
dda8d76d
NC
7779 if (is_ia64_vms (filedata))
7780 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 7781 has_dynamic_reloc = true;
28f997cf 7782
566b0d53 7783 if (! has_dynamic_reloc)
ca0e11aa
NC
7784 {
7785 if (filedata->is_separate)
7786 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
7787 filedata->file_name);
7788 else
7789 printf (_("\nThere are no dynamic relocations in this file.\n"));
7790 }
252b5132
RH
7791 }
7792 else
7793 {
2cf0635d 7794 Elf_Internal_Shdr * section;
b34976b6 7795 unsigned long i;
015dc7e1 7796 bool found = false;
252b5132 7797
dda8d76d
NC
7798 for (i = 0, section = filedata->section_headers;
7799 i < filedata->file_header.e_shnum;
b34976b6 7800 i++, section++)
252b5132
RH
7801 {
7802 if ( section->sh_type != SHT_RELA
7803 && section->sh_type != SHT_REL)
7804 continue;
7805
7806 rel_offset = section->sh_offset;
7807 rel_size = section->sh_size;
7808
7809 if (rel_size)
7810 {
b34976b6 7811 int is_rela;
d3a49aa8 7812 unsigned long num_rela;
103f02d3 7813
ca0e11aa
NC
7814 if (filedata->is_separate)
7815 printf (_("\nIn linked file '%s' relocation section "),
7816 filedata->file_name);
7817 else
7818 printf (_("\nRelocation section "));
252b5132 7819
dda8d76d 7820 if (filedata->string_table == NULL)
19936277 7821 printf ("%d", section->sh_name);
252b5132 7822 else
dda8d76d 7823 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7824
d3a49aa8
AM
7825 num_rela = rel_size / section->sh_entsize;
7826 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7827 " at offset 0x%lx contains %lu entries:\n",
7828 num_rela),
7829 rel_offset, num_rela);
252b5132 7830
d79b3d50
NC
7831 is_rela = section->sh_type == SHT_RELA;
7832
4fbb74a6 7833 if (section->sh_link != 0
dda8d76d 7834 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7835 {
2cf0635d
NC
7836 Elf_Internal_Shdr * symsec;
7837 Elf_Internal_Sym * symtab;
d79b3d50 7838 unsigned long nsyms;
c256ffe7 7839 unsigned long strtablen = 0;
2cf0635d 7840 char * strtab = NULL;
57346661 7841
dda8d76d 7842 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7843 if (symsec->sh_type != SHT_SYMTAB
7844 && symsec->sh_type != SHT_DYNSYM)
7845 continue;
7846
28d13567
AM
7847 if (!get_symtab (filedata, symsec,
7848 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7849 continue;
252b5132 7850
dda8d76d 7851 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7852 symtab, nsyms, strtab, strtablen,
7853 is_rela,
7854 symsec->sh_type == SHT_DYNSYM);
9db70fc3 7855 free (strtab);
d79b3d50
NC
7856 free (symtab);
7857 }
7858 else
dda8d76d 7859 dump_relocations (filedata, rel_offset, rel_size,
32ec8896 7860 NULL, 0, NULL, 0, is_rela,
015dc7e1 7861 false /* is_dynamic */);
252b5132 7862
015dc7e1 7863 found = true;
252b5132
RH
7864 }
7865 }
7866
7867 if (! found)
45ac8f4f
NC
7868 {
7869 /* Users sometimes forget the -D option, so try to be helpful. */
7870 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7871 {
978c4450 7872 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 7873 {
ca0e11aa
NC
7874 if (filedata->is_separate)
7875 printf (_("\nThere are no static relocations in linked file '%s'."),
7876 filedata->file_name);
7877 else
7878 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
7879 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7880
7881 break;
7882 }
7883 }
7884 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
7885 {
7886 if (filedata->is_separate)
7887 printf (_("\nThere are no relocations in linked file '%s'.\n"),
7888 filedata->file_name);
7889 else
7890 printf (_("\nThere are no relocations in this file.\n"));
7891 }
45ac8f4f 7892 }
252b5132
RH
7893 }
7894
015dc7e1 7895 return true;
252b5132
RH
7896}
7897
4d6ed7c8
NC
7898/* An absolute address consists of a section and an offset. If the
7899 section is NULL, the offset itself is the address, otherwise, the
7900 address equals to LOAD_ADDRESS(section) + offset. */
7901
7902struct absaddr
948f632f
DA
7903{
7904 unsigned short section;
7905 bfd_vma offset;
7906};
4d6ed7c8 7907
948f632f
DA
7908/* Find the nearest symbol at or below ADDR. Returns the symbol
7909 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7910
4d6ed7c8 7911static void
dda8d76d
NC
7912find_symbol_for_address (Filedata * filedata,
7913 Elf_Internal_Sym * symtab,
7914 unsigned long nsyms,
7915 const char * strtab,
7916 unsigned long strtab_size,
7917 struct absaddr addr,
7918 const char ** symname,
7919 bfd_vma * offset)
4d6ed7c8 7920{
d3ba0551 7921 bfd_vma dist = 0x100000;
2cf0635d 7922 Elf_Internal_Sym * sym;
948f632f
DA
7923 Elf_Internal_Sym * beg;
7924 Elf_Internal_Sym * end;
2cf0635d 7925 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7926
0b6ae522 7927 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7928 beg = symtab;
7929 end = symtab + nsyms;
0b6ae522 7930
948f632f 7931 while (beg < end)
4d6ed7c8 7932 {
948f632f
DA
7933 bfd_vma value;
7934
7935 sym = beg + (end - beg) / 2;
0b6ae522 7936
948f632f 7937 value = sym->st_value;
0b6ae522
DJ
7938 REMOVE_ARCH_BITS (value);
7939
948f632f 7940 if (sym->st_name != 0
4d6ed7c8 7941 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7942 && addr.offset >= value
7943 && addr.offset - value < dist)
4d6ed7c8
NC
7944 {
7945 best = sym;
0b6ae522 7946 dist = addr.offset - value;
4d6ed7c8
NC
7947 if (!dist)
7948 break;
7949 }
948f632f
DA
7950
7951 if (addr.offset < value)
7952 end = sym;
7953 else
7954 beg = sym + 1;
4d6ed7c8 7955 }
1b31d05e 7956
4d6ed7c8
NC
7957 if (best)
7958 {
57346661 7959 *symname = (best->st_name >= strtab_size
2b692964 7960 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7961 *offset = dist;
7962 return;
7963 }
1b31d05e 7964
4d6ed7c8
NC
7965 *symname = NULL;
7966 *offset = addr.offset;
7967}
7968
32ec8896 7969static /* signed */ int
948f632f
DA
7970symcmp (const void *p, const void *q)
7971{
7972 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7973 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7974
7975 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7976}
7977
7978/* Process the unwind section. */
7979
7980#include "unwind-ia64.h"
7981
7982struct ia64_unw_table_entry
7983{
7984 struct absaddr start;
7985 struct absaddr end;
7986 struct absaddr info;
7987};
7988
7989struct ia64_unw_aux_info
7990{
32ec8896
NC
7991 struct ia64_unw_table_entry * table; /* Unwind table. */
7992 unsigned long table_len; /* Length of unwind table. */
7993 unsigned char * info; /* Unwind info. */
7994 unsigned long info_size; /* Size of unwind info. */
7995 bfd_vma info_addr; /* Starting address of unwind info. */
7996 bfd_vma seg_base; /* Starting address of segment. */
7997 Elf_Internal_Sym * symtab; /* The symbol table. */
7998 unsigned long nsyms; /* Number of symbols. */
7999 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8000 unsigned long nfuns; /* Number of entries in funtab. */
8001 char * strtab; /* The string table. */
8002 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
8003};
8004
015dc7e1 8005static bool
dda8d76d 8006dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8007{
2cf0635d 8008 struct ia64_unw_table_entry * tp;
948f632f 8009 unsigned long j, nfuns;
4d6ed7c8 8010 int in_body;
015dc7e1 8011 bool res = true;
7036c0e1 8012
948f632f
DA
8013 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8014 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8015 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8016 aux->funtab[nfuns++] = aux->symtab[j];
8017 aux->nfuns = nfuns;
8018 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8019
4d6ed7c8
NC
8020 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8021 {
8022 bfd_vma stamp;
8023 bfd_vma offset;
2cf0635d
NC
8024 const unsigned char * dp;
8025 const unsigned char * head;
53774b7e 8026 const unsigned char * end;
2cf0635d 8027 const char * procname;
4d6ed7c8 8028
dda8d76d 8029 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8030 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8031
8032 fputs ("\n<", stdout);
8033
8034 if (procname)
8035 {
8036 fputs (procname, stdout);
8037
8038 if (offset)
8039 printf ("+%lx", (unsigned long) offset);
8040 }
8041
8042 fputs (">: [", stdout);
8043 print_vma (tp->start.offset, PREFIX_HEX);
8044 fputc ('-', stdout);
8045 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 8046 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
8047 (unsigned long) (tp->info.offset - aux->seg_base));
8048
53774b7e
NC
8049 /* PR 17531: file: 86232b32. */
8050 if (aux->info == NULL)
8051 continue;
8052
97c0a079
AM
8053 offset = tp->info.offset;
8054 if (tp->info.section)
8055 {
8056 if (tp->info.section >= filedata->file_header.e_shnum)
8057 {
8058 warn (_("Invalid section %u in table entry %ld\n"),
8059 tp->info.section, (long) (tp - aux->table));
015dc7e1 8060 res = false;
97c0a079
AM
8061 continue;
8062 }
8063 offset += filedata->section_headers[tp->info.section].sh_addr;
8064 }
8065 offset -= aux->info_addr;
53774b7e 8066 /* PR 17531: file: 0997b4d1. */
90679903
AM
8067 if (offset >= aux->info_size
8068 || aux->info_size - offset < 8)
53774b7e
NC
8069 {
8070 warn (_("Invalid offset %lx in table entry %ld\n"),
8071 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8072 res = false;
53774b7e
NC
8073 continue;
8074 }
8075
97c0a079 8076 head = aux->info + offset;
a4a00738 8077 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8078
86f55779 8079 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8080 (unsigned) UNW_VER (stamp),
8081 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8082 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8083 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8084 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8085
8086 if (UNW_VER (stamp) != 1)
8087 {
2b692964 8088 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8089 continue;
8090 }
8091
8092 in_body = 0;
53774b7e
NC
8093 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8094 /* PR 17531: file: 16ceda89. */
8095 if (end > aux->info + aux->info_size)
8096 end = aux->info + aux->info_size;
8097 for (dp = head + 8; dp < end;)
b4477bc8 8098 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8099 }
948f632f
DA
8100
8101 free (aux->funtab);
32ec8896
NC
8102
8103 return res;
4d6ed7c8
NC
8104}
8105
015dc7e1 8106static bool
dda8d76d
NC
8107slurp_ia64_unwind_table (Filedata * filedata,
8108 struct ia64_unw_aux_info * aux,
8109 Elf_Internal_Shdr * sec)
4d6ed7c8 8110{
89fac5e3 8111 unsigned long size, nrelas, i;
2cf0635d
NC
8112 Elf_Internal_Phdr * seg;
8113 struct ia64_unw_table_entry * tep;
8114 Elf_Internal_Shdr * relsec;
8115 Elf_Internal_Rela * rela;
8116 Elf_Internal_Rela * rp;
8117 unsigned char * table;
8118 unsigned char * tp;
8119 Elf_Internal_Sym * sym;
8120 const char * relname;
4d6ed7c8 8121
53774b7e
NC
8122 aux->table_len = 0;
8123
4d6ed7c8
NC
8124 /* First, find the starting address of the segment that includes
8125 this section: */
8126
dda8d76d 8127 if (filedata->file_header.e_phnum)
4d6ed7c8 8128 {
dda8d76d 8129 if (! get_program_headers (filedata))
015dc7e1 8130 return false;
4d6ed7c8 8131
dda8d76d
NC
8132 for (seg = filedata->program_headers;
8133 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8134 ++seg)
4d6ed7c8
NC
8135 {
8136 if (seg->p_type != PT_LOAD)
8137 continue;
8138
8139 if (sec->sh_addr >= seg->p_vaddr
8140 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8141 {
8142 aux->seg_base = seg->p_vaddr;
8143 break;
8144 }
8145 }
4d6ed7c8
NC
8146 }
8147
8148 /* Second, build the unwind table from the contents of the unwind section: */
8149 size = sec->sh_size;
dda8d76d 8150 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8151 _("unwind table"));
a6e9f9df 8152 if (!table)
015dc7e1 8153 return false;
4d6ed7c8 8154
53774b7e 8155 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8156 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8157 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8158 tep = aux->table;
53774b7e
NC
8159
8160 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8161 {
8162 tep->start.section = SHN_UNDEF;
8163 tep->end.section = SHN_UNDEF;
8164 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8165 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8166 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8167 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8168 tep->start.offset += aux->seg_base;
8169 tep->end.offset += aux->seg_base;
8170 tep->info.offset += aux->seg_base;
8171 }
8172 free (table);
8173
41e92641 8174 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8175 for (relsec = filedata->section_headers;
8176 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8177 ++relsec)
8178 {
8179 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8180 || relsec->sh_info >= filedata->file_header.e_shnum
8181 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8182 continue;
8183
dda8d76d 8184 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8185 & rela, & nrelas))
53774b7e
NC
8186 {
8187 free (aux->table);
8188 aux->table = NULL;
8189 aux->table_len = 0;
015dc7e1 8190 return false;
53774b7e 8191 }
4d6ed7c8
NC
8192
8193 for (rp = rela; rp < rela + nrelas; ++rp)
8194 {
4770fb94 8195 unsigned int sym_ndx;
726bd37d
AM
8196 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8197 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8198
82b1b41b
NC
8199 /* PR 17531: file: 9fa67536. */
8200 if (relname == NULL)
8201 {
726bd37d 8202 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8203 continue;
8204 }
948f632f 8205
24d127aa 8206 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8207 {
82b1b41b 8208 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8209 continue;
8210 }
8211
89fac5e3 8212 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8213
53774b7e
NC
8214 /* PR 17531: file: 5bc8d9bf. */
8215 if (i >= aux->table_len)
8216 {
8217 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8218 continue;
8219 }
8220
4770fb94
AM
8221 sym_ndx = get_reloc_symindex (rp->r_info);
8222 if (sym_ndx >= aux->nsyms)
8223 {
8224 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8225 sym_ndx);
8226 continue;
8227 }
8228 sym = aux->symtab + sym_ndx;
8229
53774b7e 8230 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8231 {
8232 case 0:
8233 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8234 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8235 break;
8236 case 1:
8237 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8238 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8239 break;
8240 case 2:
8241 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8242 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8243 break;
8244 default:
8245 break;
8246 }
8247 }
8248
8249 free (rela);
8250 }
8251
015dc7e1 8252 return true;
4d6ed7c8
NC
8253}
8254
015dc7e1 8255static bool
dda8d76d 8256ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8257{
2cf0635d
NC
8258 Elf_Internal_Shdr * sec;
8259 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8260 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8261 struct ia64_unw_aux_info aux;
015dc7e1 8262 bool res = true;
f1467e33 8263
4d6ed7c8
NC
8264 memset (& aux, 0, sizeof (aux));
8265
dda8d76d 8266 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8267 {
28d13567 8268 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8269 {
28d13567 8270 if (aux.symtab)
4082ef84 8271 {
28d13567
AM
8272 error (_("Multiple symbol tables encountered\n"));
8273 free (aux.symtab);
8274 aux.symtab = NULL;
4082ef84 8275 free (aux.strtab);
28d13567 8276 aux.strtab = NULL;
4082ef84 8277 }
28d13567
AM
8278 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8279 &aux.strtab, &aux.strtab_size))
015dc7e1 8280 return false;
4d6ed7c8
NC
8281 }
8282 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8283 unwcount++;
8284 }
8285
8286 if (!unwcount)
8287 printf (_("\nThere are no unwind sections in this file.\n"));
8288
8289 while (unwcount-- > 0)
8290 {
2cf0635d 8291 char * suffix;
579f31ac
JJ
8292 size_t len, len2;
8293
dda8d76d
NC
8294 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8295 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8296 if (sec->sh_type == SHT_IA_64_UNWIND)
8297 {
8298 unwsec = sec;
8299 break;
8300 }
4082ef84
NC
8301 /* We have already counted the number of SHT_IA64_UNWIND
8302 sections so the loop above should never fail. */
8303 assert (unwsec != NULL);
579f31ac
JJ
8304
8305 unwstart = i + 1;
8306 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8307
e4b17d5c
L
8308 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8309 {
8310 /* We need to find which section group it is in. */
4082ef84 8311 struct group_list * g;
e4b17d5c 8312
978c4450
AM
8313 if (filedata->section_headers_groups == NULL
8314 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8315 i = filedata->file_header.e_shnum;
4082ef84 8316 else
e4b17d5c 8317 {
978c4450 8318 g = filedata->section_headers_groups[i]->root;
18bd398b 8319
4082ef84
NC
8320 for (; g != NULL; g = g->next)
8321 {
dda8d76d 8322 sec = filedata->section_headers + g->section_index;
e4b17d5c 8323
b9e920ec
AM
8324 if (SECTION_NAME_VALID (sec)
8325 && streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
4082ef84
NC
8326 break;
8327 }
8328
8329 if (g == NULL)
dda8d76d 8330 i = filedata->file_header.e_shnum;
4082ef84 8331 }
e4b17d5c 8332 }
b9e920ec 8333 else if (SECTION_NAME_VALID (unwsec)
e9b095a5
ML
8334 && startswith (SECTION_NAME (unwsec),
8335 ELF_STRING_ia64_unwind_once))
579f31ac 8336 {
18bd398b 8337 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
8338 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
8339 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8340 for (i = 0, sec = filedata->section_headers;
8341 i < filedata->file_header.e_shnum;
579f31ac 8342 ++i, ++sec)
b9e920ec 8343 if (SECTION_NAME_VALID (sec)
e9b095a5
ML
8344 && startswith (SECTION_NAME (sec),
8345 ELF_STRING_ia64_unwind_info_once)
18bd398b 8346 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8347 break;
8348 }
8349 else
8350 {
8351 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8352 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8353 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8354 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8355 suffix = "";
b9e920ec 8356 if (SECTION_NAME_VALID (unwsec)
e9b095a5 8357 && startswith (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind))
579f31ac 8358 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8359 for (i = 0, sec = filedata->section_headers;
8360 i < filedata->file_header.e_shnum;
579f31ac 8361 ++i, ++sec)
b9e920ec 8362 if (SECTION_NAME_VALID (sec)
e9b095a5 8363 && startswith (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info)
18bd398b 8364 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8365 break;
8366 }
8367
dda8d76d 8368 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8369 {
8370 printf (_("\nCould not find unwind info section for "));
8371
dda8d76d 8372 if (filedata->string_table == NULL)
579f31ac
JJ
8373 printf ("%d", unwsec->sh_name);
8374 else
dda8d76d 8375 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8376 }
8377 else
4d6ed7c8 8378 {
4d6ed7c8 8379 aux.info_addr = sec->sh_addr;
dda8d76d 8380 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8381 sec->sh_size,
8382 _("unwind info"));
59245841 8383 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8384
579f31ac 8385 printf (_("\nUnwind section "));
4d6ed7c8 8386
dda8d76d 8387 if (filedata->string_table == NULL)
579f31ac
JJ
8388 printf ("%d", unwsec->sh_name);
8389 else
dda8d76d 8390 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8391
579f31ac 8392 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8393 (unsigned long) unwsec->sh_offset,
89fac5e3 8394 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8395
dda8d76d 8396 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8397 && aux.table_len > 0)
dda8d76d 8398 dump_ia64_unwind (filedata, & aux);
579f31ac 8399
9db70fc3
AM
8400 free ((char *) aux.table);
8401 free ((char *) aux.info);
579f31ac
JJ
8402 aux.table = NULL;
8403 aux.info = NULL;
8404 }
4d6ed7c8 8405 }
4d6ed7c8 8406
9db70fc3
AM
8407 free (aux.symtab);
8408 free ((char *) aux.strtab);
32ec8896
NC
8409
8410 return res;
4d6ed7c8
NC
8411}
8412
3f5e193b 8413struct hppa_unw_table_entry
32ec8896
NC
8414{
8415 struct absaddr start;
8416 struct absaddr end;
8417 unsigned int Cannot_unwind:1; /* 0 */
8418 unsigned int Millicode:1; /* 1 */
8419 unsigned int Millicode_save_sr0:1; /* 2 */
8420 unsigned int Region_description:2; /* 3..4 */
8421 unsigned int reserved1:1; /* 5 */
8422 unsigned int Entry_SR:1; /* 6 */
8423 unsigned int Entry_FR:4; /* Number saved 7..10 */
8424 unsigned int Entry_GR:5; /* Number saved 11..15 */
8425 unsigned int Args_stored:1; /* 16 */
8426 unsigned int Variable_Frame:1; /* 17 */
8427 unsigned int Separate_Package_Body:1; /* 18 */
8428 unsigned int Frame_Extension_Millicode:1; /* 19 */
8429 unsigned int Stack_Overflow_Check:1; /* 20 */
8430 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8431 unsigned int Ada_Region:1; /* 22 */
8432 unsigned int cxx_info:1; /* 23 */
8433 unsigned int cxx_try_catch:1; /* 24 */
8434 unsigned int sched_entry_seq:1; /* 25 */
8435 unsigned int reserved2:1; /* 26 */
8436 unsigned int Save_SP:1; /* 27 */
8437 unsigned int Save_RP:1; /* 28 */
8438 unsigned int Save_MRP_in_frame:1; /* 29 */
8439 unsigned int extn_ptr_defined:1; /* 30 */
8440 unsigned int Cleanup_defined:1; /* 31 */
8441
8442 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8443 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8444 unsigned int Large_frame:1; /* 2 */
8445 unsigned int Pseudo_SP_Set:1; /* 3 */
8446 unsigned int reserved4:1; /* 4 */
8447 unsigned int Total_frame_size:27; /* 5..31 */
8448};
3f5e193b 8449
57346661 8450struct hppa_unw_aux_info
948f632f 8451{
32ec8896
NC
8452 struct hppa_unw_table_entry * table; /* Unwind table. */
8453 unsigned long table_len; /* Length of unwind table. */
8454 bfd_vma seg_base; /* Starting address of segment. */
8455 Elf_Internal_Sym * symtab; /* The symbol table. */
8456 unsigned long nsyms; /* Number of symbols. */
8457 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8458 unsigned long nfuns; /* Number of entries in funtab. */
8459 char * strtab; /* The string table. */
8460 unsigned long strtab_size; /* Size of string table. */
948f632f 8461};
57346661 8462
015dc7e1 8463static bool
dda8d76d 8464dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8465{
2cf0635d 8466 struct hppa_unw_table_entry * tp;
948f632f 8467 unsigned long j, nfuns;
015dc7e1 8468 bool res = true;
948f632f
DA
8469
8470 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8471 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8472 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8473 aux->funtab[nfuns++] = aux->symtab[j];
8474 aux->nfuns = nfuns;
8475 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8476
57346661
AM
8477 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8478 {
8479 bfd_vma offset;
2cf0635d 8480 const char * procname;
57346661 8481
dda8d76d 8482 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8483 aux->strtab_size, tp->start, &procname,
8484 &offset);
8485
8486 fputs ("\n<", stdout);
8487
8488 if (procname)
8489 {
8490 fputs (procname, stdout);
8491
8492 if (offset)
8493 printf ("+%lx", (unsigned long) offset);
8494 }
8495
8496 fputs (">: [", stdout);
8497 print_vma (tp->start.offset, PREFIX_HEX);
8498 fputc ('-', stdout);
8499 print_vma (tp->end.offset, PREFIX_HEX);
8500 printf ("]\n\t");
8501
18bd398b
NC
8502#define PF(_m) if (tp->_m) printf (#_m " ");
8503#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8504 PF(Cannot_unwind);
8505 PF(Millicode);
8506 PF(Millicode_save_sr0);
18bd398b 8507 /* PV(Region_description); */
57346661
AM
8508 PF(Entry_SR);
8509 PV(Entry_FR);
8510 PV(Entry_GR);
8511 PF(Args_stored);
8512 PF(Variable_Frame);
8513 PF(Separate_Package_Body);
8514 PF(Frame_Extension_Millicode);
8515 PF(Stack_Overflow_Check);
8516 PF(Two_Instruction_SP_Increment);
8517 PF(Ada_Region);
8518 PF(cxx_info);
8519 PF(cxx_try_catch);
8520 PF(sched_entry_seq);
8521 PF(Save_SP);
8522 PF(Save_RP);
8523 PF(Save_MRP_in_frame);
8524 PF(extn_ptr_defined);
8525 PF(Cleanup_defined);
8526 PF(MPE_XL_interrupt_marker);
8527 PF(HP_UX_interrupt_marker);
8528 PF(Large_frame);
8529 PF(Pseudo_SP_Set);
8530 PV(Total_frame_size);
8531#undef PF
8532#undef PV
8533 }
8534
18bd398b 8535 printf ("\n");
948f632f
DA
8536
8537 free (aux->funtab);
32ec8896
NC
8538
8539 return res;
57346661
AM
8540}
8541
015dc7e1 8542static bool
dda8d76d
NC
8543slurp_hppa_unwind_table (Filedata * filedata,
8544 struct hppa_unw_aux_info * aux,
8545 Elf_Internal_Shdr * sec)
57346661 8546{
1c0751b2 8547 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8548 Elf_Internal_Phdr * seg;
8549 struct hppa_unw_table_entry * tep;
8550 Elf_Internal_Shdr * relsec;
8551 Elf_Internal_Rela * rela;
8552 Elf_Internal_Rela * rp;
8553 unsigned char * table;
8554 unsigned char * tp;
8555 Elf_Internal_Sym * sym;
8556 const char * relname;
57346661 8557
57346661
AM
8558 /* First, find the starting address of the segment that includes
8559 this section. */
dda8d76d 8560 if (filedata->file_header.e_phnum)
57346661 8561 {
dda8d76d 8562 if (! get_program_headers (filedata))
015dc7e1 8563 return false;
57346661 8564
dda8d76d
NC
8565 for (seg = filedata->program_headers;
8566 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8567 ++seg)
8568 {
8569 if (seg->p_type != PT_LOAD)
8570 continue;
8571
8572 if (sec->sh_addr >= seg->p_vaddr
8573 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8574 {
8575 aux->seg_base = seg->p_vaddr;
8576 break;
8577 }
8578 }
8579 }
8580
8581 /* Second, build the unwind table from the contents of the unwind
8582 section. */
8583 size = sec->sh_size;
dda8d76d 8584 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8585 _("unwind table"));
57346661 8586 if (!table)
015dc7e1 8587 return false;
57346661 8588
1c0751b2
DA
8589 unw_ent_size = 16;
8590 nentries = size / unw_ent_size;
8591 size = unw_ent_size * nentries;
57346661 8592
e3fdc001 8593 aux->table_len = nentries;
3f5e193b
NC
8594 tep = aux->table = (struct hppa_unw_table_entry *)
8595 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8596
1c0751b2 8597 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8598 {
8599 unsigned int tmp1, tmp2;
8600
8601 tep->start.section = SHN_UNDEF;
8602 tep->end.section = SHN_UNDEF;
8603
1c0751b2
DA
8604 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8605 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8606 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8607 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8608
8609 tep->start.offset += aux->seg_base;
8610 tep->end.offset += aux->seg_base;
57346661
AM
8611
8612 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8613 tep->Millicode = (tmp1 >> 30) & 0x1;
8614 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8615 tep->Region_description = (tmp1 >> 27) & 0x3;
8616 tep->reserved1 = (tmp1 >> 26) & 0x1;
8617 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8618 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8619 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8620 tep->Args_stored = (tmp1 >> 15) & 0x1;
8621 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8622 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8623 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8624 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8625 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8626 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8627 tep->cxx_info = (tmp1 >> 8) & 0x1;
8628 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8629 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8630 tep->reserved2 = (tmp1 >> 5) & 0x1;
8631 tep->Save_SP = (tmp1 >> 4) & 0x1;
8632 tep->Save_RP = (tmp1 >> 3) & 0x1;
8633 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8634 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8635 tep->Cleanup_defined = tmp1 & 0x1;
8636
8637 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8638 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8639 tep->Large_frame = (tmp2 >> 29) & 0x1;
8640 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8641 tep->reserved4 = (tmp2 >> 27) & 0x1;
8642 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8643 }
8644 free (table);
8645
8646 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8647 for (relsec = filedata->section_headers;
8648 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8649 ++relsec)
8650 {
8651 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8652 || relsec->sh_info >= filedata->file_header.e_shnum
8653 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8654 continue;
8655
dda8d76d 8656 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8657 & rela, & nrelas))
015dc7e1 8658 return false;
57346661
AM
8659
8660 for (rp = rela; rp < rela + nrelas; ++rp)
8661 {
4770fb94 8662 unsigned int sym_ndx;
726bd37d
AM
8663 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8664 relname = elf_hppa_reloc_type (r_type);
57346661 8665
726bd37d
AM
8666 if (relname == NULL)
8667 {
8668 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8669 continue;
8670 }
8671
57346661 8672 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 8673 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 8674 {
726bd37d 8675 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8676 continue;
8677 }
8678
8679 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8680 if (i >= aux->table_len)
8681 {
8682 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8683 continue;
8684 }
57346661 8685
4770fb94
AM
8686 sym_ndx = get_reloc_symindex (rp->r_info);
8687 if (sym_ndx >= aux->nsyms)
8688 {
8689 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8690 sym_ndx);
8691 continue;
8692 }
8693 sym = aux->symtab + sym_ndx;
8694
43f6cd05 8695 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8696 {
8697 case 0:
8698 aux->table[i].start.section = sym->st_shndx;
1e456d54 8699 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8700 break;
8701 case 1:
8702 aux->table[i].end.section = sym->st_shndx;
1e456d54 8703 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8704 break;
8705 default:
8706 break;
8707 }
8708 }
8709
8710 free (rela);
8711 }
8712
015dc7e1 8713 return true;
57346661
AM
8714}
8715
015dc7e1 8716static bool
dda8d76d 8717hppa_process_unwind (Filedata * filedata)
57346661 8718{
57346661 8719 struct hppa_unw_aux_info aux;
2cf0635d 8720 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8721 Elf_Internal_Shdr * sec;
18bd398b 8722 unsigned long i;
015dc7e1 8723 bool res = true;
57346661 8724
dda8d76d 8725 if (filedata->string_table == NULL)
015dc7e1 8726 return false;
1b31d05e
NC
8727
8728 memset (& aux, 0, sizeof (aux));
57346661 8729
dda8d76d 8730 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8731 {
28d13567 8732 if (sec->sh_type == SHT_SYMTAB)
57346661 8733 {
28d13567 8734 if (aux.symtab)
4082ef84 8735 {
28d13567
AM
8736 error (_("Multiple symbol tables encountered\n"));
8737 free (aux.symtab);
8738 aux.symtab = NULL;
4082ef84 8739 free (aux.strtab);
28d13567 8740 aux.strtab = NULL;
4082ef84 8741 }
28d13567
AM
8742 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8743 &aux.strtab, &aux.strtab_size))
015dc7e1 8744 return false;
57346661 8745 }
b9e920ec
AM
8746 else if (SECTION_NAME_VALID (sec)
8747 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8748 unwsec = sec;
8749 }
8750
8751 if (!unwsec)
8752 printf (_("\nThere are no unwind sections in this file.\n"));
8753
dda8d76d 8754 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8755 {
b9e920ec
AM
8756 if (SECTION_NAME_VALID (sec)
8757 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8758 {
43f6cd05 8759 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8760
d3a49aa8
AM
8761 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8762 "contains %lu entry:\n",
8763 "\nUnwind section '%s' at offset 0x%lx "
8764 "contains %lu entries:\n",
8765 num_unwind),
dda8d76d 8766 printable_section_name (filedata, sec),
57346661 8767 (unsigned long) sec->sh_offset,
d3a49aa8 8768 num_unwind);
57346661 8769
dda8d76d 8770 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 8771 res = false;
66b09c7e
S
8772
8773 if (res && aux.table_len > 0)
32ec8896 8774 {
dda8d76d 8775 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 8776 res = false;
32ec8896 8777 }
57346661 8778
9db70fc3 8779 free ((char *) aux.table);
57346661
AM
8780 aux.table = NULL;
8781 }
8782 }
8783
9db70fc3
AM
8784 free (aux.symtab);
8785 free ((char *) aux.strtab);
32ec8896
NC
8786
8787 return res;
57346661
AM
8788}
8789
0b6ae522
DJ
8790struct arm_section
8791{
a734115a
NC
8792 unsigned char * data; /* The unwind data. */
8793 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8794 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8795 unsigned long nrelas; /* The number of relocations. */
8796 unsigned int rel_type; /* REL or RELA ? */
8797 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8798};
8799
8800struct arm_unw_aux_info
8801{
dda8d76d 8802 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8803 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8804 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8805 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8806 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8807 char * strtab; /* The file's string table. */
8808 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8809};
8810
8811static const char *
dda8d76d
NC
8812arm_print_vma_and_name (Filedata * filedata,
8813 struct arm_unw_aux_info * aux,
8814 bfd_vma fn,
8815 struct absaddr addr)
0b6ae522
DJ
8816{
8817 const char *procname;
8818 bfd_vma sym_offset;
8819
8820 if (addr.section == SHN_UNDEF)
8821 addr.offset = fn;
8822
dda8d76d 8823 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8824 aux->strtab_size, addr, &procname,
8825 &sym_offset);
8826
8827 print_vma (fn, PREFIX_HEX);
8828
8829 if (procname)
8830 {
8831 fputs (" <", stdout);
8832 fputs (procname, stdout);
8833
8834 if (sym_offset)
8835 printf ("+0x%lx", (unsigned long) sym_offset);
8836 fputc ('>', stdout);
8837 }
8838
8839 return procname;
8840}
8841
8842static void
8843arm_free_section (struct arm_section *arm_sec)
8844{
9db70fc3
AM
8845 free (arm_sec->data);
8846 free (arm_sec->rela);
0b6ae522
DJ
8847}
8848
a734115a
NC
8849/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8850 cached section and install SEC instead.
8851 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8852 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8853 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8854 relocation's offset in ADDR.
1b31d05e
NC
8855 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8856 into the string table of the symbol associated with the reloc. If no
8857 reloc was applied store -1 there.
8858 5) Return TRUE upon success, FALSE otherwise. */
a734115a 8859
015dc7e1 8860static bool
dda8d76d
NC
8861get_unwind_section_word (Filedata * filedata,
8862 struct arm_unw_aux_info * aux,
1b31d05e
NC
8863 struct arm_section * arm_sec,
8864 Elf_Internal_Shdr * sec,
8865 bfd_vma word_offset,
8866 unsigned int * wordp,
8867 struct absaddr * addr,
8868 bfd_vma * sym_name)
0b6ae522
DJ
8869{
8870 Elf_Internal_Rela *rp;
8871 Elf_Internal_Sym *sym;
8872 const char * relname;
8873 unsigned int word;
015dc7e1 8874 bool wrapped;
0b6ae522 8875
e0a31db1 8876 if (sec == NULL || arm_sec == NULL)
015dc7e1 8877 return false;
e0a31db1 8878
0b6ae522
DJ
8879 addr->section = SHN_UNDEF;
8880 addr->offset = 0;
8881
1b31d05e
NC
8882 if (sym_name != NULL)
8883 *sym_name = (bfd_vma) -1;
8884
a734115a 8885 /* If necessary, update the section cache. */
0b6ae522
DJ
8886 if (sec != arm_sec->sec)
8887 {
8888 Elf_Internal_Shdr *relsec;
8889
8890 arm_free_section (arm_sec);
8891
8892 arm_sec->sec = sec;
dda8d76d 8893 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8894 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8895 arm_sec->rela = NULL;
8896 arm_sec->nrelas = 0;
8897
dda8d76d
NC
8898 for (relsec = filedata->section_headers;
8899 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8900 ++relsec)
8901 {
dda8d76d
NC
8902 if (relsec->sh_info >= filedata->file_header.e_shnum
8903 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8904 /* PR 15745: Check the section type as well. */
8905 || (relsec->sh_type != SHT_REL
8906 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8907 continue;
8908
a734115a 8909 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8910 if (relsec->sh_type == SHT_REL)
8911 {
dda8d76d 8912 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8913 relsec->sh_size,
8914 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 8915 return false;
0b6ae522 8916 }
1ae40aa4 8917 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8918 {
dda8d76d 8919 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8920 relsec->sh_size,
8921 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 8922 return false;
0b6ae522 8923 }
1ae40aa4 8924 break;
0b6ae522
DJ
8925 }
8926
8927 arm_sec->next_rela = arm_sec->rela;
8928 }
8929
a734115a 8930 /* If there is no unwind data we can do nothing. */
0b6ae522 8931 if (arm_sec->data == NULL)
015dc7e1 8932 return false;
0b6ae522 8933
e0a31db1 8934 /* If the offset is invalid then fail. */
f32ba729
NC
8935 if (/* PR 21343 *//* PR 18879 */
8936 sec->sh_size < 4
8937 || word_offset > (sec->sh_size - 4)
1a915552 8938 || ((bfd_signed_vma) word_offset) < 0)
015dc7e1 8939 return false;
e0a31db1 8940
a734115a 8941 /* Get the word at the required offset. */
0b6ae522
DJ
8942 word = byte_get (arm_sec->data + word_offset, 4);
8943
0eff7165
NC
8944 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8945 if (arm_sec->rela == NULL)
8946 {
8947 * wordp = word;
015dc7e1 8948 return true;
0eff7165
NC
8949 }
8950
a734115a 8951 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 8952 wrapped = false;
0b6ae522
DJ
8953 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8954 {
8955 bfd_vma prelval, offset;
8956
8957 if (rp->r_offset > word_offset && !wrapped)
8958 {
8959 rp = arm_sec->rela;
015dc7e1 8960 wrapped = true;
0b6ae522
DJ
8961 }
8962 if (rp->r_offset > word_offset)
8963 break;
8964
8965 if (rp->r_offset & 3)
8966 {
8967 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8968 (unsigned long) rp->r_offset);
8969 continue;
8970 }
8971
8972 if (rp->r_offset < word_offset)
8973 continue;
8974
74e1a04b
NC
8975 /* PR 17531: file: 027-161405-0.004 */
8976 if (aux->symtab == NULL)
8977 continue;
8978
0b6ae522
DJ
8979 if (arm_sec->rel_type == SHT_REL)
8980 {
8981 offset = word & 0x7fffffff;
8982 if (offset & 0x40000000)
8983 offset |= ~ (bfd_vma) 0x7fffffff;
8984 }
a734115a 8985 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8986 offset = rp->r_addend;
a734115a 8987 else
74e1a04b
NC
8988 {
8989 error (_("Unknown section relocation type %d encountered\n"),
8990 arm_sec->rel_type);
8991 break;
8992 }
0b6ae522 8993
071436c6
NC
8994 /* PR 17531 file: 027-1241568-0.004. */
8995 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8996 {
8997 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8998 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8999 break;
9000 }
9001
9002 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9003 offset += sym->st_value;
9004 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9005
a734115a 9006 /* Check that we are processing the expected reloc type. */
dda8d76d 9007 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9008 {
9009 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9010 if (relname == NULL)
9011 {
9012 warn (_("Skipping unknown ARM relocation type: %d\n"),
9013 (int) ELF32_R_TYPE (rp->r_info));
9014 continue;
9015 }
a734115a
NC
9016
9017 if (streq (relname, "R_ARM_NONE"))
9018 continue;
0b4362b0 9019
a734115a
NC
9020 if (! streq (relname, "R_ARM_PREL31"))
9021 {
071436c6 9022 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9023 continue;
9024 }
9025 }
dda8d76d 9026 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9027 {
9028 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9029 if (relname == NULL)
9030 {
9031 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9032 (int) ELF32_R_TYPE (rp->r_info));
9033 continue;
9034 }
0b4362b0 9035
a734115a
NC
9036 if (streq (relname, "R_C6000_NONE"))
9037 continue;
9038
9039 if (! streq (relname, "R_C6000_PREL31"))
9040 {
071436c6 9041 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9042 continue;
9043 }
9044
9045 prelval >>= 1;
9046 }
9047 else
74e1a04b
NC
9048 {
9049 /* This function currently only supports ARM and TI unwinders. */
9050 warn (_("Only TI and ARM unwinders are currently supported\n"));
9051 break;
9052 }
fa197c1c 9053
0b6ae522
DJ
9054 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
9055 addr->section = sym->st_shndx;
9056 addr->offset = offset;
74e1a04b 9057
1b31d05e
NC
9058 if (sym_name)
9059 * sym_name = sym->st_name;
0b6ae522
DJ
9060 break;
9061 }
9062
9063 *wordp = word;
9064 arm_sec->next_rela = rp;
9065
015dc7e1 9066 return true;
0b6ae522
DJ
9067}
9068
a734115a
NC
9069static const char *tic6x_unwind_regnames[16] =
9070{
0b4362b0
RM
9071 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9072 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9073 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9074};
fa197c1c 9075
0b6ae522 9076static void
fa197c1c 9077decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9078{
fa197c1c
PB
9079 int i;
9080
9081 for (i = 12; mask; mask >>= 1, i--)
9082 {
9083 if (mask & 1)
9084 {
9085 fputs (tic6x_unwind_regnames[i], stdout);
9086 if (mask > 1)
9087 fputs (", ", stdout);
9088 }
9089 }
9090}
0b6ae522
DJ
9091
9092#define ADVANCE \
9093 if (remaining == 0 && more_words) \
9094 { \
9095 data_offset += 4; \
dda8d76d 9096 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9097 data_offset, & word, & addr, NULL)) \
015dc7e1 9098 return false; \
0b6ae522
DJ
9099 remaining = 4; \
9100 more_words--; \
9101 } \
9102
9103#define GET_OP(OP) \
9104 ADVANCE; \
9105 if (remaining) \
9106 { \
9107 remaining--; \
9108 (OP) = word >> 24; \
9109 word <<= 8; \
9110 } \
9111 else \
9112 { \
2b692964 9113 printf (_("[Truncated opcode]\n")); \
015dc7e1 9114 return false; \
0b6ae522 9115 } \
cc5914eb 9116 printf ("0x%02x ", OP)
0b6ae522 9117
015dc7e1 9118static bool
dda8d76d
NC
9119decode_arm_unwind_bytecode (Filedata * filedata,
9120 struct arm_unw_aux_info * aux,
948f632f
DA
9121 unsigned int word,
9122 unsigned int remaining,
9123 unsigned int more_words,
9124 bfd_vma data_offset,
9125 Elf_Internal_Shdr * data_sec,
9126 struct arm_section * data_arm_sec)
fa197c1c
PB
9127{
9128 struct absaddr addr;
015dc7e1 9129 bool res = true;
0b6ae522
DJ
9130
9131 /* Decode the unwinding instructions. */
9132 while (1)
9133 {
9134 unsigned int op, op2;
9135
9136 ADVANCE;
9137 if (remaining == 0)
9138 break;
9139 remaining--;
9140 op = word >> 24;
9141 word <<= 8;
9142
cc5914eb 9143 printf (" 0x%02x ", op);
0b6ae522
DJ
9144
9145 if ((op & 0xc0) == 0x00)
9146 {
9147 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9148
cc5914eb 9149 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9150 }
9151 else if ((op & 0xc0) == 0x40)
9152 {
9153 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9154
cc5914eb 9155 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9156 }
9157 else if ((op & 0xf0) == 0x80)
9158 {
9159 GET_OP (op2);
9160 if (op == 0x80 && op2 == 0)
9161 printf (_("Refuse to unwind"));
9162 else
9163 {
9164 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9165 bool first = true;
0b6ae522 9166 int i;
2b692964 9167
0b6ae522
DJ
9168 printf ("pop {");
9169 for (i = 0; i < 12; i++)
9170 if (mask & (1 << i))
9171 {
9172 if (first)
015dc7e1 9173 first = false;
0b6ae522
DJ
9174 else
9175 printf (", ");
9176 printf ("r%d", 4 + i);
9177 }
9178 printf ("}");
9179 }
9180 }
9181 else if ((op & 0xf0) == 0x90)
9182 {
9183 if (op == 0x9d || op == 0x9f)
9184 printf (_(" [Reserved]"));
9185 else
cc5914eb 9186 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9187 }
9188 else if ((op & 0xf0) == 0xa0)
9189 {
9190 int end = 4 + (op & 0x07);
015dc7e1 9191 bool first = true;
0b6ae522 9192 int i;
61865e30 9193
0b6ae522
DJ
9194 printf (" pop {");
9195 for (i = 4; i <= end; i++)
9196 {
9197 if (first)
015dc7e1 9198 first = false;
0b6ae522
DJ
9199 else
9200 printf (", ");
9201 printf ("r%d", i);
9202 }
9203 if (op & 0x08)
9204 {
1b31d05e 9205 if (!first)
0b6ae522
DJ
9206 printf (", ");
9207 printf ("r14");
9208 }
9209 printf ("}");
9210 }
9211 else if (op == 0xb0)
9212 printf (_(" finish"));
9213 else if (op == 0xb1)
9214 {
9215 GET_OP (op2);
9216 if (op2 == 0 || (op2 & 0xf0) != 0)
9217 printf (_("[Spare]"));
9218 else
9219 {
9220 unsigned int mask = op2 & 0x0f;
015dc7e1 9221 bool first = true;
0b6ae522 9222 int i;
61865e30 9223
0b6ae522
DJ
9224 printf ("pop {");
9225 for (i = 0; i < 12; i++)
9226 if (mask & (1 << i))
9227 {
9228 if (first)
015dc7e1 9229 first = false;
0b6ae522
DJ
9230 else
9231 printf (", ");
9232 printf ("r%d", i);
9233 }
9234 printf ("}");
9235 }
9236 }
9237 else if (op == 0xb2)
9238 {
b115cf96 9239 unsigned char buf[9];
0b6ae522
DJ
9240 unsigned int i, len;
9241 unsigned long offset;
61865e30 9242
b115cf96 9243 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9244 {
9245 GET_OP (buf[i]);
9246 if ((buf[i] & 0x80) == 0)
9247 break;
9248 }
4082ef84 9249 if (i == sizeof (buf))
32ec8896 9250 {
27a45f42 9251 error (_("corrupt change to vsp\n"));
015dc7e1 9252 res = false;
32ec8896 9253 }
4082ef84
NC
9254 else
9255 {
015dc7e1 9256 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9257 assert (len == i + 1);
9258 offset = offset * 4 + 0x204;
9259 printf ("vsp = vsp + %ld", offset);
9260 }
0b6ae522 9261 }
61865e30 9262 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9263 {
61865e30
NC
9264 unsigned int first, last;
9265
9266 GET_OP (op2);
9267 first = op2 >> 4;
9268 last = op2 & 0x0f;
9269 if (op == 0xc8)
9270 first = first + 16;
9271 printf ("pop {D%d", first);
9272 if (last)
9273 printf ("-D%d", first + last);
9274 printf ("}");
9275 }
9276 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9277 {
9278 unsigned int count = op & 0x07;
9279
9280 printf ("pop {D8");
9281 if (count)
9282 printf ("-D%d", 8 + count);
9283 printf ("}");
9284 }
9285 else if (op >= 0xc0 && op <= 0xc5)
9286 {
9287 unsigned int count = op & 0x07;
9288
9289 printf (" pop {wR10");
9290 if (count)
9291 printf ("-wR%d", 10 + count);
9292 printf ("}");
9293 }
9294 else if (op == 0xc6)
9295 {
9296 unsigned int first, last;
9297
9298 GET_OP (op2);
9299 first = op2 >> 4;
9300 last = op2 & 0x0f;
9301 printf ("pop {wR%d", first);
9302 if (last)
9303 printf ("-wR%d", first + last);
9304 printf ("}");
9305 }
9306 else if (op == 0xc7)
9307 {
9308 GET_OP (op2);
9309 if (op2 == 0 || (op2 & 0xf0) != 0)
9310 printf (_("[Spare]"));
0b6ae522
DJ
9311 else
9312 {
61865e30 9313 unsigned int mask = op2 & 0x0f;
015dc7e1 9314 bool first = true;
61865e30
NC
9315 int i;
9316
9317 printf ("pop {");
9318 for (i = 0; i < 4; i++)
9319 if (mask & (1 << i))
9320 {
9321 if (first)
015dc7e1 9322 first = false;
61865e30
NC
9323 else
9324 printf (", ");
9325 printf ("wCGR%d", i);
9326 }
9327 printf ("}");
0b6ae522
DJ
9328 }
9329 }
61865e30 9330 else
32ec8896
NC
9331 {
9332 printf (_(" [unsupported opcode]"));
015dc7e1 9333 res = false;
32ec8896
NC
9334 }
9335
0b6ae522
DJ
9336 printf ("\n");
9337 }
32ec8896
NC
9338
9339 return res;
fa197c1c
PB
9340}
9341
015dc7e1 9342static bool
dda8d76d
NC
9343decode_tic6x_unwind_bytecode (Filedata * filedata,
9344 struct arm_unw_aux_info * aux,
948f632f
DA
9345 unsigned int word,
9346 unsigned int remaining,
9347 unsigned int more_words,
9348 bfd_vma data_offset,
9349 Elf_Internal_Shdr * data_sec,
9350 struct arm_section * data_arm_sec)
fa197c1c
PB
9351{
9352 struct absaddr addr;
9353
9354 /* Decode the unwinding instructions. */
9355 while (1)
9356 {
9357 unsigned int op, op2;
9358
9359 ADVANCE;
9360 if (remaining == 0)
9361 break;
9362 remaining--;
9363 op = word >> 24;
9364 word <<= 8;
9365
9cf03b7e 9366 printf (" 0x%02x ", op);
fa197c1c
PB
9367
9368 if ((op & 0xc0) == 0x00)
9369 {
9370 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9371 printf (" sp = sp + %d", offset);
fa197c1c
PB
9372 }
9373 else if ((op & 0xc0) == 0x80)
9374 {
9375 GET_OP (op2);
9376 if (op == 0x80 && op2 == 0)
9377 printf (_("Refuse to unwind"));
9378 else
9379 {
9380 unsigned int mask = ((op & 0x1f) << 8) | op2;
9381 if (op & 0x20)
9382 printf ("pop compact {");
9383 else
9384 printf ("pop {");
9385
9386 decode_tic6x_unwind_regmask (mask);
9387 printf("}");
9388 }
9389 }
9390 else if ((op & 0xf0) == 0xc0)
9391 {
9392 unsigned int reg;
9393 unsigned int nregs;
9394 unsigned int i;
9395 const char *name;
a734115a
NC
9396 struct
9397 {
32ec8896
NC
9398 unsigned int offset;
9399 unsigned int reg;
fa197c1c
PB
9400 } regpos[16];
9401
9402 /* Scan entire instruction first so that GET_OP output is not
9403 interleaved with disassembly. */
9404 nregs = 0;
9405 for (i = 0; nregs < (op & 0xf); i++)
9406 {
9407 GET_OP (op2);
9408 reg = op2 >> 4;
9409 if (reg != 0xf)
9410 {
9411 regpos[nregs].offset = i * 2;
9412 regpos[nregs].reg = reg;
9413 nregs++;
9414 }
9415
9416 reg = op2 & 0xf;
9417 if (reg != 0xf)
9418 {
9419 regpos[nregs].offset = i * 2 + 1;
9420 regpos[nregs].reg = reg;
9421 nregs++;
9422 }
9423 }
9424
9425 printf (_("pop frame {"));
18344509 9426 if (nregs == 0)
fa197c1c 9427 {
18344509
NC
9428 printf (_("*corrupt* - no registers specified"));
9429 }
9430 else
9431 {
9432 reg = nregs - 1;
9433 for (i = i * 2; i > 0; i--)
fa197c1c 9434 {
18344509
NC
9435 if (regpos[reg].offset == i - 1)
9436 {
9437 name = tic6x_unwind_regnames[regpos[reg].reg];
9438 if (reg > 0)
9439 reg--;
9440 }
9441 else
9442 name = _("[pad]");
fa197c1c 9443
18344509
NC
9444 fputs (name, stdout);
9445 if (i > 1)
9446 printf (", ");
9447 }
fa197c1c
PB
9448 }
9449
9450 printf ("}");
9451 }
9452 else if (op == 0xd0)
9453 printf (" MOV FP, SP");
9454 else if (op == 0xd1)
9455 printf (" __c6xabi_pop_rts");
9456 else if (op == 0xd2)
9457 {
9458 unsigned char buf[9];
9459 unsigned int i, len;
9460 unsigned long offset;
a734115a 9461
fa197c1c
PB
9462 for (i = 0; i < sizeof (buf); i++)
9463 {
9464 GET_OP (buf[i]);
9465 if ((buf[i] & 0x80) == 0)
9466 break;
9467 }
0eff7165
NC
9468 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9469 if (i == sizeof (buf))
9470 {
0eff7165 9471 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 9472 return false;
0eff7165 9473 }
948f632f 9474
015dc7e1 9475 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
9476 assert (len == i + 1);
9477 offset = offset * 8 + 0x408;
9478 printf (_("sp = sp + %ld"), offset);
9479 }
9480 else if ((op & 0xf0) == 0xe0)
9481 {
9482 if ((op & 0x0f) == 7)
9483 printf (" RETURN");
9484 else
9485 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9486 }
9487 else
9488 {
9489 printf (_(" [unsupported opcode]"));
9490 }
9491 putchar ('\n');
9492 }
32ec8896 9493
015dc7e1 9494 return true;
fa197c1c
PB
9495}
9496
9497static bfd_vma
dda8d76d 9498arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9499{
9500 bfd_vma offset;
9501
9502 offset = word & 0x7fffffff;
9503 if (offset & 0x40000000)
9504 offset |= ~ (bfd_vma) 0x7fffffff;
9505
dda8d76d 9506 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9507 offset <<= 1;
9508
9509 return offset + where;
9510}
9511
015dc7e1 9512static bool
dda8d76d
NC
9513decode_arm_unwind (Filedata * filedata,
9514 struct arm_unw_aux_info * aux,
1b31d05e
NC
9515 unsigned int word,
9516 unsigned int remaining,
9517 bfd_vma data_offset,
9518 Elf_Internal_Shdr * data_sec,
9519 struct arm_section * data_arm_sec)
fa197c1c
PB
9520{
9521 int per_index;
9522 unsigned int more_words = 0;
37e14bc3 9523 struct absaddr addr;
1b31d05e 9524 bfd_vma sym_name = (bfd_vma) -1;
015dc7e1 9525 bool res = true;
fa197c1c
PB
9526
9527 if (remaining == 0)
9528 {
1b31d05e
NC
9529 /* Fetch the first word.
9530 Note - when decoding an object file the address extracted
9531 here will always be 0. So we also pass in the sym_name
9532 parameter so that we can find the symbol associated with
9533 the personality routine. */
dda8d76d 9534 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9535 & word, & addr, & sym_name))
015dc7e1 9536 return false;
1b31d05e 9537
fa197c1c
PB
9538 remaining = 4;
9539 }
c93dbb25
CZ
9540 else
9541 {
9542 addr.section = SHN_UNDEF;
9543 addr.offset = 0;
9544 }
fa197c1c
PB
9545
9546 if ((word & 0x80000000) == 0)
9547 {
9548 /* Expand prel31 for personality routine. */
9549 bfd_vma fn;
9550 const char *procname;
9551
dda8d76d 9552 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9553 printf (_(" Personality routine: "));
1b31d05e
NC
9554 if (fn == 0
9555 && addr.section == SHN_UNDEF && addr.offset == 0
9556 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9557 {
9558 procname = aux->strtab + sym_name;
9559 print_vma (fn, PREFIX_HEX);
9560 if (procname)
9561 {
9562 fputs (" <", stdout);
9563 fputs (procname, stdout);
9564 fputc ('>', stdout);
9565 }
9566 }
9567 else
dda8d76d 9568 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9569 fputc ('\n', stdout);
9570
9571 /* The GCC personality routines use the standard compact
9572 encoding, starting with one byte giving the number of
9573 words. */
9574 if (procname != NULL
24d127aa
ML
9575 && (startswith (procname, "__gcc_personality_v0")
9576 || startswith (procname, "__gxx_personality_v0")
9577 || startswith (procname, "__gcj_personality_v0")
9578 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
9579 {
9580 remaining = 0;
9581 more_words = 1;
9582 ADVANCE;
9583 if (!remaining)
9584 {
9585 printf (_(" [Truncated data]\n"));
015dc7e1 9586 return false;
fa197c1c
PB
9587 }
9588 more_words = word >> 24;
9589 word <<= 8;
9590 remaining--;
9591 per_index = -1;
9592 }
9593 else
015dc7e1 9594 return true;
fa197c1c
PB
9595 }
9596 else
9597 {
1b31d05e 9598 /* ARM EHABI Section 6.3:
0b4362b0 9599
1b31d05e 9600 An exception-handling table entry for the compact model looks like:
0b4362b0 9601
1b31d05e
NC
9602 31 30-28 27-24 23-0
9603 -- ----- ----- ----
9604 1 0 index Data for personalityRoutine[index] */
9605
dda8d76d 9606 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9607 && (word & 0x70000000))
32ec8896
NC
9608 {
9609 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 9610 res = false;
32ec8896 9611 }
1b31d05e 9612
fa197c1c 9613 per_index = (word >> 24) & 0x7f;
1b31d05e 9614 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9615 if (per_index == 0)
9616 {
9617 more_words = 0;
9618 word <<= 8;
9619 remaining--;
9620 }
9621 else if (per_index < 3)
9622 {
9623 more_words = (word >> 16) & 0xff;
9624 word <<= 16;
9625 remaining -= 2;
9626 }
9627 }
9628
dda8d76d 9629 switch (filedata->file_header.e_machine)
fa197c1c
PB
9630 {
9631 case EM_ARM:
9632 if (per_index < 3)
9633 {
dda8d76d 9634 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 9635 data_offset, data_sec, data_arm_sec))
015dc7e1 9636 res = false;
fa197c1c
PB
9637 }
9638 else
1b31d05e
NC
9639 {
9640 warn (_("Unknown ARM compact model index encountered\n"));
9641 printf (_(" [reserved]\n"));
015dc7e1 9642 res = false;
1b31d05e 9643 }
fa197c1c
PB
9644 break;
9645
9646 case EM_TI_C6000:
9647 if (per_index < 3)
9648 {
dda8d76d 9649 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 9650 data_offset, data_sec, data_arm_sec))
015dc7e1 9651 res = false;
fa197c1c
PB
9652 }
9653 else if (per_index < 5)
9654 {
9655 if (((word >> 17) & 0x7f) == 0x7f)
9656 printf (_(" Restore stack from frame pointer\n"));
9657 else
9658 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9659 printf (_(" Registers restored: "));
9660 if (per_index == 4)
9661 printf (" (compact) ");
9662 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9663 putchar ('\n');
9664 printf (_(" Return register: %s\n"),
9665 tic6x_unwind_regnames[word & 0xf]);
9666 }
9667 else
1b31d05e 9668 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9669 break;
9670
9671 default:
74e1a04b 9672 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9673 filedata->file_header.e_machine);
015dc7e1 9674 res = false;
fa197c1c 9675 }
0b6ae522
DJ
9676
9677 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9678
9679 return res;
0b6ae522
DJ
9680}
9681
015dc7e1 9682static bool
dda8d76d
NC
9683dump_arm_unwind (Filedata * filedata,
9684 struct arm_unw_aux_info * aux,
9685 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9686{
9687 struct arm_section exidx_arm_sec, extab_arm_sec;
9688 unsigned int i, exidx_len;
948f632f 9689 unsigned long j, nfuns;
015dc7e1 9690 bool res = true;
0b6ae522
DJ
9691
9692 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9693 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9694 exidx_len = exidx_sec->sh_size / 8;
9695
948f632f
DA
9696 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9697 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9698 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9699 aux->funtab[nfuns++] = aux->symtab[j];
9700 aux->nfuns = nfuns;
9701 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9702
0b6ae522
DJ
9703 for (i = 0; i < exidx_len; i++)
9704 {
9705 unsigned int exidx_fn, exidx_entry;
9706 struct absaddr fn_addr, entry_addr;
9707 bfd_vma fn;
9708
9709 fputc ('\n', stdout);
9710
dda8d76d 9711 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9712 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9713 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9714 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9715 {
948f632f 9716 free (aux->funtab);
1b31d05e
NC
9717 arm_free_section (& exidx_arm_sec);
9718 arm_free_section (& extab_arm_sec);
015dc7e1 9719 return false;
0b6ae522
DJ
9720 }
9721
83c257ca
NC
9722 /* ARM EHABI, Section 5:
9723 An index table entry consists of 2 words.
9724 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9725 if (exidx_fn & 0x80000000)
32ec8896
NC
9726 {
9727 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 9728 res = false;
32ec8896 9729 }
83c257ca 9730
dda8d76d 9731 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9732
dda8d76d 9733 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9734 fputs (": ", stdout);
9735
9736 if (exidx_entry == 1)
9737 {
9738 print_vma (exidx_entry, PREFIX_HEX);
9739 fputs (" [cantunwind]\n", stdout);
9740 }
9741 else if (exidx_entry & 0x80000000)
9742 {
9743 print_vma (exidx_entry, PREFIX_HEX);
9744 fputc ('\n', stdout);
dda8d76d 9745 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9746 }
9747 else
9748 {
8f73510c 9749 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9750 Elf_Internal_Shdr *table_sec;
9751
9752 fputs ("@", stdout);
dda8d76d 9753 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9754 print_vma (table, PREFIX_HEX);
9755 printf ("\n");
9756
9757 /* Locate the matching .ARM.extab. */
9758 if (entry_addr.section != SHN_UNDEF
dda8d76d 9759 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9760 {
dda8d76d 9761 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9762 table_offset = entry_addr.offset;
1a915552
NC
9763 /* PR 18879 */
9764 if (table_offset > table_sec->sh_size
9765 || ((bfd_signed_vma) table_offset) < 0)
9766 {
9767 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9768 (unsigned long) table_offset,
dda8d76d 9769 printable_section_name (filedata, table_sec));
015dc7e1 9770 res = false;
1a915552
NC
9771 continue;
9772 }
0b6ae522
DJ
9773 }
9774 else
9775 {
dda8d76d 9776 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9777 if (table_sec != NULL)
9778 table_offset = table - table_sec->sh_addr;
9779 }
32ec8896 9780
0b6ae522
DJ
9781 if (table_sec == NULL)
9782 {
9783 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9784 (unsigned long) table);
015dc7e1 9785 res = false;
0b6ae522
DJ
9786 continue;
9787 }
32ec8896 9788
dda8d76d 9789 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 9790 &extab_arm_sec))
015dc7e1 9791 res = false;
0b6ae522
DJ
9792 }
9793 }
9794
9795 printf ("\n");
9796
948f632f 9797 free (aux->funtab);
0b6ae522
DJ
9798 arm_free_section (&exidx_arm_sec);
9799 arm_free_section (&extab_arm_sec);
32ec8896
NC
9800
9801 return res;
0b6ae522
DJ
9802}
9803
fa197c1c 9804/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9805
015dc7e1 9806static bool
dda8d76d 9807arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9808{
9809 struct arm_unw_aux_info aux;
9810 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9811 Elf_Internal_Shdr *sec;
9812 unsigned long i;
fa197c1c 9813 unsigned int sec_type;
015dc7e1 9814 bool res = true;
0b6ae522 9815
dda8d76d 9816 switch (filedata->file_header.e_machine)
fa197c1c
PB
9817 {
9818 case EM_ARM:
9819 sec_type = SHT_ARM_EXIDX;
9820 break;
9821
9822 case EM_TI_C6000:
9823 sec_type = SHT_C6000_UNWIND;
9824 break;
9825
0b4362b0 9826 default:
74e1a04b 9827 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9828 filedata->file_header.e_machine);
015dc7e1 9829 return false;
fa197c1c
PB
9830 }
9831
dda8d76d 9832 if (filedata->string_table == NULL)
015dc7e1 9833 return false;
1b31d05e
NC
9834
9835 memset (& aux, 0, sizeof (aux));
dda8d76d 9836 aux.filedata = filedata;
0b6ae522 9837
dda8d76d 9838 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9839 {
28d13567 9840 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9841 {
28d13567 9842 if (aux.symtab)
74e1a04b 9843 {
28d13567
AM
9844 error (_("Multiple symbol tables encountered\n"));
9845 free (aux.symtab);
9846 aux.symtab = NULL;
74e1a04b 9847 free (aux.strtab);
28d13567 9848 aux.strtab = NULL;
74e1a04b 9849 }
28d13567
AM
9850 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9851 &aux.strtab, &aux.strtab_size))
015dc7e1 9852 return false;
0b6ae522 9853 }
fa197c1c 9854 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9855 unwsec = sec;
9856 }
9857
1b31d05e 9858 if (unwsec == NULL)
0b6ae522 9859 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9860 else
dda8d76d 9861 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9862 {
9863 if (sec->sh_type == sec_type)
9864 {
d3a49aa8
AM
9865 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9866 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9867 "contains %lu entry:\n",
9868 "\nUnwind section '%s' at offset 0x%lx "
9869 "contains %lu entries:\n",
9870 num_unwind),
dda8d76d 9871 printable_section_name (filedata, sec),
1b31d05e 9872 (unsigned long) sec->sh_offset,
d3a49aa8 9873 num_unwind);
0b6ae522 9874
dda8d76d 9875 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 9876 res = false;
1b31d05e
NC
9877 }
9878 }
0b6ae522 9879
9db70fc3
AM
9880 free (aux.symtab);
9881 free ((char *) aux.strtab);
32ec8896
NC
9882
9883 return res;
0b6ae522
DJ
9884}
9885
3ecc00ec
NC
9886static bool
9887no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
9888{
9889 printf (_("No processor specific unwind information to decode\n"));
9890 return true;
9891}
9892
015dc7e1 9893static bool
dda8d76d 9894process_unwind (Filedata * filedata)
57346661 9895{
2cf0635d
NC
9896 struct unwind_handler
9897 {
32ec8896 9898 unsigned int machtype;
015dc7e1 9899 bool (* handler)(Filedata *);
2cf0635d
NC
9900 } handlers[] =
9901 {
0b6ae522 9902 { EM_ARM, arm_process_unwind },
57346661
AM
9903 { EM_IA_64, ia64_process_unwind },
9904 { EM_PARISC, hppa_process_unwind },
fa197c1c 9905 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
9906 { EM_386, no_processor_specific_unwind },
9907 { EM_X86_64, no_processor_specific_unwind },
32ec8896 9908 { 0, NULL }
57346661
AM
9909 };
9910 int i;
9911
9912 if (!do_unwind)
015dc7e1 9913 return true;
57346661
AM
9914
9915 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9916 if (filedata->file_header.e_machine == handlers[i].machtype)
9917 return handlers[i].handler (filedata);
57346661 9918
1b31d05e 9919 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9920 get_machine_name (filedata->file_header.e_machine));
015dc7e1 9921 return true;
57346661
AM
9922}
9923
37c18eed
SD
9924static void
9925dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
9926{
9927 switch (entry->d_tag)
9928 {
9929 case DT_AARCH64_BTI_PLT:
1dbade74 9930 case DT_AARCH64_PAC_PLT:
37c18eed
SD
9931 break;
9932 default:
9933 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9934 break;
9935 }
9936 putchar ('\n');
9937}
9938
252b5132 9939static void
978c4450 9940dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
9941{
9942 switch (entry->d_tag)
9943 {
9944 case DT_MIPS_FLAGS:
9945 if (entry->d_un.d_val == 0)
4b68bca3 9946 printf (_("NONE"));
252b5132
RH
9947 else
9948 {
9949 static const char * opts[] =
9950 {
9951 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9952 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9953 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9954 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9955 "RLD_ORDER_SAFE"
9956 };
9957 unsigned int cnt;
015dc7e1 9958 bool first = true;
2b692964 9959
60bca95a 9960 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9961 if (entry->d_un.d_val & (1 << cnt))
9962 {
9963 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 9964 first = false;
252b5132 9965 }
252b5132
RH
9966 }
9967 break;
103f02d3 9968
252b5132 9969 case DT_MIPS_IVERSION:
978c4450
AM
9970 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
9971 printf (_("Interface Version: %s"),
9972 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 9973 else
76ca31c0
NC
9974 {
9975 char buf[40];
9976 sprintf_vma (buf, entry->d_un.d_ptr);
9977 /* Note: coded this way so that there is a single string for translation. */
9978 printf (_("<corrupt: %s>"), buf);
9979 }
252b5132 9980 break;
103f02d3 9981
252b5132
RH
9982 case DT_MIPS_TIME_STAMP:
9983 {
d5b07ef4 9984 char timebuf[128];
2cf0635d 9985 struct tm * tmp;
91d6fa6a 9986 time_t atime = entry->d_un.d_val;
82b1b41b 9987
91d6fa6a 9988 tmp = gmtime (&atime);
82b1b41b
NC
9989 /* PR 17531: file: 6accc532. */
9990 if (tmp == NULL)
9991 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9992 else
9993 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9994 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9995 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9996 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9997 }
9998 break;
103f02d3 9999
252b5132
RH
10000 case DT_MIPS_RLD_VERSION:
10001 case DT_MIPS_LOCAL_GOTNO:
10002 case DT_MIPS_CONFLICTNO:
10003 case DT_MIPS_LIBLISTNO:
10004 case DT_MIPS_SYMTABNO:
10005 case DT_MIPS_UNREFEXTNO:
10006 case DT_MIPS_HIPAGENO:
10007 case DT_MIPS_DELTA_CLASS_NO:
10008 case DT_MIPS_DELTA_INSTANCE_NO:
10009 case DT_MIPS_DELTA_RELOC_NO:
10010 case DT_MIPS_DELTA_SYM_NO:
10011 case DT_MIPS_DELTA_CLASSSYM_NO:
10012 case DT_MIPS_COMPACT_SIZE:
c69075ac 10013 print_vma (entry->d_un.d_val, DEC);
252b5132 10014 break;
103f02d3 10015
f16a9783 10016 case DT_MIPS_XHASH:
978c4450
AM
10017 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10018 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10019 /* Falls through. */
10020
103f02d3 10021 default:
4b68bca3 10022 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10023 }
4b68bca3 10024 putchar ('\n');
103f02d3
UD
10025}
10026
103f02d3 10027static void
2cf0635d 10028dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10029{
10030 switch (entry->d_tag)
10031 {
10032 case DT_HP_DLD_FLAGS:
10033 {
10034 static struct
10035 {
10036 long int bit;
2cf0635d 10037 const char * str;
5e220199
NC
10038 }
10039 flags[] =
10040 {
10041 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10042 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10043 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10044 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10045 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10046 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10047 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10048 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10049 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10050 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10051 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10052 { DT_HP_GST, "HP_GST" },
10053 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10054 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10055 { DT_HP_NODELETE, "HP_NODELETE" },
10056 { DT_HP_GROUP, "HP_GROUP" },
10057 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10058 };
015dc7e1 10059 bool first = true;
5e220199 10060 size_t cnt;
f7a99963 10061 bfd_vma val = entry->d_un.d_val;
103f02d3 10062
60bca95a 10063 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10064 if (val & flags[cnt].bit)
30800947
NC
10065 {
10066 if (! first)
10067 putchar (' ');
10068 fputs (flags[cnt].str, stdout);
015dc7e1 10069 first = false;
30800947
NC
10070 val ^= flags[cnt].bit;
10071 }
76da6bbe 10072
103f02d3 10073 if (val != 0 || first)
f7a99963
NC
10074 {
10075 if (! first)
10076 putchar (' ');
10077 print_vma (val, HEX);
10078 }
103f02d3
UD
10079 }
10080 break;
76da6bbe 10081
252b5132 10082 default:
f7a99963
NC
10083 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10084 break;
252b5132 10085 }
35b1837e 10086 putchar ('\n');
252b5132
RH
10087}
10088
28f997cf
TG
10089#ifdef BFD64
10090
10091/* VMS vs Unix time offset and factor. */
10092
10093#define VMS_EPOCH_OFFSET 35067168000000000LL
10094#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10095#ifndef INT64_MIN
10096#define INT64_MIN (-9223372036854775807LL - 1)
10097#endif
28f997cf
TG
10098
10099/* Display a VMS time in a human readable format. */
10100
10101static void
10102print_vms_time (bfd_int64_t vmstime)
10103{
dccc31de 10104 struct tm *tm = NULL;
28f997cf
TG
10105 time_t unxtime;
10106
dccc31de
AM
10107 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10108 {
10109 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10110 unxtime = vmstime;
10111 if (unxtime == vmstime)
10112 tm = gmtime (&unxtime);
10113 }
10114 if (tm != NULL)
10115 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10116 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10117 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
10118}
10119#endif /* BFD64 */
10120
ecc51f48 10121static void
2cf0635d 10122dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10123{
10124 switch (entry->d_tag)
10125 {
0de14b54 10126 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10127 /* First 3 slots reserved. */
ecc51f48
NC
10128 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10129 printf (" -- ");
10130 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10131 break;
10132
28f997cf
TG
10133 case DT_IA_64_VMS_LINKTIME:
10134#ifdef BFD64
10135 print_vms_time (entry->d_un.d_val);
10136#endif
10137 break;
10138
10139 case DT_IA_64_VMS_LNKFLAGS:
10140 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10141 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10142 printf (" CALL_DEBUG");
10143 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10144 printf (" NOP0BUFS");
10145 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10146 printf (" P0IMAGE");
10147 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10148 printf (" MKTHREADS");
10149 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10150 printf (" UPCALLS");
10151 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10152 printf (" IMGSTA");
10153 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10154 printf (" INITIALIZE");
10155 if (entry->d_un.d_val & VMS_LF_MAIN)
10156 printf (" MAIN");
10157 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10158 printf (" EXE_INIT");
10159 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10160 printf (" TBK_IN_IMG");
10161 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10162 printf (" DBG_IN_IMG");
10163 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10164 printf (" TBK_IN_DSF");
10165 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10166 printf (" DBG_IN_DSF");
10167 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10168 printf (" SIGNATURES");
10169 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10170 printf (" REL_SEG_OFF");
10171 break;
10172
bdf4d63a
JJ
10173 default:
10174 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10175 break;
ecc51f48 10176 }
bdf4d63a 10177 putchar ('\n');
ecc51f48
NC
10178}
10179
015dc7e1 10180static bool
dda8d76d 10181get_32bit_dynamic_section (Filedata * filedata)
252b5132 10182{
2cf0635d
NC
10183 Elf32_External_Dyn * edyn;
10184 Elf32_External_Dyn * ext;
10185 Elf_Internal_Dyn * entry;
103f02d3 10186
978c4450
AM
10187 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10188 filedata->dynamic_addr, 1,
10189 filedata->dynamic_size,
10190 _("dynamic section"));
a6e9f9df 10191 if (!edyn)
015dc7e1 10192 return false;
103f02d3 10193
071436c6
NC
10194 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10195 might not have the luxury of section headers. Look for the DT_NULL
10196 terminator to determine the number of entries. */
978c4450
AM
10197 for (ext = edyn, filedata->dynamic_nent = 0;
10198 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10199 ext++)
10200 {
978c4450 10201 filedata->dynamic_nent++;
ba2685cc
AM
10202 if (BYTE_GET (ext->d_tag) == DT_NULL)
10203 break;
10204 }
252b5132 10205
978c4450
AM
10206 filedata->dynamic_section
10207 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10208 if (filedata->dynamic_section == NULL)
252b5132 10209 {
8b73c356 10210 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10211 (unsigned long) filedata->dynamic_nent);
9ea033b2 10212 free (edyn);
015dc7e1 10213 return false;
9ea033b2 10214 }
252b5132 10215
978c4450
AM
10216 for (ext = edyn, entry = filedata->dynamic_section;
10217 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10218 ext++, entry++)
9ea033b2 10219 {
fb514b26
AM
10220 entry->d_tag = BYTE_GET (ext->d_tag);
10221 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10222 }
10223
9ea033b2
NC
10224 free (edyn);
10225
015dc7e1 10226 return true;
9ea033b2
NC
10227}
10228
015dc7e1 10229static bool
dda8d76d 10230get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10231{
2cf0635d
NC
10232 Elf64_External_Dyn * edyn;
10233 Elf64_External_Dyn * ext;
10234 Elf_Internal_Dyn * entry;
103f02d3 10235
071436c6 10236 /* Read in the data. */
978c4450
AM
10237 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10238 filedata->dynamic_addr, 1,
10239 filedata->dynamic_size,
10240 _("dynamic section"));
a6e9f9df 10241 if (!edyn)
015dc7e1 10242 return false;
103f02d3 10243
071436c6
NC
10244 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10245 might not have the luxury of section headers. Look for the DT_NULL
10246 terminator to determine the number of entries. */
978c4450 10247 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10248 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10249 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10250 ext++)
10251 {
978c4450 10252 filedata->dynamic_nent++;
66543521 10253 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10254 break;
10255 }
252b5132 10256
978c4450
AM
10257 filedata->dynamic_section
10258 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10259 if (filedata->dynamic_section == NULL)
252b5132 10260 {
8b73c356 10261 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10262 (unsigned long) filedata->dynamic_nent);
252b5132 10263 free (edyn);
015dc7e1 10264 return false;
252b5132
RH
10265 }
10266
071436c6 10267 /* Convert from external to internal formats. */
978c4450
AM
10268 for (ext = edyn, entry = filedata->dynamic_section;
10269 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10270 ext++, entry++)
252b5132 10271 {
66543521
AM
10272 entry->d_tag = BYTE_GET (ext->d_tag);
10273 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10274 }
10275
10276 free (edyn);
10277
015dc7e1 10278 return true;
9ea033b2
NC
10279}
10280
e9e44622
JJ
10281static void
10282print_dynamic_flags (bfd_vma flags)
d1133906 10283{
015dc7e1 10284 bool first = true;
13ae64f3 10285
d1133906
NC
10286 while (flags)
10287 {
10288 bfd_vma flag;
10289
10290 flag = flags & - flags;
10291 flags &= ~ flag;
10292
e9e44622 10293 if (first)
015dc7e1 10294 first = false;
e9e44622
JJ
10295 else
10296 putc (' ', stdout);
13ae64f3 10297
d1133906
NC
10298 switch (flag)
10299 {
e9e44622
JJ
10300 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10301 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10302 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10303 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10304 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10305 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10306 }
10307 }
e9e44622 10308 puts ("");
d1133906
NC
10309}
10310
10ca4b04
L
10311static bfd_vma *
10312get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10313{
10314 unsigned char * e_data;
10315 bfd_vma * i_data;
10316
10317 /* If the size_t type is smaller than the bfd_size_type, eg because
10318 you are building a 32-bit tool on a 64-bit host, then make sure
10319 that when (number) is cast to (size_t) no information is lost. */
10320 if (sizeof (size_t) < sizeof (bfd_size_type)
10321 && (bfd_size_type) ((size_t) number) != number)
10322 {
10323 error (_("Size truncation prevents reading %s elements of size %u\n"),
10324 bfd_vmatoa ("u", number), ent_size);
10325 return NULL;
10326 }
10327
10328 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10329 attempting to allocate memory when the read is bound to fail. */
10330 if (ent_size * number > filedata->file_size)
10331 {
10332 error (_("Invalid number of dynamic entries: %s\n"),
10333 bfd_vmatoa ("u", number));
10334 return NULL;
10335 }
10336
10337 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10338 if (e_data == NULL)
10339 {
10340 error (_("Out of memory reading %s dynamic entries\n"),
10341 bfd_vmatoa ("u", number));
10342 return NULL;
10343 }
10344
10345 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10346 {
10347 error (_("Unable to read in %s bytes of dynamic data\n"),
10348 bfd_vmatoa ("u", number * ent_size));
10349 free (e_data);
10350 return NULL;
10351 }
10352
10353 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10354 if (i_data == NULL)
10355 {
10356 error (_("Out of memory allocating space for %s dynamic entries\n"),
10357 bfd_vmatoa ("u", number));
10358 free (e_data);
10359 return NULL;
10360 }
10361
10362 while (number--)
10363 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10364
10365 free (e_data);
10366
10367 return i_data;
10368}
10369
10370static unsigned long
10371get_num_dynamic_syms (Filedata * filedata)
10372{
10373 unsigned long num_of_syms = 0;
10374
10375 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10376 return num_of_syms;
10377
978c4450 10378 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10379 {
10380 unsigned char nb[8];
10381 unsigned char nc[8];
10382 unsigned int hash_ent_size = 4;
10383
10384 if ((filedata->file_header.e_machine == EM_ALPHA
10385 || filedata->file_header.e_machine == EM_S390
10386 || filedata->file_header.e_machine == EM_S390_OLD)
10387 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10388 hash_ent_size = 8;
10389
10390 if (fseek (filedata->handle,
978c4450
AM
10391 (filedata->archive_file_offset
10392 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10393 sizeof nb + sizeof nc)),
10394 SEEK_SET))
10395 {
10396 error (_("Unable to seek to start of dynamic information\n"));
10397 goto no_hash;
10398 }
10399
10400 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10401 {
10402 error (_("Failed to read in number of buckets\n"));
10403 goto no_hash;
10404 }
10405
10406 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10407 {
10408 error (_("Failed to read in number of chains\n"));
10409 goto no_hash;
10410 }
10411
978c4450
AM
10412 filedata->nbuckets = byte_get (nb, hash_ent_size);
10413 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10414
2482f306
AM
10415 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10416 {
10417 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10418 hash_ent_size);
10419 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10420 hash_ent_size);
001890e1 10421
2482f306
AM
10422 if (filedata->buckets != NULL && filedata->chains != NULL)
10423 num_of_syms = filedata->nchains;
10424 }
ceb9bf11 10425 no_hash:
10ca4b04
L
10426 if (num_of_syms == 0)
10427 {
9db70fc3
AM
10428 free (filedata->buckets);
10429 filedata->buckets = NULL;
10430 free (filedata->chains);
10431 filedata->chains = NULL;
978c4450 10432 filedata->nbuckets = 0;
10ca4b04
L
10433 }
10434 }
10435
978c4450 10436 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10437 {
10438 unsigned char nb[16];
10439 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10440 bfd_vma buckets_vma;
10441 unsigned long hn;
10ca4b04
L
10442
10443 if (fseek (filedata->handle,
978c4450
AM
10444 (filedata->archive_file_offset
10445 + offset_from_vma (filedata,
10446 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10447 sizeof nb)),
10448 SEEK_SET))
10449 {
10450 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10451 goto no_gnu_hash;
10452 }
10453
10454 if (fread (nb, 16, 1, filedata->handle) != 1)
10455 {
10456 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10457 goto no_gnu_hash;
10458 }
10459
978c4450
AM
10460 filedata->ngnubuckets = byte_get (nb, 4);
10461 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10462 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10463 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10464 if (is_32bit_elf)
10465 buckets_vma += bitmaskwords * 4;
10466 else
10467 buckets_vma += bitmaskwords * 8;
10468
10469 if (fseek (filedata->handle,
978c4450 10470 (filedata->archive_file_offset
10ca4b04
L
10471 + offset_from_vma (filedata, buckets_vma, 4)),
10472 SEEK_SET))
10473 {
10474 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10475 goto no_gnu_hash;
10476 }
10477
978c4450
AM
10478 filedata->gnubuckets
10479 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10480
978c4450 10481 if (filedata->gnubuckets == NULL)
90837ea7 10482 goto no_gnu_hash;
10ca4b04 10483
978c4450
AM
10484 for (i = 0; i < filedata->ngnubuckets; i++)
10485 if (filedata->gnubuckets[i] != 0)
10ca4b04 10486 {
978c4450 10487 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10488 goto no_gnu_hash;
10ca4b04 10489
978c4450
AM
10490 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10491 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10492 }
10493
10494 if (maxchain == 0xffffffff)
90837ea7 10495 goto no_gnu_hash;
10ca4b04 10496
978c4450 10497 maxchain -= filedata->gnusymidx;
10ca4b04
L
10498
10499 if (fseek (filedata->handle,
978c4450
AM
10500 (filedata->archive_file_offset
10501 + offset_from_vma (filedata,
10502 buckets_vma + 4 * (filedata->ngnubuckets
10503 + maxchain),
10504 4)),
10ca4b04
L
10505 SEEK_SET))
10506 {
10507 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10508 goto no_gnu_hash;
10509 }
10510
10511 do
10512 {
10513 if (fread (nb, 4, 1, filedata->handle) != 1)
10514 {
10515 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10516 goto no_gnu_hash;
10517 }
10518
10519 if (maxchain + 1 == 0)
90837ea7 10520 goto no_gnu_hash;
10ca4b04
L
10521
10522 ++maxchain;
10523 }
10524 while ((byte_get (nb, 4) & 1) == 0);
10525
10526 if (fseek (filedata->handle,
978c4450
AM
10527 (filedata->archive_file_offset
10528 + offset_from_vma (filedata, (buckets_vma
10529 + 4 * filedata->ngnubuckets),
10530 4)),
10ca4b04
L
10531 SEEK_SET))
10532 {
10533 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10534 goto no_gnu_hash;
10535 }
10536
978c4450
AM
10537 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10538 filedata->ngnuchains = maxchain;
10ca4b04 10539
978c4450 10540 if (filedata->gnuchains == NULL)
90837ea7 10541 goto no_gnu_hash;
10ca4b04 10542
978c4450 10543 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10544 {
10545 if (fseek (filedata->handle,
978c4450 10546 (filedata->archive_file_offset
10ca4b04 10547 + offset_from_vma (filedata, (buckets_vma
978c4450 10548 + 4 * (filedata->ngnubuckets
10ca4b04
L
10549 + maxchain)), 4)),
10550 SEEK_SET))
10551 {
10552 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10553 goto no_gnu_hash;
10554 }
10555
978c4450 10556 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10557 if (filedata->mipsxlat == NULL)
10558 goto no_gnu_hash;
10ca4b04
L
10559 }
10560
978c4450
AM
10561 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10562 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10563 {
978c4450
AM
10564 bfd_vma si = filedata->gnubuckets[hn];
10565 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10566
10567 do
10568 {
978c4450 10569 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 10570 {
c31ab5a0
AM
10571 if (off < filedata->ngnuchains
10572 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 10573 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
10574 }
10575 else
10576 {
10577 if (si >= num_of_syms)
10578 num_of_syms = si + 1;
10579 }
10580 si++;
10581 }
978c4450
AM
10582 while (off < filedata->ngnuchains
10583 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
10584 }
10585
90837ea7 10586 if (num_of_syms == 0)
10ca4b04 10587 {
90837ea7 10588 no_gnu_hash:
9db70fc3
AM
10589 free (filedata->mipsxlat);
10590 filedata->mipsxlat = NULL;
10591 free (filedata->gnuchains);
10592 filedata->gnuchains = NULL;
10593 free (filedata->gnubuckets);
10594 filedata->gnubuckets = NULL;
978c4450
AM
10595 filedata->ngnubuckets = 0;
10596 filedata->ngnuchains = 0;
10ca4b04
L
10597 }
10598 }
10599
10600 return num_of_syms;
10601}
10602
b2d38a17
NC
10603/* Parse and display the contents of the dynamic section. */
10604
015dc7e1 10605static bool
dda8d76d 10606process_dynamic_section (Filedata * filedata)
9ea033b2 10607{
2cf0635d 10608 Elf_Internal_Dyn * entry;
9ea033b2 10609
978c4450 10610 if (filedata->dynamic_size == 0)
9ea033b2
NC
10611 {
10612 if (do_dynamic)
ca0e11aa
NC
10613 {
10614 if (filedata->is_separate)
10615 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
10616 filedata->file_name);
10617 else
10618 printf (_("\nThere is no dynamic section in this file.\n"));
10619 }
9ea033b2 10620
015dc7e1 10621 return true;
9ea033b2
NC
10622 }
10623
10624 if (is_32bit_elf)
10625 {
dda8d76d 10626 if (! get_32bit_dynamic_section (filedata))
015dc7e1 10627 return false;
32ec8896
NC
10628 }
10629 else
10630 {
dda8d76d 10631 if (! get_64bit_dynamic_section (filedata))
015dc7e1 10632 return false;
9ea033b2 10633 }
9ea033b2 10634
252b5132 10635 /* Find the appropriate symbol table. */
978c4450 10636 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 10637 {
2482f306
AM
10638 unsigned long num_of_syms;
10639
978c4450
AM
10640 for (entry = filedata->dynamic_section;
10641 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10642 ++entry)
10ca4b04 10643 if (entry->d_tag == DT_SYMTAB)
978c4450 10644 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 10645 else if (entry->d_tag == DT_SYMENT)
978c4450 10646 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 10647 else if (entry->d_tag == DT_HASH)
978c4450 10648 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 10649 else if (entry->d_tag == DT_GNU_HASH)
978c4450 10650 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
10651 else if ((filedata->file_header.e_machine == EM_MIPS
10652 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10653 && entry->d_tag == DT_MIPS_XHASH)
10654 {
978c4450
AM
10655 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10656 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 10657 }
252b5132 10658
2482f306
AM
10659 num_of_syms = get_num_dynamic_syms (filedata);
10660
10661 if (num_of_syms != 0
10662 && filedata->dynamic_symbols == NULL
10663 && filedata->dynamic_info[DT_SYMTAB]
978c4450 10664 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
10665 {
10666 Elf_Internal_Phdr *seg;
2482f306 10667 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 10668
2482f306
AM
10669 if (! get_program_headers (filedata))
10670 {
10671 error (_("Cannot interpret virtual addresses "
10672 "without program headers.\n"));
015dc7e1 10673 return false;
2482f306 10674 }
252b5132 10675
2482f306
AM
10676 for (seg = filedata->program_headers;
10677 seg < filedata->program_headers + filedata->file_header.e_phnum;
10678 ++seg)
10679 {
10680 if (seg->p_type != PT_LOAD)
10681 continue;
252b5132 10682
2482f306
AM
10683 if (seg->p_offset + seg->p_filesz > filedata->file_size)
10684 {
10685 /* See PR 21379 for a reproducer. */
10686 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 10687 return false;
2482f306 10688 }
252b5132 10689
2482f306
AM
10690 if (vma >= (seg->p_vaddr & -seg->p_align)
10691 && vma < seg->p_vaddr + seg->p_filesz)
10692 {
10693 /* Since we do not know how big the symbol table is,
10694 we default to reading in up to the end of PT_LOAD
10695 segment and processing that. This is overkill, I
10696 know, but it should work. */
10697 Elf_Internal_Shdr section;
10698 section.sh_offset = (vma - seg->p_vaddr
10699 + seg->p_offset);
10700 section.sh_size = (num_of_syms
10701 * filedata->dynamic_info[DT_SYMENT]);
10702 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
10703
10704 if (do_checks
10705 && filedata->dynamic_symtab_section != NULL
10706 && ((filedata->dynamic_symtab_section->sh_offset
10707 != section.sh_offset)
10708 || (filedata->dynamic_symtab_section->sh_size
10709 != section.sh_size)
10710 || (filedata->dynamic_symtab_section->sh_entsize
10711 != section.sh_entsize)))
10712 warn (_("\
10713the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
10714
2482f306
AM
10715 section.sh_name = filedata->string_table_length;
10716 filedata->dynamic_symbols
10717 = GET_ELF_SYMBOLS (filedata, &section,
10718 &filedata->num_dynamic_syms);
10719 if (filedata->dynamic_symbols == NULL
10720 || filedata->num_dynamic_syms != num_of_syms)
10721 {
10722 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 10723 return false;
2482f306
AM
10724 }
10725 break;
10726 }
10727 }
10728 }
10729 }
252b5132
RH
10730
10731 /* Similarly find a string table. */
978c4450
AM
10732 if (filedata->dynamic_strings == NULL)
10733 for (entry = filedata->dynamic_section;
10734 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
10735 ++entry)
10736 {
10737 if (entry->d_tag == DT_STRTAB)
978c4450 10738 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 10739
10ca4b04 10740 if (entry->d_tag == DT_STRSZ)
978c4450 10741 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10742
978c4450
AM
10743 if (filedata->dynamic_info[DT_STRTAB]
10744 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
10745 {
10746 unsigned long offset;
978c4450 10747 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
10748
10749 offset = offset_from_vma (filedata,
978c4450 10750 filedata->dynamic_info[DT_STRTAB],
10ca4b04 10751 str_tab_len);
8ac10c5b
L
10752 if (do_checks
10753 && filedata->dynamic_strtab_section
10754 && ((filedata->dynamic_strtab_section->sh_offset
10755 != (file_ptr) offset)
10756 || (filedata->dynamic_strtab_section->sh_size
10757 != str_tab_len)))
10758 warn (_("\
10759the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
10760
978c4450
AM
10761 filedata->dynamic_strings
10762 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
10763 _("dynamic string table"));
10764 if (filedata->dynamic_strings == NULL)
10ca4b04
L
10765 {
10766 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10767 break;
10768 }
e3d39609 10769
978c4450 10770 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
10771 break;
10772 }
10773 }
252b5132
RH
10774
10775 /* And find the syminfo section if available. */
978c4450 10776 if (filedata->dynamic_syminfo == NULL)
252b5132 10777 {
3e8bba36 10778 unsigned long syminsz = 0;
252b5132 10779
978c4450
AM
10780 for (entry = filedata->dynamic_section;
10781 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10782 ++entry)
252b5132
RH
10783 {
10784 if (entry->d_tag == DT_SYMINENT)
10785 {
10786 /* Note: these braces are necessary to avoid a syntax
10787 error from the SunOS4 C compiler. */
049b0c3a
NC
10788 /* PR binutils/17531: A corrupt file can trigger this test.
10789 So do not use an assert, instead generate an error message. */
10790 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10791 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10792 (int) entry->d_un.d_val);
252b5132
RH
10793 }
10794 else if (entry->d_tag == DT_SYMINSZ)
10795 syminsz = entry->d_un.d_val;
10796 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
10797 filedata->dynamic_syminfo_offset
10798 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
10799 }
10800
978c4450 10801 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 10802 {
2cf0635d
NC
10803 Elf_External_Syminfo * extsyminfo;
10804 Elf_External_Syminfo * extsym;
10805 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10806
10807 /* There is a syminfo section. Read the data. */
3f5e193b 10808 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
10809 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
10810 1, syminsz, _("symbol information"));
a6e9f9df 10811 if (!extsyminfo)
015dc7e1 10812 return false;
252b5132 10813
978c4450 10814 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
10815 {
10816 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 10817 free (filedata->dynamic_syminfo);
e3d39609 10818 }
978c4450
AM
10819 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
10820 if (filedata->dynamic_syminfo == NULL)
252b5132 10821 {
2482f306
AM
10822 error (_("Out of memory allocating %lu bytes "
10823 "for dynamic symbol info\n"),
8b73c356 10824 (unsigned long) syminsz);
015dc7e1 10825 return false;
252b5132
RH
10826 }
10827
2482f306
AM
10828 filedata->dynamic_syminfo_nent
10829 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 10830 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
10831 syminfo < (filedata->dynamic_syminfo
10832 + filedata->dynamic_syminfo_nent);
86dba8ee 10833 ++syminfo, ++extsym)
252b5132 10834 {
86dba8ee
AM
10835 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10836 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10837 }
10838
10839 free (extsyminfo);
10840 }
10841 }
10842
978c4450 10843 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa
NC
10844 {
10845 if (filedata->dynamic_nent == 1)
10846 {
10847 if (filedata->is_separate)
10848 printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains 1 entry:\n"),
10849 filedata->file_name,
10850 filedata->dynamic_addr);
10851 else
10852 printf (_("\nDynamic section at offset 0x%lx contains 1 entry:\n"),
10853 filedata->dynamic_addr);
10854 }
10855 else
10856 {
10857 if (filedata->is_separate)
10858 printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n"),
10859 filedata->file_name,
10860 filedata->dynamic_addr,
10861 (unsigned long) filedata->dynamic_nent);
10862 else
10863 printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
10864 filedata->dynamic_addr,
10865 (unsigned long) filedata->dynamic_nent);
10866 }
10867 }
252b5132
RH
10868 if (do_dynamic)
10869 printf (_(" Tag Type Name/Value\n"));
10870
978c4450
AM
10871 for (entry = filedata->dynamic_section;
10872 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10873 entry++)
252b5132
RH
10874 {
10875 if (do_dynamic)
f7a99963 10876 {
2cf0635d 10877 const char * dtype;
e699b9ff 10878
f7a99963
NC
10879 putchar (' ');
10880 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10881 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10882 printf (" (%s)%*s", dtype,
32ec8896 10883 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10884 }
252b5132
RH
10885
10886 switch (entry->d_tag)
10887 {
d1133906
NC
10888 case DT_FLAGS:
10889 if (do_dynamic)
e9e44622 10890 print_dynamic_flags (entry->d_un.d_val);
d1133906 10891 break;
76da6bbe 10892
252b5132
RH
10893 case DT_AUXILIARY:
10894 case DT_FILTER:
019148e4
L
10895 case DT_CONFIG:
10896 case DT_DEPAUDIT:
10897 case DT_AUDIT:
252b5132
RH
10898 if (do_dynamic)
10899 {
019148e4 10900 switch (entry->d_tag)
b34976b6 10901 {
019148e4
L
10902 case DT_AUXILIARY:
10903 printf (_("Auxiliary library"));
10904 break;
10905
10906 case DT_FILTER:
10907 printf (_("Filter library"));
10908 break;
10909
b34976b6 10910 case DT_CONFIG:
019148e4
L
10911 printf (_("Configuration file"));
10912 break;
10913
10914 case DT_DEPAUDIT:
10915 printf (_("Dependency audit library"));
10916 break;
10917
10918 case DT_AUDIT:
10919 printf (_("Audit library"));
10920 break;
10921 }
252b5132 10922
978c4450
AM
10923 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10924 printf (": [%s]\n",
10925 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 10926 else
f7a99963
NC
10927 {
10928 printf (": ");
10929 print_vma (entry->d_un.d_val, PREFIX_HEX);
10930 putchar ('\n');
10931 }
252b5132
RH
10932 }
10933 break;
10934
dcefbbbd 10935 case DT_FEATURE:
252b5132
RH
10936 if (do_dynamic)
10937 {
10938 printf (_("Flags:"));
86f55779 10939
252b5132
RH
10940 if (entry->d_un.d_val == 0)
10941 printf (_(" None\n"));
10942 else
10943 {
10944 unsigned long int val = entry->d_un.d_val;
86f55779 10945
252b5132
RH
10946 if (val & DTF_1_PARINIT)
10947 {
10948 printf (" PARINIT");
10949 val ^= DTF_1_PARINIT;
10950 }
dcefbbbd
L
10951 if (val & DTF_1_CONFEXP)
10952 {
10953 printf (" CONFEXP");
10954 val ^= DTF_1_CONFEXP;
10955 }
252b5132
RH
10956 if (val != 0)
10957 printf (" %lx", val);
10958 puts ("");
10959 }
10960 }
10961 break;
10962
10963 case DT_POSFLAG_1:
10964 if (do_dynamic)
10965 {
10966 printf (_("Flags:"));
86f55779 10967
252b5132
RH
10968 if (entry->d_un.d_val == 0)
10969 printf (_(" None\n"));
10970 else
10971 {
10972 unsigned long int val = entry->d_un.d_val;
86f55779 10973
252b5132
RH
10974 if (val & DF_P1_LAZYLOAD)
10975 {
10976 printf (" LAZYLOAD");
10977 val ^= DF_P1_LAZYLOAD;
10978 }
10979 if (val & DF_P1_GROUPPERM)
10980 {
10981 printf (" GROUPPERM");
10982 val ^= DF_P1_GROUPPERM;
10983 }
10984 if (val != 0)
10985 printf (" %lx", val);
10986 puts ("");
10987 }
10988 }
10989 break;
10990
10991 case DT_FLAGS_1:
10992 if (do_dynamic)
10993 {
10994 printf (_("Flags:"));
10995 if (entry->d_un.d_val == 0)
10996 printf (_(" None\n"));
10997 else
10998 {
10999 unsigned long int val = entry->d_un.d_val;
86f55779 11000
252b5132
RH
11001 if (val & DF_1_NOW)
11002 {
11003 printf (" NOW");
11004 val ^= DF_1_NOW;
11005 }
11006 if (val & DF_1_GLOBAL)
11007 {
11008 printf (" GLOBAL");
11009 val ^= DF_1_GLOBAL;
11010 }
11011 if (val & DF_1_GROUP)
11012 {
11013 printf (" GROUP");
11014 val ^= DF_1_GROUP;
11015 }
11016 if (val & DF_1_NODELETE)
11017 {
11018 printf (" NODELETE");
11019 val ^= DF_1_NODELETE;
11020 }
11021 if (val & DF_1_LOADFLTR)
11022 {
11023 printf (" LOADFLTR");
11024 val ^= DF_1_LOADFLTR;
11025 }
11026 if (val & DF_1_INITFIRST)
11027 {
11028 printf (" INITFIRST");
11029 val ^= DF_1_INITFIRST;
11030 }
11031 if (val & DF_1_NOOPEN)
11032 {
11033 printf (" NOOPEN");
11034 val ^= DF_1_NOOPEN;
11035 }
11036 if (val & DF_1_ORIGIN)
11037 {
11038 printf (" ORIGIN");
11039 val ^= DF_1_ORIGIN;
11040 }
11041 if (val & DF_1_DIRECT)
11042 {
11043 printf (" DIRECT");
11044 val ^= DF_1_DIRECT;
11045 }
11046 if (val & DF_1_TRANS)
11047 {
11048 printf (" TRANS");
11049 val ^= DF_1_TRANS;
11050 }
11051 if (val & DF_1_INTERPOSE)
11052 {
11053 printf (" INTERPOSE");
11054 val ^= DF_1_INTERPOSE;
11055 }
f7db6139 11056 if (val & DF_1_NODEFLIB)
dcefbbbd 11057 {
f7db6139
L
11058 printf (" NODEFLIB");
11059 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11060 }
11061 if (val & DF_1_NODUMP)
11062 {
11063 printf (" NODUMP");
11064 val ^= DF_1_NODUMP;
11065 }
34b60028 11066 if (val & DF_1_CONFALT)
dcefbbbd 11067 {
34b60028
L
11068 printf (" CONFALT");
11069 val ^= DF_1_CONFALT;
11070 }
11071 if (val & DF_1_ENDFILTEE)
11072 {
11073 printf (" ENDFILTEE");
11074 val ^= DF_1_ENDFILTEE;
11075 }
11076 if (val & DF_1_DISPRELDNE)
11077 {
11078 printf (" DISPRELDNE");
11079 val ^= DF_1_DISPRELDNE;
11080 }
11081 if (val & DF_1_DISPRELPND)
11082 {
11083 printf (" DISPRELPND");
11084 val ^= DF_1_DISPRELPND;
11085 }
11086 if (val & DF_1_NODIRECT)
11087 {
11088 printf (" NODIRECT");
11089 val ^= DF_1_NODIRECT;
11090 }
11091 if (val & DF_1_IGNMULDEF)
11092 {
11093 printf (" IGNMULDEF");
11094 val ^= DF_1_IGNMULDEF;
11095 }
11096 if (val & DF_1_NOKSYMS)
11097 {
11098 printf (" NOKSYMS");
11099 val ^= DF_1_NOKSYMS;
11100 }
11101 if (val & DF_1_NOHDR)
11102 {
11103 printf (" NOHDR");
11104 val ^= DF_1_NOHDR;
11105 }
11106 if (val & DF_1_EDITED)
11107 {
11108 printf (" EDITED");
11109 val ^= DF_1_EDITED;
11110 }
11111 if (val & DF_1_NORELOC)
11112 {
11113 printf (" NORELOC");
11114 val ^= DF_1_NORELOC;
11115 }
11116 if (val & DF_1_SYMINTPOSE)
11117 {
11118 printf (" SYMINTPOSE");
11119 val ^= DF_1_SYMINTPOSE;
11120 }
11121 if (val & DF_1_GLOBAUDIT)
11122 {
11123 printf (" GLOBAUDIT");
11124 val ^= DF_1_GLOBAUDIT;
11125 }
11126 if (val & DF_1_SINGLETON)
11127 {
11128 printf (" SINGLETON");
11129 val ^= DF_1_SINGLETON;
dcefbbbd 11130 }
5c383f02
RO
11131 if (val & DF_1_STUB)
11132 {
11133 printf (" STUB");
11134 val ^= DF_1_STUB;
11135 }
11136 if (val & DF_1_PIE)
11137 {
11138 printf (" PIE");
11139 val ^= DF_1_PIE;
11140 }
b1202ffa
L
11141 if (val & DF_1_KMOD)
11142 {
11143 printf (" KMOD");
11144 val ^= DF_1_KMOD;
11145 }
11146 if (val & DF_1_WEAKFILTER)
11147 {
11148 printf (" WEAKFILTER");
11149 val ^= DF_1_WEAKFILTER;
11150 }
11151 if (val & DF_1_NOCOMMON)
11152 {
11153 printf (" NOCOMMON");
11154 val ^= DF_1_NOCOMMON;
11155 }
252b5132
RH
11156 if (val != 0)
11157 printf (" %lx", val);
11158 puts ("");
11159 }
11160 }
11161 break;
11162
11163 case DT_PLTREL:
978c4450 11164 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11165 if (do_dynamic)
dda8d76d 11166 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11167 break;
11168
11169 case DT_NULL :
11170 case DT_NEEDED :
11171 case DT_PLTGOT :
11172 case DT_HASH :
11173 case DT_STRTAB :
11174 case DT_SYMTAB :
11175 case DT_RELA :
11176 case DT_INIT :
11177 case DT_FINI :
11178 case DT_SONAME :
11179 case DT_RPATH :
11180 case DT_SYMBOLIC:
11181 case DT_REL :
11182 case DT_DEBUG :
11183 case DT_TEXTREL :
11184 case DT_JMPREL :
019148e4 11185 case DT_RUNPATH :
978c4450 11186 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11187
11188 if (do_dynamic)
11189 {
2cf0635d 11190 char * name;
252b5132 11191
978c4450
AM
11192 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
11193 name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11194 else
d79b3d50 11195 name = NULL;
252b5132
RH
11196
11197 if (name)
11198 {
11199 switch (entry->d_tag)
11200 {
11201 case DT_NEEDED:
11202 printf (_("Shared library: [%s]"), name);
11203
13acb58d
AM
11204 if (filedata->program_interpreter
11205 && streq (name, filedata->program_interpreter))
f7a99963 11206 printf (_(" program interpreter"));
252b5132
RH
11207 break;
11208
11209 case DT_SONAME:
f7a99963 11210 printf (_("Library soname: [%s]"), name);
252b5132
RH
11211 break;
11212
11213 case DT_RPATH:
f7a99963 11214 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11215 break;
11216
019148e4
L
11217 case DT_RUNPATH:
11218 printf (_("Library runpath: [%s]"), name);
11219 break;
11220
252b5132 11221 default:
f7a99963
NC
11222 print_vma (entry->d_un.d_val, PREFIX_HEX);
11223 break;
252b5132
RH
11224 }
11225 }
11226 else
f7a99963
NC
11227 print_vma (entry->d_un.d_val, PREFIX_HEX);
11228
11229 putchar ('\n');
252b5132
RH
11230 }
11231 break;
11232
11233 case DT_PLTRELSZ:
11234 case DT_RELASZ :
11235 case DT_STRSZ :
11236 case DT_RELSZ :
11237 case DT_RELAENT :
11238 case DT_SYMENT :
11239 case DT_RELENT :
978c4450 11240 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11241 /* Fall through. */
252b5132
RH
11242 case DT_PLTPADSZ:
11243 case DT_MOVEENT :
11244 case DT_MOVESZ :
11245 case DT_INIT_ARRAYSZ:
11246 case DT_FINI_ARRAYSZ:
047b2264
JJ
11247 case DT_GNU_CONFLICTSZ:
11248 case DT_GNU_LIBLISTSZ:
252b5132 11249 if (do_dynamic)
f7a99963
NC
11250 {
11251 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11252 printf (_(" (bytes)\n"));
f7a99963 11253 }
252b5132
RH
11254 break;
11255
11256 case DT_VERDEFNUM:
11257 case DT_VERNEEDNUM:
11258 case DT_RELACOUNT:
11259 case DT_RELCOUNT:
11260 if (do_dynamic)
f7a99963
NC
11261 {
11262 print_vma (entry->d_un.d_val, UNSIGNED);
11263 putchar ('\n');
11264 }
252b5132
RH
11265 break;
11266
11267 case DT_SYMINSZ:
11268 case DT_SYMINENT:
11269 case DT_SYMINFO:
11270 case DT_USED:
11271 case DT_INIT_ARRAY:
11272 case DT_FINI_ARRAY:
11273 if (do_dynamic)
11274 {
d79b3d50 11275 if (entry->d_tag == DT_USED
978c4450 11276 && VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
252b5132 11277 {
978c4450 11278 char * name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11279
b34976b6 11280 if (*name)
252b5132
RH
11281 {
11282 printf (_("Not needed object: [%s]\n"), name);
11283 break;
11284 }
11285 }
103f02d3 11286
f7a99963
NC
11287 print_vma (entry->d_un.d_val, PREFIX_HEX);
11288 putchar ('\n');
252b5132
RH
11289 }
11290 break;
11291
11292 case DT_BIND_NOW:
11293 /* The value of this entry is ignored. */
35b1837e
AM
11294 if (do_dynamic)
11295 putchar ('\n');
252b5132 11296 break;
103f02d3 11297
047b2264
JJ
11298 case DT_GNU_PRELINKED:
11299 if (do_dynamic)
11300 {
2cf0635d 11301 struct tm * tmp;
91d6fa6a 11302 time_t atime = entry->d_un.d_val;
047b2264 11303
91d6fa6a 11304 tmp = gmtime (&atime);
071436c6
NC
11305 /* PR 17533 file: 041-1244816-0.004. */
11306 if (tmp == NULL)
5a2cbcf4
L
11307 printf (_("<corrupt time val: %lx"),
11308 (unsigned long) atime);
071436c6
NC
11309 else
11310 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11311 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11312 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11313
11314 }
11315 break;
11316
fdc90cb4 11317 case DT_GNU_HASH:
978c4450 11318 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11319 if (do_dynamic)
11320 {
11321 print_vma (entry->d_un.d_val, PREFIX_HEX);
11322 putchar ('\n');
11323 }
11324 break;
11325
a5da3dee
VDM
11326 case DT_GNU_FLAGS_1:
11327 if (do_dynamic)
11328 {
11329 printf (_("Flags:"));
11330 if (entry->d_un.d_val == 0)
11331 printf (_(" None\n"));
11332 else
11333 {
11334 unsigned long int val = entry->d_un.d_val;
11335
11336 if (val & DF_GNU_1_UNIQUE)
11337 {
11338 printf (" UNIQUE");
11339 val ^= DF_GNU_1_UNIQUE;
11340 }
11341 if (val != 0)
11342 printf (" %lx", val);
11343 puts ("");
11344 }
11345 }
11346 break;
11347
252b5132
RH
11348 default:
11349 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11350 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11351 = entry->d_un.d_val;
252b5132
RH
11352
11353 if (do_dynamic)
11354 {
dda8d76d 11355 switch (filedata->file_header.e_machine)
252b5132 11356 {
37c18eed
SD
11357 case EM_AARCH64:
11358 dynamic_section_aarch64_val (entry);
11359 break;
252b5132 11360 case EM_MIPS:
4fe85591 11361 case EM_MIPS_RS3_LE:
978c4450 11362 dynamic_section_mips_val (filedata, entry);
252b5132 11363 break;
103f02d3 11364 case EM_PARISC:
b2d38a17 11365 dynamic_section_parisc_val (entry);
103f02d3 11366 break;
ecc51f48 11367 case EM_IA_64:
b2d38a17 11368 dynamic_section_ia64_val (entry);
ecc51f48 11369 break;
252b5132 11370 default:
f7a99963
NC
11371 print_vma (entry->d_un.d_val, PREFIX_HEX);
11372 putchar ('\n');
252b5132
RH
11373 }
11374 }
11375 break;
11376 }
11377 }
11378
015dc7e1 11379 return true;
252b5132
RH
11380}
11381
11382static char *
d3ba0551 11383get_ver_flags (unsigned int flags)
252b5132 11384{
6d4f21f6 11385 static char buff[128];
252b5132
RH
11386
11387 buff[0] = 0;
11388
11389 if (flags == 0)
11390 return _("none");
11391
11392 if (flags & VER_FLG_BASE)
7bb1ad17 11393 strcat (buff, "BASE");
252b5132
RH
11394
11395 if (flags & VER_FLG_WEAK)
11396 {
11397 if (flags & VER_FLG_BASE)
7bb1ad17 11398 strcat (buff, " | ");
252b5132 11399
7bb1ad17 11400 strcat (buff, "WEAK");
252b5132
RH
11401 }
11402
44ec90b9
RO
11403 if (flags & VER_FLG_INFO)
11404 {
11405 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11406 strcat (buff, " | ");
44ec90b9 11407
7bb1ad17 11408 strcat (buff, "INFO");
44ec90b9
RO
11409 }
11410
11411 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11412 {
11413 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11414 strcat (buff, " | ");
11415
11416 strcat (buff, _("<unknown>"));
11417 }
252b5132
RH
11418
11419 return buff;
11420}
11421
11422/* Display the contents of the version sections. */
98fb390a 11423
015dc7e1 11424static bool
dda8d76d 11425process_version_sections (Filedata * filedata)
252b5132 11426{
2cf0635d 11427 Elf_Internal_Shdr * section;
b34976b6 11428 unsigned i;
015dc7e1 11429 bool found = false;
252b5132
RH
11430
11431 if (! do_version)
015dc7e1 11432 return true;
252b5132 11433
dda8d76d
NC
11434 for (i = 0, section = filedata->section_headers;
11435 i < filedata->file_header.e_shnum;
b34976b6 11436 i++, section++)
252b5132
RH
11437 {
11438 switch (section->sh_type)
11439 {
11440 case SHT_GNU_verdef:
11441 {
2cf0635d 11442 Elf_External_Verdef * edefs;
452bf675
AM
11443 unsigned long idx;
11444 unsigned long cnt;
2cf0635d 11445 char * endbuf;
252b5132 11446
015dc7e1 11447 found = true;
252b5132 11448
ca0e11aa
NC
11449 if (filedata->is_separate)
11450 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
11451 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
11452 section->sh_info),
11453 filedata->file_name,
11454 printable_section_name (filedata, section),
11455 section->sh_info);
11456 else
11457 printf (ngettext ("\nVersion definition section '%s' "
11458 "contains %u entry:\n",
11459 "\nVersion definition section '%s' "
11460 "contains %u entries:\n",
11461 section->sh_info),
11462 printable_section_name (filedata, section),
11463 section->sh_info);
047c3dbf 11464
ae9ac79e 11465 printf (_(" Addr: 0x"));
252b5132 11466 printf_vma (section->sh_addr);
233f82cf 11467 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11468 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11469 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11470
3f5e193b 11471 edefs = (Elf_External_Verdef *)
dda8d76d 11472 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11473 _("version definition section"));
a6e9f9df
AM
11474 if (!edefs)
11475 break;
59245841 11476 endbuf = (char *) edefs + section->sh_size;
252b5132 11477
1445030f 11478 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11479 {
2cf0635d
NC
11480 char * vstart;
11481 Elf_External_Verdef * edef;
b34976b6 11482 Elf_Internal_Verdef ent;
2cf0635d 11483 Elf_External_Verdaux * eaux;
b34976b6 11484 Elf_Internal_Verdaux aux;
452bf675 11485 unsigned long isum;
b34976b6 11486 int j;
103f02d3 11487
252b5132 11488 vstart = ((char *) edefs) + idx;
54806181
AM
11489 if (vstart + sizeof (*edef) > endbuf)
11490 break;
252b5132
RH
11491
11492 edef = (Elf_External_Verdef *) vstart;
11493
11494 ent.vd_version = BYTE_GET (edef->vd_version);
11495 ent.vd_flags = BYTE_GET (edef->vd_flags);
11496 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11497 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11498 ent.vd_hash = BYTE_GET (edef->vd_hash);
11499 ent.vd_aux = BYTE_GET (edef->vd_aux);
11500 ent.vd_next = BYTE_GET (edef->vd_next);
11501
452bf675 11502 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11503 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11504
11505 printf (_(" Index: %d Cnt: %d "),
11506 ent.vd_ndx, ent.vd_cnt);
11507
452bf675 11508 /* Check for overflow. */
1445030f 11509 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11510 break;
11511
252b5132
RH
11512 vstart += ent.vd_aux;
11513
1445030f
AM
11514 if (vstart + sizeof (*eaux) > endbuf)
11515 break;
252b5132
RH
11516 eaux = (Elf_External_Verdaux *) vstart;
11517
11518 aux.vda_name = BYTE_GET (eaux->vda_name);
11519 aux.vda_next = BYTE_GET (eaux->vda_next);
11520
978c4450
AM
11521 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
11522 printf (_("Name: %s\n"),
11523 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132
RH
11524 else
11525 printf (_("Name index: %ld\n"), aux.vda_name);
11526
11527 isum = idx + ent.vd_aux;
11528
b34976b6 11529 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11530 {
1445030f
AM
11531 if (aux.vda_next < sizeof (*eaux)
11532 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11533 {
11534 warn (_("Invalid vda_next field of %lx\n"),
11535 aux.vda_next);
11536 j = ent.vd_cnt;
11537 break;
11538 }
dd24e3da 11539 /* Check for overflow. */
7e26601c 11540 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11541 break;
11542
252b5132
RH
11543 isum += aux.vda_next;
11544 vstart += aux.vda_next;
11545
54806181
AM
11546 if (vstart + sizeof (*eaux) > endbuf)
11547 break;
1445030f 11548 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11549
11550 aux.vda_name = BYTE_GET (eaux->vda_name);
11551 aux.vda_next = BYTE_GET (eaux->vda_next);
11552
978c4450 11553 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
452bf675 11554 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450
AM
11555 isum, j,
11556 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132 11557 else
452bf675 11558 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11559 isum, j, aux.vda_name);
11560 }
dd24e3da 11561
54806181
AM
11562 if (j < ent.vd_cnt)
11563 printf (_(" Version def aux past end of section\n"));
252b5132 11564
c9f02c3e
MR
11565 /* PR 17531:
11566 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11567 if (ent.vd_next < sizeof (*edef)
11568 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11569 {
11570 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11571 cnt = section->sh_info;
11572 break;
11573 }
452bf675 11574 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11575 break;
11576
252b5132
RH
11577 idx += ent.vd_next;
11578 }
dd24e3da 11579
54806181
AM
11580 if (cnt < section->sh_info)
11581 printf (_(" Version definition past end of section\n"));
252b5132
RH
11582
11583 free (edefs);
11584 }
11585 break;
103f02d3 11586
252b5132
RH
11587 case SHT_GNU_verneed:
11588 {
2cf0635d 11589 Elf_External_Verneed * eneed;
452bf675
AM
11590 unsigned long idx;
11591 unsigned long cnt;
2cf0635d 11592 char * endbuf;
252b5132 11593
015dc7e1 11594 found = true;
252b5132 11595
ca0e11aa
NC
11596 if (filedata->is_separate)
11597 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
11598 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
11599 section->sh_info),
11600 filedata->file_name,
11601 printable_section_name (filedata, section),
11602 section->sh_info);
11603 else
11604 printf (ngettext ("\nVersion needs section '%s' "
11605 "contains %u entry:\n",
11606 "\nVersion needs section '%s' "
11607 "contains %u entries:\n",
11608 section->sh_info),
11609 printable_section_name (filedata, section),
11610 section->sh_info);
047c3dbf 11611
252b5132
RH
11612 printf (_(" Addr: 0x"));
11613 printf_vma (section->sh_addr);
72de5009 11614 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11615 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11616 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11617
dda8d76d 11618 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11619 section->sh_offset, 1,
11620 section->sh_size,
9cf03b7e 11621 _("Version Needs section"));
a6e9f9df
AM
11622 if (!eneed)
11623 break;
59245841 11624 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11625
11626 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11627 {
2cf0635d 11628 Elf_External_Verneed * entry;
b34976b6 11629 Elf_Internal_Verneed ent;
452bf675 11630 unsigned long isum;
b34976b6 11631 int j;
2cf0635d 11632 char * vstart;
252b5132
RH
11633
11634 vstart = ((char *) eneed) + idx;
54806181
AM
11635 if (vstart + sizeof (*entry) > endbuf)
11636 break;
252b5132
RH
11637
11638 entry = (Elf_External_Verneed *) vstart;
11639
11640 ent.vn_version = BYTE_GET (entry->vn_version);
11641 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11642 ent.vn_file = BYTE_GET (entry->vn_file);
11643 ent.vn_aux = BYTE_GET (entry->vn_aux);
11644 ent.vn_next = BYTE_GET (entry->vn_next);
11645
452bf675 11646 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11647
978c4450
AM
11648 if (VALID_DYNAMIC_NAME (filedata, ent.vn_file))
11649 printf (_(" File: %s"),
11650 GET_DYNAMIC_NAME (filedata, ent.vn_file));
252b5132
RH
11651 else
11652 printf (_(" File: %lx"), ent.vn_file);
11653
11654 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11655
dd24e3da 11656 /* Check for overflow. */
7e26601c 11657 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11658 break;
252b5132
RH
11659 vstart += ent.vn_aux;
11660
11661 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11662 {
2cf0635d 11663 Elf_External_Vernaux * eaux;
b34976b6 11664 Elf_Internal_Vernaux aux;
252b5132 11665
54806181
AM
11666 if (vstart + sizeof (*eaux) > endbuf)
11667 break;
252b5132
RH
11668 eaux = (Elf_External_Vernaux *) vstart;
11669
11670 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11671 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11672 aux.vna_other = BYTE_GET (eaux->vna_other);
11673 aux.vna_name = BYTE_GET (eaux->vna_name);
11674 aux.vna_next = BYTE_GET (eaux->vna_next);
11675
978c4450 11676 if (VALID_DYNAMIC_NAME (filedata, aux.vna_name))
452bf675 11677 printf (_(" %#06lx: Name: %s"),
978c4450 11678 isum, GET_DYNAMIC_NAME (filedata, aux.vna_name));
252b5132 11679 else
452bf675 11680 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11681 isum, aux.vna_name);
11682
11683 printf (_(" Flags: %s Version: %d\n"),
11684 get_ver_flags (aux.vna_flags), aux.vna_other);
11685
1445030f
AM
11686 if (aux.vna_next < sizeof (*eaux)
11687 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11688 {
11689 warn (_("Invalid vna_next field of %lx\n"),
11690 aux.vna_next);
11691 j = ent.vn_cnt;
11692 break;
11693 }
1445030f
AM
11694 /* Check for overflow. */
11695 if (aux.vna_next > (size_t) (endbuf - vstart))
11696 break;
252b5132
RH
11697 isum += aux.vna_next;
11698 vstart += aux.vna_next;
11699 }
9cf03b7e 11700
54806181 11701 if (j < ent.vn_cnt)
f9a6a8f0 11702 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 11703
1445030f
AM
11704 if (ent.vn_next < sizeof (*entry)
11705 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11706 {
452bf675 11707 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11708 cnt = section->sh_info;
11709 break;
11710 }
1445030f
AM
11711 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11712 break;
252b5132
RH
11713 idx += ent.vn_next;
11714 }
9cf03b7e 11715
54806181 11716 if (cnt < section->sh_info)
9cf03b7e 11717 warn (_("Missing Version Needs information\n"));
103f02d3 11718
252b5132
RH
11719 free (eneed);
11720 }
11721 break;
11722
11723 case SHT_GNU_versym:
11724 {
2cf0635d 11725 Elf_Internal_Shdr * link_section;
8b73c356
NC
11726 size_t total;
11727 unsigned int cnt;
2cf0635d
NC
11728 unsigned char * edata;
11729 unsigned short * data;
11730 char * strtab;
11731 Elf_Internal_Sym * symbols;
11732 Elf_Internal_Shdr * string_sec;
ba5cdace 11733 unsigned long num_syms;
d3ba0551 11734 long off;
252b5132 11735
dda8d76d 11736 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11737 break;
11738
dda8d76d 11739 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11740 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11741
dda8d76d 11742 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11743 break;
11744
015dc7e1 11745 found = true;
252b5132 11746
dda8d76d 11747 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
11748 if (symbols == NULL)
11749 break;
252b5132 11750
dda8d76d 11751 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11752
dda8d76d 11753 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11754 string_sec->sh_size,
11755 _("version string table"));
a6e9f9df 11756 if (!strtab)
0429c154
MS
11757 {
11758 free (symbols);
11759 break;
11760 }
252b5132 11761
ca0e11aa
NC
11762 if (filedata->is_separate)
11763 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
11764 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
11765 total),
11766 filedata->file_name,
11767 printable_section_name (filedata, section),
11768 (unsigned long) total);
11769 else
11770 printf (ngettext ("\nVersion symbols section '%s' "
11771 "contains %lu entry:\n",
11772 "\nVersion symbols section '%s' "
11773 "contains %lu entries:\n",
11774 total),
11775 printable_section_name (filedata, section),
11776 (unsigned long) total);
252b5132 11777
ae9ac79e 11778 printf (_(" Addr: 0x"));
252b5132 11779 printf_vma (section->sh_addr);
72de5009 11780 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11781 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11782 printable_section_name (filedata, link_section));
252b5132 11783
dda8d76d 11784 off = offset_from_vma (filedata,
978c4450 11785 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11786 total * sizeof (short));
95099889
AM
11787 edata = (unsigned char *) get_data (NULL, filedata, off,
11788 sizeof (short), total,
11789 _("version symbol data"));
a6e9f9df
AM
11790 if (!edata)
11791 {
11792 free (strtab);
0429c154 11793 free (symbols);
a6e9f9df
AM
11794 break;
11795 }
252b5132 11796
3f5e193b 11797 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11798
11799 for (cnt = total; cnt --;)
b34976b6
AM
11800 data[cnt] = byte_get (edata + cnt * sizeof (short),
11801 sizeof (short));
252b5132
RH
11802
11803 free (edata);
11804
11805 for (cnt = 0; cnt < total; cnt += 4)
11806 {
11807 int j, nn;
ab273396
AM
11808 char *name;
11809 char *invalid = _("*invalid*");
252b5132
RH
11810
11811 printf (" %03x:", cnt);
11812
11813 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11814 switch (data[cnt + j])
252b5132
RH
11815 {
11816 case 0:
11817 fputs (_(" 0 (*local*) "), stdout);
11818 break;
11819
11820 case 1:
11821 fputs (_(" 1 (*global*) "), stdout);
11822 break;
11823
11824 default:
c244d050
NC
11825 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11826 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11827
dd24e3da 11828 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11829 array, break to avoid an out-of-bounds read. */
11830 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11831 {
11832 warn (_("invalid index into symbol array\n"));
11833 break;
11834 }
11835
ab273396 11836 name = NULL;
978c4450 11837 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11838 {
b34976b6
AM
11839 Elf_Internal_Verneed ivn;
11840 unsigned long offset;
252b5132 11841
d93f0186 11842 offset = offset_from_vma
978c4450
AM
11843 (filedata,
11844 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11845 sizeof (Elf_External_Verneed));
252b5132 11846
b34976b6 11847 do
252b5132 11848 {
b34976b6
AM
11849 Elf_Internal_Vernaux ivna;
11850 Elf_External_Verneed evn;
11851 Elf_External_Vernaux evna;
11852 unsigned long a_off;
252b5132 11853
dda8d76d 11854 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11855 _("version need")) == NULL)
11856 break;
0b4362b0 11857
252b5132
RH
11858 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11859 ivn.vn_next = BYTE_GET (evn.vn_next);
11860
11861 a_off = offset + ivn.vn_aux;
11862
11863 do
11864 {
dda8d76d 11865 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11866 1, _("version need aux (2)")) == NULL)
11867 {
11868 ivna.vna_next = 0;
11869 ivna.vna_other = 0;
11870 }
11871 else
11872 {
11873 ivna.vna_next = BYTE_GET (evna.vna_next);
11874 ivna.vna_other = BYTE_GET (evna.vna_other);
11875 }
252b5132
RH
11876
11877 a_off += ivna.vna_next;
11878 }
b34976b6 11879 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11880 && ivna.vna_next != 0);
11881
b34976b6 11882 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11883 {
11884 ivna.vna_name = BYTE_GET (evna.vna_name);
11885
54806181 11886 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11887 name = invalid;
54806181
AM
11888 else
11889 name = strtab + ivna.vna_name;
252b5132
RH
11890 break;
11891 }
11892
11893 offset += ivn.vn_next;
11894 }
11895 while (ivn.vn_next);
11896 }
00d93f34 11897
ab273396 11898 if (data[cnt + j] != 0x8001
978c4450 11899 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 11900 {
b34976b6
AM
11901 Elf_Internal_Verdef ivd;
11902 Elf_External_Verdef evd;
11903 unsigned long offset;
252b5132 11904
d93f0186 11905 offset = offset_from_vma
978c4450
AM
11906 (filedata,
11907 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 11908 sizeof evd);
252b5132
RH
11909
11910 do
11911 {
dda8d76d 11912 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
11913 _("version def")) == NULL)
11914 {
11915 ivd.vd_next = 0;
948f632f 11916 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
11917 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
11918 break;
59245841
NC
11919 }
11920 else
11921 {
11922 ivd.vd_next = BYTE_GET (evd.vd_next);
11923 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11924 }
252b5132
RH
11925
11926 offset += ivd.vd_next;
11927 }
c244d050 11928 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
11929 && ivd.vd_next != 0);
11930
c244d050 11931 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 11932 {
b34976b6
AM
11933 Elf_External_Verdaux evda;
11934 Elf_Internal_Verdaux ivda;
252b5132
RH
11935
11936 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11937
dda8d76d 11938 if (get_data (&evda, filedata,
59245841
NC
11939 offset - ivd.vd_next + ivd.vd_aux,
11940 sizeof (evda), 1,
11941 _("version def aux")) == NULL)
11942 break;
252b5132
RH
11943
11944 ivda.vda_name = BYTE_GET (evda.vda_name);
11945
54806181 11946 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
11947 name = invalid;
11948 else if (name != NULL && name != invalid)
11949 name = _("*both*");
54806181
AM
11950 else
11951 name = strtab + ivda.vda_name;
252b5132
RH
11952 }
11953 }
ab273396
AM
11954 if (name != NULL)
11955 nn += printf ("(%s%-*s",
11956 name,
11957 12 - (int) strlen (name),
11958 ")");
252b5132
RH
11959
11960 if (nn < 18)
11961 printf ("%*c", 18 - nn, ' ');
11962 }
11963
11964 putchar ('\n');
11965 }
11966
11967 free (data);
11968 free (strtab);
11969 free (symbols);
11970 }
11971 break;
103f02d3 11972
252b5132
RH
11973 default:
11974 break;
11975 }
11976 }
11977
11978 if (! found)
ca0e11aa
NC
11979 {
11980 if (filedata->is_separate)
11981 printf (_("\nNo version information found in linked file '%s'.\n"),
11982 filedata->file_name);
11983 else
11984 printf (_("\nNo version information found in this file.\n"));
11985 }
252b5132 11986
015dc7e1 11987 return true;
252b5132
RH
11988}
11989
d1133906 11990static const char *
dda8d76d 11991get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 11992{
89246a0e 11993 static char buff[64];
252b5132
RH
11994
11995 switch (binding)
11996 {
b34976b6
AM
11997 case STB_LOCAL: return "LOCAL";
11998 case STB_GLOBAL: return "GLOBAL";
11999 case STB_WEAK: return "WEAK";
252b5132
RH
12000 default:
12001 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12002 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12003 binding);
252b5132 12004 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12005 {
12006 if (binding == STB_GNU_UNIQUE
df3a023b 12007 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12008 return "UNIQUE";
12009 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12010 }
252b5132 12011 else
e9e44622 12012 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12013 return buff;
12014 }
12015}
12016
d1133906 12017static const char *
dda8d76d 12018get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12019{
89246a0e 12020 static char buff[64];
252b5132
RH
12021
12022 switch (type)
12023 {
b34976b6
AM
12024 case STT_NOTYPE: return "NOTYPE";
12025 case STT_OBJECT: return "OBJECT";
12026 case STT_FUNC: return "FUNC";
12027 case STT_SECTION: return "SECTION";
12028 case STT_FILE: return "FILE";
12029 case STT_COMMON: return "COMMON";
12030 case STT_TLS: return "TLS";
15ab5209
DB
12031 case STT_RELC: return "RELC";
12032 case STT_SRELC: return "SRELC";
252b5132
RH
12033 default:
12034 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12035 {
dda8d76d 12036 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12037 return "THUMB_FUNC";
103f02d3 12038
dda8d76d 12039 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12040 return "REGISTER";
12041
dda8d76d 12042 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12043 return "PARISC_MILLI";
12044
e9e44622 12045 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12046 }
252b5132 12047 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12048 {
dda8d76d 12049 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12050 {
12051 if (type == STT_HP_OPAQUE)
12052 return "HP_OPAQUE";
12053 if (type == STT_HP_STUB)
12054 return "HP_STUB";
12055 }
12056
d8045f23 12057 if (type == STT_GNU_IFUNC
dda8d76d 12058 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12059 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12060 return "IFUNC";
12061
e9e44622 12062 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12063 }
252b5132 12064 else
e9e44622 12065 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12066 return buff;
12067 }
12068}
12069
d1133906 12070static const char *
d3ba0551 12071get_symbol_visibility (unsigned int visibility)
d1133906
NC
12072{
12073 switch (visibility)
12074 {
b34976b6
AM
12075 case STV_DEFAULT: return "DEFAULT";
12076 case STV_INTERNAL: return "INTERNAL";
12077 case STV_HIDDEN: return "HIDDEN";
d1133906 12078 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12079 default:
27a45f42 12080 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12081 return _("<unknown>");
d1133906
NC
12082 }
12083}
12084
2057d69d
CZ
12085static const char *
12086get_alpha_symbol_other (unsigned int other)
9abca702 12087{
2057d69d
CZ
12088 switch (other)
12089 {
12090 case STO_ALPHA_NOPV: return "NOPV";
12091 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12092 default:
27a45f42 12093 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12094 return _("<unknown>");
9abca702 12095 }
2057d69d
CZ
12096}
12097
fd85a6a1
NC
12098static const char *
12099get_solaris_symbol_visibility (unsigned int visibility)
12100{
12101 switch (visibility)
12102 {
12103 case 4: return "EXPORTED";
12104 case 5: return "SINGLETON";
12105 case 6: return "ELIMINATE";
12106 default: return get_symbol_visibility (visibility);
12107 }
12108}
12109
2301ed1c
SN
12110static const char *
12111get_aarch64_symbol_other (unsigned int other)
12112{
12113 static char buf[32];
12114
12115 if (other & STO_AARCH64_VARIANT_PCS)
12116 {
12117 other &= ~STO_AARCH64_VARIANT_PCS;
12118 if (other == 0)
12119 return "VARIANT_PCS";
12120 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12121 return buf;
12122 }
12123 return NULL;
12124}
12125
5e2b0d47
NC
12126static const char *
12127get_mips_symbol_other (unsigned int other)
12128{
12129 switch (other)
12130 {
32ec8896
NC
12131 case STO_OPTIONAL: return "OPTIONAL";
12132 case STO_MIPS_PLT: return "MIPS PLT";
12133 case STO_MIPS_PIC: return "MIPS PIC";
12134 case STO_MICROMIPS: return "MICROMIPS";
12135 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12136 case STO_MIPS16: return "MIPS16";
12137 default: return NULL;
5e2b0d47
NC
12138 }
12139}
12140
28f997cf 12141static const char *
dda8d76d 12142get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12143{
dda8d76d 12144 if (is_ia64_vms (filedata))
28f997cf
TG
12145 {
12146 static char res[32];
12147
12148 res[0] = 0;
12149
12150 /* Function types is for images and .STB files only. */
dda8d76d 12151 switch (filedata->file_header.e_type)
28f997cf
TG
12152 {
12153 case ET_DYN:
12154 case ET_EXEC:
12155 switch (VMS_ST_FUNC_TYPE (other))
12156 {
12157 case VMS_SFT_CODE_ADDR:
12158 strcat (res, " CA");
12159 break;
12160 case VMS_SFT_SYMV_IDX:
12161 strcat (res, " VEC");
12162 break;
12163 case VMS_SFT_FD:
12164 strcat (res, " FD");
12165 break;
12166 case VMS_SFT_RESERVE:
12167 strcat (res, " RSV");
12168 break;
12169 default:
bee0ee85
NC
12170 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12171 VMS_ST_FUNC_TYPE (other));
12172 strcat (res, " <unknown>");
12173 break;
28f997cf
TG
12174 }
12175 break;
12176 default:
12177 break;
12178 }
12179 switch (VMS_ST_LINKAGE (other))
12180 {
12181 case VMS_STL_IGNORE:
12182 strcat (res, " IGN");
12183 break;
12184 case VMS_STL_RESERVE:
12185 strcat (res, " RSV");
12186 break;
12187 case VMS_STL_STD:
12188 strcat (res, " STD");
12189 break;
12190 case VMS_STL_LNK:
12191 strcat (res, " LNK");
12192 break;
12193 default:
bee0ee85
NC
12194 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12195 VMS_ST_LINKAGE (other));
12196 strcat (res, " <unknown>");
12197 break;
28f997cf
TG
12198 }
12199
12200 if (res[0] != 0)
12201 return res + 1;
12202 else
12203 return res;
12204 }
12205 return NULL;
12206}
12207
6911b7dc
AM
12208static const char *
12209get_ppc64_symbol_other (unsigned int other)
12210{
14732552
AM
12211 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12212 return NULL;
12213
12214 other >>= STO_PPC64_LOCAL_BIT;
12215 if (other <= 6)
6911b7dc 12216 {
89246a0e 12217 static char buf[64];
14732552
AM
12218 if (other >= 2)
12219 other = ppc64_decode_local_entry (other);
12220 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12221 return buf;
12222 }
12223 return NULL;
12224}
12225
5e2b0d47 12226static const char *
dda8d76d 12227get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12228{
12229 const char * result = NULL;
89246a0e 12230 static char buff [64];
5e2b0d47
NC
12231
12232 if (other == 0)
12233 return "";
12234
dda8d76d 12235 switch (filedata->file_header.e_machine)
5e2b0d47 12236 {
2057d69d
CZ
12237 case EM_ALPHA:
12238 result = get_alpha_symbol_other (other);
12239 break;
2301ed1c
SN
12240 case EM_AARCH64:
12241 result = get_aarch64_symbol_other (other);
12242 break;
5e2b0d47
NC
12243 case EM_MIPS:
12244 result = get_mips_symbol_other (other);
28f997cf
TG
12245 break;
12246 case EM_IA_64:
dda8d76d 12247 result = get_ia64_symbol_other (filedata, other);
28f997cf 12248 break;
6911b7dc
AM
12249 case EM_PPC64:
12250 result = get_ppc64_symbol_other (other);
12251 break;
5e2b0d47 12252 default:
fd85a6a1 12253 result = NULL;
5e2b0d47
NC
12254 break;
12255 }
12256
12257 if (result)
12258 return result;
12259
12260 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12261 return buff;
12262}
12263
d1133906 12264static const char *
dda8d76d 12265get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12266{
b34976b6 12267 static char buff[32];
5cf1065c 12268
252b5132
RH
12269 switch (type)
12270 {
b34976b6
AM
12271 case SHN_UNDEF: return "UND";
12272 case SHN_ABS: return "ABS";
12273 case SHN_COMMON: return "COM";
252b5132 12274 default:
9ce701e2 12275 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12276 && filedata->file_header.e_machine == EM_IA_64
12277 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12278 return "ANSI_COM";
12279 else if ((filedata->file_header.e_machine == EM_X86_64
12280 || filedata->file_header.e_machine == EM_L1OM
12281 || filedata->file_header.e_machine == EM_K1OM)
12282 && type == SHN_X86_64_LCOMMON)
12283 return "LARGE_COM";
12284 else if ((type == SHN_MIPS_SCOMMON
12285 && filedata->file_header.e_machine == EM_MIPS)
12286 || (type == SHN_TIC6X_SCOMMON
12287 && filedata->file_header.e_machine == EM_TI_C6000))
12288 return "SCOM";
12289 else if (type == SHN_MIPS_SUNDEFINED
12290 && filedata->file_header.e_machine == EM_MIPS)
12291 return "SUND";
12292 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12293 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12294 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12295 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12296 else if (type >= SHN_LORESERVE)
12297 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12298 else if (filedata->file_header.e_shnum != 0
12299 && type >= filedata->file_header.e_shnum)
12300 sprintf (buff, _("bad section index[%3d]"), type);
12301 else
12302 sprintf (buff, "%3d", type);
12303 break;
fd85a6a1
NC
12304 }
12305
10ca4b04 12306 return buff;
6bd1a22c
L
12307}
12308
bb4d2ac2 12309static const char *
dda8d76d 12310get_symbol_version_string (Filedata * filedata,
015dc7e1 12311 bool is_dynsym,
1449284b
NC
12312 const char * strtab,
12313 unsigned long int strtab_size,
12314 unsigned int si,
12315 Elf_Internal_Sym * psym,
12316 enum versioned_symbol_info * sym_info,
12317 unsigned short * vna_other)
bb4d2ac2 12318{
ab273396
AM
12319 unsigned char data[2];
12320 unsigned short vers_data;
12321 unsigned long offset;
7a815dd5 12322 unsigned short max_vd_ndx;
bb4d2ac2 12323
ab273396 12324 if (!is_dynsym
978c4450 12325 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12326 return NULL;
bb4d2ac2 12327
978c4450
AM
12328 offset = offset_from_vma (filedata,
12329 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12330 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12331
dda8d76d 12332 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12333 sizeof (data), 1, _("version data")) == NULL)
12334 return NULL;
12335
12336 vers_data = byte_get (data, 2);
bb4d2ac2 12337
1f6f5dba 12338 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12339 return NULL;
bb4d2ac2 12340
0b8b7609 12341 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12342 max_vd_ndx = 0;
12343
ab273396
AM
12344 /* Usually we'd only see verdef for defined symbols, and verneed for
12345 undefined symbols. However, symbols defined by the linker in
12346 .dynbss for variables copied from a shared library in order to
12347 avoid text relocations are defined yet have verneed. We could
12348 use a heuristic to detect the special case, for example, check
12349 for verneed first on symbols defined in SHT_NOBITS sections, but
12350 it is simpler and more reliable to just look for both verdef and
12351 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12352
ab273396
AM
12353 if (psym->st_shndx != SHN_UNDEF
12354 && vers_data != 0x8001
978c4450 12355 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12356 {
12357 Elf_Internal_Verdef ivd;
12358 Elf_Internal_Verdaux ivda;
12359 Elf_External_Verdaux evda;
12360 unsigned long off;
bb4d2ac2 12361
dda8d76d 12362 off = offset_from_vma (filedata,
978c4450 12363 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12364 sizeof (Elf_External_Verdef));
12365
12366 do
bb4d2ac2 12367 {
ab273396
AM
12368 Elf_External_Verdef evd;
12369
dda8d76d 12370 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12371 _("version def")) == NULL)
12372 {
12373 ivd.vd_ndx = 0;
12374 ivd.vd_aux = 0;
12375 ivd.vd_next = 0;
1f6f5dba 12376 ivd.vd_flags = 0;
ab273396
AM
12377 }
12378 else
bb4d2ac2 12379 {
ab273396
AM
12380 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12381 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12382 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12383 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12384 }
bb4d2ac2 12385
7a815dd5
L
12386 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12387 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12388
ab273396
AM
12389 off += ivd.vd_next;
12390 }
12391 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12392
ab273396
AM
12393 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12394 {
9abca702 12395 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12396 return NULL;
12397
ab273396
AM
12398 off -= ivd.vd_next;
12399 off += ivd.vd_aux;
bb4d2ac2 12400
dda8d76d 12401 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12402 _("version def aux")) != NULL)
12403 {
12404 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12405
ab273396 12406 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12407 return (ivda.vda_name < strtab_size
12408 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12409 }
12410 }
12411 }
bb4d2ac2 12412
978c4450 12413 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12414 {
12415 Elf_External_Verneed evn;
12416 Elf_Internal_Verneed ivn;
12417 Elf_Internal_Vernaux ivna;
bb4d2ac2 12418
dda8d76d 12419 offset = offset_from_vma (filedata,
978c4450 12420 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12421 sizeof evn);
12422 do
12423 {
12424 unsigned long vna_off;
bb4d2ac2 12425
dda8d76d 12426 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12427 _("version need")) == NULL)
12428 {
12429 ivna.vna_next = 0;
12430 ivna.vna_other = 0;
12431 ivna.vna_name = 0;
12432 break;
12433 }
bb4d2ac2 12434
ab273396
AM
12435 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12436 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12437
ab273396 12438 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12439
ab273396
AM
12440 do
12441 {
12442 Elf_External_Vernaux evna;
bb4d2ac2 12443
dda8d76d 12444 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12445 _("version need aux (3)")) == NULL)
bb4d2ac2 12446 {
ab273396
AM
12447 ivna.vna_next = 0;
12448 ivna.vna_other = 0;
12449 ivna.vna_name = 0;
bb4d2ac2 12450 }
bb4d2ac2 12451 else
bb4d2ac2 12452 {
ab273396
AM
12453 ivna.vna_other = BYTE_GET (evna.vna_other);
12454 ivna.vna_next = BYTE_GET (evna.vna_next);
12455 ivna.vna_name = BYTE_GET (evna.vna_name);
12456 }
bb4d2ac2 12457
ab273396
AM
12458 vna_off += ivna.vna_next;
12459 }
12460 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12461
ab273396
AM
12462 if (ivna.vna_other == vers_data)
12463 break;
bb4d2ac2 12464
ab273396
AM
12465 offset += ivn.vn_next;
12466 }
12467 while (ivn.vn_next != 0);
bb4d2ac2 12468
ab273396
AM
12469 if (ivna.vna_other == vers_data)
12470 {
12471 *sym_info = symbol_undefined;
12472 *vna_other = ivna.vna_other;
12473 return (ivna.vna_name < strtab_size
12474 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12475 }
7a815dd5
L
12476 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12477 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12478 return _("<corrupt>");
bb4d2ac2 12479 }
ab273396 12480 return NULL;
bb4d2ac2
L
12481}
12482
047c3dbf
NL
12483/* Display a symbol size on stdout. Format is based on --sym-base setting. */
12484
12485static unsigned int
12486print_dynamic_symbol_size (bfd_vma vma, int base)
12487{
12488 switch (base)
12489 {
12490 case 8:
12491 return print_vma (vma, OCTAL_5);
12492
12493 case 10:
12494 return print_vma (vma, UNSIGNED_5);
12495
12496 case 16:
12497 return print_vma (vma, PREFIX_HEX_5);
12498
12499 case 0:
12500 default:
12501 return print_vma (vma, DEC_5);
12502 }
12503}
12504
10ca4b04
L
12505static void
12506print_dynamic_symbol (Filedata *filedata, unsigned long si,
12507 Elf_Internal_Sym *symtab,
12508 Elf_Internal_Shdr *section,
12509 char *strtab, size_t strtab_size)
252b5132 12510{
10ca4b04
L
12511 const char *version_string;
12512 enum versioned_symbol_info sym_info;
12513 unsigned short vna_other;
23356397
NC
12514 bool is_valid;
12515 const char * sstr;
10ca4b04 12516 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 12517
10ca4b04
L
12518 printf ("%6ld: ", si);
12519 print_vma (psym->st_value, LONG_HEX);
12520 putchar (' ');
047c3dbf 12521 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
12522 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12523 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12524 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12525 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12526 else
252b5132 12527 {
10ca4b04 12528 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12529
10ca4b04
L
12530 printf (" %-7s", get_symbol_visibility (vis));
12531 /* Check to see if any other bits in the st_other field are set.
12532 Note - displaying this information disrupts the layout of the
12533 table being generated, but for the moment this case is very rare. */
12534 if (psym->st_other ^ vis)
12535 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12536 }
10ca4b04 12537 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 12538
23356397
NC
12539 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
12540 && psym->st_shndx < filedata->file_header.e_shnum
12541 && psym->st_name == 0)
12542 {
12543 is_valid = SECTION_NAME_VALID (filedata->section_headers + psym->st_shndx);
12544 sstr = is_valid ?
12545 SECTION_NAME_PRINT (filedata->section_headers + psym->st_shndx)
12546 : _("<corrupt>");
12547 }
12548 else
12549 {
12550 is_valid = VALID_SYMBOL_NAME (strtab, strtab_size, psym->st_name);
12551 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
12552 }
10ca4b04
L
12553
12554 version_string
12555 = get_symbol_version_string (filedata,
12556 (section == NULL
12557 || section->sh_type == SHT_DYNSYM),
12558 strtab, strtab_size, si,
12559 psym, &sym_info, &vna_other);
b9e920ec 12560
0942c7ab
NC
12561 int len_avail = 21;
12562 if (! do_wide && version_string != NULL)
12563 {
ddb43bab 12564 char buffer[16];
0942c7ab 12565
ddb43bab 12566 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
12567
12568 if (sym_info == symbol_undefined)
12569 len_avail -= sprintf (buffer," (%d)", vna_other);
12570 else if (sym_info != symbol_hidden)
12571 len_avail -= 1;
12572 }
12573
12574 print_symbol (len_avail, sstr);
b9e920ec 12575
10ca4b04
L
12576 if (version_string)
12577 {
12578 if (sym_info == symbol_undefined)
12579 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12580 else
10ca4b04
L
12581 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12582 version_string);
12583 }
6bd1a22c 12584
10ca4b04 12585 putchar ('\n');
6bd1a22c 12586
10ca4b04
L
12587 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12588 && section != NULL
12589 && si >= section->sh_info
12590 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12591 && filedata->file_header.e_machine != EM_MIPS
12592 /* Solaris binaries have been found to violate this requirement as
12593 well. Not sure if this is a bug or an ABI requirement. */
12594 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12595 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12596 si, printable_section_name (filedata, section), section->sh_info);
12597}
f16a9783 12598
0f03783c
NC
12599static const char *
12600get_lto_kind (unsigned int kind)
12601{
12602 switch (kind)
12603 {
12604 case 0: return "DEF";
12605 case 1: return "WEAKDEF";
12606 case 2: return "UNDEF";
12607 case 3: return "WEAKUNDEF";
12608 case 4: return "COMMON";
12609 default:
12610 break;
12611 }
12612
12613 static char buffer[30];
12614 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
12615 sprintf (buffer, "<unknown: %u>", kind);
12616 return buffer;
12617}
12618
12619static const char *
12620get_lto_visibility (unsigned int visibility)
12621{
12622 switch (visibility)
12623 {
12624 case 0: return "DEFAULT";
12625 case 1: return "PROTECTED";
12626 case 2: return "INTERNAL";
12627 case 3: return "HIDDEN";
12628 default:
12629 break;
12630 }
12631
12632 static char buffer[30];
12633 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
12634 sprintf (buffer, "<unknown: %u>", visibility);
12635 return buffer;
12636}
12637
12638static const char *
12639get_lto_sym_type (unsigned int sym_type)
12640{
12641 switch (sym_type)
12642 {
12643 case 0: return "UNKNOWN";
12644 case 1: return "FUNCTION";
12645 case 2: return "VARIABLE";
12646 default:
12647 break;
12648 }
12649
12650 static char buffer[30];
12651 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
12652 sprintf (buffer, "<unknown: %u>", sym_type);
12653 return buffer;
12654}
12655
12656/* Display an LTO format symbol table.
12657 FIXME: The format of LTO symbol tables is not formalized.
12658 So this code could need changing in the future. */
12659
015dc7e1 12660static bool
0f03783c
NC
12661display_lto_symtab (Filedata * filedata,
12662 Elf_Internal_Shdr * section)
12663{
12664 if (section->sh_size == 0)
12665 {
ca0e11aa
NC
12666 if (filedata->is_separate)
12667 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
12668 printable_section_name (filedata, section),
12669 filedata->file_name);
12670 else
12671 printf (_("\nLTO Symbol table '%s' is empty!\n"),
12672 printable_section_name (filedata, section));
047c3dbf 12673
015dc7e1 12674 return true;
0f03783c
NC
12675 }
12676
12677 if (section->sh_size > filedata->file_size)
12678 {
12679 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
12680 printable_section_name (filedata, section),
12681 (unsigned long) section->sh_size);
015dc7e1 12682 return false;
0f03783c
NC
12683 }
12684
12685 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
12686 section->sh_size, 1, _("LTO symbols"));
12687 if (alloced_data == NULL)
015dc7e1 12688 return false;
0f03783c
NC
12689
12690 /* Look for extended data for the symbol table. */
12691 Elf_Internal_Shdr * ext;
12692 void * ext_data_orig = NULL;
12693 char * ext_data = NULL;
12694 char * ext_data_end = NULL;
12695 char * ext_name = NULL;
12696
12697 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
b9e920ec 12698 SECTION_NAME (section) + sizeof (".gnu.lto_.symtab.") - 1) > 0
0f03783c
NC
12699 && ext_name != NULL /* Paranoia. */
12700 && (ext = find_section (filedata, ext_name)) != NULL)
12701 {
12702 if (ext->sh_size < 3)
12703 error (_("LTO Symbol extension table '%s' is empty!\n"),
12704 printable_section_name (filedata, ext));
12705 else
12706 {
12707 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
12708 ext->sh_size, 1,
12709 _("LTO ext symbol data"));
12710 if (ext_data != NULL)
12711 {
12712 ext_data_end = ext_data + ext->sh_size;
12713 if (* ext_data++ != 1)
12714 error (_("Unexpected version number in symbol extension table\n"));
12715 }
12716 }
12717 }
b9e920ec 12718
0f03783c
NC
12719 const unsigned char * data = (const unsigned char *) alloced_data;
12720 const unsigned char * end = data + section->sh_size;
12721
ca0e11aa
NC
12722 if (filedata->is_separate)
12723 printf (_("\nIn linked file '%s': "), filedata->file_name);
12724 else
12725 printf ("\n");
12726
0f03783c
NC
12727 if (ext_data_orig != NULL)
12728 {
12729 if (do_wide)
ca0e11aa 12730 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
12731 printable_section_name (filedata, section),
12732 printable_section_name (filedata, ext));
12733 else
12734 {
ca0e11aa 12735 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
12736 printable_section_name (filedata, section));
12737 printf (_(" and extension table '%s' contain:\n"),
12738 printable_section_name (filedata, ext));
12739 }
12740 }
12741 else
ca0e11aa 12742 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 12743 printable_section_name (filedata, section));
b9e920ec 12744
0f03783c 12745 /* FIXME: Add a wide version. */
b9e920ec 12746 if (ext_data_orig != NULL)
0f03783c
NC
12747 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
12748 else
12749 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
12750
12751 /* FIXME: We do not handle style prefixes. */
12752
12753 while (data < end)
12754 {
12755 const unsigned char * sym_name = data;
12756 data += strnlen ((const char *) sym_name, end - data) + 1;
12757 if (data >= end)
12758 goto fail;
12759
12760 const unsigned char * comdat_key = data;
12761 data += strnlen ((const char *) comdat_key, end - data) + 1;
12762 if (data >= end)
12763 goto fail;
12764
12765 if (data + 2 + 8 + 4 > end)
12766 goto fail;
12767
12768 unsigned int kind = *data++;
12769 unsigned int visibility = *data++;
12770
12771 elf_vma size = byte_get (data, 8);
12772 data += 8;
12773
12774 elf_vma slot = byte_get (data, 4);
12775 data += 4;
12776
12777 if (ext_data != NULL)
12778 {
12779 if (ext_data < (ext_data_end - 1))
12780 {
12781 unsigned int sym_type = * ext_data ++;
12782 unsigned int sec_kind = * ext_data ++;
12783
12784 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
12785 * comdat_key == 0 ? "-" : (char *) comdat_key,
12786 get_lto_kind (kind),
12787 get_lto_visibility (visibility),
12788 (long) size,
12789 (long) slot,
12790 get_lto_sym_type (sym_type),
12791 (long) sec_kind);
12792 print_symbol (6, (const char *) sym_name);
12793 }
12794 else
12795 {
12796 error (_("Ran out of LTO symbol extension data\n"));
12797 ext_data = NULL;
12798 /* FIXME: return FAIL result ? */
12799 }
12800 }
12801 else
12802 {
12803 printf (" %10s %10s %11s %08lx %08lx _",
12804 * comdat_key == 0 ? "-" : (char *) comdat_key,
12805 get_lto_kind (kind),
12806 get_lto_visibility (visibility),
12807 (long) size,
12808 (long) slot);
12809 print_symbol (21, (const char *) sym_name);
12810 }
12811 putchar ('\n');
12812 }
12813
12814 if (ext_data != NULL && ext_data < ext_data_end)
12815 {
12816 error (_("Data remains in the LTO symbol extension table\n"));
12817 goto fail;
12818 }
12819
12820 free (alloced_data);
12821 free (ext_data_orig);
12822 free (ext_name);
015dc7e1 12823 return true;
b9e920ec 12824
0f03783c
NC
12825 fail:
12826 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
12827 free (alloced_data);
12828 free (ext_data_orig);
12829 free (ext_name);
015dc7e1 12830 return false;
0f03783c
NC
12831}
12832
12833/* Display LTO symbol tables. */
12834
015dc7e1 12835static bool
0f03783c
NC
12836process_lto_symbol_tables (Filedata * filedata)
12837{
12838 Elf_Internal_Shdr * section;
12839 unsigned int i;
015dc7e1 12840 bool res = true;
0f03783c
NC
12841
12842 if (!do_lto_syms)
015dc7e1 12843 return true;
0f03783c
NC
12844
12845 if (filedata->section_headers == NULL)
015dc7e1 12846 return true;
0f03783c
NC
12847
12848 for (i = 0, section = filedata->section_headers;
12849 i < filedata->file_header.e_shnum;
12850 i++, section++)
b9e920ec 12851 if (SECTION_NAME_VALID (section)
08dedd66 12852 && startswith (SECTION_NAME (section), ".gnu.lto_.symtab."))
0f03783c
NC
12853 res &= display_lto_symtab (filedata, section);
12854
b9e920ec 12855 return res;
0f03783c
NC
12856}
12857
10ca4b04 12858/* Dump the symbol table. */
0f03783c 12859
015dc7e1 12860static bool
10ca4b04
L
12861process_symbol_table (Filedata * filedata)
12862{
12863 Elf_Internal_Shdr * section;
f16a9783 12864
10ca4b04 12865 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 12866 return true;
6bd1a22c 12867
978c4450 12868 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
12869 && do_syms
12870 && do_using_dynamic
978c4450
AM
12871 && filedata->dynamic_strings != NULL
12872 && filedata->dynamic_symbols != NULL)
6bd1a22c 12873 {
10ca4b04 12874 unsigned long si;
6bd1a22c 12875
ca0e11aa
NC
12876 if (filedata->is_separate)
12877 {
12878 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
12879 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
12880 filedata->num_dynamic_syms),
12881 filedata->file_name,
12882 filedata->num_dynamic_syms);
12883 }
12884 else
12885 {
12886 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12887 "\nSymbol table for image contains %lu entries:\n",
12888 filedata->num_dynamic_syms),
12889 filedata->num_dynamic_syms);
12890 }
10ca4b04
L
12891 if (is_32bit_elf)
12892 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12893 else
12894 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12895
978c4450
AM
12896 for (si = 0; si < filedata->num_dynamic_syms; si++)
12897 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
12898 filedata->dynamic_strings,
12899 filedata->dynamic_strings_length);
252b5132 12900 }
8b73c356 12901 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 12902 && filedata->section_headers != NULL)
252b5132 12903 {
b34976b6 12904 unsigned int i;
252b5132 12905
dda8d76d
NC
12906 for (i = 0, section = filedata->section_headers;
12907 i < filedata->file_header.e_shnum;
252b5132
RH
12908 i++, section++)
12909 {
2cf0635d 12910 char * strtab = NULL;
c256ffe7 12911 unsigned long int strtab_size = 0;
2cf0635d 12912 Elf_Internal_Sym * symtab;
ef3df110 12913 unsigned long si, num_syms;
252b5132 12914
2c610e4b
L
12915 if ((section->sh_type != SHT_SYMTAB
12916 && section->sh_type != SHT_DYNSYM)
12917 || (!do_syms
12918 && section->sh_type == SHT_SYMTAB))
252b5132
RH
12919 continue;
12920
dd24e3da
NC
12921 if (section->sh_entsize == 0)
12922 {
12923 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 12924 printable_section_name (filedata, section));
dd24e3da
NC
12925 continue;
12926 }
12927
d3a49aa8 12928 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
12929
12930 if (filedata->is_separate)
12931 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
12932 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
12933 num_syms),
12934 filedata->file_name,
12935 printable_section_name (filedata, section),
12936 num_syms);
12937 else
12938 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
12939 "\nSymbol table '%s' contains %lu entries:\n",
12940 num_syms),
12941 printable_section_name (filedata, section),
12942 num_syms);
dd24e3da 12943
f7a99963 12944 if (is_32bit_elf)
ca47b30c 12945 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 12946 else
ca47b30c 12947 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 12948
dda8d76d 12949 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
12950 if (symtab == NULL)
12951 continue;
12952
dda8d76d 12953 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 12954 {
dda8d76d
NC
12955 strtab = filedata->string_table;
12956 strtab_size = filedata->string_table_length;
c256ffe7 12957 }
dda8d76d 12958 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 12959 {
2cf0635d 12960 Elf_Internal_Shdr * string_sec;
252b5132 12961
dda8d76d 12962 string_sec = filedata->section_headers + section->sh_link;
252b5132 12963
dda8d76d 12964 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
12965 1, string_sec->sh_size,
12966 _("string table"));
c256ffe7 12967 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
12968 }
12969
10ca4b04
L
12970 for (si = 0; si < num_syms; si++)
12971 print_dynamic_symbol (filedata, si, symtab, section,
12972 strtab, strtab_size);
252b5132
RH
12973
12974 free (symtab);
dda8d76d 12975 if (strtab != filedata->string_table)
252b5132
RH
12976 free (strtab);
12977 }
12978 }
12979 else if (do_syms)
12980 printf
12981 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
12982
978c4450 12983 if (do_histogram && filedata->buckets != NULL)
252b5132 12984 {
2cf0635d
NC
12985 unsigned long * lengths;
12986 unsigned long * counts;
66543521
AM
12987 unsigned long hn;
12988 bfd_vma si;
12989 unsigned long maxlength = 0;
12990 unsigned long nzero_counts = 0;
12991 unsigned long nsyms = 0;
6bd6a03d 12992 char *visited;
252b5132 12993
d3a49aa8
AM
12994 printf (ngettext ("\nHistogram for bucket list length "
12995 "(total of %lu bucket):\n",
12996 "\nHistogram for bucket list length "
12997 "(total of %lu buckets):\n",
978c4450
AM
12998 (unsigned long) filedata->nbuckets),
12999 (unsigned long) filedata->nbuckets);
252b5132 13000
978c4450
AM
13001 lengths = (unsigned long *) calloc (filedata->nbuckets,
13002 sizeof (*lengths));
252b5132
RH
13003 if (lengths == NULL)
13004 {
8b73c356 13005 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13006 goto err_out;
252b5132 13007 }
978c4450
AM
13008 visited = xcmalloc (filedata->nchains, 1);
13009 memset (visited, 0, filedata->nchains);
8b73c356
NC
13010
13011 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13012 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13013 {
978c4450 13014 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13015 {
b34976b6 13016 ++nsyms;
252b5132 13017 if (maxlength < ++lengths[hn])
b34976b6 13018 ++maxlength;
978c4450 13019 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13020 {
13021 error (_("histogram chain is corrupt\n"));
13022 break;
13023 }
13024 visited[si] = 1;
252b5132
RH
13025 }
13026 }
6bd6a03d 13027 free (visited);
252b5132 13028
3f5e193b 13029 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13030 if (counts == NULL)
13031 {
b2e951ec 13032 free (lengths);
8b73c356 13033 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13034 goto err_out;
252b5132
RH
13035 }
13036
978c4450 13037 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13038 ++counts[lengths[hn]];
252b5132 13039
978c4450 13040 if (filedata->nbuckets > 0)
252b5132 13041 {
66543521
AM
13042 unsigned long i;
13043 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13044 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13045 for (i = 1; i <= maxlength; ++i)
103f02d3 13046 {
66543521
AM
13047 nzero_counts += counts[i] * i;
13048 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13049 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13050 (nzero_counts * 100.0) / nsyms);
13051 }
252b5132
RH
13052 }
13053
13054 free (counts);
13055 free (lengths);
13056 }
13057
978c4450
AM
13058 free (filedata->buckets);
13059 filedata->buckets = NULL;
13060 filedata->nbuckets = 0;
13061 free (filedata->chains);
13062 filedata->chains = NULL;
252b5132 13063
978c4450 13064 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13065 {
2cf0635d
NC
13066 unsigned long * lengths;
13067 unsigned long * counts;
fdc90cb4
JJ
13068 unsigned long hn;
13069 unsigned long maxlength = 0;
13070 unsigned long nzero_counts = 0;
13071 unsigned long nsyms = 0;
fdc90cb4 13072
f16a9783 13073 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13074 "(total of %lu bucket):\n",
f16a9783 13075 "\nHistogram for `%s' bucket list length "
d3a49aa8 13076 "(total of %lu buckets):\n",
978c4450
AM
13077 (unsigned long) filedata->ngnubuckets),
13078 GNU_HASH_SECTION_NAME (filedata),
13079 (unsigned long) filedata->ngnubuckets);
8b73c356 13080
978c4450
AM
13081 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13082 sizeof (*lengths));
fdc90cb4
JJ
13083 if (lengths == NULL)
13084 {
8b73c356 13085 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13086 goto err_out;
fdc90cb4
JJ
13087 }
13088
fdc90cb4
JJ
13089 printf (_(" Length Number %% of total Coverage\n"));
13090
978c4450
AM
13091 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13092 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
13093 {
13094 bfd_vma off, length = 1;
13095
978c4450 13096 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13097 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13098 off < filedata->ngnuchains
13099 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13100 ++off)
fdc90cb4
JJ
13101 ++length;
13102 lengths[hn] = length;
13103 if (length > maxlength)
13104 maxlength = length;
13105 nsyms += length;
13106 }
13107
3f5e193b 13108 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13109 if (counts == NULL)
13110 {
b2e951ec 13111 free (lengths);
8b73c356 13112 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13113 goto err_out;
fdc90cb4
JJ
13114 }
13115
978c4450 13116 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13117 ++counts[lengths[hn]];
13118
978c4450 13119 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13120 {
13121 unsigned long j;
13122 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13123 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13124 for (j = 1; j <= maxlength; ++j)
13125 {
13126 nzero_counts += counts[j] * j;
13127 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13128 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13129 (nzero_counts * 100.0) / nsyms);
13130 }
13131 }
13132
13133 free (counts);
13134 free (lengths);
fdc90cb4 13135 }
978c4450
AM
13136 free (filedata->gnubuckets);
13137 filedata->gnubuckets = NULL;
13138 filedata->ngnubuckets = 0;
13139 free (filedata->gnuchains);
13140 filedata->gnuchains = NULL;
13141 filedata->ngnuchains = 0;
13142 free (filedata->mipsxlat);
13143 filedata->mipsxlat = NULL;
015dc7e1 13144 return true;
fd486f32
AM
13145
13146 err_out:
978c4450
AM
13147 free (filedata->gnubuckets);
13148 filedata->gnubuckets = NULL;
13149 filedata->ngnubuckets = 0;
13150 free (filedata->gnuchains);
13151 filedata->gnuchains = NULL;
13152 filedata->ngnuchains = 0;
13153 free (filedata->mipsxlat);
13154 filedata->mipsxlat = NULL;
13155 free (filedata->buckets);
13156 filedata->buckets = NULL;
13157 filedata->nbuckets = 0;
13158 free (filedata->chains);
13159 filedata->chains = NULL;
015dc7e1 13160 return false;
252b5132
RH
13161}
13162
015dc7e1 13163static bool
ca0e11aa 13164process_syminfo (Filedata * filedata)
252b5132 13165{
b4c96d0d 13166 unsigned int i;
252b5132 13167
978c4450 13168 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13169 || !do_dynamic)
13170 /* No syminfo, this is ok. */
015dc7e1 13171 return true;
252b5132
RH
13172
13173 /* There better should be a dynamic symbol section. */
978c4450 13174 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13175 return false;
252b5132 13176
ca0e11aa
NC
13177 if (filedata->is_separate)
13178 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13179 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13180 filedata->dynamic_syminfo_nent),
13181 filedata->file_name,
13182 filedata->dynamic_syminfo_offset,
13183 filedata->dynamic_syminfo_nent);
13184 else
d3a49aa8
AM
13185 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13186 "contains %d entry:\n",
13187 "\nDynamic info segment at offset 0x%lx "
13188 "contains %d entries:\n",
978c4450 13189 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13190 filedata->dynamic_syminfo_offset,
13191 filedata->dynamic_syminfo_nent);
252b5132
RH
13192
13193 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13194 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13195 {
978c4450 13196 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13197
31104126 13198 printf ("%4d: ", i);
978c4450 13199 if (i >= filedata->num_dynamic_syms)
4082ef84 13200 printf (_("<corrupt index>"));
978c4450
AM
13201 else if (VALID_DYNAMIC_NAME (filedata, filedata->dynamic_symbols[i].st_name))
13202 print_symbol (30, GET_DYNAMIC_NAME (filedata,
13203 filedata->dynamic_symbols[i].st_name));
d79b3d50 13204 else
978c4450 13205 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13206 putchar (' ');
252b5132 13207
978c4450 13208 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13209 {
13210 case SYMINFO_BT_SELF:
13211 fputs ("SELF ", stdout);
13212 break;
13213 case SYMINFO_BT_PARENT:
13214 fputs ("PARENT ", stdout);
13215 break;
13216 default:
978c4450
AM
13217 if (filedata->dynamic_syminfo[i].si_boundto > 0
13218 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
13219 && VALID_DYNAMIC_NAME (filedata,
13220 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13221 {
978c4450
AM
13222 print_symbol (10, GET_DYNAMIC_NAME (filedata,
13223 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13224 putchar (' ' );
13225 }
252b5132 13226 else
978c4450 13227 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13228 break;
13229 }
13230
13231 if (flags & SYMINFO_FLG_DIRECT)
13232 printf (" DIRECT");
13233 if (flags & SYMINFO_FLG_PASSTHRU)
13234 printf (" PASSTHRU");
13235 if (flags & SYMINFO_FLG_COPY)
13236 printf (" COPY");
13237 if (flags & SYMINFO_FLG_LAZYLOAD)
13238 printf (" LAZYLOAD");
13239
13240 puts ("");
13241 }
13242
015dc7e1 13243 return true;
252b5132
RH
13244}
13245
75802ccb
CE
13246/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13247 is contained by the region START .. END. The types of ADDR, START
13248 and END should all be the same. Note both ADDR + NELEM and END
13249 point to just beyond the end of the regions that are being tested. */
13250#define IN_RANGE(START,END,ADDR,NELEM) \
13251 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13252
cf13d699
NC
13253/* Check to see if the given reloc needs to be handled in a target specific
13254 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13255 FALSE.
13256
13257 If called with reloc == NULL, then this is a signal that reloc processing
13258 for the current section has finished, and any saved state should be
13259 discarded. */
09c11c86 13260
015dc7e1 13261static bool
dda8d76d
NC
13262target_specific_reloc_handling (Filedata * filedata,
13263 Elf_Internal_Rela * reloc,
13264 unsigned char * start,
13265 unsigned char * end,
13266 Elf_Internal_Sym * symtab,
13267 unsigned long num_syms)
252b5132 13268{
f84ce13b
NC
13269 unsigned int reloc_type = 0;
13270 unsigned long sym_index = 0;
13271
13272 if (reloc)
13273 {
dda8d76d 13274 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13275 sym_index = get_reloc_symindex (reloc->r_info);
13276 }
252b5132 13277
dda8d76d 13278 switch (filedata->file_header.e_machine)
252b5132 13279 {
13761a11
NC
13280 case EM_MSP430:
13281 case EM_MSP430_OLD:
13282 {
13283 static Elf_Internal_Sym * saved_sym = NULL;
13284
f84ce13b
NC
13285 if (reloc == NULL)
13286 {
13287 saved_sym = NULL;
015dc7e1 13288 return true;
f84ce13b
NC
13289 }
13290
13761a11
NC
13291 switch (reloc_type)
13292 {
13293 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13294 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13295 if (uses_msp430x_relocs (filedata))
13761a11 13296 break;
1a0670f3 13297 /* Fall through. */
13761a11 13298 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13299 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13300 /* PR 21139. */
13301 if (sym_index >= num_syms)
13302 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13303 sym_index);
13304 else
13305 saved_sym = symtab + sym_index;
015dc7e1 13306 return true;
13761a11
NC
13307
13308 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13309 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13310 goto handle_sym_diff;
0b4362b0 13311
13761a11
NC
13312 case 5: /* R_MSP430_16_BYTE */
13313 case 9: /* R_MSP430_8 */
7d81bc93 13314 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13315 if (uses_msp430x_relocs (filedata))
13761a11
NC
13316 break;
13317 goto handle_sym_diff;
13318
13319 case 2: /* R_MSP430_ABS16 */
13320 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13321 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13322 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13323 break;
13324 goto handle_sym_diff;
0b4362b0 13325
13761a11
NC
13326 handle_sym_diff:
13327 if (saved_sym != NULL)
13328 {
13329 bfd_vma value;
5a805384 13330 unsigned int reloc_size = 0;
7d81bc93
JL
13331 int leb_ret = 0;
13332 switch (reloc_type)
13333 {
13334 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13335 reloc_size = 4;
13336 break;
13337 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13338 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13339 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13340 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13341 &reloc_size, &leb_ret);
7d81bc93
JL
13342 break;
13343 default:
13344 reloc_size = 2;
13345 break;
13346 }
13761a11 13347
5a805384 13348 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13349 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13350 "ULEB128 value\n"),
13351 (long) reloc->r_offset);
13352 else if (sym_index >= num_syms)
f84ce13b
NC
13353 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13354 sym_index);
03f7786e 13355 else
f84ce13b
NC
13356 {
13357 value = reloc->r_addend + (symtab[sym_index].st_value
13358 - saved_sym->st_value);
13359
b32e566b 13360 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13361 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13362 else
13363 /* PR 21137 */
13364 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13365 (long) reloc->r_offset);
f84ce13b 13366 }
13761a11
NC
13367
13368 saved_sym = NULL;
015dc7e1 13369 return true;
13761a11
NC
13370 }
13371 break;
13372
13373 default:
13374 if (saved_sym != NULL)
071436c6 13375 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
13376 break;
13377 }
13378 break;
13379 }
13380
cf13d699
NC
13381 case EM_MN10300:
13382 case EM_CYGNUS_MN10300:
13383 {
13384 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 13385
f84ce13b
NC
13386 if (reloc == NULL)
13387 {
13388 saved_sym = NULL;
015dc7e1 13389 return true;
f84ce13b
NC
13390 }
13391
cf13d699
NC
13392 switch (reloc_type)
13393 {
13394 case 34: /* R_MN10300_ALIGN */
015dc7e1 13395 return true;
cf13d699 13396 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
13397 if (sym_index >= num_syms)
13398 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
13399 sym_index);
13400 else
13401 saved_sym = symtab + sym_index;
015dc7e1 13402 return true;
f84ce13b 13403
cf13d699
NC
13404 case 1: /* R_MN10300_32 */
13405 case 2: /* R_MN10300_16 */
13406 if (saved_sym != NULL)
13407 {
03f7786e 13408 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 13409 bfd_vma value;
252b5132 13410
f84ce13b
NC
13411 if (sym_index >= num_syms)
13412 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
13413 sym_index);
03f7786e 13414 else
f84ce13b
NC
13415 {
13416 value = reloc->r_addend + (symtab[sym_index].st_value
13417 - saved_sym->st_value);
13418
b32e566b 13419 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13420 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13421 else
13422 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
13423 (long) reloc->r_offset);
f84ce13b 13424 }
252b5132 13425
cf13d699 13426 saved_sym = NULL;
015dc7e1 13427 return true;
cf13d699
NC
13428 }
13429 break;
13430 default:
13431 if (saved_sym != NULL)
071436c6 13432 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
13433 break;
13434 }
13435 break;
13436 }
6ff71e76
NC
13437
13438 case EM_RL78:
13439 {
13440 static bfd_vma saved_sym1 = 0;
13441 static bfd_vma saved_sym2 = 0;
13442 static bfd_vma value;
13443
f84ce13b
NC
13444 if (reloc == NULL)
13445 {
13446 saved_sym1 = saved_sym2 = 0;
015dc7e1 13447 return true;
f84ce13b
NC
13448 }
13449
6ff71e76
NC
13450 switch (reloc_type)
13451 {
13452 case 0x80: /* R_RL78_SYM. */
13453 saved_sym1 = saved_sym2;
f84ce13b
NC
13454 if (sym_index >= num_syms)
13455 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
13456 sym_index);
13457 else
13458 {
13459 saved_sym2 = symtab[sym_index].st_value;
13460 saved_sym2 += reloc->r_addend;
13461 }
015dc7e1 13462 return true;
6ff71e76
NC
13463
13464 case 0x83: /* R_RL78_OPsub. */
13465 value = saved_sym1 - saved_sym2;
13466 saved_sym2 = saved_sym1 = 0;
015dc7e1 13467 return true;
6ff71e76
NC
13468 break;
13469
13470 case 0x41: /* R_RL78_ABS32. */
b32e566b 13471 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 13472 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
13473 else
13474 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13475 (long) reloc->r_offset);
6ff71e76 13476 value = 0;
015dc7e1 13477 return true;
6ff71e76
NC
13478
13479 case 0x43: /* R_RL78_ABS16. */
b32e566b 13480 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 13481 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
13482 else
13483 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13484 (long) reloc->r_offset);
6ff71e76 13485 value = 0;
015dc7e1 13486 return true;
6ff71e76
NC
13487
13488 default:
13489 break;
13490 }
13491 break;
13492 }
252b5132
RH
13493 }
13494
015dc7e1 13495 return false;
252b5132
RH
13496}
13497
aca88567
NC
13498/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
13499 DWARF debug sections. This is a target specific test. Note - we do not
13500 go through the whole including-target-headers-multiple-times route, (as
13501 we have already done with <elf/h8.h>) because this would become very
13502 messy and even then this function would have to contain target specific
13503 information (the names of the relocs instead of their numeric values).
13504 FIXME: This is not the correct way to solve this problem. The proper way
13505 is to have target specific reloc sizing and typing functions created by
13506 the reloc-macros.h header, in the same way that it already creates the
13507 reloc naming functions. */
13508
015dc7e1 13509static bool
dda8d76d 13510is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13511{
d347c9df 13512 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13513 switch (filedata->file_header.e_machine)
aca88567 13514 {
41e92641 13515 case EM_386:
22abe556 13516 case EM_IAMCU:
41e92641 13517 return reloc_type == 1; /* R_386_32. */
aca88567
NC
13518 case EM_68K:
13519 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
13520 case EM_860:
13521 return reloc_type == 1; /* R_860_32. */
13522 case EM_960:
13523 return reloc_type == 2; /* R_960_32. */
a06ea964 13524 case EM_AARCH64:
9282b95a
JW
13525 return (reloc_type == 258
13526 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
13527 case EM_BPF:
13528 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
13529 case EM_ADAPTEVA_EPIPHANY:
13530 return reloc_type == 3;
aca88567 13531 case EM_ALPHA:
137b6b5f 13532 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
13533 case EM_ARC:
13534 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
13535 case EM_ARC_COMPACT:
13536 case EM_ARC_COMPACT2:
13537 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
13538 case EM_ARM:
13539 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 13540 case EM_AVR_OLD:
aca88567
NC
13541 case EM_AVR:
13542 return reloc_type == 1;
13543 case EM_BLACKFIN:
13544 return reloc_type == 0x12; /* R_byte4_data. */
13545 case EM_CRIS:
13546 return reloc_type == 3; /* R_CRIS_32. */
13547 case EM_CR16:
13548 return reloc_type == 3; /* R_CR16_NUM32. */
13549 case EM_CRX:
13550 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
13551 case EM_CSKY:
13552 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
13553 case EM_CYGNUS_FRV:
13554 return reloc_type == 1;
41e92641
NC
13555 case EM_CYGNUS_D10V:
13556 case EM_D10V:
13557 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
13558 case EM_CYGNUS_D30V:
13559 case EM_D30V:
13560 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
13561 case EM_DLX:
13562 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
13563 case EM_CYGNUS_FR30:
13564 case EM_FR30:
13565 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
13566 case EM_FT32:
13567 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
13568 case EM_H8S:
13569 case EM_H8_300:
13570 case EM_H8_300H:
13571 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 13572 case EM_IA_64:
262cdac7
AM
13573 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
13574 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
13575 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
13576 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
13577 case EM_IP2K_OLD:
13578 case EM_IP2K:
13579 return reloc_type == 2; /* R_IP2K_32. */
13580 case EM_IQ2000:
13581 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
13582 case EM_LATTICEMICO32:
13583 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 13584 case EM_M32C_OLD:
aca88567
NC
13585 case EM_M32C:
13586 return reloc_type == 3; /* R_M32C_32. */
13587 case EM_M32R:
13588 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
13589 case EM_68HC11:
13590 case EM_68HC12:
13591 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 13592 case EM_S12Z:
2849d19f
JD
13593 return reloc_type == 7 || /* R_S12Z_EXT32 */
13594 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
13595 case EM_MCORE:
13596 return reloc_type == 1; /* R_MCORE_ADDR32. */
13597 case EM_CYGNUS_MEP:
13598 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
13599 case EM_METAG:
13600 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
13601 case EM_MICROBLAZE:
13602 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
13603 case EM_MIPS:
13604 return reloc_type == 2; /* R_MIPS_32. */
13605 case EM_MMIX:
13606 return reloc_type == 4; /* R_MMIX_32. */
13607 case EM_CYGNUS_MN10200:
13608 case EM_MN10200:
13609 return reloc_type == 1; /* R_MN10200_32. */
13610 case EM_CYGNUS_MN10300:
13611 case EM_MN10300:
13612 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
13613 case EM_MOXIE:
13614 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
13615 case EM_MSP430_OLD:
13616 case EM_MSP430:
13761a11 13617 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
13618 case EM_MT:
13619 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
13620 case EM_NDS32:
13621 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 13622 case EM_ALTERA_NIOS2:
36591ba1 13623 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
13624 case EM_NIOS32:
13625 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
13626 case EM_OR1K:
13627 return reloc_type == 1; /* R_OR1K_32. */
aca88567 13628 case EM_PARISC:
9abca702 13629 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 13630 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 13631 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
13632 case EM_PJ:
13633 case EM_PJ_OLD:
13634 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
13635 case EM_PPC64:
13636 return reloc_type == 1; /* R_PPC64_ADDR32. */
13637 case EM_PPC:
13638 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
13639 case EM_TI_PRU:
13640 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
13641 case EM_RISCV:
13642 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
13643 case EM_RL78:
13644 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
13645 case EM_RX:
13646 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
13647 case EM_S370:
13648 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
13649 case EM_S390_OLD:
13650 case EM_S390:
13651 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
13652 case EM_SCORE:
13653 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
13654 case EM_SH:
13655 return reloc_type == 1; /* R_SH_DIR32. */
13656 case EM_SPARC32PLUS:
13657 case EM_SPARCV9:
13658 case EM_SPARC:
13659 return reloc_type == 3 /* R_SPARC_32. */
13660 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
13661 case EM_SPU:
13662 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
13663 case EM_TI_C6000:
13664 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
13665 case EM_TILEGX:
13666 return reloc_type == 2; /* R_TILEGX_32. */
13667 case EM_TILEPRO:
13668 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
13669 case EM_CYGNUS_V850:
13670 case EM_V850:
13671 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
13672 case EM_V800:
13673 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
13674 case EM_VAX:
13675 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
13676 case EM_VISIUM:
13677 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
13678 case EM_WEBASSEMBLY:
13679 return reloc_type == 1; /* R_WASM32_32. */
aca88567 13680 case EM_X86_64:
8a9036a4 13681 case EM_L1OM:
7a9068fe 13682 case EM_K1OM:
aca88567 13683 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
13684 case EM_XC16X:
13685 case EM_C166:
13686 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
13687 case EM_XGATE:
13688 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
13689 case EM_XSTORMY16:
13690 return reloc_type == 1; /* R_XSTROMY16_32. */
13691 case EM_XTENSA_OLD:
13692 case EM_XTENSA:
13693 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
13694 case EM_Z80:
13695 return reloc_type == 6; /* R_Z80_32. */
aca88567 13696 default:
bee0ee85
NC
13697 {
13698 static unsigned int prev_warn = 0;
13699
13700 /* Avoid repeating the same warning multiple times. */
dda8d76d 13701 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 13702 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
13703 filedata->file_header.e_machine);
13704 prev_warn = filedata->file_header.e_machine;
015dc7e1 13705 return false;
bee0ee85 13706 }
aca88567
NC
13707 }
13708}
13709
13710/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13711 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
13712
015dc7e1 13713static bool
dda8d76d 13714is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13715{
dda8d76d 13716 switch (filedata->file_header.e_machine)
d347c9df 13717 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 13718 {
41e92641 13719 case EM_386:
22abe556 13720 case EM_IAMCU:
3e0873ac 13721 return reloc_type == 2; /* R_386_PC32. */
aca88567 13722 case EM_68K:
3e0873ac 13723 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
13724 case EM_AARCH64:
13725 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
13726 case EM_ADAPTEVA_EPIPHANY:
13727 return reloc_type == 6;
aca88567
NC
13728 case EM_ALPHA:
13729 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
13730 case EM_ARC_COMPACT:
13731 case EM_ARC_COMPACT2:
13732 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 13733 case EM_ARM:
3e0873ac 13734 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
13735 case EM_AVR_OLD:
13736 case EM_AVR:
13737 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
13738 case EM_MICROBLAZE:
13739 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
13740 case EM_OR1K:
13741 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 13742 case EM_PARISC:
85acf597 13743 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
13744 case EM_PPC:
13745 return reloc_type == 26; /* R_PPC_REL32. */
13746 case EM_PPC64:
3e0873ac 13747 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
13748 case EM_RISCV:
13749 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
13750 case EM_S390_OLD:
13751 case EM_S390:
3e0873ac 13752 return reloc_type == 5; /* R_390_PC32. */
aca88567 13753 case EM_SH:
3e0873ac 13754 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
13755 case EM_SPARC32PLUS:
13756 case EM_SPARCV9:
13757 case EM_SPARC:
3e0873ac 13758 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
13759 case EM_SPU:
13760 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
13761 case EM_TILEGX:
13762 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
13763 case EM_TILEPRO:
13764 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
13765 case EM_VISIUM:
13766 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 13767 case EM_X86_64:
8a9036a4 13768 case EM_L1OM:
7a9068fe 13769 case EM_K1OM:
3e0873ac 13770 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
13771 case EM_VAX:
13772 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
13773 case EM_XTENSA_OLD:
13774 case EM_XTENSA:
13775 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
13776 default:
13777 /* Do not abort or issue an error message here. Not all targets use
13778 pc-relative 32-bit relocs in their DWARF debug information and we
13779 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
13780 more helpful warning message will be generated by apply_relocations
13781 anyway, so just return. */
015dc7e1 13782 return false;
aca88567
NC
13783 }
13784}
13785
13786/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13787 a 64-bit absolute RELA relocation used in DWARF debug sections. */
13788
015dc7e1 13789static bool
dda8d76d 13790is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13791{
dda8d76d 13792 switch (filedata->file_header.e_machine)
aca88567 13793 {
a06ea964
NC
13794 case EM_AARCH64:
13795 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
13796 case EM_ALPHA:
13797 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 13798 case EM_IA_64:
262cdac7
AM
13799 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
13800 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
13801 case EM_PARISC:
13802 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
13803 case EM_PPC64:
13804 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
13805 case EM_RISCV:
13806 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
13807 case EM_SPARC32PLUS:
13808 case EM_SPARCV9:
13809 case EM_SPARC:
714da62f
NC
13810 return reloc_type == 32 /* R_SPARC_64. */
13811 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 13812 case EM_X86_64:
8a9036a4 13813 case EM_L1OM:
7a9068fe 13814 case EM_K1OM:
aca88567 13815 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
13816 case EM_S390_OLD:
13817 case EM_S390:
aa137e4d
NC
13818 return reloc_type == 22; /* R_S390_64. */
13819 case EM_TILEGX:
13820 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 13821 case EM_MIPS:
aa137e4d 13822 return reloc_type == 18; /* R_MIPS_64. */
aca88567 13823 default:
015dc7e1 13824 return false;
aca88567
NC
13825 }
13826}
13827
85acf597
RH
13828/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
13829 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
13830
015dc7e1 13831static bool
dda8d76d 13832is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 13833{
dda8d76d 13834 switch (filedata->file_header.e_machine)
85acf597 13835 {
a06ea964
NC
13836 case EM_AARCH64:
13837 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 13838 case EM_ALPHA:
aa137e4d 13839 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 13840 case EM_IA_64:
262cdac7
AM
13841 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
13842 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 13843 case EM_PARISC:
aa137e4d 13844 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 13845 case EM_PPC64:
aa137e4d 13846 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
13847 case EM_SPARC32PLUS:
13848 case EM_SPARCV9:
13849 case EM_SPARC:
aa137e4d 13850 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 13851 case EM_X86_64:
8a9036a4 13852 case EM_L1OM:
7a9068fe 13853 case EM_K1OM:
aa137e4d 13854 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
13855 case EM_S390_OLD:
13856 case EM_S390:
aa137e4d
NC
13857 return reloc_type == 23; /* R_S390_PC64. */
13858 case EM_TILEGX:
13859 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 13860 default:
015dc7e1 13861 return false;
85acf597
RH
13862 }
13863}
13864
4dc3c23d
AM
13865/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13866 a 24-bit absolute RELA relocation used in DWARF debug sections. */
13867
015dc7e1 13868static bool
dda8d76d 13869is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 13870{
dda8d76d 13871 switch (filedata->file_header.e_machine)
4dc3c23d
AM
13872 {
13873 case EM_CYGNUS_MN10200:
13874 case EM_MN10200:
13875 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
13876 case EM_FT32:
13877 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
13878 case EM_Z80:
13879 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 13880 default:
015dc7e1 13881 return false;
4dc3c23d
AM
13882 }
13883}
13884
aca88567
NC
13885/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13886 a 16-bit absolute RELA relocation used in DWARF debug sections. */
13887
015dc7e1 13888static bool
dda8d76d 13889is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 13890{
d347c9df 13891 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13892 switch (filedata->file_header.e_machine)
4b78141a 13893 {
886a2506
NC
13894 case EM_ARC:
13895 case EM_ARC_COMPACT:
13896 case EM_ARC_COMPACT2:
13897 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
13898 case EM_ADAPTEVA_EPIPHANY:
13899 return reloc_type == 5;
aca88567
NC
13900 case EM_AVR_OLD:
13901 case EM_AVR:
13902 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
13903 case EM_CYGNUS_D10V:
13904 case EM_D10V:
13905 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
13906 case EM_FT32:
13907 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
13908 case EM_H8S:
13909 case EM_H8_300:
13910 case EM_H8_300H:
aca88567
NC
13911 return reloc_type == R_H8_DIR16;
13912 case EM_IP2K_OLD:
13913 case EM_IP2K:
13914 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 13915 case EM_M32C_OLD:
f4236fe4
DD
13916 case EM_M32C:
13917 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
13918 case EM_CYGNUS_MN10200:
13919 case EM_MN10200:
13920 return reloc_type == 2; /* R_MN10200_16. */
13921 case EM_CYGNUS_MN10300:
13922 case EM_MN10300:
13923 return reloc_type == 2; /* R_MN10300_16. */
aca88567 13924 case EM_MSP430:
dda8d76d 13925 if (uses_msp430x_relocs (filedata))
13761a11 13926 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 13927 /* Fall through. */
78c8d46c 13928 case EM_MSP430_OLD:
aca88567 13929 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
13930 case EM_NDS32:
13931 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 13932 case EM_ALTERA_NIOS2:
36591ba1 13933 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
13934 case EM_NIOS32:
13935 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
13936 case EM_OR1K:
13937 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
13938 case EM_RISCV:
13939 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
13940 case EM_TI_PRU:
13941 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
13942 case EM_TI_C6000:
13943 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
13944 case EM_VISIUM:
13945 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
13946 case EM_XC16X:
13947 case EM_C166:
13948 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
13949 case EM_XGATE:
13950 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
13951 case EM_Z80:
13952 return reloc_type == 4; /* R_Z80_16. */
4b78141a 13953 default:
015dc7e1 13954 return false;
4b78141a
NC
13955 }
13956}
13957
39e07931
AS
13958/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13959 a 8-bit absolute RELA relocation used in DWARF debug sections. */
13960
015dc7e1 13961static bool
39e07931
AS
13962is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13963{
13964 switch (filedata->file_header.e_machine)
13965 {
13966 case EM_RISCV:
13967 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
13968 case EM_Z80:
13969 return reloc_type == 1; /* R_Z80_8. */
39e07931 13970 default:
015dc7e1 13971 return false;
39e07931
AS
13972 }
13973}
13974
13975/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13976 a 6-bit absolute RELA relocation used in DWARF debug sections. */
13977
015dc7e1 13978static bool
39e07931
AS
13979is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13980{
13981 switch (filedata->file_header.e_machine)
13982 {
13983 case EM_RISCV:
13984 return reloc_type == 53; /* R_RISCV_SET6. */
13985 default:
015dc7e1 13986 return false;
39e07931
AS
13987 }
13988}
13989
03336641
JW
13990/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13991 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
13992
015dc7e1 13993static bool
03336641
JW
13994is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13995{
13996 /* Please keep this table alpha-sorted for ease of visual lookup. */
13997 switch (filedata->file_header.e_machine)
13998 {
13999 case EM_RISCV:
14000 return reloc_type == 35; /* R_RISCV_ADD32. */
14001 default:
015dc7e1 14002 return false;
03336641
JW
14003 }
14004}
14005
14006/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14007 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14008
015dc7e1 14009static bool
03336641
JW
14010is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14011{
14012 /* Please keep this table alpha-sorted for ease of visual lookup. */
14013 switch (filedata->file_header.e_machine)
14014 {
14015 case EM_RISCV:
14016 return reloc_type == 39; /* R_RISCV_SUB32. */
14017 default:
015dc7e1 14018 return false;
03336641
JW
14019 }
14020}
14021
14022/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14023 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14024
015dc7e1 14025static bool
03336641
JW
14026is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14027{
14028 /* Please keep this table alpha-sorted for ease of visual lookup. */
14029 switch (filedata->file_header.e_machine)
14030 {
14031 case EM_RISCV:
14032 return reloc_type == 36; /* R_RISCV_ADD64. */
14033 default:
015dc7e1 14034 return false;
03336641
JW
14035 }
14036}
14037
14038/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14039 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14040
015dc7e1 14041static bool
03336641
JW
14042is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14043{
14044 /* Please keep this table alpha-sorted for ease of visual lookup. */
14045 switch (filedata->file_header.e_machine)
14046 {
14047 case EM_RISCV:
14048 return reloc_type == 40; /* R_RISCV_SUB64. */
14049 default:
015dc7e1 14050 return false;
03336641
JW
14051 }
14052}
14053
14054/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14055 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14056
015dc7e1 14057static bool
03336641
JW
14058is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14059{
14060 /* Please keep this table alpha-sorted for ease of visual lookup. */
14061 switch (filedata->file_header.e_machine)
14062 {
14063 case EM_RISCV:
14064 return reloc_type == 34; /* R_RISCV_ADD16. */
14065 default:
015dc7e1 14066 return false;
03336641
JW
14067 }
14068}
14069
14070/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14071 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14072
015dc7e1 14073static bool
03336641
JW
14074is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14075{
14076 /* Please keep this table alpha-sorted for ease of visual lookup. */
14077 switch (filedata->file_header.e_machine)
14078 {
14079 case EM_RISCV:
14080 return reloc_type == 38; /* R_RISCV_SUB16. */
14081 default:
015dc7e1 14082 return false;
03336641
JW
14083 }
14084}
14085
14086/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14087 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14088
015dc7e1 14089static bool
03336641
JW
14090is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14091{
14092 /* Please keep this table alpha-sorted for ease of visual lookup. */
14093 switch (filedata->file_header.e_machine)
14094 {
14095 case EM_RISCV:
14096 return reloc_type == 33; /* R_RISCV_ADD8. */
14097 default:
015dc7e1 14098 return false;
03336641
JW
14099 }
14100}
14101
14102/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14103 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14104
015dc7e1 14105static bool
03336641
JW
14106is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14107{
14108 /* Please keep this table alpha-sorted for ease of visual lookup. */
14109 switch (filedata->file_header.e_machine)
14110 {
14111 case EM_RISCV:
14112 return reloc_type == 37; /* R_RISCV_SUB8. */
14113 default:
015dc7e1 14114 return false;
03336641
JW
14115 }
14116}
14117
39e07931
AS
14118/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14119 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14120
015dc7e1 14121static bool
39e07931
AS
14122is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14123{
14124 switch (filedata->file_header.e_machine)
14125 {
14126 case EM_RISCV:
14127 return reloc_type == 52; /* R_RISCV_SUB6. */
14128 default:
015dc7e1 14129 return false;
39e07931
AS
14130 }
14131}
14132
2a7b2e88
JK
14133/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14134 relocation entries (possibly formerly used for SHT_GROUP sections). */
14135
015dc7e1 14136static bool
dda8d76d 14137is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14138{
dda8d76d 14139 switch (filedata->file_header.e_machine)
2a7b2e88 14140 {
cb8f3167 14141 case EM_386: /* R_386_NONE. */
d347c9df 14142 case EM_68K: /* R_68K_NONE. */
cfb8c092 14143 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14144 case EM_ALPHA: /* R_ALPHA_NONE. */
14145 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14146 case EM_ARC: /* R_ARC_NONE. */
886a2506 14147 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14148 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14149 case EM_ARM: /* R_ARM_NONE. */
d347c9df 14150 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 14151 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14152 case EM_FT32: /* R_FT32_NONE. */
14153 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14154 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14155 case EM_L1OM: /* R_X86_64_NONE. */
14156 case EM_M32R: /* R_M32R_NONE. */
14157 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14158 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14159 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14160 case EM_NIOS32: /* R_NIOS_NONE. */
14161 case EM_OR1K: /* R_OR1K_NONE. */
14162 case EM_PARISC: /* R_PARISC_NONE. */
14163 case EM_PPC64: /* R_PPC64_NONE. */
14164 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14165 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14166 case EM_S390: /* R_390_NONE. */
14167 case EM_S390_OLD:
14168 case EM_SH: /* R_SH_NONE. */
14169 case EM_SPARC32PLUS:
14170 case EM_SPARC: /* R_SPARC_NONE. */
14171 case EM_SPARCV9:
aa137e4d
NC
14172 case EM_TILEGX: /* R_TILEGX_NONE. */
14173 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14174 case EM_TI_C6000:/* R_C6000_NONE. */
14175 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 14176 case EM_XC16X:
6655dba2 14177 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14178 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14179 return reloc_type == 0;
d347c9df 14180
a06ea964
NC
14181 case EM_AARCH64:
14182 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14183 case EM_AVR_OLD:
14184 case EM_AVR:
14185 return (reloc_type == 0 /* R_AVR_NONE. */
14186 || reloc_type == 30 /* R_AVR_DIFF8. */
14187 || reloc_type == 31 /* R_AVR_DIFF16. */
14188 || reloc_type == 32 /* R_AVR_DIFF32. */);
14189 case EM_METAG:
14190 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
14191 case EM_NDS32:
14192 return (reloc_type == 0 /* R_XTENSA_NONE. */
14193 || reloc_type == 204 /* R_NDS32_DIFF8. */
14194 || reloc_type == 205 /* R_NDS32_DIFF16. */
14195 || reloc_type == 206 /* R_NDS32_DIFF32. */
14196 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
14197 case EM_TI_PRU:
14198 return (reloc_type == 0 /* R_PRU_NONE. */
14199 || reloc_type == 65 /* R_PRU_DIFF8. */
14200 || reloc_type == 66 /* R_PRU_DIFF16. */
14201 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14202 case EM_XTENSA_OLD:
14203 case EM_XTENSA:
4dc3c23d
AM
14204 return (reloc_type == 0 /* R_XTENSA_NONE. */
14205 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14206 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14207 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14208 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14209 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14210 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14211 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14212 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14213 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14214 }
015dc7e1 14215 return false;
2a7b2e88
JK
14216}
14217
d1c4b12b
NC
14218/* Returns TRUE if there is a relocation against
14219 section NAME at OFFSET bytes. */
14220
015dc7e1 14221bool
d1c4b12b
NC
14222reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14223{
14224 Elf_Internal_Rela * relocs;
14225 Elf_Internal_Rela * rp;
14226
14227 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14228 return false;
d1c4b12b
NC
14229
14230 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14231
14232 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14233 if (rp->r_offset == offset)
015dc7e1 14234 return true;
d1c4b12b 14235
015dc7e1 14236 return false;
d1c4b12b
NC
14237}
14238
cf13d699 14239/* Apply relocations to a section.
32ec8896
NC
14240 Returns TRUE upon success, FALSE otherwise.
14241 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14242 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14243 will be set to the number of relocs loaded.
14244
cf13d699 14245 Note: So far support has been added only for those relocations
32ec8896
NC
14246 which can be found in debug sections. FIXME: Add support for
14247 more relocations ? */
1b315056 14248
015dc7e1 14249static bool
dda8d76d 14250apply_relocations (Filedata * filedata,
d1c4b12b
NC
14251 const Elf_Internal_Shdr * section,
14252 unsigned char * start,
14253 bfd_size_type size,
1449284b 14254 void ** relocs_return,
d1c4b12b 14255 unsigned long * num_relocs_return)
1b315056 14256{
cf13d699 14257 Elf_Internal_Shdr * relsec;
0d2a7a93 14258 unsigned char * end = start + size;
cb8f3167 14259
d1c4b12b
NC
14260 if (relocs_return != NULL)
14261 {
14262 * (Elf_Internal_Rela **) relocs_return = NULL;
14263 * num_relocs_return = 0;
14264 }
14265
dda8d76d 14266 if (filedata->file_header.e_type != ET_REL)
32ec8896 14267 /* No relocs to apply. */
015dc7e1 14268 return true;
1b315056 14269
cf13d699 14270 /* Find the reloc section associated with the section. */
dda8d76d
NC
14271 for (relsec = filedata->section_headers;
14272 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14273 ++relsec)
252b5132 14274 {
015dc7e1 14275 bool is_rela;
41e92641 14276 unsigned long num_relocs;
2cf0635d
NC
14277 Elf_Internal_Rela * relocs;
14278 Elf_Internal_Rela * rp;
14279 Elf_Internal_Shdr * symsec;
14280 Elf_Internal_Sym * symtab;
ba5cdace 14281 unsigned long num_syms;
2cf0635d 14282 Elf_Internal_Sym * sym;
252b5132 14283
41e92641 14284 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14285 || relsec->sh_info >= filedata->file_header.e_shnum
14286 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14287 || relsec->sh_size == 0
dda8d76d 14288 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14289 continue;
428409d5 14290
a788aedd
AM
14291 symsec = filedata->section_headers + relsec->sh_link;
14292 if (symsec->sh_type != SHT_SYMTAB
14293 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14294 return false;
a788aedd 14295
41e92641
NC
14296 is_rela = relsec->sh_type == SHT_RELA;
14297
14298 if (is_rela)
14299 {
dda8d76d 14300 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14301 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14302 return false;
41e92641
NC
14303 }
14304 else
14305 {
dda8d76d 14306 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14307 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14308 return false;
41e92641
NC
14309 }
14310
14311 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14312 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14313 is_rela = false;
428409d5 14314
dda8d76d 14315 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 14316
41e92641 14317 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14318 {
015dc7e1
AM
14319 bfd_vma addend;
14320 unsigned int reloc_type;
14321 unsigned int reloc_size;
14322 bool reloc_inplace = false;
14323 bool reloc_subtract = false;
14324 unsigned char *rloc;
14325 unsigned long sym_index;
4b78141a 14326
dda8d76d 14327 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14328
dda8d76d 14329 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14330 continue;
dda8d76d 14331 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14332 continue;
dda8d76d
NC
14333 else if (is_32bit_abs_reloc (filedata, reloc_type)
14334 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14335 reloc_size = 4;
dda8d76d
NC
14336 else if (is_64bit_abs_reloc (filedata, reloc_type)
14337 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14338 reloc_size = 8;
dda8d76d 14339 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14340 reloc_size = 3;
dda8d76d 14341 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14342 reloc_size = 2;
39e07931
AS
14343 else if (is_8bit_abs_reloc (filedata, reloc_type)
14344 || is_6bit_abs_reloc (filedata, reloc_type))
14345 reloc_size = 1;
03336641
JW
14346 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14347 reloc_type))
14348 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14349 {
14350 reloc_size = 4;
015dc7e1 14351 reloc_inplace = true;
03336641
JW
14352 }
14353 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14354 reloc_type))
14355 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14356 {
14357 reloc_size = 8;
015dc7e1 14358 reloc_inplace = true;
03336641
JW
14359 }
14360 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14361 reloc_type))
14362 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14363 {
14364 reloc_size = 2;
015dc7e1 14365 reloc_inplace = true;
03336641
JW
14366 }
14367 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14368 reloc_type))
14369 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14370 {
14371 reloc_size = 1;
015dc7e1 14372 reloc_inplace = true;
03336641 14373 }
39e07931
AS
14374 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
14375 reloc_type)))
14376 {
14377 reloc_size = 1;
015dc7e1 14378 reloc_inplace = true;
39e07931 14379 }
aca88567 14380 else
4b78141a 14381 {
bee0ee85 14382 static unsigned int prev_reloc = 0;
dda8d76d 14383
bee0ee85
NC
14384 if (reloc_type != prev_reloc)
14385 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 14386 reloc_type, printable_section_name (filedata, section));
bee0ee85 14387 prev_reloc = reloc_type;
4b78141a
NC
14388 continue;
14389 }
103f02d3 14390
91d6fa6a 14391 rloc = start + rp->r_offset;
75802ccb 14392 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
14393 {
14394 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
14395 (unsigned long) rp->r_offset,
dda8d76d 14396 printable_section_name (filedata, section));
700dd8b7
L
14397 continue;
14398 }
103f02d3 14399
ba5cdace
NC
14400 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
14401 if (sym_index >= num_syms)
14402 {
14403 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 14404 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
14405 continue;
14406 }
14407 sym = symtab + sym_index;
41e92641
NC
14408
14409 /* If the reloc has a symbol associated with it,
55f25fc3
L
14410 make sure that it is of an appropriate type.
14411
14412 Relocations against symbols without type can happen.
14413 Gcc -feliminate-dwarf2-dups may generate symbols
14414 without type for debug info.
14415
14416 Icc generates relocations against function symbols
14417 instead of local labels.
14418
14419 Relocations against object symbols can happen, eg when
14420 referencing a global array. For an example of this see
14421 the _clz.o binary in libgcc.a. */
aca88567 14422 if (sym != symtab
b8871f35 14423 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 14424 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 14425 {
d3a49aa8 14426 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
14427 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
14428 printable_section_name (filedata, relsec),
d3a49aa8 14429 (long int)(rp - relocs));
aca88567 14430 continue;
5b18a4bc 14431 }
252b5132 14432
4dc3c23d
AM
14433 addend = 0;
14434 if (is_rela)
14435 addend += rp->r_addend;
c47320c3
AM
14436 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
14437 partial_inplace. */
4dc3c23d 14438 if (!is_rela
dda8d76d 14439 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 14440 && reloc_type == 1)
dda8d76d
NC
14441 || ((filedata->file_header.e_machine == EM_PJ
14442 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 14443 && reloc_type == 1)
dda8d76d
NC
14444 || ((filedata->file_header.e_machine == EM_D30V
14445 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
14446 && reloc_type == 12)
14447 || reloc_inplace)
39e07931
AS
14448 {
14449 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
14450 addend += byte_get (rloc, reloc_size) & 0x3f;
14451 else
14452 addend += byte_get (rloc, reloc_size);
14453 }
cb8f3167 14454
dda8d76d
NC
14455 if (is_32bit_pcrel_reloc (filedata, reloc_type)
14456 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
14457 {
14458 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 14459 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 14460 addend -= 8;
91d6fa6a 14461 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
14462 reloc_size);
14463 }
39e07931
AS
14464 else if (is_6bit_abs_reloc (filedata, reloc_type)
14465 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
14466 {
14467 if (reloc_subtract)
14468 addend -= sym->st_value;
14469 else
14470 addend += sym->st_value;
14471 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
14472 byte_put (rloc, addend, reloc_size);
14473 }
03336641
JW
14474 else if (reloc_subtract)
14475 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 14476 else
91d6fa6a 14477 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 14478 }
252b5132 14479
5b18a4bc 14480 free (symtab);
f84ce13b
NC
14481 /* Let the target specific reloc processing code know that
14482 we have finished with these relocs. */
dda8d76d 14483 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
14484
14485 if (relocs_return)
14486 {
14487 * (Elf_Internal_Rela **) relocs_return = relocs;
14488 * num_relocs_return = num_relocs;
14489 }
14490 else
14491 free (relocs);
14492
5b18a4bc
NC
14493 break;
14494 }
32ec8896 14495
015dc7e1 14496 return true;
5b18a4bc 14497}
103f02d3 14498
cf13d699 14499#ifdef SUPPORT_DISASSEMBLY
015dc7e1 14500static bool
dda8d76d 14501disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14502{
dda8d76d 14503 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 14504
74e1a04b 14505 /* FIXME: XXX -- to be done --- XXX */
cf13d699 14506
015dc7e1 14507 return true;
cf13d699
NC
14508}
14509#endif
14510
14511/* Reads in the contents of SECTION from FILE, returning a pointer
14512 to a malloc'ed buffer or NULL if something went wrong. */
14513
14514static char *
dda8d76d 14515get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14516{
dda8d76d 14517 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
14518
14519 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
14520 {
c6b78c96 14521 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 14522 printable_section_name (filedata, section));
cf13d699
NC
14523 return NULL;
14524 }
14525
dda8d76d 14526 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 14527 _("section contents"));
cf13d699
NC
14528}
14529
0e602686
NC
14530/* Uncompresses a section that was compressed using zlib, in place. */
14531
015dc7e1 14532static bool
dda8d76d
NC
14533uncompress_section_contents (unsigned char ** buffer,
14534 dwarf_size_type uncompressed_size,
14535 dwarf_size_type * size)
0e602686
NC
14536{
14537 dwarf_size_type compressed_size = *size;
14538 unsigned char * compressed_buffer = *buffer;
14539 unsigned char * uncompressed_buffer;
14540 z_stream strm;
14541 int rc;
14542
14543 /* It is possible the section consists of several compressed
14544 buffers concatenated together, so we uncompress in a loop. */
14545 /* PR 18313: The state field in the z_stream structure is supposed
14546 to be invisible to the user (ie us), but some compilers will
14547 still complain about it being used without initialisation. So
14548 we first zero the entire z_stream structure and then set the fields
14549 that we need. */
14550 memset (& strm, 0, sizeof strm);
14551 strm.avail_in = compressed_size;
14552 strm.next_in = (Bytef *) compressed_buffer;
14553 strm.avail_out = uncompressed_size;
14554 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
14555
14556 rc = inflateInit (& strm);
14557 while (strm.avail_in > 0)
14558 {
14559 if (rc != Z_OK)
3624a6c1 14560 break;
0e602686
NC
14561 strm.next_out = ((Bytef *) uncompressed_buffer
14562 + (uncompressed_size - strm.avail_out));
14563 rc = inflate (&strm, Z_FINISH);
14564 if (rc != Z_STREAM_END)
3624a6c1 14565 break;
0e602686
NC
14566 rc = inflateReset (& strm);
14567 }
ad92f33d
AM
14568 if (inflateEnd (& strm) != Z_OK
14569 || rc != Z_OK
0e602686
NC
14570 || strm.avail_out != 0)
14571 goto fail;
14572
14573 *buffer = uncompressed_buffer;
14574 *size = uncompressed_size;
015dc7e1 14575 return true;
0e602686
NC
14576
14577 fail:
14578 free (uncompressed_buffer);
14579 /* Indicate decompression failure. */
14580 *buffer = NULL;
015dc7e1 14581 return false;
0e602686 14582}
dd24e3da 14583
015dc7e1 14584static bool
dda8d76d 14585dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14586{
015dc7e1
AM
14587 Elf_Internal_Shdr *relsec;
14588 bfd_size_type num_bytes;
14589 unsigned char *data;
14590 unsigned char *end;
14591 unsigned char *real_start;
14592 unsigned char *start;
14593 bool some_strings_shown;
cf13d699 14594
dda8d76d 14595 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14596 if (start == NULL)
c6b78c96 14597 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 14598 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 14599
0e602686 14600 num_bytes = section->sh_size;
cf13d699 14601
835f2fae
NC
14602 if (filedata->is_separate)
14603 printf (_("\nString dump of section '%s' in linked file %s:\n"),
14604 printable_section_name (filedata, section),
14605 filedata->file_name);
14606 else
14607 printf (_("\nString dump of section '%s':\n"),
14608 printable_section_name (filedata, section));
cf13d699 14609
0e602686
NC
14610 if (decompress_dumps)
14611 {
14612 dwarf_size_type new_size = num_bytes;
14613 dwarf_size_type uncompressed_size = 0;
14614
14615 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14616 {
14617 Elf_Internal_Chdr chdr;
14618 unsigned int compression_header_size
ebdf1ebf
NC
14619 = get_compression_header (& chdr, (unsigned char *) start,
14620 num_bytes);
5844b465
NC
14621 if (compression_header_size == 0)
14622 /* An error message will have already been generated
14623 by get_compression_header. */
14624 goto error_out;
0e602686 14625
813dabb9 14626 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14627 {
813dabb9 14628 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14629 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14630 goto error_out;
813dabb9 14631 }
813dabb9
L
14632 uncompressed_size = chdr.ch_size;
14633 start += compression_header_size;
14634 new_size -= compression_header_size;
0e602686
NC
14635 }
14636 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14637 {
14638 /* Read the zlib header. In this case, it should be "ZLIB"
14639 followed by the uncompressed section size, 8 bytes in
14640 big-endian order. */
14641 uncompressed_size = start[4]; uncompressed_size <<= 8;
14642 uncompressed_size += start[5]; uncompressed_size <<= 8;
14643 uncompressed_size += start[6]; uncompressed_size <<= 8;
14644 uncompressed_size += start[7]; uncompressed_size <<= 8;
14645 uncompressed_size += start[8]; uncompressed_size <<= 8;
14646 uncompressed_size += start[9]; uncompressed_size <<= 8;
14647 uncompressed_size += start[10]; uncompressed_size <<= 8;
14648 uncompressed_size += start[11];
14649 start += 12;
14650 new_size -= 12;
14651 }
14652
1835f746
NC
14653 if (uncompressed_size)
14654 {
14655 if (uncompress_section_contents (& start,
14656 uncompressed_size, & new_size))
14657 num_bytes = new_size;
14658 else
14659 {
14660 error (_("Unable to decompress section %s\n"),
dda8d76d 14661 printable_section_name (filedata, section));
f761cb13 14662 goto error_out;
1835f746
NC
14663 }
14664 }
bc303e5d
NC
14665 else
14666 start = real_start;
0e602686 14667 }
fd8008d8 14668
cf13d699
NC
14669 /* If the section being dumped has relocations against it the user might
14670 be expecting these relocations to have been applied. Check for this
14671 case and issue a warning message in order to avoid confusion.
14672 FIXME: Maybe we ought to have an option that dumps a section with
14673 relocs applied ? */
dda8d76d
NC
14674 for (relsec = filedata->section_headers;
14675 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14676 ++relsec)
14677 {
14678 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14679 || relsec->sh_info >= filedata->file_header.e_shnum
14680 || filedata->section_headers + relsec->sh_info != section
cf13d699 14681 || relsec->sh_size == 0
dda8d76d 14682 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14683 continue;
14684
14685 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14686 break;
14687 }
14688
cf13d699
NC
14689 data = start;
14690 end = start + num_bytes;
015dc7e1 14691 some_strings_shown = false;
cf13d699 14692
ba3265d0
NC
14693#ifdef HAVE_MBSTATE_T
14694 mbstate_t state;
14695 /* Initialise the multibyte conversion state. */
14696 memset (& state, 0, sizeof (state));
14697#endif
14698
015dc7e1 14699 bool continuing = false;
ba3265d0 14700
cf13d699
NC
14701 while (data < end)
14702 {
14703 while (!ISPRINT (* data))
14704 if (++ data >= end)
14705 break;
14706
14707 if (data < end)
14708 {
071436c6
NC
14709 size_t maxlen = end - data;
14710
ba3265d0
NC
14711 if (continuing)
14712 {
14713 printf (" ");
015dc7e1 14714 continuing = false;
ba3265d0
NC
14715 }
14716 else
14717 {
d1ce973e 14718 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
14719 }
14720
4082ef84
NC
14721 if (maxlen > 0)
14722 {
f3da8a96 14723 char c = 0;
ba3265d0
NC
14724
14725 while (maxlen)
14726 {
14727 c = *data++;
14728
14729 if (c == 0)
14730 break;
14731
14732 /* PR 25543: Treat new-lines as string-ending characters. */
14733 if (c == '\n')
14734 {
14735 printf ("\\n\n");
14736 if (*data != 0)
015dc7e1 14737 continuing = true;
ba3265d0
NC
14738 break;
14739 }
14740
14741 /* Do not print control characters directly as they can affect terminal
14742 settings. Such characters usually appear in the names generated
14743 by the assembler for local labels. */
14744 if (ISCNTRL (c))
14745 {
14746 printf ("^%c", c + 0x40);
14747 }
14748 else if (ISPRINT (c))
14749 {
14750 putchar (c);
14751 }
14752 else
14753 {
14754 size_t n;
14755#ifdef HAVE_MBSTATE_T
14756 wchar_t w;
14757#endif
14758 /* Let printf do the hard work of displaying multibyte characters. */
14759 printf ("%.1s", data - 1);
14760#ifdef HAVE_MBSTATE_T
14761 /* Try to find out how many bytes made up the character that was
14762 just printed. Advance the symbol pointer past the bytes that
14763 were displayed. */
14764 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
14765#else
14766 n = 1;
14767#endif
14768 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
14769 data += (n - 1);
14770 }
14771 }
14772
14773 if (c != '\n')
14774 putchar ('\n');
4082ef84
NC
14775 }
14776 else
14777 {
14778 printf (_("<corrupt>\n"));
14779 data = end;
14780 }
015dc7e1 14781 some_strings_shown = true;
cf13d699
NC
14782 }
14783 }
14784
14785 if (! some_strings_shown)
14786 printf (_(" No strings found in this section."));
14787
0e602686 14788 free (real_start);
cf13d699
NC
14789
14790 putchar ('\n');
015dc7e1 14791 return true;
f761cb13
AM
14792
14793error_out:
14794 free (real_start);
015dc7e1 14795 return false;
cf13d699
NC
14796}
14797
015dc7e1
AM
14798static bool
14799dump_section_as_bytes (Elf_Internal_Shdr *section,
14800 Filedata *filedata,
14801 bool relocate)
cf13d699
NC
14802{
14803 Elf_Internal_Shdr * relsec;
0e602686
NC
14804 bfd_size_type bytes;
14805 bfd_size_type section_size;
14806 bfd_vma addr;
14807 unsigned char * data;
14808 unsigned char * real_start;
14809 unsigned char * start;
14810
dda8d76d 14811 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14812 if (start == NULL)
c6b78c96 14813 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 14814 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 14815
0e602686 14816 section_size = section->sh_size;
cf13d699 14817
835f2fae
NC
14818 if (filedata->is_separate)
14819 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
14820 printable_section_name (filedata, section),
14821 filedata->file_name);
14822 else
14823 printf (_("\nHex dump of section '%s':\n"),
14824 printable_section_name (filedata, section));
cf13d699 14825
0e602686
NC
14826 if (decompress_dumps)
14827 {
14828 dwarf_size_type new_size = section_size;
14829 dwarf_size_type uncompressed_size = 0;
14830
14831 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14832 {
14833 Elf_Internal_Chdr chdr;
14834 unsigned int compression_header_size
ebdf1ebf 14835 = get_compression_header (& chdr, start, section_size);
0e602686 14836
5844b465
NC
14837 if (compression_header_size == 0)
14838 /* An error message will have already been generated
14839 by get_compression_header. */
14840 goto error_out;
14841
813dabb9 14842 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14843 {
813dabb9 14844 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14845 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14846 goto error_out;
0e602686 14847 }
813dabb9
L
14848 uncompressed_size = chdr.ch_size;
14849 start += compression_header_size;
14850 new_size -= compression_header_size;
0e602686
NC
14851 }
14852 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14853 {
14854 /* Read the zlib header. In this case, it should be "ZLIB"
14855 followed by the uncompressed section size, 8 bytes in
14856 big-endian order. */
14857 uncompressed_size = start[4]; uncompressed_size <<= 8;
14858 uncompressed_size += start[5]; uncompressed_size <<= 8;
14859 uncompressed_size += start[6]; uncompressed_size <<= 8;
14860 uncompressed_size += start[7]; uncompressed_size <<= 8;
14861 uncompressed_size += start[8]; uncompressed_size <<= 8;
14862 uncompressed_size += start[9]; uncompressed_size <<= 8;
14863 uncompressed_size += start[10]; uncompressed_size <<= 8;
14864 uncompressed_size += start[11];
14865 start += 12;
14866 new_size -= 12;
14867 }
14868
f055032e
NC
14869 if (uncompressed_size)
14870 {
14871 if (uncompress_section_contents (& start, uncompressed_size,
14872 & new_size))
bc303e5d
NC
14873 {
14874 section_size = new_size;
14875 }
f055032e
NC
14876 else
14877 {
14878 error (_("Unable to decompress section %s\n"),
dda8d76d 14879 printable_section_name (filedata, section));
bc303e5d 14880 /* FIXME: Print the section anyway ? */
f761cb13 14881 goto error_out;
f055032e
NC
14882 }
14883 }
bc303e5d
NC
14884 else
14885 start = real_start;
0e602686 14886 }
14ae95f2 14887
cf13d699
NC
14888 if (relocate)
14889 {
dda8d76d 14890 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 14891 goto error_out;
cf13d699
NC
14892 }
14893 else
14894 {
14895 /* If the section being dumped has relocations against it the user might
14896 be expecting these relocations to have been applied. Check for this
14897 case and issue a warning message in order to avoid confusion.
14898 FIXME: Maybe we ought to have an option that dumps a section with
14899 relocs applied ? */
dda8d76d
NC
14900 for (relsec = filedata->section_headers;
14901 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14902 ++relsec)
14903 {
14904 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14905 || relsec->sh_info >= filedata->file_header.e_shnum
14906 || filedata->section_headers + relsec->sh_info != section
cf13d699 14907 || relsec->sh_size == 0
dda8d76d 14908 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14909 continue;
14910
14911 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14912 break;
14913 }
14914 }
14915
14916 addr = section->sh_addr;
0e602686 14917 bytes = section_size;
cf13d699
NC
14918 data = start;
14919
14920 while (bytes)
14921 {
14922 int j;
14923 int k;
14924 int lbytes;
14925
14926 lbytes = (bytes > 16 ? 16 : bytes);
14927
14928 printf (" 0x%8.8lx ", (unsigned long) addr);
14929
14930 for (j = 0; j < 16; j++)
14931 {
14932 if (j < lbytes)
14933 printf ("%2.2x", data[j]);
14934 else
14935 printf (" ");
14936
14937 if ((j & 3) == 3)
14938 printf (" ");
14939 }
14940
14941 for (j = 0; j < lbytes; j++)
14942 {
14943 k = data[j];
14944 if (k >= ' ' && k < 0x7f)
14945 printf ("%c", k);
14946 else
14947 printf (".");
14948 }
14949
14950 putchar ('\n');
14951
14952 data += lbytes;
14953 addr += lbytes;
14954 bytes -= lbytes;
14955 }
14956
0e602686 14957 free (real_start);
cf13d699
NC
14958
14959 putchar ('\n');
015dc7e1 14960 return true;
f761cb13
AM
14961
14962 error_out:
14963 free (real_start);
015dc7e1 14964 return false;
cf13d699
NC
14965}
14966
094e34f2 14967#ifdef ENABLE_LIBCTF
7d9813f1
NA
14968static ctf_sect_t *
14969shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
14970{
b9e920ec 14971 buf->cts_name = SECTION_NAME_PRINT (shdr);
7d9813f1
NA
14972 buf->cts_size = shdr->sh_size;
14973 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
14974
14975 return buf;
14976}
14977
14978/* Formatting callback function passed to ctf_dump. Returns either the pointer
14979 it is passed, or a pointer to newly-allocated storage, in which case
14980 dump_ctf() will free it when it no longer needs it. */
14981
2f6ecaed
NA
14982static char *
14983dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14984 char *s, void *arg)
7d9813f1 14985{
3e50a591 14986 const char *blanks = arg;
7d9813f1
NA
14987 char *new_s;
14988
3e50a591 14989 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
14990 return s;
14991 return new_s;
14992}
14993
926c9e76
NA
14994/* Dump CTF errors/warnings. */
14995static void
139633c3 14996dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
14997{
14998 ctf_next_t *it = NULL;
14999 char *errtext;
15000 int is_warning;
15001 int err;
15002
15003 /* Dump accumulated errors and warnings. */
15004 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15005 {
5e9b84f7 15006 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15007 errtext);
15008 free (errtext);
15009 }
15010 if (err != ECTF_NEXT_END)
15011 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15012}
15013
2f6ecaed
NA
15014/* Dump one CTF archive member. */
15015
15016static int
139633c3 15017dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
2f6ecaed 15018{
139633c3 15019 ctf_dict_t *parent = (ctf_dict_t *) arg;
2f6ecaed
NA
15020 const char *things[] = {"Header", "Labels", "Data objects",
15021 "Function objects", "Variables", "Types", "Strings",
15022 ""};
15023 const char **thing;
15024 size_t i;
8b37e7b6 15025 int err = 0;
2f6ecaed
NA
15026
15027 /* Only print out the name of non-default-named archive members.
15028 The name .ctf appears everywhere, even for things that aren't
15029 really archives, so printing it out is liable to be confusing.
15030
15031 The parent, if there is one, is the default-owned archive member:
15032 avoid importing it into itself. (This does no harm, but looks
15033 confusing.) */
15034
15035 if (strcmp (name, ".ctf") != 0)
15036 {
15037 printf (_("\nCTF archive member: %s:\n"), name);
15038 ctf_import (ctf, parent);
15039 }
15040
15041 for (i = 0, thing = things; *thing[0]; thing++, i++)
15042 {
15043 ctf_dump_state_t *s = NULL;
15044 char *item;
15045
15046 printf ("\n %s:\n", *thing);
15047 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15048 (void *) " ")) != NULL)
15049 {
15050 printf ("%s\n", item);
15051 free (item);
15052 }
15053
15054 if (ctf_errno (ctf))
15055 {
15056 error (_("Iteration failed: %s, %s\n"), *thing,
15057 ctf_errmsg (ctf_errno (ctf)));
8b37e7b6
NA
15058 err = 1;
15059 goto out;
2f6ecaed
NA
15060 }
15061 }
8b37e7b6
NA
15062
15063 out:
926c9e76 15064 dump_ctf_errs (ctf);
8b37e7b6 15065 return err;
2f6ecaed
NA
15066}
15067
015dc7e1 15068static bool
7d9813f1
NA
15069dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15070{
15071 Elf_Internal_Shdr * parent_sec = NULL;
15072 Elf_Internal_Shdr * symtab_sec = NULL;
15073 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15074 void * data = NULL;
15075 void * symdata = NULL;
15076 void * strdata = NULL;
15077 void * parentdata = NULL;
15078 ctf_sect_t ctfsect, symsect, strsect, parentsect;
15079 ctf_sect_t * symsectp = NULL;
15080 ctf_sect_t * strsectp = NULL;
2f6ecaed
NA
15081 ctf_archive_t * ctfa = NULL;
15082 ctf_archive_t * parenta = NULL, *lookparent;
139633c3 15083 ctf_dict_t * parent = NULL;
7d9813f1 15084
7d9813f1 15085 int err;
015dc7e1 15086 bool ret = false;
7d9813f1
NA
15087
15088 shdr_to_ctf_sect (&ctfsect, section, filedata);
15089 data = get_section_contents (section, filedata);
15090 ctfsect.cts_data = data;
15091
616febde 15092 if (!dump_ctf_symtab_name)
3d16b64e 15093 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15094
15095 if (!dump_ctf_strtab_name)
3d16b64e 15096 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15097
15098 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15099 {
15100 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15101 {
15102 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15103 goto fail;
15104 }
15105 if ((symdata = (void *) get_data (NULL, filedata,
15106 symtab_sec->sh_offset, 1,
15107 symtab_sec->sh_size,
15108 _("symbols"))) == NULL)
15109 goto fail;
15110 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15111 symsect.cts_data = symdata;
15112 }
835f2fae 15113
df16e041 15114 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15115 {
15116 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15117 {
15118 error (_("No string table section named %s\n"),
15119 dump_ctf_strtab_name);
15120 goto fail;
15121 }
15122 if ((strdata = (void *) get_data (NULL, filedata,
15123 strtab_sec->sh_offset, 1,
15124 strtab_sec->sh_size,
15125 _("strings"))) == NULL)
15126 goto fail;
15127 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15128 strsect.cts_data = strdata;
15129 }
835f2fae 15130
7d9813f1
NA
15131 if (dump_ctf_parent_name)
15132 {
15133 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
15134 {
15135 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
15136 goto fail;
15137 }
15138 if ((parentdata = (void *) get_data (NULL, filedata,
15139 parent_sec->sh_offset, 1,
15140 parent_sec->sh_size,
15141 _("CTF parent"))) == NULL)
15142 goto fail;
15143 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
15144 parentsect.cts_data = parentdata;
15145 }
15146
2f6ecaed
NA
15147 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15148 libctf papers over the difference, so we can pretend it is always an
15149 archive. Possibly open the parent as well, if one was specified. */
7d9813f1 15150
2f6ecaed 15151 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15152 {
926c9e76 15153 dump_ctf_errs (NULL);
7d9813f1
NA
15154 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15155 goto fail;
15156 }
15157
96c61be5
NA
15158 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15159 != ELFDATA2MSB);
15160
7d9813f1
NA
15161 if (parentdata)
15162 {
2f6ecaed
NA
15163 if ((parenta = ctf_arc_bufopen (&parentsect, symsectp, strsectp,
15164 &err)) == NULL)
7d9813f1 15165 {
926c9e76 15166 dump_ctf_errs (NULL);
7d9813f1
NA
15167 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15168 goto fail;
15169 }
2f6ecaed
NA
15170 lookparent = parenta;
15171 }
15172 else
15173 lookparent = ctfa;
7d9813f1 15174
2f6ecaed
NA
15175 /* Assume that the applicable parent archive member is the default one.
15176 (This is what all known implementations are expected to do, if they
15177 put CTFs and their parents in archives together.) */
ae41200b 15178 if ((parent = ctf_dict_open (lookparent, NULL, &err)) == NULL)
2f6ecaed 15179 {
926c9e76 15180 dump_ctf_errs (NULL);
2f6ecaed
NA
15181 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15182 goto fail;
7d9813f1
NA
15183 }
15184
015dc7e1 15185 ret = true;
7d9813f1 15186
835f2fae
NC
15187 if (filedata->is_separate)
15188 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15189 printable_section_name (filedata, section),
15190 filedata->file_name);
15191 else
15192 printf (_("\nDump of CTF section '%s':\n"),
15193 printable_section_name (filedata, section));
7d9813f1 15194
83d59285
NA
15195 if ((err = ctf_archive_iter (ctfa, dump_ctf_archive_member, parent)) != 0)
15196 {
15197 dump_ctf_errs (NULL);
15198 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
015dc7e1 15199 ret = false;
83d59285 15200 }
7d9813f1
NA
15201
15202 fail:
139633c3 15203 ctf_dict_close (parent);
2f6ecaed
NA
15204 ctf_close (ctfa);
15205 ctf_close (parenta);
7d9813f1
NA
15206 free (parentdata);
15207 free (data);
15208 free (symdata);
15209 free (strdata);
15210 return ret;
15211}
094e34f2 15212#endif
7d9813f1 15213
015dc7e1 15214static bool
dda8d76d
NC
15215load_specific_debug_section (enum dwarf_section_display_enum debug,
15216 const Elf_Internal_Shdr * sec,
15217 void * data)
1007acb3 15218{
2cf0635d 15219 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15220 char buf [64];
dda8d76d 15221 Filedata * filedata = (Filedata *) data;
9abca702 15222
19e6b90e 15223 if (section->start != NULL)
dda8d76d
NC
15224 {
15225 /* If it is already loaded, do nothing. */
15226 if (streq (section->filename, filedata->file_name))
015dc7e1 15227 return true;
dda8d76d
NC
15228 free (section->start);
15229 }
1007acb3 15230
19e6b90e
L
15231 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15232 section->address = sec->sh_addr;
dda8d76d
NC
15233 section->filename = filedata->file_name;
15234 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15235 sec->sh_offset, 1,
15236 sec->sh_size, buf);
59245841
NC
15237 if (section->start == NULL)
15238 section->size = 0;
15239 else
15240 {
77115a4a
L
15241 unsigned char *start = section->start;
15242 dwarf_size_type size = sec->sh_size;
dab394de 15243 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15244
15245 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15246 {
15247 Elf_Internal_Chdr chdr;
d8024a91
NC
15248 unsigned int compression_header_size;
15249
f53be977
L
15250 if (size < (is_32bit_elf
15251 ? sizeof (Elf32_External_Chdr)
15252 : sizeof (Elf64_External_Chdr)))
d8024a91 15253 {
55be8fd0 15254 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15255 section->name);
015dc7e1 15256 return false;
d8024a91
NC
15257 }
15258
ebdf1ebf 15259 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15260 if (compression_header_size == 0)
15261 /* An error message will have already been generated
15262 by get_compression_header. */
015dc7e1 15263 return false;
d8024a91 15264
813dabb9
L
15265 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15266 {
15267 warn (_("section '%s' has unsupported compress type: %d\n"),
15268 section->name, chdr.ch_type);
015dc7e1 15269 return false;
813dabb9 15270 }
dab394de 15271 uncompressed_size = chdr.ch_size;
77115a4a
L
15272 start += compression_header_size;
15273 size -= compression_header_size;
15274 }
dab394de
L
15275 else if (size > 12 && streq ((char *) start, "ZLIB"))
15276 {
15277 /* Read the zlib header. In this case, it should be "ZLIB"
15278 followed by the uncompressed section size, 8 bytes in
15279 big-endian order. */
15280 uncompressed_size = start[4]; uncompressed_size <<= 8;
15281 uncompressed_size += start[5]; uncompressed_size <<= 8;
15282 uncompressed_size += start[6]; uncompressed_size <<= 8;
15283 uncompressed_size += start[7]; uncompressed_size <<= 8;
15284 uncompressed_size += start[8]; uncompressed_size <<= 8;
15285 uncompressed_size += start[9]; uncompressed_size <<= 8;
15286 uncompressed_size += start[10]; uncompressed_size <<= 8;
15287 uncompressed_size += start[11];
15288 start += 12;
15289 size -= 12;
15290 }
15291
1835f746 15292 if (uncompressed_size)
77115a4a 15293 {
1835f746
NC
15294 if (uncompress_section_contents (&start, uncompressed_size,
15295 &size))
15296 {
15297 /* Free the compressed buffer, update the section buffer
15298 and the section size if uncompress is successful. */
15299 free (section->start);
15300 section->start = start;
15301 }
15302 else
15303 {
15304 error (_("Unable to decompress section %s\n"),
dda8d76d 15305 printable_section_name (filedata, sec));
015dc7e1 15306 return false;
1835f746 15307 }
77115a4a 15308 }
bc303e5d 15309
77115a4a 15310 section->size = size;
59245841 15311 }
4a114e3e 15312
1b315056 15313 if (section->start == NULL)
015dc7e1 15314 return false;
1b315056 15315
19e6b90e 15316 if (debug_displays [debug].relocate)
32ec8896 15317 {
dda8d76d 15318 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15319 & section->reloc_info, & section->num_relocs))
015dc7e1 15320 return false;
32ec8896 15321 }
d1c4b12b
NC
15322 else
15323 {
15324 section->reloc_info = NULL;
15325 section->num_relocs = 0;
15326 }
1007acb3 15327
015dc7e1 15328 return true;
1007acb3
L
15329}
15330
301a9420
AM
15331#if HAVE_LIBDEBUGINFOD
15332/* Return a hex string representation of the build-id. */
15333unsigned char *
15334get_build_id (void * data)
15335{
ca0e11aa 15336 Filedata * filedata = (Filedata *) data;
301a9420
AM
15337 Elf_Internal_Shdr * shdr;
15338 unsigned long i;
15339
55be8fd0
NC
15340 /* Iterate through notes to find note.gnu.build-id.
15341 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15342 for (i = 0, shdr = filedata->section_headers;
15343 i < filedata->file_header.e_shnum && shdr != NULL;
15344 i++, shdr++)
15345 {
15346 if (shdr->sh_type != SHT_NOTE)
15347 continue;
15348
15349 char * next;
15350 char * end;
15351 size_t data_remaining;
15352 size_t min_notesz;
15353 Elf_External_Note * enote;
15354 Elf_Internal_Note inote;
15355
15356 bfd_vma offset = shdr->sh_offset;
15357 bfd_vma align = shdr->sh_addralign;
15358 bfd_vma length = shdr->sh_size;
15359
15360 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15361 if (enote == NULL)
15362 continue;
15363
15364 if (align < 4)
15365 align = 4;
15366 else if (align != 4 && align != 8)
f761cb13
AM
15367 {
15368 free (enote);
15369 continue;
15370 }
301a9420
AM
15371
15372 end = (char *) enote + length;
15373 data_remaining = end - (char *) enote;
15374
15375 if (!is_ia64_vms (filedata))
15376 {
15377 min_notesz = offsetof (Elf_External_Note, name);
15378 if (data_remaining < min_notesz)
15379 {
55be8fd0
NC
15380 warn (_("\
15381malformed note encountered in section %s whilst scanning for build-id note\n"),
15382 printable_section_name (filedata, shdr));
f761cb13 15383 free (enote);
55be8fd0 15384 continue;
301a9420
AM
15385 }
15386 data_remaining -= min_notesz;
15387
15388 inote.type = BYTE_GET (enote->type);
15389 inote.namesz = BYTE_GET (enote->namesz);
15390 inote.namedata = enote->name;
15391 inote.descsz = BYTE_GET (enote->descsz);
15392 inote.descdata = ((char *) enote
15393 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15394 inote.descpos = offset + (inote.descdata - (char *) enote);
15395 next = ((char *) enote
15396 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15397 }
15398 else
15399 {
15400 Elf64_External_VMS_Note *vms_enote;
15401
15402 /* PR binutils/15191
15403 Make sure that there is enough data to read. */
15404 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15405 if (data_remaining < min_notesz)
15406 {
55be8fd0
NC
15407 warn (_("\
15408malformed note encountered in section %s whilst scanning for build-id note\n"),
15409 printable_section_name (filedata, shdr));
f761cb13 15410 free (enote);
55be8fd0 15411 continue;
301a9420
AM
15412 }
15413 data_remaining -= min_notesz;
15414
15415 vms_enote = (Elf64_External_VMS_Note *) enote;
15416 inote.type = BYTE_GET (vms_enote->type);
15417 inote.namesz = BYTE_GET (vms_enote->namesz);
15418 inote.namedata = vms_enote->name;
15419 inote.descsz = BYTE_GET (vms_enote->descsz);
15420 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15421 inote.descpos = offset + (inote.descdata - (char *) enote);
15422 next = inote.descdata + align_power (inote.descsz, 3);
15423 }
15424
15425 /* Skip malformed notes. */
15426 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
15427 || (size_t) (inote.descdata - inote.namedata) > data_remaining
15428 || (size_t) (next - inote.descdata) < inote.descsz
15429 || ((size_t) (next - inote.descdata)
15430 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
15431 {
55be8fd0
NC
15432 warn (_("\
15433malformed note encountered in section %s whilst scanning for build-id note\n"),
15434 printable_section_name (filedata, shdr));
f761cb13 15435 free (enote);
301a9420
AM
15436 continue;
15437 }
15438
15439 /* Check if this is the build-id note. If so then convert the build-id
15440 bytes to a hex string. */
15441 if (inote.namesz > 0
24d127aa 15442 && startswith (inote.namedata, "GNU")
301a9420
AM
15443 && inote.type == NT_GNU_BUILD_ID)
15444 {
15445 unsigned long j;
15446 char * build_id;
15447
15448 build_id = malloc (inote.descsz * 2 + 1);
15449 if (build_id == NULL)
f761cb13
AM
15450 {
15451 free (enote);
15452 return NULL;
15453 }
301a9420
AM
15454
15455 for (j = 0; j < inote.descsz; ++j)
15456 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
15457 build_id[inote.descsz * 2] = '\0';
f761cb13 15458 free (enote);
301a9420 15459
55be8fd0 15460 return (unsigned char *) build_id;
301a9420 15461 }
f761cb13 15462 free (enote);
301a9420
AM
15463 }
15464
15465 return NULL;
15466}
15467#endif /* HAVE_LIBDEBUGINFOD */
15468
657d0d47
CC
15469/* If this is not NULL, load_debug_section will only look for sections
15470 within the list of sections given here. */
32ec8896 15471static unsigned int * section_subset = NULL;
657d0d47 15472
015dc7e1 15473bool
dda8d76d 15474load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 15475{
2cf0635d
NC
15476 struct dwarf_section * section = &debug_displays [debug].section;
15477 Elf_Internal_Shdr * sec;
dda8d76d
NC
15478 Filedata * filedata = (Filedata *) data;
15479
f425ec66
NC
15480 /* Without section headers we cannot find any sections. */
15481 if (filedata->section_headers == NULL)
015dc7e1 15482 return false;
f425ec66 15483
9c1ce108
AM
15484 if (filedata->string_table == NULL
15485 && filedata->file_header.e_shstrndx != SHN_UNDEF
15486 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
15487 {
15488 Elf_Internal_Shdr * strs;
15489
15490 /* Read in the string table, so that we have section names to scan. */
15491 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
15492
4dff97b2 15493 if (strs != NULL && strs->sh_size != 0)
dda8d76d 15494 {
9c1ce108
AM
15495 filedata->string_table
15496 = (char *) get_data (NULL, filedata, strs->sh_offset,
15497 1, strs->sh_size, _("string table"));
dda8d76d 15498
9c1ce108
AM
15499 filedata->string_table_length
15500 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
15501 }
15502 }
d966045b
DJ
15503
15504 /* Locate the debug section. */
dda8d76d 15505 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
15506 if (sec != NULL)
15507 section->name = section->uncompressed_name;
15508 else
15509 {
dda8d76d 15510 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
15511 if (sec != NULL)
15512 section->name = section->compressed_name;
15513 }
15514 if (sec == NULL)
015dc7e1 15515 return false;
d966045b 15516
657d0d47
CC
15517 /* If we're loading from a subset of sections, and we've loaded
15518 a section matching this name before, it's likely that it's a
15519 different one. */
15520 if (section_subset != NULL)
15521 free_debug_section (debug);
15522
dda8d76d 15523 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
15524}
15525
19e6b90e
L
15526void
15527free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 15528{
2cf0635d 15529 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 15530
19e6b90e
L
15531 if (section->start == NULL)
15532 return;
1007acb3 15533
19e6b90e
L
15534 free ((char *) section->start);
15535 section->start = NULL;
15536 section->address = 0;
15537 section->size = 0;
a788aedd 15538
9db70fc3
AM
15539 free (section->reloc_info);
15540 section->reloc_info = NULL;
15541 section->num_relocs = 0;
1007acb3
L
15542}
15543
015dc7e1 15544static bool
dda8d76d 15545display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 15546{
b9e920ec 15547 char * name = SECTION_NAME_VALID (section) ? SECTION_NAME (section) : "";
dda8d76d 15548 const char * print_name = printable_section_name (filedata, section);
19e6b90e 15549 bfd_size_type length;
015dc7e1 15550 bool result = true;
3f5e193b 15551 int i;
1007acb3 15552
19e6b90e
L
15553 length = section->sh_size;
15554 if (length == 0)
1007acb3 15555 {
74e1a04b 15556 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 15557 return true;
1007acb3 15558 }
5dff79d8
NC
15559 if (section->sh_type == SHT_NOBITS)
15560 {
15561 /* There is no point in dumping the contents of a debugging section
15562 which has the NOBITS type - the bits in the file will be random.
15563 This can happen when a file containing a .eh_frame section is
15564 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
15565 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
15566 print_name);
015dc7e1 15567 return false;
5dff79d8 15568 }
1007acb3 15569
24d127aa 15570 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 15571 name = ".debug_info";
1007acb3 15572
19e6b90e
L
15573 /* See if we know how to display the contents of this section. */
15574 for (i = 0; i < max; i++)
d85bf2ba
NC
15575 {
15576 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
15577 struct dwarf_section_display * display = debug_displays + i;
15578 struct dwarf_section * sec = & display->section;
d966045b 15579
d85bf2ba 15580 if (streq (sec->uncompressed_name, name)
24d127aa 15581 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15582 || streq (sec->compressed_name, name))
15583 {
015dc7e1 15584 bool secondary = (section != find_section (filedata, name));
1007acb3 15585
d85bf2ba
NC
15586 if (secondary)
15587 free_debug_section (id);
dda8d76d 15588
24d127aa 15589 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15590 sec->name = name;
15591 else if (streq (sec->uncompressed_name, name))
15592 sec->name = sec->uncompressed_name;
15593 else
15594 sec->name = sec->compressed_name;
657d0d47 15595
d85bf2ba
NC
15596 if (load_specific_debug_section (id, section, filedata))
15597 {
15598 /* If this debug section is part of a CU/TU set in a .dwp file,
15599 restrict load_debug_section to the sections in that set. */
15600 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 15601
d85bf2ba 15602 result &= display->display (sec, filedata);
657d0d47 15603
d85bf2ba 15604 section_subset = NULL;
1007acb3 15605
44266f36 15606 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
15607 free_debug_section (id);
15608 }
15609 break;
15610 }
15611 }
1007acb3 15612
19e6b90e 15613 if (i == max)
1007acb3 15614 {
74e1a04b 15615 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 15616 result = false;
1007acb3
L
15617 }
15618
19e6b90e 15619 return result;
5b18a4bc 15620}
103f02d3 15621
aef1f6d0
DJ
15622/* Set DUMP_SECTS for all sections where dumps were requested
15623 based on section name. */
15624
15625static void
dda8d76d 15626initialise_dumps_byname (Filedata * filedata)
aef1f6d0 15627{
2cf0635d 15628 struct dump_list_entry * cur;
aef1f6d0
DJ
15629
15630 for (cur = dump_sects_byname; cur; cur = cur->next)
15631 {
15632 unsigned int i;
015dc7e1 15633 bool any = false;
aef1f6d0 15634
dda8d76d 15635 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
15636 if (SECTION_NAME_VALID (filedata->section_headers + i)
15637 && streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 15638 {
6431e409 15639 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 15640 any = true;
aef1f6d0
DJ
15641 }
15642
835f2fae
NC
15643 if (!any && !filedata->is_separate)
15644 warn (_("Section '%s' was not dumped because it does not exist\n"),
15645 cur->name);
aef1f6d0
DJ
15646 }
15647}
15648
015dc7e1 15649static bool
dda8d76d 15650process_section_contents (Filedata * filedata)
5b18a4bc 15651{
2cf0635d 15652 Elf_Internal_Shdr * section;
19e6b90e 15653 unsigned int i;
015dc7e1 15654 bool res = true;
103f02d3 15655
19e6b90e 15656 if (! do_dump)
015dc7e1 15657 return true;
103f02d3 15658
dda8d76d 15659 initialise_dumps_byname (filedata);
aef1f6d0 15660
dda8d76d 15661 for (i = 0, section = filedata->section_headers;
6431e409 15662 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
15663 i++, section++)
15664 {
6431e409 15665 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 15666
d6bfbc39
NC
15667 if (filedata->is_separate && ! process_links)
15668 dump &= DEBUG_DUMP;
047c3dbf 15669
19e6b90e 15670#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
15671 if (dump & DISASS_DUMP)
15672 {
15673 if (! disassemble_section (section, filedata))
015dc7e1 15674 res = false;
dda8d76d 15675 }
19e6b90e 15676#endif
dda8d76d 15677 if (dump & HEX_DUMP)
32ec8896 15678 {
015dc7e1
AM
15679 if (! dump_section_as_bytes (section, filedata, false))
15680 res = false;
32ec8896 15681 }
103f02d3 15682
dda8d76d 15683 if (dump & RELOC_DUMP)
32ec8896 15684 {
015dc7e1
AM
15685 if (! dump_section_as_bytes (section, filedata, true))
15686 res = false;
32ec8896 15687 }
09c11c86 15688
dda8d76d 15689 if (dump & STRING_DUMP)
32ec8896 15690 {
dda8d76d 15691 if (! dump_section_as_strings (section, filedata))
015dc7e1 15692 res = false;
32ec8896 15693 }
cf13d699 15694
dda8d76d 15695 if (dump & DEBUG_DUMP)
32ec8896 15696 {
dda8d76d 15697 if (! display_debug_section (i, section, filedata))
015dc7e1 15698 res = false;
32ec8896 15699 }
7d9813f1 15700
094e34f2 15701#ifdef ENABLE_LIBCTF
7d9813f1
NA
15702 if (dump & CTF_DUMP)
15703 {
15704 if (! dump_section_as_ctf (section, filedata))
015dc7e1 15705 res = false;
7d9813f1 15706 }
094e34f2 15707#endif
5b18a4bc 15708 }
103f02d3 15709
835f2fae 15710 if (! filedata->is_separate)
0ee3043f 15711 {
835f2fae
NC
15712 /* Check to see if the user requested a
15713 dump of a section that does not exist. */
15714 for (; i < filedata->dump.num_dump_sects; i++)
15715 if (filedata->dump.dump_sects[i])
15716 {
ca0e11aa 15717 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 15718 res = false;
835f2fae 15719 }
0ee3043f 15720 }
32ec8896
NC
15721
15722 return res;
5b18a4bc 15723}
103f02d3 15724
5b18a4bc 15725static void
19e6b90e 15726process_mips_fpe_exception (int mask)
5b18a4bc 15727{
19e6b90e
L
15728 if (mask)
15729 {
015dc7e1 15730 bool first = true;
32ec8896 15731
19e6b90e 15732 if (mask & OEX_FPU_INEX)
015dc7e1 15733 fputs ("INEX", stdout), first = false;
19e6b90e 15734 if (mask & OEX_FPU_UFLO)
015dc7e1 15735 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 15736 if (mask & OEX_FPU_OFLO)
015dc7e1 15737 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 15738 if (mask & OEX_FPU_DIV0)
015dc7e1 15739 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
15740 if (mask & OEX_FPU_INVAL)
15741 printf ("%sINVAL", first ? "" : "|");
15742 }
5b18a4bc 15743 else
19e6b90e 15744 fputs ("0", stdout);
5b18a4bc 15745}
103f02d3 15746
f6f0e17b
NC
15747/* Display's the value of TAG at location P. If TAG is
15748 greater than 0 it is assumed to be an unknown tag, and
15749 a message is printed to this effect. Otherwise it is
15750 assumed that a message has already been printed.
15751
15752 If the bottom bit of TAG is set it assumed to have a
15753 string value, otherwise it is assumed to have an integer
15754 value.
15755
15756 Returns an updated P pointing to the first unread byte
15757 beyond the end of TAG's value.
15758
15759 Reads at or beyond END will not be made. */
15760
15761static unsigned char *
60abdbed 15762display_tag_value (signed int tag,
f6f0e17b
NC
15763 unsigned char * p,
15764 const unsigned char * const end)
15765{
15766 unsigned long val;
15767
15768 if (tag > 0)
15769 printf (" Tag_unknown_%d: ", tag);
15770
15771 if (p >= end)
15772 {
4082ef84 15773 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
15774 }
15775 else if (tag & 1)
15776 {
071436c6
NC
15777 /* PR 17531 file: 027-19978-0.004. */
15778 size_t maxlen = (end - p) - 1;
15779
15780 putchar ('"');
4082ef84
NC
15781 if (maxlen > 0)
15782 {
15783 print_symbol ((int) maxlen, (const char *) p);
15784 p += strnlen ((char *) p, maxlen) + 1;
15785 }
15786 else
15787 {
15788 printf (_("<corrupt string tag>"));
15789 p = (unsigned char *) end;
15790 }
071436c6 15791 printf ("\"\n");
f6f0e17b
NC
15792 }
15793 else
15794 {
cd30bcef 15795 READ_ULEB (val, p, end);
f6f0e17b
NC
15796 printf ("%ld (0x%lx)\n", val, val);
15797 }
15798
4082ef84 15799 assert (p <= end);
f6f0e17b
NC
15800 return p;
15801}
15802
53a346d8
CZ
15803/* ARC ABI attributes section. */
15804
15805static unsigned char *
15806display_arc_attribute (unsigned char * p,
15807 const unsigned char * const end)
15808{
15809 unsigned int tag;
53a346d8
CZ
15810 unsigned int val;
15811
cd30bcef 15812 READ_ULEB (tag, p, end);
53a346d8
CZ
15813
15814 switch (tag)
15815 {
15816 case Tag_ARC_PCS_config:
cd30bcef 15817 READ_ULEB (val, p, end);
53a346d8
CZ
15818 printf (" Tag_ARC_PCS_config: ");
15819 switch (val)
15820 {
15821 case 0:
15822 printf (_("Absent/Non standard\n"));
15823 break;
15824 case 1:
15825 printf (_("Bare metal/mwdt\n"));
15826 break;
15827 case 2:
15828 printf (_("Bare metal/newlib\n"));
15829 break;
15830 case 3:
15831 printf (_("Linux/uclibc\n"));
15832 break;
15833 case 4:
15834 printf (_("Linux/glibc\n"));
15835 break;
15836 default:
15837 printf (_("Unknown\n"));
15838 break;
15839 }
15840 break;
15841
15842 case Tag_ARC_CPU_base:
cd30bcef 15843 READ_ULEB (val, p, end);
53a346d8
CZ
15844 printf (" Tag_ARC_CPU_base: ");
15845 switch (val)
15846 {
15847 default:
15848 case TAG_CPU_NONE:
15849 printf (_("Absent\n"));
15850 break;
15851 case TAG_CPU_ARC6xx:
15852 printf ("ARC6xx\n");
15853 break;
15854 case TAG_CPU_ARC7xx:
15855 printf ("ARC7xx\n");
15856 break;
15857 case TAG_CPU_ARCEM:
15858 printf ("ARCEM\n");
15859 break;
15860 case TAG_CPU_ARCHS:
15861 printf ("ARCHS\n");
15862 break;
15863 }
15864 break;
15865
15866 case Tag_ARC_CPU_variation:
cd30bcef 15867 READ_ULEB (val, p, end);
53a346d8
CZ
15868 printf (" Tag_ARC_CPU_variation: ");
15869 switch (val)
15870 {
15871 default:
15872 if (val > 0 && val < 16)
53a346d8 15873 printf ("Core%d\n", val);
d8cbc93b
JL
15874 else
15875 printf ("Unknown\n");
15876 break;
15877
53a346d8
CZ
15878 case 0:
15879 printf (_("Absent\n"));
15880 break;
15881 }
15882 break;
15883
15884 case Tag_ARC_CPU_name:
15885 printf (" Tag_ARC_CPU_name: ");
15886 p = display_tag_value (-1, p, end);
15887 break;
15888
15889 case Tag_ARC_ABI_rf16:
cd30bcef 15890 READ_ULEB (val, p, end);
53a346d8
CZ
15891 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
15892 break;
15893
15894 case Tag_ARC_ABI_osver:
cd30bcef 15895 READ_ULEB (val, p, end);
53a346d8
CZ
15896 printf (" Tag_ARC_ABI_osver: v%d\n", val);
15897 break;
15898
15899 case Tag_ARC_ABI_pic:
15900 case Tag_ARC_ABI_sda:
cd30bcef 15901 READ_ULEB (val, p, end);
53a346d8
CZ
15902 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
15903 : " Tag_ARC_ABI_pic: ");
15904 switch (val)
15905 {
15906 case 0:
15907 printf (_("Absent\n"));
15908 break;
15909 case 1:
15910 printf ("MWDT\n");
15911 break;
15912 case 2:
15913 printf ("GNU\n");
15914 break;
15915 default:
15916 printf (_("Unknown\n"));
15917 break;
15918 }
15919 break;
15920
15921 case Tag_ARC_ABI_tls:
cd30bcef 15922 READ_ULEB (val, p, end);
53a346d8
CZ
15923 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
15924 break;
15925
15926 case Tag_ARC_ABI_enumsize:
cd30bcef 15927 READ_ULEB (val, p, end);
53a346d8
CZ
15928 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
15929 _("smallest"));
15930 break;
15931
15932 case Tag_ARC_ABI_exceptions:
cd30bcef 15933 READ_ULEB (val, p, end);
53a346d8
CZ
15934 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
15935 : _("default"));
15936 break;
15937
15938 case Tag_ARC_ABI_double_size:
cd30bcef 15939 READ_ULEB (val, p, end);
53a346d8
CZ
15940 printf (" Tag_ARC_ABI_double_size: %d\n", val);
15941 break;
15942
15943 case Tag_ARC_ISA_config:
15944 printf (" Tag_ARC_ISA_config: ");
15945 p = display_tag_value (-1, p, end);
15946 break;
15947
15948 case Tag_ARC_ISA_apex:
15949 printf (" Tag_ARC_ISA_apex: ");
15950 p = display_tag_value (-1, p, end);
15951 break;
15952
15953 case Tag_ARC_ISA_mpy_option:
cd30bcef 15954 READ_ULEB (val, p, end);
53a346d8
CZ
15955 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
15956 break;
15957
db1e1b45 15958 case Tag_ARC_ATR_version:
cd30bcef 15959 READ_ULEB (val, p, end);
db1e1b45 15960 printf (" Tag_ARC_ATR_version: %d\n", val);
15961 break;
15962
53a346d8
CZ
15963 default:
15964 return display_tag_value (tag & 1, p, end);
15965 }
15966
15967 return p;
15968}
15969
11c1ff18
PB
15970/* ARM EABI attributes section. */
15971typedef struct
15972{
70e99720 15973 unsigned int tag;
2cf0635d 15974 const char * name;
11c1ff18 15975 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 15976 unsigned int type;
288f0ba2 15977 const char *const *table;
11c1ff18
PB
15978} arm_attr_public_tag;
15979
288f0ba2 15980static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 15981 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 15982 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 15983 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
288f0ba2
AM
15984static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
15985static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 15986 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 15987static const char *const arm_attr_tag_FP_arch[] =
bca38921 15988 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 15989 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
15990static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
15991static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
15992 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
15993 "NEON for ARMv8.1"};
288f0ba2 15994static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
15995 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
15996 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 15997static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 15998 {"V6", "SB", "TLS", "Unused"};
288f0ba2 15999static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16000 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16001static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16002 {"Absolute", "PC-relative", "None"};
288f0ba2 16003static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16004 {"None", "direct", "GOT-indirect"};
288f0ba2 16005static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16006 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16007static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16008static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16009 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16010static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16011static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16012static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16013 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16014static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16015 {"Unused", "small", "int", "forced to int"};
288f0ba2 16016static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16017 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16018static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16019 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16020static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16021 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16022static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16023 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16024 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16025static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16026 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16027 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16028static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16029static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16030 {"Not Allowed", "Allowed"};
288f0ba2 16031static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16032 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16033static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16034 {"Follow architecture", "Allowed"};
288f0ba2 16035static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16036 {"Not Allowed", "Allowed"};
288f0ba2 16037static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16038 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16039 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16040static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16041static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16042 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16043 "TrustZone and Virtualization Extensions"};
288f0ba2 16044static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16045 {"Not Allowed", "Allowed"};
11c1ff18 16046
288f0ba2 16047static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16048 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16049
11c1ff18
PB
16050#define LOOKUP(id, name) \
16051 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16052static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16053{
16054 {4, "CPU_raw_name", 1, NULL},
16055 {5, "CPU_name", 1, NULL},
16056 LOOKUP(6, CPU_arch),
16057 {7, "CPU_arch_profile", 0, NULL},
16058 LOOKUP(8, ARM_ISA_use),
16059 LOOKUP(9, THUMB_ISA_use),
75375b3e 16060 LOOKUP(10, FP_arch),
11c1ff18 16061 LOOKUP(11, WMMX_arch),
f5f53991
AS
16062 LOOKUP(12, Advanced_SIMD_arch),
16063 LOOKUP(13, PCS_config),
11c1ff18
PB
16064 LOOKUP(14, ABI_PCS_R9_use),
16065 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16066 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16067 LOOKUP(17, ABI_PCS_GOT_use),
16068 LOOKUP(18, ABI_PCS_wchar_t),
16069 LOOKUP(19, ABI_FP_rounding),
16070 LOOKUP(20, ABI_FP_denormal),
16071 LOOKUP(21, ABI_FP_exceptions),
16072 LOOKUP(22, ABI_FP_user_exceptions),
16073 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16074 {24, "ABI_align_needed", 0, NULL},
16075 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16076 LOOKUP(26, ABI_enum_size),
16077 LOOKUP(27, ABI_HardFP_use),
16078 LOOKUP(28, ABI_VFP_args),
16079 LOOKUP(29, ABI_WMMX_args),
16080 LOOKUP(30, ABI_optimization_goals),
16081 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16082 {32, "compatibility", 0, NULL},
f5f53991 16083 LOOKUP(34, CPU_unaligned_access),
75375b3e 16084 LOOKUP(36, FP_HP_extension),
8e79c3df 16085 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16086 LOOKUP(42, MPextension_use),
16087 LOOKUP(44, DIV_use),
15afaa63 16088 LOOKUP(46, DSP_extension),
a7ad558c 16089 LOOKUP(48, MVE_arch),
f5f53991
AS
16090 {64, "nodefaults", 0, NULL},
16091 {65, "also_compatible_with", 0, NULL},
16092 LOOKUP(66, T2EE_use),
16093 {67, "conformance", 1, NULL},
16094 LOOKUP(68, Virtualization_use),
cd21e546 16095 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16096};
16097#undef LOOKUP
16098
11c1ff18 16099static unsigned char *
f6f0e17b
NC
16100display_arm_attribute (unsigned char * p,
16101 const unsigned char * const end)
11c1ff18 16102{
70e99720 16103 unsigned int tag;
70e99720 16104 unsigned int val;
2cf0635d 16105 arm_attr_public_tag * attr;
11c1ff18 16106 unsigned i;
70e99720 16107 unsigned int type;
11c1ff18 16108
cd30bcef 16109 READ_ULEB (tag, p, end);
11c1ff18 16110 attr = NULL;
2cf0635d 16111 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16112 {
16113 if (arm_attr_public_tags[i].tag == tag)
16114 {
16115 attr = &arm_attr_public_tags[i];
16116 break;
16117 }
16118 }
16119
16120 if (attr)
16121 {
16122 printf (" Tag_%s: ", attr->name);
16123 switch (attr->type)
16124 {
16125 case 0:
16126 switch (tag)
16127 {
16128 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16129 READ_ULEB (val, p, end);
11c1ff18
PB
16130 switch (val)
16131 {
2b692964
NC
16132 case 0: printf (_("None\n")); break;
16133 case 'A': printf (_("Application\n")); break;
16134 case 'R': printf (_("Realtime\n")); break;
16135 case 'M': printf (_("Microcontroller\n")); break;
16136 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16137 default: printf ("??? (%d)\n", val); break;
16138 }
16139 break;
16140
75375b3e 16141 case 24: /* Tag_align_needed. */
cd30bcef 16142 READ_ULEB (val, p, end);
75375b3e
MGD
16143 switch (val)
16144 {
2b692964
NC
16145 case 0: printf (_("None\n")); break;
16146 case 1: printf (_("8-byte\n")); break;
16147 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16148 case 3: printf ("??? 3\n"); break;
16149 default:
16150 if (val <= 12)
dd24e3da 16151 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16152 1 << val);
16153 else
16154 printf ("??? (%d)\n", val);
16155 break;
16156 }
16157 break;
16158
16159 case 25: /* Tag_align_preserved. */
cd30bcef 16160 READ_ULEB (val, p, end);
75375b3e
MGD
16161 switch (val)
16162 {
2b692964
NC
16163 case 0: printf (_("None\n")); break;
16164 case 1: printf (_("8-byte, except leaf SP\n")); break;
16165 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16166 case 3: printf ("??? 3\n"); break;
16167 default:
16168 if (val <= 12)
dd24e3da 16169 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16170 1 << val);
16171 else
16172 printf ("??? (%d)\n", val);
16173 break;
16174 }
16175 break;
16176
11c1ff18 16177 case 32: /* Tag_compatibility. */
071436c6 16178 {
cd30bcef 16179 READ_ULEB (val, p, end);
071436c6 16180 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16181 if (p < end - 1)
16182 {
16183 size_t maxlen = (end - p) - 1;
16184
16185 print_symbol ((int) maxlen, (const char *) p);
16186 p += strnlen ((char *) p, maxlen) + 1;
16187 }
16188 else
16189 {
16190 printf (_("<corrupt>"));
16191 p = (unsigned char *) end;
16192 }
071436c6 16193 putchar ('\n');
071436c6 16194 }
11c1ff18
PB
16195 break;
16196
f5f53991 16197 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16198 /* PR 17531: file: 001-505008-0.01. */
16199 if (p < end)
16200 p++;
2b692964 16201 printf (_("True\n"));
f5f53991
AS
16202 break;
16203
16204 case 65: /* Tag_also_compatible_with. */
cd30bcef 16205 READ_ULEB (val, p, end);
f5f53991
AS
16206 if (val == 6 /* Tag_CPU_arch. */)
16207 {
cd30bcef 16208 READ_ULEB (val, p, end);
071436c6 16209 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16210 printf ("??? (%d)\n", val);
16211 else
16212 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16213 }
16214 else
16215 printf ("???\n");
071436c6
NC
16216 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16217 ;
f5f53991
AS
16218 break;
16219
11c1ff18 16220 default:
bee0ee85
NC
16221 printf (_("<unknown: %d>\n"), tag);
16222 break;
11c1ff18
PB
16223 }
16224 return p;
16225
16226 case 1:
f6f0e17b 16227 return display_tag_value (-1, p, end);
11c1ff18 16228 case 2:
f6f0e17b 16229 return display_tag_value (0, p, end);
11c1ff18
PB
16230
16231 default:
16232 assert (attr->type & 0x80);
cd30bcef 16233 READ_ULEB (val, p, end);
11c1ff18
PB
16234 type = attr->type & 0x7f;
16235 if (val >= type)
16236 printf ("??? (%d)\n", val);
16237 else
16238 printf ("%s\n", attr->table[val]);
16239 return p;
16240 }
16241 }
11c1ff18 16242
f6f0e17b 16243 return display_tag_value (tag, p, end);
11c1ff18
PB
16244}
16245
104d59d1 16246static unsigned char *
60bca95a 16247display_gnu_attribute (unsigned char * p,
60abdbed 16248 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16249 const unsigned char * const end)
104d59d1 16250{
cd30bcef 16251 unsigned int tag;
60abdbed 16252 unsigned int val;
104d59d1 16253
cd30bcef 16254 READ_ULEB (tag, p, end);
104d59d1
JM
16255
16256 /* Tag_compatibility is the only generic GNU attribute defined at
16257 present. */
16258 if (tag == 32)
16259 {
cd30bcef 16260 READ_ULEB (val, p, end);
071436c6
NC
16261
16262 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16263 if (p == end)
16264 {
071436c6 16265 printf (_("<corrupt>\n"));
f6f0e17b
NC
16266 warn (_("corrupt vendor attribute\n"));
16267 }
16268 else
16269 {
4082ef84
NC
16270 if (p < end - 1)
16271 {
16272 size_t maxlen = (end - p) - 1;
071436c6 16273
4082ef84
NC
16274 print_symbol ((int) maxlen, (const char *) p);
16275 p += strnlen ((char *) p, maxlen) + 1;
16276 }
16277 else
16278 {
16279 printf (_("<corrupt>"));
16280 p = (unsigned char *) end;
16281 }
071436c6 16282 putchar ('\n');
f6f0e17b 16283 }
104d59d1
JM
16284 return p;
16285 }
16286
16287 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16288 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16289
f6f0e17b 16290 return display_tag_value (tag, p, end);
104d59d1
JM
16291}
16292
85f7484a
PB
16293static unsigned char *
16294display_m68k_gnu_attribute (unsigned char * p,
16295 unsigned int tag,
16296 const unsigned char * const end)
16297{
16298 unsigned int val;
16299
16300 if (tag == Tag_GNU_M68K_ABI_FP)
16301 {
16302 printf (" Tag_GNU_M68K_ABI_FP: ");
16303 if (p == end)
16304 {
16305 printf (_("<corrupt>\n"));
16306 return p;
16307 }
16308 READ_ULEB (val, p, end);
16309
16310 if (val > 3)
16311 printf ("(%#x), ", val);
16312
16313 switch (val & 3)
16314 {
16315 case 0:
16316 printf (_("unspecified hard/soft float\n"));
16317 break;
16318 case 1:
16319 printf (_("hard float\n"));
16320 break;
16321 case 2:
16322 printf (_("soft float\n"));
16323 break;
16324 }
16325 return p;
16326 }
16327
16328 return display_tag_value (tag & 1, p, end);
16329}
16330
34c8bcba 16331static unsigned char *
f6f0e17b 16332display_power_gnu_attribute (unsigned char * p,
60abdbed 16333 unsigned int tag,
f6f0e17b 16334 const unsigned char * const end)
34c8bcba 16335{
005d79fd 16336 unsigned int val;
34c8bcba
JM
16337
16338 if (tag == Tag_GNU_Power_ABI_FP)
16339 {
34c8bcba 16340 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16341 if (p == end)
005d79fd
AM
16342 {
16343 printf (_("<corrupt>\n"));
16344 return p;
16345 }
cd30bcef 16346 READ_ULEB (val, p, end);
60bca95a 16347
005d79fd
AM
16348 if (val > 15)
16349 printf ("(%#x), ", val);
16350
16351 switch (val & 3)
34c8bcba
JM
16352 {
16353 case 0:
005d79fd 16354 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16355 break;
16356 case 1:
005d79fd 16357 printf (_("hard float, "));
34c8bcba
JM
16358 break;
16359 case 2:
005d79fd 16360 printf (_("soft float, "));
34c8bcba 16361 break;
3c7b9897 16362 case 3:
005d79fd 16363 printf (_("single-precision hard float, "));
3c7b9897 16364 break;
005d79fd
AM
16365 }
16366
16367 switch (val & 0xC)
16368 {
16369 case 0:
16370 printf (_("unspecified long double\n"));
16371 break;
16372 case 4:
16373 printf (_("128-bit IBM long double\n"));
16374 break;
16375 case 8:
16376 printf (_("64-bit long double\n"));
16377 break;
16378 case 12:
16379 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16380 break;
16381 }
16382 return p;
005d79fd 16383 }
34c8bcba 16384
c6e65352
DJ
16385 if (tag == Tag_GNU_Power_ABI_Vector)
16386 {
c6e65352 16387 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 16388 if (p == end)
005d79fd
AM
16389 {
16390 printf (_("<corrupt>\n"));
16391 return p;
16392 }
cd30bcef 16393 READ_ULEB (val, p, end);
005d79fd
AM
16394
16395 if (val > 3)
16396 printf ("(%#x), ", val);
16397
16398 switch (val & 3)
c6e65352
DJ
16399 {
16400 case 0:
005d79fd 16401 printf (_("unspecified\n"));
c6e65352
DJ
16402 break;
16403 case 1:
005d79fd 16404 printf (_("generic\n"));
c6e65352
DJ
16405 break;
16406 case 2:
16407 printf ("AltiVec\n");
16408 break;
16409 case 3:
16410 printf ("SPE\n");
16411 break;
c6e65352
DJ
16412 }
16413 return p;
005d79fd 16414 }
c6e65352 16415
f82e0623
NF
16416 if (tag == Tag_GNU_Power_ABI_Struct_Return)
16417 {
005d79fd 16418 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 16419 if (p == end)
f6f0e17b 16420 {
005d79fd 16421 printf (_("<corrupt>\n"));
f6f0e17b
NC
16422 return p;
16423 }
cd30bcef 16424 READ_ULEB (val, p, end);
0b4362b0 16425
005d79fd
AM
16426 if (val > 2)
16427 printf ("(%#x), ", val);
16428
16429 switch (val & 3)
16430 {
16431 case 0:
16432 printf (_("unspecified\n"));
16433 break;
16434 case 1:
16435 printf ("r3/r4\n");
16436 break;
16437 case 2:
16438 printf (_("memory\n"));
16439 break;
16440 case 3:
16441 printf ("???\n");
16442 break;
16443 }
f82e0623
NF
16444 return p;
16445 }
16446
f6f0e17b 16447 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
16448}
16449
643f7afb
AK
16450static unsigned char *
16451display_s390_gnu_attribute (unsigned char * p,
60abdbed 16452 unsigned int tag,
643f7afb
AK
16453 const unsigned char * const end)
16454{
cd30bcef 16455 unsigned int val;
643f7afb
AK
16456
16457 if (tag == Tag_GNU_S390_ABI_Vector)
16458 {
643f7afb 16459 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 16460 READ_ULEB (val, p, end);
643f7afb
AK
16461
16462 switch (val)
16463 {
16464 case 0:
16465 printf (_("any\n"));
16466 break;
16467 case 1:
16468 printf (_("software\n"));
16469 break;
16470 case 2:
16471 printf (_("hardware\n"));
16472 break;
16473 default:
16474 printf ("??? (%d)\n", val);
16475 break;
16476 }
16477 return p;
16478 }
16479
16480 return display_tag_value (tag & 1, p, end);
16481}
16482
9e8c70f9 16483static void
60abdbed 16484display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
16485{
16486 if (mask)
16487 {
015dc7e1 16488 bool first = true;
071436c6 16489
9e8c70f9 16490 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 16491 fputs ("mul32", stdout), first = false;
9e8c70f9 16492 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 16493 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 16494 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 16495 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 16496 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 16497 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 16498 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 16499 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 16500 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 16501 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 16502 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 16503 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 16504 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 16505 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 16506 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 16507 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 16508 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 16509 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 16510 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 16511 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 16512 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 16513 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 16514 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 16515 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 16516 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 16517 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 16518 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 16519 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 16520 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 16521 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
16522 }
16523 else
071436c6
NC
16524 fputc ('0', stdout);
16525 fputc ('\n', stdout);
9e8c70f9
DM
16526}
16527
3d68f91c 16528static void
60abdbed 16529display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
16530{
16531 if (mask)
16532 {
015dc7e1 16533 bool first = true;
071436c6 16534
3d68f91c 16535 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 16536 fputs ("fjathplus", stdout), first = false;
3d68f91c 16537 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 16538 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 16539 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 16540 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 16541 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 16542 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 16543 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 16544 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 16545 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 16546 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 16547 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 16548 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 16549 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 16550 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 16551 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 16552 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 16553 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 16554 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 16555 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 16556 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
16557 }
16558 else
071436c6
NC
16559 fputc ('0', stdout);
16560 fputc ('\n', stdout);
3d68f91c
JM
16561}
16562
9e8c70f9 16563static unsigned char *
f6f0e17b 16564display_sparc_gnu_attribute (unsigned char * p,
60abdbed 16565 unsigned int tag,
f6f0e17b 16566 const unsigned char * const end)
9e8c70f9 16567{
cd30bcef 16568 unsigned int val;
3d68f91c 16569
9e8c70f9
DM
16570 if (tag == Tag_GNU_Sparc_HWCAPS)
16571 {
cd30bcef 16572 READ_ULEB (val, p, end);
9e8c70f9 16573 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
16574 display_sparc_hwcaps (val);
16575 return p;
3d68f91c
JM
16576 }
16577 if (tag == Tag_GNU_Sparc_HWCAPS2)
16578 {
cd30bcef 16579 READ_ULEB (val, p, end);
3d68f91c
JM
16580 printf (" Tag_GNU_Sparc_HWCAPS2: ");
16581 display_sparc_hwcaps2 (val);
16582 return p;
16583 }
9e8c70f9 16584
f6f0e17b 16585 return display_tag_value (tag, p, end);
9e8c70f9
DM
16586}
16587
351cdf24 16588static void
32ec8896 16589print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
16590{
16591 switch (val)
16592 {
16593 case Val_GNU_MIPS_ABI_FP_ANY:
16594 printf (_("Hard or soft float\n"));
16595 break;
16596 case Val_GNU_MIPS_ABI_FP_DOUBLE:
16597 printf (_("Hard float (double precision)\n"));
16598 break;
16599 case Val_GNU_MIPS_ABI_FP_SINGLE:
16600 printf (_("Hard float (single precision)\n"));
16601 break;
16602 case Val_GNU_MIPS_ABI_FP_SOFT:
16603 printf (_("Soft float\n"));
16604 break;
16605 case Val_GNU_MIPS_ABI_FP_OLD_64:
16606 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
16607 break;
16608 case Val_GNU_MIPS_ABI_FP_XX:
16609 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
16610 break;
16611 case Val_GNU_MIPS_ABI_FP_64:
16612 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
16613 break;
16614 case Val_GNU_MIPS_ABI_FP_64A:
16615 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
16616 break;
3350cc01
CM
16617 case Val_GNU_MIPS_ABI_FP_NAN2008:
16618 printf (_("NaN 2008 compatibility\n"));
16619 break;
351cdf24
MF
16620 default:
16621 printf ("??? (%d)\n", val);
16622 break;
16623 }
16624}
16625
2cf19d5c 16626static unsigned char *
f6f0e17b 16627display_mips_gnu_attribute (unsigned char * p,
60abdbed 16628 unsigned int tag,
f6f0e17b 16629 const unsigned char * const end)
2cf19d5c 16630{
2cf19d5c
JM
16631 if (tag == Tag_GNU_MIPS_ABI_FP)
16632 {
32ec8896 16633 unsigned int val;
f6f0e17b 16634
2cf19d5c 16635 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 16636 READ_ULEB (val, p, end);
351cdf24 16637 print_mips_fp_abi_value (val);
2cf19d5c
JM
16638 return p;
16639 }
16640
a9f58168
CF
16641 if (tag == Tag_GNU_MIPS_ABI_MSA)
16642 {
32ec8896 16643 unsigned int val;
a9f58168 16644
a9f58168 16645 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 16646 READ_ULEB (val, p, end);
a9f58168
CF
16647
16648 switch (val)
16649 {
16650 case Val_GNU_MIPS_ABI_MSA_ANY:
16651 printf (_("Any MSA or not\n"));
16652 break;
16653 case Val_GNU_MIPS_ABI_MSA_128:
16654 printf (_("128-bit MSA\n"));
16655 break;
16656 default:
16657 printf ("??? (%d)\n", val);
16658 break;
16659 }
16660 return p;
16661 }
16662
f6f0e17b 16663 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
16664}
16665
59e6276b 16666static unsigned char *
f6f0e17b
NC
16667display_tic6x_attribute (unsigned char * p,
16668 const unsigned char * const end)
59e6276b 16669{
60abdbed 16670 unsigned int tag;
cd30bcef 16671 unsigned int val;
59e6276b 16672
cd30bcef 16673 READ_ULEB (tag, p, end);
59e6276b
JM
16674
16675 switch (tag)
16676 {
75fa6dc1 16677 case Tag_ISA:
75fa6dc1 16678 printf (" Tag_ISA: ");
cd30bcef 16679 READ_ULEB (val, p, end);
59e6276b
JM
16680
16681 switch (val)
16682 {
75fa6dc1 16683 case C6XABI_Tag_ISA_none:
59e6276b
JM
16684 printf (_("None\n"));
16685 break;
75fa6dc1 16686 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
16687 printf ("C62x\n");
16688 break;
75fa6dc1 16689 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
16690 printf ("C67x\n");
16691 break;
75fa6dc1 16692 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
16693 printf ("C67x+\n");
16694 break;
75fa6dc1 16695 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
16696 printf ("C64x\n");
16697 break;
75fa6dc1 16698 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
16699 printf ("C64x+\n");
16700 break;
75fa6dc1 16701 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
16702 printf ("C674x\n");
16703 break;
16704 default:
16705 printf ("??? (%d)\n", val);
16706 break;
16707 }
16708 return p;
16709
87779176 16710 case Tag_ABI_wchar_t:
87779176 16711 printf (" Tag_ABI_wchar_t: ");
cd30bcef 16712 READ_ULEB (val, p, end);
87779176
JM
16713 switch (val)
16714 {
16715 case 0:
16716 printf (_("Not used\n"));
16717 break;
16718 case 1:
16719 printf (_("2 bytes\n"));
16720 break;
16721 case 2:
16722 printf (_("4 bytes\n"));
16723 break;
16724 default:
16725 printf ("??? (%d)\n", val);
16726 break;
16727 }
16728 return p;
16729
16730 case Tag_ABI_stack_align_needed:
87779176 16731 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 16732 READ_ULEB (val, p, end);
87779176
JM
16733 switch (val)
16734 {
16735 case 0:
16736 printf (_("8-byte\n"));
16737 break;
16738 case 1:
16739 printf (_("16-byte\n"));
16740 break;
16741 default:
16742 printf ("??? (%d)\n", val);
16743 break;
16744 }
16745 return p;
16746
16747 case Tag_ABI_stack_align_preserved:
cd30bcef 16748 READ_ULEB (val, p, end);
87779176
JM
16749 printf (" Tag_ABI_stack_align_preserved: ");
16750 switch (val)
16751 {
16752 case 0:
16753 printf (_("8-byte\n"));
16754 break;
16755 case 1:
16756 printf (_("16-byte\n"));
16757 break;
16758 default:
16759 printf ("??? (%d)\n", val);
16760 break;
16761 }
16762 return p;
16763
b5593623 16764 case Tag_ABI_DSBT:
cd30bcef 16765 READ_ULEB (val, p, end);
b5593623
JM
16766 printf (" Tag_ABI_DSBT: ");
16767 switch (val)
16768 {
16769 case 0:
16770 printf (_("DSBT addressing not used\n"));
16771 break;
16772 case 1:
16773 printf (_("DSBT addressing used\n"));
16774 break;
16775 default:
16776 printf ("??? (%d)\n", val);
16777 break;
16778 }
16779 return p;
16780
87779176 16781 case Tag_ABI_PID:
cd30bcef 16782 READ_ULEB (val, p, end);
87779176
JM
16783 printf (" Tag_ABI_PID: ");
16784 switch (val)
16785 {
16786 case 0:
16787 printf (_("Data addressing position-dependent\n"));
16788 break;
16789 case 1:
16790 printf (_("Data addressing position-independent, GOT near DP\n"));
16791 break;
16792 case 2:
16793 printf (_("Data addressing position-independent, GOT far from DP\n"));
16794 break;
16795 default:
16796 printf ("??? (%d)\n", val);
16797 break;
16798 }
16799 return p;
16800
16801 case Tag_ABI_PIC:
cd30bcef 16802 READ_ULEB (val, p, end);
87779176
JM
16803 printf (" Tag_ABI_PIC: ");
16804 switch (val)
16805 {
16806 case 0:
16807 printf (_("Code addressing position-dependent\n"));
16808 break;
16809 case 1:
16810 printf (_("Code addressing position-independent\n"));
16811 break;
16812 default:
16813 printf ("??? (%d)\n", val);
16814 break;
16815 }
16816 return p;
16817
16818 case Tag_ABI_array_object_alignment:
cd30bcef 16819 READ_ULEB (val, p, end);
87779176
JM
16820 printf (" Tag_ABI_array_object_alignment: ");
16821 switch (val)
16822 {
16823 case 0:
16824 printf (_("8-byte\n"));
16825 break;
16826 case 1:
16827 printf (_("4-byte\n"));
16828 break;
16829 case 2:
16830 printf (_("16-byte\n"));
16831 break;
16832 default:
16833 printf ("??? (%d)\n", val);
16834 break;
16835 }
16836 return p;
16837
16838 case Tag_ABI_array_object_align_expected:
cd30bcef 16839 READ_ULEB (val, p, end);
87779176
JM
16840 printf (" Tag_ABI_array_object_align_expected: ");
16841 switch (val)
16842 {
16843 case 0:
16844 printf (_("8-byte\n"));
16845 break;
16846 case 1:
16847 printf (_("4-byte\n"));
16848 break;
16849 case 2:
16850 printf (_("16-byte\n"));
16851 break;
16852 default:
16853 printf ("??? (%d)\n", val);
16854 break;
16855 }
16856 return p;
16857
3cbd1c06 16858 case Tag_ABI_compatibility:
071436c6 16859 {
cd30bcef 16860 READ_ULEB (val, p, end);
071436c6 16861 printf (" Tag_ABI_compatibility: ");
071436c6 16862 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16863 if (p < end - 1)
16864 {
16865 size_t maxlen = (end - p) - 1;
16866
16867 print_symbol ((int) maxlen, (const char *) p);
16868 p += strnlen ((char *) p, maxlen) + 1;
16869 }
16870 else
16871 {
16872 printf (_("<corrupt>"));
16873 p = (unsigned char *) end;
16874 }
071436c6 16875 putchar ('\n');
071436c6
NC
16876 return p;
16877 }
87779176
JM
16878
16879 case Tag_ABI_conformance:
071436c6 16880 {
4082ef84
NC
16881 printf (" Tag_ABI_conformance: \"");
16882 if (p < end - 1)
16883 {
16884 size_t maxlen = (end - p) - 1;
071436c6 16885
4082ef84
NC
16886 print_symbol ((int) maxlen, (const char *) p);
16887 p += strnlen ((char *) p, maxlen) + 1;
16888 }
16889 else
16890 {
16891 printf (_("<corrupt>"));
16892 p = (unsigned char *) end;
16893 }
071436c6 16894 printf ("\"\n");
071436c6
NC
16895 return p;
16896 }
59e6276b
JM
16897 }
16898
f6f0e17b
NC
16899 return display_tag_value (tag, p, end);
16900}
59e6276b 16901
f6f0e17b 16902static void
60abdbed 16903display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
16904{
16905 unsigned long addr = 0;
16906 size_t bytes = end - p;
16907
feceaa59 16908 assert (end >= p);
f6f0e17b 16909 while (bytes)
87779176 16910 {
f6f0e17b
NC
16911 int j;
16912 int k;
16913 int lbytes = (bytes > 16 ? 16 : bytes);
16914
16915 printf (" 0x%8.8lx ", addr);
16916
16917 for (j = 0; j < 16; j++)
16918 {
16919 if (j < lbytes)
16920 printf ("%2.2x", p[j]);
16921 else
16922 printf (" ");
16923
16924 if ((j & 3) == 3)
16925 printf (" ");
16926 }
16927
16928 for (j = 0; j < lbytes; j++)
16929 {
16930 k = p[j];
16931 if (k >= ' ' && k < 0x7f)
16932 printf ("%c", k);
16933 else
16934 printf (".");
16935 }
16936
16937 putchar ('\n');
16938
16939 p += lbytes;
16940 bytes -= lbytes;
16941 addr += lbytes;
87779176 16942 }
59e6276b 16943
f6f0e17b 16944 putchar ('\n');
59e6276b
JM
16945}
16946
13761a11 16947static unsigned char *
b0191216 16948display_msp430_attribute (unsigned char * p,
13761a11
NC
16949 const unsigned char * const end)
16950{
60abdbed
NC
16951 unsigned int val;
16952 unsigned int tag;
13761a11 16953
cd30bcef 16954 READ_ULEB (tag, p, end);
0b4362b0 16955
13761a11
NC
16956 switch (tag)
16957 {
16958 case OFBA_MSPABI_Tag_ISA:
13761a11 16959 printf (" Tag_ISA: ");
cd30bcef 16960 READ_ULEB (val, p, end);
13761a11
NC
16961 switch (val)
16962 {
16963 case 0: printf (_("None\n")); break;
16964 case 1: printf (_("MSP430\n")); break;
16965 case 2: printf (_("MSP430X\n")); break;
16966 default: printf ("??? (%d)\n", val); break;
16967 }
16968 break;
16969
16970 case OFBA_MSPABI_Tag_Code_Model:
13761a11 16971 printf (" Tag_Code_Model: ");
cd30bcef 16972 READ_ULEB (val, p, end);
13761a11
NC
16973 switch (val)
16974 {
16975 case 0: printf (_("None\n")); break;
16976 case 1: printf (_("Small\n")); break;
16977 case 2: printf (_("Large\n")); break;
16978 default: printf ("??? (%d)\n", val); break;
16979 }
16980 break;
16981
16982 case OFBA_MSPABI_Tag_Data_Model:
13761a11 16983 printf (" Tag_Data_Model: ");
cd30bcef 16984 READ_ULEB (val, p, end);
13761a11
NC
16985 switch (val)
16986 {
16987 case 0: printf (_("None\n")); break;
16988 case 1: printf (_("Small\n")); break;
16989 case 2: printf (_("Large\n")); break;
16990 case 3: printf (_("Restricted Large\n")); break;
16991 default: printf ("??? (%d)\n", val); break;
16992 }
16993 break;
16994
16995 default:
16996 printf (_(" <unknown tag %d>: "), tag);
16997
16998 if (tag & 1)
16999 {
071436c6 17000 putchar ('"');
4082ef84
NC
17001 if (p < end - 1)
17002 {
17003 size_t maxlen = (end - p) - 1;
17004
17005 print_symbol ((int) maxlen, (const char *) p);
17006 p += strnlen ((char *) p, maxlen) + 1;
17007 }
17008 else
17009 {
17010 printf (_("<corrupt>"));
17011 p = (unsigned char *) end;
17012 }
071436c6 17013 printf ("\"\n");
13761a11
NC
17014 }
17015 else
17016 {
cd30bcef 17017 READ_ULEB (val, p, end);
13761a11
NC
17018 printf ("%d (0x%x)\n", val, val);
17019 }
17020 break;
17021 }
17022
4082ef84 17023 assert (p <= end);
13761a11
NC
17024 return p;
17025}
17026
c0ea7c52
JL
17027static unsigned char *
17028display_msp430_gnu_attribute (unsigned char * p,
17029 unsigned int tag,
17030 const unsigned char * const end)
17031{
17032 if (tag == Tag_GNU_MSP430_Data_Region)
17033 {
cd30bcef 17034 unsigned int val;
c0ea7c52 17035
c0ea7c52 17036 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17037 READ_ULEB (val, p, end);
c0ea7c52
JL
17038
17039 switch (val)
17040 {
17041 case Val_GNU_MSP430_Data_Region_Any:
17042 printf (_("Any Region\n"));
17043 break;
17044 case Val_GNU_MSP430_Data_Region_Lower:
17045 printf (_("Lower Region Only\n"));
17046 break;
17047 default:
cd30bcef 17048 printf ("??? (%u)\n", val);
c0ea7c52
JL
17049 }
17050 return p;
17051 }
17052 return display_tag_value (tag & 1, p, end);
17053}
17054
2dc8dd17
JW
17055struct riscv_attr_tag_t {
17056 const char *name;
cd30bcef 17057 unsigned int tag;
2dc8dd17
JW
17058};
17059
17060static struct riscv_attr_tag_t riscv_attr_tag[] =
17061{
17062#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17063 T(arch),
17064 T(priv_spec),
17065 T(priv_spec_minor),
17066 T(priv_spec_revision),
17067 T(unaligned_access),
17068 T(stack_align),
17069#undef T
17070};
17071
17072static unsigned char *
17073display_riscv_attribute (unsigned char *p,
17074 const unsigned char * const end)
17075{
cd30bcef
AM
17076 unsigned int val;
17077 unsigned int tag;
2dc8dd17
JW
17078 struct riscv_attr_tag_t *attr = NULL;
17079 unsigned i;
17080
cd30bcef 17081 READ_ULEB (tag, p, end);
2dc8dd17
JW
17082
17083 /* Find the name of attribute. */
17084 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17085 {
17086 if (riscv_attr_tag[i].tag == tag)
17087 {
17088 attr = &riscv_attr_tag[i];
17089 break;
17090 }
17091 }
17092
17093 if (attr)
17094 printf (" %s: ", attr->name);
17095 else
17096 return display_tag_value (tag, p, end);
17097
17098 switch (tag)
17099 {
17100 case Tag_RISCV_priv_spec:
17101 case Tag_RISCV_priv_spec_minor:
17102 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17103 READ_ULEB (val, p, end);
17104 printf (_("%u\n"), val);
2dc8dd17
JW
17105 break;
17106 case Tag_RISCV_unaligned_access:
cd30bcef 17107 READ_ULEB (val, p, end);
2dc8dd17
JW
17108 switch (val)
17109 {
17110 case 0:
17111 printf (_("No unaligned access\n"));
17112 break;
17113 case 1:
17114 printf (_("Unaligned access\n"));
17115 break;
17116 }
17117 break;
17118 case Tag_RISCV_stack_align:
cd30bcef
AM
17119 READ_ULEB (val, p, end);
17120 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17121 break;
17122 case Tag_RISCV_arch:
17123 p = display_tag_value (-1, p, end);
17124 break;
17125 default:
17126 return display_tag_value (tag, p, end);
17127 }
17128
17129 return p;
17130}
17131
0861f561
CQ
17132static unsigned char *
17133display_csky_attribute (unsigned char * p,
17134 const unsigned char * const end)
17135{
17136 unsigned int tag;
17137 unsigned int val;
17138 READ_ULEB (tag, p, end);
17139
17140 if (tag >= Tag_CSKY_MAX)
17141 {
17142 return display_tag_value (-1, p, end);
17143 }
17144
17145 switch (tag)
17146 {
17147 case Tag_CSKY_ARCH_NAME:
17148 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17149 return display_tag_value (-1, p, end);
17150 case Tag_CSKY_CPU_NAME:
17151 printf (" Tag_CSKY_CPU_NAME:\t\t");
17152 return display_tag_value (-1, p, end);
17153
17154 case Tag_CSKY_ISA_FLAGS:
17155 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17156 return display_tag_value (0, p, end);
17157 case Tag_CSKY_ISA_EXT_FLAGS:
17158 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17159 return display_tag_value (0, p, end);
17160
17161 case Tag_CSKY_DSP_VERSION:
17162 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17163 READ_ULEB (val, p, end);
17164 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17165 printf ("DSP Extension\n");
17166 else if (val == VAL_CSKY_DSP_VERSION_2)
17167 printf ("DSP 2.0\n");
17168 break;
17169
17170 case Tag_CSKY_VDSP_VERSION:
17171 printf (" Tag_CSKY_VDSP_VERSION:\t");
17172 READ_ULEB (val, p, end);
17173 printf ("VDSP Version %d\n", val);
17174 break;
17175
17176 case Tag_CSKY_FPU_VERSION:
17177 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17178 READ_ULEB (val, p, end);
17179 if (val == VAL_CSKY_FPU_VERSION_1)
17180 printf ("ABIV1 FPU Version 1\n");
17181 else if (val == VAL_CSKY_FPU_VERSION_2)
17182 printf ("FPU Version 2\n");
17183 break;
17184
17185 case Tag_CSKY_FPU_ABI:
17186 printf (" Tag_CSKY_FPU_ABI:\t\t");
17187 READ_ULEB (val, p, end);
17188 if (val == VAL_CSKY_FPU_ABI_HARD)
17189 printf ("Hard\n");
17190 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17191 printf ("SoftFP\n");
17192 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17193 printf ("Soft\n");
17194 break;
17195 case Tag_CSKY_FPU_ROUNDING:
17196 READ_ULEB (val, p, end);
17197 if (val == 1) {
17198 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17199 printf ("Needed\n");
17200 }
17201 break;
17202 case Tag_CSKY_FPU_DENORMAL:
17203 READ_ULEB (val, p, end);
17204 if (val == 1) {
17205 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17206 printf ("Needed\n");
17207 }
17208 break;
17209 case Tag_CSKY_FPU_Exception:
17210 READ_ULEB (val, p, end);
17211 if (val == 1) {
17212 printf (" Tag_CSKY_FPU_Exception:\t");
17213 printf ("Needed\n");
17214 }
17215 break;
17216 case Tag_CSKY_FPU_NUMBER_MODULE:
17217 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17218 return display_tag_value (-1, p, end);
17219 case Tag_CSKY_FPU_HARDFP:
17220 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17221 READ_ULEB (val, p, end);
17222 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17223 printf (" Half");
17224 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17225 printf (" Single");
17226 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17227 printf (" Double");
17228 printf ("\n");
17229 break;
17230 default:
17231 return display_tag_value (tag, p, end);
17232 }
17233 return p;
17234}
17235
015dc7e1 17236static bool
dda8d76d 17237process_attributes (Filedata * filedata,
60bca95a 17238 const char * public_name,
104d59d1 17239 unsigned int proc_type,
f6f0e17b 17240 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17241 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17242{
2cf0635d 17243 Elf_Internal_Shdr * sect;
11c1ff18 17244 unsigned i;
015dc7e1 17245 bool res = true;
11c1ff18
PB
17246
17247 /* Find the section header so that we get the size. */
dda8d76d
NC
17248 for (i = 0, sect = filedata->section_headers;
17249 i < filedata->file_header.e_shnum;
11c1ff18
PB
17250 i++, sect++)
17251 {
071436c6
NC
17252 unsigned char * contents;
17253 unsigned char * p;
17254
104d59d1 17255 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17256 continue;
17257
dda8d76d 17258 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17259 sect->sh_size, _("attributes"));
60bca95a 17260 if (contents == NULL)
32ec8896 17261 {
015dc7e1 17262 res = false;
32ec8896
NC
17263 continue;
17264 }
60bca95a 17265
11c1ff18 17266 p = contents;
60abdbed
NC
17267 /* The first character is the version of the attributes.
17268 Currently only version 1, (aka 'A') is recognised here. */
17269 if (*p != 'A')
32ec8896
NC
17270 {
17271 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17272 res = false;
32ec8896 17273 }
60abdbed 17274 else
11c1ff18 17275 {
071436c6
NC
17276 bfd_vma section_len;
17277
17278 section_len = sect->sh_size - 1;
11c1ff18 17279 p++;
60bca95a 17280
071436c6 17281 while (section_len > 0)
11c1ff18 17282 {
071436c6 17283 bfd_vma attr_len;
e9847026 17284 unsigned int namelen;
015dc7e1
AM
17285 bool public_section;
17286 bool gnu_section;
11c1ff18 17287
071436c6 17288 if (section_len <= 4)
e0a31db1
NC
17289 {
17290 error (_("Tag section ends prematurely\n"));
015dc7e1 17291 res = false;
e0a31db1
NC
17292 break;
17293 }
071436c6 17294 attr_len = byte_get (p, 4);
11c1ff18 17295 p += 4;
60bca95a 17296
071436c6 17297 if (attr_len > section_len)
11c1ff18 17298 {
071436c6
NC
17299 error (_("Bad attribute length (%u > %u)\n"),
17300 (unsigned) attr_len, (unsigned) section_len);
17301 attr_len = section_len;
015dc7e1 17302 res = false;
11c1ff18 17303 }
74e1a04b 17304 /* PR 17531: file: 001-101425-0.004 */
071436c6 17305 else if (attr_len < 5)
74e1a04b 17306 {
071436c6 17307 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17308 res = false;
74e1a04b
NC
17309 break;
17310 }
e9847026 17311
071436c6
NC
17312 section_len -= attr_len;
17313 attr_len -= 4;
17314
17315 namelen = strnlen ((char *) p, attr_len) + 1;
17316 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17317 {
17318 error (_("Corrupt attribute section name\n"));
015dc7e1 17319 res = false;
e9847026
NC
17320 break;
17321 }
17322
071436c6
NC
17323 printf (_("Attribute Section: "));
17324 print_symbol (INT_MAX, (const char *) p);
17325 putchar ('\n');
60bca95a
NC
17326
17327 if (public_name && streq ((char *) p, public_name))
015dc7e1 17328 public_section = true;
11c1ff18 17329 else
015dc7e1 17330 public_section = false;
60bca95a
NC
17331
17332 if (streq ((char *) p, "gnu"))
015dc7e1 17333 gnu_section = true;
104d59d1 17334 else
015dc7e1 17335 gnu_section = false;
60bca95a 17336
11c1ff18 17337 p += namelen;
071436c6 17338 attr_len -= namelen;
e0a31db1 17339
071436c6 17340 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17341 {
e0a31db1 17342 int tag;
cd30bcef 17343 unsigned int val;
11c1ff18 17344 bfd_vma size;
071436c6 17345 unsigned char * end;
60bca95a 17346
e0a31db1 17347 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17348 if (attr_len < 6)
e0a31db1
NC
17349 {
17350 error (_("Unused bytes at end of section\n"));
015dc7e1 17351 res = false;
e0a31db1
NC
17352 section_len = 0;
17353 break;
17354 }
17355
17356 tag = *(p++);
11c1ff18 17357 size = byte_get (p, 4);
071436c6 17358 if (size > attr_len)
11c1ff18 17359 {
e9847026 17360 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17361 (unsigned) size, (unsigned) attr_len);
015dc7e1 17362 res = false;
071436c6 17363 size = attr_len;
11c1ff18 17364 }
e0a31db1
NC
17365 /* PR binutils/17531: Safe handling of corrupt files. */
17366 if (size < 6)
17367 {
17368 error (_("Bad subsection length (%u < 6)\n"),
17369 (unsigned) size);
015dc7e1 17370 res = false;
e0a31db1
NC
17371 section_len = 0;
17372 break;
17373 }
60bca95a 17374
071436c6 17375 attr_len -= size;
11c1ff18 17376 end = p + size - 1;
071436c6 17377 assert (end <= contents + sect->sh_size);
11c1ff18 17378 p += 4;
60bca95a 17379
11c1ff18
PB
17380 switch (tag)
17381 {
17382 case 1:
2b692964 17383 printf (_("File Attributes\n"));
11c1ff18
PB
17384 break;
17385 case 2:
2b692964 17386 printf (_("Section Attributes:"));
11c1ff18
PB
17387 goto do_numlist;
17388 case 3:
2b692964 17389 printf (_("Symbol Attributes:"));
1a0670f3 17390 /* Fall through. */
11c1ff18
PB
17391 do_numlist:
17392 for (;;)
17393 {
cd30bcef 17394 READ_ULEB (val, p, end);
11c1ff18
PB
17395 if (val == 0)
17396 break;
17397 printf (" %d", val);
17398 }
17399 printf ("\n");
17400 break;
17401 default:
2b692964 17402 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 17403 public_section = false;
11c1ff18
PB
17404 break;
17405 }
60bca95a 17406
071436c6 17407 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
17408 {
17409 while (p < end)
f6f0e17b 17410 p = display_pub_attribute (p, end);
60abdbed 17411 assert (p == end);
104d59d1 17412 }
071436c6 17413 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
17414 {
17415 while (p < end)
17416 p = display_gnu_attribute (p,
f6f0e17b
NC
17417 display_proc_gnu_attribute,
17418 end);
60abdbed 17419 assert (p == end);
11c1ff18 17420 }
071436c6 17421 else if (p < end)
11c1ff18 17422 {
071436c6 17423 printf (_(" Unknown attribute:\n"));
f6f0e17b 17424 display_raw_attribute (p, end);
11c1ff18
PB
17425 p = end;
17426 }
071436c6
NC
17427 else
17428 attr_len = 0;
11c1ff18
PB
17429 }
17430 }
17431 }
d70c5fc7 17432
60bca95a 17433 free (contents);
11c1ff18 17434 }
32ec8896
NC
17435
17436 return res;
11c1ff18
PB
17437}
17438
ccb4c951
RS
17439/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
17440 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
17441 and return the VMA of the next entry, or -1 if there was a problem.
17442 Does not read from DATA_END or beyond. */
ccb4c951
RS
17443
17444static bfd_vma
82b1b41b
NC
17445print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
17446 unsigned char * data_end)
ccb4c951
RS
17447{
17448 printf (" ");
17449 print_vma (addr, LONG_HEX);
17450 printf (" ");
17451 if (addr < pltgot + 0xfff0)
17452 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
17453 else
17454 printf ("%10s", "");
17455 printf (" ");
17456 if (data == NULL)
2b692964 17457 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
17458 else
17459 {
17460 bfd_vma entry;
82b1b41b 17461 unsigned char * from = data + addr - pltgot;
ccb4c951 17462
82b1b41b
NC
17463 if (from + (is_32bit_elf ? 4 : 8) > data_end)
17464 {
17465 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
17466 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
17467 return (bfd_vma) -1;
17468 }
17469 else
17470 {
17471 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17472 print_vma (entry, LONG_HEX);
17473 }
ccb4c951
RS
17474 }
17475 return addr + (is_32bit_elf ? 4 : 8);
17476}
17477
861fb55a
DJ
17478/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
17479 PLTGOT. Print the Address and Initial fields of an entry at VMA
17480 ADDR and return the VMA of the next entry. */
17481
17482static bfd_vma
2cf0635d 17483print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
17484{
17485 printf (" ");
17486 print_vma (addr, LONG_HEX);
17487 printf (" ");
17488 if (data == NULL)
2b692964 17489 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
17490 else
17491 {
17492 bfd_vma entry;
17493
17494 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17495 print_vma (entry, LONG_HEX);
17496 }
17497 return addr + (is_32bit_elf ? 4 : 8);
17498}
17499
351cdf24
MF
17500static void
17501print_mips_ases (unsigned int mask)
17502{
17503 if (mask & AFL_ASE_DSP)
17504 fputs ("\n\tDSP ASE", stdout);
17505 if (mask & AFL_ASE_DSPR2)
17506 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
17507 if (mask & AFL_ASE_DSPR3)
17508 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
17509 if (mask & AFL_ASE_EVA)
17510 fputs ("\n\tEnhanced VA Scheme", stdout);
17511 if (mask & AFL_ASE_MCU)
17512 fputs ("\n\tMCU (MicroController) ASE", stdout);
17513 if (mask & AFL_ASE_MDMX)
17514 fputs ("\n\tMDMX ASE", stdout);
17515 if (mask & AFL_ASE_MIPS3D)
17516 fputs ("\n\tMIPS-3D ASE", stdout);
17517 if (mask & AFL_ASE_MT)
17518 fputs ("\n\tMT ASE", stdout);
17519 if (mask & AFL_ASE_SMARTMIPS)
17520 fputs ("\n\tSmartMIPS ASE", stdout);
17521 if (mask & AFL_ASE_VIRT)
17522 fputs ("\n\tVZ ASE", stdout);
17523 if (mask & AFL_ASE_MSA)
17524 fputs ("\n\tMSA ASE", stdout);
17525 if (mask & AFL_ASE_MIPS16)
17526 fputs ("\n\tMIPS16 ASE", stdout);
17527 if (mask & AFL_ASE_MICROMIPS)
17528 fputs ("\n\tMICROMIPS ASE", stdout);
17529 if (mask & AFL_ASE_XPA)
17530 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
17531 if (mask & AFL_ASE_MIPS16E2)
17532 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
17533 if (mask & AFL_ASE_CRC)
17534 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
17535 if (mask & AFL_ASE_GINV)
17536 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
17537 if (mask & AFL_ASE_LOONGSON_MMI)
17538 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
17539 if (mask & AFL_ASE_LOONGSON_CAM)
17540 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
17541 if (mask & AFL_ASE_LOONGSON_EXT)
17542 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
17543 if (mask & AFL_ASE_LOONGSON_EXT2)
17544 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
17545 if (mask == 0)
17546 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
17547 else if ((mask & ~AFL_ASE_MASK) != 0)
17548 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
17549}
17550
17551static void
17552print_mips_isa_ext (unsigned int isa_ext)
17553{
17554 switch (isa_ext)
17555 {
17556 case 0:
17557 fputs (_("None"), stdout);
17558 break;
17559 case AFL_EXT_XLR:
17560 fputs ("RMI XLR", stdout);
17561 break;
2c629856
N
17562 case AFL_EXT_OCTEON3:
17563 fputs ("Cavium Networks Octeon3", stdout);
17564 break;
351cdf24
MF
17565 case AFL_EXT_OCTEON2:
17566 fputs ("Cavium Networks Octeon2", stdout);
17567 break;
17568 case AFL_EXT_OCTEONP:
17569 fputs ("Cavium Networks OcteonP", stdout);
17570 break;
351cdf24
MF
17571 case AFL_EXT_OCTEON:
17572 fputs ("Cavium Networks Octeon", stdout);
17573 break;
17574 case AFL_EXT_5900:
17575 fputs ("Toshiba R5900", stdout);
17576 break;
17577 case AFL_EXT_4650:
17578 fputs ("MIPS R4650", stdout);
17579 break;
17580 case AFL_EXT_4010:
17581 fputs ("LSI R4010", stdout);
17582 break;
17583 case AFL_EXT_4100:
17584 fputs ("NEC VR4100", stdout);
17585 break;
17586 case AFL_EXT_3900:
17587 fputs ("Toshiba R3900", stdout);
17588 break;
17589 case AFL_EXT_10000:
17590 fputs ("MIPS R10000", stdout);
17591 break;
17592 case AFL_EXT_SB1:
17593 fputs ("Broadcom SB-1", stdout);
17594 break;
17595 case AFL_EXT_4111:
17596 fputs ("NEC VR4111/VR4181", stdout);
17597 break;
17598 case AFL_EXT_4120:
17599 fputs ("NEC VR4120", stdout);
17600 break;
17601 case AFL_EXT_5400:
17602 fputs ("NEC VR5400", stdout);
17603 break;
17604 case AFL_EXT_5500:
17605 fputs ("NEC VR5500", stdout);
17606 break;
17607 case AFL_EXT_LOONGSON_2E:
17608 fputs ("ST Microelectronics Loongson 2E", stdout);
17609 break;
17610 case AFL_EXT_LOONGSON_2F:
17611 fputs ("ST Microelectronics Loongson 2F", stdout);
17612 break;
38bf472a
MR
17613 case AFL_EXT_INTERAPTIV_MR2:
17614 fputs ("Imagination interAptiv MR2", stdout);
17615 break;
351cdf24 17616 default:
00ac7aa0 17617 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
17618 }
17619}
17620
32ec8896 17621static signed int
351cdf24
MF
17622get_mips_reg_size (int reg_size)
17623{
17624 return (reg_size == AFL_REG_NONE) ? 0
17625 : (reg_size == AFL_REG_32) ? 32
17626 : (reg_size == AFL_REG_64) ? 64
17627 : (reg_size == AFL_REG_128) ? 128
17628 : -1;
17629}
17630
015dc7e1 17631static bool
dda8d76d 17632process_mips_specific (Filedata * filedata)
5b18a4bc 17633{
2cf0635d 17634 Elf_Internal_Dyn * entry;
351cdf24 17635 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
17636 size_t liblist_offset = 0;
17637 size_t liblistno = 0;
17638 size_t conflictsno = 0;
17639 size_t options_offset = 0;
17640 size_t conflicts_offset = 0;
861fb55a
DJ
17641 size_t pltrelsz = 0;
17642 size_t pltrel = 0;
ccb4c951 17643 bfd_vma pltgot = 0;
861fb55a
DJ
17644 bfd_vma mips_pltgot = 0;
17645 bfd_vma jmprel = 0;
ccb4c951
RS
17646 bfd_vma local_gotno = 0;
17647 bfd_vma gotsym = 0;
17648 bfd_vma symtabno = 0;
015dc7e1 17649 bool res = true;
103f02d3 17650
dda8d76d 17651 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 17652 display_mips_gnu_attribute))
015dc7e1 17653 res = false;
2cf19d5c 17654
dda8d76d 17655 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
17656
17657 if (sect != NULL)
17658 {
17659 Elf_External_ABIFlags_v0 *abiflags_ext;
17660 Elf_Internal_ABIFlags_v0 abiflags_in;
17661
17662 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
17663 {
17664 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 17665 res = false;
32ec8896 17666 }
351cdf24
MF
17667 else
17668 {
dda8d76d 17669 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
17670 sect->sh_size, _("MIPS ABI Flags section"));
17671 if (abiflags_ext)
17672 {
17673 abiflags_in.version = BYTE_GET (abiflags_ext->version);
17674 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
17675 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
17676 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
17677 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
17678 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
17679 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
17680 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
17681 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
17682 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
17683 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
17684
17685 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
17686 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
17687 if (abiflags_in.isa_rev > 1)
17688 printf ("r%d", abiflags_in.isa_rev);
17689 printf ("\nGPR size: %d",
17690 get_mips_reg_size (abiflags_in.gpr_size));
17691 printf ("\nCPR1 size: %d",
17692 get_mips_reg_size (abiflags_in.cpr1_size));
17693 printf ("\nCPR2 size: %d",
17694 get_mips_reg_size (abiflags_in.cpr2_size));
17695 fputs ("\nFP ABI: ", stdout);
17696 print_mips_fp_abi_value (abiflags_in.fp_abi);
17697 fputs ("ISA Extension: ", stdout);
17698 print_mips_isa_ext (abiflags_in.isa_ext);
17699 fputs ("\nASEs:", stdout);
17700 print_mips_ases (abiflags_in.ases);
17701 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
17702 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
17703 fputc ('\n', stdout);
17704 free (abiflags_ext);
17705 }
17706 }
17707 }
17708
19e6b90e 17709 /* We have a lot of special sections. Thanks SGI! */
978c4450 17710 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
17711 {
17712 /* No dynamic information available. See if there is static GOT. */
dda8d76d 17713 sect = find_section (filedata, ".got");
bbdd9a68
MR
17714 if (sect != NULL)
17715 {
17716 unsigned char *data_end;
17717 unsigned char *data;
17718 bfd_vma ent, end;
17719 int addr_size;
17720
17721 pltgot = sect->sh_addr;
17722
17723 ent = pltgot;
17724 addr_size = (is_32bit_elf ? 4 : 8);
17725 end = pltgot + sect->sh_size;
17726
dda8d76d 17727 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
17728 end - pltgot, 1,
17729 _("Global Offset Table data"));
17730 /* PR 12855: Null data is handled gracefully throughout. */
17731 data_end = data + (end - pltgot);
17732
17733 printf (_("\nStatic GOT:\n"));
17734 printf (_(" Canonical gp value: "));
17735 print_vma (ent + 0x7ff0, LONG_HEX);
17736 printf ("\n\n");
17737
17738 /* In a dynamic binary GOT[0] is reserved for the dynamic
17739 loader to store the lazy resolver pointer, however in
17740 a static binary it may well have been omitted and GOT
17741 reduced to a table of addresses.
17742 PR 21344: Check for the entry being fully available
17743 before fetching it. */
17744 if (data
17745 && data + ent - pltgot + addr_size <= data_end
17746 && byte_get (data + ent - pltgot, addr_size) == 0)
17747 {
17748 printf (_(" Reserved entries:\n"));
17749 printf (_(" %*s %10s %*s\n"),
17750 addr_size * 2, _("Address"), _("Access"),
17751 addr_size * 2, _("Value"));
17752 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17753 printf ("\n");
17754 if (ent == (bfd_vma) -1)
17755 goto sgot_print_fail;
17756
17757 /* Check for the MSB of GOT[1] being set, identifying a
17758 GNU object. This entry will be used by some runtime
17759 loaders, to store the module pointer. Otherwise this
17760 is an ordinary local entry.
17761 PR 21344: Check for the entry being fully available
17762 before fetching it. */
17763 if (data
17764 && data + ent - pltgot + addr_size <= data_end
17765 && (byte_get (data + ent - pltgot, addr_size)
17766 >> (addr_size * 8 - 1)) != 0)
17767 {
17768 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17769 printf ("\n");
17770 if (ent == (bfd_vma) -1)
17771 goto sgot_print_fail;
17772 }
17773 printf ("\n");
17774 }
17775
f17e9d8a 17776 if (data != NULL && ent < end)
bbdd9a68
MR
17777 {
17778 printf (_(" Local entries:\n"));
17779 printf (" %*s %10s %*s\n",
17780 addr_size * 2, _("Address"), _("Access"),
17781 addr_size * 2, _("Value"));
17782 while (ent < end)
17783 {
17784 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17785 printf ("\n");
17786 if (ent == (bfd_vma) -1)
17787 goto sgot_print_fail;
17788 }
17789 printf ("\n");
17790 }
17791
17792 sgot_print_fail:
9db70fc3 17793 free (data);
bbdd9a68
MR
17794 }
17795 return res;
17796 }
252b5132 17797
978c4450 17798 for (entry = filedata->dynamic_section;
071436c6 17799 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
17800 (entry < filedata->dynamic_section + filedata->dynamic_nent
17801 && entry->d_tag != DT_NULL);
071436c6 17802 ++entry)
252b5132
RH
17803 switch (entry->d_tag)
17804 {
17805 case DT_MIPS_LIBLIST:
d93f0186 17806 liblist_offset
dda8d76d 17807 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17808 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
17809 break;
17810 case DT_MIPS_LIBLISTNO:
17811 liblistno = entry->d_un.d_val;
17812 break;
17813 case DT_MIPS_OPTIONS:
dda8d76d 17814 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
17815 break;
17816 case DT_MIPS_CONFLICT:
d93f0186 17817 conflicts_offset
dda8d76d 17818 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17819 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
17820 break;
17821 case DT_MIPS_CONFLICTNO:
17822 conflictsno = entry->d_un.d_val;
17823 break;
ccb4c951 17824 case DT_PLTGOT:
861fb55a
DJ
17825 pltgot = entry->d_un.d_ptr;
17826 break;
ccb4c951
RS
17827 case DT_MIPS_LOCAL_GOTNO:
17828 local_gotno = entry->d_un.d_val;
17829 break;
17830 case DT_MIPS_GOTSYM:
17831 gotsym = entry->d_un.d_val;
17832 break;
17833 case DT_MIPS_SYMTABNO:
17834 symtabno = entry->d_un.d_val;
17835 break;
861fb55a
DJ
17836 case DT_MIPS_PLTGOT:
17837 mips_pltgot = entry->d_un.d_ptr;
17838 break;
17839 case DT_PLTREL:
17840 pltrel = entry->d_un.d_val;
17841 break;
17842 case DT_PLTRELSZ:
17843 pltrelsz = entry->d_un.d_val;
17844 break;
17845 case DT_JMPREL:
17846 jmprel = entry->d_un.d_ptr;
17847 break;
252b5132
RH
17848 default:
17849 break;
17850 }
17851
17852 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
17853 {
2cf0635d 17854 Elf32_External_Lib * elib;
252b5132
RH
17855 size_t cnt;
17856
dda8d76d 17857 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
17858 sizeof (Elf32_External_Lib),
17859 liblistno,
17860 _("liblist section data"));
a6e9f9df 17861 if (elib)
252b5132 17862 {
d3a49aa8
AM
17863 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
17864 "\nSection '.liblist' contains %lu entries:\n",
17865 (unsigned long) liblistno),
a6e9f9df 17866 (unsigned long) liblistno);
2b692964 17867 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
17868 stdout);
17869
17870 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 17871 {
a6e9f9df 17872 Elf32_Lib liblist;
91d6fa6a 17873 time_t atime;
d5b07ef4 17874 char timebuf[128];
2cf0635d 17875 struct tm * tmp;
a6e9f9df
AM
17876
17877 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17878 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
17879 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17880 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17881 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17882
91d6fa6a 17883 tmp = gmtime (&atime);
e9e44622
JJ
17884 snprintf (timebuf, sizeof (timebuf),
17885 "%04u-%02u-%02uT%02u:%02u:%02u",
17886 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17887 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 17888
31104126 17889 printf ("%3lu: ", (unsigned long) cnt);
978c4450
AM
17890 if (VALID_DYNAMIC_NAME (filedata, liblist.l_name))
17891 print_symbol (20, GET_DYNAMIC_NAME (filedata, liblist.l_name));
d79b3d50 17892 else
2b692964 17893 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
17894 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
17895 liblist.l_version);
a6e9f9df
AM
17896
17897 if (liblist.l_flags == 0)
2b692964 17898 puts (_(" NONE"));
a6e9f9df
AM
17899 else
17900 {
17901 static const struct
252b5132 17902 {
2cf0635d 17903 const char * name;
a6e9f9df 17904 int bit;
252b5132 17905 }
a6e9f9df
AM
17906 l_flags_vals[] =
17907 {
17908 { " EXACT_MATCH", LL_EXACT_MATCH },
17909 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
17910 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
17911 { " EXPORTS", LL_EXPORTS },
17912 { " DELAY_LOAD", LL_DELAY_LOAD },
17913 { " DELTA", LL_DELTA }
17914 };
17915 int flags = liblist.l_flags;
17916 size_t fcnt;
17917
60bca95a 17918 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
17919 if ((flags & l_flags_vals[fcnt].bit) != 0)
17920 {
17921 fputs (l_flags_vals[fcnt].name, stdout);
17922 flags ^= l_flags_vals[fcnt].bit;
17923 }
17924 if (flags != 0)
17925 printf (" %#x", (unsigned int) flags);
252b5132 17926
a6e9f9df
AM
17927 puts ("");
17928 }
252b5132 17929 }
252b5132 17930
a6e9f9df
AM
17931 free (elib);
17932 }
32ec8896 17933 else
015dc7e1 17934 res = false;
252b5132
RH
17935 }
17936
17937 if (options_offset != 0)
17938 {
2cf0635d 17939 Elf_External_Options * eopt;
252b5132
RH
17940 size_t offset;
17941 int cnt;
dda8d76d 17942 sect = filedata->section_headers;
252b5132
RH
17943
17944 /* Find the section header so that we get the size. */
dda8d76d 17945 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 17946 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
17947 if (sect == NULL)
17948 {
17949 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 17950 return false;
071436c6 17951 }
7fc0c668
NC
17952 /* PR 24243 */
17953 if (sect->sh_size < sizeof (* eopt))
17954 {
17955 error (_("The MIPS options section is too small.\n"));
015dc7e1 17956 return false;
7fc0c668 17957 }
252b5132 17958
dda8d76d 17959 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 17960 sect->sh_size, _("options"));
a6e9f9df 17961 if (eopt)
252b5132 17962 {
fd17d1e6 17963 Elf_Internal_Options option;
76da6bbe 17964
a6e9f9df 17965 offset = cnt = 0;
82b1b41b 17966 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 17967 {
2cf0635d 17968 Elf_External_Options * eoption;
fd17d1e6 17969 unsigned int optsize;
252b5132 17970
a6e9f9df 17971 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 17972
fd17d1e6 17973 optsize = BYTE_GET (eoption->size);
76da6bbe 17974
82b1b41b 17975 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
17976 if (optsize < sizeof (* eopt)
17977 || optsize > sect->sh_size - offset)
82b1b41b 17978 {
645f43a8 17979 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 17980 optsize);
645f43a8 17981 free (eopt);
015dc7e1 17982 return false;
82b1b41b 17983 }
fd17d1e6 17984 offset += optsize;
a6e9f9df
AM
17985 ++cnt;
17986 }
252b5132 17987
d3a49aa8
AM
17988 printf (ngettext ("\nSection '%s' contains %d entry:\n",
17989 "\nSection '%s' contains %d entries:\n",
17990 cnt),
dda8d76d 17991 printable_section_name (filedata, sect), cnt);
76da6bbe 17992
82b1b41b 17993 offset = 0;
a6e9f9df 17994 while (cnt-- > 0)
252b5132 17995 {
a6e9f9df 17996 size_t len;
fd17d1e6
AM
17997 Elf_External_Options * eoption;
17998
17999 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18000
18001 option.kind = BYTE_GET (eoption->kind);
18002 option.size = BYTE_GET (eoption->size);
18003 option.section = BYTE_GET (eoption->section);
18004 option.info = BYTE_GET (eoption->info);
a6e9f9df 18005
fd17d1e6 18006 switch (option.kind)
252b5132 18007 {
a6e9f9df
AM
18008 case ODK_NULL:
18009 /* This shouldn't happen. */
d0c4e780 18010 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18011 option.section, option.info);
a6e9f9df 18012 break;
2e6be59c 18013
a6e9f9df
AM
18014 case ODK_REGINFO:
18015 printf (" REGINFO ");
dda8d76d 18016 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18017 {
2cf0635d 18018 Elf32_External_RegInfo * ereg;
b34976b6 18019 Elf32_RegInfo reginfo;
a6e9f9df 18020
2e6be59c 18021 /* 32bit form. */
fd17d1e6
AM
18022 if (option.size < (sizeof (Elf_External_Options)
18023 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18024 {
18025 printf (_("<corrupt>\n"));
18026 error (_("Truncated MIPS REGINFO option\n"));
18027 cnt = 0;
18028 break;
18029 }
18030
fd17d1e6 18031 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18032
a6e9f9df
AM
18033 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18034 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18035 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18036 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18037 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18038 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18039
d0c4e780
AM
18040 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18041 reginfo.ri_gprmask, reginfo.ri_gp_value);
18042 printf (" "
18043 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18044 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18045 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18046 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18047 }
18048 else
18049 {
18050 /* 64 bit form. */
2cf0635d 18051 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18052 Elf64_Internal_RegInfo reginfo;
18053
fd17d1e6
AM
18054 if (option.size < (sizeof (Elf_External_Options)
18055 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18056 {
18057 printf (_("<corrupt>\n"));
18058 error (_("Truncated MIPS REGINFO option\n"));
18059 cnt = 0;
18060 break;
18061 }
18062
fd17d1e6 18063 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18064 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18065 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18066 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18067 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18068 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18069 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18070
d0c4e780
AM
18071 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18072 reginfo.ri_gprmask, reginfo.ri_gp_value);
18073 printf (" "
18074 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18075 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18076 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18077 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18078 }
fd17d1e6 18079 offset += option.size;
a6e9f9df 18080 continue;
2e6be59c 18081
a6e9f9df
AM
18082 case ODK_EXCEPTIONS:
18083 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18084 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18085 fputs (") fpe_max(", stdout);
fd17d1e6 18086 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18087 fputs (")", stdout);
18088
fd17d1e6 18089 if (option.info & OEX_PAGE0)
a6e9f9df 18090 fputs (" PAGE0", stdout);
fd17d1e6 18091 if (option.info & OEX_SMM)
a6e9f9df 18092 fputs (" SMM", stdout);
fd17d1e6 18093 if (option.info & OEX_FPDBUG)
a6e9f9df 18094 fputs (" FPDBUG", stdout);
fd17d1e6 18095 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18096 fputs (" DISMISS", stdout);
18097 break;
2e6be59c 18098
a6e9f9df
AM
18099 case ODK_PAD:
18100 fputs (" PAD ", stdout);
fd17d1e6 18101 if (option.info & OPAD_PREFIX)
a6e9f9df 18102 fputs (" PREFIX", stdout);
fd17d1e6 18103 if (option.info & OPAD_POSTFIX)
a6e9f9df 18104 fputs (" POSTFIX", stdout);
fd17d1e6 18105 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18106 fputs (" SYMBOL", stdout);
18107 break;
2e6be59c 18108
a6e9f9df
AM
18109 case ODK_HWPATCH:
18110 fputs (" HWPATCH ", stdout);
fd17d1e6 18111 if (option.info & OHW_R4KEOP)
a6e9f9df 18112 fputs (" R4KEOP", stdout);
fd17d1e6 18113 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18114 fputs (" R8KPFETCH", stdout);
fd17d1e6 18115 if (option.info & OHW_R5KEOP)
a6e9f9df 18116 fputs (" R5KEOP", stdout);
fd17d1e6 18117 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18118 fputs (" R5KCVTL", stdout);
18119 break;
2e6be59c 18120
a6e9f9df
AM
18121 case ODK_FILL:
18122 fputs (" FILL ", stdout);
18123 /* XXX Print content of info word? */
18124 break;
2e6be59c 18125
a6e9f9df
AM
18126 case ODK_TAGS:
18127 fputs (" TAGS ", stdout);
18128 /* XXX Print content of info word? */
18129 break;
2e6be59c 18130
a6e9f9df
AM
18131 case ODK_HWAND:
18132 fputs (" HWAND ", stdout);
fd17d1e6 18133 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18134 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18135 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18136 fputs (" R4KEOP_CLEAN", stdout);
18137 break;
2e6be59c 18138
a6e9f9df
AM
18139 case ODK_HWOR:
18140 fputs (" HWOR ", stdout);
fd17d1e6 18141 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18142 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18143 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18144 fputs (" R4KEOP_CLEAN", stdout);
18145 break;
2e6be59c 18146
a6e9f9df 18147 case ODK_GP_GROUP:
d0c4e780 18148 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18149 option.info & OGP_GROUP,
18150 (option.info & OGP_SELF) >> 16);
a6e9f9df 18151 break;
2e6be59c 18152
a6e9f9df 18153 case ODK_IDENT:
d0c4e780 18154 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18155 option.info & OGP_GROUP,
18156 (option.info & OGP_SELF) >> 16);
a6e9f9df 18157 break;
2e6be59c 18158
a6e9f9df
AM
18159 default:
18160 /* This shouldn't happen. */
d0c4e780 18161 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18162 option.kind, option.section, option.info);
a6e9f9df 18163 break;
252b5132 18164 }
a6e9f9df 18165
2cf0635d 18166 len = sizeof (* eopt);
fd17d1e6 18167 while (len < option.size)
82b1b41b 18168 {
fd17d1e6 18169 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18170
82b1b41b
NC
18171 if (ISPRINT (datum))
18172 printf ("%c", datum);
18173 else
18174 printf ("\\%03o", datum);
18175 len ++;
18176 }
a6e9f9df 18177 fputs ("\n", stdout);
82b1b41b 18178
fd17d1e6 18179 offset += option.size;
252b5132 18180 }
a6e9f9df 18181 free (eopt);
252b5132 18182 }
32ec8896 18183 else
015dc7e1 18184 res = false;
252b5132
RH
18185 }
18186
18187 if (conflicts_offset != 0 && conflictsno != 0)
18188 {
2cf0635d 18189 Elf32_Conflict * iconf;
252b5132
RH
18190 size_t cnt;
18191
978c4450 18192 if (filedata->dynamic_symbols == NULL)
252b5132 18193 {
591a748a 18194 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18195 return false;
252b5132
RH
18196 }
18197
7296a62a
NC
18198 /* PR 21345 - print a slightly more helpful error message
18199 if we are sure that the cmalloc will fail. */
645f43a8 18200 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18201 {
18202 error (_("Overlarge number of conflicts detected: %lx\n"),
18203 (long) conflictsno);
015dc7e1 18204 return false;
7296a62a
NC
18205 }
18206
3f5e193b 18207 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18208 if (iconf == NULL)
18209 {
8b73c356 18210 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18211 return false;
252b5132
RH
18212 }
18213
9ea033b2 18214 if (is_32bit_elf)
252b5132 18215 {
2cf0635d 18216 Elf32_External_Conflict * econf32;
a6e9f9df 18217
3f5e193b 18218 econf32 = (Elf32_External_Conflict *)
95099889
AM
18219 get_data (NULL, filedata, conflicts_offset,
18220 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18221 if (!econf32)
5a814d6d
AM
18222 {
18223 free (iconf);
015dc7e1 18224 return false;
5a814d6d 18225 }
252b5132
RH
18226
18227 for (cnt = 0; cnt < conflictsno; ++cnt)
18228 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18229
18230 free (econf32);
252b5132
RH
18231 }
18232 else
18233 {
2cf0635d 18234 Elf64_External_Conflict * econf64;
a6e9f9df 18235
3f5e193b 18236 econf64 = (Elf64_External_Conflict *)
95099889
AM
18237 get_data (NULL, filedata, conflicts_offset,
18238 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18239 if (!econf64)
5a814d6d
AM
18240 {
18241 free (iconf);
015dc7e1 18242 return false;
5a814d6d 18243 }
252b5132
RH
18244
18245 for (cnt = 0; cnt < conflictsno; ++cnt)
18246 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18247
18248 free (econf64);
252b5132
RH
18249 }
18250
d3a49aa8
AM
18251 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18252 "\nSection '.conflict' contains %lu entries:\n",
18253 (unsigned long) conflictsno),
c7e7ca54 18254 (unsigned long) conflictsno);
252b5132
RH
18255 puts (_(" Num: Index Value Name"));
18256
18257 for (cnt = 0; cnt < conflictsno; ++cnt)
18258 {
b34976b6 18259 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18260
978c4450 18261 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18262 printf (_("<corrupt symbol index>"));
d79b3d50 18263 else
e0a31db1
NC
18264 {
18265 Elf_Internal_Sym * psym;
18266
978c4450 18267 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18268 print_vma (psym->st_value, FULL_HEX);
18269 putchar (' ');
978c4450
AM
18270 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18271 print_symbol (25, GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18272 else
18273 printf (_("<corrupt: %14ld>"), psym->st_name);
18274 }
31104126 18275 putchar ('\n');
252b5132
RH
18276 }
18277
252b5132
RH
18278 free (iconf);
18279 }
18280
ccb4c951
RS
18281 if (pltgot != 0 && local_gotno != 0)
18282 {
91d6fa6a 18283 bfd_vma ent, local_end, global_end;
bbeee7ea 18284 size_t i, offset;
2cf0635d 18285 unsigned char * data;
82b1b41b 18286 unsigned char * data_end;
bbeee7ea 18287 int addr_size;
ccb4c951 18288
91d6fa6a 18289 ent = pltgot;
ccb4c951
RS
18290 addr_size = (is_32bit_elf ? 4 : 8);
18291 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18292
74e1a04b
NC
18293 /* PR binutils/17533 file: 012-111227-0.004 */
18294 if (symtabno < gotsym)
18295 {
18296 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18297 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18298 return false;
74e1a04b 18299 }
82b1b41b 18300
74e1a04b 18301 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18302 /* PR 17531: file: 54c91a34. */
18303 if (global_end < local_end)
18304 {
18305 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18306 return false;
82b1b41b 18307 }
948f632f 18308
dda8d76d
NC
18309 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18310 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18311 global_end - pltgot, 1,
18312 _("Global Offset Table data"));
919383ac 18313 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18314 data_end = data + (global_end - pltgot);
59245841 18315
ccb4c951
RS
18316 printf (_("\nPrimary GOT:\n"));
18317 printf (_(" Canonical gp value: "));
18318 print_vma (pltgot + 0x7ff0, LONG_HEX);
18319 printf ("\n\n");
18320
18321 printf (_(" Reserved entries:\n"));
18322 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18323 addr_size * 2, _("Address"), _("Access"),
18324 addr_size * 2, _("Initial"));
82b1b41b 18325 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18326 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18327 if (ent == (bfd_vma) -1)
18328 goto got_print_fail;
75ec1fdb 18329
c4ab9505
MR
18330 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18331 This entry will be used by some runtime loaders, to store the
18332 module pointer. Otherwise this is an ordinary local entry.
18333 PR 21344: Check for the entry being fully available before
18334 fetching it. */
18335 if (data
18336 && data + ent - pltgot + addr_size <= data_end
18337 && (byte_get (data + ent - pltgot, addr_size)
18338 >> (addr_size * 8 - 1)) != 0)
18339 {
18340 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18341 printf (_(" Module pointer (GNU extension)\n"));
18342 if (ent == (bfd_vma) -1)
18343 goto got_print_fail;
ccb4c951
RS
18344 }
18345 printf ("\n");
18346
f17e9d8a 18347 if (data != NULL && ent < local_end)
ccb4c951
RS
18348 {
18349 printf (_(" Local entries:\n"));
cc5914eb 18350 printf (" %*s %10s %*s\n",
2b692964
NC
18351 addr_size * 2, _("Address"), _("Access"),
18352 addr_size * 2, _("Initial"));
91d6fa6a 18353 while (ent < local_end)
ccb4c951 18354 {
82b1b41b 18355 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18356 printf ("\n");
82b1b41b
NC
18357 if (ent == (bfd_vma) -1)
18358 goto got_print_fail;
ccb4c951
RS
18359 }
18360 printf ("\n");
18361 }
18362
f17e9d8a 18363 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18364 {
18365 int sym_width;
18366
18367 printf (_(" Global entries:\n"));
cc5914eb 18368 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18369 addr_size * 2, _("Address"),
18370 _("Access"),
2b692964 18371 addr_size * 2, _("Initial"),
9cf03b7e
NC
18372 addr_size * 2, _("Sym.Val."),
18373 _("Type"),
18374 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18375 _("Ndx"), _("Name"));
0b4362b0 18376
ccb4c951 18377 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18378
ccb4c951
RS
18379 for (i = gotsym; i < symtabno; i++)
18380 {
82b1b41b 18381 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18382 printf (" ");
e0a31db1 18383
978c4450 18384 if (filedata->dynamic_symbols == NULL)
e0a31db1 18385 printf (_("<no dynamic symbols>"));
978c4450 18386 else if (i < filedata->num_dynamic_syms)
e0a31db1 18387 {
978c4450 18388 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
18389
18390 print_vma (psym->st_value, LONG_HEX);
18391 printf (" %-7s %3s ",
dda8d76d
NC
18392 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18393 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 18394
978c4450
AM
18395 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18396 print_symbol (sym_width,
18397 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18398 else
18399 printf (_("<corrupt: %14ld>"), psym->st_name);
18400 }
ccb4c951 18401 else
7fc5ac57
JBG
18402 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
18403 (unsigned long) i);
e0a31db1 18404
ccb4c951 18405 printf ("\n");
82b1b41b
NC
18406 if (ent == (bfd_vma) -1)
18407 break;
ccb4c951
RS
18408 }
18409 printf ("\n");
18410 }
18411
82b1b41b 18412 got_print_fail:
9db70fc3 18413 free (data);
ccb4c951
RS
18414 }
18415
861fb55a
DJ
18416 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
18417 {
91d6fa6a 18418 bfd_vma ent, end;
861fb55a
DJ
18419 size_t offset, rel_offset;
18420 unsigned long count, i;
2cf0635d 18421 unsigned char * data;
861fb55a 18422 int addr_size, sym_width;
2cf0635d 18423 Elf_Internal_Rela * rels;
861fb55a 18424
dda8d76d 18425 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
18426 if (pltrel == DT_RELA)
18427 {
dda8d76d 18428 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18429 return false;
861fb55a
DJ
18430 }
18431 else
18432 {
dda8d76d 18433 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18434 return false;
861fb55a
DJ
18435 }
18436
91d6fa6a 18437 ent = mips_pltgot;
861fb55a
DJ
18438 addr_size = (is_32bit_elf ? 4 : 8);
18439 end = mips_pltgot + (2 + count) * addr_size;
18440
dda8d76d
NC
18441 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
18442 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 18443 1, _("Procedure Linkage Table data"));
59245841 18444 if (data == NULL)
288f0ba2
AM
18445 {
18446 free (rels);
015dc7e1 18447 return false;
288f0ba2 18448 }
59245841 18449
9cf03b7e 18450 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
18451 printf (_(" Reserved entries:\n"));
18452 printf (_(" %*s %*s Purpose\n"),
2b692964 18453 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 18454 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18455 printf (_(" PLT lazy resolver\n"));
91d6fa6a 18456 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18457 printf (_(" Module pointer\n"));
861fb55a
DJ
18458 printf ("\n");
18459
18460 printf (_(" Entries:\n"));
cc5914eb 18461 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
18462 addr_size * 2, _("Address"),
18463 addr_size * 2, _("Initial"),
18464 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
18465 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
18466 for (i = 0; i < count; i++)
18467 {
df97ab2a 18468 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 18469
91d6fa6a 18470 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 18471 printf (" ");
e0a31db1 18472
978c4450 18473 if (idx >= filedata->num_dynamic_syms)
df97ab2a 18474 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 18475 else
e0a31db1 18476 {
978c4450 18477 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
18478
18479 print_vma (psym->st_value, LONG_HEX);
18480 printf (" %-7s %3s ",
dda8d76d
NC
18481 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18482 get_symbol_index_type (filedata, psym->st_shndx));
978c4450
AM
18483 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18484 print_symbol (sym_width,
18485 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18486 else
18487 printf (_("<corrupt: %14ld>"), psym->st_name);
18488 }
861fb55a
DJ
18489 printf ("\n");
18490 }
18491 printf ("\n");
18492
9db70fc3 18493 free (data);
861fb55a
DJ
18494 free (rels);
18495 }
18496
32ec8896 18497 return res;
252b5132
RH
18498}
18499
015dc7e1 18500static bool
dda8d76d 18501process_nds32_specific (Filedata * filedata)
35c08157
KLC
18502{
18503 Elf_Internal_Shdr *sect = NULL;
18504
dda8d76d 18505 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 18506 if (sect != NULL && sect->sh_size >= 4)
35c08157 18507 {
9c7b8e9b
AM
18508 unsigned char *buf;
18509 unsigned int flag;
35c08157
KLC
18510
18511 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
18512 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
18513 _("NDS32 elf flags section"));
35c08157 18514
9c7b8e9b 18515 if (buf == NULL)
015dc7e1 18516 return false;
32ec8896 18517
9c7b8e9b
AM
18518 flag = byte_get (buf, 4);
18519 free (buf);
18520 switch (flag & 0x3)
35c08157
KLC
18521 {
18522 case 0:
18523 printf ("(VEC_SIZE):\tNo entry.\n");
18524 break;
18525 case 1:
18526 printf ("(VEC_SIZE):\t4 bytes\n");
18527 break;
18528 case 2:
18529 printf ("(VEC_SIZE):\t16 bytes\n");
18530 break;
18531 case 3:
18532 printf ("(VEC_SIZE):\treserved\n");
18533 break;
18534 }
18535 }
18536
015dc7e1 18537 return true;
35c08157
KLC
18538}
18539
015dc7e1 18540static bool
dda8d76d 18541process_gnu_liblist (Filedata * filedata)
047b2264 18542{
2cf0635d
NC
18543 Elf_Internal_Shdr * section;
18544 Elf_Internal_Shdr * string_sec;
18545 Elf32_External_Lib * elib;
18546 char * strtab;
c256ffe7 18547 size_t strtab_size;
047b2264 18548 size_t cnt;
d3a49aa8 18549 unsigned long num_liblist;
047b2264 18550 unsigned i;
015dc7e1 18551 bool res = true;
047b2264
JJ
18552
18553 if (! do_arch)
015dc7e1 18554 return true;
047b2264 18555
dda8d76d
NC
18556 for (i = 0, section = filedata->section_headers;
18557 i < filedata->file_header.e_shnum;
b34976b6 18558 i++, section++)
047b2264
JJ
18559 {
18560 switch (section->sh_type)
18561 {
18562 case SHT_GNU_LIBLIST:
dda8d76d 18563 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
18564 break;
18565
3f5e193b 18566 elib = (Elf32_External_Lib *)
dda8d76d 18567 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 18568 _("liblist section data"));
047b2264
JJ
18569
18570 if (elib == NULL)
32ec8896 18571 {
015dc7e1 18572 res = false;
32ec8896
NC
18573 break;
18574 }
047b2264 18575
dda8d76d
NC
18576 string_sec = filedata->section_headers + section->sh_link;
18577 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
18578 string_sec->sh_size,
18579 _("liblist string table"));
047b2264
JJ
18580 if (strtab == NULL
18581 || section->sh_entsize != sizeof (Elf32_External_Lib))
18582 {
18583 free (elib);
2842702f 18584 free (strtab);
015dc7e1 18585 res = false;
047b2264
JJ
18586 break;
18587 }
59245841 18588 strtab_size = string_sec->sh_size;
047b2264 18589
d3a49aa8
AM
18590 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
18591 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
18592 "\nLibrary list section '%s' contains %lu entries:\n",
18593 num_liblist),
dda8d76d 18594 printable_section_name (filedata, section),
d3a49aa8 18595 num_liblist);
047b2264 18596
2b692964 18597 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
18598
18599 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
18600 ++cnt)
18601 {
18602 Elf32_Lib liblist;
91d6fa6a 18603 time_t atime;
d5b07ef4 18604 char timebuf[128];
2cf0635d 18605 struct tm * tmp;
047b2264
JJ
18606
18607 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18608 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
18609 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18610 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18611 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18612
91d6fa6a 18613 tmp = gmtime (&atime);
e9e44622
JJ
18614 snprintf (timebuf, sizeof (timebuf),
18615 "%04u-%02u-%02uT%02u:%02u:%02u",
18616 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18617 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
18618
18619 printf ("%3lu: ", (unsigned long) cnt);
18620 if (do_wide)
c256ffe7 18621 printf ("%-20s", liblist.l_name < strtab_size
2b692964 18622 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 18623 else
c256ffe7 18624 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 18625 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
18626 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
18627 liblist.l_version, liblist.l_flags);
18628 }
18629
18630 free (elib);
2842702f 18631 free (strtab);
047b2264
JJ
18632 }
18633 }
18634
32ec8896 18635 return res;
047b2264
JJ
18636}
18637
9437c45b 18638static const char *
dda8d76d 18639get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
18640{
18641 static char buff[64];
103f02d3 18642
dda8d76d 18643 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
18644 switch (e_type)
18645 {
57346661 18646 case NT_AUXV:
1ec5cd37 18647 return _("NT_AUXV (auxiliary vector)");
57346661 18648 case NT_PRSTATUS:
1ec5cd37 18649 return _("NT_PRSTATUS (prstatus structure)");
57346661 18650 case NT_FPREGSET:
1ec5cd37 18651 return _("NT_FPREGSET (floating point registers)");
57346661 18652 case NT_PRPSINFO:
1ec5cd37 18653 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 18654 case NT_TASKSTRUCT:
1ec5cd37 18655 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
18656 case NT_GDB_TDESC:
18657 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 18658 case NT_PRXFPREG:
1ec5cd37 18659 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
18660 case NT_PPC_VMX:
18661 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
18662 case NT_PPC_VSX:
18663 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
18664 case NT_PPC_TAR:
18665 return _("NT_PPC_TAR (ppc TAR register)");
18666 case NT_PPC_PPR:
18667 return _("NT_PPC_PPR (ppc PPR register)");
18668 case NT_PPC_DSCR:
18669 return _("NT_PPC_DSCR (ppc DSCR register)");
18670 case NT_PPC_EBB:
18671 return _("NT_PPC_EBB (ppc EBB registers)");
18672 case NT_PPC_PMU:
18673 return _("NT_PPC_PMU (ppc PMU registers)");
18674 case NT_PPC_TM_CGPR:
18675 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
18676 case NT_PPC_TM_CFPR:
18677 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
18678 case NT_PPC_TM_CVMX:
18679 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
18680 case NT_PPC_TM_CVSX:
3fd21718 18681 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
18682 case NT_PPC_TM_SPR:
18683 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
18684 case NT_PPC_TM_CTAR:
18685 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
18686 case NT_PPC_TM_CPPR:
18687 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
18688 case NT_PPC_TM_CDSCR:
18689 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
18690 case NT_386_TLS:
18691 return _("NT_386_TLS (x86 TLS information)");
18692 case NT_386_IOPERM:
18693 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
18694 case NT_X86_XSTATE:
18695 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
18696 case NT_X86_CET:
18697 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
18698 case NT_S390_HIGH_GPRS:
18699 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
18700 case NT_S390_TIMER:
18701 return _("NT_S390_TIMER (s390 timer register)");
18702 case NT_S390_TODCMP:
18703 return _("NT_S390_TODCMP (s390 TOD comparator register)");
18704 case NT_S390_TODPREG:
18705 return _("NT_S390_TODPREG (s390 TOD programmable register)");
18706 case NT_S390_CTRS:
18707 return _("NT_S390_CTRS (s390 control registers)");
18708 case NT_S390_PREFIX:
18709 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
18710 case NT_S390_LAST_BREAK:
18711 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
18712 case NT_S390_SYSTEM_CALL:
18713 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
18714 case NT_S390_TDB:
18715 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
18716 case NT_S390_VXRS_LOW:
18717 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
18718 case NT_S390_VXRS_HIGH:
18719 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
18720 case NT_S390_GS_CB:
18721 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
18722 case NT_S390_GS_BC:
18723 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
18724 case NT_ARM_VFP:
18725 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
18726 case NT_ARM_TLS:
18727 return _("NT_ARM_TLS (AArch TLS registers)");
18728 case NT_ARM_HW_BREAK:
18729 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
18730 case NT_ARM_HW_WATCH:
18731 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
3b2bef8b
LM
18732 case NT_ARM_SVE:
18733 return _("NT_ARM_SVE (AArch SVE registers)");
18734 case NT_ARM_PAC_MASK:
18735 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
18736 case NT_ARM_TAGGED_ADDR_CTRL:
18737 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
27456742
AK
18738 case NT_ARC_V2:
18739 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
18740 case NT_RISCV_CSR:
18741 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 18742 case NT_PSTATUS:
1ec5cd37 18743 return _("NT_PSTATUS (pstatus structure)");
57346661 18744 case NT_FPREGS:
1ec5cd37 18745 return _("NT_FPREGS (floating point registers)");
57346661 18746 case NT_PSINFO:
1ec5cd37 18747 return _("NT_PSINFO (psinfo structure)");
57346661 18748 case NT_LWPSTATUS:
1ec5cd37 18749 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 18750 case NT_LWPSINFO:
1ec5cd37 18751 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 18752 case NT_WIN32PSTATUS:
1ec5cd37 18753 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
18754 case NT_SIGINFO:
18755 return _("NT_SIGINFO (siginfo_t data)");
18756 case NT_FILE:
18757 return _("NT_FILE (mapped files)");
894982bf
LM
18758 case NT_MEMTAG:
18759 return _("NT_MEMTAG (memory tags)");
1ec5cd37
NC
18760 default:
18761 break;
18762 }
18763 else
18764 switch (e_type)
18765 {
18766 case NT_VERSION:
18767 return _("NT_VERSION (version)");
18768 case NT_ARCH:
18769 return _("NT_ARCH (architecture)");
9ef920e9 18770 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 18771 return _("OPEN");
9ef920e9 18772 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 18773 return _("func");
1ec5cd37
NC
18774 default:
18775 break;
18776 }
18777
e9e44622 18778 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 18779 return buff;
779fe533
NC
18780}
18781
015dc7e1 18782static bool
9ece1fa9
TT
18783print_core_note (Elf_Internal_Note *pnote)
18784{
18785 unsigned int addr_size = is_32bit_elf ? 4 : 8;
18786 bfd_vma count, page_size;
18787 unsigned char *descdata, *filenames, *descend;
18788
18789 if (pnote->type != NT_FILE)
04ac15ab
AS
18790 {
18791 if (do_wide)
18792 printf ("\n");
015dc7e1 18793 return true;
04ac15ab 18794 }
9ece1fa9
TT
18795
18796#ifndef BFD64
18797 if (!is_32bit_elf)
18798 {
18799 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
18800 /* Still "successful". */
015dc7e1 18801 return true;
9ece1fa9
TT
18802 }
18803#endif
18804
18805 if (pnote->descsz < 2 * addr_size)
18806 {
32ec8896 18807 error (_(" Malformed note - too short for header\n"));
015dc7e1 18808 return false;
9ece1fa9
TT
18809 }
18810
18811 descdata = (unsigned char *) pnote->descdata;
18812 descend = descdata + pnote->descsz;
18813
18814 if (descdata[pnote->descsz - 1] != '\0')
18815 {
32ec8896 18816 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 18817 return false;
9ece1fa9
TT
18818 }
18819
18820 count = byte_get (descdata, addr_size);
18821 descdata += addr_size;
18822
18823 page_size = byte_get (descdata, addr_size);
18824 descdata += addr_size;
18825
5396a86e
AM
18826 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
18827 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 18828 {
32ec8896 18829 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 18830 return false;
9ece1fa9
TT
18831 }
18832
18833 printf (_(" Page size: "));
18834 print_vma (page_size, DEC);
18835 printf ("\n");
18836
18837 printf (_(" %*s%*s%*s\n"),
18838 (int) (2 + 2 * addr_size), _("Start"),
18839 (int) (4 + 2 * addr_size), _("End"),
18840 (int) (4 + 2 * addr_size), _("Page Offset"));
18841 filenames = descdata + count * 3 * addr_size;
595712bb 18842 while (count-- > 0)
9ece1fa9
TT
18843 {
18844 bfd_vma start, end, file_ofs;
18845
18846 if (filenames == descend)
18847 {
32ec8896 18848 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 18849 return false;
9ece1fa9
TT
18850 }
18851
18852 start = byte_get (descdata, addr_size);
18853 descdata += addr_size;
18854 end = byte_get (descdata, addr_size);
18855 descdata += addr_size;
18856 file_ofs = byte_get (descdata, addr_size);
18857 descdata += addr_size;
18858
18859 printf (" ");
18860 print_vma (start, FULL_HEX);
18861 printf (" ");
18862 print_vma (end, FULL_HEX);
18863 printf (" ");
18864 print_vma (file_ofs, FULL_HEX);
18865 printf ("\n %s\n", filenames);
18866
18867 filenames += 1 + strlen ((char *) filenames);
18868 }
18869
015dc7e1 18870 return true;
9ece1fa9
TT
18871}
18872
1118d252
RM
18873static const char *
18874get_gnu_elf_note_type (unsigned e_type)
18875{
1449284b 18876 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
18877 switch (e_type)
18878 {
18879 case NT_GNU_ABI_TAG:
18880 return _("NT_GNU_ABI_TAG (ABI version tag)");
18881 case NT_GNU_HWCAP:
18882 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
18883 case NT_GNU_BUILD_ID:
18884 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
18885 case NT_GNU_GOLD_VERSION:
18886 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
18887 case NT_GNU_PROPERTY_TYPE_0:
18888 return _("NT_GNU_PROPERTY_TYPE_0");
18889 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
18890 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
18891 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
18892 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 18893 default:
1449284b
NC
18894 {
18895 static char buff[64];
1118d252 18896
1449284b
NC
18897 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18898 return buff;
18899 }
18900 }
1118d252
RM
18901}
18902
a9eafb08
L
18903static void
18904decode_x86_compat_isa (unsigned int bitmask)
18905{
18906 while (bitmask)
18907 {
18908 unsigned int bit = bitmask & (- bitmask);
18909
18910 bitmask &= ~ bit;
18911 switch (bit)
18912 {
18913 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
18914 printf ("i486");
18915 break;
18916 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
18917 printf ("586");
18918 break;
18919 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
18920 printf ("686");
18921 break;
18922 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
18923 printf ("SSE");
18924 break;
18925 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
18926 printf ("SSE2");
18927 break;
18928 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
18929 printf ("SSE3");
18930 break;
18931 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
18932 printf ("SSSE3");
18933 break;
18934 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
18935 printf ("SSE4_1");
18936 break;
18937 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
18938 printf ("SSE4_2");
18939 break;
18940 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
18941 printf ("AVX");
18942 break;
18943 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
18944 printf ("AVX2");
18945 break;
18946 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
18947 printf ("AVX512F");
18948 break;
18949 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
18950 printf ("AVX512CD");
18951 break;
18952 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
18953 printf ("AVX512ER");
18954 break;
18955 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
18956 printf ("AVX512PF");
18957 break;
18958 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
18959 printf ("AVX512VL");
18960 break;
18961 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
18962 printf ("AVX512DQ");
18963 break;
18964 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
18965 printf ("AVX512BW");
18966 break;
65b3d26e
L
18967 default:
18968 printf (_("<unknown: %x>"), bit);
18969 break;
a9eafb08
L
18970 }
18971 if (bitmask)
18972 printf (", ");
18973 }
18974}
18975
9ef920e9 18976static void
32930e4e 18977decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 18978{
0a59decb 18979 if (!bitmask)
90c745dc
L
18980 {
18981 printf (_("<None>"));
18982 return;
18983 }
90c745dc 18984
9ef920e9
NC
18985 while (bitmask)
18986 {
1fc87489 18987 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
18988
18989 bitmask &= ~ bit;
18990 switch (bit)
18991 {
32930e4e 18992 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
18993 printf ("CMOV");
18994 break;
32930e4e 18995 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
18996 printf ("SSE");
18997 break;
32930e4e 18998 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
18999 printf ("SSE2");
19000 break;
32930e4e 19001 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19002 printf ("SSE3");
19003 break;
32930e4e 19004 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19005 printf ("SSSE3");
19006 break;
32930e4e 19007 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19008 printf ("SSE4_1");
19009 break;
32930e4e 19010 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19011 printf ("SSE4_2");
19012 break;
32930e4e 19013 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19014 printf ("AVX");
19015 break;
32930e4e 19016 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19017 printf ("AVX2");
19018 break;
32930e4e 19019 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19020 printf ("FMA");
19021 break;
32930e4e 19022 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19023 printf ("AVX512F");
19024 break;
32930e4e 19025 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19026 printf ("AVX512CD");
19027 break;
32930e4e 19028 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19029 printf ("AVX512ER");
19030 break;
32930e4e 19031 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19032 printf ("AVX512PF");
19033 break;
32930e4e 19034 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19035 printf ("AVX512VL");
19036 break;
32930e4e 19037 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19038 printf ("AVX512DQ");
19039 break;
32930e4e 19040 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19041 printf ("AVX512BW");
19042 break;
32930e4e 19043 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19044 printf ("AVX512_4FMAPS");
19045 break;
32930e4e 19046 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19047 printf ("AVX512_4VNNIW");
19048 break;
32930e4e 19049 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19050 printf ("AVX512_BITALG");
19051 break;
32930e4e 19052 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19053 printf ("AVX512_IFMA");
19054 break;
32930e4e 19055 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19056 printf ("AVX512_VBMI");
19057 break;
32930e4e 19058 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19059 printf ("AVX512_VBMI2");
19060 break;
32930e4e 19061 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19062 printf ("AVX512_VNNI");
19063 break;
32930e4e 19064 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19065 printf ("AVX512_BF16");
19066 break;
65b3d26e
L
19067 default:
19068 printf (_("<unknown: %x>"), bit);
19069 break;
9ef920e9
NC
19070 }
19071 if (bitmask)
19072 printf (", ");
19073 }
19074}
19075
32930e4e
L
19076static void
19077decode_x86_isa (unsigned int bitmask)
19078{
32930e4e
L
19079 while (bitmask)
19080 {
19081 unsigned int bit = bitmask & (- bitmask);
19082
19083 bitmask &= ~ bit;
19084 switch (bit)
19085 {
b0ab0693
L
19086 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19087 printf ("x86-64-baseline");
19088 break;
32930e4e
L
19089 case GNU_PROPERTY_X86_ISA_1_V2:
19090 printf ("x86-64-v2");
19091 break;
19092 case GNU_PROPERTY_X86_ISA_1_V3:
19093 printf ("x86-64-v3");
19094 break;
19095 case GNU_PROPERTY_X86_ISA_1_V4:
19096 printf ("x86-64-v4");
19097 break;
19098 default:
19099 printf (_("<unknown: %x>"), bit);
19100 break;
19101 }
19102 if (bitmask)
19103 printf (", ");
19104 }
19105}
19106
ee2fdd6f 19107static void
a9eafb08 19108decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19109{
0a59decb 19110 if (!bitmask)
90c745dc
L
19111 {
19112 printf (_("<None>"));
19113 return;
19114 }
90c745dc 19115
ee2fdd6f
L
19116 while (bitmask)
19117 {
19118 unsigned int bit = bitmask & (- bitmask);
19119
19120 bitmask &= ~ bit;
19121 switch (bit)
19122 {
19123 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19124 printf ("IBT");
ee2fdd6f 19125 break;
48580982 19126 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19127 printf ("SHSTK");
48580982 19128 break;
279d901e
L
19129 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19130 printf ("LAM_U48");
19131 break;
19132 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19133 printf ("LAM_U57");
19134 break;
ee2fdd6f
L
19135 default:
19136 printf (_("<unknown: %x>"), bit);
19137 break;
19138 }
19139 if (bitmask)
19140 printf (", ");
19141 }
19142}
19143
a9eafb08
L
19144static void
19145decode_x86_feature_2 (unsigned int bitmask)
19146{
0a59decb 19147 if (!bitmask)
90c745dc
L
19148 {
19149 printf (_("<None>"));
19150 return;
19151 }
90c745dc 19152
a9eafb08
L
19153 while (bitmask)
19154 {
19155 unsigned int bit = bitmask & (- bitmask);
19156
19157 bitmask &= ~ bit;
19158 switch (bit)
19159 {
19160 case GNU_PROPERTY_X86_FEATURE_2_X86:
19161 printf ("x86");
19162 break;
19163 case GNU_PROPERTY_X86_FEATURE_2_X87:
19164 printf ("x87");
19165 break;
19166 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19167 printf ("MMX");
19168 break;
19169 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19170 printf ("XMM");
19171 break;
19172 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19173 printf ("YMM");
19174 break;
19175 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19176 printf ("ZMM");
19177 break;
a308b89d
L
19178 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19179 printf ("TMM");
19180 break;
32930e4e
L
19181 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19182 printf ("MASK");
19183 break;
a9eafb08
L
19184 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19185 printf ("FXSR");
19186 break;
19187 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19188 printf ("XSAVE");
19189 break;
19190 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19191 printf ("XSAVEOPT");
19192 break;
19193 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19194 printf ("XSAVEC");
19195 break;
65b3d26e
L
19196 default:
19197 printf (_("<unknown: %x>"), bit);
19198 break;
a9eafb08
L
19199 }
19200 if (bitmask)
19201 printf (", ");
19202 }
19203}
19204
cd702818
SD
19205static void
19206decode_aarch64_feature_1_and (unsigned int bitmask)
19207{
19208 while (bitmask)
19209 {
19210 unsigned int bit = bitmask & (- bitmask);
19211
19212 bitmask &= ~ bit;
19213 switch (bit)
19214 {
19215 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19216 printf ("BTI");
19217 break;
19218
19219 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19220 printf ("PAC");
19221 break;
19222
19223 default:
19224 printf (_("<unknown: %x>"), bit);
19225 break;
19226 }
19227 if (bitmask)
19228 printf (", ");
19229 }
19230}
19231
9ef920e9 19232static void
dda8d76d 19233print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19234{
19235 unsigned char * ptr = (unsigned char *) pnote->descdata;
19236 unsigned char * ptr_end = ptr + pnote->descsz;
19237 unsigned int size = is_32bit_elf ? 4 : 8;
19238
19239 printf (_(" Properties: "));
19240
1fc87489 19241 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19242 {
19243 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19244 return;
19245 }
19246
6ab2c4ed 19247 while (ptr < ptr_end)
9ef920e9 19248 {
1fc87489 19249 unsigned int j;
6ab2c4ed
MC
19250 unsigned int type;
19251 unsigned int datasz;
19252
19253 if ((size_t) (ptr_end - ptr) < 8)
19254 {
19255 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19256 break;
19257 }
19258
19259 type = byte_get (ptr, 4);
19260 datasz = byte_get (ptr + 4, 4);
9ef920e9 19261
1fc87489 19262 ptr += 8;
9ef920e9 19263
6ab2c4ed 19264 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19265 {
1fc87489
L
19266 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19267 type, datasz);
9ef920e9 19268 break;
1fc87489 19269 }
9ef920e9 19270
1fc87489
L
19271 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19272 {
dda8d76d
NC
19273 if (filedata->file_header.e_machine == EM_X86_64
19274 || filedata->file_header.e_machine == EM_IAMCU
19275 || filedata->file_header.e_machine == EM_386)
1fc87489 19276 {
aa7bca9b
L
19277 unsigned int bitmask;
19278
19279 if (datasz == 4)
0a59decb 19280 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19281 else
19282 bitmask = 0;
19283
1fc87489
L
19284 switch (type)
19285 {
19286 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19287 if (datasz != 4)
aa7bca9b
L
19288 printf (_("x86 ISA used: <corrupt length: %#x> "),
19289 datasz);
1fc87489 19290 else
aa7bca9b
L
19291 {
19292 printf ("x86 ISA used: ");
19293 decode_x86_isa (bitmask);
19294 }
1fc87489 19295 goto next;
9ef920e9 19296
1fc87489 19297 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19298 if (datasz != 4)
aa7bca9b
L
19299 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19300 datasz);
1fc87489 19301 else
aa7bca9b
L
19302 {
19303 printf ("x86 ISA needed: ");
19304 decode_x86_isa (bitmask);
19305 }
1fc87489 19306 goto next;
9ef920e9 19307
ee2fdd6f 19308 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19309 if (datasz != 4)
aa7bca9b
L
19310 printf (_("x86 feature: <corrupt length: %#x> "),
19311 datasz);
ee2fdd6f 19312 else
aa7bca9b
L
19313 {
19314 printf ("x86 feature: ");
a9eafb08
L
19315 decode_x86_feature_1 (bitmask);
19316 }
19317 goto next;
19318
19319 case GNU_PROPERTY_X86_FEATURE_2_USED:
19320 if (datasz != 4)
19321 printf (_("x86 feature used: <corrupt length: %#x> "),
19322 datasz);
19323 else
19324 {
19325 printf ("x86 feature used: ");
19326 decode_x86_feature_2 (bitmask);
19327 }
19328 goto next;
19329
19330 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
19331 if (datasz != 4)
19332 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
19333 else
19334 {
19335 printf ("x86 feature needed: ");
19336 decode_x86_feature_2 (bitmask);
19337 }
19338 goto next;
19339
19340 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
19341 if (datasz != 4)
19342 printf (_("x86 ISA used: <corrupt length: %#x> "),
19343 datasz);
19344 else
19345 {
19346 printf ("x86 ISA used: ");
19347 decode_x86_compat_isa (bitmask);
19348 }
19349 goto next;
19350
19351 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
19352 if (datasz != 4)
19353 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19354 datasz);
19355 else
19356 {
19357 printf ("x86 ISA needed: ");
19358 decode_x86_compat_isa (bitmask);
aa7bca9b 19359 }
ee2fdd6f
L
19360 goto next;
19361
32930e4e
L
19362 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
19363 if (datasz != 4)
19364 printf (_("x86 ISA used: <corrupt length: %#x> "),
19365 datasz);
19366 else
19367 {
19368 printf ("x86 ISA used: ");
19369 decode_x86_compat_2_isa (bitmask);
19370 }
19371 goto next;
19372
19373 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
19374 if (datasz != 4)
19375 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19376 datasz);
19377 else
19378 {
19379 printf ("x86 ISA needed: ");
19380 decode_x86_compat_2_isa (bitmask);
19381 }
19382 goto next;
19383
1fc87489
L
19384 default:
19385 break;
19386 }
19387 }
cd702818
SD
19388 else if (filedata->file_header.e_machine == EM_AARCH64)
19389 {
19390 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
19391 {
19392 printf ("AArch64 feature: ");
19393 if (datasz != 4)
19394 printf (_("<corrupt length: %#x> "), datasz);
19395 else
19396 decode_aarch64_feature_1_and (byte_get (ptr, 4));
19397 goto next;
19398 }
19399 }
1fc87489
L
19400 }
19401 else
19402 {
19403 switch (type)
9ef920e9 19404 {
1fc87489
L
19405 case GNU_PROPERTY_STACK_SIZE:
19406 printf (_("stack size: "));
19407 if (datasz != size)
19408 printf (_("<corrupt length: %#x> "), datasz);
19409 else
19410 printf ("%#lx", (unsigned long) byte_get (ptr, size));
19411 goto next;
19412
19413 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
19414 printf ("no copy on protected ");
19415 if (datasz)
19416 printf (_("<corrupt length: %#x> "), datasz);
19417 goto next;
19418
19419 default:
9ef920e9
NC
19420 break;
19421 }
9ef920e9
NC
19422 }
19423
1fc87489
L
19424 if (type < GNU_PROPERTY_LOPROC)
19425 printf (_("<unknown type %#x data: "), type);
19426 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 19427 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
19428 else
19429 printf (_("<application-specific type %#x data: "), type);
19430 for (j = 0; j < datasz; ++j)
19431 printf ("%02x ", ptr[j] & 0xff);
19432 printf (">");
19433
dc1e8a47 19434 next:
9ef920e9 19435 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
19436 if (ptr == ptr_end)
19437 break;
1fc87489 19438
6ab2c4ed
MC
19439 if (do_wide)
19440 printf (", ");
19441 else
19442 printf ("\n\t");
9ef920e9
NC
19443 }
19444
19445 printf ("\n");
19446}
19447
015dc7e1 19448static bool
dda8d76d 19449print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 19450{
1449284b 19451 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
19452 switch (pnote->type)
19453 {
19454 case NT_GNU_BUILD_ID:
19455 {
19456 unsigned long i;
19457
19458 printf (_(" Build ID: "));
19459 for (i = 0; i < pnote->descsz; ++i)
19460 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 19461 printf ("\n");
664f90a3
TT
19462 }
19463 break;
19464
19465 case NT_GNU_ABI_TAG:
19466 {
19467 unsigned long os, major, minor, subminor;
19468 const char *osname;
19469
3102e897
NC
19470 /* PR 17531: file: 030-599401-0.004. */
19471 if (pnote->descsz < 16)
19472 {
19473 printf (_(" <corrupt GNU_ABI_TAG>\n"));
19474 break;
19475 }
19476
664f90a3
TT
19477 os = byte_get ((unsigned char *) pnote->descdata, 4);
19478 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19479 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
19480 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
19481
19482 switch (os)
19483 {
19484 case GNU_ABI_TAG_LINUX:
19485 osname = "Linux";
19486 break;
19487 case GNU_ABI_TAG_HURD:
19488 osname = "Hurd";
19489 break;
19490 case GNU_ABI_TAG_SOLARIS:
19491 osname = "Solaris";
19492 break;
19493 case GNU_ABI_TAG_FREEBSD:
19494 osname = "FreeBSD";
19495 break;
19496 case GNU_ABI_TAG_NETBSD:
19497 osname = "NetBSD";
19498 break;
14ae95f2
RM
19499 case GNU_ABI_TAG_SYLLABLE:
19500 osname = "Syllable";
19501 break;
19502 case GNU_ABI_TAG_NACL:
19503 osname = "NaCl";
19504 break;
664f90a3
TT
19505 default:
19506 osname = "Unknown";
19507 break;
19508 }
19509
19510 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
19511 major, minor, subminor);
19512 }
19513 break;
926c5385
CC
19514
19515 case NT_GNU_GOLD_VERSION:
19516 {
19517 unsigned long i;
19518
19519 printf (_(" Version: "));
19520 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
19521 printf ("%c", pnote->descdata[i]);
19522 printf ("\n");
19523 }
19524 break;
1449284b
NC
19525
19526 case NT_GNU_HWCAP:
19527 {
19528 unsigned long num_entries, mask;
19529
19530 /* Hardware capabilities information. Word 0 is the number of entries.
19531 Word 1 is a bitmask of enabled entries. The rest of the descriptor
19532 is a series of entries, where each entry is a single byte followed
19533 by a nul terminated string. The byte gives the bit number to test
19534 if enabled in the bitmask. */
19535 printf (_(" Hardware Capabilities: "));
19536 if (pnote->descsz < 8)
19537 {
32ec8896 19538 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 19539 return false;
1449284b
NC
19540 }
19541 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
19542 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19543 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
19544 /* FIXME: Add code to display the entries... */
19545 }
19546 break;
19547
9ef920e9 19548 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 19549 print_gnu_property_note (filedata, pnote);
9ef920e9 19550 break;
9abca702 19551
1449284b
NC
19552 default:
19553 /* Handle unrecognised types. An error message should have already been
19554 created by get_gnu_elf_note_type(), so all that we need to do is to
19555 display the data. */
19556 {
19557 unsigned long i;
19558
19559 printf (_(" Description data: "));
19560 for (i = 0; i < pnote->descsz; ++i)
19561 printf ("%02x ", pnote->descdata[i] & 0xff);
19562 printf ("\n");
19563 }
19564 break;
664f90a3
TT
19565 }
19566
015dc7e1 19567 return true;
664f90a3
TT
19568}
19569
685080f2
NC
19570static const char *
19571get_v850_elf_note_type (enum v850_notes n_type)
19572{
19573 static char buff[64];
19574
19575 switch (n_type)
19576 {
19577 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
19578 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
19579 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
19580 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
19581 case V850_NOTE_CACHE_INFO: return _("Use of cache");
19582 case V850_NOTE_MMU_INFO: return _("Use of MMU");
19583 default:
19584 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
19585 return buff;
19586 }
19587}
19588
015dc7e1 19589static bool
685080f2
NC
19590print_v850_note (Elf_Internal_Note * pnote)
19591{
19592 unsigned int val;
19593
19594 if (pnote->descsz != 4)
015dc7e1 19595 return false;
32ec8896 19596
685080f2
NC
19597 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
19598
19599 if (val == 0)
19600 {
19601 printf (_("not set\n"));
015dc7e1 19602 return true;
685080f2
NC
19603 }
19604
19605 switch (pnote->type)
19606 {
19607 case V850_NOTE_ALIGNMENT:
19608 switch (val)
19609 {
015dc7e1
AM
19610 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
19611 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
19612 }
19613 break;
14ae95f2 19614
685080f2
NC
19615 case V850_NOTE_DATA_SIZE:
19616 switch (val)
19617 {
015dc7e1
AM
19618 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
19619 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
19620 }
19621 break;
14ae95f2 19622
685080f2
NC
19623 case V850_NOTE_FPU_INFO:
19624 switch (val)
19625 {
015dc7e1
AM
19626 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
19627 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
19628 }
19629 break;
14ae95f2 19630
685080f2
NC
19631 case V850_NOTE_MMU_INFO:
19632 case V850_NOTE_CACHE_INFO:
19633 case V850_NOTE_SIMD_INFO:
19634 if (val == EF_RH850_SIMD)
19635 {
19636 printf (_("yes\n"));
015dc7e1 19637 return true;
685080f2
NC
19638 }
19639 break;
19640
19641 default:
19642 /* An 'unknown note type' message will already have been displayed. */
19643 break;
19644 }
19645
19646 printf (_("unknown value: %x\n"), val);
015dc7e1 19647 return false;
685080f2
NC
19648}
19649
015dc7e1 19650static bool
c6056a74
SF
19651process_netbsd_elf_note (Elf_Internal_Note * pnote)
19652{
19653 unsigned int version;
19654
19655 switch (pnote->type)
19656 {
19657 case NT_NETBSD_IDENT:
b966f55f
AM
19658 if (pnote->descsz < 1)
19659 break;
c6056a74
SF
19660 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19661 if ((version / 10000) % 100)
b966f55f 19662 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
19663 version, version / 100000000, (version / 1000000) % 100,
19664 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 19665 'A' + (version / 10000) % 26);
c6056a74
SF
19666 else
19667 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 19668 version, version / 100000000, (version / 1000000) % 100,
15f205b1 19669 (version / 100) % 100);
015dc7e1 19670 return true;
c6056a74
SF
19671
19672 case NT_NETBSD_MARCH:
9abca702 19673 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 19674 pnote->descdata);
015dc7e1 19675 return true;
c6056a74 19676
9abca702 19677 case NT_NETBSD_PAX:
b966f55f
AM
19678 if (pnote->descsz < 1)
19679 break;
9abca702
CZ
19680 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19681 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
19682 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
19683 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
19684 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
19685 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
19686 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
19687 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 19688 return true;
c6056a74 19689 }
b966f55f
AM
19690
19691 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
19692 pnote->descsz, pnote->type);
015dc7e1 19693 return false;
c6056a74
SF
19694}
19695
f4ddf30f 19696static const char *
dda8d76d 19697get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 19698{
f4ddf30f
JB
19699 switch (e_type)
19700 {
19701 case NT_FREEBSD_THRMISC:
19702 return _("NT_THRMISC (thrmisc structure)");
19703 case NT_FREEBSD_PROCSTAT_PROC:
19704 return _("NT_PROCSTAT_PROC (proc data)");
19705 case NT_FREEBSD_PROCSTAT_FILES:
19706 return _("NT_PROCSTAT_FILES (files data)");
19707 case NT_FREEBSD_PROCSTAT_VMMAP:
19708 return _("NT_PROCSTAT_VMMAP (vmmap data)");
19709 case NT_FREEBSD_PROCSTAT_GROUPS:
19710 return _("NT_PROCSTAT_GROUPS (groups data)");
19711 case NT_FREEBSD_PROCSTAT_UMASK:
19712 return _("NT_PROCSTAT_UMASK (umask data)");
19713 case NT_FREEBSD_PROCSTAT_RLIMIT:
19714 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
19715 case NT_FREEBSD_PROCSTAT_OSREL:
19716 return _("NT_PROCSTAT_OSREL (osreldate data)");
19717 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
19718 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
19719 case NT_FREEBSD_PROCSTAT_AUXV:
19720 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
19721 case NT_FREEBSD_PTLWPINFO:
19722 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 19723 }
dda8d76d 19724 return get_note_type (filedata, e_type);
f4ddf30f
JB
19725}
19726
9437c45b 19727static const char *
dda8d76d 19728get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
19729{
19730 static char buff[64];
19731
540e6170
CZ
19732 switch (e_type)
19733 {
19734 case NT_NETBSDCORE_PROCINFO:
19735 /* NetBSD core "procinfo" structure. */
19736 return _("NetBSD procinfo structure");
9437c45b 19737
540e6170
CZ
19738 case NT_NETBSDCORE_AUXV:
19739 return _("NetBSD ELF auxiliary vector data");
9437c45b 19740
06d949ec
KR
19741 case NT_NETBSDCORE_LWPSTATUS:
19742 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 19743
540e6170 19744 default:
06d949ec 19745 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
19746 defined for NetBSD core files. If the note type is less
19747 than the start of the machine-dependent note types, we don't
19748 understand it. */
19749
19750 if (e_type < NT_NETBSDCORE_FIRSTMACH)
19751 {
19752 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19753 return buff;
19754 }
19755 break;
9437c45b
JT
19756 }
19757
dda8d76d 19758 switch (filedata->file_header.e_machine)
9437c45b
JT
19759 {
19760 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
19761 and PT_GETFPREGS == mach+2. */
19762
19763 case EM_OLD_ALPHA:
19764 case EM_ALPHA:
19765 case EM_SPARC:
19766 case EM_SPARC32PLUS:
19767 case EM_SPARCV9:
19768 switch (e_type)
19769 {
2b692964 19770 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 19771 return _("PT_GETREGS (reg structure)");
2b692964 19772 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 19773 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19774 default:
19775 break;
19776 }
19777 break;
19778
c0d38b0e
CZ
19779 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
19780 There's also old PT___GETREGS40 == mach + 1 for old reg
19781 structure which lacks GBR. */
19782 case EM_SH:
19783 switch (e_type)
19784 {
19785 case NT_NETBSDCORE_FIRSTMACH + 1:
19786 return _("PT___GETREGS40 (old reg structure)");
19787 case NT_NETBSDCORE_FIRSTMACH + 3:
19788 return _("PT_GETREGS (reg structure)");
19789 case NT_NETBSDCORE_FIRSTMACH + 5:
19790 return _("PT_GETFPREGS (fpreg structure)");
19791 default:
19792 break;
19793 }
19794 break;
19795
9437c45b
JT
19796 /* On all other arch's, PT_GETREGS == mach+1 and
19797 PT_GETFPREGS == mach+3. */
19798 default:
19799 switch (e_type)
19800 {
2b692964 19801 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 19802 return _("PT_GETREGS (reg structure)");
2b692964 19803 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 19804 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19805 default:
19806 break;
19807 }
19808 }
19809
9cf03b7e 19810 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 19811 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
19812 return buff;
19813}
19814
70616151
TT
19815static const char *
19816get_stapsdt_note_type (unsigned e_type)
19817{
19818 static char buff[64];
19819
19820 switch (e_type)
19821 {
19822 case NT_STAPSDT:
19823 return _("NT_STAPSDT (SystemTap probe descriptors)");
19824
19825 default:
19826 break;
19827 }
19828
19829 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19830 return buff;
19831}
19832
015dc7e1 19833static bool
c6a9fc58
TT
19834print_stapsdt_note (Elf_Internal_Note *pnote)
19835{
3ca60c57
NC
19836 size_t len, maxlen;
19837 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
19838 char *data = pnote->descdata;
19839 char *data_end = pnote->descdata + pnote->descsz;
19840 bfd_vma pc, base_addr, semaphore;
19841 char *provider, *probe, *arg_fmt;
19842
3ca60c57
NC
19843 if (pnote->descsz < (addr_size * 3))
19844 goto stapdt_note_too_small;
19845
c6a9fc58
TT
19846 pc = byte_get ((unsigned char *) data, addr_size);
19847 data += addr_size;
3ca60c57 19848
c6a9fc58
TT
19849 base_addr = byte_get ((unsigned char *) data, addr_size);
19850 data += addr_size;
3ca60c57 19851
c6a9fc58
TT
19852 semaphore = byte_get ((unsigned char *) data, addr_size);
19853 data += addr_size;
19854
3ca60c57
NC
19855 if (data >= data_end)
19856 goto stapdt_note_too_small;
19857 maxlen = data_end - data;
19858 len = strnlen (data, maxlen);
19859 if (len < maxlen)
19860 {
19861 provider = data;
19862 data += len + 1;
19863 }
19864 else
19865 goto stapdt_note_too_small;
19866
19867 if (data >= data_end)
19868 goto stapdt_note_too_small;
19869 maxlen = data_end - data;
19870 len = strnlen (data, maxlen);
19871 if (len < maxlen)
19872 {
19873 probe = data;
19874 data += len + 1;
19875 }
19876 else
19877 goto stapdt_note_too_small;
9abca702 19878
3ca60c57
NC
19879 if (data >= data_end)
19880 goto stapdt_note_too_small;
19881 maxlen = data_end - data;
19882 len = strnlen (data, maxlen);
19883 if (len < maxlen)
19884 {
19885 arg_fmt = data;
19886 data += len + 1;
19887 }
19888 else
19889 goto stapdt_note_too_small;
c6a9fc58
TT
19890
19891 printf (_(" Provider: %s\n"), provider);
19892 printf (_(" Name: %s\n"), probe);
19893 printf (_(" Location: "));
19894 print_vma (pc, FULL_HEX);
19895 printf (_(", Base: "));
19896 print_vma (base_addr, FULL_HEX);
19897 printf (_(", Semaphore: "));
19898 print_vma (semaphore, FULL_HEX);
9cf03b7e 19899 printf ("\n");
c6a9fc58
TT
19900 printf (_(" Arguments: %s\n"), arg_fmt);
19901
19902 return data == data_end;
3ca60c57
NC
19903
19904 stapdt_note_too_small:
19905 printf (_(" <corrupt - note is too small>\n"));
19906 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 19907 return false;
c6a9fc58
TT
19908}
19909
00e98fc7
TG
19910static const char *
19911get_ia64_vms_note_type (unsigned e_type)
19912{
19913 static char buff[64];
19914
19915 switch (e_type)
19916 {
19917 case NT_VMS_MHD:
19918 return _("NT_VMS_MHD (module header)");
19919 case NT_VMS_LNM:
19920 return _("NT_VMS_LNM (language name)");
19921 case NT_VMS_SRC:
19922 return _("NT_VMS_SRC (source files)");
19923 case NT_VMS_TITLE:
9cf03b7e 19924 return "NT_VMS_TITLE";
00e98fc7
TG
19925 case NT_VMS_EIDC:
19926 return _("NT_VMS_EIDC (consistency check)");
19927 case NT_VMS_FPMODE:
19928 return _("NT_VMS_FPMODE (FP mode)");
19929 case NT_VMS_LINKTIME:
9cf03b7e 19930 return "NT_VMS_LINKTIME";
00e98fc7
TG
19931 case NT_VMS_IMGNAM:
19932 return _("NT_VMS_IMGNAM (image name)");
19933 case NT_VMS_IMGID:
19934 return _("NT_VMS_IMGID (image id)");
19935 case NT_VMS_LINKID:
19936 return _("NT_VMS_LINKID (link id)");
19937 case NT_VMS_IMGBID:
19938 return _("NT_VMS_IMGBID (build id)");
19939 case NT_VMS_GSTNAM:
19940 return _("NT_VMS_GSTNAM (sym table name)");
19941 case NT_VMS_ORIG_DYN:
9cf03b7e 19942 return "NT_VMS_ORIG_DYN";
00e98fc7 19943 case NT_VMS_PATCHTIME:
9cf03b7e 19944 return "NT_VMS_PATCHTIME";
00e98fc7
TG
19945 default:
19946 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19947 return buff;
19948 }
19949}
19950
015dc7e1 19951static bool
00e98fc7
TG
19952print_ia64_vms_note (Elf_Internal_Note * pnote)
19953{
8d18bf79
NC
19954 int maxlen = pnote->descsz;
19955
19956 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
19957 goto desc_size_fail;
19958
00e98fc7
TG
19959 switch (pnote->type)
19960 {
19961 case NT_VMS_MHD:
8d18bf79
NC
19962 if (maxlen <= 36)
19963 goto desc_size_fail;
19964
19965 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
19966
19967 printf (_(" Creation date : %.17s\n"), pnote->descdata);
19968 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
19969 if (l + 34 < maxlen)
19970 {
19971 printf (_(" Module name : %s\n"), pnote->descdata + 34);
19972 if (l + 35 < maxlen)
19973 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
19974 else
19975 printf (_(" Module version : <missing>\n"));
19976 }
00e98fc7 19977 else
8d18bf79
NC
19978 {
19979 printf (_(" Module name : <missing>\n"));
19980 printf (_(" Module version : <missing>\n"));
19981 }
00e98fc7 19982 break;
8d18bf79 19983
00e98fc7 19984 case NT_VMS_LNM:
8d18bf79 19985 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19986 break;
8d18bf79 19987
00e98fc7
TG
19988#ifdef BFD64
19989 case NT_VMS_FPMODE:
9cf03b7e 19990 printf (_(" Floating Point mode: "));
8d18bf79
NC
19991 if (maxlen < 8)
19992 goto desc_size_fail;
19993 /* FIXME: Generate an error if descsz > 8 ? */
19994
4a5cb34f 19995 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 19996 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 19997 break;
8d18bf79 19998
00e98fc7
TG
19999 case NT_VMS_LINKTIME:
20000 printf (_(" Link time: "));
8d18bf79
NC
20001 if (maxlen < 8)
20002 goto desc_size_fail;
20003 /* FIXME: Generate an error if descsz > 8 ? */
20004
00e98fc7 20005 print_vms_time
8d18bf79 20006 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20007 printf ("\n");
20008 break;
8d18bf79 20009
00e98fc7
TG
20010 case NT_VMS_PATCHTIME:
20011 printf (_(" Patch time: "));
8d18bf79
NC
20012 if (maxlen < 8)
20013 goto desc_size_fail;
20014 /* FIXME: Generate an error if descsz > 8 ? */
20015
00e98fc7 20016 print_vms_time
8d18bf79 20017 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20018 printf ("\n");
20019 break;
8d18bf79 20020
00e98fc7 20021 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20022 if (maxlen < 34)
20023 goto desc_size_fail;
20024
00e98fc7
TG
20025 printf (_(" Major id: %u, minor id: %u\n"),
20026 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
20027 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 20028 printf (_(" Last modified : "));
00e98fc7
TG
20029 print_vms_time
20030 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 20031 printf (_("\n Link flags : "));
4a5cb34f 20032 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 20033 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 20034 printf (_(" Header flags: 0x%08x\n"),
948f632f 20035 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 20036 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
20037 break;
20038#endif
8d18bf79 20039
00e98fc7 20040 case NT_VMS_IMGNAM:
8d18bf79 20041 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20042 break;
8d18bf79 20043
00e98fc7 20044 case NT_VMS_GSTNAM:
8d18bf79 20045 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20046 break;
8d18bf79 20047
00e98fc7 20048 case NT_VMS_IMGID:
8d18bf79 20049 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20050 break;
8d18bf79 20051
00e98fc7 20052 case NT_VMS_LINKID:
8d18bf79 20053 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20054 break;
8d18bf79 20055
00e98fc7 20056 default:
015dc7e1 20057 return false;
00e98fc7 20058 }
8d18bf79 20059
015dc7e1 20060 return true;
8d18bf79
NC
20061
20062 desc_size_fail:
20063 printf (_(" <corrupt - data size is too small>\n"));
20064 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20065 return false;
00e98fc7
TG
20066}
20067
fd486f32
AM
20068struct build_attr_cache {
20069 Filedata *filedata;
20070 char *strtab;
20071 unsigned long strtablen;
20072 Elf_Internal_Sym *symtab;
20073 unsigned long nsyms;
20074} ba_cache;
20075
6f156d7a
NC
20076/* Find the symbol associated with a build attribute that is attached
20077 to address OFFSET. If PNAME is non-NULL then store the name of
20078 the symbol (if found) in the provided pointer, Returns NULL if a
20079 symbol could not be found. */
c799a79d 20080
6f156d7a 20081static Elf_Internal_Sym *
015dc7e1
AM
20082get_symbol_for_build_attribute (Filedata *filedata,
20083 unsigned long offset,
20084 bool is_open_attr,
20085 const char **pname)
9ef920e9 20086{
fd486f32
AM
20087 Elf_Internal_Sym *saved_sym = NULL;
20088 Elf_Internal_Sym *sym;
9ef920e9 20089
dda8d76d 20090 if (filedata->section_headers != NULL
fd486f32 20091 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20092 {
c799a79d 20093 Elf_Internal_Shdr * symsec;
9ef920e9 20094
fd486f32
AM
20095 free (ba_cache.strtab);
20096 ba_cache.strtab = NULL;
20097 free (ba_cache.symtab);
20098 ba_cache.symtab = NULL;
20099
c799a79d 20100 /* Load the symbol and string sections. */
dda8d76d
NC
20101 for (symsec = filedata->section_headers;
20102 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20103 symsec ++)
9ef920e9 20104 {
28d13567
AM
20105 if (symsec->sh_type == SHT_SYMTAB
20106 && get_symtab (filedata, symsec,
20107 &ba_cache.symtab, &ba_cache.nsyms,
20108 &ba_cache.strtab, &ba_cache.strtablen))
20109 break;
9ef920e9 20110 }
fd486f32 20111 ba_cache.filedata = filedata;
9ef920e9
NC
20112 }
20113
fd486f32 20114 if (ba_cache.symtab == NULL)
6f156d7a 20115 return NULL;
9ef920e9 20116
c799a79d 20117 /* Find a symbol whose value matches offset. */
fd486f32 20118 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20119 if (sym->st_value == offset)
20120 {
fd486f32 20121 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20122 /* Huh ? This should not happen. */
20123 continue;
9ef920e9 20124
fd486f32 20125 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20126 continue;
9ef920e9 20127
8fd75781
NC
20128 /* The AArch64 and ARM architectures define mapping symbols
20129 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20130 if (ba_cache.strtab[sym->st_name] == '$'
20131 && ba_cache.strtab[sym->st_name + 1] != 0
20132 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20133 continue;
20134
c799a79d
NC
20135 if (is_open_attr)
20136 {
20137 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20138 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20139 FUNC symbols entirely. */
20140 switch (ELF_ST_TYPE (sym->st_info))
20141 {
c799a79d 20142 case STT_OBJECT:
6f156d7a 20143 case STT_FILE:
c799a79d 20144 saved_sym = sym;
6f156d7a
NC
20145 if (sym->st_size)
20146 {
20147 /* If the symbol has a size associated
20148 with it then we can stop searching. */
fd486f32 20149 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20150 }
c799a79d 20151 continue;
9ef920e9 20152
c799a79d
NC
20153 case STT_FUNC:
20154 /* Ignore function symbols. */
20155 continue;
20156
20157 default:
20158 break;
20159 }
20160
20161 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20162 {
c799a79d
NC
20163 case STB_GLOBAL:
20164 if (saved_sym == NULL
20165 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20166 saved_sym = sym;
20167 break;
c871dade 20168
c799a79d
NC
20169 case STB_LOCAL:
20170 if (saved_sym == NULL)
20171 saved_sym = sym;
20172 break;
20173
20174 default:
9ef920e9
NC
20175 break;
20176 }
20177 }
c799a79d
NC
20178 else
20179 {
20180 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20181 continue;
20182
20183 saved_sym = sym;
20184 break;
20185 }
20186 }
20187
6f156d7a 20188 if (saved_sym && pname)
fd486f32 20189 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20190
20191 return saved_sym;
c799a79d
NC
20192}
20193
d20e98ab
NC
20194/* Returns true iff addr1 and addr2 are in the same section. */
20195
015dc7e1 20196static bool
d20e98ab
NC
20197same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20198{
20199 Elf_Internal_Shdr * a1;
20200 Elf_Internal_Shdr * a2;
20201
20202 a1 = find_section_by_address (filedata, addr1);
20203 a2 = find_section_by_address (filedata, addr2);
9abca702 20204
d20e98ab
NC
20205 return a1 == a2 && a1 != NULL;
20206}
20207
015dc7e1 20208static bool
dda8d76d
NC
20209print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20210 Filedata * filedata)
c799a79d 20211{
015dc7e1
AM
20212 static unsigned long global_offset = 0;
20213 static unsigned long global_end = 0;
20214 static unsigned long func_offset = 0;
20215 static unsigned long func_end = 0;
c871dade 20216
015dc7e1
AM
20217 Elf_Internal_Sym *sym;
20218 const char *name;
20219 unsigned long start;
20220 unsigned long end;
20221 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20222
20223 switch (pnote->descsz)
c799a79d 20224 {
6f156d7a
NC
20225 case 0:
20226 /* A zero-length description means that the range of
20227 the previous note of the same type should be used. */
c799a79d 20228 if (is_open_attr)
c871dade 20229 {
6f156d7a
NC
20230 if (global_end > global_offset)
20231 printf (_(" Applies to region from %#lx to %#lx\n"),
20232 global_offset, global_end);
20233 else
20234 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20235 }
20236 else
20237 {
6f156d7a
NC
20238 if (func_end > func_offset)
20239 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20240 else
20241 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20242 }
015dc7e1 20243 return true;
9ef920e9 20244
6f156d7a
NC
20245 case 4:
20246 start = byte_get ((unsigned char *) pnote->descdata, 4);
20247 end = 0;
20248 break;
20249
20250 case 8:
c74147bb
NC
20251 start = byte_get ((unsigned char *) pnote->descdata, 4);
20252 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20253 break;
20254
20255 case 16:
20256 start = byte_get ((unsigned char *) pnote->descdata, 8);
20257 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20258 break;
9abca702 20259
6f156d7a 20260 default:
c799a79d
NC
20261 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
20262 printf (_(" <invalid descsz>"));
015dc7e1 20263 return false;
c799a79d
NC
20264 }
20265
6f156d7a
NC
20266 name = NULL;
20267 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
20268 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
20269 in order to avoid them being confused with the start address of the
20270 first function in the file... */
20271 if (sym == NULL && is_open_attr)
20272 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
20273 & name);
6f156d7a
NC
20274
20275 if (end == 0 && sym != NULL && sym->st_size > 0)
20276 end = start + sym->st_size;
c799a79d
NC
20277
20278 if (is_open_attr)
20279 {
d20e98ab
NC
20280 /* FIXME: Need to properly allow for section alignment.
20281 16 is just the alignment used on x86_64. */
20282 if (global_end > 0
20283 && start > BFD_ALIGN (global_end, 16)
20284 /* Build notes are not guaranteed to be organised in order of
20285 increasing address, but we should find the all of the notes
20286 for one section in the same place. */
20287 && same_section (filedata, start, global_end))
6f156d7a
NC
20288 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
20289 global_end + 1, start - 1);
20290
20291 printf (_(" Applies to region from %#lx"), start);
20292 global_offset = start;
20293
20294 if (end)
20295 {
20296 printf (_(" to %#lx"), end);
20297 global_end = end;
20298 }
c799a79d
NC
20299 }
20300 else
20301 {
6f156d7a
NC
20302 printf (_(" Applies to region from %#lx"), start);
20303 func_offset = start;
20304
20305 if (end)
20306 {
20307 printf (_(" to %#lx"), end);
20308 func_end = end;
20309 }
c799a79d
NC
20310 }
20311
6f156d7a
NC
20312 if (sym && name)
20313 printf (_(" (%s)"), name);
20314
20315 printf ("\n");
015dc7e1 20316 return true;
9ef920e9
NC
20317}
20318
015dc7e1 20319static bool
9ef920e9
NC
20320print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
20321{
1d15e434
NC
20322 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
20323 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
20324 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
20325 char name_type;
20326 char name_attribute;
1d15e434 20327 const char * expected_types;
9ef920e9
NC
20328 const char * name = pnote->namedata;
20329 const char * text;
88305e1b 20330 signed int left;
9ef920e9
NC
20331
20332 if (name == NULL || pnote->namesz < 2)
20333 {
20334 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 20335 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20336 return false;
9ef920e9
NC
20337 }
20338
6f156d7a
NC
20339 if (do_wide)
20340 left = 28;
20341 else
20342 left = 20;
88305e1b
NC
20343
20344 /* Version 2 of the spec adds a "GA" prefix to the name field. */
20345 if (name[0] == 'G' && name[1] == 'A')
20346 {
6f156d7a
NC
20347 if (pnote->namesz < 4)
20348 {
20349 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
20350 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20351 return false;
6f156d7a
NC
20352 }
20353
88305e1b
NC
20354 printf ("GA");
20355 name += 2;
20356 left -= 2;
20357 }
20358
9ef920e9
NC
20359 switch ((name_type = * name))
20360 {
20361 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20362 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20363 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20364 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20365 printf ("%c", * name);
88305e1b 20366 left --;
9ef920e9
NC
20367 break;
20368 default:
20369 error (_("unrecognised attribute type in name field: %d\n"), name_type);
20370 print_symbol (-20, _("<unknown name type>"));
015dc7e1 20371 return false;
9ef920e9
NC
20372 }
20373
9ef920e9
NC
20374 ++ name;
20375 text = NULL;
20376
20377 switch ((name_attribute = * name))
20378 {
20379 case GNU_BUILD_ATTRIBUTE_VERSION:
20380 text = _("<version>");
1d15e434 20381 expected_types = string_expected;
9ef920e9
NC
20382 ++ name;
20383 break;
20384 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20385 text = _("<stack prot>");
75d7d298 20386 expected_types = "!+*";
9ef920e9
NC
20387 ++ name;
20388 break;
20389 case GNU_BUILD_ATTRIBUTE_RELRO:
20390 text = _("<relro>");
1d15e434 20391 expected_types = bool_expected;
9ef920e9
NC
20392 ++ name;
20393 break;
20394 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
20395 text = _("<stack size>");
1d15e434 20396 expected_types = number_expected;
9ef920e9
NC
20397 ++ name;
20398 break;
20399 case GNU_BUILD_ATTRIBUTE_TOOL:
20400 text = _("<tool>");
1d15e434 20401 expected_types = string_expected;
9ef920e9
NC
20402 ++ name;
20403 break;
20404 case GNU_BUILD_ATTRIBUTE_ABI:
20405 text = _("<ABI>");
20406 expected_types = "$*";
20407 ++ name;
20408 break;
20409 case GNU_BUILD_ATTRIBUTE_PIC:
20410 text = _("<PIC>");
1d15e434 20411 expected_types = number_expected;
9ef920e9
NC
20412 ++ name;
20413 break;
a8be5506
NC
20414 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
20415 text = _("<short enum>");
1d15e434 20416 expected_types = bool_expected;
a8be5506
NC
20417 ++ name;
20418 break;
9ef920e9
NC
20419 default:
20420 if (ISPRINT (* name))
20421 {
20422 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
20423
20424 if (len > left && ! do_wide)
20425 len = left;
75d7d298 20426 printf ("%.*s:", len, name);
9ef920e9 20427 left -= len;
0dd6ae21 20428 name += len;
9ef920e9
NC
20429 }
20430 else
20431 {
3e6b6445 20432 static char tmpbuf [128];
88305e1b 20433
3e6b6445
NC
20434 error (_("unrecognised byte in name field: %d\n"), * name);
20435 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
20436 text = tmpbuf;
20437 name ++;
9ef920e9
NC
20438 }
20439 expected_types = "*$!+";
20440 break;
20441 }
20442
20443 if (text)
88305e1b 20444 left -= printf ("%s", text);
9ef920e9
NC
20445
20446 if (strchr (expected_types, name_type) == NULL)
75d7d298 20447 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
20448
20449 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
20450 {
20451 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
20452 (unsigned long) pnote->namesz,
20453 (long) (name - pnote->namedata));
015dc7e1 20454 return false;
9ef920e9
NC
20455 }
20456
20457 if (left < 1 && ! do_wide)
015dc7e1 20458 return true;
9ef920e9
NC
20459
20460 switch (name_type)
20461 {
20462 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20463 {
b06b2c92 20464 unsigned int bytes;
ddef72cd
NC
20465 unsigned long long val = 0;
20466 unsigned int shift = 0;
20467 char * decoded = NULL;
20468
b06b2c92
NC
20469 bytes = pnote->namesz - (name - pnote->namedata);
20470 if (bytes > 0)
20471 /* The -1 is because the name field is always 0 terminated, and we
20472 want to be able to ensure that the shift in the while loop below
20473 will not overflow. */
20474 -- bytes;
20475
ddef72cd
NC
20476 if (bytes > sizeof (val))
20477 {
3e6b6445
NC
20478 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
20479 bytes);
20480 bytes = sizeof (val);
ddef72cd 20481 }
3e6b6445
NC
20482 /* We do not bother to warn if bytes == 0 as this can
20483 happen with some early versions of the gcc plugin. */
9ef920e9
NC
20484
20485 while (bytes --)
20486 {
54b8331d 20487 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
20488
20489 val |= byte << shift;
9ef920e9
NC
20490 shift += 8;
20491 }
20492
75d7d298 20493 switch (name_attribute)
9ef920e9 20494 {
75d7d298 20495 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
20496 switch (val)
20497 {
75d7d298
NC
20498 case 0: decoded = "static"; break;
20499 case 1: decoded = "pic"; break;
20500 case 2: decoded = "PIC"; break;
20501 case 3: decoded = "pie"; break;
20502 case 4: decoded = "PIE"; break;
20503 default: break;
9ef920e9 20504 }
75d7d298
NC
20505 break;
20506 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20507 switch (val)
9ef920e9 20508 {
75d7d298
NC
20509 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
20510 case 0: decoded = "off"; break;
20511 case 1: decoded = "on"; break;
20512 case 2: decoded = "all"; break;
20513 case 3: decoded = "strong"; break;
20514 case 4: decoded = "explicit"; break;
20515 default: break;
9ef920e9 20516 }
75d7d298
NC
20517 break;
20518 default:
20519 break;
9ef920e9
NC
20520 }
20521
75d7d298 20522 if (decoded != NULL)
3e6b6445
NC
20523 {
20524 print_symbol (-left, decoded);
20525 left = 0;
20526 }
20527 else if (val == 0)
20528 {
20529 printf ("0x0");
20530 left -= 3;
20531 }
9ef920e9 20532 else
75d7d298
NC
20533 {
20534 if (do_wide)
ddef72cd 20535 left -= printf ("0x%llx", val);
75d7d298 20536 else
ddef72cd 20537 left -= printf ("0x%-.*llx", left, val);
75d7d298 20538 }
9ef920e9
NC
20539 }
20540 break;
20541 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20542 left -= print_symbol (- left, name);
20543 break;
20544 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20545 left -= print_symbol (- left, "true");
20546 break;
20547 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20548 left -= print_symbol (- left, "false");
20549 break;
20550 }
20551
20552 if (do_wide && left > 0)
20553 printf ("%-*s", left, " ");
9abca702 20554
015dc7e1 20555 return true;
9ef920e9
NC
20556}
20557
6d118b09
NC
20558/* Note that by the ELF standard, the name field is already null byte
20559 terminated, and namesz includes the terminating null byte.
20560 I.E. the value of namesz for the name "FSF" is 4.
20561
e3c8793a 20562 If the value of namesz is zero, there is no name present. */
9ef920e9 20563
015dc7e1 20564static bool
9ef920e9 20565process_note (Elf_Internal_Note * pnote,
dda8d76d 20566 Filedata * filedata)
779fe533 20567{
2cf0635d
NC
20568 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
20569 const char * nt;
9437c45b
JT
20570
20571 if (pnote->namesz == 0)
1ec5cd37
NC
20572 /* If there is no note name, then use the default set of
20573 note type strings. */
dda8d76d 20574 nt = get_note_type (filedata, pnote->type);
1ec5cd37 20575
24d127aa 20576 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
20577 /* GNU-specific object file notes. */
20578 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 20579
24d127aa 20580 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 20581 /* FreeBSD-specific core file notes. */
dda8d76d 20582 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 20583
24d127aa 20584 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 20585 /* NetBSD-specific core file notes. */
dda8d76d 20586 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 20587
24d127aa 20588 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
20589 /* NetBSD-specific core file notes. */
20590 return process_netbsd_elf_note (pnote);
20591
24d127aa 20592 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
20593 /* NetBSD-specific core file notes. */
20594 return process_netbsd_elf_note (pnote);
20595
e9b095a5 20596 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
20597 {
20598 /* SPU-specific core file notes. */
20599 nt = pnote->namedata + 4;
20600 name = "SPU";
20601 }
20602
24d127aa 20603 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
20604 /* VMS/ia64-specific file notes. */
20605 nt = get_ia64_vms_note_type (pnote->type);
20606
24d127aa 20607 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
20608 nt = get_stapsdt_note_type (pnote->type);
20609
9437c45b 20610 else
1ec5cd37
NC
20611 /* Don't recognize this note name; just use the default set of
20612 note type strings. */
dda8d76d 20613 nt = get_note_type (filedata, pnote->type);
9437c45b 20614
1449284b 20615 printf (" ");
9ef920e9 20616
24d127aa 20617 if (((startswith (pnote->namedata, "GA")
483767a3
AM
20618 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20619 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20620 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20621 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
20622 print_gnu_build_attribute_name (pnote);
20623 else
20624 print_symbol (-20, name);
20625
20626 if (do_wide)
20627 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
20628 else
20629 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 20630
24d127aa 20631 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 20632 return print_ia64_vms_note (pnote);
24d127aa 20633 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 20634 return print_gnu_note (filedata, pnote);
24d127aa 20635 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 20636 return print_stapsdt_note (pnote);
24d127aa 20637 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 20638 return print_core_note (pnote);
24d127aa 20639 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
20640 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20641 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20642 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20643 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 20644 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 20645
9ef920e9 20646 if (pnote->descsz)
1449284b
NC
20647 {
20648 unsigned long i;
20649
20650 printf (_(" description data: "));
20651 for (i = 0; i < pnote->descsz; i++)
178d8719 20652 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
20653 if (!do_wide)
20654 printf ("\n");
1449284b
NC
20655 }
20656
9ef920e9
NC
20657 if (do_wide)
20658 printf ("\n");
20659
015dc7e1 20660 return true;
1449284b 20661}
6d118b09 20662
015dc7e1 20663static bool
dda8d76d
NC
20664process_notes_at (Filedata * filedata,
20665 Elf_Internal_Shdr * section,
20666 bfd_vma offset,
82ed9683
L
20667 bfd_vma length,
20668 bfd_vma align)
779fe533 20669{
015dc7e1
AM
20670 Elf_External_Note *pnotes;
20671 Elf_External_Note *external;
20672 char *end;
20673 bool res = true;
103f02d3 20674
779fe533 20675 if (length <= 0)
015dc7e1 20676 return false;
103f02d3 20677
1449284b
NC
20678 if (section)
20679 {
dda8d76d 20680 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 20681 if (pnotes)
32ec8896 20682 {
dda8d76d 20683 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
20684 {
20685 free (pnotes);
015dc7e1 20686 return false;
f761cb13 20687 }
32ec8896 20688 }
1449284b
NC
20689 }
20690 else
82ed9683 20691 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 20692 _("notes"));
4dff97b2 20693
dd24e3da 20694 if (pnotes == NULL)
015dc7e1 20695 return false;
779fe533 20696
103f02d3 20697 external = pnotes;
103f02d3 20698
ca0e11aa
NC
20699 if (filedata->is_separate)
20700 printf (_("In linked file '%s': "), filedata->file_name);
20701 else
20702 printf ("\n");
1449284b 20703 if (section)
ca0e11aa 20704 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 20705 else
ca0e11aa 20706 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
20707 (unsigned long) offset, (unsigned long) length);
20708
82ed9683
L
20709 /* NB: Some note sections may have alignment value of 0 or 1. gABI
20710 specifies that notes should be aligned to 4 bytes in 32-bit
20711 objects and to 8 bytes in 64-bit objects. As a Linux extension,
20712 we also support 4 byte alignment in 64-bit objects. If section
20713 alignment is less than 4, we treate alignment as 4 bytes. */
20714 if (align < 4)
20715 align = 4;
20716 else if (align != 4 && align != 8)
20717 {
20718 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
20719 (long) align);
a788aedd 20720 free (pnotes);
015dc7e1 20721 return false;
82ed9683
L
20722 }
20723
dbe15e4e 20724 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 20725
c8071705
NC
20726 end = (char *) pnotes + length;
20727 while ((char *) external < end)
779fe533 20728 {
b34976b6 20729 Elf_Internal_Note inote;
15b42fb0 20730 size_t min_notesz;
4dff97b2 20731 char * next;
2cf0635d 20732 char * temp = NULL;
c8071705 20733 size_t data_remaining = end - (char *) external;
6d118b09 20734
dda8d76d 20735 if (!is_ia64_vms (filedata))
15b42fb0 20736 {
9dd3a467
NC
20737 /* PR binutils/15191
20738 Make sure that there is enough data to read. */
15b42fb0
AM
20739 min_notesz = offsetof (Elf_External_Note, name);
20740 if (data_remaining < min_notesz)
9dd3a467 20741 {
d3a49aa8
AM
20742 warn (ngettext ("Corrupt note: only %ld byte remains, "
20743 "not enough for a full note\n",
20744 "Corrupt note: only %ld bytes remain, "
20745 "not enough for a full note\n",
20746 data_remaining),
20747 (long) data_remaining);
9dd3a467
NC
20748 break;
20749 }
5396a86e
AM
20750 data_remaining -= min_notesz;
20751
15b42fb0
AM
20752 inote.type = BYTE_GET (external->type);
20753 inote.namesz = BYTE_GET (external->namesz);
20754 inote.namedata = external->name;
20755 inote.descsz = BYTE_GET (external->descsz);
276da9b3 20756 inote.descdata = ((char *) external
4dff97b2 20757 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 20758 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 20759 next = ((char *) external
4dff97b2 20760 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 20761 }
00e98fc7 20762 else
15b42fb0
AM
20763 {
20764 Elf64_External_VMS_Note *vms_external;
00e98fc7 20765
9dd3a467
NC
20766 /* PR binutils/15191
20767 Make sure that there is enough data to read. */
15b42fb0
AM
20768 min_notesz = offsetof (Elf64_External_VMS_Note, name);
20769 if (data_remaining < min_notesz)
9dd3a467 20770 {
d3a49aa8
AM
20771 warn (ngettext ("Corrupt note: only %ld byte remains, "
20772 "not enough for a full note\n",
20773 "Corrupt note: only %ld bytes remain, "
20774 "not enough for a full note\n",
20775 data_remaining),
20776 (long) data_remaining);
9dd3a467
NC
20777 break;
20778 }
5396a86e 20779 data_remaining -= min_notesz;
3e55a963 20780
15b42fb0
AM
20781 vms_external = (Elf64_External_VMS_Note *) external;
20782 inote.type = BYTE_GET (vms_external->type);
20783 inote.namesz = BYTE_GET (vms_external->namesz);
20784 inote.namedata = vms_external->name;
20785 inote.descsz = BYTE_GET (vms_external->descsz);
20786 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
20787 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20788 next = inote.descdata + align_power (inote.descsz, 3);
20789 }
20790
5396a86e
AM
20791 /* PR 17531: file: 3443835e. */
20792 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
20793 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
20794 || (size_t) (inote.descdata - inote.namedata) > data_remaining
20795 || (size_t) (next - inote.descdata) < inote.descsz
20796 || ((size_t) (next - inote.descdata)
20797 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 20798 {
15b42fb0 20799 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 20800 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
20801 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
20802 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
20803 break;
20804 }
20805
15b42fb0 20806 external = (Elf_External_Note *) next;
dd24e3da 20807
6d118b09
NC
20808 /* Verify that name is null terminated. It appears that at least
20809 one version of Linux (RedHat 6.0) generates corefiles that don't
20810 comply with the ELF spec by failing to include the null byte in
20811 namesz. */
18344509 20812 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 20813 {
5396a86e 20814 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 20815 {
5396a86e
AM
20816 temp = (char *) malloc (inote.namesz + 1);
20817 if (temp == NULL)
20818 {
20819 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 20820 res = false;
5396a86e
AM
20821 break;
20822 }
76da6bbe 20823
5396a86e
AM
20824 memcpy (temp, inote.namedata, inote.namesz);
20825 inote.namedata = temp;
20826 }
20827 inote.namedata[inote.namesz] = 0;
6d118b09
NC
20828 }
20829
dda8d76d 20830 if (! process_note (& inote, filedata))
015dc7e1 20831 res = false;
103f02d3 20832
9db70fc3
AM
20833 free (temp);
20834 temp = NULL;
779fe533
NC
20835 }
20836
20837 free (pnotes);
103f02d3 20838
779fe533
NC
20839 return res;
20840}
20841
015dc7e1 20842static bool
dda8d76d 20843process_corefile_note_segments (Filedata * filedata)
779fe533 20844{
015dc7e1 20845 Elf_Internal_Phdr *segment;
b34976b6 20846 unsigned int i;
015dc7e1 20847 bool res = true;
103f02d3 20848
dda8d76d 20849 if (! get_program_headers (filedata))
015dc7e1 20850 return true;
103f02d3 20851
dda8d76d
NC
20852 for (i = 0, segment = filedata->program_headers;
20853 i < filedata->file_header.e_phnum;
b34976b6 20854 i++, segment++)
779fe533
NC
20855 {
20856 if (segment->p_type == PT_NOTE)
dda8d76d 20857 if (! process_notes_at (filedata, NULL,
32ec8896 20858 (bfd_vma) segment->p_offset,
82ed9683
L
20859 (bfd_vma) segment->p_filesz,
20860 (bfd_vma) segment->p_align))
015dc7e1 20861 res = false;
779fe533 20862 }
103f02d3 20863
779fe533
NC
20864 return res;
20865}
20866
015dc7e1 20867static bool
dda8d76d 20868process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
20869{
20870 Elf_External_Note * pnotes;
20871 Elf_External_Note * external;
c8071705 20872 char * end;
015dc7e1 20873 bool res = true;
685080f2
NC
20874
20875 if (length <= 0)
015dc7e1 20876 return false;
685080f2 20877
dda8d76d 20878 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
20879 _("v850 notes"));
20880 if (pnotes == NULL)
015dc7e1 20881 return false;
685080f2
NC
20882
20883 external = pnotes;
c8071705 20884 end = (char*) pnotes + length;
685080f2
NC
20885
20886 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
20887 (unsigned long) offset, (unsigned long) length);
20888
c8071705 20889 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
20890 {
20891 Elf_External_Note * next;
20892 Elf_Internal_Note inote;
20893
20894 inote.type = BYTE_GET (external->type);
20895 inote.namesz = BYTE_GET (external->namesz);
20896 inote.namedata = external->name;
20897 inote.descsz = BYTE_GET (external->descsz);
20898 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
20899 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20900
c8071705
NC
20901 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
20902 {
20903 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
20904 inote.descdata = inote.namedata;
20905 inote.namesz = 0;
20906 }
20907
685080f2
NC
20908 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
20909
c8071705 20910 if ( ((char *) next > end)
685080f2
NC
20911 || ((char *) next < (char *) pnotes))
20912 {
20913 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
20914 (unsigned long) ((char *) external - (char *) pnotes));
20915 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20916 inote.type, inote.namesz, inote.descsz);
20917 break;
20918 }
20919
20920 external = next;
20921
20922 /* Prevent out-of-bounds indexing. */
c8071705 20923 if ( inote.namedata + inote.namesz > end
685080f2
NC
20924 || inote.namedata + inote.namesz < inote.namedata)
20925 {
20926 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
20927 (unsigned long) ((char *) external - (char *) pnotes));
20928 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20929 inote.type, inote.namesz, inote.descsz);
20930 break;
20931 }
20932
20933 printf (" %s: ", get_v850_elf_note_type (inote.type));
20934
20935 if (! print_v850_note (& inote))
20936 {
015dc7e1 20937 res = false;
685080f2
NC
20938 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
20939 inote.namesz, inote.descsz);
20940 }
20941 }
20942
20943 free (pnotes);
20944
20945 return res;
20946}
20947
015dc7e1 20948static bool
dda8d76d 20949process_note_sections (Filedata * filedata)
1ec5cd37 20950{
015dc7e1 20951 Elf_Internal_Shdr *section;
1ec5cd37 20952 unsigned long i;
32ec8896 20953 unsigned int n = 0;
015dc7e1 20954 bool res = true;
1ec5cd37 20955
dda8d76d
NC
20956 for (i = 0, section = filedata->section_headers;
20957 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 20958 i++, section++)
685080f2
NC
20959 {
20960 if (section->sh_type == SHT_NOTE)
20961 {
dda8d76d 20962 if (! process_notes_at (filedata, section,
32ec8896 20963 (bfd_vma) section->sh_offset,
82ed9683
L
20964 (bfd_vma) section->sh_size,
20965 (bfd_vma) section->sh_addralign))
015dc7e1 20966 res = false;
685080f2
NC
20967 n++;
20968 }
20969
dda8d76d
NC
20970 if (( filedata->file_header.e_machine == EM_V800
20971 || filedata->file_header.e_machine == EM_V850
20972 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
20973 && section->sh_type == SHT_RENESAS_INFO)
20974 {
dda8d76d 20975 if (! process_v850_notes (filedata,
32ec8896
NC
20976 (bfd_vma) section->sh_offset,
20977 (bfd_vma) section->sh_size))
015dc7e1 20978 res = false;
685080f2
NC
20979 n++;
20980 }
20981 }
df565f32
NC
20982
20983 if (n == 0)
20984 /* Try processing NOTE segments instead. */
dda8d76d 20985 return process_corefile_note_segments (filedata);
1ec5cd37
NC
20986
20987 return res;
20988}
20989
015dc7e1 20990static bool
dda8d76d 20991process_notes (Filedata * filedata)
779fe533
NC
20992{
20993 /* If we have not been asked to display the notes then do nothing. */
20994 if (! do_notes)
015dc7e1 20995 return true;
103f02d3 20996
dda8d76d
NC
20997 if (filedata->file_header.e_type != ET_CORE)
20998 return process_note_sections (filedata);
103f02d3 20999
779fe533 21000 /* No program headers means no NOTE segment. */
dda8d76d
NC
21001 if (filedata->file_header.e_phnum > 0)
21002 return process_corefile_note_segments (filedata);
779fe533 21003
ca0e11aa
NC
21004 if (filedata->is_separate)
21005 printf (_("No notes found in linked file '%s'.\n"),
21006 filedata->file_name);
21007 else
21008 printf (_("No notes found file.\n"));
21009
015dc7e1 21010 return true;
779fe533
NC
21011}
21012
60abdbed
NC
21013static unsigned char *
21014display_public_gnu_attributes (unsigned char * start,
21015 const unsigned char * const end)
21016{
21017 printf (_(" Unknown GNU attribute: %s\n"), start);
21018
21019 start += strnlen ((char *) start, end - start);
21020 display_raw_attribute (start, end);
21021
21022 return (unsigned char *) end;
21023}
21024
21025static unsigned char *
21026display_generic_attribute (unsigned char * start,
21027 unsigned int tag,
21028 const unsigned char * const end)
21029{
21030 if (tag == 0)
21031 return (unsigned char *) end;
21032
21033 return display_tag_value (tag, start, end);
21034}
21035
015dc7e1 21036static bool
dda8d76d 21037process_arch_specific (Filedata * filedata)
252b5132 21038{
a952a375 21039 if (! do_arch)
015dc7e1 21040 return true;
a952a375 21041
dda8d76d 21042 switch (filedata->file_header.e_machine)
252b5132 21043 {
53a346d8
CZ
21044 case EM_ARC:
21045 case EM_ARC_COMPACT:
21046 case EM_ARC_COMPACT2:
dda8d76d 21047 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
21048 display_arc_attribute,
21049 display_generic_attribute);
11c1ff18 21050 case EM_ARM:
dda8d76d 21051 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
21052 display_arm_attribute,
21053 display_generic_attribute);
21054
252b5132 21055 case EM_MIPS:
4fe85591 21056 case EM_MIPS_RS3_LE:
dda8d76d 21057 return process_mips_specific (filedata);
60abdbed
NC
21058
21059 case EM_MSP430:
dda8d76d 21060 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21061 display_msp430_attribute,
c0ea7c52 21062 display_msp430_gnu_attribute);
60abdbed 21063
2dc8dd17
JW
21064 case EM_RISCV:
21065 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21066 display_riscv_attribute,
21067 display_generic_attribute);
21068
35c08157 21069 case EM_NDS32:
dda8d76d 21070 return process_nds32_specific (filedata);
60abdbed 21071
85f7484a
PB
21072 case EM_68K:
21073 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21074 display_m68k_gnu_attribute);
21075
34c8bcba 21076 case EM_PPC:
b82317dd 21077 case EM_PPC64:
dda8d76d 21078 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21079 display_power_gnu_attribute);
21080
643f7afb
AK
21081 case EM_S390:
21082 case EM_S390_OLD:
dda8d76d 21083 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21084 display_s390_gnu_attribute);
21085
9e8c70f9
DM
21086 case EM_SPARC:
21087 case EM_SPARC32PLUS:
21088 case EM_SPARCV9:
dda8d76d 21089 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21090 display_sparc_gnu_attribute);
21091
59e6276b 21092 case EM_TI_C6000:
dda8d76d 21093 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
21094 display_tic6x_attribute,
21095 display_generic_attribute);
21096
0861f561
CQ
21097 case EM_CSKY:
21098 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
21099 display_csky_attribute, NULL);
21100
252b5132 21101 default:
dda8d76d 21102 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
21103 display_public_gnu_attributes,
21104 display_generic_attribute);
252b5132 21105 }
252b5132
RH
21106}
21107
015dc7e1 21108static bool
dda8d76d 21109get_file_header (Filedata * filedata)
252b5132 21110{
9ea033b2 21111 /* Read in the identity array. */
dda8d76d 21112 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21113 return false;
252b5132 21114
9ea033b2 21115 /* Determine how to read the rest of the header. */
dda8d76d 21116 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 21117 {
1a0670f3
AM
21118 default:
21119 case ELFDATANONE:
adab8cdc
AO
21120 case ELFDATA2LSB:
21121 byte_get = byte_get_little_endian;
21122 byte_put = byte_put_little_endian;
21123 break;
21124 case ELFDATA2MSB:
21125 byte_get = byte_get_big_endian;
21126 byte_put = byte_put_big_endian;
21127 break;
9ea033b2
NC
21128 }
21129
21130 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 21131 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
21132
21133 /* Read in the rest of the header. */
21134 if (is_32bit_elf)
21135 {
21136 Elf32_External_Ehdr ehdr32;
252b5132 21137
dda8d76d 21138 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21139 return false;
103f02d3 21140
dda8d76d
NC
21141 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
21142 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
21143 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
21144 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
21145 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
21146 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
21147 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
21148 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
21149 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
21150 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
21151 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
21152 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
21153 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 21154 }
252b5132 21155 else
9ea033b2
NC
21156 {
21157 Elf64_External_Ehdr ehdr64;
a952a375
NC
21158
21159 /* If we have been compiled with sizeof (bfd_vma) == 4, then
21160 we will not be able to cope with the 64bit data found in
21161 64 ELF files. Detect this now and abort before we start
50c2245b 21162 overwriting things. */
a952a375
NC
21163 if (sizeof (bfd_vma) < 8)
21164 {
e3c8793a
NC
21165 error (_("This instance of readelf has been built without support for a\n\
2116664 bit data type and so it cannot read 64 bit ELF files.\n"));
015dc7e1 21167 return false;
a952a375 21168 }
103f02d3 21169
dda8d76d 21170 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21171 return false;
103f02d3 21172
dda8d76d
NC
21173 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
21174 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
21175 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
21176 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
21177 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
21178 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
21179 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
21180 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
21181 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
21182 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
21183 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
21184 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
21185 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 21186 }
252b5132 21187
dda8d76d 21188 if (filedata->file_header.e_shoff)
7ece0d85
JJ
21189 {
21190 /* There may be some extensions in the first section header. Don't
21191 bomb if we can't read it. */
21192 if (is_32bit_elf)
015dc7e1 21193 get_32bit_section_headers (filedata, true);
7ece0d85 21194 else
015dc7e1 21195 get_64bit_section_headers (filedata, true);
7ece0d85 21196 }
560f3c1c 21197
015dc7e1 21198 return true;
252b5132
RH
21199}
21200
13acb58d
AM
21201static void
21202free_filedata (Filedata *filedata)
21203{
21204 free (filedata->program_interpreter);
21205 filedata->program_interpreter = NULL;
21206
21207 free (filedata->program_headers);
21208 filedata->program_headers = NULL;
21209
21210 free (filedata->section_headers);
21211 filedata->section_headers = NULL;
21212
21213 free (filedata->string_table);
21214 filedata->string_table = NULL;
21215 filedata->string_table_length = 0;
21216
21217 free (filedata->dump.dump_sects);
21218 filedata->dump.dump_sects = NULL;
21219 filedata->dump.num_dump_sects = 0;
21220
21221 free (filedata->dynamic_strings);
21222 filedata->dynamic_strings = NULL;
21223 filedata->dynamic_strings_length = 0;
21224
21225 free (filedata->dynamic_symbols);
21226 filedata->dynamic_symbols = NULL;
21227 filedata->num_dynamic_syms = 0;
21228
21229 free (filedata->dynamic_syminfo);
21230 filedata->dynamic_syminfo = NULL;
21231
21232 free (filedata->dynamic_section);
21233 filedata->dynamic_section = NULL;
21234
21235 while (filedata->symtab_shndx_list != NULL)
21236 {
21237 elf_section_list *next = filedata->symtab_shndx_list->next;
21238 free (filedata->symtab_shndx_list);
21239 filedata->symtab_shndx_list = next;
21240 }
21241
21242 free (filedata->section_headers_groups);
21243 filedata->section_headers_groups = NULL;
21244
21245 if (filedata->section_groups)
21246 {
21247 size_t i;
21248 struct group_list * g;
21249 struct group_list * next;
21250
21251 for (i = 0; i < filedata->group_count; i++)
21252 {
21253 for (g = filedata->section_groups [i].root; g != NULL; g = next)
21254 {
21255 next = g->next;
21256 free (g);
21257 }
21258 }
21259
21260 free (filedata->section_groups);
21261 filedata->section_groups = NULL;
21262 }
21263}
21264
dda8d76d
NC
21265static void
21266close_file (Filedata * filedata)
21267{
21268 if (filedata)
21269 {
21270 if (filedata->handle)
21271 fclose (filedata->handle);
21272 free (filedata);
21273 }
21274}
21275
21276void
21277close_debug_file (void * data)
21278{
13acb58d 21279 free_filedata ((Filedata *) data);
dda8d76d
NC
21280 close_file ((Filedata *) data);
21281}
21282
21283static Filedata *
015dc7e1 21284open_file (const char * pathname, bool is_separate)
dda8d76d
NC
21285{
21286 struct stat statbuf;
21287 Filedata * filedata = NULL;
21288
21289 if (stat (pathname, & statbuf) < 0
21290 || ! S_ISREG (statbuf.st_mode))
21291 goto fail;
21292
21293 filedata = calloc (1, sizeof * filedata);
21294 if (filedata == NULL)
21295 goto fail;
21296
21297 filedata->handle = fopen (pathname, "rb");
21298 if (filedata->handle == NULL)
21299 goto fail;
21300
21301 filedata->file_size = (bfd_size_type) statbuf.st_size;
21302 filedata->file_name = pathname;
ca0e11aa 21303 filedata->is_separate = is_separate;
dda8d76d
NC
21304
21305 if (! get_file_header (filedata))
21306 goto fail;
21307
21308 if (filedata->file_header.e_shoff)
21309 {
015dc7e1 21310 bool res;
dda8d76d
NC
21311
21312 /* Read the section headers again, this time for real. */
21313 if (is_32bit_elf)
015dc7e1 21314 res = get_32bit_section_headers (filedata, false);
dda8d76d 21315 else
015dc7e1 21316 res = get_64bit_section_headers (filedata, false);
dda8d76d
NC
21317
21318 if (!res)
21319 goto fail;
21320 }
21321
21322 return filedata;
21323
21324 fail:
21325 if (filedata)
21326 {
21327 if (filedata->handle)
21328 fclose (filedata->handle);
21329 free (filedata);
21330 }
21331 return NULL;
21332}
21333
21334void *
21335open_debug_file (const char * pathname)
21336{
015dc7e1 21337 return open_file (pathname, true);
dda8d76d
NC
21338}
21339
835f2fae
NC
21340static void
21341initialise_dump_sects (Filedata * filedata)
21342{
21343 /* Initialise the dump_sects array from the cmdline_dump_sects array.
21344 Note we do this even if cmdline_dump_sects is empty because we
21345 must make sure that the dump_sets array is zeroed out before each
21346 object file is processed. */
21347 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
21348 memset (filedata->dump.dump_sects, 0,
21349 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21350
21351 if (cmdline.num_dump_sects > 0)
21352 {
21353 if (filedata->dump.num_dump_sects == 0)
21354 /* A sneaky way of allocating the dump_sects array. */
21355 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
21356
21357 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
21358 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
21359 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21360 }
21361}
21362
fb52b2f4
NC
21363/* Process one ELF object file according to the command line options.
21364 This file may actually be stored in an archive. The file is
32ec8896
NC
21365 positioned at the start of the ELF object. Returns TRUE if no
21366 problems were encountered, FALSE otherwise. */
fb52b2f4 21367
015dc7e1 21368static bool
dda8d76d 21369process_object (Filedata * filedata)
252b5132 21370{
015dc7e1 21371 bool have_separate_files;
252b5132 21372 unsigned int i;
015dc7e1 21373 bool res;
252b5132 21374
dda8d76d 21375 if (! get_file_header (filedata))
252b5132 21376 {
dda8d76d 21377 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 21378 return false;
252b5132
RH
21379 }
21380
21381 /* Initialise per file variables. */
978c4450
AM
21382 for (i = ARRAY_SIZE (filedata->version_info); i--;)
21383 filedata->version_info[i] = 0;
252b5132 21384
978c4450
AM
21385 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
21386 filedata->dynamic_info[i] = 0;
21387 filedata->dynamic_info_DT_GNU_HASH = 0;
21388 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
21389
21390 /* Process the file. */
21391 if (show_name)
dda8d76d 21392 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 21393
835f2fae 21394 initialise_dump_sects (filedata);
d70c5fc7 21395
dda8d76d 21396 if (! process_file_header (filedata))
015dc7e1 21397 return false;
252b5132 21398
dda8d76d 21399 if (! process_section_headers (filedata))
2f62977e 21400 {
32ec8896 21401 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 21402 do_unwind = do_version = do_dump = do_arch = false;
252b5132 21403
2f62977e 21404 if (! do_using_dynamic)
015dc7e1 21405 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 21406 }
252b5132 21407
dda8d76d 21408 if (! process_section_groups (filedata))
32ec8896 21409 /* Without loaded section groups we cannot process unwind. */
015dc7e1 21410 do_unwind = false;
d1f5c6e3 21411
2482f306
AM
21412 res = process_program_headers (filedata);
21413 if (res)
21414 res = process_dynamic_section (filedata);
252b5132 21415
dda8d76d 21416 if (! process_relocs (filedata))
015dc7e1 21417 res = false;
252b5132 21418
dda8d76d 21419 if (! process_unwind (filedata))
015dc7e1 21420 res = false;
4d6ed7c8 21421
dda8d76d 21422 if (! process_symbol_table (filedata))
015dc7e1 21423 res = false;
252b5132 21424
0f03783c 21425 if (! process_lto_symbol_tables (filedata))
015dc7e1 21426 res = false;
b9e920ec 21427
dda8d76d 21428 if (! process_syminfo (filedata))
015dc7e1 21429 res = false;
252b5132 21430
dda8d76d 21431 if (! process_version_sections (filedata))
015dc7e1 21432 res = false;
252b5132 21433
82ed9683 21434 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 21435 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 21436 else
015dc7e1 21437 have_separate_files = false;
dda8d76d
NC
21438
21439 if (! process_section_contents (filedata))
015dc7e1 21440 res = false;
f5842774 21441
24841daa 21442 if (have_separate_files)
dda8d76d 21443 {
24841daa
NC
21444 separate_info * d;
21445
21446 for (d = first_separate_info; d != NULL; d = d->next)
21447 {
835f2fae
NC
21448 initialise_dump_sects (d->handle);
21449
ca0e11aa 21450 if (process_links && ! process_file_header (d->handle))
015dc7e1 21451 res = false;
ca0e11aa 21452 else if (! process_section_headers (d->handle))
015dc7e1 21453 res = false;
d6bfbc39 21454 else if (! process_section_contents (d->handle))
015dc7e1 21455 res = false;
ca0e11aa
NC
21456 else if (process_links)
21457 {
ca0e11aa 21458 if (! process_section_groups (d->handle))
015dc7e1 21459 res = false;
ca0e11aa 21460 if (! process_program_headers (d->handle))
015dc7e1 21461 res = false;
ca0e11aa 21462 if (! process_dynamic_section (d->handle))
015dc7e1 21463 res = false;
ca0e11aa 21464 if (! process_relocs (d->handle))
015dc7e1 21465 res = false;
ca0e11aa 21466 if (! process_unwind (d->handle))
015dc7e1 21467 res = false;
ca0e11aa 21468 if (! process_symbol_table (d->handle))
015dc7e1 21469 res = false;
ca0e11aa 21470 if (! process_lto_symbol_tables (d->handle))
015dc7e1 21471 res = false;
ca0e11aa 21472 if (! process_syminfo (d->handle))
015dc7e1 21473 res = false;
ca0e11aa 21474 if (! process_version_sections (d->handle))
015dc7e1 21475 res = false;
ca0e11aa 21476 if (! process_notes (d->handle))
015dc7e1 21477 res = false;
ca0e11aa 21478 }
24841daa
NC
21479 }
21480
21481 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
21482 }
21483
21484 if (! process_notes (filedata))
015dc7e1 21485 res = false;
103f02d3 21486
dda8d76d 21487 if (! process_gnu_liblist (filedata))
015dc7e1 21488 res = false;
047b2264 21489
dda8d76d 21490 if (! process_arch_specific (filedata))
015dc7e1 21491 res = false;
252b5132 21492
13acb58d 21493 free_filedata (filedata);
e4b17d5c 21494
19e6b90e 21495 free_debug_memory ();
18bd398b 21496
32ec8896 21497 return res;
252b5132
RH
21498}
21499
2cf0635d 21500/* Process an ELF archive.
32ec8896
NC
21501 On entry the file is positioned just after the ARMAG string.
21502 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 21503
015dc7e1
AM
21504static bool
21505process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
21506{
21507 struct archive_info arch;
21508 struct archive_info nested_arch;
21509 size_t got;
015dc7e1 21510 bool ret = true;
2cf0635d 21511
015dc7e1 21512 show_name = true;
2cf0635d
NC
21513
21514 /* The ARCH structure is used to hold information about this archive. */
21515 arch.file_name = NULL;
21516 arch.file = NULL;
21517 arch.index_array = NULL;
21518 arch.sym_table = NULL;
21519 arch.longnames = NULL;
21520
21521 /* The NESTED_ARCH structure is used as a single-item cache of information
21522 about a nested archive (when members of a thin archive reside within
21523 another regular archive file). */
21524 nested_arch.file_name = NULL;
21525 nested_arch.file = NULL;
21526 nested_arch.index_array = NULL;
21527 nested_arch.sym_table = NULL;
21528 nested_arch.longnames = NULL;
21529
dda8d76d 21530 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
21531 filedata->file_size, is_thin_archive,
21532 do_archive_index) != 0)
2cf0635d 21533 {
015dc7e1 21534 ret = false;
2cf0635d 21535 goto out;
4145f1d5 21536 }
fb52b2f4 21537
4145f1d5
NC
21538 if (do_archive_index)
21539 {
2cf0635d 21540 if (arch.sym_table == NULL)
1cb7d8b1
AM
21541 error (_("%s: unable to dump the index as none was found\n"),
21542 filedata->file_name);
4145f1d5
NC
21543 else
21544 {
591f7597 21545 unsigned long i, l;
4145f1d5
NC
21546 unsigned long current_pos;
21547
1cb7d8b1
AM
21548 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
21549 "in the symbol table)\n"),
21550 filedata->file_name, (unsigned long) arch.index_num,
21551 arch.sym_size);
dda8d76d
NC
21552
21553 current_pos = ftell (filedata->handle);
4145f1d5 21554
2cf0635d 21555 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 21556 {
1cb7d8b1
AM
21557 if (i == 0
21558 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
21559 {
21560 char * member_name
21561 = get_archive_member_name_at (&arch, arch.index_array[i],
21562 &nested_arch);
2cf0635d 21563
1cb7d8b1
AM
21564 if (member_name != NULL)
21565 {
21566 char * qualified_name
21567 = make_qualified_name (&arch, &nested_arch,
21568 member_name);
2cf0635d 21569
1cb7d8b1
AM
21570 if (qualified_name != NULL)
21571 {
21572 printf (_("Contents of binary %s at offset "),
21573 qualified_name);
c2a7d3f5
NC
21574 (void) print_vma (arch.index_array[i], PREFIX_HEX);
21575 putchar ('\n');
1cb7d8b1
AM
21576 free (qualified_name);
21577 }
fd486f32 21578 free (member_name);
4145f1d5
NC
21579 }
21580 }
2cf0635d
NC
21581
21582 if (l >= arch.sym_size)
4145f1d5 21583 {
1cb7d8b1
AM
21584 error (_("%s: end of the symbol table reached "
21585 "before the end of the index\n"),
dda8d76d 21586 filedata->file_name);
015dc7e1 21587 ret = false;
cb8f3167 21588 break;
4145f1d5 21589 }
591f7597 21590 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
21591 printf ("\t%.*s\n",
21592 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 21593 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
21594 }
21595
67ce483b 21596 if (arch.uses_64bit_indices)
c2a7d3f5
NC
21597 l = (l + 7) & ~ 7;
21598 else
21599 l += l & 1;
21600
2cf0635d 21601 if (l < arch.sym_size)
32ec8896 21602 {
d3a49aa8
AM
21603 error (ngettext ("%s: %ld byte remains in the symbol table, "
21604 "but without corresponding entries in "
21605 "the index table\n",
21606 "%s: %ld bytes remain in the symbol table, "
21607 "but without corresponding entries in "
21608 "the index table\n",
21609 arch.sym_size - l),
dda8d76d 21610 filedata->file_name, arch.sym_size - l);
015dc7e1 21611 ret = false;
32ec8896 21612 }
4145f1d5 21613
dda8d76d 21614 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 21615 {
1cb7d8b1
AM
21616 error (_("%s: failed to seek back to start of object files "
21617 "in the archive\n"),
dda8d76d 21618 filedata->file_name);
015dc7e1 21619 ret = false;
2cf0635d 21620 goto out;
4145f1d5 21621 }
fb52b2f4 21622 }
4145f1d5
NC
21623
21624 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
21625 && !do_segments && !do_header && !do_dump && !do_version
21626 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 21627 && !do_section_groups && !do_dyn_syms)
2cf0635d 21628 {
015dc7e1 21629 ret = true; /* Archive index only. */
2cf0635d
NC
21630 goto out;
21631 }
fb52b2f4
NC
21632 }
21633
fb52b2f4
NC
21634 while (1)
21635 {
2cf0635d
NC
21636 char * name;
21637 size_t namelen;
21638 char * qualified_name;
21639
21640 /* Read the next archive header. */
dda8d76d 21641 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
21642 {
21643 error (_("%s: failed to seek to next archive header\n"),
21644 arch.file_name);
015dc7e1 21645 ret = false;
1cb7d8b1
AM
21646 break;
21647 }
dda8d76d 21648 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 21649 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
21650 {
21651 if (got == 0)
2cf0635d 21652 break;
28e817cc
NC
21653 /* PR 24049 - we cannot use filedata->file_name as this will
21654 have already been freed. */
21655 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 21656
015dc7e1 21657 ret = false;
1cb7d8b1
AM
21658 break;
21659 }
2cf0635d 21660 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
21661 {
21662 error (_("%s: did not find a valid archive header\n"),
21663 arch.file_name);
015dc7e1 21664 ret = false;
1cb7d8b1
AM
21665 break;
21666 }
2cf0635d
NC
21667
21668 arch.next_arhdr_offset += sizeof arch.arhdr;
21669
978c4450
AM
21670 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
21671 if (filedata->archive_file_size & 01)
21672 ++filedata->archive_file_size;
2cf0635d
NC
21673
21674 name = get_archive_member_name (&arch, &nested_arch);
21675 if (name == NULL)
fb52b2f4 21676 {
28e817cc 21677 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 21678 ret = false;
d989285c 21679 break;
fb52b2f4 21680 }
2cf0635d 21681 namelen = strlen (name);
fb52b2f4 21682
2cf0635d
NC
21683 qualified_name = make_qualified_name (&arch, &nested_arch, name);
21684 if (qualified_name == NULL)
fb52b2f4 21685 {
28e817cc 21686 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 21687 free (name);
015dc7e1 21688 ret = false;
d989285c 21689 break;
fb52b2f4
NC
21690 }
21691
2cf0635d 21692 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
21693 {
21694 /* This is a proxy for an external member of a thin archive. */
21695 Filedata * member_filedata;
21696 char * member_file_name = adjust_relative_path
dda8d76d 21697 (filedata->file_name, name, namelen);
32ec8896 21698
fd486f32 21699 free (name);
1cb7d8b1
AM
21700 if (member_file_name == NULL)
21701 {
fd486f32 21702 free (qualified_name);
015dc7e1 21703 ret = false;
1cb7d8b1
AM
21704 break;
21705 }
2cf0635d 21706
015dc7e1 21707 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
21708 if (member_filedata == NULL)
21709 {
21710 error (_("Input file '%s' is not readable.\n"), member_file_name);
21711 free (member_file_name);
fd486f32 21712 free (qualified_name);
015dc7e1 21713 ret = false;
1cb7d8b1
AM
21714 break;
21715 }
2cf0635d 21716
978c4450 21717 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 21718 member_filedata->file_name = qualified_name;
2cf0635d 21719
1cb7d8b1 21720 if (! process_object (member_filedata))
015dc7e1 21721 ret = false;
2cf0635d 21722
1cb7d8b1
AM
21723 close_file (member_filedata);
21724 free (member_file_name);
1cb7d8b1 21725 }
2cf0635d 21726 else if (is_thin_archive)
1cb7d8b1
AM
21727 {
21728 Filedata thin_filedata;
eb02c04d 21729
1cb7d8b1 21730 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 21731
a043396b
NC
21732 /* PR 15140: Allow for corrupt thin archives. */
21733 if (nested_arch.file == NULL)
21734 {
21735 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 21736 qualified_name, name);
fd486f32
AM
21737 free (qualified_name);
21738 free (name);
015dc7e1 21739 ret = false;
a043396b
NC
21740 break;
21741 }
fd486f32 21742 free (name);
a043396b 21743
1cb7d8b1 21744 /* This is a proxy for a member of a nested archive. */
978c4450
AM
21745 filedata->archive_file_offset
21746 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 21747
1cb7d8b1
AM
21748 /* The nested archive file will have been opened and setup by
21749 get_archive_member_name. */
978c4450
AM
21750 if (fseek (nested_arch.file, filedata->archive_file_offset,
21751 SEEK_SET) != 0)
1cb7d8b1
AM
21752 {
21753 error (_("%s: failed to seek to archive member.\n"),
21754 nested_arch.file_name);
fd486f32 21755 free (qualified_name);
015dc7e1 21756 ret = false;
1cb7d8b1
AM
21757 break;
21758 }
2cf0635d 21759
dda8d76d
NC
21760 thin_filedata.handle = nested_arch.file;
21761 thin_filedata.file_name = qualified_name;
9abca702 21762
1cb7d8b1 21763 if (! process_object (& thin_filedata))
015dc7e1 21764 ret = false;
1cb7d8b1 21765 }
2cf0635d 21766 else
1cb7d8b1 21767 {
fd486f32 21768 free (name);
978c4450 21769 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 21770 filedata->file_name = qualified_name;
1cb7d8b1 21771 if (! process_object (filedata))
015dc7e1 21772 ret = false;
978c4450 21773 arch.next_arhdr_offset += filedata->archive_file_size;
4c836627 21774 /* Stop looping with "negative" archive_file_size. */
978c4450 21775 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 21776 arch.next_arhdr_offset = -1ul;
1cb7d8b1 21777 }
fb52b2f4 21778
2cf0635d 21779 free (qualified_name);
fb52b2f4
NC
21780 }
21781
4145f1d5 21782 out:
2cf0635d
NC
21783 if (nested_arch.file != NULL)
21784 fclose (nested_arch.file);
21785 release_archive (&nested_arch);
21786 release_archive (&arch);
fb52b2f4 21787
d989285c 21788 return ret;
fb52b2f4
NC
21789}
21790
015dc7e1 21791static bool
2cf0635d 21792process_file (char * file_name)
fb52b2f4 21793{
dda8d76d 21794 Filedata * filedata = NULL;
fb52b2f4
NC
21795 struct stat statbuf;
21796 char armag[SARMAG];
015dc7e1 21797 bool ret = true;
fb52b2f4
NC
21798
21799 if (stat (file_name, &statbuf) < 0)
21800 {
f24ddbdd
NC
21801 if (errno == ENOENT)
21802 error (_("'%s': No such file\n"), file_name);
21803 else
21804 error (_("Could not locate '%s'. System error message: %s\n"),
21805 file_name, strerror (errno));
015dc7e1 21806 return false;
f24ddbdd
NC
21807 }
21808
21809 if (! S_ISREG (statbuf.st_mode))
21810 {
21811 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 21812 return false;
fb52b2f4
NC
21813 }
21814
dda8d76d
NC
21815 filedata = calloc (1, sizeof * filedata);
21816 if (filedata == NULL)
21817 {
21818 error (_("Out of memory allocating file data structure\n"));
015dc7e1 21819 return false;
dda8d76d
NC
21820 }
21821
21822 filedata->file_name = file_name;
21823 filedata->handle = fopen (file_name, "rb");
21824 if (filedata->handle == NULL)
fb52b2f4 21825 {
f24ddbdd 21826 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 21827 free (filedata);
015dc7e1 21828 return false;
fb52b2f4
NC
21829 }
21830
dda8d76d 21831 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 21832 {
4145f1d5 21833 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
21834 fclose (filedata->handle);
21835 free (filedata);
015dc7e1 21836 return false;
fb52b2f4
NC
21837 }
21838
dda8d76d 21839 filedata->file_size = (bfd_size_type) statbuf.st_size;
015dc7e1 21840 filedata->is_separate = false;
f54498b4 21841
fb52b2f4 21842 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 21843 {
015dc7e1
AM
21844 if (! process_archive (filedata, false))
21845 ret = false;
32ec8896 21846 }
2cf0635d 21847 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 21848 {
015dc7e1
AM
21849 if ( ! process_archive (filedata, true))
21850 ret = false;
32ec8896 21851 }
fb52b2f4
NC
21852 else
21853 {
1b513401 21854 if (do_archive_index && !check_all)
4145f1d5
NC
21855 error (_("File %s is not an archive so its index cannot be displayed.\n"),
21856 file_name);
21857
dda8d76d 21858 rewind (filedata->handle);
978c4450 21859 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 21860
dda8d76d 21861 if (! process_object (filedata))
015dc7e1 21862 ret = false;
fb52b2f4
NC
21863 }
21864
dda8d76d 21865 fclose (filedata->handle);
8fb879cd
AM
21866 free (filedata->section_headers);
21867 free (filedata->program_headers);
21868 free (filedata->string_table);
6431e409 21869 free (filedata->dump.dump_sects);
dda8d76d 21870 free (filedata);
32ec8896 21871
fd486f32 21872 free (ba_cache.strtab);
1bd6175a 21873 ba_cache.strtab = NULL;
fd486f32 21874 free (ba_cache.symtab);
1bd6175a 21875 ba_cache.symtab = NULL;
fd486f32
AM
21876 ba_cache.filedata = NULL;
21877
fb52b2f4
NC
21878 return ret;
21879}
21880
252b5132
RH
21881#ifdef SUPPORT_DISASSEMBLY
21882/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 21883 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 21884 symbols. */
252b5132
RH
21885
21886void
2cf0635d 21887print_address (unsigned int addr, FILE * outfile)
252b5132
RH
21888{
21889 fprintf (outfile,"0x%8.8x", addr);
21890}
21891
e3c8793a 21892/* Needed by the i386 disassembler. */
dda8d76d 21893
252b5132
RH
21894void
21895db_task_printsym (unsigned int addr)
21896{
21897 print_address (addr, stderr);
21898}
21899#endif
21900
21901int
2cf0635d 21902main (int argc, char ** argv)
252b5132 21903{
ff78d6d6
L
21904 int err;
21905
87b9f255 21906#ifdef HAVE_LC_MESSAGES
252b5132 21907 setlocale (LC_MESSAGES, "");
3882b010 21908#endif
3882b010 21909 setlocale (LC_CTYPE, "");
252b5132
RH
21910 bindtextdomain (PACKAGE, LOCALEDIR);
21911 textdomain (PACKAGE);
21912
869b9d07
MM
21913 expandargv (&argc, &argv);
21914
dda8d76d 21915 parse_args (& cmdline, argc, argv);
59f14fc0 21916
18bd398b 21917 if (optind < (argc - 1))
1b513401
NC
21918 /* When displaying information for more than one file,
21919 prefix the information with the file name. */
015dc7e1 21920 show_name = true;
5656ba2c
L
21921 else if (optind >= argc)
21922 {
1b513401 21923 /* Ensure that the warning is always displayed. */
015dc7e1 21924 do_checks = true;
1b513401 21925
5656ba2c
L
21926 warn (_("Nothing to do.\n"));
21927 usage (stderr);
21928 }
18bd398b 21929
015dc7e1 21930 err = false;
252b5132 21931 while (optind < argc)
32ec8896 21932 if (! process_file (argv[optind++]))
015dc7e1 21933 err = true;
252b5132 21934
9db70fc3 21935 free (cmdline.dump_sects);
252b5132 21936
7d9813f1
NA
21937 free (dump_ctf_symtab_name);
21938 free (dump_ctf_strtab_name);
21939 free (dump_ctf_parent_name);
21940
32ec8896 21941 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 21942}
This page took 4.713006 seconds and 4 git commands to generate.