readelf section reading
[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
10ca4b04
L
360#define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
361 (strtab != NULL && offset < strtab_size)
978c4450
AM
362#define VALID_DYNAMIC_NAME(filedata, offset) \
363 VALID_SYMBOL_NAME (filedata->dynamic_strings, \
364 filedata->dynamic_strings_length, offset)
d79b3d50
NC
365/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
366 already been called and verified that the string exists. */
978c4450
AM
367#define GET_DYNAMIC_NAME(filedata, offset) \
368 (filedata->dynamic_strings + offset)
18bd398b 369
61865e30
NC
370#define REMOVE_ARCH_BITS(ADDR) \
371 do \
372 { \
dda8d76d 373 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
374 (ADDR) &= ~1; \
375 } \
376 while (0)
f16a9783
MS
377
378/* Get the correct GNU hash section name. */
978c4450
AM
379#define GNU_HASH_SECTION_NAME(filedata) \
380 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 381\f
66cfc0fd
AM
382/* Print a BFD_VMA to an internal buffer, for use in error messages.
383 BFD_FMA_FMT can't be used in translated strings. */
384
385static const char *
386bfd_vmatoa (char *fmtch, bfd_vma value)
387{
388 /* bfd_vmatoa is used more then once in a printf call for output.
389 Cycle through an array of buffers. */
390 static int buf_pos = 0;
391 static struct bfd_vmatoa_buf
392 {
393 char place[64];
394 } buf[4];
395 char *ret;
396 char fmt[32];
397
398 ret = buf[buf_pos++].place;
399 buf_pos %= ARRAY_SIZE (buf);
400
401 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
402 snprintf (ret, sizeof (buf[0].place), fmt, value);
403 return ret;
404}
405
dda8d76d
NC
406/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
407 OFFSET + the offset of the current archive member, if we are examining an
408 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
409 allocate a buffer using malloc and fill that. In either case return the
410 pointer to the start of the retrieved data or NULL if something went wrong.
411 If something does go wrong and REASON is not NULL then emit an error
412 message using REASON as part of the context. */
59245841 413
c256ffe7 414static void *
dda8d76d
NC
415get_data (void * var,
416 Filedata * filedata,
417 unsigned long offset,
418 bfd_size_type size,
419 bfd_size_type nmemb,
420 const char * reason)
a6e9f9df 421{
2cf0635d 422 void * mvar;
57028622 423 bfd_size_type amt = size * nmemb;
a6e9f9df 424
c256ffe7 425 if (size == 0 || nmemb == 0)
a6e9f9df
AM
426 return NULL;
427
57028622
NC
428 /* If the size_t type is smaller than the bfd_size_type, eg because
429 you are building a 32-bit tool on a 64-bit host, then make sure
430 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
431 if ((size_t) size != size
432 || (size_t) nmemb != nmemb
433 || (size_t) amt != amt)
57028622
NC
434 {
435 if (reason)
66cfc0fd
AM
436 error (_("Size truncation prevents reading %s"
437 " elements of size %s for %s\n"),
438 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
439 return NULL;
440 }
441
442 /* Check for size overflow. */
7c1c1904 443 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
444 {
445 if (reason)
66cfc0fd
AM
446 error (_("Size overflow prevents reading %s"
447 " elements of size %s for %s\n"),
448 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
449 return NULL;
450 }
451
c22b42ce 452 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 453 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
454 if (filedata->archive_file_offset > filedata->file_size
455 || offset > filedata->file_size - filedata->archive_file_offset
456 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 457 {
049b0c3a 458 if (reason)
66cfc0fd
AM
459 error (_("Reading %s bytes extends past end of file for %s\n"),
460 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
461 return NULL;
462 }
463
978c4450
AM
464 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
465 SEEK_SET))
071436c6
NC
466 {
467 if (reason)
c9c1d674 468 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 469 filedata->archive_file_offset + offset, reason);
071436c6
NC
470 return NULL;
471 }
472
a6e9f9df
AM
473 mvar = var;
474 if (mvar == NULL)
475 {
7c1c1904
AM
476 /* + 1 so that we can '\0' terminate invalid string table sections. */
477 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
478
479 if (mvar == NULL)
480 {
049b0c3a 481 if (reason)
66cfc0fd
AM
482 error (_("Out of memory allocating %s bytes for %s\n"),
483 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
484 return NULL;
485 }
c256ffe7 486
c9c1d674 487 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
488 }
489
dda8d76d 490 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 491 {
049b0c3a 492 if (reason)
66cfc0fd
AM
493 error (_("Unable to read in %s bytes of %s\n"),
494 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
495 if (mvar != var)
496 free (mvar);
497 return NULL;
498 }
499
500 return mvar;
501}
502
32ec8896
NC
503/* Print a VMA value in the MODE specified.
504 Returns the number of characters displayed. */
cb8f3167 505
32ec8896 506static unsigned int
14a91970 507print_vma (bfd_vma vma, print_mode mode)
66543521 508{
32ec8896 509 unsigned int nc = 0;
66543521 510
14a91970 511 switch (mode)
66543521 512 {
14a91970
AM
513 case FULL_HEX:
514 nc = printf ("0x");
1a0670f3 515 /* Fall through. */
14a91970 516 case LONG_HEX:
f7a99963 517#ifdef BFD64
14a91970 518 if (is_32bit_elf)
437c2fb7 519 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 520#endif
14a91970
AM
521 printf_vma (vma);
522 return nc + 16;
b19aac67 523
14a91970
AM
524 case DEC_5:
525 if (vma <= 99999)
526 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 527 /* Fall through. */
14a91970
AM
528 case PREFIX_HEX:
529 nc = printf ("0x");
1a0670f3 530 /* Fall through. */
14a91970
AM
531 case HEX:
532 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 533
047c3dbf
NL
534 case PREFIX_HEX_5:
535 nc = printf ("0x");
536 /* Fall through. */
537 case HEX_5:
538 return nc + printf ("%05" BFD_VMA_FMT "x", vma);
539
14a91970
AM
540 case DEC:
541 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 542
14a91970
AM
543 case UNSIGNED:
544 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896 545
047c3dbf
NL
546 case UNSIGNED_5:
547 return printf ("%5" BFD_VMA_FMT "u", vma);
548
549 case OCTAL:
550 return printf ("%" BFD_VMA_FMT "o", vma);
551
552 case OCTAL_5:
553 return printf ("%5" BFD_VMA_FMT "o", vma);
554
32ec8896
NC
555 default:
556 /* FIXME: Report unrecognised mode ? */
557 return 0;
f7a99963 558 }
f7a99963
NC
559}
560
047c3dbf 561
7bfd842d 562/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 563 multibye characters (assuming the host environment supports them).
31104126 564
7bfd842d
NC
565 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
566
0942c7ab
NC
567 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
568 abs(WIDTH) - 5 characters followed by "[...]".
569
7bfd842d
NC
570 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
571 padding as necessary.
171191ba
NC
572
573 Returns the number of emitted characters. */
574
575static unsigned int
0942c7ab 576print_symbol (signed int width, const char * symbol)
31104126 577{
015dc7e1
AM
578 bool extra_padding = false;
579 bool do_dots = false;
32ec8896 580 signed int num_printed = 0;
3bfcb652 581#ifdef HAVE_MBSTATE_T
7bfd842d 582 mbstate_t state;
3bfcb652 583#endif
32ec8896 584 unsigned int width_remaining;
79bc120c 585 const void * alloced_symbol = NULL;
961c521f 586
7bfd842d 587 if (width < 0)
961c521f 588 {
88305e1b 589 /* Keep the width positive. This helps the code below. */
961c521f 590 width = - width;
015dc7e1 591 extra_padding = true;
0b4362b0 592 }
56d8f8a9
NC
593 else if (width == 0)
594 return 0;
961c521f 595
7bfd842d
NC
596 if (do_wide)
597 /* Set the remaining width to a very large value.
598 This simplifies the code below. */
599 width_remaining = INT_MAX;
600 else
0942c7ab
NC
601 {
602 width_remaining = width;
603 if (! do_not_show_symbol_truncation
604 && (int) strlen (symbol) > width)
605 {
606 width_remaining -= 5;
607 if ((int) width_remaining < 0)
608 width_remaining = 0;
015dc7e1 609 do_dots = true;
0942c7ab
NC
610 }
611 }
cb8f3167 612
3bfcb652 613#ifdef HAVE_MBSTATE_T
7bfd842d
NC
614 /* Initialise the multibyte conversion state. */
615 memset (& state, 0, sizeof (state));
3bfcb652 616#endif
961c521f 617
79bc120c
NC
618 if (do_demangle && *symbol)
619 {
620 const char * res = cplus_demangle (symbol, demangle_flags);
621
622 if (res != NULL)
623 alloced_symbol = symbol = res;
624 }
625
7bfd842d
NC
626 while (width_remaining)
627 {
628 size_t n;
7bfd842d 629 const char c = *symbol++;
961c521f 630
7bfd842d 631 if (c == 0)
961c521f
NC
632 break;
633
7bfd842d
NC
634 /* Do not print control characters directly as they can affect terminal
635 settings. Such characters usually appear in the names generated
636 by the assembler for local labels. */
637 if (ISCNTRL (c))
961c521f 638 {
7bfd842d 639 if (width_remaining < 2)
961c521f
NC
640 break;
641
7bfd842d
NC
642 printf ("^%c", c + 0x40);
643 width_remaining -= 2;
171191ba 644 num_printed += 2;
961c521f 645 }
7bfd842d
NC
646 else if (ISPRINT (c))
647 {
648 putchar (c);
649 width_remaining --;
650 num_printed ++;
651 }
961c521f
NC
652 else
653 {
3bfcb652
NC
654#ifdef HAVE_MBSTATE_T
655 wchar_t w;
656#endif
7bfd842d
NC
657 /* Let printf do the hard work of displaying multibyte characters. */
658 printf ("%.1s", symbol - 1);
659 width_remaining --;
660 num_printed ++;
661
3bfcb652 662#ifdef HAVE_MBSTATE_T
7bfd842d
NC
663 /* Try to find out how many bytes made up the character that was
664 just printed. Advance the symbol pointer past the bytes that
665 were displayed. */
666 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
667#else
668 n = 1;
669#endif
7bfd842d
NC
670 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
671 symbol += (n - 1);
961c521f 672 }
961c521f 673 }
171191ba 674
0942c7ab
NC
675 if (do_dots)
676 num_printed += printf ("[...]");
677
7bfd842d 678 if (extra_padding && num_printed < width)
171191ba
NC
679 {
680 /* Fill in the remaining spaces. */
7bfd842d
NC
681 printf ("%-*s", width - num_printed, " ");
682 num_printed = width;
171191ba
NC
683 }
684
79bc120c 685 free ((void *) alloced_symbol);
171191ba 686 return num_printed;
31104126
NC
687}
688
1449284b 689/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
690 the given section's name. Like print_symbol, except that it does not try
691 to print multibyte characters, it just interprets them as hex values. */
692
693static const char *
dda8d76d 694printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 695{
ca0e11aa 696#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 697 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
b9e920ec 698 const char * name = SECTION_NAME_PRINT (sec);
74e1a04b
NC
699 char * buf = sec_name_buf;
700 char c;
701 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
702
703 while ((c = * name ++) != 0)
704 {
705 if (ISCNTRL (c))
706 {
707 if (remaining < 2)
708 break;
948f632f 709
74e1a04b
NC
710 * buf ++ = '^';
711 * buf ++ = c + 0x40;
712 remaining -= 2;
713 }
714 else if (ISPRINT (c))
715 {
716 * buf ++ = c;
717 remaining -= 1;
718 }
719 else
720 {
721 static char hex[17] = "0123456789ABCDEF";
722
723 if (remaining < 4)
724 break;
725 * buf ++ = '<';
726 * buf ++ = hex[(c & 0xf0) >> 4];
727 * buf ++ = hex[c & 0x0f];
728 * buf ++ = '>';
729 remaining -= 4;
730 }
731
732 if (remaining == 0)
733 break;
734 }
735
736 * buf = 0;
737 return sec_name_buf;
738}
739
740static const char *
dda8d76d 741printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 742{
dda8d76d 743 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
744 return _("<corrupt>");
745
dda8d76d 746 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
747}
748
89fac5e3
RS
749/* Return a pointer to section NAME, or NULL if no such section exists. */
750
751static Elf_Internal_Shdr *
dda8d76d 752find_section (Filedata * filedata, const char * name)
89fac5e3
RS
753{
754 unsigned int i;
755
68807c3c
NC
756 if (filedata->section_headers == NULL)
757 return NULL;
dda8d76d
NC
758
759 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
760 if (SECTION_NAME_VALID (filedata->section_headers + i)
761 && streq (SECTION_NAME (filedata->section_headers + i), name))
dda8d76d 762 return filedata->section_headers + i;
89fac5e3
RS
763
764 return NULL;
765}
766
0b6ae522
DJ
767/* Return a pointer to a section containing ADDR, or NULL if no such
768 section exists. */
769
770static Elf_Internal_Shdr *
dda8d76d 771find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
772{
773 unsigned int i;
774
68807c3c
NC
775 if (filedata->section_headers == NULL)
776 return NULL;
777
dda8d76d 778 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 779 {
dda8d76d
NC
780 Elf_Internal_Shdr *sec = filedata->section_headers + i;
781
0b6ae522
DJ
782 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
783 return sec;
784 }
785
786 return NULL;
787}
788
071436c6 789static Elf_Internal_Shdr *
dda8d76d 790find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
791{
792 unsigned int i;
793
68807c3c
NC
794 if (filedata->section_headers == NULL)
795 return NULL;
796
dda8d76d 797 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 798 {
dda8d76d
NC
799 Elf_Internal_Shdr *sec = filedata->section_headers + i;
800
071436c6
NC
801 if (sec->sh_type == type)
802 return sec;
803 }
804
805 return NULL;
806}
807
657d0d47
CC
808/* Return a pointer to section NAME, or NULL if no such section exists,
809 restricted to the list of sections given in SET. */
810
811static Elf_Internal_Shdr *
dda8d76d 812find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
813{
814 unsigned int i;
815
68807c3c
NC
816 if (filedata->section_headers == NULL)
817 return NULL;
818
657d0d47
CC
819 if (set != NULL)
820 {
821 while ((i = *set++) > 0)
b814a36d
NC
822 {
823 /* See PR 21156 for a reproducer. */
dda8d76d 824 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
825 continue; /* FIXME: Should we issue an error message ? */
826
b9e920ec
AM
827 if (SECTION_NAME_VALID (filedata->section_headers + i)
828 && streq (SECTION_NAME (filedata->section_headers + i), name))
dda8d76d 829 return filedata->section_headers + i;
b814a36d 830 }
657d0d47
CC
831 }
832
dda8d76d 833 return find_section (filedata, name);
657d0d47
CC
834}
835
32ec8896 836/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
837 This OS has so many departures from the ELF standard that we test it at
838 many places. */
839
015dc7e1 840static inline bool
dda8d76d 841is_ia64_vms (Filedata * filedata)
28f997cf 842{
dda8d76d
NC
843 return filedata->file_header.e_machine == EM_IA_64
844 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
845}
846
bcedfee6 847/* Guess the relocation size commonly used by the specific machines. */
252b5132 848
015dc7e1 849static bool
2dc4cec1 850guess_is_rela (unsigned int e_machine)
252b5132 851{
9c19a809 852 switch (e_machine)
252b5132
RH
853 {
854 /* Targets that use REL relocations. */
252b5132 855 case EM_386:
22abe556 856 case EM_IAMCU:
f954747f 857 case EM_960:
e9f53129 858 case EM_ARM:
2b0337b0 859 case EM_D10V:
252b5132 860 case EM_CYGNUS_D10V:
e9f53129 861 case EM_DLX:
252b5132 862 case EM_MIPS:
4fe85591 863 case EM_MIPS_RS3_LE:
e9f53129 864 case EM_CYGNUS_M32R:
1c0d3aa6 865 case EM_SCORE:
f6c1a2d5 866 case EM_XGATE:
fe944acf 867 case EM_NFP:
aca4efc7 868 case EM_BPF:
015dc7e1 869 return false;
103f02d3 870
252b5132
RH
871 /* Targets that use RELA relocations. */
872 case EM_68K:
f954747f 873 case EM_860:
a06ea964 874 case EM_AARCH64:
cfb8c092 875 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
876 case EM_ALPHA:
877 case EM_ALTERA_NIOS2:
886a2506
NC
878 case EM_ARC:
879 case EM_ARC_COMPACT:
880 case EM_ARC_COMPACT2:
e9f53129
AM
881 case EM_AVR:
882 case EM_AVR_OLD:
883 case EM_BLACKFIN:
60bca95a 884 case EM_CR16:
e9f53129
AM
885 case EM_CRIS:
886 case EM_CRX:
b8891f8d 887 case EM_CSKY:
2b0337b0 888 case EM_D30V:
252b5132 889 case EM_CYGNUS_D30V:
2b0337b0 890 case EM_FR30:
3f8107ab 891 case EM_FT32:
252b5132 892 case EM_CYGNUS_FR30:
5c70f934 893 case EM_CYGNUS_FRV:
e9f53129
AM
894 case EM_H8S:
895 case EM_H8_300:
896 case EM_H8_300H:
800eeca4 897 case EM_IA_64:
1e4cf259
NC
898 case EM_IP2K:
899 case EM_IP2K_OLD:
3b36097d 900 case EM_IQ2000:
84e94c90 901 case EM_LATTICEMICO32:
ff7eeb89 902 case EM_M32C_OLD:
49f58d10 903 case EM_M32C:
e9f53129
AM
904 case EM_M32R:
905 case EM_MCORE:
15ab5209 906 case EM_CYGNUS_MEP:
a3c62988 907 case EM_METAG:
e9f53129
AM
908 case EM_MMIX:
909 case EM_MN10200:
910 case EM_CYGNUS_MN10200:
911 case EM_MN10300:
912 case EM_CYGNUS_MN10300:
5506d11a 913 case EM_MOXIE:
e9f53129
AM
914 case EM_MSP430:
915 case EM_MSP430_OLD:
d031aafb 916 case EM_MT:
35c08157 917 case EM_NDS32:
64fd6348 918 case EM_NIOS32:
73589c9d 919 case EM_OR1K:
e9f53129
AM
920 case EM_PPC64:
921 case EM_PPC:
2b100bb5 922 case EM_TI_PRU:
e23eba97 923 case EM_RISCV:
99c513f6 924 case EM_RL78:
c7927a3c 925 case EM_RX:
e9f53129
AM
926 case EM_S390:
927 case EM_S390_OLD:
928 case EM_SH:
929 case EM_SPARC:
930 case EM_SPARC32PLUS:
931 case EM_SPARCV9:
932 case EM_SPU:
40b36596 933 case EM_TI_C6000:
aa137e4d
NC
934 case EM_TILEGX:
935 case EM_TILEPRO:
708e2187 936 case EM_V800:
e9f53129
AM
937 case EM_V850:
938 case EM_CYGNUS_V850:
939 case EM_VAX:
619ed720 940 case EM_VISIUM:
e9f53129 941 case EM_X86_64:
8a9036a4 942 case EM_L1OM:
7a9068fe 943 case EM_K1OM:
e9f53129
AM
944 case EM_XSTORMY16:
945 case EM_XTENSA:
946 case EM_XTENSA_OLD:
7ba29e2a
NC
947 case EM_MICROBLAZE:
948 case EM_MICROBLAZE_OLD:
f96bd6c2 949 case EM_WEBASSEMBLY:
015dc7e1 950 return true;
103f02d3 951
e9f53129
AM
952 case EM_68HC05:
953 case EM_68HC08:
954 case EM_68HC11:
955 case EM_68HC16:
956 case EM_FX66:
957 case EM_ME16:
d1133906 958 case EM_MMA:
d1133906
NC
959 case EM_NCPU:
960 case EM_NDR1:
e9f53129 961 case EM_PCP:
d1133906 962 case EM_ST100:
e9f53129 963 case EM_ST19:
d1133906 964 case EM_ST7:
e9f53129
AM
965 case EM_ST9PLUS:
966 case EM_STARCORE:
d1133906 967 case EM_SVX:
e9f53129 968 case EM_TINYJ:
9c19a809
NC
969 default:
970 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 971 return false;
9c19a809
NC
972 }
973}
252b5132 974
dda8d76d 975/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
976 Returns TRUE upon success, FALSE otherwise. If successful then a
977 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
978 and the number of relocs loaded is placed in *NRELASP. It is the caller's
979 responsibility to free the allocated buffer. */
980
015dc7e1 981static bool
dda8d76d
NC
982slurp_rela_relocs (Filedata * filedata,
983 unsigned long rel_offset,
984 unsigned long rel_size,
985 Elf_Internal_Rela ** relasp,
986 unsigned long * nrelasp)
9c19a809 987{
2cf0635d 988 Elf_Internal_Rela * relas;
8b73c356 989 size_t nrelas;
4d6ed7c8 990 unsigned int i;
252b5132 991
4d6ed7c8
NC
992 if (is_32bit_elf)
993 {
2cf0635d 994 Elf32_External_Rela * erelas;
103f02d3 995
dda8d76d 996 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 997 rel_size, _("32-bit relocation data"));
a6e9f9df 998 if (!erelas)
015dc7e1 999 return false;
252b5132 1000
4d6ed7c8 1001 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1002
3f5e193b
NC
1003 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1004 sizeof (Elf_Internal_Rela));
103f02d3 1005
4d6ed7c8
NC
1006 if (relas == NULL)
1007 {
c256ffe7 1008 free (erelas);
591a748a 1009 error (_("out of memory parsing relocs\n"));
015dc7e1 1010 return false;
4d6ed7c8 1011 }
103f02d3 1012
4d6ed7c8
NC
1013 for (i = 0; i < nrelas; i++)
1014 {
1015 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1016 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1017 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1018 }
103f02d3 1019
4d6ed7c8
NC
1020 free (erelas);
1021 }
1022 else
1023 {
2cf0635d 1024 Elf64_External_Rela * erelas;
103f02d3 1025
dda8d76d 1026 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1027 rel_size, _("64-bit relocation data"));
a6e9f9df 1028 if (!erelas)
015dc7e1 1029 return false;
4d6ed7c8
NC
1030
1031 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1032
3f5e193b
NC
1033 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1034 sizeof (Elf_Internal_Rela));
103f02d3 1035
4d6ed7c8
NC
1036 if (relas == NULL)
1037 {
c256ffe7 1038 free (erelas);
591a748a 1039 error (_("out of memory parsing relocs\n"));
015dc7e1 1040 return false;
9c19a809 1041 }
4d6ed7c8
NC
1042
1043 for (i = 0; i < nrelas; i++)
9c19a809 1044 {
66543521
AM
1045 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1046 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1047 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1048
1049 /* The #ifdef BFD64 below is to prevent a compile time
1050 warning. We know that if we do not have a 64 bit data
1051 type that we will never execute this code anyway. */
1052#ifdef BFD64
dda8d76d
NC
1053 if (filedata->file_header.e_machine == EM_MIPS
1054 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1055 {
1056 /* In little-endian objects, r_info isn't really a
1057 64-bit little-endian value: it has a 32-bit
1058 little-endian symbol index followed by four
1059 individual byte fields. Reorder INFO
1060 accordingly. */
91d6fa6a
NC
1061 bfd_vma inf = relas[i].r_info;
1062 inf = (((inf & 0xffffffff) << 32)
1063 | ((inf >> 56) & 0xff)
1064 | ((inf >> 40) & 0xff00)
1065 | ((inf >> 24) & 0xff0000)
1066 | ((inf >> 8) & 0xff000000));
1067 relas[i].r_info = inf;
861fb55a
DJ
1068 }
1069#endif /* BFD64 */
4d6ed7c8 1070 }
103f02d3 1071
4d6ed7c8
NC
1072 free (erelas);
1073 }
32ec8896 1074
4d6ed7c8
NC
1075 *relasp = relas;
1076 *nrelasp = nrelas;
015dc7e1 1077 return true;
4d6ed7c8 1078}
103f02d3 1079
dda8d76d 1080/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1081 Returns TRUE upon success, FALSE otherwise. If successful then a
1082 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1083 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1084 responsibility to free the allocated buffer. */
1085
015dc7e1 1086static bool
dda8d76d
NC
1087slurp_rel_relocs (Filedata * filedata,
1088 unsigned long rel_offset,
1089 unsigned long rel_size,
1090 Elf_Internal_Rela ** relsp,
1091 unsigned long * nrelsp)
4d6ed7c8 1092{
2cf0635d 1093 Elf_Internal_Rela * rels;
8b73c356 1094 size_t nrels;
4d6ed7c8 1095 unsigned int i;
103f02d3 1096
4d6ed7c8
NC
1097 if (is_32bit_elf)
1098 {
2cf0635d 1099 Elf32_External_Rel * erels;
103f02d3 1100
dda8d76d 1101 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1102 rel_size, _("32-bit relocation data"));
a6e9f9df 1103 if (!erels)
015dc7e1 1104 return false;
103f02d3 1105
4d6ed7c8 1106 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1107
3f5e193b 1108 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1109
4d6ed7c8
NC
1110 if (rels == NULL)
1111 {
c256ffe7 1112 free (erels);
591a748a 1113 error (_("out of memory parsing relocs\n"));
015dc7e1 1114 return false;
4d6ed7c8
NC
1115 }
1116
1117 for (i = 0; i < nrels; i++)
1118 {
1119 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1120 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1121 rels[i].r_addend = 0;
9ea033b2 1122 }
4d6ed7c8
NC
1123
1124 free (erels);
9c19a809
NC
1125 }
1126 else
1127 {
2cf0635d 1128 Elf64_External_Rel * erels;
9ea033b2 1129
dda8d76d 1130 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1131 rel_size, _("64-bit relocation data"));
a6e9f9df 1132 if (!erels)
015dc7e1 1133 return false;
103f02d3 1134
4d6ed7c8 1135 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1136
3f5e193b 1137 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1138
4d6ed7c8 1139 if (rels == NULL)
9c19a809 1140 {
c256ffe7 1141 free (erels);
591a748a 1142 error (_("out of memory parsing relocs\n"));
015dc7e1 1143 return false;
4d6ed7c8 1144 }
103f02d3 1145
4d6ed7c8
NC
1146 for (i = 0; i < nrels; i++)
1147 {
66543521
AM
1148 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1149 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1150 rels[i].r_addend = 0;
861fb55a
DJ
1151
1152 /* The #ifdef BFD64 below is to prevent a compile time
1153 warning. We know that if we do not have a 64 bit data
1154 type that we will never execute this code anyway. */
1155#ifdef BFD64
dda8d76d
NC
1156 if (filedata->file_header.e_machine == EM_MIPS
1157 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1158 {
1159 /* In little-endian objects, r_info isn't really a
1160 64-bit little-endian value: it has a 32-bit
1161 little-endian symbol index followed by four
1162 individual byte fields. Reorder INFO
1163 accordingly. */
91d6fa6a
NC
1164 bfd_vma inf = rels[i].r_info;
1165 inf = (((inf & 0xffffffff) << 32)
1166 | ((inf >> 56) & 0xff)
1167 | ((inf >> 40) & 0xff00)
1168 | ((inf >> 24) & 0xff0000)
1169 | ((inf >> 8) & 0xff000000));
1170 rels[i].r_info = inf;
861fb55a
DJ
1171 }
1172#endif /* BFD64 */
4d6ed7c8 1173 }
103f02d3 1174
4d6ed7c8
NC
1175 free (erels);
1176 }
32ec8896 1177
4d6ed7c8
NC
1178 *relsp = rels;
1179 *nrelsp = nrels;
015dc7e1 1180 return true;
4d6ed7c8 1181}
103f02d3 1182
aca88567
NC
1183/* Returns the reloc type extracted from the reloc info field. */
1184
1185static unsigned int
dda8d76d 1186get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1187{
1188 if (is_32bit_elf)
1189 return ELF32_R_TYPE (reloc_info);
1190
dda8d76d 1191 switch (filedata->file_header.e_machine)
aca88567
NC
1192 {
1193 case EM_MIPS:
1194 /* Note: We assume that reloc_info has already been adjusted for us. */
1195 return ELF64_MIPS_R_TYPE (reloc_info);
1196
1197 case EM_SPARCV9:
1198 return ELF64_R_TYPE_ID (reloc_info);
1199
1200 default:
1201 return ELF64_R_TYPE (reloc_info);
1202 }
1203}
1204
1205/* Return the symbol index extracted from the reloc info field. */
1206
1207static bfd_vma
1208get_reloc_symindex (bfd_vma reloc_info)
1209{
1210 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1211}
1212
015dc7e1 1213static inline bool
dda8d76d 1214uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1215{
1216 return
dda8d76d 1217 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1218 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1219 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1220 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1221 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1222}
1223
d3ba0551
AM
1224/* Display the contents of the relocation data found at the specified
1225 offset. */
ee42cf8c 1226
015dc7e1 1227static bool
dda8d76d
NC
1228dump_relocations (Filedata * filedata,
1229 unsigned long rel_offset,
1230 unsigned long rel_size,
1231 Elf_Internal_Sym * symtab,
1232 unsigned long nsyms,
1233 char * strtab,
1234 unsigned long strtablen,
1235 int is_rela,
015dc7e1 1236 bool is_dynsym)
4d6ed7c8 1237{
32ec8896 1238 unsigned long i;
2cf0635d 1239 Elf_Internal_Rela * rels;
015dc7e1 1240 bool res = true;
103f02d3 1241
4d6ed7c8 1242 if (is_rela == UNKNOWN)
dda8d76d 1243 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1244
4d6ed7c8
NC
1245 if (is_rela)
1246 {
dda8d76d 1247 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1248 return false;
4d6ed7c8
NC
1249 }
1250 else
1251 {
dda8d76d 1252 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1253 return false;
252b5132
RH
1254 }
1255
410f7a12
L
1256 if (is_32bit_elf)
1257 {
1258 if (is_rela)
2c71103e
NC
1259 {
1260 if (do_wide)
1261 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1262 else
1263 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1264 }
410f7a12 1265 else
2c71103e
NC
1266 {
1267 if (do_wide)
1268 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1269 else
1270 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1271 }
410f7a12 1272 }
252b5132 1273 else
410f7a12
L
1274 {
1275 if (is_rela)
2c71103e
NC
1276 {
1277 if (do_wide)
8beeaeb7 1278 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1279 else
1280 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1281 }
410f7a12 1282 else
2c71103e
NC
1283 {
1284 if (do_wide)
8beeaeb7 1285 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1286 else
1287 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1288 }
410f7a12 1289 }
252b5132
RH
1290
1291 for (i = 0; i < rel_size; i++)
1292 {
2cf0635d 1293 const char * rtype;
b34976b6 1294 bfd_vma offset;
91d6fa6a 1295 bfd_vma inf;
b34976b6
AM
1296 bfd_vma symtab_index;
1297 bfd_vma type;
103f02d3 1298
b34976b6 1299 offset = rels[i].r_offset;
91d6fa6a 1300 inf = rels[i].r_info;
103f02d3 1301
dda8d76d 1302 type = get_reloc_type (filedata, inf);
91d6fa6a 1303 symtab_index = get_reloc_symindex (inf);
252b5132 1304
410f7a12
L
1305 if (is_32bit_elf)
1306 {
39dbeff8
AM
1307 printf ("%8.8lx %8.8lx ",
1308 (unsigned long) offset & 0xffffffff,
91d6fa6a 1309 (unsigned long) inf & 0xffffffff);
410f7a12
L
1310 }
1311 else
1312 {
39dbeff8 1313 printf (do_wide
d1ce973e
AM
1314 ? "%16.16" BFD_VMA_FMT "x %16.16" BFD_VMA_FMT "x "
1315 : "%12.12" BFD_VMA_FMT "x %12.12" BFD_VMA_FMT "x ",
91d6fa6a 1316 offset, inf);
410f7a12 1317 }
103f02d3 1318
dda8d76d 1319 switch (filedata->file_header.e_machine)
252b5132
RH
1320 {
1321 default:
1322 rtype = NULL;
1323 break;
1324
a06ea964
NC
1325 case EM_AARCH64:
1326 rtype = elf_aarch64_reloc_type (type);
1327 break;
1328
2b0337b0 1329 case EM_M32R:
252b5132 1330 case EM_CYGNUS_M32R:
9ea033b2 1331 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1332 break;
1333
1334 case EM_386:
22abe556 1335 case EM_IAMCU:
9ea033b2 1336 rtype = elf_i386_reloc_type (type);
252b5132
RH
1337 break;
1338
ba2685cc
AM
1339 case EM_68HC11:
1340 case EM_68HC12:
1341 rtype = elf_m68hc11_reloc_type (type);
1342 break;
75751cd9 1343
7b4ae824
JD
1344 case EM_S12Z:
1345 rtype = elf_s12z_reloc_type (type);
1346 break;
1347
252b5132 1348 case EM_68K:
9ea033b2 1349 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1350 break;
1351
f954747f
AM
1352 case EM_960:
1353 rtype = elf_i960_reloc_type (type);
1354 break;
1355
adde6300 1356 case EM_AVR:
2b0337b0 1357 case EM_AVR_OLD:
adde6300
AM
1358 rtype = elf_avr_reloc_type (type);
1359 break;
1360
9ea033b2
NC
1361 case EM_OLD_SPARCV9:
1362 case EM_SPARC32PLUS:
1363 case EM_SPARCV9:
252b5132 1364 case EM_SPARC:
9ea033b2 1365 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1366 break;
1367
e9f53129
AM
1368 case EM_SPU:
1369 rtype = elf_spu_reloc_type (type);
1370 break;
1371
708e2187
NC
1372 case EM_V800:
1373 rtype = v800_reloc_type (type);
1374 break;
2b0337b0 1375 case EM_V850:
252b5132 1376 case EM_CYGNUS_V850:
9ea033b2 1377 rtype = v850_reloc_type (type);
252b5132
RH
1378 break;
1379
2b0337b0 1380 case EM_D10V:
252b5132 1381 case EM_CYGNUS_D10V:
9ea033b2 1382 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1383 break;
1384
2b0337b0 1385 case EM_D30V:
252b5132 1386 case EM_CYGNUS_D30V:
9ea033b2 1387 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1388 break;
1389
d172d4ba
NC
1390 case EM_DLX:
1391 rtype = elf_dlx_reloc_type (type);
1392 break;
1393
252b5132 1394 case EM_SH:
9ea033b2 1395 rtype = elf_sh_reloc_type (type);
252b5132
RH
1396 break;
1397
2b0337b0 1398 case EM_MN10300:
252b5132 1399 case EM_CYGNUS_MN10300:
9ea033b2 1400 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1401 break;
1402
2b0337b0 1403 case EM_MN10200:
252b5132 1404 case EM_CYGNUS_MN10200:
9ea033b2 1405 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1406 break;
1407
2b0337b0 1408 case EM_FR30:
252b5132 1409 case EM_CYGNUS_FR30:
9ea033b2 1410 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1411 break;
1412
ba2685cc
AM
1413 case EM_CYGNUS_FRV:
1414 rtype = elf_frv_reloc_type (type);
1415 break;
5c70f934 1416
b8891f8d
AJ
1417 case EM_CSKY:
1418 rtype = elf_csky_reloc_type (type);
1419 break;
1420
3f8107ab
AM
1421 case EM_FT32:
1422 rtype = elf_ft32_reloc_type (type);
1423 break;
1424
252b5132 1425 case EM_MCORE:
9ea033b2 1426 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1427 break;
1428
3c3bdf30
NC
1429 case EM_MMIX:
1430 rtype = elf_mmix_reloc_type (type);
1431 break;
1432
5506d11a
AM
1433 case EM_MOXIE:
1434 rtype = elf_moxie_reloc_type (type);
1435 break;
1436
2469cfa2 1437 case EM_MSP430:
dda8d76d 1438 if (uses_msp430x_relocs (filedata))
13761a11
NC
1439 {
1440 rtype = elf_msp430x_reloc_type (type);
1441 break;
1442 }
1a0670f3 1443 /* Fall through. */
2469cfa2
NC
1444 case EM_MSP430_OLD:
1445 rtype = elf_msp430_reloc_type (type);
1446 break;
1447
35c08157
KLC
1448 case EM_NDS32:
1449 rtype = elf_nds32_reloc_type (type);
1450 break;
1451
252b5132 1452 case EM_PPC:
9ea033b2 1453 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1454 break;
1455
c833c019
AM
1456 case EM_PPC64:
1457 rtype = elf_ppc64_reloc_type (type);
1458 break;
1459
252b5132 1460 case EM_MIPS:
4fe85591 1461 case EM_MIPS_RS3_LE:
9ea033b2 1462 rtype = elf_mips_reloc_type (type);
252b5132
RH
1463 break;
1464
e23eba97
NC
1465 case EM_RISCV:
1466 rtype = elf_riscv_reloc_type (type);
1467 break;
1468
252b5132 1469 case EM_ALPHA:
9ea033b2 1470 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1471 break;
1472
1473 case EM_ARM:
9ea033b2 1474 rtype = elf_arm_reloc_type (type);
252b5132
RH
1475 break;
1476
584da044 1477 case EM_ARC:
886a2506
NC
1478 case EM_ARC_COMPACT:
1479 case EM_ARC_COMPACT2:
9ea033b2 1480 rtype = elf_arc_reloc_type (type);
252b5132
RH
1481 break;
1482
1483 case EM_PARISC:
69e617ca 1484 rtype = elf_hppa_reloc_type (type);
252b5132 1485 break;
7d466069 1486
b8720f9d
JL
1487 case EM_H8_300:
1488 case EM_H8_300H:
1489 case EM_H8S:
1490 rtype = elf_h8_reloc_type (type);
1491 break;
1492
73589c9d
CS
1493 case EM_OR1K:
1494 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1495 break;
1496
7d466069 1497 case EM_PJ:
2b0337b0 1498 case EM_PJ_OLD:
7d466069
ILT
1499 rtype = elf_pj_reloc_type (type);
1500 break;
800eeca4
JW
1501 case EM_IA_64:
1502 rtype = elf_ia64_reloc_type (type);
1503 break;
1b61cf92
HPN
1504
1505 case EM_CRIS:
1506 rtype = elf_cris_reloc_type (type);
1507 break;
535c37ff 1508
f954747f
AM
1509 case EM_860:
1510 rtype = elf_i860_reloc_type (type);
1511 break;
1512
bcedfee6 1513 case EM_X86_64:
8a9036a4 1514 case EM_L1OM:
7a9068fe 1515 case EM_K1OM:
bcedfee6
NC
1516 rtype = elf_x86_64_reloc_type (type);
1517 break;
a85d7ed0 1518
f954747f
AM
1519 case EM_S370:
1520 rtype = i370_reloc_type (type);
1521 break;
1522
53c7db4b
KH
1523 case EM_S390_OLD:
1524 case EM_S390:
1525 rtype = elf_s390_reloc_type (type);
1526 break;
93fbbb04 1527
1c0d3aa6
NC
1528 case EM_SCORE:
1529 rtype = elf_score_reloc_type (type);
1530 break;
1531
93fbbb04
GK
1532 case EM_XSTORMY16:
1533 rtype = elf_xstormy16_reloc_type (type);
1534 break;
179d3252 1535
1fe1f39c
NC
1536 case EM_CRX:
1537 rtype = elf_crx_reloc_type (type);
1538 break;
1539
179d3252
JT
1540 case EM_VAX:
1541 rtype = elf_vax_reloc_type (type);
1542 break;
1e4cf259 1543
619ed720
EB
1544 case EM_VISIUM:
1545 rtype = elf_visium_reloc_type (type);
1546 break;
1547
aca4efc7
JM
1548 case EM_BPF:
1549 rtype = elf_bpf_reloc_type (type);
1550 break;
1551
cfb8c092
NC
1552 case EM_ADAPTEVA_EPIPHANY:
1553 rtype = elf_epiphany_reloc_type (type);
1554 break;
1555
1e4cf259
NC
1556 case EM_IP2K:
1557 case EM_IP2K_OLD:
1558 rtype = elf_ip2k_reloc_type (type);
1559 break;
3b36097d
SC
1560
1561 case EM_IQ2000:
1562 rtype = elf_iq2000_reloc_type (type);
1563 break;
88da6820
NC
1564
1565 case EM_XTENSA_OLD:
1566 case EM_XTENSA:
1567 rtype = elf_xtensa_reloc_type (type);
1568 break;
a34e3ecb 1569
84e94c90
NC
1570 case EM_LATTICEMICO32:
1571 rtype = elf_lm32_reloc_type (type);
1572 break;
1573
ff7eeb89 1574 case EM_M32C_OLD:
49f58d10
JB
1575 case EM_M32C:
1576 rtype = elf_m32c_reloc_type (type);
1577 break;
1578
d031aafb
NS
1579 case EM_MT:
1580 rtype = elf_mt_reloc_type (type);
a34e3ecb 1581 break;
1d65ded4
CM
1582
1583 case EM_BLACKFIN:
1584 rtype = elf_bfin_reloc_type (type);
1585 break;
15ab5209
DB
1586
1587 case EM_CYGNUS_MEP:
1588 rtype = elf_mep_reloc_type (type);
1589 break;
60bca95a
NC
1590
1591 case EM_CR16:
1592 rtype = elf_cr16_reloc_type (type);
1593 break;
dd24e3da 1594
7ba29e2a
NC
1595 case EM_MICROBLAZE:
1596 case EM_MICROBLAZE_OLD:
1597 rtype = elf_microblaze_reloc_type (type);
1598 break;
c7927a3c 1599
99c513f6
DD
1600 case EM_RL78:
1601 rtype = elf_rl78_reloc_type (type);
1602 break;
1603
c7927a3c
NC
1604 case EM_RX:
1605 rtype = elf_rx_reloc_type (type);
1606 break;
c29aca4a 1607
a3c62988
NC
1608 case EM_METAG:
1609 rtype = elf_metag_reloc_type (type);
1610 break;
1611
c29aca4a
NC
1612 case EM_XC16X:
1613 case EM_C166:
1614 rtype = elf_xc16x_reloc_type (type);
1615 break;
40b36596
JM
1616
1617 case EM_TI_C6000:
1618 rtype = elf_tic6x_reloc_type (type);
1619 break;
aa137e4d
NC
1620
1621 case EM_TILEGX:
1622 rtype = elf_tilegx_reloc_type (type);
1623 break;
1624
1625 case EM_TILEPRO:
1626 rtype = elf_tilepro_reloc_type (type);
1627 break;
f6c1a2d5 1628
f96bd6c2
PC
1629 case EM_WEBASSEMBLY:
1630 rtype = elf_wasm32_reloc_type (type);
1631 break;
1632
f6c1a2d5
NC
1633 case EM_XGATE:
1634 rtype = elf_xgate_reloc_type (type);
1635 break;
36591ba1
SL
1636
1637 case EM_ALTERA_NIOS2:
1638 rtype = elf_nios2_reloc_type (type);
1639 break;
2b100bb5
DD
1640
1641 case EM_TI_PRU:
1642 rtype = elf_pru_reloc_type (type);
1643 break;
fe944acf
FT
1644
1645 case EM_NFP:
1646 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1647 rtype = elf_nfp3200_reloc_type (type);
1648 else
1649 rtype = elf_nfp_reloc_type (type);
1650 break;
6655dba2
SB
1651
1652 case EM_Z80:
1653 rtype = elf_z80_reloc_type (type);
1654 break;
252b5132
RH
1655 }
1656
1657 if (rtype == NULL)
39dbeff8 1658 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1659 else
5c144731 1660 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1661
dda8d76d 1662 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1663 && rtype != NULL
7ace3541
RH
1664 && streq (rtype, "R_ALPHA_LITUSE")
1665 && is_rela)
1666 {
1667 switch (rels[i].r_addend)
1668 {
1669 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1670 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1671 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1672 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1673 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1674 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1675 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1676 default: rtype = NULL;
1677 }
32ec8896 1678
7ace3541
RH
1679 if (rtype)
1680 printf (" (%s)", rtype);
1681 else
1682 {
1683 putchar (' ');
1684 printf (_("<unknown addend: %lx>"),
1685 (unsigned long) rels[i].r_addend);
015dc7e1 1686 res = false;
7ace3541
RH
1687 }
1688 }
1689 else if (symtab_index)
252b5132 1690 {
af3fc3bc 1691 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1692 {
27a45f42
AS
1693 error (_(" bad symbol index: %08lx in reloc\n"),
1694 (unsigned long) symtab_index);
015dc7e1 1695 res = false;
32ec8896 1696 }
af3fc3bc 1697 else
19936277 1698 {
2cf0635d 1699 Elf_Internal_Sym * psym;
bb4d2ac2
L
1700 const char * version_string;
1701 enum versioned_symbol_info sym_info;
1702 unsigned short vna_other;
19936277 1703
af3fc3bc 1704 psym = symtab + symtab_index;
103f02d3 1705
bb4d2ac2 1706 version_string
dda8d76d 1707 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1708 strtab, strtablen,
1709 symtab_index,
1710 psym,
1711 &sym_info,
1712 &vna_other);
1713
af3fc3bc 1714 printf (" ");
171191ba 1715
d8045f23
NC
1716 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1717 {
1718 const char * name;
1719 unsigned int len;
1720 unsigned int width = is_32bit_elf ? 8 : 14;
1721
1722 /* Relocations against GNU_IFUNC symbols do not use the value
1723 of the symbol as the address to relocate against. Instead
1724 they invoke the function named by the symbol and use its
1725 result as the address for relocation.
1726
1727 To indicate this to the user, do not display the value of
1728 the symbol in the "Symbols's Value" field. Instead show
1729 its name followed by () as a hint that the symbol is
1730 invoked. */
1731
1732 if (strtab == NULL
1733 || psym->st_name == 0
1734 || psym->st_name >= strtablen)
1735 name = "??";
1736 else
1737 name = strtab + psym->st_name;
1738
1739 len = print_symbol (width, name);
bb4d2ac2
L
1740 if (version_string)
1741 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1742 version_string);
d8045f23
NC
1743 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1744 }
1745 else
1746 {
1747 print_vma (psym->st_value, LONG_HEX);
171191ba 1748
d8045f23
NC
1749 printf (is_32bit_elf ? " " : " ");
1750 }
103f02d3 1751
af3fc3bc 1752 if (psym->st_name == 0)
f1ef08cb 1753 {
2cf0635d 1754 const char * sec_name = "<null>";
f1ef08cb
AM
1755 char name_buf[40];
1756
1757 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1758 {
dda8d76d 1759 if (psym->st_shndx < filedata->file_header.e_shnum)
b9e920ec
AM
1760 sec_name = SECTION_NAME_PRINT (filedata->section_headers
1761 + psym->st_shndx);
f1ef08cb
AM
1762 else if (psym->st_shndx == SHN_ABS)
1763 sec_name = "ABS";
1764 else if (psym->st_shndx == SHN_COMMON)
1765 sec_name = "COMMON";
dda8d76d 1766 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1767 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1768 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1769 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1770 sec_name = "SCOMMON";
dda8d76d 1771 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1772 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1773 sec_name = "SUNDEF";
dda8d76d
NC
1774 else if ((filedata->file_header.e_machine == EM_X86_64
1775 || filedata->file_header.e_machine == EM_L1OM
1776 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1777 && psym->st_shndx == SHN_X86_64_LCOMMON)
1778 sec_name = "LARGE_COMMON";
dda8d76d
NC
1779 else if (filedata->file_header.e_machine == EM_IA_64
1780 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1781 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1782 sec_name = "ANSI_COM";
dda8d76d 1783 else if (is_ia64_vms (filedata)
148b93f2
NC
1784 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1785 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1786 else
1787 {
1788 sprintf (name_buf, "<section 0x%x>",
1789 (unsigned int) psym->st_shndx);
1790 sec_name = name_buf;
1791 }
1792 }
1793 print_symbol (22, sec_name);
1794 }
af3fc3bc 1795 else if (strtab == NULL)
d79b3d50 1796 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1797 else if (psym->st_name >= strtablen)
32ec8896 1798 {
27a45f42
AS
1799 error (_("<corrupt string table index: %3ld>\n"),
1800 psym->st_name);
015dc7e1 1801 res = false;
32ec8896 1802 }
af3fc3bc 1803 else
bb4d2ac2
L
1804 {
1805 print_symbol (22, strtab + psym->st_name);
1806 if (version_string)
1807 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1808 version_string);
1809 }
103f02d3 1810
af3fc3bc 1811 if (is_rela)
171191ba 1812 {
7360e63f 1813 bfd_vma off = rels[i].r_addend;
171191ba 1814
7360e63f 1815 if ((bfd_signed_vma) off < 0)
598aaa76 1816 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1817 else
598aaa76 1818 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1819 }
19936277 1820 }
252b5132 1821 }
1b228002 1822 else if (is_rela)
f7a99963 1823 {
7360e63f 1824 bfd_vma off = rels[i].r_addend;
e04d7088
L
1825
1826 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1827 if ((bfd_signed_vma) off < 0)
e04d7088
L
1828 printf ("-%" BFD_VMA_FMT "x", - off);
1829 else
1830 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1831 }
252b5132 1832
dda8d76d 1833 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1834 && rtype != NULL
1835 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1836 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1837
252b5132 1838 putchar ('\n');
2c71103e 1839
aca88567 1840#ifdef BFD64
dda8d76d 1841 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1842 {
91d6fa6a
NC
1843 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1844 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1845 const char * rtype2 = elf_mips_reloc_type (type2);
1846 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1847
2c71103e
NC
1848 printf (" Type2: ");
1849
1850 if (rtype2 == NULL)
39dbeff8
AM
1851 printf (_("unrecognized: %-7lx"),
1852 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1853 else
1854 printf ("%-17.17s", rtype2);
1855
18bd398b 1856 printf ("\n Type3: ");
2c71103e
NC
1857
1858 if (rtype3 == NULL)
39dbeff8
AM
1859 printf (_("unrecognized: %-7lx"),
1860 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1861 else
1862 printf ("%-17.17s", rtype3);
1863
53c7db4b 1864 putchar ('\n');
2c71103e 1865 }
aca88567 1866#endif /* BFD64 */
252b5132
RH
1867 }
1868
c8286bd1 1869 free (rels);
32ec8896
NC
1870
1871 return res;
252b5132
RH
1872}
1873
37c18eed
SD
1874static const char *
1875get_aarch64_dynamic_type (unsigned long type)
1876{
1877 switch (type)
1878 {
1879 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 1880 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 1881 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
1882 default:
1883 return NULL;
1884 }
1885}
1886
252b5132 1887static const char *
d3ba0551 1888get_mips_dynamic_type (unsigned long type)
252b5132
RH
1889{
1890 switch (type)
1891 {
1892 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1893 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1894 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1895 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1896 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1897 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1898 case DT_MIPS_MSYM: return "MIPS_MSYM";
1899 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1900 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1901 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1902 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1903 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1904 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1905 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1906 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1907 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1908 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1909 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1910 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1911 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1912 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1913 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1914 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1915 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1916 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1917 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1918 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1919 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1920 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1921 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1922 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1923 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1924 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1925 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1926 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1927 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1928 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1929 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1930 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1931 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1932 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1933 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1934 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1935 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1936 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1937 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 1938 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
1939 default:
1940 return NULL;
1941 }
1942}
1943
9a097730 1944static const char *
d3ba0551 1945get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1946{
1947 switch (type)
1948 {
1949 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1950 default:
1951 return NULL;
1952 }
103f02d3
UD
1953}
1954
7490d522
AM
1955static const char *
1956get_ppc_dynamic_type (unsigned long type)
1957{
1958 switch (type)
1959 {
a7f2871e 1960 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1961 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1962 default:
1963 return NULL;
1964 }
1965}
1966
f1cb7e17 1967static const char *
d3ba0551 1968get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1969{
1970 switch (type)
1971 {
a7f2871e
AM
1972 case DT_PPC64_GLINK: return "PPC64_GLINK";
1973 case DT_PPC64_OPD: return "PPC64_OPD";
1974 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1975 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1976 default:
1977 return NULL;
1978 }
1979}
1980
103f02d3 1981static const char *
d3ba0551 1982get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1983{
1984 switch (type)
1985 {
1986 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1987 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1988 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1989 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1990 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1991 case DT_HP_PREINIT: return "HP_PREINIT";
1992 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1993 case DT_HP_NEEDED: return "HP_NEEDED";
1994 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1995 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1996 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1997 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1998 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1999 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2000 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2001 case DT_HP_FILTERED: return "HP_FILTERED";
2002 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2003 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2004 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2005 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2006 case DT_PLT: return "PLT";
2007 case DT_PLT_SIZE: return "PLT_SIZE";
2008 case DT_DLT: return "DLT";
2009 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2010 default:
2011 return NULL;
2012 }
2013}
9a097730 2014
ecc51f48 2015static const char *
d3ba0551 2016get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2017{
2018 switch (type)
2019 {
148b93f2
NC
2020 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2021 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2022 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2023 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2024 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2025 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2026 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2027 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2028 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2029 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2030 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2031 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2032 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2033 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2034 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2035 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2036 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2037 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2038 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2039 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2040 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2041 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2042 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2043 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2044 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2045 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2046 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2047 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2048 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2049 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2050 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2051 default:
2052 return NULL;
2053 }
2054}
2055
fd85a6a1
NC
2056static const char *
2057get_solaris_section_type (unsigned long type)
2058{
2059 switch (type)
2060 {
2061 case 0x6fffffee: return "SUNW_ancillary";
2062 case 0x6fffffef: return "SUNW_capchain";
2063 case 0x6ffffff0: return "SUNW_capinfo";
2064 case 0x6ffffff1: return "SUNW_symsort";
2065 case 0x6ffffff2: return "SUNW_tlssort";
2066 case 0x6ffffff3: return "SUNW_LDYNSYM";
2067 case 0x6ffffff4: return "SUNW_dof";
2068 case 0x6ffffff5: return "SUNW_cap";
2069 case 0x6ffffff6: return "SUNW_SIGNATURE";
2070 case 0x6ffffff7: return "SUNW_ANNOTATE";
2071 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2072 case 0x6ffffff9: return "SUNW_DEBUG";
2073 case 0x6ffffffa: return "SUNW_move";
2074 case 0x6ffffffb: return "SUNW_COMDAT";
2075 case 0x6ffffffc: return "SUNW_syminfo";
2076 case 0x6ffffffd: return "SUNW_verdef";
2077 case 0x6ffffffe: return "SUNW_verneed";
2078 case 0x6fffffff: return "SUNW_versym";
2079 case 0x70000000: return "SPARC_GOTDATA";
2080 default: return NULL;
2081 }
2082}
2083
fabcb361
RH
2084static const char *
2085get_alpha_dynamic_type (unsigned long type)
2086{
2087 switch (type)
2088 {
2089 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2090 default: return NULL;
fabcb361
RH
2091 }
2092}
2093
1c0d3aa6
NC
2094static const char *
2095get_score_dynamic_type (unsigned long type)
2096{
2097 switch (type)
2098 {
2099 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2100 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2101 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2102 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2103 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2104 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2105 default: return NULL;
1c0d3aa6
NC
2106 }
2107}
2108
40b36596
JM
2109static const char *
2110get_tic6x_dynamic_type (unsigned long type)
2111{
2112 switch (type)
2113 {
2114 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2115 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2116 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2117 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2118 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2119 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2120 default: return NULL;
40b36596
JM
2121 }
2122}
1c0d3aa6 2123
36591ba1
SL
2124static const char *
2125get_nios2_dynamic_type (unsigned long type)
2126{
2127 switch (type)
2128 {
2129 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2130 default: return NULL;
36591ba1
SL
2131 }
2132}
2133
fd85a6a1
NC
2134static const char *
2135get_solaris_dynamic_type (unsigned long type)
2136{
2137 switch (type)
2138 {
2139 case 0x6000000d: return "SUNW_AUXILIARY";
2140 case 0x6000000e: return "SUNW_RTLDINF";
2141 case 0x6000000f: return "SUNW_FILTER";
2142 case 0x60000010: return "SUNW_CAP";
2143 case 0x60000011: return "SUNW_SYMTAB";
2144 case 0x60000012: return "SUNW_SYMSZ";
2145 case 0x60000013: return "SUNW_SORTENT";
2146 case 0x60000014: return "SUNW_SYMSORT";
2147 case 0x60000015: return "SUNW_SYMSORTSZ";
2148 case 0x60000016: return "SUNW_TLSSORT";
2149 case 0x60000017: return "SUNW_TLSSORTSZ";
2150 case 0x60000018: return "SUNW_CAPINFO";
2151 case 0x60000019: return "SUNW_STRPAD";
2152 case 0x6000001a: return "SUNW_CAPCHAIN";
2153 case 0x6000001b: return "SUNW_LDMACH";
2154 case 0x6000001d: return "SUNW_CAPCHAINENT";
2155 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2156 case 0x60000021: return "SUNW_PARENT";
2157 case 0x60000023: return "SUNW_ASLR";
2158 case 0x60000025: return "SUNW_RELAX";
2159 case 0x60000029: return "SUNW_NXHEAP";
2160 case 0x6000002b: return "SUNW_NXSTACK";
2161
2162 case 0x70000001: return "SPARC_REGISTER";
2163 case 0x7ffffffd: return "AUXILIARY";
2164 case 0x7ffffffe: return "USED";
2165 case 0x7fffffff: return "FILTER";
2166
15f205b1 2167 default: return NULL;
fd85a6a1
NC
2168 }
2169}
2170
252b5132 2171static const char *
dda8d76d 2172get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2173{
e9e44622 2174 static char buff[64];
252b5132
RH
2175
2176 switch (type)
2177 {
2178 case DT_NULL: return "NULL";
2179 case DT_NEEDED: return "NEEDED";
2180 case DT_PLTRELSZ: return "PLTRELSZ";
2181 case DT_PLTGOT: return "PLTGOT";
2182 case DT_HASH: return "HASH";
2183 case DT_STRTAB: return "STRTAB";
2184 case DT_SYMTAB: return "SYMTAB";
2185 case DT_RELA: return "RELA";
2186 case DT_RELASZ: return "RELASZ";
2187 case DT_RELAENT: return "RELAENT";
2188 case DT_STRSZ: return "STRSZ";
2189 case DT_SYMENT: return "SYMENT";
2190 case DT_INIT: return "INIT";
2191 case DT_FINI: return "FINI";
2192 case DT_SONAME: return "SONAME";
2193 case DT_RPATH: return "RPATH";
2194 case DT_SYMBOLIC: return "SYMBOLIC";
2195 case DT_REL: return "REL";
2196 case DT_RELSZ: return "RELSZ";
2197 case DT_RELENT: return "RELENT";
2198 case DT_PLTREL: return "PLTREL";
2199 case DT_DEBUG: return "DEBUG";
2200 case DT_TEXTREL: return "TEXTREL";
2201 case DT_JMPREL: return "JMPREL";
2202 case DT_BIND_NOW: return "BIND_NOW";
2203 case DT_INIT_ARRAY: return "INIT_ARRAY";
2204 case DT_FINI_ARRAY: return "FINI_ARRAY";
2205 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2206 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2207 case DT_RUNPATH: return "RUNPATH";
2208 case DT_FLAGS: return "FLAGS";
2d0e6f43 2209
d1133906
NC
2210 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2211 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2212 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2213
05107a46 2214 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2215 case DT_PLTPADSZ: return "PLTPADSZ";
2216 case DT_MOVEENT: return "MOVEENT";
2217 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2218 case DT_FEATURE: return "FEATURE";
252b5132
RH
2219 case DT_POSFLAG_1: return "POSFLAG_1";
2220 case DT_SYMINSZ: return "SYMINSZ";
2221 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2222
252b5132 2223 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2224 case DT_CONFIG: return "CONFIG";
2225 case DT_DEPAUDIT: return "DEPAUDIT";
2226 case DT_AUDIT: return "AUDIT";
2227 case DT_PLTPAD: return "PLTPAD";
2228 case DT_MOVETAB: return "MOVETAB";
252b5132 2229 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2230
252b5132 2231 case DT_VERSYM: return "VERSYM";
103f02d3 2232
67a4f2b7
AO
2233 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2234 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2235 case DT_RELACOUNT: return "RELACOUNT";
2236 case DT_RELCOUNT: return "RELCOUNT";
2237 case DT_FLAGS_1: return "FLAGS_1";
2238 case DT_VERDEF: return "VERDEF";
2239 case DT_VERDEFNUM: return "VERDEFNUM";
2240 case DT_VERNEED: return "VERNEED";
2241 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2242
019148e4 2243 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2244 case DT_USED: return "USED";
2245 case DT_FILTER: return "FILTER";
103f02d3 2246
047b2264
JJ
2247 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2248 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2249 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2250 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2251 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2252 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2253 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2254
252b5132
RH
2255 default:
2256 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2257 {
2cf0635d 2258 const char * result;
103f02d3 2259
dda8d76d 2260 switch (filedata->file_header.e_machine)
252b5132 2261 {
37c18eed
SD
2262 case EM_AARCH64:
2263 result = get_aarch64_dynamic_type (type);
2264 break;
252b5132 2265 case EM_MIPS:
4fe85591 2266 case EM_MIPS_RS3_LE:
252b5132
RH
2267 result = get_mips_dynamic_type (type);
2268 break;
9a097730
RH
2269 case EM_SPARCV9:
2270 result = get_sparc64_dynamic_type (type);
2271 break;
7490d522
AM
2272 case EM_PPC:
2273 result = get_ppc_dynamic_type (type);
2274 break;
f1cb7e17
AM
2275 case EM_PPC64:
2276 result = get_ppc64_dynamic_type (type);
2277 break;
ecc51f48
NC
2278 case EM_IA_64:
2279 result = get_ia64_dynamic_type (type);
2280 break;
fabcb361
RH
2281 case EM_ALPHA:
2282 result = get_alpha_dynamic_type (type);
2283 break;
1c0d3aa6
NC
2284 case EM_SCORE:
2285 result = get_score_dynamic_type (type);
2286 break;
40b36596
JM
2287 case EM_TI_C6000:
2288 result = get_tic6x_dynamic_type (type);
2289 break;
36591ba1
SL
2290 case EM_ALTERA_NIOS2:
2291 result = get_nios2_dynamic_type (type);
2292 break;
252b5132 2293 default:
dda8d76d 2294 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2295 result = get_solaris_dynamic_type (type);
2296 else
2297 result = NULL;
252b5132
RH
2298 break;
2299 }
2300
2301 if (result != NULL)
2302 return result;
2303
e9e44622 2304 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2305 }
eec8f817 2306 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2307 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2308 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2309 {
2cf0635d 2310 const char * result;
103f02d3 2311
dda8d76d 2312 switch (filedata->file_header.e_machine)
103f02d3
UD
2313 {
2314 case EM_PARISC:
2315 result = get_parisc_dynamic_type (type);
2316 break;
148b93f2
NC
2317 case EM_IA_64:
2318 result = get_ia64_dynamic_type (type);
2319 break;
103f02d3 2320 default:
dda8d76d 2321 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2322 result = get_solaris_dynamic_type (type);
2323 else
2324 result = NULL;
103f02d3
UD
2325 break;
2326 }
2327
2328 if (result != NULL)
2329 return result;
2330
e9e44622
JJ
2331 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2332 type);
103f02d3 2333 }
252b5132 2334 else
e9e44622 2335 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2336
252b5132
RH
2337 return buff;
2338 }
2339}
2340
2341static char *
d3ba0551 2342get_file_type (unsigned e_type)
252b5132 2343{
89246a0e 2344 static char buff[64];
252b5132
RH
2345
2346 switch (e_type)
2347 {
32ec8896
NC
2348 case ET_NONE: return _("NONE (None)");
2349 case ET_REL: return _("REL (Relocatable file)");
2350 case ET_EXEC: return _("EXEC (Executable file)");
2351 case ET_DYN: return _("DYN (Shared object file)");
2352 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2353
2354 default:
2355 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2356 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2357 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2358 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2359 else
e9e44622 2360 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2361 return buff;
2362 }
2363}
2364
2365static char *
d3ba0551 2366get_machine_name (unsigned e_machine)
252b5132 2367{
b34976b6 2368 static char buff[64]; /* XXX */
252b5132
RH
2369
2370 switch (e_machine)
2371 {
55e22ca8
NC
2372 /* Please keep this switch table sorted by increasing EM_ value. */
2373 /* 0 */
c45021f2
NC
2374 case EM_NONE: return _("None");
2375 case EM_M32: return "WE32100";
2376 case EM_SPARC: return "Sparc";
2377 case EM_386: return "Intel 80386";
2378 case EM_68K: return "MC68000";
2379 case EM_88K: return "MC88000";
22abe556 2380 case EM_IAMCU: return "Intel MCU";
fb70ec17 2381 case EM_860: return "Intel 80860";
c45021f2
NC
2382 case EM_MIPS: return "MIPS R3000";
2383 case EM_S370: return "IBM System/370";
55e22ca8 2384 /* 10 */
7036c0e1 2385 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2386 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2387 case EM_PARISC: return "HPPA";
55e22ca8 2388 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2389 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2390 case EM_960: return "Intel 80960";
c45021f2 2391 case EM_PPC: return "PowerPC";
55e22ca8 2392 /* 20 */
285d1771 2393 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2394 case EM_S390_OLD:
2395 case EM_S390: return "IBM S/390";
2396 case EM_SPU: return "SPU";
2397 /* 30 */
2398 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2399 case EM_FR20: return "Fujitsu FR20";
2400 case EM_RH32: return "TRW RH32";
b34976b6 2401 case EM_MCORE: return "MCORE";
55e22ca8 2402 /* 40 */
7036c0e1
AJ
2403 case EM_ARM: return "ARM";
2404 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2405 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2406 case EM_SPARCV9: return "Sparc v9";
2407 case EM_TRICORE: return "Siemens Tricore";
584da044 2408 case EM_ARC: return "ARC";
c2dcd04e
NC
2409 case EM_H8_300: return "Renesas H8/300";
2410 case EM_H8_300H: return "Renesas H8/300H";
2411 case EM_H8S: return "Renesas H8S";
2412 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2413 /* 50 */
30800947 2414 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2415 case EM_MIPS_X: return "Stanford MIPS-X";
2416 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2417 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2418 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2419 case EM_PCP: return "Siemens PCP";
2420 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2421 case EM_NDR1: return "Denso NDR1 microprocesspr";
2422 case EM_STARCORE: return "Motorola Star*Core processor";
2423 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2424 /* 60 */
7036c0e1
AJ
2425 case EM_ST100: return "STMicroelectronics ST100 processor";
2426 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2427 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2428 case EM_PDSP: return "Sony DSP processor";
2429 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2430 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2431 case EM_FX66: return "Siemens FX66 microcontroller";
2432 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2433 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2434 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2435 /* 70 */
7036c0e1
AJ
2436 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2437 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2438 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2439 case EM_SVX: return "Silicon Graphics SVx";
2440 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2441 case EM_VAX: return "Digital VAX";
1b61cf92 2442 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2443 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2444 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2445 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2446 /* 80 */
b34976b6 2447 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2448 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2449 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2450 case EM_AVR_OLD:
2451 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2452 case EM_CYGNUS_FR30:
2453 case EM_FR30: return "Fujitsu FR30";
2454 case EM_CYGNUS_D10V:
2455 case EM_D10V: return "d10v";
2456 case EM_CYGNUS_D30V:
2457 case EM_D30V: return "d30v";
2458 case EM_CYGNUS_V850:
2459 case EM_V850: return "Renesas V850";
2460 case EM_CYGNUS_M32R:
2461 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2462 case EM_CYGNUS_MN10300:
2463 case EM_MN10300: return "mn10300";
2464 /* 90 */
2465 case EM_CYGNUS_MN10200:
2466 case EM_MN10200: return "mn10200";
2467 case EM_PJ: return "picoJava";
73589c9d 2468 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2469 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2470 case EM_XTENSA_OLD:
2471 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2472 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2473 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2474 case EM_NS32K: return "National Semiconductor 32000 series";
2475 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2476 case EM_SNP1K: return "Trebia SNP 1000 processor";
2477 /* 100 */
9abca702 2478 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2479 case EM_IP2K_OLD:
2480 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2481 case EM_MAX: return "MAX Processor";
2482 case EM_CR: return "National Semiconductor CompactRISC";
2483 case EM_F2MC16: return "Fujitsu F2MC16";
2484 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2485 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2486 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2487 case EM_SEP: return "Sharp embedded microprocessor";
2488 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2489 /* 110 */
11636f9e
JM
2490 case EM_UNICORE: return "Unicore";
2491 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2492 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2493 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2494 case EM_CRX: return "National Semiconductor CRX microprocessor";
2495 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2496 case EM_C166:
d70c5fc7 2497 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2498 case EM_M16C: return "Renesas M16C series microprocessors";
2499 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2500 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2501 /* 120 */
2502 case EM_M32C: return "Renesas M32c";
2503 /* 130 */
11636f9e
JM
2504 case EM_TSK3000: return "Altium TSK3000 core";
2505 case EM_RS08: return "Freescale RS08 embedded processor";
2506 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2507 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2508 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2509 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2510 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2511 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2512 /* 140 */
11636f9e
JM
2513 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2514 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2515 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2516 case EM_TI_PRU: return "TI PRU I/O processor";
2517 /* 160 */
11636f9e
JM
2518 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2519 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2520 case EM_R32C: return "Renesas R32C series microprocessors";
2521 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2522 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2523 case EM_8051: return "Intel 8051 and variants";
2524 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2525 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2526 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2527 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2528 /* 170 */
11636f9e
JM
2529 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2530 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2531 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2532 case EM_RX: return "Renesas RX";
a3c62988 2533 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2534 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2535 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2536 case EM_CR16:
2537 case EM_MICROBLAZE:
2538 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2539 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2540 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2541 /* 180 */
2542 case EM_L1OM: return "Intel L1OM";
2543 case EM_K1OM: return "Intel K1OM";
2544 case EM_INTEL182: return "Intel (reserved)";
2545 case EM_AARCH64: return "AArch64";
2546 case EM_ARM184: return "ARM (reserved)";
2547 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2548 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2549 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2550 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2551 /* 190 */
11636f9e 2552 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2553 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2554 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2555 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2556 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2557 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2558 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2559 case EM_RL78: return "Renesas RL78";
6d913794 2560 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2561 case EM_78K0R: return "Renesas 78K0R";
2562 /* 200 */
6d913794 2563 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2564 case EM_BA1: return "Beyond BA1 CPU architecture";
2565 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2566 case EM_XCORE: return "XMOS xCORE processor family";
2567 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2568 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2569 /* 210 */
6d913794
NC
2570 case EM_KM32: return "KM211 KM32 32-bit processor";
2571 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2572 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2573 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2574 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2575 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2576 case EM_COGE: return "Cognitive Smart Memory Processor";
2577 case EM_COOL: return "Bluechip Systems CoolEngine";
2578 case EM_NORC: return "Nanoradio Optimized RISC";
2579 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2580 /* 220 */
15f205b1 2581 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2582 case EM_VISIUM: return "CDS VISIUMcore processor";
2583 case EM_FT32: return "FTDI Chip FT32";
2584 case EM_MOXIE: return "Moxie";
2585 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2586 /* 230 (all reserved) */
2587 /* 240 */
55e22ca8
NC
2588 case EM_RISCV: return "RISC-V";
2589 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2590 case EM_CEVA: return "CEVA Processor Architecture Family";
2591 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2592 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2593 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2594 case EM_IMG1: return "Imagination Technologies";
2595 /* 250 */
fe944acf 2596 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2597 case EM_VE: return "NEC Vector Engine";
2598 case EM_CSKY: return "C-SKY";
2599 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2600 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2601 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2602 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2603 case EM_65816: return "WDC 65816/65C816";
01a8c731 2604 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2605 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2606
2607 /* Large numbers... */
2608 case EM_MT: return "Morpho Techologies MT processor";
2609 case EM_ALPHA: return "Alpha";
2610 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2611 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2612 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2613 case EM_IQ2000: return "Vitesse IQ2000";
2614 case EM_M32C_OLD:
2615 case EM_NIOS32: return "Altera Nios";
2616 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2617 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2618 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2619 case EM_S12Z: return "Freescale S12Z";
55e22ca8 2620
252b5132 2621 default:
35d9dd2f 2622 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2623 return buff;
2624 }
2625}
2626
a9522a21
AB
2627static void
2628decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2629{
2630 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 2631 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
2632 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2633 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2634 architectures.
2635
2636 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2637 but also sets a specific architecture type in the e_flags field.
2638
2639 However, when decoding the flags we don't worry if we see an
2640 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2641 ARCEM architecture type. */
2642
2643 switch (e_flags & EF_ARC_MACH_MSK)
2644 {
2645 /* We only expect these to occur for EM_ARC_COMPACT2. */
2646 case EF_ARC_CPU_ARCV2EM:
2647 strcat (buf, ", ARC EM");
2648 break;
2649 case EF_ARC_CPU_ARCV2HS:
2650 strcat (buf, ", ARC HS");
2651 break;
2652
2653 /* We only expect these to occur for EM_ARC_COMPACT. */
2654 case E_ARC_MACH_ARC600:
2655 strcat (buf, ", ARC600");
2656 break;
2657 case E_ARC_MACH_ARC601:
2658 strcat (buf, ", ARC601");
2659 break;
2660 case E_ARC_MACH_ARC700:
2661 strcat (buf, ", ARC700");
2662 break;
2663
2664 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2665 new ELF with new architecture being read by an old version of
2666 readelf, or (c) An ELF built with non-GNU compiler that does not
2667 set the architecture in the e_flags. */
2668 default:
2669 if (e_machine == EM_ARC_COMPACT)
2670 strcat (buf, ", Unknown ARCompact");
2671 else
2672 strcat (buf, ", Unknown ARC");
2673 break;
2674 }
2675
2676 switch (e_flags & EF_ARC_OSABI_MSK)
2677 {
2678 case E_ARC_OSABI_ORIG:
2679 strcat (buf, ", (ABI:legacy)");
2680 break;
2681 case E_ARC_OSABI_V2:
2682 strcat (buf, ", (ABI:v2)");
2683 break;
2684 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2685 case E_ARC_OSABI_V3:
2686 strcat (buf, ", v3 no-legacy-syscalls ABI");
2687 break;
53a346d8
CZ
2688 case E_ARC_OSABI_V4:
2689 strcat (buf, ", v4 ABI");
2690 break;
a9522a21
AB
2691 default:
2692 strcat (buf, ", unrecognised ARC OSABI flag");
2693 break;
2694 }
2695}
2696
f3485b74 2697static void
d3ba0551 2698decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2699{
2700 unsigned eabi;
015dc7e1 2701 bool unknown = false;
f3485b74
NC
2702
2703 eabi = EF_ARM_EABI_VERSION (e_flags);
2704 e_flags &= ~ EF_ARM_EABIMASK;
2705
2706 /* Handle "generic" ARM flags. */
2707 if (e_flags & EF_ARM_RELEXEC)
2708 {
2709 strcat (buf, ", relocatable executable");
2710 e_flags &= ~ EF_ARM_RELEXEC;
2711 }
76da6bbe 2712
18a20338
CL
2713 if (e_flags & EF_ARM_PIC)
2714 {
2715 strcat (buf, ", position independent");
2716 e_flags &= ~ EF_ARM_PIC;
2717 }
2718
f3485b74
NC
2719 /* Now handle EABI specific flags. */
2720 switch (eabi)
2721 {
2722 default:
2c71103e 2723 strcat (buf, ", <unrecognized EABI>");
f3485b74 2724 if (e_flags)
015dc7e1 2725 unknown = true;
f3485b74
NC
2726 break;
2727
2728 case EF_ARM_EABI_VER1:
a5bcd848 2729 strcat (buf, ", Version1 EABI");
f3485b74
NC
2730 while (e_flags)
2731 {
2732 unsigned flag;
76da6bbe 2733
f3485b74
NC
2734 /* Process flags one bit at a time. */
2735 flag = e_flags & - e_flags;
2736 e_flags &= ~ flag;
76da6bbe 2737
f3485b74
NC
2738 switch (flag)
2739 {
a5bcd848 2740 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2741 strcat (buf, ", sorted symbol tables");
2742 break;
76da6bbe 2743
f3485b74 2744 default:
015dc7e1 2745 unknown = true;
f3485b74
NC
2746 break;
2747 }
2748 }
2749 break;
76da6bbe 2750
a5bcd848
PB
2751 case EF_ARM_EABI_VER2:
2752 strcat (buf, ", Version2 EABI");
2753 while (e_flags)
2754 {
2755 unsigned flag;
2756
2757 /* Process flags one bit at a time. */
2758 flag = e_flags & - e_flags;
2759 e_flags &= ~ flag;
2760
2761 switch (flag)
2762 {
2763 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2764 strcat (buf, ", sorted symbol tables");
2765 break;
2766
2767 case EF_ARM_DYNSYMSUSESEGIDX:
2768 strcat (buf, ", dynamic symbols use segment index");
2769 break;
2770
2771 case EF_ARM_MAPSYMSFIRST:
2772 strcat (buf, ", mapping symbols precede others");
2773 break;
2774
2775 default:
015dc7e1 2776 unknown = true;
a5bcd848
PB
2777 break;
2778 }
2779 }
2780 break;
2781
d507cf36
PB
2782 case EF_ARM_EABI_VER3:
2783 strcat (buf, ", Version3 EABI");
8cb51566
PB
2784 break;
2785
2786 case EF_ARM_EABI_VER4:
2787 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2788 while (e_flags)
2789 {
2790 unsigned flag;
2791
2792 /* Process flags one bit at a time. */
2793 flag = e_flags & - e_flags;
2794 e_flags &= ~ flag;
2795
2796 switch (flag)
2797 {
2798 case EF_ARM_BE8:
2799 strcat (buf, ", BE8");
2800 break;
2801
2802 case EF_ARM_LE8:
2803 strcat (buf, ", LE8");
2804 break;
2805
2806 default:
015dc7e1 2807 unknown = true;
3bfcb652
NC
2808 break;
2809 }
3bfcb652
NC
2810 }
2811 break;
3a4a14e9
PB
2812
2813 case EF_ARM_EABI_VER5:
2814 strcat (buf, ", Version5 EABI");
d507cf36
PB
2815 while (e_flags)
2816 {
2817 unsigned flag;
2818
2819 /* Process flags one bit at a time. */
2820 flag = e_flags & - e_flags;
2821 e_flags &= ~ flag;
2822
2823 switch (flag)
2824 {
2825 case EF_ARM_BE8:
2826 strcat (buf, ", BE8");
2827 break;
2828
2829 case EF_ARM_LE8:
2830 strcat (buf, ", LE8");
2831 break;
2832
3bfcb652
NC
2833 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2834 strcat (buf, ", soft-float ABI");
2835 break;
2836
2837 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2838 strcat (buf, ", hard-float ABI");
2839 break;
2840
d507cf36 2841 default:
015dc7e1 2842 unknown = true;
d507cf36
PB
2843 break;
2844 }
2845 }
2846 break;
2847
f3485b74 2848 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2849 strcat (buf, ", GNU EABI");
f3485b74
NC
2850 while (e_flags)
2851 {
2852 unsigned flag;
76da6bbe 2853
f3485b74
NC
2854 /* Process flags one bit at a time. */
2855 flag = e_flags & - e_flags;
2856 e_flags &= ~ flag;
76da6bbe 2857
f3485b74
NC
2858 switch (flag)
2859 {
a5bcd848 2860 case EF_ARM_INTERWORK:
f3485b74
NC
2861 strcat (buf, ", interworking enabled");
2862 break;
76da6bbe 2863
a5bcd848 2864 case EF_ARM_APCS_26:
f3485b74
NC
2865 strcat (buf, ", uses APCS/26");
2866 break;
76da6bbe 2867
a5bcd848 2868 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2869 strcat (buf, ", uses APCS/float");
2870 break;
76da6bbe 2871
a5bcd848 2872 case EF_ARM_PIC:
f3485b74
NC
2873 strcat (buf, ", position independent");
2874 break;
76da6bbe 2875
a5bcd848 2876 case EF_ARM_ALIGN8:
f3485b74
NC
2877 strcat (buf, ", 8 bit structure alignment");
2878 break;
76da6bbe 2879
a5bcd848 2880 case EF_ARM_NEW_ABI:
f3485b74
NC
2881 strcat (buf, ", uses new ABI");
2882 break;
76da6bbe 2883
a5bcd848 2884 case EF_ARM_OLD_ABI:
f3485b74
NC
2885 strcat (buf, ", uses old ABI");
2886 break;
76da6bbe 2887
a5bcd848 2888 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2889 strcat (buf, ", software FP");
2890 break;
76da6bbe 2891
90e01f86
ILT
2892 case EF_ARM_VFP_FLOAT:
2893 strcat (buf, ", VFP");
2894 break;
2895
fde78edd
NC
2896 case EF_ARM_MAVERICK_FLOAT:
2897 strcat (buf, ", Maverick FP");
2898 break;
2899
f3485b74 2900 default:
015dc7e1 2901 unknown = true;
f3485b74
NC
2902 break;
2903 }
2904 }
2905 }
f3485b74
NC
2906
2907 if (unknown)
2b692964 2908 strcat (buf,_(", <unknown>"));
f3485b74
NC
2909}
2910
343433df
AB
2911static void
2912decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2913{
2914 --size; /* Leave space for null terminator. */
2915
2916 switch (e_flags & EF_AVR_MACH)
2917 {
2918 case E_AVR_MACH_AVR1:
2919 strncat (buf, ", avr:1", size);
2920 break;
2921 case E_AVR_MACH_AVR2:
2922 strncat (buf, ", avr:2", size);
2923 break;
2924 case E_AVR_MACH_AVR25:
2925 strncat (buf, ", avr:25", size);
2926 break;
2927 case E_AVR_MACH_AVR3:
2928 strncat (buf, ", avr:3", size);
2929 break;
2930 case E_AVR_MACH_AVR31:
2931 strncat (buf, ", avr:31", size);
2932 break;
2933 case E_AVR_MACH_AVR35:
2934 strncat (buf, ", avr:35", size);
2935 break;
2936 case E_AVR_MACH_AVR4:
2937 strncat (buf, ", avr:4", size);
2938 break;
2939 case E_AVR_MACH_AVR5:
2940 strncat (buf, ", avr:5", size);
2941 break;
2942 case E_AVR_MACH_AVR51:
2943 strncat (buf, ", avr:51", size);
2944 break;
2945 case E_AVR_MACH_AVR6:
2946 strncat (buf, ", avr:6", size);
2947 break;
2948 case E_AVR_MACH_AVRTINY:
2949 strncat (buf, ", avr:100", size);
2950 break;
2951 case E_AVR_MACH_XMEGA1:
2952 strncat (buf, ", avr:101", size);
2953 break;
2954 case E_AVR_MACH_XMEGA2:
2955 strncat (buf, ", avr:102", size);
2956 break;
2957 case E_AVR_MACH_XMEGA3:
2958 strncat (buf, ", avr:103", size);
2959 break;
2960 case E_AVR_MACH_XMEGA4:
2961 strncat (buf, ", avr:104", size);
2962 break;
2963 case E_AVR_MACH_XMEGA5:
2964 strncat (buf, ", avr:105", size);
2965 break;
2966 case E_AVR_MACH_XMEGA6:
2967 strncat (buf, ", avr:106", size);
2968 break;
2969 case E_AVR_MACH_XMEGA7:
2970 strncat (buf, ", avr:107", size);
2971 break;
2972 default:
2973 strncat (buf, ", avr:<unknown>", size);
2974 break;
2975 }
2976
2977 size -= strlen (buf);
2978 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2979 strncat (buf, ", link-relax", size);
2980}
2981
35c08157
KLC
2982static void
2983decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2984{
2985 unsigned abi;
2986 unsigned arch;
2987 unsigned config;
2988 unsigned version;
015dc7e1 2989 bool has_fpu = false;
32ec8896 2990 unsigned int r = 0;
35c08157
KLC
2991
2992 static const char *ABI_STRINGS[] =
2993 {
2994 "ABI v0", /* use r5 as return register; only used in N1213HC */
2995 "ABI v1", /* use r0 as return register */
2996 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2997 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2998 "AABI",
2999 "ABI2 FP+"
35c08157
KLC
3000 };
3001 static const char *VER_STRINGS[] =
3002 {
3003 "Andes ELF V1.3 or older",
3004 "Andes ELF V1.3.1",
3005 "Andes ELF V1.4"
3006 };
3007 static const char *ARCH_STRINGS[] =
3008 {
3009 "",
3010 "Andes Star v1.0",
3011 "Andes Star v2.0",
3012 "Andes Star v3.0",
3013 "Andes Star v3.0m"
3014 };
3015
3016 abi = EF_NDS_ABI & e_flags;
3017 arch = EF_NDS_ARCH & e_flags;
3018 config = EF_NDS_INST & e_flags;
3019 version = EF_NDS32_ELF_VERSION & e_flags;
3020
3021 memset (buf, 0, size);
3022
3023 switch (abi)
3024 {
3025 case E_NDS_ABI_V0:
3026 case E_NDS_ABI_V1:
3027 case E_NDS_ABI_V2:
3028 case E_NDS_ABI_V2FP:
3029 case E_NDS_ABI_AABI:
40c7a7cb 3030 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3031 /* In case there are holes in the array. */
3032 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3033 break;
3034
3035 default:
3036 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3037 break;
3038 }
3039
3040 switch (version)
3041 {
3042 case E_NDS32_ELF_VER_1_2:
3043 case E_NDS32_ELF_VER_1_3:
3044 case E_NDS32_ELF_VER_1_4:
3045 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3046 break;
3047
3048 default:
3049 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3050 break;
3051 }
3052
3053 if (E_NDS_ABI_V0 == abi)
3054 {
3055 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3056 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3057 if (arch == E_NDS_ARCH_STAR_V1_0)
3058 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3059 return;
3060 }
3061
3062 switch (arch)
3063 {
3064 case E_NDS_ARCH_STAR_V1_0:
3065 case E_NDS_ARCH_STAR_V2_0:
3066 case E_NDS_ARCH_STAR_V3_0:
3067 case E_NDS_ARCH_STAR_V3_M:
3068 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3069 break;
3070
3071 default:
3072 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3073 /* ARCH version determines how the e_flags are interpreted.
3074 If it is unknown, we cannot proceed. */
3075 return;
3076 }
3077
3078 /* Newer ABI; Now handle architecture specific flags. */
3079 if (arch == E_NDS_ARCH_STAR_V1_0)
3080 {
3081 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3082 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3083
3084 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3085 r += snprintf (buf + r, size -r, ", MAC");
3086
3087 if (config & E_NDS32_HAS_DIV_INST)
3088 r += snprintf (buf + r, size -r, ", DIV");
3089
3090 if (config & E_NDS32_HAS_16BIT_INST)
3091 r += snprintf (buf + r, size -r, ", 16b");
3092 }
3093 else
3094 {
3095 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3096 {
3097 if (version <= E_NDS32_ELF_VER_1_3)
3098 r += snprintf (buf + r, size -r, ", [B8]");
3099 else
3100 r += snprintf (buf + r, size -r, ", EX9");
3101 }
3102
3103 if (config & E_NDS32_HAS_MAC_DX_INST)
3104 r += snprintf (buf + r, size -r, ", MAC_DX");
3105
3106 if (config & E_NDS32_HAS_DIV_DX_INST)
3107 r += snprintf (buf + r, size -r, ", DIV_DX");
3108
3109 if (config & E_NDS32_HAS_16BIT_INST)
3110 {
3111 if (version <= E_NDS32_ELF_VER_1_3)
3112 r += snprintf (buf + r, size -r, ", 16b");
3113 else
3114 r += snprintf (buf + r, size -r, ", IFC");
3115 }
3116 }
3117
3118 if (config & E_NDS32_HAS_EXT_INST)
3119 r += snprintf (buf + r, size -r, ", PERF1");
3120
3121 if (config & E_NDS32_HAS_EXT2_INST)
3122 r += snprintf (buf + r, size -r, ", PERF2");
3123
3124 if (config & E_NDS32_HAS_FPU_INST)
3125 {
015dc7e1 3126 has_fpu = true;
35c08157
KLC
3127 r += snprintf (buf + r, size -r, ", FPU_SP");
3128 }
3129
3130 if (config & E_NDS32_HAS_FPU_DP_INST)
3131 {
015dc7e1 3132 has_fpu = true;
35c08157
KLC
3133 r += snprintf (buf + r, size -r, ", FPU_DP");
3134 }
3135
3136 if (config & E_NDS32_HAS_FPU_MAC_INST)
3137 {
015dc7e1 3138 has_fpu = true;
35c08157
KLC
3139 r += snprintf (buf + r, size -r, ", FPU_MAC");
3140 }
3141
3142 if (has_fpu)
3143 {
3144 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3145 {
3146 case E_NDS32_FPU_REG_8SP_4DP:
3147 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3148 break;
3149 case E_NDS32_FPU_REG_16SP_8DP:
3150 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3151 break;
3152 case E_NDS32_FPU_REG_32SP_16DP:
3153 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3154 break;
3155 case E_NDS32_FPU_REG_32SP_32DP:
3156 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3157 break;
3158 }
3159 }
3160
3161 if (config & E_NDS32_HAS_AUDIO_INST)
3162 r += snprintf (buf + r, size -r, ", AUDIO");
3163
3164 if (config & E_NDS32_HAS_STRING_INST)
3165 r += snprintf (buf + r, size -r, ", STR");
3166
3167 if (config & E_NDS32_HAS_REDUCED_REGS)
3168 r += snprintf (buf + r, size -r, ", 16REG");
3169
3170 if (config & E_NDS32_HAS_VIDEO_INST)
3171 {
3172 if (version <= E_NDS32_ELF_VER_1_3)
3173 r += snprintf (buf + r, size -r, ", VIDEO");
3174 else
3175 r += snprintf (buf + r, size -r, ", SATURATION");
3176 }
3177
3178 if (config & E_NDS32_HAS_ENCRIPT_INST)
3179 r += snprintf (buf + r, size -r, ", ENCRP");
3180
3181 if (config & E_NDS32_HAS_L2C_INST)
3182 r += snprintf (buf + r, size -r, ", L2C");
3183}
3184
252b5132 3185static char *
dda8d76d 3186get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3187{
b34976b6 3188 static char buf[1024];
252b5132
RH
3189
3190 buf[0] = '\0';
76da6bbe 3191
252b5132
RH
3192 if (e_flags)
3193 {
3194 switch (e_machine)
3195 {
3196 default:
3197 break;
3198
886a2506 3199 case EM_ARC_COMPACT2:
886a2506 3200 case EM_ARC_COMPACT:
a9522a21
AB
3201 decode_ARC_machine_flags (e_flags, e_machine, buf);
3202 break;
886a2506 3203
f3485b74
NC
3204 case EM_ARM:
3205 decode_ARM_machine_flags (e_flags, buf);
3206 break;
76da6bbe 3207
343433df
AB
3208 case EM_AVR:
3209 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3210 break;
3211
781303ce
MF
3212 case EM_BLACKFIN:
3213 if (e_flags & EF_BFIN_PIC)
3214 strcat (buf, ", PIC");
3215
3216 if (e_flags & EF_BFIN_FDPIC)
3217 strcat (buf, ", FDPIC");
3218
3219 if (e_flags & EF_BFIN_CODE_IN_L1)
3220 strcat (buf, ", code in L1");
3221
3222 if (e_flags & EF_BFIN_DATA_IN_L1)
3223 strcat (buf, ", data in L1");
3224
3225 break;
3226
ec2dfb42
AO
3227 case EM_CYGNUS_FRV:
3228 switch (e_flags & EF_FRV_CPU_MASK)
3229 {
3230 case EF_FRV_CPU_GENERIC:
3231 break;
3232
3233 default:
3234 strcat (buf, ", fr???");
3235 break;
57346661 3236
ec2dfb42
AO
3237 case EF_FRV_CPU_FR300:
3238 strcat (buf, ", fr300");
3239 break;
3240
3241 case EF_FRV_CPU_FR400:
3242 strcat (buf, ", fr400");
3243 break;
3244 case EF_FRV_CPU_FR405:
3245 strcat (buf, ", fr405");
3246 break;
3247
3248 case EF_FRV_CPU_FR450:
3249 strcat (buf, ", fr450");
3250 break;
3251
3252 case EF_FRV_CPU_FR500:
3253 strcat (buf, ", fr500");
3254 break;
3255 case EF_FRV_CPU_FR550:
3256 strcat (buf, ", fr550");
3257 break;
3258
3259 case EF_FRV_CPU_SIMPLE:
3260 strcat (buf, ", simple");
3261 break;
3262 case EF_FRV_CPU_TOMCAT:
3263 strcat (buf, ", tomcat");
3264 break;
3265 }
1c877e87 3266 break;
ec2dfb42 3267
53c7db4b 3268 case EM_68K:
425c6cb0 3269 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3270 strcat (buf, ", m68000");
425c6cb0 3271 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3272 strcat (buf, ", cpu32");
3273 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3274 strcat (buf, ", fido_a");
425c6cb0 3275 else
266abb8f 3276 {
2cf0635d
NC
3277 char const * isa = _("unknown");
3278 char const * mac = _("unknown mac");
3279 char const * additional = NULL;
0112cd26 3280
c694fd50 3281 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3282 {
c694fd50 3283 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3284 isa = "A";
3285 additional = ", nodiv";
3286 break;
c694fd50 3287 case EF_M68K_CF_ISA_A:
266abb8f
NS
3288 isa = "A";
3289 break;
c694fd50 3290 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3291 isa = "A+";
3292 break;
c694fd50 3293 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3294 isa = "B";
3295 additional = ", nousp";
3296 break;
c694fd50 3297 case EF_M68K_CF_ISA_B:
266abb8f
NS
3298 isa = "B";
3299 break;
f608cd77
NS
3300 case EF_M68K_CF_ISA_C:
3301 isa = "C";
3302 break;
3303 case EF_M68K_CF_ISA_C_NODIV:
3304 isa = "C";
3305 additional = ", nodiv";
3306 break;
266abb8f
NS
3307 }
3308 strcat (buf, ", cf, isa ");
3309 strcat (buf, isa);
0b2e31dc
NS
3310 if (additional)
3311 strcat (buf, additional);
c694fd50 3312 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3313 strcat (buf, ", float");
c694fd50 3314 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3315 {
3316 case 0:
3317 mac = NULL;
3318 break;
c694fd50 3319 case EF_M68K_CF_MAC:
266abb8f
NS
3320 mac = "mac";
3321 break;
c694fd50 3322 case EF_M68K_CF_EMAC:
266abb8f
NS
3323 mac = "emac";
3324 break;
f608cd77
NS
3325 case EF_M68K_CF_EMAC_B:
3326 mac = "emac_b";
3327 break;
266abb8f
NS
3328 }
3329 if (mac)
3330 {
3331 strcat (buf, ", ");
3332 strcat (buf, mac);
3333 }
266abb8f 3334 }
53c7db4b 3335 break;
33c63f9d 3336
153a2776
NC
3337 case EM_CYGNUS_MEP:
3338 switch (e_flags & EF_MEP_CPU_MASK)
3339 {
3340 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3341 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3342 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3343 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3344 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3345 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3346 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3347 }
3348
3349 switch (e_flags & EF_MEP_COP_MASK)
3350 {
3351 case EF_MEP_COP_NONE: break;
3352 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3353 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3354 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3355 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3356 default: strcat (buf, _("<unknown MeP copro type>")); break;
3357 }
3358
3359 if (e_flags & EF_MEP_LIBRARY)
3360 strcat (buf, ", Built for Library");
3361
3362 if (e_flags & EF_MEP_INDEX_MASK)
3363 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3364 e_flags & EF_MEP_INDEX_MASK);
3365
3366 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3367 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3368 e_flags & ~ EF_MEP_ALL_FLAGS);
3369 break;
3370
252b5132
RH
3371 case EM_PPC:
3372 if (e_flags & EF_PPC_EMB)
3373 strcat (buf, ", emb");
3374
3375 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3376 strcat (buf, _(", relocatable"));
252b5132
RH
3377
3378 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3379 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3380 break;
3381
ee67d69a
AM
3382 case EM_PPC64:
3383 if (e_flags & EF_PPC64_ABI)
3384 {
3385 char abi[] = ", abiv0";
3386
3387 abi[6] += e_flags & EF_PPC64_ABI;
3388 strcat (buf, abi);
3389 }
3390 break;
3391
708e2187
NC
3392 case EM_V800:
3393 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3394 strcat (buf, ", RH850 ABI");
0b4362b0 3395
708e2187
NC
3396 if (e_flags & EF_V800_850E3)
3397 strcat (buf, ", V3 architecture");
3398
3399 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3400 strcat (buf, ", FPU not used");
3401
3402 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3403 strcat (buf, ", regmode: COMMON");
3404
3405 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3406 strcat (buf, ", r4 not used");
3407
3408 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3409 strcat (buf, ", r30 not used");
3410
3411 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3412 strcat (buf, ", r5 not used");
3413
3414 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3415 strcat (buf, ", r2 not used");
3416
3417 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3418 {
3419 switch (e_flags & - e_flags)
3420 {
3421 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3422 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3423 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3424 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3425 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3426 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3427 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3428 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3429 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3430 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3431 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3432 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3433 default: break;
3434 }
3435 }
3436 break;
3437
2b0337b0 3438 case EM_V850:
252b5132
RH
3439 case EM_CYGNUS_V850:
3440 switch (e_flags & EF_V850_ARCH)
3441 {
78c8d46c
NC
3442 case E_V850E3V5_ARCH:
3443 strcat (buf, ", v850e3v5");
3444 break;
1cd986c5
NC
3445 case E_V850E2V3_ARCH:
3446 strcat (buf, ", v850e2v3");
3447 break;
3448 case E_V850E2_ARCH:
3449 strcat (buf, ", v850e2");
3450 break;
3451 case E_V850E1_ARCH:
3452 strcat (buf, ", v850e1");
8ad30312 3453 break;
252b5132
RH
3454 case E_V850E_ARCH:
3455 strcat (buf, ", v850e");
3456 break;
252b5132
RH
3457 case E_V850_ARCH:
3458 strcat (buf, ", v850");
3459 break;
3460 default:
2b692964 3461 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3462 break;
3463 }
3464 break;
3465
2b0337b0 3466 case EM_M32R:
252b5132
RH
3467 case EM_CYGNUS_M32R:
3468 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3469 strcat (buf, ", m32r");
252b5132
RH
3470 break;
3471
3472 case EM_MIPS:
4fe85591 3473 case EM_MIPS_RS3_LE:
252b5132
RH
3474 if (e_flags & EF_MIPS_NOREORDER)
3475 strcat (buf, ", noreorder");
3476
3477 if (e_flags & EF_MIPS_PIC)
3478 strcat (buf, ", pic");
3479
3480 if (e_flags & EF_MIPS_CPIC)
3481 strcat (buf, ", cpic");
3482
d1bdd336
TS
3483 if (e_flags & EF_MIPS_UCODE)
3484 strcat (buf, ", ugen_reserved");
3485
252b5132
RH
3486 if (e_flags & EF_MIPS_ABI2)
3487 strcat (buf, ", abi2");
3488
43521d43
TS
3489 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3490 strcat (buf, ", odk first");
3491
a5d22d2a
TS
3492 if (e_flags & EF_MIPS_32BITMODE)
3493 strcat (buf, ", 32bitmode");
3494
ba92f887
MR
3495 if (e_flags & EF_MIPS_NAN2008)
3496 strcat (buf, ", nan2008");
3497
fef1b0b3
SE
3498 if (e_flags & EF_MIPS_FP64)
3499 strcat (buf, ", fp64");
3500
156c2f8b
NC
3501 switch ((e_flags & EF_MIPS_MACH))
3502 {
3503 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3504 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3505 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3506 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3507 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3508 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3509 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3510 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3511 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3512 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3513 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3514 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3515 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3516 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3517 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3518 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3519 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3520 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3521 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3522 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3523 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3524 case 0:
3525 /* We simply ignore the field in this case to avoid confusion:
3526 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3527 extension. */
3528 break;
2b692964 3529 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3530 }
43521d43
TS
3531
3532 switch ((e_flags & EF_MIPS_ABI))
3533 {
3534 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3535 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3536 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3537 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3538 case 0:
3539 /* We simply ignore the field in this case to avoid confusion:
3540 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3541 This means it is likely to be an o32 file, but not for
3542 sure. */
3543 break;
2b692964 3544 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3545 }
3546
3547 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3548 strcat (buf, ", mdmx");
3549
3550 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3551 strcat (buf, ", mips16");
3552
df58fc94
RS
3553 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3554 strcat (buf, ", micromips");
3555
43521d43
TS
3556 switch ((e_flags & EF_MIPS_ARCH))
3557 {
3558 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3559 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3560 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3561 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3562 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3563 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3564 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3565 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3566 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3567 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3568 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3569 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3570 }
252b5132 3571 break;
351b4b40 3572
35c08157
KLC
3573 case EM_NDS32:
3574 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3575 break;
3576
fe944acf
FT
3577 case EM_NFP:
3578 switch (EF_NFP_MACH (e_flags))
3579 {
3580 case E_NFP_MACH_3200:
3581 strcat (buf, ", NFP-32xx");
3582 break;
3583 case E_NFP_MACH_6000:
3584 strcat (buf, ", NFP-6xxx");
3585 break;
3586 }
3587 break;
3588
e23eba97
NC
3589 case EM_RISCV:
3590 if (e_flags & EF_RISCV_RVC)
3591 strcat (buf, ", RVC");
2922d21d 3592
7f999549
JW
3593 if (e_flags & EF_RISCV_RVE)
3594 strcat (buf, ", RVE");
3595
2922d21d
AW
3596 switch (e_flags & EF_RISCV_FLOAT_ABI)
3597 {
3598 case EF_RISCV_FLOAT_ABI_SOFT:
3599 strcat (buf, ", soft-float ABI");
3600 break;
3601
3602 case EF_RISCV_FLOAT_ABI_SINGLE:
3603 strcat (buf, ", single-float ABI");
3604 break;
3605
3606 case EF_RISCV_FLOAT_ABI_DOUBLE:
3607 strcat (buf, ", double-float ABI");
3608 break;
3609
3610 case EF_RISCV_FLOAT_ABI_QUAD:
3611 strcat (buf, ", quad-float ABI");
3612 break;
3613 }
e23eba97
NC
3614 break;
3615
ccde1100
AO
3616 case EM_SH:
3617 switch ((e_flags & EF_SH_MACH_MASK))
3618 {
3619 case EF_SH1: strcat (buf, ", sh1"); break;
3620 case EF_SH2: strcat (buf, ", sh2"); break;
3621 case EF_SH3: strcat (buf, ", sh3"); break;
3622 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3623 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3624 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3625 case EF_SH3E: strcat (buf, ", sh3e"); break;
3626 case EF_SH4: strcat (buf, ", sh4"); break;
3627 case EF_SH5: strcat (buf, ", sh5"); break;
3628 case EF_SH2E: strcat (buf, ", sh2e"); break;
3629 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3630 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3631 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3632 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3633 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3634 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3635 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3636 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3637 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3638 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3639 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3640 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3641 }
3642
cec6a5b8
MR
3643 if (e_flags & EF_SH_PIC)
3644 strcat (buf, ", pic");
3645
3646 if (e_flags & EF_SH_FDPIC)
3647 strcat (buf, ", fdpic");
ccde1100 3648 break;
948f632f 3649
73589c9d
CS
3650 case EM_OR1K:
3651 if (e_flags & EF_OR1K_NODELAY)
3652 strcat (buf, ", no delay");
3653 break;
57346661 3654
351b4b40
RH
3655 case EM_SPARCV9:
3656 if (e_flags & EF_SPARC_32PLUS)
3657 strcat (buf, ", v8+");
3658
3659 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3660 strcat (buf, ", ultrasparcI");
3661
3662 if (e_flags & EF_SPARC_SUN_US3)
3663 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3664
3665 if (e_flags & EF_SPARC_HAL_R1)
3666 strcat (buf, ", halr1");
3667
3668 if (e_flags & EF_SPARC_LEDATA)
3669 strcat (buf, ", ledata");
3670
3671 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3672 strcat (buf, ", tso");
3673
3674 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3675 strcat (buf, ", pso");
3676
3677 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3678 strcat (buf, ", rmo");
3679 break;
7d466069 3680
103f02d3
UD
3681 case EM_PARISC:
3682 switch (e_flags & EF_PARISC_ARCH)
3683 {
3684 case EFA_PARISC_1_0:
3685 strcpy (buf, ", PA-RISC 1.0");
3686 break;
3687 case EFA_PARISC_1_1:
3688 strcpy (buf, ", PA-RISC 1.1");
3689 break;
3690 case EFA_PARISC_2_0:
3691 strcpy (buf, ", PA-RISC 2.0");
3692 break;
3693 default:
3694 break;
3695 }
3696 if (e_flags & EF_PARISC_TRAPNIL)
3697 strcat (buf, ", trapnil");
3698 if (e_flags & EF_PARISC_EXT)
3699 strcat (buf, ", ext");
3700 if (e_flags & EF_PARISC_LSB)
3701 strcat (buf, ", lsb");
3702 if (e_flags & EF_PARISC_WIDE)
3703 strcat (buf, ", wide");
3704 if (e_flags & EF_PARISC_NO_KABP)
3705 strcat (buf, ", no kabp");
3706 if (e_flags & EF_PARISC_LAZYSWAP)
3707 strcat (buf, ", lazyswap");
30800947 3708 break;
76da6bbe 3709
7d466069 3710 case EM_PJ:
2b0337b0 3711 case EM_PJ_OLD:
7d466069
ILT
3712 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3713 strcat (buf, ", new calling convention");
3714
3715 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3716 strcat (buf, ", gnu calling convention");
3717 break;
4d6ed7c8
NC
3718
3719 case EM_IA_64:
3720 if ((e_flags & EF_IA_64_ABI64))
3721 strcat (buf, ", 64-bit");
3722 else
3723 strcat (buf, ", 32-bit");
3724 if ((e_flags & EF_IA_64_REDUCEDFP))
3725 strcat (buf, ", reduced fp model");
3726 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3727 strcat (buf, ", no function descriptors, constant gp");
3728 else if ((e_flags & EF_IA_64_CONS_GP))
3729 strcat (buf, ", constant gp");
3730 if ((e_flags & EF_IA_64_ABSOLUTE))
3731 strcat (buf, ", absolute");
dda8d76d 3732 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3733 {
3734 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3735 strcat (buf, ", vms_linkages");
3736 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3737 {
3738 case EF_IA_64_VMS_COMCOD_SUCCESS:
3739 break;
3740 case EF_IA_64_VMS_COMCOD_WARNING:
3741 strcat (buf, ", warning");
3742 break;
3743 case EF_IA_64_VMS_COMCOD_ERROR:
3744 strcat (buf, ", error");
3745 break;
3746 case EF_IA_64_VMS_COMCOD_ABORT:
3747 strcat (buf, ", abort");
3748 break;
3749 default:
bee0ee85
NC
3750 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3751 e_flags & EF_IA_64_VMS_COMCOD);
3752 strcat (buf, ", <unknown>");
28f997cf
TG
3753 }
3754 }
4d6ed7c8 3755 break;
179d3252
JT
3756
3757 case EM_VAX:
3758 if ((e_flags & EF_VAX_NONPIC))
3759 strcat (buf, ", non-PIC");
3760 if ((e_flags & EF_VAX_DFLOAT))
3761 strcat (buf, ", D-Float");
3762 if ((e_flags & EF_VAX_GFLOAT))
3763 strcat (buf, ", G-Float");
3764 break;
c7927a3c 3765
619ed720
EB
3766 case EM_VISIUM:
3767 if (e_flags & EF_VISIUM_ARCH_MCM)
3768 strcat (buf, ", mcm");
3769 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3770 strcat (buf, ", mcm24");
3771 if (e_flags & EF_VISIUM_ARCH_GR6)
3772 strcat (buf, ", gr6");
3773 break;
3774
4046d87a 3775 case EM_RL78:
1740ba0c
NC
3776 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3777 {
3778 case E_FLAG_RL78_ANY_CPU: break;
3779 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3780 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3781 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3782 }
856ea05c
KP
3783 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3784 strcat (buf, ", 64-bit doubles");
4046d87a 3785 break;
0b4362b0 3786
c7927a3c
NC
3787 case EM_RX:
3788 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3789 strcat (buf, ", 64-bit doubles");
3790 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3791 strcat (buf, ", dsp");
d4cb0ea0 3792 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3793 strcat (buf, ", pid");
708e2187
NC
3794 if (e_flags & E_FLAG_RX_ABI)
3795 strcat (buf, ", RX ABI");
3525236c
NC
3796 if (e_flags & E_FLAG_RX_SINSNS_SET)
3797 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3798 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3799 if (e_flags & E_FLAG_RX_V2)
3800 strcat (buf, ", V2");
f87673e0
YS
3801 if (e_flags & E_FLAG_RX_V3)
3802 strcat (buf, ", V3");
d4cb0ea0 3803 break;
55786da2
AK
3804
3805 case EM_S390:
3806 if (e_flags & EF_S390_HIGH_GPRS)
3807 strcat (buf, ", highgprs");
d4cb0ea0 3808 break;
40b36596
JM
3809
3810 case EM_TI_C6000:
3811 if ((e_flags & EF_C6000_REL))
3812 strcat (buf, ", relocatable module");
d4cb0ea0 3813 break;
13761a11
NC
3814
3815 case EM_MSP430:
3816 strcat (buf, _(": architecture variant: "));
3817 switch (e_flags & EF_MSP430_MACH)
3818 {
3819 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3820 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3821 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3822 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3823 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3824 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3825 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3826 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3827 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3828 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3829 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3830 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3831 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3832 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3833 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3834 default:
3835 strcat (buf, _(": unknown")); break;
3836 }
3837
3838 if (e_flags & ~ EF_MSP430_MACH)
3839 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
3840 break;
3841
3842 case EM_Z80:
3843 switch (e_flags & EF_Z80_MACH_MSK)
3844 {
3845 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
3846 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
3847 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
3848 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
3849 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
3850 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 3851 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
3852 default:
3853 strcat (buf, _(", unknown")); break;
3854 }
3855 break;
252b5132
RH
3856 }
3857 }
3858
3859 return buf;
3860}
3861
252b5132 3862static const char *
dda8d76d 3863get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3864{
3865 static char buff[32];
3866
3867 switch (osabi)
3868 {
3869 case ELFOSABI_NONE: return "UNIX - System V";
3870 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3871 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3872 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3873 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3874 case ELFOSABI_AIX: return "UNIX - AIX";
3875 case ELFOSABI_IRIX: return "UNIX - IRIX";
3876 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3877 case ELFOSABI_TRU64: return "UNIX - TRU64";
3878 case ELFOSABI_MODESTO: return "Novell - Modesto";
3879 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3880 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3881 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3882 case ELFOSABI_AROS: return "AROS";
11636f9e 3883 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3884 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3885 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3886 default:
40b36596 3887 if (osabi >= 64)
dda8d76d 3888 switch (filedata->file_header.e_machine)
40b36596
JM
3889 {
3890 case EM_ARM:
3891 switch (osabi)
3892 {
3893 case ELFOSABI_ARM: return "ARM";
18a20338 3894 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3895 default:
3896 break;
3897 }
3898 break;
3899
3900 case EM_MSP430:
3901 case EM_MSP430_OLD:
619ed720 3902 case EM_VISIUM:
40b36596
JM
3903 switch (osabi)
3904 {
3905 case ELFOSABI_STANDALONE: return _("Standalone App");
3906 default:
3907 break;
3908 }
3909 break;
3910
3911 case EM_TI_C6000:
3912 switch (osabi)
3913 {
3914 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3915 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3916 default:
3917 break;
3918 }
3919 break;
3920
3921 default:
3922 break;
3923 }
e9e44622 3924 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3925 return buff;
3926 }
3927}
3928
a06ea964
NC
3929static const char *
3930get_aarch64_segment_type (unsigned long type)
3931{
3932 switch (type)
3933 {
32ec8896
NC
3934 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3935 default: return NULL;
a06ea964 3936 }
a06ea964
NC
3937}
3938
b294bdf8
MM
3939static const char *
3940get_arm_segment_type (unsigned long type)
3941{
3942 switch (type)
3943 {
32ec8896
NC
3944 case PT_ARM_EXIDX: return "EXIDX";
3945 default: return NULL;
b294bdf8 3946 }
b294bdf8
MM
3947}
3948
b4cbbe8f
AK
3949static const char *
3950get_s390_segment_type (unsigned long type)
3951{
3952 switch (type)
3953 {
3954 case PT_S390_PGSTE: return "S390_PGSTE";
3955 default: return NULL;
3956 }
3957}
3958
d3ba0551
AM
3959static const char *
3960get_mips_segment_type (unsigned long type)
252b5132
RH
3961{
3962 switch (type)
3963 {
32ec8896
NC
3964 case PT_MIPS_REGINFO: return "REGINFO";
3965 case PT_MIPS_RTPROC: return "RTPROC";
3966 case PT_MIPS_OPTIONS: return "OPTIONS";
3967 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3968 default: return NULL;
252b5132 3969 }
252b5132
RH
3970}
3971
103f02d3 3972static const char *
d3ba0551 3973get_parisc_segment_type (unsigned long type)
103f02d3
UD
3974{
3975 switch (type)
3976 {
103f02d3
UD
3977 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3978 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3979 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3980 default: return NULL;
103f02d3 3981 }
103f02d3
UD
3982}
3983
4d6ed7c8 3984static const char *
d3ba0551 3985get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3986{
3987 switch (type)
3988 {
3989 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3990 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 3991 default: return NULL;
4d6ed7c8 3992 }
4d6ed7c8
NC
3993}
3994
40b36596
JM
3995static const char *
3996get_tic6x_segment_type (unsigned long type)
3997{
3998 switch (type)
3999 {
32ec8896
NC
4000 case PT_C6000_PHATTR: return "C6000_PHATTR";
4001 default: return NULL;
40b36596 4002 }
40b36596
JM
4003}
4004
df3a023b
AM
4005static const char *
4006get_hpux_segment_type (unsigned long type, unsigned e_machine)
4007{
4008 if (e_machine == EM_PARISC)
4009 switch (type)
4010 {
4011 case PT_HP_TLS: return "HP_TLS";
4012 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4013 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4014 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4015 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4016 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4017 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4018 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4019 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4020 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4021 case PT_HP_PARALLEL: return "HP_PARALLEL";
4022 case PT_HP_FASTBIND: return "HP_FASTBIND";
4023 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4024 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4025 case PT_HP_STACK: return "HP_STACK";
4026 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4027 default: return NULL;
4028 }
4029
4030 if (e_machine == EM_IA_64)
4031 switch (type)
4032 {
4033 case PT_HP_TLS: return "HP_TLS";
4034 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4035 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4036 case PT_IA_64_HP_STACK: return "HP_STACK";
4037 default: return NULL;
4038 }
4039
4040 return NULL;
4041}
4042
5522f910
NC
4043static const char *
4044get_solaris_segment_type (unsigned long type)
4045{
4046 switch (type)
4047 {
4048 case 0x6464e550: return "PT_SUNW_UNWIND";
4049 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4050 case 0x6ffffff7: return "PT_LOSUNW";
4051 case 0x6ffffffa: return "PT_SUNWBSS";
4052 case 0x6ffffffb: return "PT_SUNWSTACK";
4053 case 0x6ffffffc: return "PT_SUNWDTRACE";
4054 case 0x6ffffffd: return "PT_SUNWCAP";
4055 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4056 default: return NULL;
5522f910
NC
4057 }
4058}
4059
252b5132 4060static const char *
dda8d76d 4061get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4062{
b34976b6 4063 static char buff[32];
252b5132
RH
4064
4065 switch (p_type)
4066 {
b34976b6
AM
4067 case PT_NULL: return "NULL";
4068 case PT_LOAD: return "LOAD";
252b5132 4069 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4070 case PT_INTERP: return "INTERP";
4071 case PT_NOTE: return "NOTE";
4072 case PT_SHLIB: return "SHLIB";
4073 case PT_PHDR: return "PHDR";
13ae64f3 4074 case PT_TLS: return "TLS";
32ec8896 4075 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4076 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4077 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4078 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4079
3eba3ef3
NC
4080 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4081 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4082 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4083
252b5132 4084 default:
df3a023b 4085 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4086 {
2cf0635d 4087 const char * result;
103f02d3 4088
dda8d76d 4089 switch (filedata->file_header.e_machine)
252b5132 4090 {
a06ea964
NC
4091 case EM_AARCH64:
4092 result = get_aarch64_segment_type (p_type);
4093 break;
b294bdf8
MM
4094 case EM_ARM:
4095 result = get_arm_segment_type (p_type);
4096 break;
252b5132 4097 case EM_MIPS:
4fe85591 4098 case EM_MIPS_RS3_LE:
252b5132
RH
4099 result = get_mips_segment_type (p_type);
4100 break;
103f02d3
UD
4101 case EM_PARISC:
4102 result = get_parisc_segment_type (p_type);
4103 break;
4d6ed7c8
NC
4104 case EM_IA_64:
4105 result = get_ia64_segment_type (p_type);
4106 break;
40b36596
JM
4107 case EM_TI_C6000:
4108 result = get_tic6x_segment_type (p_type);
4109 break;
b4cbbe8f
AK
4110 case EM_S390:
4111 case EM_S390_OLD:
4112 result = get_s390_segment_type (p_type);
4113 break;
252b5132
RH
4114 default:
4115 result = NULL;
4116 break;
4117 }
103f02d3 4118
252b5132
RH
4119 if (result != NULL)
4120 return result;
103f02d3 4121
1a9ccd70 4122 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4123 }
4124 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4125 {
df3a023b 4126 const char * result = NULL;
103f02d3 4127
df3a023b 4128 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4129 {
df3a023b
AM
4130 case ELFOSABI_GNU:
4131 case ELFOSABI_FREEBSD:
4132 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4133 {
4134 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4135 result = buff;
4136 }
103f02d3 4137 break;
df3a023b
AM
4138 case ELFOSABI_HPUX:
4139 result = get_hpux_segment_type (p_type,
4140 filedata->file_header.e_machine);
4141 break;
4142 case ELFOSABI_SOLARIS:
4143 result = get_solaris_segment_type (p_type);
00428cca 4144 break;
103f02d3 4145 default:
103f02d3
UD
4146 break;
4147 }
103f02d3
UD
4148 if (result != NULL)
4149 return result;
4150
1a9ccd70 4151 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4152 }
252b5132 4153 else
e9e44622 4154 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4155
4156 return buff;
4157 }
4158}
4159
53a346d8
CZ
4160static const char *
4161get_arc_section_type_name (unsigned int sh_type)
4162{
4163 switch (sh_type)
4164 {
4165 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4166 default:
4167 break;
4168 }
4169 return NULL;
4170}
4171
252b5132 4172static const char *
d3ba0551 4173get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4174{
4175 switch (sh_type)
4176 {
b34976b6
AM
4177 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4178 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4179 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4180 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4181 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4182 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4183 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4184 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4185 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4186 case SHT_MIPS_RELD: return "MIPS_RELD";
4187 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4188 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4189 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4190 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4191 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4192 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4193 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4194 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4195 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4196 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4197 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4198 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4199 case SHT_MIPS_LINE: return "MIPS_LINE";
4200 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4201 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4202 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4203 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4204 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4205 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4206 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4207 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4208 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4209 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4210 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4211 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4212 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4213 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4214 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4215 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4216 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4217 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4218 default:
4219 break;
4220 }
4221 return NULL;
4222}
4223
103f02d3 4224static const char *
d3ba0551 4225get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4226{
4227 switch (sh_type)
4228 {
4229 case SHT_PARISC_EXT: return "PARISC_EXT";
4230 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4231 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4232 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4233 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4234 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4235 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4236 default: return NULL;
103f02d3 4237 }
103f02d3
UD
4238}
4239
4d6ed7c8 4240static const char *
dda8d76d 4241get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4242{
18bd398b 4243 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4244 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4245 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4246
4d6ed7c8
NC
4247 switch (sh_type)
4248 {
148b93f2
NC
4249 case SHT_IA_64_EXT: return "IA_64_EXT";
4250 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4251 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4252 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4253 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4254 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4255 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4256 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4257 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4258 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4259 default:
4260 break;
4261 }
4262 return NULL;
4263}
4264
d2b2c203
DJ
4265static const char *
4266get_x86_64_section_type_name (unsigned int sh_type)
4267{
4268 switch (sh_type)
4269 {
4270 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4271 default: return NULL;
d2b2c203 4272 }
d2b2c203
DJ
4273}
4274
a06ea964
NC
4275static const char *
4276get_aarch64_section_type_name (unsigned int sh_type)
4277{
4278 switch (sh_type)
4279 {
32ec8896
NC
4280 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4281 default: return NULL;
a06ea964 4282 }
a06ea964
NC
4283}
4284
40a18ebd
NC
4285static const char *
4286get_arm_section_type_name (unsigned int sh_type)
4287{
4288 switch (sh_type)
4289 {
7f6fed87
NC
4290 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4291 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4292 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4293 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4294 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4295 default: return NULL;
40a18ebd 4296 }
40a18ebd
NC
4297}
4298
40b36596
JM
4299static const char *
4300get_tic6x_section_type_name (unsigned int sh_type)
4301{
4302 switch (sh_type)
4303 {
32ec8896
NC
4304 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4305 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4306 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4307 case SHT_TI_ICODE: return "TI_ICODE";
4308 case SHT_TI_XREF: return "TI_XREF";
4309 case SHT_TI_HANDLER: return "TI_HANDLER";
4310 case SHT_TI_INITINFO: return "TI_INITINFO";
4311 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4312 default: return NULL;
40b36596 4313 }
40b36596
JM
4314}
4315
13761a11 4316static const char *
b0191216 4317get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4318{
4319 switch (sh_type)
4320 {
32ec8896
NC
4321 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4322 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4323 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4324 default: return NULL;
13761a11
NC
4325 }
4326}
4327
fe944acf
FT
4328static const char *
4329get_nfp_section_type_name (unsigned int sh_type)
4330{
4331 switch (sh_type)
4332 {
4333 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4334 case SHT_NFP_INITREG: return "NFP_INITREG";
4335 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4336 default: return NULL;
4337 }
4338}
4339
685080f2
NC
4340static const char *
4341get_v850_section_type_name (unsigned int sh_type)
4342{
4343 switch (sh_type)
4344 {
32ec8896
NC
4345 case SHT_V850_SCOMMON: return "V850 Small Common";
4346 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4347 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4348 case SHT_RENESAS_IOP: return "RENESAS IOP";
4349 case SHT_RENESAS_INFO: return "RENESAS INFO";
4350 default: return NULL;
685080f2
NC
4351 }
4352}
4353
2dc8dd17
JW
4354static const char *
4355get_riscv_section_type_name (unsigned int sh_type)
4356{
4357 switch (sh_type)
4358 {
4359 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4360 default: return NULL;
4361 }
4362}
4363
0861f561
CQ
4364static const char *
4365get_csky_section_type_name (unsigned int sh_type)
4366{
4367 switch (sh_type)
4368 {
4369 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4370 default: return NULL;
4371 }
4372}
4373
252b5132 4374static const char *
dda8d76d 4375get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4376{
b34976b6 4377 static char buff[32];
9fb71ee4 4378 const char * result;
252b5132
RH
4379
4380 switch (sh_type)
4381 {
4382 case SHT_NULL: return "NULL";
4383 case SHT_PROGBITS: return "PROGBITS";
4384 case SHT_SYMTAB: return "SYMTAB";
4385 case SHT_STRTAB: return "STRTAB";
4386 case SHT_RELA: return "RELA";
4387 case SHT_HASH: return "HASH";
4388 case SHT_DYNAMIC: return "DYNAMIC";
4389 case SHT_NOTE: return "NOTE";
4390 case SHT_NOBITS: return "NOBITS";
4391 case SHT_REL: return "REL";
4392 case SHT_SHLIB: return "SHLIB";
4393 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4394 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4395 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4396 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4397 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4398 case SHT_GROUP: return "GROUP";
67ce483b 4399 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4400 case SHT_GNU_verdef: return "VERDEF";
4401 case SHT_GNU_verneed: return "VERNEED";
4402 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4403 case 0x6ffffff0: return "VERSYM";
4404 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4405 case 0x7ffffffd: return "AUXILIARY";
4406 case 0x7fffffff: return "FILTER";
047b2264 4407 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4408
4409 default:
4410 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4411 {
dda8d76d 4412 switch (filedata->file_header.e_machine)
252b5132 4413 {
53a346d8
CZ
4414 case EM_ARC:
4415 case EM_ARC_COMPACT:
4416 case EM_ARC_COMPACT2:
4417 result = get_arc_section_type_name (sh_type);
4418 break;
252b5132 4419 case EM_MIPS:
4fe85591 4420 case EM_MIPS_RS3_LE:
252b5132
RH
4421 result = get_mips_section_type_name (sh_type);
4422 break;
103f02d3
UD
4423 case EM_PARISC:
4424 result = get_parisc_section_type_name (sh_type);
4425 break;
4d6ed7c8 4426 case EM_IA_64:
dda8d76d 4427 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4428 break;
d2b2c203 4429 case EM_X86_64:
8a9036a4 4430 case EM_L1OM:
7a9068fe 4431 case EM_K1OM:
d2b2c203
DJ
4432 result = get_x86_64_section_type_name (sh_type);
4433 break;
a06ea964
NC
4434 case EM_AARCH64:
4435 result = get_aarch64_section_type_name (sh_type);
4436 break;
40a18ebd
NC
4437 case EM_ARM:
4438 result = get_arm_section_type_name (sh_type);
4439 break;
40b36596
JM
4440 case EM_TI_C6000:
4441 result = get_tic6x_section_type_name (sh_type);
4442 break;
13761a11 4443 case EM_MSP430:
b0191216 4444 result = get_msp430_section_type_name (sh_type);
13761a11 4445 break;
fe944acf
FT
4446 case EM_NFP:
4447 result = get_nfp_section_type_name (sh_type);
4448 break;
685080f2
NC
4449 case EM_V800:
4450 case EM_V850:
4451 case EM_CYGNUS_V850:
4452 result = get_v850_section_type_name (sh_type);
4453 break;
2dc8dd17
JW
4454 case EM_RISCV:
4455 result = get_riscv_section_type_name (sh_type);
4456 break;
0861f561
CQ
4457 case EM_CSKY:
4458 result = get_csky_section_type_name (sh_type);
4459 break;
252b5132
RH
4460 default:
4461 result = NULL;
4462 break;
4463 }
4464
4465 if (result != NULL)
4466 return result;
4467
9fb71ee4 4468 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4469 }
4470 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4471 {
dda8d76d 4472 switch (filedata->file_header.e_machine)
148b93f2
NC
4473 {
4474 case EM_IA_64:
dda8d76d 4475 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4476 break;
4477 default:
dda8d76d 4478 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4479 result = get_solaris_section_type (sh_type);
4480 else
1b4b80bf
NC
4481 {
4482 switch (sh_type)
4483 {
4484 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4485 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4486 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4487 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4488 default:
4489 result = NULL;
4490 break;
4491 }
4492 }
148b93f2
NC
4493 break;
4494 }
4495
4496 if (result != NULL)
4497 return result;
4498
9fb71ee4 4499 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4500 }
252b5132 4501 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4502 {
dda8d76d 4503 switch (filedata->file_header.e_machine)
685080f2
NC
4504 {
4505 case EM_V800:
4506 case EM_V850:
4507 case EM_CYGNUS_V850:
9fb71ee4 4508 result = get_v850_section_type_name (sh_type);
a9fb83be 4509 break;
685080f2 4510 default:
9fb71ee4 4511 result = NULL;
685080f2
NC
4512 break;
4513 }
4514
9fb71ee4
NC
4515 if (result != NULL)
4516 return result;
4517
4518 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4519 }
252b5132 4520 else
a7dbfd1c
NC
4521 /* This message is probably going to be displayed in a 15
4522 character wide field, so put the hex value first. */
4523 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4524
252b5132
RH
4525 return buff;
4526 }
4527}
4528
79bc120c
NC
4529enum long_option_values
4530{
4531 OPTION_DEBUG_DUMP = 512,
4532 OPTION_DYN_SYMS,
0f03783c 4533 OPTION_LTO_SYMS,
79bc120c
NC
4534 OPTION_DWARF_DEPTH,
4535 OPTION_DWARF_START,
4536 OPTION_DWARF_CHECK,
4537 OPTION_CTF_DUMP,
4538 OPTION_CTF_PARENT,
4539 OPTION_CTF_SYMBOLS,
4540 OPTION_CTF_STRINGS,
4541 OPTION_WITH_SYMBOL_VERSIONS,
4542 OPTION_RECURSE_LIMIT,
4543 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
4544 OPTION_NO_DEMANGLING,
4545 OPTION_SYM_BASE
79bc120c 4546};
2979dc34 4547
85b1c36d 4548static struct option options[] =
252b5132 4549{
79bc120c
NC
4550 /* Note - This table is alpha-sorted on the 'val'
4551 field in order to make adding new options easier. */
4552 {"arch-specific", no_argument, 0, 'A'},
b34976b6 4553 {"all", no_argument, 0, 'a'},
79bc120c
NC
4554 {"demangle", optional_argument, 0, 'C'},
4555 {"archive-index", no_argument, 0, 'c'},
4556 {"use-dynamic", no_argument, 0, 'D'},
4557 {"dynamic", no_argument, 0, 'd'},
b34976b6 4558 {"headers", no_argument, 0, 'e'},
79bc120c
NC
4559 {"section-groups", no_argument, 0, 'g'},
4560 {"help", no_argument, 0, 'H'},
4561 {"file-header", no_argument, 0, 'h'},
b34976b6 4562 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
4563 {"lint", no_argument, 0, 'L'},
4564 {"enable-checks", no_argument, 0, 'L'},
4565 {"program-headers", no_argument, 0, 'l'},
b34976b6 4566 {"segments", no_argument, 0, 'l'},
595cf52e 4567 {"full-section-name",no_argument, 0, 'N'},
79bc120c 4568 {"notes", no_argument, 0, 'n'},
ca0e11aa 4569 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
4570 {"string-dump", required_argument, 0, 'p'},
4571 {"relocated-dump", required_argument, 0, 'R'},
4572 {"relocs", no_argument, 0, 'r'},
4573 {"section-headers", no_argument, 0, 'S'},
4574 {"sections", no_argument, 0, 'S'},
b34976b6
AM
4575 {"symbols", no_argument, 0, 's'},
4576 {"syms", no_argument, 0, 's'},
79bc120c
NC
4577 {"silent-truncation",no_argument, 0, 'T'},
4578 {"section-details", no_argument, 0, 't'},
09c11c86 4579 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
4580 {"version-info", no_argument, 0, 'V'},
4581 {"version", no_argument, 0, 'v'},
4582 {"wide", no_argument, 0, 'W'},
b34976b6 4583 {"hex-dump", required_argument, 0, 'x'},
0e602686 4584 {"decompress", no_argument, 0, 'z'},
252b5132 4585
79bc120c
NC
4586 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
4587 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
4588 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4589 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4590 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 4591 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 4592 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
4593 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4594 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4595 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 4596#ifdef ENABLE_LIBCTF
d344b407 4597 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
4598 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
4599 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
4600 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 4601#endif
047c3dbf 4602 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 4603
b34976b6 4604 {0, no_argument, 0, 0}
252b5132
RH
4605};
4606
4607static void
2cf0635d 4608usage (FILE * stream)
252b5132 4609{
92f01d61
JM
4610 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4611 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
4612 fprintf (stream, _(" Options are:\n"));
4613 fprintf (stream, _("\
4614 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
4615 fprintf (stream, _("\
4616 -h --file-header Display the ELF file header\n"));
4617 fprintf (stream, _("\
4618 -l --program-headers Display the program headers\n"));
4619 fprintf (stream, _("\
4620 --segments An alias for --program-headers\n"));
4621 fprintf (stream, _("\
4622 -S --section-headers Display the sections' header\n"));
4623 fprintf (stream, _("\
4624 --sections An alias for --section-headers\n"));
4625 fprintf (stream, _("\
4626 -g --section-groups Display the section groups\n"));
4627 fprintf (stream, _("\
4628 -t --section-details Display the section details\n"));
4629 fprintf (stream, _("\
4630 -e --headers Equivalent to: -h -l -S\n"));
4631 fprintf (stream, _("\
4632 -s --syms Display the symbol table\n"));
4633 fprintf (stream, _("\
4634 --symbols An alias for --syms\n"));
4635 fprintf (stream, _("\
4636 --dyn-syms Display the dynamic symbol table\n"));
4637 fprintf (stream, _("\
4638 --lto-syms Display LTO symbol tables\n"));
4639 fprintf (stream, _("\
047c3dbf
NL
4640 --sym-base=[0|8|10|16] \n\
4641 Force base for symbol sizes. The options are \n\
d6249f5f
AM
4642 mixed (the default), octal, decimal, hexadecimal.\n"));
4643 fprintf (stream, _("\
79bc120c
NC
4644 -C --demangle[=STYLE] Decode low-level symbol names into user-level names\n\
4645 The STYLE, if specified, can be `auto' (the default),\n\
4646 `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
d6249f5f
AM
4647 or `gnat'\n"));
4648 fprintf (stream, _("\
4649 --no-demangle Do not demangle low-level symbol names. (default)\n"));
4650 fprintf (stream, _("\
4651 --recurse-limit Enable a demangling recursion limit. (default)\n"));
4652 fprintf (stream, _("\
4653 --no-recurse-limit Disable a demangling recursion limit\n"));
4654 fprintf (stream, _("\
4655 -n --notes Display the core notes (if present)\n"));
4656 fprintf (stream, _("\
4657 -r --relocs Display the relocations (if present)\n"));
4658 fprintf (stream, _("\
4659 -u --unwind Display the unwind info (if present)\n"));
4660 fprintf (stream, _("\
4661 -d --dynamic Display the dynamic section (if present)\n"));
4662 fprintf (stream, _("\
4663 -V --version-info Display the version sections (if present)\n"));
4664 fprintf (stream, _("\
4665 -A --arch-specific Display architecture specific information (if any)\n"));
4666 fprintf (stream, _("\
4667 -c --archive-index Display the symbol/file index in an archive\n"));
4668 fprintf (stream, _("\
4669 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
4670 fprintf (stream, _("\
4671 -L --lint|--enable-checks\n\
4672 Display warning messages for possible problems\n"));
4673 fprintf (stream, _("\
09c11c86 4674 -x --hex-dump=<number|name>\n\
d6249f5f
AM
4675 Dump the contents of section <number|name> as bytes\n"));
4676 fprintf (stream, _("\
09c11c86 4677 -p --string-dump=<number|name>\n\
d6249f5f
AM
4678 Dump the contents of section <number|name> as strings\n"));
4679 fprintf (stream, _("\
cf13d699 4680 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
4681 Dump the relocated contents of section <number|name>\n"));
4682 fprintf (stream, _("\
4683 -z --decompress Decompress section before dumping it\n"));
4684 fprintf (stream, _("\
4685 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
4686 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
4687 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
4688 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
4689 U/=trace_info]\n\
4690 Display the contents of DWARF debug sections\n"));
4691 fprintf (stream, _("\
4692 -wk --debug-dump=links Display the contents of sections that link to separate\n\
4693 debuginfo files\n"));
4694 fprintf (stream, _("\
4695 -P --process-links Display the contents of non-debug sections in separate\n\
4696 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
4697#if DEFAULT_FOR_FOLLOW_LINKS
4698 fprintf (stream, _("\
d6249f5f
AM
4699 -wK --debug-dump=follow-links\n\
4700 Follow links to separate debug info files (default)\n"));
4701 fprintf (stream, _("\
4702 -wN --debug-dump=no-follow-links\n\
4703 Do not follow links to separate debug info files\n"));
c46b7066
NC
4704#else
4705 fprintf (stream, _("\
d6249f5f
AM
4706 -wK --debug-dump=follow-links\n\
4707 Follow links to separate debug info files\n"));
4708 fprintf (stream, _("\
4709 -wN --debug-dump=no-follow-links\n\
4710 Do not follow links to separate debug info files\n\
4711 (default)\n"));
c46b7066 4712#endif
fd2f0033 4713 fprintf (stream, _("\
d6249f5f
AM
4714 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
4715 fprintf (stream, _("\
4716 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 4717#ifdef ENABLE_LIBCTF
7d9813f1 4718 fprintf (stream, _("\
d6249f5f
AM
4719 --ctf=<number|name> Display CTF info from section <number|name>\n"));
4720 fprintf (stream, _("\
7d9813f1 4721 --ctf-parent=<number|name>\n\
d6249f5f
AM
4722 Use section <number|name> as the CTF parent\n"));
4723 fprintf (stream, _("\
7d9813f1 4724 --ctf-symbols=<number|name>\n\
d6249f5f
AM
4725 Use section <number|name> as the CTF external symtab\n"));
4726 fprintf (stream, _("\
7d9813f1 4727 --ctf-strings=<number|name>\n\
d6249f5f 4728 Use section <number|name> as the CTF external strtab\n"));
094e34f2 4729#endif
7d9813f1 4730
252b5132 4731#ifdef SUPPORT_DISASSEMBLY
92f01d61 4732 fprintf (stream, _("\
09c11c86
NC
4733 -i --instruction-dump=<number|name>\n\
4734 Disassemble the contents of section <number|name>\n"));
252b5132 4735#endif
92f01d61 4736 fprintf (stream, _("\
d6249f5f
AM
4737 -I --histogram Display histogram of bucket list lengths\n"));
4738 fprintf (stream, _("\
4739 -W --wide Allow output width to exceed 80 characters\n"));
4740 fprintf (stream, _("\
4741 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
4742 fprintf (stream, _("\
4743 @<file> Read options from <file>\n"));
4744 fprintf (stream, _("\
4745 -H --help Display this information\n"));
4746 fprintf (stream, _("\
8b53311e 4747 -v --version Display the version number of readelf\n"));
1118d252 4748
92f01d61
JM
4749 if (REPORT_BUGS_TO[0] && stream == stdout)
4750 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4751
92f01d61 4752 exit (stream == stdout ? 0 : 1);
252b5132
RH
4753}
4754
18bd398b
NC
4755/* Record the fact that the user wants the contents of section number
4756 SECTION to be displayed using the method(s) encoded as flags bits
4757 in TYPE. Note, TYPE can be zero if we are creating the array for
4758 the first time. */
4759
252b5132 4760static void
6431e409
AM
4761request_dump_bynumber (struct dump_data *dumpdata,
4762 unsigned int section, dump_type type)
252b5132 4763{
6431e409 4764 if (section >= dumpdata->num_dump_sects)
252b5132 4765 {
2cf0635d 4766 dump_type * new_dump_sects;
252b5132 4767
3f5e193b 4768 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4769 sizeof (* new_dump_sects));
252b5132
RH
4770
4771 if (new_dump_sects == NULL)
591a748a 4772 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4773 else
4774 {
6431e409 4775 if (dumpdata->dump_sects)
21b65bac
NC
4776 {
4777 /* Copy current flag settings. */
6431e409
AM
4778 memcpy (new_dump_sects, dumpdata->dump_sects,
4779 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4780
6431e409 4781 free (dumpdata->dump_sects);
21b65bac 4782 }
252b5132 4783
6431e409
AM
4784 dumpdata->dump_sects = new_dump_sects;
4785 dumpdata->num_dump_sects = section + 1;
252b5132
RH
4786 }
4787 }
4788
6431e409
AM
4789 if (dumpdata->dump_sects)
4790 dumpdata->dump_sects[section] |= type;
252b5132
RH
4791}
4792
aef1f6d0
DJ
4793/* Request a dump by section name. */
4794
4795static void
2cf0635d 4796request_dump_byname (const char * section, dump_type type)
aef1f6d0 4797{
2cf0635d 4798 struct dump_list_entry * new_request;
aef1f6d0 4799
3f5e193b
NC
4800 new_request = (struct dump_list_entry *)
4801 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4802 if (!new_request)
591a748a 4803 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4804
4805 new_request->name = strdup (section);
4806 if (!new_request->name)
591a748a 4807 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4808
4809 new_request->type = type;
4810
4811 new_request->next = dump_sects_byname;
4812 dump_sects_byname = new_request;
4813}
4814
cf13d699 4815static inline void
6431e409 4816request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
4817{
4818 int section;
4819 char * cp;
4820
015dc7e1 4821 do_dump = true;
cf13d699
NC
4822 section = strtoul (optarg, & cp, 0);
4823
4824 if (! *cp && section >= 0)
6431e409 4825 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
4826 else
4827 request_dump_byname (optarg, type);
4828}
4829
252b5132 4830static void
6431e409 4831parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
4832{
4833 int c;
4834
4835 if (argc < 2)
92f01d61 4836 usage (stderr);
252b5132
RH
4837
4838 while ((c = getopt_long
ca0e11aa 4839 (argc, argv, "ACDHILNPR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4840 {
252b5132
RH
4841 switch (c)
4842 {
4843 case 0:
4844 /* Long options. */
4845 break;
4846 case 'H':
92f01d61 4847 usage (stdout);
252b5132
RH
4848 break;
4849
4850 case 'a':
015dc7e1
AM
4851 do_syms = true;
4852 do_reloc = true;
4853 do_unwind = true;
4854 do_dynamic = true;
4855 do_header = true;
4856 do_sections = true;
4857 do_section_groups = true;
4858 do_segments = true;
4859 do_version = true;
4860 do_histogram = true;
4861 do_arch = true;
4862 do_notes = true;
252b5132 4863 break;
79bc120c 4864
f5842774 4865 case 'g':
015dc7e1 4866 do_section_groups = true;
f5842774 4867 break;
5477e8a0 4868 case 't':
595cf52e 4869 case 'N':
015dc7e1
AM
4870 do_sections = true;
4871 do_section_details = true;
595cf52e 4872 break;
252b5132 4873 case 'e':
015dc7e1
AM
4874 do_header = true;
4875 do_sections = true;
4876 do_segments = true;
252b5132 4877 break;
a952a375 4878 case 'A':
015dc7e1 4879 do_arch = true;
a952a375 4880 break;
252b5132 4881 case 'D':
015dc7e1 4882 do_using_dynamic = true;
252b5132
RH
4883 break;
4884 case 'r':
015dc7e1 4885 do_reloc = true;
252b5132 4886 break;
4d6ed7c8 4887 case 'u':
015dc7e1 4888 do_unwind = true;
4d6ed7c8 4889 break;
252b5132 4890 case 'h':
015dc7e1 4891 do_header = true;
252b5132
RH
4892 break;
4893 case 'l':
015dc7e1 4894 do_segments = true;
252b5132
RH
4895 break;
4896 case 's':
015dc7e1 4897 do_syms = true;
252b5132
RH
4898 break;
4899 case 'S':
015dc7e1 4900 do_sections = true;
252b5132
RH
4901 break;
4902 case 'd':
015dc7e1 4903 do_dynamic = true;
252b5132 4904 break;
a952a375 4905 case 'I':
015dc7e1 4906 do_histogram = true;
a952a375 4907 break;
779fe533 4908 case 'n':
015dc7e1 4909 do_notes = true;
779fe533 4910 break;
4145f1d5 4911 case 'c':
015dc7e1 4912 do_archive_index = true;
4145f1d5 4913 break;
1b513401 4914 case 'L':
015dc7e1 4915 do_checks = true;
1b513401 4916 break;
ca0e11aa 4917 case 'P':
015dc7e1
AM
4918 process_links = true;
4919 do_follow_links = true;
ca0e11aa 4920 break;
252b5132 4921 case 'x':
6431e409 4922 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 4923 break;
09c11c86 4924 case 'p':
6431e409 4925 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
4926 break;
4927 case 'R':
6431e409 4928 request_dump (dumpdata, RELOC_DUMP);
09c11c86 4929 break;
0e602686 4930 case 'z':
015dc7e1 4931 decompress_dumps = true;
0e602686 4932 break;
252b5132 4933 case 'w':
015dc7e1 4934 do_dump = true;
0f03783c 4935 if (optarg == NULL)
613ff48b 4936 {
015dc7e1 4937 do_debugging = true;
613ff48b
CC
4938 dwarf_select_sections_all ();
4939 }
252b5132
RH
4940 else
4941 {
015dc7e1 4942 do_debugging = false;
4cb93e3b 4943 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4944 }
4945 break;
2979dc34 4946 case OPTION_DEBUG_DUMP:
015dc7e1 4947 do_dump = true;
0f03783c 4948 if (optarg == NULL)
d6249f5f
AM
4949 {
4950 do_debugging = true;
4951 dwarf_select_sections_all ();
4952 }
2979dc34
JJ
4953 else
4954 {
015dc7e1 4955 do_debugging = false;
4cb93e3b 4956 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4957 }
4958 break;
fd2f0033
TT
4959 case OPTION_DWARF_DEPTH:
4960 {
4961 char *cp;
4962
4963 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4964 }
4965 break;
4966 case OPTION_DWARF_START:
4967 {
4968 char *cp;
4969
4970 dwarf_start_die = strtoul (optarg, & cp, 0);
4971 }
4972 break;
4723351a 4973 case OPTION_DWARF_CHECK:
015dc7e1 4974 dwarf_check = true;
4723351a 4975 break;
7d9813f1 4976 case OPTION_CTF_DUMP:
015dc7e1 4977 do_ctf = true;
6431e409 4978 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
4979 break;
4980 case OPTION_CTF_SYMBOLS:
df16e041 4981 free (dump_ctf_symtab_name);
7d9813f1
NA
4982 dump_ctf_symtab_name = strdup (optarg);
4983 break;
4984 case OPTION_CTF_STRINGS:
df16e041 4985 free (dump_ctf_strtab_name);
7d9813f1
NA
4986 dump_ctf_strtab_name = strdup (optarg);
4987 break;
4988 case OPTION_CTF_PARENT:
df16e041 4989 free (dump_ctf_parent_name);
7d9813f1
NA
4990 dump_ctf_parent_name = strdup (optarg);
4991 break;
2c610e4b 4992 case OPTION_DYN_SYMS:
015dc7e1 4993 do_dyn_syms = true;
2c610e4b 4994 break;
0f03783c 4995 case OPTION_LTO_SYMS:
015dc7e1 4996 do_lto_syms = true;
0f03783c 4997 break;
252b5132
RH
4998#ifdef SUPPORT_DISASSEMBLY
4999 case 'i':
6431e409 5000 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5001 break;
252b5132
RH
5002#endif
5003 case 'v':
5004 print_version (program_name);
5005 break;
5006 case 'V':
015dc7e1 5007 do_version = true;
252b5132 5008 break;
d974e256 5009 case 'W':
015dc7e1 5010 do_wide = true;
d974e256 5011 break;
0942c7ab 5012 case 'T':
015dc7e1 5013 do_not_show_symbol_truncation = true;
0942c7ab 5014 break;
79bc120c 5015 case 'C':
015dc7e1 5016 do_demangle = true;
79bc120c
NC
5017 if (optarg != NULL)
5018 {
5019 enum demangling_styles style;
5020
5021 style = cplus_demangle_name_to_style (optarg);
5022 if (style == unknown_demangling)
5023 error (_("unknown demangling style `%s'"), optarg);
5024
5025 cplus_demangle_set_style (style);
5026 }
5027 break;
5028 case OPTION_NO_DEMANGLING:
015dc7e1 5029 do_demangle = false;
79bc120c
NC
5030 break;
5031 case OPTION_RECURSE_LIMIT:
5032 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5033 break;
5034 case OPTION_NO_RECURSE_LIMIT:
5035 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5036 break;
5037 case OPTION_WITH_SYMBOL_VERSIONS:
5038 /* Ignored for backward compatibility. */
5039 break;
b9e920ec 5040
047c3dbf
NL
5041 case OPTION_SYM_BASE:
5042 sym_base = 0;
5043 if (optarg != NULL)
5044 {
5045 sym_base = strtoul (optarg, NULL, 0);
5046 switch (sym_base)
5047 {
5048 case 0:
5049 case 8:
5050 case 10:
5051 case 16:
5052 break;
5053
5054 default:
5055 sym_base = 0;
5056 break;
5057 }
5058 }
5059 break;
5060
252b5132 5061 default:
252b5132
RH
5062 /* xgettext:c-format */
5063 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5064 /* Fall through. */
252b5132 5065 case '?':
92f01d61 5066 usage (stderr);
252b5132
RH
5067 }
5068 }
5069
4d6ed7c8 5070 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5071 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5072 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5073 && !do_section_groups && !do_archive_index
0f03783c 5074 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5075 {
5076 if (do_checks)
5077 {
015dc7e1
AM
5078 check_all = true;
5079 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5080 do_segments = do_header = do_dump = do_version = true;
5081 do_histogram = do_debugging = do_arch = do_notes = true;
5082 do_section_groups = do_archive_index = do_dyn_syms = true;
5083 do_lto_syms = true;
1b513401
NC
5084 }
5085 else
5086 usage (stderr);
5087 }
252b5132
RH
5088}
5089
5090static const char *
d3ba0551 5091get_elf_class (unsigned int elf_class)
252b5132 5092{
b34976b6 5093 static char buff[32];
103f02d3 5094
252b5132
RH
5095 switch (elf_class)
5096 {
5097 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5098 case ELFCLASS32: return "ELF32";
5099 case ELFCLASS64: return "ELF64";
ab5e7794 5100 default:
e9e44622 5101 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5102 return buff;
252b5132
RH
5103 }
5104}
5105
5106static const char *
d3ba0551 5107get_data_encoding (unsigned int encoding)
252b5132 5108{
b34976b6 5109 static char buff[32];
103f02d3 5110
252b5132
RH
5111 switch (encoding)
5112 {
5113 case ELFDATANONE: return _("none");
33c63f9d
CM
5114 case ELFDATA2LSB: return _("2's complement, little endian");
5115 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5116 default:
e9e44622 5117 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5118 return buff;
252b5132
RH
5119 }
5120}
5121
dda8d76d 5122/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5123
015dc7e1 5124static bool
dda8d76d 5125process_file_header (Filedata * filedata)
252b5132 5126{
dda8d76d
NC
5127 Elf_Internal_Ehdr * header = & filedata->file_header;
5128
5129 if ( header->e_ident[EI_MAG0] != ELFMAG0
5130 || header->e_ident[EI_MAG1] != ELFMAG1
5131 || header->e_ident[EI_MAG2] != ELFMAG2
5132 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5133 {
5134 error
5135 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
015dc7e1 5136 return false;
252b5132
RH
5137 }
5138
ca0e11aa
NC
5139 if (! filedata->is_separate)
5140 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5141
252b5132
RH
5142 if (do_header)
5143 {
32ec8896 5144 unsigned i;
252b5132 5145
ca0e11aa
NC
5146 if (filedata->is_separate)
5147 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5148 else
5149 printf (_("ELF Header:\n"));
252b5132 5150 printf (_(" Magic: "));
b34976b6 5151 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5152 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5153 printf ("\n");
5154 printf (_(" Class: %s\n"),
dda8d76d 5155 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5156 printf (_(" Data: %s\n"),
dda8d76d 5157 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5158 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5159 header->e_ident[EI_VERSION],
5160 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5161 ? _(" (current)")
dda8d76d 5162 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5163 ? _(" <unknown>")
789be9f7 5164 : "")));
252b5132 5165 printf (_(" OS/ABI: %s\n"),
dda8d76d 5166 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5167 printf (_(" ABI Version: %d\n"),
dda8d76d 5168 header->e_ident[EI_ABIVERSION]);
252b5132 5169 printf (_(" Type: %s\n"),
dda8d76d 5170 get_file_type (header->e_type));
252b5132 5171 printf (_(" Machine: %s\n"),
dda8d76d 5172 get_machine_name (header->e_machine));
252b5132 5173 printf (_(" Version: 0x%lx\n"),
e8a64888 5174 header->e_version);
76da6bbe 5175
f7a99963 5176 printf (_(" Entry point address: "));
e8a64888 5177 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5178 printf (_("\n Start of program headers: "));
e8a64888 5179 print_vma (header->e_phoff, DEC);
f7a99963 5180 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5181 print_vma (header->e_shoff, DEC);
f7a99963 5182 printf (_(" (bytes into file)\n"));
76da6bbe 5183
252b5132 5184 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5185 header->e_flags,
dda8d76d 5186 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5187 printf (_(" Size of this header: %u (bytes)\n"),
5188 header->e_ehsize);
5189 printf (_(" Size of program headers: %u (bytes)\n"),
5190 header->e_phentsize);
5191 printf (_(" Number of program headers: %u"),
5192 header->e_phnum);
dda8d76d
NC
5193 if (filedata->section_headers != NULL
5194 && header->e_phnum == PN_XNUM
5195 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
5196 {
5197 header->e_phnum = filedata->section_headers[0].sh_info;
5198 printf (" (%u)", header->e_phnum);
5199 }
2046a35d 5200 putc ('\n', stdout);
e8a64888
AM
5201 printf (_(" Size of section headers: %u (bytes)\n"),
5202 header->e_shentsize);
5203 printf (_(" Number of section headers: %u"),
5204 header->e_shnum);
dda8d76d 5205 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5206 {
5207 header->e_shnum = filedata->section_headers[0].sh_size;
5208 printf (" (%u)", header->e_shnum);
5209 }
560f3c1c 5210 putc ('\n', stdout);
e8a64888
AM
5211 printf (_(" Section header string table index: %u"),
5212 header->e_shstrndx);
dda8d76d
NC
5213 if (filedata->section_headers != NULL
5214 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5215 {
5216 header->e_shstrndx = filedata->section_headers[0].sh_link;
5217 printf (" (%u)", header->e_shstrndx);
5218 }
5219 if (header->e_shstrndx != SHN_UNDEF
5220 && header->e_shstrndx >= header->e_shnum)
5221 {
5222 header->e_shstrndx = SHN_UNDEF;
5223 printf (_(" <corrupt: out of range>"));
5224 }
560f3c1c
AM
5225 putc ('\n', stdout);
5226 }
5227
dda8d76d 5228 if (filedata->section_headers != NULL)
560f3c1c 5229 {
dda8d76d
NC
5230 if (header->e_phnum == PN_XNUM
5231 && filedata->section_headers[0].sh_info != 0)
5232 header->e_phnum = filedata->section_headers[0].sh_info;
5233 if (header->e_shnum == SHN_UNDEF)
5234 header->e_shnum = filedata->section_headers[0].sh_size;
5235 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5236 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5237 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
5238 header->e_shstrndx = SHN_UNDEF;
5239 free (filedata->section_headers);
5240 filedata->section_headers = NULL;
252b5132 5241 }
103f02d3 5242
015dc7e1 5243 return true;
9ea033b2
NC
5244}
5245
dda8d76d
NC
5246/* Read in the program headers from FILEDATA and store them in PHEADERS.
5247 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5248
015dc7e1 5249static bool
dda8d76d 5250get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5251{
2cf0635d
NC
5252 Elf32_External_Phdr * phdrs;
5253 Elf32_External_Phdr * external;
5254 Elf_Internal_Phdr * internal;
b34976b6 5255 unsigned int i;
dda8d76d
NC
5256 unsigned int size = filedata->file_header.e_phentsize;
5257 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5258
5259 /* PR binutils/17531: Cope with unexpected section header sizes. */
5260 if (size == 0 || num == 0)
015dc7e1 5261 return false;
e0a31db1
NC
5262 if (size < sizeof * phdrs)
5263 {
5264 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5265 return false;
e0a31db1
NC
5266 }
5267 if (size > sizeof * phdrs)
5268 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5269
dda8d76d 5270 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5271 size, num, _("program headers"));
5272 if (phdrs == NULL)
015dc7e1 5273 return false;
9ea033b2 5274
91d6fa6a 5275 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5276 i < filedata->file_header.e_phnum;
b34976b6 5277 i++, internal++, external++)
252b5132 5278 {
9ea033b2
NC
5279 internal->p_type = BYTE_GET (external->p_type);
5280 internal->p_offset = BYTE_GET (external->p_offset);
5281 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5282 internal->p_paddr = BYTE_GET (external->p_paddr);
5283 internal->p_filesz = BYTE_GET (external->p_filesz);
5284 internal->p_memsz = BYTE_GET (external->p_memsz);
5285 internal->p_flags = BYTE_GET (external->p_flags);
5286 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5287 }
5288
9ea033b2 5289 free (phdrs);
015dc7e1 5290 return true;
252b5132
RH
5291}
5292
dda8d76d
NC
5293/* Read in the program headers from FILEDATA and store them in PHEADERS.
5294 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5295
015dc7e1 5296static bool
dda8d76d 5297get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5298{
2cf0635d
NC
5299 Elf64_External_Phdr * phdrs;
5300 Elf64_External_Phdr * external;
5301 Elf_Internal_Phdr * internal;
b34976b6 5302 unsigned int i;
dda8d76d
NC
5303 unsigned int size = filedata->file_header.e_phentsize;
5304 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5305
5306 /* PR binutils/17531: Cope with unexpected section header sizes. */
5307 if (size == 0 || num == 0)
015dc7e1 5308 return false;
e0a31db1
NC
5309 if (size < sizeof * phdrs)
5310 {
5311 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5312 return false;
e0a31db1
NC
5313 }
5314 if (size > sizeof * phdrs)
5315 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5316
dda8d76d 5317 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5318 size, num, _("program headers"));
a6e9f9df 5319 if (!phdrs)
015dc7e1 5320 return false;
9ea033b2 5321
91d6fa6a 5322 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5323 i < filedata->file_header.e_phnum;
b34976b6 5324 i++, internal++, external++)
9ea033b2
NC
5325 {
5326 internal->p_type = BYTE_GET (external->p_type);
5327 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5328 internal->p_offset = BYTE_GET (external->p_offset);
5329 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5330 internal->p_paddr = BYTE_GET (external->p_paddr);
5331 internal->p_filesz = BYTE_GET (external->p_filesz);
5332 internal->p_memsz = BYTE_GET (external->p_memsz);
5333 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5334 }
5335
5336 free (phdrs);
015dc7e1 5337 return true;
9ea033b2 5338}
252b5132 5339
32ec8896 5340/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5341
015dc7e1 5342static bool
dda8d76d 5343get_program_headers (Filedata * filedata)
d93f0186 5344{
2cf0635d 5345 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5346
5347 /* Check cache of prior read. */
dda8d76d 5348 if (filedata->program_headers != NULL)
015dc7e1 5349 return true;
d93f0186 5350
82156ab7
NC
5351 /* Be kind to memory checkers by looking for
5352 e_phnum values which we know must be invalid. */
dda8d76d 5353 if (filedata->file_header.e_phnum
82156ab7 5354 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5355 >= filedata->file_size)
82156ab7
NC
5356 {
5357 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5358 filedata->file_header.e_phnum);
015dc7e1 5359 return false;
82156ab7 5360 }
d93f0186 5361
dda8d76d 5362 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5363 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5364 if (phdrs == NULL)
5365 {
8b73c356 5366 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5367 filedata->file_header.e_phnum);
015dc7e1 5368 return false;
d93f0186
NC
5369 }
5370
5371 if (is_32bit_elf
dda8d76d
NC
5372 ? get_32bit_program_headers (filedata, phdrs)
5373 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5374 {
dda8d76d 5375 filedata->program_headers = phdrs;
015dc7e1 5376 return true;
d93f0186
NC
5377 }
5378
5379 free (phdrs);
015dc7e1 5380 return false;
d93f0186
NC
5381}
5382
32ec8896 5383/* Returns TRUE if the program headers were loaded. */
2f62977e 5384
015dc7e1 5385static bool
dda8d76d 5386process_program_headers (Filedata * filedata)
252b5132 5387{
2cf0635d 5388 Elf_Internal_Phdr * segment;
b34976b6 5389 unsigned int i;
1a9ccd70 5390 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5391
978c4450
AM
5392 filedata->dynamic_addr = 0;
5393 filedata->dynamic_size = 0;
663f67df 5394
dda8d76d 5395 if (filedata->file_header.e_phnum == 0)
252b5132 5396 {
82f2dbf7 5397 /* PR binutils/12467. */
dda8d76d 5398 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5399 {
5400 warn (_("possibly corrupt ELF header - it has a non-zero program"
5401 " header offset, but no program headers\n"));
015dc7e1 5402 return false;
32ec8896 5403 }
82f2dbf7 5404 else if (do_segments)
ca0e11aa
NC
5405 {
5406 if (filedata->is_separate)
5407 printf (_("\nThere are no program headers in linked file '%s'.\n"),
5408 filedata->file_name);
5409 else
5410 printf (_("\nThere are no program headers in this file.\n"));
5411 }
015dc7e1 5412 return true;
252b5132
RH
5413 }
5414
5415 if (do_segments && !do_header)
5416 {
ca0e11aa
NC
5417 if (filedata->is_separate)
5418 printf ("\nIn linked file '%s' the ELF file type is %s\n",
5419 filedata->file_name,
5420 get_file_type (filedata->file_header.e_type));
5421 else
5422 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
dda8d76d 5423 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5424 printf (ngettext ("There is %d program header, starting at offset %s\n",
5425 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5426 filedata->file_header.e_phnum),
5427 filedata->file_header.e_phnum,
5428 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5429 }
5430
dda8d76d 5431 if (! get_program_headers (filedata))
015dc7e1 5432 return true;
103f02d3 5433
252b5132
RH
5434 if (do_segments)
5435 {
dda8d76d 5436 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5437 printf (_("\nProgram Headers:\n"));
5438 else
5439 printf (_("\nProgram Headers:\n"));
76da6bbe 5440
f7a99963
NC
5441 if (is_32bit_elf)
5442 printf
5443 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5444 else if (do_wide)
5445 printf
5446 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5447 else
5448 {
5449 printf
5450 (_(" Type Offset VirtAddr PhysAddr\n"));
5451 printf
5452 (_(" FileSiz MemSiz Flags Align\n"));
5453 }
252b5132
RH
5454 }
5455
dda8d76d
NC
5456 for (i = 0, segment = filedata->program_headers;
5457 i < filedata->file_header.e_phnum;
b34976b6 5458 i++, segment++)
252b5132
RH
5459 {
5460 if (do_segments)
5461 {
dda8d76d 5462 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5463
5464 if (is_32bit_elf)
5465 {
5466 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5467 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5468 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5469 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5470 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5471 printf ("%c%c%c ",
5472 (segment->p_flags & PF_R ? 'R' : ' '),
5473 (segment->p_flags & PF_W ? 'W' : ' '),
5474 (segment->p_flags & PF_X ? 'E' : ' '));
5475 printf ("%#lx", (unsigned long) segment->p_align);
5476 }
d974e256
JJ
5477 else if (do_wide)
5478 {
5479 if ((unsigned long) segment->p_offset == segment->p_offset)
5480 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5481 else
5482 {
5483 print_vma (segment->p_offset, FULL_HEX);
5484 putchar (' ');
5485 }
5486
5487 print_vma (segment->p_vaddr, FULL_HEX);
5488 putchar (' ');
5489 print_vma (segment->p_paddr, FULL_HEX);
5490 putchar (' ');
5491
5492 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5493 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5494 else
5495 {
5496 print_vma (segment->p_filesz, FULL_HEX);
5497 putchar (' ');
5498 }
5499
5500 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5501 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5502 else
5503 {
f48e6c45 5504 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5505 }
5506
5507 printf (" %c%c%c ",
5508 (segment->p_flags & PF_R ? 'R' : ' '),
5509 (segment->p_flags & PF_W ? 'W' : ' '),
5510 (segment->p_flags & PF_X ? 'E' : ' '));
5511
5512 if ((unsigned long) segment->p_align == segment->p_align)
5513 printf ("%#lx", (unsigned long) segment->p_align);
5514 else
5515 {
5516 print_vma (segment->p_align, PREFIX_HEX);
5517 }
5518 }
f7a99963
NC
5519 else
5520 {
5521 print_vma (segment->p_offset, FULL_HEX);
5522 putchar (' ');
5523 print_vma (segment->p_vaddr, FULL_HEX);
5524 putchar (' ');
5525 print_vma (segment->p_paddr, FULL_HEX);
5526 printf ("\n ");
5527 print_vma (segment->p_filesz, FULL_HEX);
5528 putchar (' ');
5529 print_vma (segment->p_memsz, FULL_HEX);
5530 printf (" %c%c%c ",
5531 (segment->p_flags & PF_R ? 'R' : ' '),
5532 (segment->p_flags & PF_W ? 'W' : ' '),
5533 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5534 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5535 }
252b5132 5536
1a9ccd70
NC
5537 putc ('\n', stdout);
5538 }
f54498b4 5539
252b5132
RH
5540 switch (segment->p_type)
5541 {
1a9ccd70 5542 case PT_LOAD:
502d895c
NC
5543#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5544 required by the ELF standard, several programs, including the Linux
5545 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5546 if (previous_load
5547 && previous_load->p_vaddr > segment->p_vaddr)
5548 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5549#endif
1a9ccd70
NC
5550 if (segment->p_memsz < segment->p_filesz)
5551 error (_("the segment's file size is larger than its memory size\n"));
5552 previous_load = segment;
5553 break;
5554
5555 case PT_PHDR:
5556 /* PR 20815 - Verify that the program header is loaded into memory. */
5557 if (i > 0 && previous_load != NULL)
5558 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5559 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5560 {
5561 unsigned int j;
5562
dda8d76d 5563 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5564 {
5565 Elf_Internal_Phdr *load = filedata->program_headers + j;
5566 if (load->p_type == PT_LOAD
5567 && load->p_offset <= segment->p_offset
5568 && (load->p_offset + load->p_filesz
5569 >= segment->p_offset + segment->p_filesz)
5570 && load->p_vaddr <= segment->p_vaddr
5571 && (load->p_vaddr + load->p_filesz
5572 >= segment->p_vaddr + segment->p_filesz))
5573 break;
5574 }
dda8d76d 5575 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5576 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5577 }
5578 break;
5579
252b5132 5580 case PT_DYNAMIC:
978c4450 5581 if (filedata->dynamic_addr)
252b5132
RH
5582 error (_("more than one dynamic segment\n"));
5583
20737c13
AM
5584 /* By default, assume that the .dynamic section is the first
5585 section in the DYNAMIC segment. */
978c4450
AM
5586 filedata->dynamic_addr = segment->p_offset;
5587 filedata->dynamic_size = segment->p_filesz;
20737c13 5588
b2d38a17
NC
5589 /* Try to locate the .dynamic section. If there is
5590 a section header table, we can easily locate it. */
dda8d76d 5591 if (filedata->section_headers != NULL)
b2d38a17 5592 {
2cf0635d 5593 Elf_Internal_Shdr * sec;
b2d38a17 5594
dda8d76d 5595 sec = find_section (filedata, ".dynamic");
89fac5e3 5596 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5597 {
28f997cf
TG
5598 /* A corresponding .dynamic section is expected, but on
5599 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5600 if (!is_ia64_vms (filedata))
28f997cf 5601 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5602 break;
5603 }
5604
42bb2e33 5605 if (sec->sh_type == SHT_NOBITS)
20737c13 5606 {
978c4450 5607 filedata->dynamic_size = 0;
20737c13
AM
5608 break;
5609 }
42bb2e33 5610
978c4450
AM
5611 filedata->dynamic_addr = sec->sh_offset;
5612 filedata->dynamic_size = sec->sh_size;
b2d38a17 5613
8ac10c5b
L
5614 /* The PT_DYNAMIC segment, which is used by the run-time
5615 loader, should exactly match the .dynamic section. */
5616 if (do_checks
5617 && (filedata->dynamic_addr != segment->p_offset
5618 || filedata->dynamic_size != segment->p_filesz))
5619 warn (_("\
5620the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 5621 }
39e224f6
MW
5622
5623 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5624 segment. Check this after matching against the section headers
5625 so we don't warn on debuginfo file (which have NOBITS .dynamic
5626 sections). */
978c4450
AM
5627 if (filedata->dynamic_addr > filedata->file_size
5628 || (filedata->dynamic_size
5629 > filedata->file_size - filedata->dynamic_addr))
39e224f6
MW
5630 {
5631 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
978c4450 5632 filedata->dynamic_addr = filedata->dynamic_size = 0;
39e224f6 5633 }
252b5132
RH
5634 break;
5635
5636 case PT_INTERP:
13acb58d
AM
5637 if (segment->p_offset >= filedata->file_size
5638 || segment->p_filesz > filedata->file_size - segment->p_offset
5639 || segment->p_filesz - 1 >= (size_t) -2
5640 || fseek (filedata->handle,
5641 filedata->archive_file_offset + (long) segment->p_offset,
5642 SEEK_SET))
252b5132
RH
5643 error (_("Unable to find program interpreter name\n"));
5644 else
5645 {
13acb58d
AM
5646 size_t len = segment->p_filesz;
5647 free (filedata->program_interpreter);
5648 filedata->program_interpreter = xmalloc (len + 1);
5649 len = fread (filedata->program_interpreter, 1, len,
5650 filedata->handle);
5651 filedata->program_interpreter[len] = 0;
252b5132
RH
5652
5653 if (do_segments)
f54498b4 5654 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 5655 filedata->program_interpreter);
252b5132
RH
5656 }
5657 break;
5658 }
252b5132
RH
5659 }
5660
dda8d76d
NC
5661 if (do_segments
5662 && filedata->section_headers != NULL
5663 && filedata->string_table != NULL)
252b5132
RH
5664 {
5665 printf (_("\n Section to Segment mapping:\n"));
5666 printf (_(" Segment Sections...\n"));
5667
dda8d76d 5668 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5669 {
9ad5cbcf 5670 unsigned int j;
2cf0635d 5671 Elf_Internal_Shdr * section;
252b5132 5672
dda8d76d
NC
5673 segment = filedata->program_headers + i;
5674 section = filedata->section_headers + 1;
252b5132
RH
5675
5676 printf (" %2.2d ", i);
5677
dda8d76d 5678 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5679 {
f4638467
AM
5680 if (!ELF_TBSS_SPECIAL (section, segment)
5681 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5682 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5683 }
5684
5685 putc ('\n',stdout);
5686 }
5687 }
5688
015dc7e1 5689 return true;
252b5132
RH
5690}
5691
5692
d93f0186
NC
5693/* Find the file offset corresponding to VMA by using the program headers. */
5694
5695static long
dda8d76d 5696offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5697{
2cf0635d 5698 Elf_Internal_Phdr * seg;
d93f0186 5699
dda8d76d 5700 if (! get_program_headers (filedata))
d93f0186
NC
5701 {
5702 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5703 return (long) vma;
5704 }
5705
dda8d76d
NC
5706 for (seg = filedata->program_headers;
5707 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5708 ++seg)
5709 {
5710 if (seg->p_type != PT_LOAD)
5711 continue;
5712
5713 if (vma >= (seg->p_vaddr & -seg->p_align)
5714 && vma + size <= seg->p_vaddr + seg->p_filesz)
5715 return vma - seg->p_vaddr + seg->p_offset;
5716 }
5717
5718 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5719 (unsigned long) vma);
d93f0186
NC
5720 return (long) vma;
5721}
5722
5723
dda8d76d
NC
5724/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5725 If PROBE is true, this is just a probe and we do not generate any error
5726 messages if the load fails. */
049b0c3a 5727
015dc7e1
AM
5728static bool
5729get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 5730{
2cf0635d
NC
5731 Elf32_External_Shdr * shdrs;
5732 Elf_Internal_Shdr * internal;
dda8d76d
NC
5733 unsigned int i;
5734 unsigned int size = filedata->file_header.e_shentsize;
5735 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5736
5737 /* PR binutils/17531: Cope with unexpected section header sizes. */
5738 if (size == 0 || num == 0)
015dc7e1 5739 return false;
049b0c3a
NC
5740 if (size < sizeof * shdrs)
5741 {
5742 if (! probe)
5743 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 5744 return false;
049b0c3a
NC
5745 }
5746 if (!probe && size > sizeof * shdrs)
5747 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5748
dda8d76d 5749 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5750 size, num,
5751 probe ? NULL : _("section headers"));
5752 if (shdrs == NULL)
015dc7e1 5753 return false;
252b5132 5754
dda8d76d
NC
5755 filedata->section_headers = (Elf_Internal_Shdr *)
5756 cmalloc (num, sizeof (Elf_Internal_Shdr));
5757 if (filedata->section_headers == NULL)
252b5132 5758 {
049b0c3a 5759 if (!probe)
8b73c356 5760 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5761 free (shdrs);
015dc7e1 5762 return false;
252b5132
RH
5763 }
5764
dda8d76d 5765 for (i = 0, internal = filedata->section_headers;
560f3c1c 5766 i < num;
b34976b6 5767 i++, internal++)
252b5132
RH
5768 {
5769 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5770 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5771 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5772 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5773 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5774 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5775 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5776 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5777 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5778 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5779 if (!probe && internal->sh_link > num)
5780 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5781 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5782 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5783 }
5784
5785 free (shdrs);
015dc7e1 5786 return true;
252b5132
RH
5787}
5788
dda8d76d
NC
5789/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5790
015dc7e1
AM
5791static bool
5792get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 5793{
dda8d76d
NC
5794 Elf64_External_Shdr * shdrs;
5795 Elf_Internal_Shdr * internal;
5796 unsigned int i;
5797 unsigned int size = filedata->file_header.e_shentsize;
5798 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5799
5800 /* PR binutils/17531: Cope with unexpected section header sizes. */
5801 if (size == 0 || num == 0)
015dc7e1 5802 return false;
dda8d76d 5803
049b0c3a
NC
5804 if (size < sizeof * shdrs)
5805 {
5806 if (! probe)
5807 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 5808 return false;
049b0c3a 5809 }
dda8d76d 5810
049b0c3a
NC
5811 if (! probe && size > sizeof * shdrs)
5812 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5813
dda8d76d
NC
5814 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5815 filedata->file_header.e_shoff,
049b0c3a
NC
5816 size, num,
5817 probe ? NULL : _("section headers"));
5818 if (shdrs == NULL)
015dc7e1 5819 return false;
9ea033b2 5820
dda8d76d
NC
5821 filedata->section_headers = (Elf_Internal_Shdr *)
5822 cmalloc (num, sizeof (Elf_Internal_Shdr));
5823 if (filedata->section_headers == NULL)
9ea033b2 5824 {
049b0c3a 5825 if (! probe)
8b73c356 5826 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5827 free (shdrs);
015dc7e1 5828 return false;
9ea033b2
NC
5829 }
5830
dda8d76d 5831 for (i = 0, internal = filedata->section_headers;
560f3c1c 5832 i < num;
b34976b6 5833 i++, internal++)
9ea033b2
NC
5834 {
5835 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5836 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5837 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5838 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5839 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5840 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5841 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5842 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5843 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5844 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5845 if (!probe && internal->sh_link > num)
5846 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5847 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5848 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5849 }
5850
5851 free (shdrs);
015dc7e1 5852 return true;
9ea033b2
NC
5853}
5854
4de91c10
AM
5855static bool
5856get_section_headers (Filedata *filedata, bool probe)
5857{
5858 if (filedata->section_headers != NULL)
5859 return true;
5860
5861 if (filedata->file_header.e_shoff == 0)
5862 return true;
5863
5864 if (is_32bit_elf)
5865 return get_32bit_section_headers (filedata, probe);
5866 else
5867 return get_64bit_section_headers (filedata, probe);
5868}
5869
252b5132 5870static Elf_Internal_Sym *
dda8d76d
NC
5871get_32bit_elf_symbols (Filedata * filedata,
5872 Elf_Internal_Shdr * section,
5873 unsigned long * num_syms_return)
252b5132 5874{
ba5cdace 5875 unsigned long number = 0;
dd24e3da 5876 Elf32_External_Sym * esyms = NULL;
ba5cdace 5877 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5878 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5879 Elf_Internal_Sym * psym;
b34976b6 5880 unsigned int j;
e3d39609 5881 elf_section_list * entry;
252b5132 5882
c9c1d674
EG
5883 if (section->sh_size == 0)
5884 {
5885 if (num_syms_return != NULL)
5886 * num_syms_return = 0;
5887 return NULL;
5888 }
5889
dd24e3da 5890 /* Run some sanity checks first. */
c9c1d674 5891 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5892 {
c9c1d674 5893 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5894 printable_section_name (filedata, section),
5895 (unsigned long) section->sh_entsize);
ba5cdace 5896 goto exit_point;
dd24e3da
NC
5897 }
5898
dda8d76d 5899 if (section->sh_size > filedata->file_size)
f54498b4
NC
5900 {
5901 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5902 printable_section_name (filedata, section),
5903 (unsigned long) section->sh_size);
f54498b4
NC
5904 goto exit_point;
5905 }
5906
dd24e3da
NC
5907 number = section->sh_size / section->sh_entsize;
5908
5909 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5910 {
c9c1d674 5911 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5912 (unsigned long) section->sh_size,
dda8d76d 5913 printable_section_name (filedata, section),
8066deb1 5914 (unsigned long) section->sh_entsize);
ba5cdace 5915 goto exit_point;
dd24e3da
NC
5916 }
5917
dda8d76d 5918 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5919 section->sh_size, _("symbols"));
dd24e3da 5920 if (esyms == NULL)
ba5cdace 5921 goto exit_point;
252b5132 5922
e3d39609 5923 shndx = NULL;
978c4450 5924 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5925 {
5926 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5927 continue;
5928
5929 if (shndx != NULL)
5930 {
5931 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5932 free (shndx);
5933 }
5934
5935 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5936 entry->hdr->sh_offset,
5937 1, entry->hdr->sh_size,
5938 _("symbol table section indices"));
5939 if (shndx == NULL)
5940 goto exit_point;
5941
5942 /* PR17531: file: heap-buffer-overflow */
5943 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5944 {
5945 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5946 printable_section_name (filedata, entry->hdr),
5947 (unsigned long) entry->hdr->sh_size,
5948 (unsigned long) section->sh_size);
5949 goto exit_point;
c9c1d674 5950 }
e3d39609 5951 }
9ad5cbcf 5952
3f5e193b 5953 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5954
5955 if (isyms == NULL)
5956 {
8b73c356
NC
5957 error (_("Out of memory reading %lu symbols\n"),
5958 (unsigned long) number);
dd24e3da 5959 goto exit_point;
252b5132
RH
5960 }
5961
dd24e3da 5962 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5963 {
5964 psym->st_name = BYTE_GET (esyms[j].st_name);
5965 psym->st_value = BYTE_GET (esyms[j].st_value);
5966 psym->st_size = BYTE_GET (esyms[j].st_size);
5967 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5968 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5969 psym->st_shndx
5970 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5971 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5972 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5973 psym->st_info = BYTE_GET (esyms[j].st_info);
5974 psym->st_other = BYTE_GET (esyms[j].st_other);
5975 }
5976
dd24e3da 5977 exit_point:
e3d39609
NC
5978 free (shndx);
5979 free (esyms);
252b5132 5980
ba5cdace
NC
5981 if (num_syms_return != NULL)
5982 * num_syms_return = isyms == NULL ? 0 : number;
5983
252b5132
RH
5984 return isyms;
5985}
5986
9ea033b2 5987static Elf_Internal_Sym *
dda8d76d
NC
5988get_64bit_elf_symbols (Filedata * filedata,
5989 Elf_Internal_Shdr * section,
5990 unsigned long * num_syms_return)
9ea033b2 5991{
ba5cdace
NC
5992 unsigned long number = 0;
5993 Elf64_External_Sym * esyms = NULL;
5994 Elf_External_Sym_Shndx * shndx = NULL;
5995 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5996 Elf_Internal_Sym * psym;
b34976b6 5997 unsigned int j;
e3d39609 5998 elf_section_list * entry;
9ea033b2 5999
c9c1d674
EG
6000 if (section->sh_size == 0)
6001 {
6002 if (num_syms_return != NULL)
6003 * num_syms_return = 0;
6004 return NULL;
6005 }
6006
dd24e3da 6007 /* Run some sanity checks first. */
c9c1d674 6008 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6009 {
c9c1d674 6010 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 6011 printable_section_name (filedata, section),
8066deb1 6012 (unsigned long) section->sh_entsize);
ba5cdace 6013 goto exit_point;
dd24e3da
NC
6014 }
6015
dda8d76d 6016 if (section->sh_size > filedata->file_size)
f54498b4
NC
6017 {
6018 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 6019 printable_section_name (filedata, section),
8066deb1 6020 (unsigned long) section->sh_size);
f54498b4
NC
6021 goto exit_point;
6022 }
6023
dd24e3da
NC
6024 number = section->sh_size / section->sh_entsize;
6025
6026 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6027 {
c9c1d674 6028 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6029 (unsigned long) section->sh_size,
dda8d76d 6030 printable_section_name (filedata, section),
8066deb1 6031 (unsigned long) section->sh_entsize);
ba5cdace 6032 goto exit_point;
dd24e3da
NC
6033 }
6034
dda8d76d 6035 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6036 section->sh_size, _("symbols"));
a6e9f9df 6037 if (!esyms)
ba5cdace 6038 goto exit_point;
9ea033b2 6039
e3d39609 6040 shndx = NULL;
978c4450 6041 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6042 {
6043 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6044 continue;
6045
6046 if (shndx != NULL)
6047 {
6048 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6049 free (shndx);
c9c1d674 6050 }
e3d39609
NC
6051
6052 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6053 entry->hdr->sh_offset,
6054 1, entry->hdr->sh_size,
6055 _("symbol table section indices"));
6056 if (shndx == NULL)
6057 goto exit_point;
6058
6059 /* PR17531: file: heap-buffer-overflow */
6060 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6061 {
6062 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6063 printable_section_name (filedata, entry->hdr),
6064 (unsigned long) entry->hdr->sh_size,
6065 (unsigned long) section->sh_size);
6066 goto exit_point;
6067 }
6068 }
9ad5cbcf 6069
3f5e193b 6070 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6071
6072 if (isyms == NULL)
6073 {
8b73c356
NC
6074 error (_("Out of memory reading %lu symbols\n"),
6075 (unsigned long) number);
ba5cdace 6076 goto exit_point;
9ea033b2
NC
6077 }
6078
ba5cdace 6079 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6080 {
6081 psym->st_name = BYTE_GET (esyms[j].st_name);
6082 psym->st_info = BYTE_GET (esyms[j].st_info);
6083 psym->st_other = BYTE_GET (esyms[j].st_other);
6084 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6085
4fbb74a6 6086 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6087 psym->st_shndx
6088 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6089 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6090 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6091
66543521
AM
6092 psym->st_value = BYTE_GET (esyms[j].st_value);
6093 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6094 }
6095
ba5cdace 6096 exit_point:
e3d39609
NC
6097 free (shndx);
6098 free (esyms);
ba5cdace
NC
6099
6100 if (num_syms_return != NULL)
6101 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6102
6103 return isyms;
6104}
6105
4de91c10
AM
6106static Elf_Internal_Sym *
6107get_elf_symbols (Filedata *filedata,
6108 Elf_Internal_Shdr *section,
6109 unsigned long *num_syms_return)
6110{
6111 if (is_32bit_elf)
6112 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6113 else
6114 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6115}
6116
d1133906 6117static const char *
dda8d76d 6118get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 6119{
5477e8a0 6120 static char buff[1024];
2cf0635d 6121 char * p = buff;
32ec8896
NC
6122 unsigned int field_size = is_32bit_elf ? 8 : 16;
6123 signed int sindex;
6124 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
6125 bfd_vma os_flags = 0;
6126 bfd_vma proc_flags = 0;
6127 bfd_vma unknown_flags = 0;
148b93f2 6128 static const struct
5477e8a0 6129 {
2cf0635d 6130 const char * str;
32ec8896 6131 unsigned int len;
5477e8a0
L
6132 }
6133 flags [] =
6134 {
cfcac11d
NC
6135 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6136 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6137 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6138 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6139 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6140 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6141 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6142 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6143 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6144 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6145 /* IA-64 specific. */
6146 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6147 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6148 /* IA-64 OpenVMS specific. */
6149 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6150 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6151 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6152 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6153 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6154 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6155 /* Generic. */
cfcac11d 6156 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6157 /* SPARC specific. */
77115a4a 6158 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6159 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6160 /* ARM specific. */
6161 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6162 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6163 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6164 /* GNU specific. */
6165 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6166 /* VLE specific. */
6167 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6168 /* GNU specific. */
6169 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6170 };
6171
6172 if (do_section_details)
6173 {
8d5ff12c
L
6174 sprintf (buff, "[%*.*lx]: ",
6175 field_size, field_size, (unsigned long) sh_flags);
6176 p += field_size + 4;
5477e8a0 6177 }
76da6bbe 6178
d1133906
NC
6179 while (sh_flags)
6180 {
6181 bfd_vma flag;
6182
6183 flag = sh_flags & - sh_flags;
6184 sh_flags &= ~ flag;
76da6bbe 6185
5477e8a0 6186 if (do_section_details)
d1133906 6187 {
5477e8a0
L
6188 switch (flag)
6189 {
91d6fa6a
NC
6190 case SHF_WRITE: sindex = 0; break;
6191 case SHF_ALLOC: sindex = 1; break;
6192 case SHF_EXECINSTR: sindex = 2; break;
6193 case SHF_MERGE: sindex = 3; break;
6194 case SHF_STRINGS: sindex = 4; break;
6195 case SHF_INFO_LINK: sindex = 5; break;
6196 case SHF_LINK_ORDER: sindex = 6; break;
6197 case SHF_OS_NONCONFORMING: sindex = 7; break;
6198 case SHF_GROUP: sindex = 8; break;
6199 case SHF_TLS: sindex = 9; break;
18ae9cc1 6200 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6201 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6202
5477e8a0 6203 default:
91d6fa6a 6204 sindex = -1;
dda8d76d 6205 switch (filedata->file_header.e_machine)
148b93f2 6206 {
cfcac11d 6207 case EM_IA_64:
148b93f2 6208 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6209 sindex = 10;
148b93f2 6210 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6211 sindex = 11;
148b93f2 6212#ifdef BFD64
dda8d76d 6213 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6214 switch (flag)
6215 {
91d6fa6a
NC
6216 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6217 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6218 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6219 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6220 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6221 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6222 default: break;
6223 }
6224#endif
cfcac11d
NC
6225 break;
6226
caa83f8b 6227 case EM_386:
22abe556 6228 case EM_IAMCU:
caa83f8b 6229 case EM_X86_64:
7f502d6c 6230 case EM_L1OM:
7a9068fe 6231 case EM_K1OM:
cfcac11d
NC
6232 case EM_OLD_SPARCV9:
6233 case EM_SPARC32PLUS:
6234 case EM_SPARCV9:
6235 case EM_SPARC:
18ae9cc1 6236 if (flag == SHF_ORDERED)
91d6fa6a 6237 sindex = 19;
cfcac11d 6238 break;
ac4c9b04
MG
6239
6240 case EM_ARM:
6241 switch (flag)
6242 {
6243 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6244 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6245 case SHF_COMDEF: sindex = 23; break;
6246 default: break;
6247 }
6248 break;
83eef883
AFB
6249 case EM_PPC:
6250 if (flag == SHF_PPC_VLE)
6251 sindex = 25;
6252 break;
99fabbc9
JL
6253 default:
6254 break;
6255 }
ac4c9b04 6256
99fabbc9
JL
6257 switch (filedata->file_header.e_ident[EI_OSABI])
6258 {
6259 case ELFOSABI_GNU:
6260 case ELFOSABI_FREEBSD:
6261 if (flag == SHF_GNU_RETAIN)
6262 sindex = 26;
6263 /* Fall through */
6264 case ELFOSABI_NONE:
6265 if (flag == SHF_GNU_MBIND)
6266 /* We should not recognize SHF_GNU_MBIND for
6267 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6268 not set the EI_OSABI header byte. */
6269 sindex = 24;
6270 break;
cfcac11d
NC
6271 default:
6272 break;
148b93f2 6273 }
99fabbc9 6274 break;
5477e8a0
L
6275 }
6276
91d6fa6a 6277 if (sindex != -1)
5477e8a0 6278 {
8d5ff12c
L
6279 if (p != buff + field_size + 4)
6280 {
6281 if (size < (10 + 2))
bee0ee85
NC
6282 {
6283 warn (_("Internal error: not enough buffer room for section flag info"));
6284 return _("<unknown>");
6285 }
8d5ff12c
L
6286 size -= 2;
6287 *p++ = ',';
6288 *p++ = ' ';
6289 }
6290
91d6fa6a
NC
6291 size -= flags [sindex].len;
6292 p = stpcpy (p, flags [sindex].str);
5477e8a0 6293 }
3b22753a 6294 else if (flag & SHF_MASKOS)
8d5ff12c 6295 os_flags |= flag;
d1133906 6296 else if (flag & SHF_MASKPROC)
8d5ff12c 6297 proc_flags |= flag;
d1133906 6298 else
8d5ff12c 6299 unknown_flags |= flag;
5477e8a0
L
6300 }
6301 else
6302 {
6303 switch (flag)
6304 {
6305 case SHF_WRITE: *p = 'W'; break;
6306 case SHF_ALLOC: *p = 'A'; break;
6307 case SHF_EXECINSTR: *p = 'X'; break;
6308 case SHF_MERGE: *p = 'M'; break;
6309 case SHF_STRINGS: *p = 'S'; break;
6310 case SHF_INFO_LINK: *p = 'I'; break;
6311 case SHF_LINK_ORDER: *p = 'L'; break;
6312 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6313 case SHF_GROUP: *p = 'G'; break;
6314 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6315 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6316 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6317
6318 default:
dda8d76d
NC
6319 if ((filedata->file_header.e_machine == EM_X86_64
6320 || filedata->file_header.e_machine == EM_L1OM
6321 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6322 && flag == SHF_X86_64_LARGE)
6323 *p = 'l';
dda8d76d 6324 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6325 && flag == SHF_ARM_PURECODE)
99fabbc9 6326 *p = 'y';
dda8d76d 6327 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6328 && flag == SHF_PPC_VLE)
99fabbc9 6329 *p = 'v';
5477e8a0
L
6330 else if (flag & SHF_MASKOS)
6331 {
99fabbc9
JL
6332 switch (filedata->file_header.e_ident[EI_OSABI])
6333 {
6334 case ELFOSABI_GNU:
6335 case ELFOSABI_FREEBSD:
6336 if (flag == SHF_GNU_RETAIN)
6337 {
6338 *p = 'R';
6339 break;
6340 }
6341 /* Fall through */
6342 case ELFOSABI_NONE:
6343 if (flag == SHF_GNU_MBIND)
6344 {
6345 /* We should not recognize SHF_GNU_MBIND for
6346 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6347 not set the EI_OSABI header byte. */
6348 *p = 'D';
6349 break;
6350 }
6351 /* Fall through */
6352 default:
6353 *p = 'o';
6354 sh_flags &= ~SHF_MASKOS;
6355 break;
6356 }
5477e8a0
L
6357 }
6358 else if (flag & SHF_MASKPROC)
6359 {
6360 *p = 'p';
6361 sh_flags &= ~ SHF_MASKPROC;
6362 }
6363 else
6364 *p = 'x';
6365 break;
6366 }
6367 p++;
d1133906
NC
6368 }
6369 }
76da6bbe 6370
8d5ff12c
L
6371 if (do_section_details)
6372 {
6373 if (os_flags)
6374 {
6375 size -= 5 + field_size;
6376 if (p != buff + field_size + 4)
6377 {
6378 if (size < (2 + 1))
bee0ee85
NC
6379 {
6380 warn (_("Internal error: not enough buffer room for section flag info"));
6381 return _("<unknown>");
6382 }
8d5ff12c
L
6383 size -= 2;
6384 *p++ = ',';
6385 *p++ = ' ';
6386 }
6387 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6388 (unsigned long) os_flags);
6389 p += 5 + field_size;
6390 }
6391 if (proc_flags)
6392 {
6393 size -= 7 + field_size;
6394 if (p != buff + field_size + 4)
6395 {
6396 if (size < (2 + 1))
bee0ee85
NC
6397 {
6398 warn (_("Internal error: not enough buffer room for section flag info"));
6399 return _("<unknown>");
6400 }
8d5ff12c
L
6401 size -= 2;
6402 *p++ = ',';
6403 *p++ = ' ';
6404 }
6405 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6406 (unsigned long) proc_flags);
6407 p += 7 + field_size;
6408 }
6409 if (unknown_flags)
6410 {
6411 size -= 10 + field_size;
6412 if (p != buff + field_size + 4)
6413 {
6414 if (size < (2 + 1))
bee0ee85
NC
6415 {
6416 warn (_("Internal error: not enough buffer room for section flag info"));
6417 return _("<unknown>");
6418 }
8d5ff12c
L
6419 size -= 2;
6420 *p++ = ',';
6421 *p++ = ' ';
6422 }
2b692964 6423 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6424 (unsigned long) unknown_flags);
6425 p += 10 + field_size;
6426 }
6427 }
6428
e9e44622 6429 *p = '\0';
d1133906
NC
6430 return buff;
6431}
6432
5844b465 6433static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6434get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6435{
6436 if (is_32bit_elf)
6437 {
6438 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6439
ebdf1ebf
NC
6440 if (size < sizeof (* echdr))
6441 {
6442 error (_("Compressed section is too small even for a compression header\n"));
6443 return 0;
6444 }
6445
77115a4a
L
6446 chdr->ch_type = BYTE_GET (echdr->ch_type);
6447 chdr->ch_size = BYTE_GET (echdr->ch_size);
6448 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6449 return sizeof (*echdr);
6450 }
6451 else
6452 {
6453 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6454
ebdf1ebf
NC
6455 if (size < sizeof (* echdr))
6456 {
6457 error (_("Compressed section is too small even for a compression header\n"));
6458 return 0;
6459 }
6460
77115a4a
L
6461 chdr->ch_type = BYTE_GET (echdr->ch_type);
6462 chdr->ch_size = BYTE_GET (echdr->ch_size);
6463 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6464 return sizeof (*echdr);
6465 }
6466}
6467
015dc7e1 6468static bool
dda8d76d 6469process_section_headers (Filedata * filedata)
252b5132 6470{
2cf0635d 6471 Elf_Internal_Shdr * section;
b34976b6 6472 unsigned int i;
252b5132 6473
dda8d76d 6474 if (filedata->file_header.e_shnum == 0)
252b5132 6475 {
82f2dbf7 6476 /* PR binutils/12467. */
dda8d76d 6477 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6478 {
6479 warn (_("possibly corrupt ELF file header - it has a non-zero"
6480 " section header offset, but no section headers\n"));
015dc7e1 6481 return false;
32ec8896 6482 }
82f2dbf7 6483 else if (do_sections)
252b5132
RH
6484 printf (_("\nThere are no sections in this file.\n"));
6485
015dc7e1 6486 return true;
252b5132
RH
6487 }
6488
6489 if (do_sections && !do_header)
ca0e11aa
NC
6490 {
6491 if (filedata->is_separate && process_links)
6492 printf (_("In linked file '%s': "), filedata->file_name);
6493 if (! filedata->is_separate || process_links)
6494 printf (ngettext ("There is %d section header, "
6495 "starting at offset 0x%lx:\n",
6496 "There are %d section headers, "
6497 "starting at offset 0x%lx:\n",
6498 filedata->file_header.e_shnum),
6499 filedata->file_header.e_shnum,
6500 (unsigned long) filedata->file_header.e_shoff);
6501 }
252b5132 6502
4de91c10
AM
6503 if (!get_section_headers (filedata, false))
6504 return false;
252b5132
RH
6505
6506 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6507 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6508 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6509 {
dda8d76d 6510 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6511
c256ffe7
JJ
6512 if (section->sh_size != 0)
6513 {
dda8d76d
NC
6514 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6515 1, section->sh_size,
6516 _("string table"));
0de14b54 6517
dda8d76d 6518 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6519 }
252b5132
RH
6520 }
6521
6522 /* Scan the sections for the dynamic symbol table
e3c8793a 6523 and dynamic string table and debug sections. */
89fac5e3 6524 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6525 switch (filedata->file_header.e_machine)
89fac5e3
RS
6526 {
6527 case EM_MIPS:
6528 case EM_MIPS_RS3_LE:
6529 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6530 FDE addresses. However, the ABI also has a semi-official ILP32
6531 variant for which the normal FDE address size rules apply.
6532
6533 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6534 section, where XX is the size of longs in bits. Unfortunately,
6535 earlier compilers provided no way of distinguishing ILP32 objects
6536 from LP64 objects, so if there's any doubt, we should assume that
6537 the official LP64 form is being used. */
dda8d76d
NC
6538 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6539 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6540 eh_addr_size = 8;
6541 break;
0f56a26a
DD
6542
6543 case EM_H8_300:
6544 case EM_H8_300H:
dda8d76d 6545 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6546 {
6547 case E_H8_MACH_H8300:
6548 case E_H8_MACH_H8300HN:
6549 case E_H8_MACH_H8300SN:
6550 case E_H8_MACH_H8300SXN:
6551 eh_addr_size = 2;
6552 break;
6553 case E_H8_MACH_H8300H:
6554 case E_H8_MACH_H8300S:
6555 case E_H8_MACH_H8300SX:
6556 eh_addr_size = 4;
6557 break;
6558 }
f4236fe4
DD
6559 break;
6560
ff7eeb89 6561 case EM_M32C_OLD:
f4236fe4 6562 case EM_M32C:
dda8d76d 6563 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6564 {
6565 case EF_M32C_CPU_M16C:
6566 eh_addr_size = 2;
6567 break;
6568 }
6569 break;
89fac5e3
RS
6570 }
6571
76ca31c0
NC
6572#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6573 do \
6574 { \
6575 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6576 if (section->sh_entsize != expected_entsize) \
9dd3a467 6577 { \
76ca31c0
NC
6578 char buf[40]; \
6579 sprintf_vma (buf, section->sh_entsize); \
6580 /* Note: coded this way so that there is a single string for \
6581 translation. */ \
6582 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6583 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6584 (unsigned) expected_entsize); \
9dd3a467 6585 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6586 } \
6587 } \
08d8fa11 6588 while (0)
9dd3a467
NC
6589
6590#define CHECK_ENTSIZE(section, i, type) \
1b513401 6591 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
6592 sizeof (Elf64_External_##type))
6593
dda8d76d
NC
6594 for (i = 0, section = filedata->section_headers;
6595 i < filedata->file_header.e_shnum;
b34976b6 6596 i++, section++)
252b5132 6597 {
b9e920ec 6598 char * name = SECTION_NAME_PRINT (section);
252b5132 6599
1b513401
NC
6600 /* Run some sanity checks on the headers and
6601 possibly fill in some file data as well. */
6602 switch (section->sh_type)
252b5132 6603 {
1b513401 6604 case SHT_DYNSYM:
978c4450 6605 if (filedata->dynamic_symbols != NULL)
252b5132
RH
6606 {
6607 error (_("File contains multiple dynamic symbol tables\n"));
6608 continue;
6609 }
6610
08d8fa11 6611 CHECK_ENTSIZE (section, i, Sym);
978c4450 6612 filedata->dynamic_symbols
4de91c10 6613 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 6614 filedata->dynamic_symtab_section = section;
1b513401
NC
6615 break;
6616
6617 case SHT_STRTAB:
6618 if (streq (name, ".dynstr"))
252b5132 6619 {
1b513401
NC
6620 if (filedata->dynamic_strings != NULL)
6621 {
6622 error (_("File contains multiple dynamic string tables\n"));
6623 continue;
6624 }
6625
6626 filedata->dynamic_strings
6627 = (char *) get_data (NULL, filedata, section->sh_offset,
6628 1, section->sh_size, _("dynamic strings"));
6629 filedata->dynamic_strings_length
6630 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 6631 filedata->dynamic_strtab_section = section;
252b5132 6632 }
1b513401
NC
6633 break;
6634
6635 case SHT_SYMTAB_SHNDX:
6636 {
6637 elf_section_list * entry = xmalloc (sizeof * entry);
6638
6639 entry->hdr = section;
6640 entry->next = filedata->symtab_shndx_list;
6641 filedata->symtab_shndx_list = entry;
6642 }
6643 break;
6644
6645 case SHT_SYMTAB:
6646 CHECK_ENTSIZE (section, i, Sym);
6647 break;
6648
6649 case SHT_GROUP:
6650 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6651 break;
252b5132 6652
1b513401
NC
6653 case SHT_REL:
6654 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 6655 if (do_checks && section->sh_size == 0)
1b513401
NC
6656 warn (_("Section '%s': zero-sized relocation section\n"), name);
6657 break;
6658
6659 case SHT_RELA:
6660 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 6661 if (do_checks && section->sh_size == 0)
1b513401
NC
6662 warn (_("Section '%s': zero-sized relocation section\n"), name);
6663 break;
6664
6665 case SHT_NOTE:
6666 case SHT_PROGBITS:
546cb2d8
NC
6667 /* Having a zero sized section is not illegal according to the
6668 ELF standard, but it might be an indication that something
6669 is wrong. So issue a warning if we are running in lint mode. */
6670 if (do_checks && section->sh_size == 0)
1b513401
NC
6671 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
6672 break;
6673
6674 default:
6675 break;
6676 }
6677
6678 if ((do_debugging || do_debug_info || do_debug_abbrevs
6679 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
6680 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
6681 || do_debug_str || do_debug_str_offsets || do_debug_loc
6682 || do_debug_ranges
1b513401 6683 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
6684 && (startswith (name, ".debug_")
6685 || startswith (name, ".zdebug_")))
252b5132 6686 {
1b315056
CS
6687 if (name[1] == 'z')
6688 name += sizeof (".zdebug_") - 1;
6689 else
6690 name += sizeof (".debug_") - 1;
252b5132
RH
6691
6692 if (do_debugging
24d127aa
ML
6693 || (do_debug_info && startswith (name, "info"))
6694 || (do_debug_info && startswith (name, "types"))
6695 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 6696 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
6697 || (do_debug_lines && startswith (name, "line."))
6698 || (do_debug_pubnames && startswith (name, "pubnames"))
6699 || (do_debug_pubtypes && startswith (name, "pubtypes"))
6700 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
6701 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
6702 || (do_debug_aranges && startswith (name, "aranges"))
6703 || (do_debug_ranges && startswith (name, "ranges"))
6704 || (do_debug_ranges && startswith (name, "rnglists"))
6705 || (do_debug_frames && startswith (name, "frame"))
6706 || (do_debug_macinfo && startswith (name, "macinfo"))
6707 || (do_debug_macinfo && startswith (name, "macro"))
6708 || (do_debug_str && startswith (name, "str"))
6709 || (do_debug_links && startswith (name, "sup"))
6710 || (do_debug_str_offsets && startswith (name, "str_offsets"))
6711 || (do_debug_loc && startswith (name, "loc"))
6712 || (do_debug_loc && startswith (name, "loclists"))
6713 || (do_debug_addr && startswith (name, "addr"))
6714 || (do_debug_cu_index && startswith (name, "cu_index"))
6715 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 6716 )
6431e409 6717 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6718 }
a262ae96 6719 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6720 else if ((do_debugging || do_debug_info)
24d127aa 6721 && startswith (name, ".gnu.linkonce.wi."))
6431e409 6722 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6723 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6724 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6725 else if (do_gdb_index && (streq (name, ".gdb_index")
6726 || streq (name, ".debug_names")))
6431e409 6727 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6728 /* Trace sections for Itanium VMS. */
6729 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6730 || do_trace_aranges)
24d127aa 6731 && startswith (name, ".trace_"))
6f875884
TG
6732 {
6733 name += sizeof (".trace_") - 1;
6734
6735 if (do_debugging
6736 || (do_trace_info && streq (name, "info"))
6737 || (do_trace_abbrevs && streq (name, "abbrev"))
6738 || (do_trace_aranges && streq (name, "aranges"))
6739 )
6431e409 6740 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6741 }
dda8d76d 6742 else if ((do_debugging || do_debug_links)
24d127aa
ML
6743 && (startswith (name, ".gnu_debuglink")
6744 || startswith (name, ".gnu_debugaltlink")))
6431e409 6745 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6746 }
6747
6748 if (! do_sections)
015dc7e1 6749 return true;
252b5132 6750
ca0e11aa 6751 if (filedata->is_separate && ! process_links)
015dc7e1 6752 return true;
ca0e11aa
NC
6753
6754 if (filedata->is_separate)
6755 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
6756 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6757 printf (_("\nSection Headers:\n"));
6758 else
6759 printf (_("\nSection Header:\n"));
76da6bbe 6760
f7a99963 6761 if (is_32bit_elf)
595cf52e 6762 {
5477e8a0 6763 if (do_section_details)
595cf52e
L
6764 {
6765 printf (_(" [Nr] Name\n"));
5477e8a0 6766 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6767 }
6768 else
6769 printf
6770 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6771 }
d974e256 6772 else if (do_wide)
595cf52e 6773 {
5477e8a0 6774 if (do_section_details)
595cf52e
L
6775 {
6776 printf (_(" [Nr] Name\n"));
5477e8a0 6777 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6778 }
6779 else
6780 printf
6781 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6782 }
f7a99963
NC
6783 else
6784 {
5477e8a0 6785 if (do_section_details)
595cf52e
L
6786 {
6787 printf (_(" [Nr] Name\n"));
5477e8a0
L
6788 printf (_(" Type Address Offset Link\n"));
6789 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6790 }
6791 else
6792 {
6793 printf (_(" [Nr] Name Type Address Offset\n"));
6794 printf (_(" Size EntSize Flags Link Info Align\n"));
6795 }
f7a99963 6796 }
252b5132 6797
5477e8a0
L
6798 if (do_section_details)
6799 printf (_(" Flags\n"));
6800
dda8d76d
NC
6801 for (i = 0, section = filedata->section_headers;
6802 i < filedata->file_header.e_shnum;
b34976b6 6803 i++, section++)
252b5132 6804 {
dd905818
NC
6805 /* Run some sanity checks on the section header. */
6806
6807 /* Check the sh_link field. */
6808 switch (section->sh_type)
6809 {
285e3f99
AM
6810 case SHT_REL:
6811 case SHT_RELA:
6812 if (section->sh_link == 0
6813 && (filedata->file_header.e_type == ET_EXEC
6814 || filedata->file_header.e_type == ET_DYN))
6815 /* A dynamic relocation section where all entries use a
6816 zero symbol index need not specify a symtab section. */
6817 break;
6818 /* Fall through. */
dd905818
NC
6819 case SHT_SYMTAB_SHNDX:
6820 case SHT_GROUP:
6821 case SHT_HASH:
6822 case SHT_GNU_HASH:
6823 case SHT_GNU_versym:
285e3f99 6824 if (section->sh_link == 0
dda8d76d
NC
6825 || section->sh_link >= filedata->file_header.e_shnum
6826 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6827 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6828 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6829 i, section->sh_link);
6830 break;
6831
6832 case SHT_DYNAMIC:
6833 case SHT_SYMTAB:
6834 case SHT_DYNSYM:
6835 case SHT_GNU_verneed:
6836 case SHT_GNU_verdef:
6837 case SHT_GNU_LIBLIST:
285e3f99 6838 if (section->sh_link == 0
dda8d76d
NC
6839 || section->sh_link >= filedata->file_header.e_shnum
6840 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6841 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6842 i, section->sh_link);
6843 break;
6844
6845 case SHT_INIT_ARRAY:
6846 case SHT_FINI_ARRAY:
6847 case SHT_PREINIT_ARRAY:
6848 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6849 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6850 i, section->sh_link);
6851 break;
6852
6853 default:
6854 /* FIXME: Add support for target specific section types. */
6855#if 0 /* Currently we do not check other section types as there are too
6856 many special cases. Stab sections for example have a type
6857 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6858 section. */
6859 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6860 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6861 i, section->sh_link);
6862#endif
6863 break;
6864 }
6865
6866 /* Check the sh_info field. */
6867 switch (section->sh_type)
6868 {
6869 case SHT_REL:
6870 case SHT_RELA:
285e3f99
AM
6871 if (section->sh_info == 0
6872 && (filedata->file_header.e_type == ET_EXEC
6873 || filedata->file_header.e_type == ET_DYN))
6874 /* Dynamic relocations apply to segments, so they do not
6875 need to specify the section they relocate. */
6876 break;
6877 if (section->sh_info == 0
dda8d76d
NC
6878 || section->sh_info >= filedata->file_header.e_shnum
6879 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6880 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6881 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6882 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6883 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6884 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6885 /* FIXME: Are other section types valid ? */
dda8d76d 6886 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6887 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6888 i, section->sh_info);
dd905818
NC
6889 break;
6890
6891 case SHT_DYNAMIC:
6892 case SHT_HASH:
6893 case SHT_SYMTAB_SHNDX:
6894 case SHT_INIT_ARRAY:
6895 case SHT_FINI_ARRAY:
6896 case SHT_PREINIT_ARRAY:
6897 if (section->sh_info != 0)
6898 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6899 i, section->sh_info);
6900 break;
6901
6902 case SHT_GROUP:
6903 case SHT_SYMTAB:
6904 case SHT_DYNSYM:
6905 /* A symbol index - we assume that it is valid. */
6906 break;
6907
6908 default:
6909 /* FIXME: Add support for target specific section types. */
6910 if (section->sh_type == SHT_NOBITS)
6911 /* NOBITS section headers with non-zero sh_info fields can be
6912 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6913 information. The stripped sections have their headers
6914 preserved but their types set to SHT_NOBITS. So do not check
6915 this type of section. */
dd905818
NC
6916 ;
6917 else if (section->sh_flags & SHF_INFO_LINK)
6918 {
dda8d76d 6919 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6920 warn (_("[%2u]: Expected link to another section in info field"), i);
6921 }
a91e1603
L
6922 else if (section->sh_type < SHT_LOOS
6923 && (section->sh_flags & SHF_GNU_MBIND) == 0
6924 && section->sh_info != 0)
dd905818
NC
6925 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6926 i, section->sh_info);
6927 break;
6928 }
6929
3e6b6445 6930 /* Check the sh_size field. */
dda8d76d 6931 if (section->sh_size > filedata->file_size
3e6b6445
NC
6932 && section->sh_type != SHT_NOBITS
6933 && section->sh_type != SHT_NULL
6934 && section->sh_type < SHT_LOOS)
6935 warn (_("Size of section %u is larger than the entire file!\n"), i);
6936
7bfd842d 6937 printf (" [%2u] ", i);
5477e8a0 6938 if (do_section_details)
dda8d76d 6939 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6940 else
b9e920ec 6941 print_symbol (-17, SECTION_NAME_PRINT (section));
0b4362b0 6942
ea52a088 6943 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6944 get_section_type_name (filedata, section->sh_type));
0b4362b0 6945
f7a99963
NC
6946 if (is_32bit_elf)
6947 {
cfcac11d
NC
6948 const char * link_too_big = NULL;
6949
f7a99963 6950 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6951
f7a99963
NC
6952 printf ( " %6.6lx %6.6lx %2.2lx",
6953 (unsigned long) section->sh_offset,
6954 (unsigned long) section->sh_size,
6955 (unsigned long) section->sh_entsize);
d1133906 6956
5477e8a0
L
6957 if (do_section_details)
6958 fputs (" ", stdout);
6959 else
dda8d76d 6960 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6961
dda8d76d 6962 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6963 {
6964 link_too_big = "";
6965 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6966 an error but it can have special values in Solaris binaries. */
dda8d76d 6967 switch (filedata->file_header.e_machine)
cfcac11d 6968 {
caa83f8b 6969 case EM_386:
22abe556 6970 case EM_IAMCU:
caa83f8b 6971 case EM_X86_64:
7f502d6c 6972 case EM_L1OM:
7a9068fe 6973 case EM_K1OM:
cfcac11d
NC
6974 case EM_OLD_SPARCV9:
6975 case EM_SPARC32PLUS:
6976 case EM_SPARCV9:
6977 case EM_SPARC:
6978 if (section->sh_link == (SHN_BEFORE & 0xffff))
6979 link_too_big = "BEFORE";
6980 else if (section->sh_link == (SHN_AFTER & 0xffff))
6981 link_too_big = "AFTER";
6982 break;
6983 default:
6984 break;
6985 }
6986 }
6987
6988 if (do_section_details)
6989 {
6990 if (link_too_big != NULL && * link_too_big)
6991 printf ("<%s> ", link_too_big);
6992 else
6993 printf ("%2u ", section->sh_link);
6994 printf ("%3u %2lu\n", section->sh_info,
6995 (unsigned long) section->sh_addralign);
6996 }
6997 else
6998 printf ("%2u %3u %2lu\n",
6999 section->sh_link,
7000 section->sh_info,
7001 (unsigned long) section->sh_addralign);
7002
7003 if (link_too_big && ! * link_too_big)
7004 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7005 i, section->sh_link);
f7a99963 7006 }
d974e256
JJ
7007 else if (do_wide)
7008 {
7009 print_vma (section->sh_addr, LONG_HEX);
7010
7011 if ((long) section->sh_offset == section->sh_offset)
7012 printf (" %6.6lx", (unsigned long) section->sh_offset);
7013 else
7014 {
7015 putchar (' ');
7016 print_vma (section->sh_offset, LONG_HEX);
7017 }
7018
7019 if ((unsigned long) section->sh_size == section->sh_size)
7020 printf (" %6.6lx", (unsigned long) section->sh_size);
7021 else
7022 {
7023 putchar (' ');
7024 print_vma (section->sh_size, LONG_HEX);
7025 }
7026
7027 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7028 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7029 else
7030 {
7031 putchar (' ');
7032 print_vma (section->sh_entsize, LONG_HEX);
7033 }
7034
5477e8a0
L
7035 if (do_section_details)
7036 fputs (" ", stdout);
7037 else
dda8d76d 7038 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7039
72de5009 7040 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7041
7042 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7043 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7044 else
7045 {
7046 print_vma (section->sh_addralign, DEC);
7047 putchar ('\n');
7048 }
7049 }
5477e8a0 7050 else if (do_section_details)
595cf52e 7051 {
55cc53e9 7052 putchar (' ');
595cf52e
L
7053 print_vma (section->sh_addr, LONG_HEX);
7054 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7055 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7056 else
7057 {
7058 printf (" ");
7059 print_vma (section->sh_offset, LONG_HEX);
7060 }
72de5009 7061 printf (" %u\n ", section->sh_link);
595cf52e 7062 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7063 putchar (' ');
595cf52e
L
7064 print_vma (section->sh_entsize, LONG_HEX);
7065
72de5009
AM
7066 printf (" %-16u %lu\n",
7067 section->sh_info,
595cf52e
L
7068 (unsigned long) section->sh_addralign);
7069 }
f7a99963
NC
7070 else
7071 {
7072 putchar (' ');
7073 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7074 if ((long) section->sh_offset == section->sh_offset)
7075 printf (" %8.8lx", (unsigned long) section->sh_offset);
7076 else
7077 {
7078 printf (" ");
7079 print_vma (section->sh_offset, LONG_HEX);
7080 }
f7a99963
NC
7081 printf ("\n ");
7082 print_vma (section->sh_size, LONG_HEX);
7083 printf (" ");
7084 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7085
dda8d76d 7086 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7087
72de5009
AM
7088 printf (" %2u %3u %lu\n",
7089 section->sh_link,
7090 section->sh_info,
f7a99963
NC
7091 (unsigned long) section->sh_addralign);
7092 }
5477e8a0
L
7093
7094 if (do_section_details)
77115a4a 7095 {
dda8d76d 7096 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7097 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7098 {
7099 /* Minimum section size is 12 bytes for 32-bit compression
7100 header + 12 bytes for compressed data header. */
7101 unsigned char buf[24];
d8024a91 7102
77115a4a 7103 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7104 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7105 sizeof (buf), _("compression header")))
7106 {
7107 Elf_Internal_Chdr chdr;
d8024a91 7108
5844b465
NC
7109 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7110 printf (_(" [<corrupt>]\n"));
77115a4a 7111 else
5844b465
NC
7112 {
7113 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7114 printf (" ZLIB, ");
7115 else
7116 printf (_(" [<unknown>: 0x%x], "),
7117 chdr.ch_type);
7118 print_vma (chdr.ch_size, LONG_HEX);
7119 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7120 }
77115a4a
L
7121 }
7122 }
7123 }
252b5132
RH
7124 }
7125
5477e8a0 7126 if (!do_section_details)
3dbcc61d 7127 {
9fb71ee4
NC
7128 /* The ordering of the letters shown here matches the ordering of the
7129 corresponding SHF_xxx values, and hence the order in which these
7130 letters will be displayed to the user. */
7131 printf (_("Key to Flags:\n\
7132 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7133 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7134 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7135 switch (filedata->file_header.e_ident[EI_OSABI])
7136 {
7137 case ELFOSABI_GNU:
7138 case ELFOSABI_FREEBSD:
7139 printf (_("R (retain), "));
7140 /* Fall through */
7141 case ELFOSABI_NONE:
7142 printf (_("D (mbind), "));
7143 break;
7144 default:
7145 break;
7146 }
dda8d76d
NC
7147 if (filedata->file_header.e_machine == EM_X86_64
7148 || filedata->file_header.e_machine == EM_L1OM
7149 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7150 printf (_("l (large), "));
dda8d76d 7151 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7152 printf (_("y (purecode), "));
dda8d76d 7153 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7154 printf (_("v (VLE), "));
9fb71ee4 7155 printf ("p (processor specific)\n");
0b4362b0 7156 }
d1133906 7157
015dc7e1 7158 return true;
252b5132
RH
7159}
7160
015dc7e1 7161static bool
28d13567
AM
7162get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7163 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7164 char **strtab, unsigned long *strtablen)
7165{
7166 *strtab = NULL;
7167 *strtablen = 0;
4de91c10 7168 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7169
7170 if (*symtab == NULL)
015dc7e1 7171 return false;
28d13567
AM
7172
7173 if (symsec->sh_link != 0)
7174 {
7175 Elf_Internal_Shdr *strsec;
7176
7177 if (symsec->sh_link >= filedata->file_header.e_shnum)
7178 {
7179 error (_("Bad sh_link in symbol table section\n"));
7180 free (*symtab);
7181 *symtab = NULL;
7182 *nsyms = 0;
015dc7e1 7183 return false;
28d13567
AM
7184 }
7185
7186 strsec = filedata->section_headers + symsec->sh_link;
7187
7188 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7189 1, strsec->sh_size, _("string table"));
7190 if (*strtab == NULL)
7191 {
7192 free (*symtab);
7193 *symtab = NULL;
7194 *nsyms = 0;
015dc7e1 7195 return false;
28d13567
AM
7196 }
7197 *strtablen = strsec->sh_size;
7198 }
015dc7e1 7199 return true;
28d13567
AM
7200}
7201
f5842774
L
7202static const char *
7203get_group_flags (unsigned int flags)
7204{
1449284b 7205 static char buff[128];
220453ec 7206
6d913794
NC
7207 if (flags == 0)
7208 return "";
7209 else if (flags == GRP_COMDAT)
7210 return "COMDAT ";
f5842774 7211
89246a0e
AM
7212 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7213 flags,
7214 flags & GRP_MASKOS ? _("<OS specific>") : "",
7215 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7216 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7217 ? _("<unknown>") : ""));
6d913794 7218
f5842774
L
7219 return buff;
7220}
7221
015dc7e1 7222static bool
dda8d76d 7223process_section_groups (Filedata * filedata)
f5842774 7224{
2cf0635d 7225 Elf_Internal_Shdr * section;
f5842774 7226 unsigned int i;
2cf0635d
NC
7227 struct group * group;
7228 Elf_Internal_Shdr * symtab_sec;
7229 Elf_Internal_Shdr * strtab_sec;
7230 Elf_Internal_Sym * symtab;
ba5cdace 7231 unsigned long num_syms;
2cf0635d 7232 char * strtab;
c256ffe7 7233 size_t strtab_size;
d1f5c6e3
L
7234
7235 /* Don't process section groups unless needed. */
7236 if (!do_unwind && !do_section_groups)
015dc7e1 7237 return true;
f5842774 7238
dda8d76d 7239 if (filedata->file_header.e_shnum == 0)
f5842774
L
7240 {
7241 if (do_section_groups)
ca0e11aa
NC
7242 {
7243 if (filedata->is_separate)
7244 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7245 filedata->file_name);
7246 else
7247 printf (_("\nThere are no section groups in this file.\n"));
7248 }
015dc7e1 7249 return true;
f5842774
L
7250 }
7251
dda8d76d 7252 if (filedata->section_headers == NULL)
f5842774
L
7253 {
7254 error (_("Section headers are not available!\n"));
fa1908fd 7255 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7256 return false;
f5842774
L
7257 }
7258
978c4450
AM
7259 filedata->section_headers_groups
7260 = (struct group **) calloc (filedata->file_header.e_shnum,
7261 sizeof (struct group *));
e4b17d5c 7262
978c4450 7263 if (filedata->section_headers_groups == NULL)
e4b17d5c 7264 {
8b73c356 7265 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7266 filedata->file_header.e_shnum);
015dc7e1 7267 return false;
e4b17d5c
L
7268 }
7269
f5842774 7270 /* Scan the sections for the group section. */
978c4450 7271 filedata->group_count = 0;
dda8d76d
NC
7272 for (i = 0, section = filedata->section_headers;
7273 i < filedata->file_header.e_shnum;
f5842774 7274 i++, section++)
e4b17d5c 7275 if (section->sh_type == SHT_GROUP)
978c4450 7276 filedata->group_count++;
e4b17d5c 7277
978c4450 7278 if (filedata->group_count == 0)
d1f5c6e3
L
7279 {
7280 if (do_section_groups)
ca0e11aa
NC
7281 {
7282 if (filedata->is_separate)
7283 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7284 filedata->file_name);
7285 else
7286 printf (_("\nThere are no section groups in this file.\n"));
7287 }
d1f5c6e3 7288
015dc7e1 7289 return true;
d1f5c6e3
L
7290 }
7291
978c4450
AM
7292 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7293 sizeof (struct group));
e4b17d5c 7294
978c4450 7295 if (filedata->section_groups == NULL)
e4b17d5c 7296 {
8b73c356 7297 error (_("Out of memory reading %lu groups\n"),
978c4450 7298 (unsigned long) filedata->group_count);
015dc7e1 7299 return false;
e4b17d5c
L
7300 }
7301
d1f5c6e3
L
7302 symtab_sec = NULL;
7303 strtab_sec = NULL;
7304 symtab = NULL;
ba5cdace 7305 num_syms = 0;
d1f5c6e3 7306 strtab = NULL;
c256ffe7 7307 strtab_size = 0;
ca0e11aa
NC
7308
7309 if (filedata->is_separate)
7310 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7311
978c4450 7312 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7313 i < filedata->file_header.e_shnum;
e4b17d5c 7314 i++, section++)
f5842774
L
7315 {
7316 if (section->sh_type == SHT_GROUP)
7317 {
dda8d76d 7318 const char * name = printable_section_name (filedata, section);
74e1a04b 7319 const char * group_name;
2cf0635d
NC
7320 unsigned char * start;
7321 unsigned char * indices;
f5842774 7322 unsigned int entry, j, size;
2cf0635d
NC
7323 Elf_Internal_Shdr * sec;
7324 Elf_Internal_Sym * sym;
f5842774
L
7325
7326 /* Get the symbol table. */
dda8d76d
NC
7327 if (section->sh_link >= filedata->file_header.e_shnum
7328 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7329 != SHT_SYMTAB))
f5842774
L
7330 {
7331 error (_("Bad sh_link in group section `%s'\n"), name);
7332 continue;
7333 }
d1f5c6e3
L
7334
7335 if (symtab_sec != sec)
7336 {
7337 symtab_sec = sec;
9db70fc3 7338 free (symtab);
4de91c10 7339 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 7340 }
f5842774 7341
dd24e3da
NC
7342 if (symtab == NULL)
7343 {
7344 error (_("Corrupt header in group section `%s'\n"), name);
7345 continue;
7346 }
7347
ba5cdace
NC
7348 if (section->sh_info >= num_syms)
7349 {
7350 error (_("Bad sh_info in group section `%s'\n"), name);
7351 continue;
7352 }
7353
f5842774
L
7354 sym = symtab + section->sh_info;
7355
7356 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7357 {
4fbb74a6 7358 if (sym->st_shndx == 0
dda8d76d 7359 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7360 {
7361 error (_("Bad sh_info in group section `%s'\n"), name);
7362 continue;
7363 }
ba2685cc 7364
b9e920ec
AM
7365 group_name = SECTION_NAME_PRINT (filedata->section_headers
7366 + sym->st_shndx);
c256ffe7 7367 strtab_sec = NULL;
9db70fc3 7368 free (strtab);
f5842774 7369 strtab = NULL;
c256ffe7 7370 strtab_size = 0;
f5842774
L
7371 }
7372 else
7373 {
7374 /* Get the string table. */
dda8d76d 7375 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7376 {
7377 strtab_sec = NULL;
9db70fc3 7378 free (strtab);
c256ffe7
JJ
7379 strtab = NULL;
7380 strtab_size = 0;
7381 }
7382 else if (strtab_sec
dda8d76d 7383 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7384 {
7385 strtab_sec = sec;
9db70fc3 7386 free (strtab);
071436c6 7387
dda8d76d 7388 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7389 1, strtab_sec->sh_size,
7390 _("string table"));
c256ffe7 7391 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7392 }
c256ffe7 7393 group_name = sym->st_name < strtab_size
2b692964 7394 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7395 }
7396
c9c1d674
EG
7397 /* PR 17531: file: loop. */
7398 if (section->sh_entsize > section->sh_size)
7399 {
7400 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7401 printable_section_name (filedata, section),
8066deb1
AM
7402 (unsigned long) section->sh_entsize,
7403 (unsigned long) section->sh_size);
61dd8e19 7404 continue;
c9c1d674
EG
7405 }
7406
dda8d76d 7407 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7408 1, section->sh_size,
7409 _("section data"));
59245841
NC
7410 if (start == NULL)
7411 continue;
f5842774
L
7412
7413 indices = start;
7414 size = (section->sh_size / section->sh_entsize) - 1;
7415 entry = byte_get (indices, 4);
7416 indices += 4;
e4b17d5c
L
7417
7418 if (do_section_groups)
7419 {
2b692964 7420 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7421 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7422
e4b17d5c
L
7423 printf (_(" [Index] Name\n"));
7424 }
7425
7426 group->group_index = i;
7427
f5842774
L
7428 for (j = 0; j < size; j++)
7429 {
2cf0635d 7430 struct group_list * g;
e4b17d5c 7431
f5842774
L
7432 entry = byte_get (indices, 4);
7433 indices += 4;
7434
dda8d76d 7435 if (entry >= filedata->file_header.e_shnum)
391cb864 7436 {
57028622
NC
7437 static unsigned num_group_errors = 0;
7438
7439 if (num_group_errors ++ < 10)
7440 {
7441 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7442 entry, i, filedata->file_header.e_shnum - 1);
57028622 7443 if (num_group_errors == 10)
67ce483b 7444 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7445 }
391cb864
L
7446 continue;
7447 }
391cb864 7448
978c4450 7449 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7450 {
d1f5c6e3
L
7451 if (entry)
7452 {
57028622
NC
7453 static unsigned num_errs = 0;
7454
7455 if (num_errs ++ < 10)
7456 {
7457 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7458 entry, i,
978c4450 7459 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7460 if (num_errs == 10)
7461 warn (_("Further error messages about already contained group sections suppressed\n"));
7462 }
d1f5c6e3
L
7463 continue;
7464 }
7465 else
7466 {
7467 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7468 section group. We just warn it the first time
d1f5c6e3 7469 and ignore it afterwards. */
015dc7e1 7470 static bool warned = false;
d1f5c6e3
L
7471 if (!warned)
7472 {
7473 error (_("section 0 in group section [%5u]\n"),
978c4450 7474 filedata->section_headers_groups [entry]->group_index);
015dc7e1 7475 warned = true;
d1f5c6e3
L
7476 }
7477 }
e4b17d5c
L
7478 }
7479
978c4450 7480 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7481
7482 if (do_section_groups)
7483 {
dda8d76d
NC
7484 sec = filedata->section_headers + entry;
7485 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7486 }
7487
3f5e193b 7488 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7489 g->section_index = entry;
7490 g->next = group->root;
7491 group->root = g;
f5842774
L
7492 }
7493
9db70fc3 7494 free (start);
e4b17d5c
L
7495
7496 group++;
f5842774
L
7497 }
7498 }
7499
9db70fc3
AM
7500 free (symtab);
7501 free (strtab);
015dc7e1 7502 return true;
f5842774
L
7503}
7504
28f997cf
TG
7505/* Data used to display dynamic fixups. */
7506
7507struct ia64_vms_dynfixup
7508{
7509 bfd_vma needed_ident; /* Library ident number. */
7510 bfd_vma needed; /* Index in the dstrtab of the library name. */
7511 bfd_vma fixup_needed; /* Index of the library. */
7512 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7513 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7514};
7515
7516/* Data used to display dynamic relocations. */
7517
7518struct ia64_vms_dynimgrela
7519{
7520 bfd_vma img_rela_cnt; /* Number of relocations. */
7521 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7522};
7523
7524/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7525 library). */
7526
015dc7e1 7527static bool
dda8d76d
NC
7528dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7529 struct ia64_vms_dynfixup * fixup,
7530 const char * strtab,
7531 unsigned int strtab_sz)
28f997cf 7532{
32ec8896 7533 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7534 long i;
32ec8896 7535 const char * lib_name;
28f997cf 7536
978c4450
AM
7537 imfs = get_data (NULL, filedata,
7538 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7539 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7540 _("dynamic section image fixups"));
7541 if (!imfs)
015dc7e1 7542 return false;
28f997cf
TG
7543
7544 if (fixup->needed < strtab_sz)
7545 lib_name = strtab + fixup->needed;
7546 else
7547 {
32ec8896 7548 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7549 (unsigned long) fixup->needed);
28f997cf
TG
7550 lib_name = "???";
7551 }
736990c4 7552
28f997cf
TG
7553 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7554 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7555 printf
7556 (_("Seg Offset Type SymVec DataType\n"));
7557
7558 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7559 {
7560 unsigned int type;
7561 const char *rtype;
7562
7563 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7564 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7565 type = BYTE_GET (imfs [i].type);
7566 rtype = elf_ia64_reloc_type (type);
7567 if (rtype == NULL)
7568 printf (" 0x%08x ", type);
7569 else
7570 printf (" %-32s ", rtype);
7571 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7572 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7573 }
7574
7575 free (imfs);
015dc7e1 7576 return true;
28f997cf
TG
7577}
7578
7579/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7580
015dc7e1 7581static bool
dda8d76d 7582dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7583{
7584 Elf64_External_VMS_IMAGE_RELA *imrs;
7585 long i;
7586
978c4450
AM
7587 imrs = get_data (NULL, filedata,
7588 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 7589 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7590 _("dynamic section image relocations"));
28f997cf 7591 if (!imrs)
015dc7e1 7592 return false;
28f997cf
TG
7593
7594 printf (_("\nImage relocs\n"));
7595 printf
7596 (_("Seg Offset Type Addend Seg Sym Off\n"));
7597
7598 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7599 {
7600 unsigned int type;
7601 const char *rtype;
7602
7603 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7604 printf ("%08" BFD_VMA_FMT "x ",
7605 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7606 type = BYTE_GET (imrs [i].type);
7607 rtype = elf_ia64_reloc_type (type);
7608 if (rtype == NULL)
7609 printf ("0x%08x ", type);
7610 else
7611 printf ("%-31s ", rtype);
7612 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7613 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7614 printf ("%08" BFD_VMA_FMT "x\n",
7615 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7616 }
7617
7618 free (imrs);
015dc7e1 7619 return true;
28f997cf
TG
7620}
7621
7622/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7623
015dc7e1 7624static bool
dda8d76d 7625process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7626{
7627 struct ia64_vms_dynfixup fixup;
7628 struct ia64_vms_dynimgrela imgrela;
7629 Elf_Internal_Dyn *entry;
28f997cf
TG
7630 bfd_vma strtab_off = 0;
7631 bfd_vma strtab_sz = 0;
7632 char *strtab = NULL;
015dc7e1 7633 bool res = true;
28f997cf
TG
7634
7635 memset (&fixup, 0, sizeof (fixup));
7636 memset (&imgrela, 0, sizeof (imgrela));
7637
7638 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
7639 for (entry = filedata->dynamic_section;
7640 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
7641 entry++)
7642 {
7643 switch (entry->d_tag)
7644 {
7645 case DT_IA_64_VMS_STRTAB_OFFSET:
7646 strtab_off = entry->d_un.d_val;
7647 break;
7648 case DT_STRSZ:
7649 strtab_sz = entry->d_un.d_val;
7650 if (strtab == NULL)
978c4450
AM
7651 strtab = get_data (NULL, filedata,
7652 filedata->dynamic_addr + strtab_off,
28f997cf 7653 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7654 if (strtab == NULL)
7655 strtab_sz = 0;
28f997cf
TG
7656 break;
7657
7658 case DT_IA_64_VMS_NEEDED_IDENT:
7659 fixup.needed_ident = entry->d_un.d_val;
7660 break;
7661 case DT_NEEDED:
7662 fixup.needed = entry->d_un.d_val;
7663 break;
7664 case DT_IA_64_VMS_FIXUP_NEEDED:
7665 fixup.fixup_needed = entry->d_un.d_val;
7666 break;
7667 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7668 fixup.fixup_rela_cnt = entry->d_un.d_val;
7669 break;
7670 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7671 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7672 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 7673 res = false;
28f997cf 7674 break;
28f997cf
TG
7675 case DT_IA_64_VMS_IMG_RELA_CNT:
7676 imgrela.img_rela_cnt = entry->d_un.d_val;
7677 break;
7678 case DT_IA_64_VMS_IMG_RELA_OFF:
7679 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7680 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 7681 res = false;
28f997cf
TG
7682 break;
7683
7684 default:
7685 break;
7686 }
7687 }
7688
9db70fc3 7689 free (strtab);
28f997cf
TG
7690
7691 return res;
7692}
7693
85b1c36d 7694static struct
566b0d53 7695{
2cf0635d 7696 const char * name;
566b0d53
L
7697 int reloc;
7698 int size;
7699 int rela;
32ec8896
NC
7700}
7701 dynamic_relocations [] =
566b0d53 7702{
015dc7e1
AM
7703 { "REL", DT_REL, DT_RELSZ, false },
7704 { "RELA", DT_RELA, DT_RELASZ, true },
32ec8896 7705 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7706};
7707
252b5132 7708/* Process the reloc section. */
18bd398b 7709
015dc7e1 7710static bool
dda8d76d 7711process_relocs (Filedata * filedata)
252b5132 7712{
b34976b6
AM
7713 unsigned long rel_size;
7714 unsigned long rel_offset;
252b5132 7715
252b5132 7716 if (!do_reloc)
015dc7e1 7717 return true;
252b5132
RH
7718
7719 if (do_using_dynamic)
7720 {
32ec8896 7721 int is_rela;
2cf0635d 7722 const char * name;
015dc7e1 7723 bool has_dynamic_reloc;
566b0d53 7724 unsigned int i;
0de14b54 7725
015dc7e1 7726 has_dynamic_reloc = false;
252b5132 7727
566b0d53 7728 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7729 {
566b0d53
L
7730 is_rela = dynamic_relocations [i].rela;
7731 name = dynamic_relocations [i].name;
978c4450
AM
7732 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
7733 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 7734
32ec8896 7735 if (rel_size)
015dc7e1 7736 has_dynamic_reloc = true;
566b0d53
L
7737
7738 if (is_rela == UNKNOWN)
aa903cfb 7739 {
566b0d53 7740 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 7741 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
7742 {
7743 case DT_REL:
015dc7e1 7744 is_rela = false;
566b0d53
L
7745 break;
7746 case DT_RELA:
015dc7e1 7747 is_rela = true;
566b0d53
L
7748 break;
7749 }
aa903cfb 7750 }
252b5132 7751
566b0d53
L
7752 if (rel_size)
7753 {
ca0e11aa
NC
7754 if (filedata->is_separate)
7755 printf
7756 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
7757 filedata->file_name, name, rel_offset, rel_size);
7758 else
7759 printf
7760 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7761 name, rel_offset, rel_size);
252b5132 7762
dda8d76d
NC
7763 dump_relocations (filedata,
7764 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7765 rel_size,
978c4450
AM
7766 filedata->dynamic_symbols,
7767 filedata->num_dynamic_syms,
7768 filedata->dynamic_strings,
7769 filedata->dynamic_strings_length,
015dc7e1 7770 is_rela, true /* is_dynamic */);
566b0d53 7771 }
252b5132 7772 }
566b0d53 7773
dda8d76d
NC
7774 if (is_ia64_vms (filedata))
7775 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 7776 has_dynamic_reloc = true;
28f997cf 7777
566b0d53 7778 if (! has_dynamic_reloc)
ca0e11aa
NC
7779 {
7780 if (filedata->is_separate)
7781 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
7782 filedata->file_name);
7783 else
7784 printf (_("\nThere are no dynamic relocations in this file.\n"));
7785 }
252b5132
RH
7786 }
7787 else
7788 {
2cf0635d 7789 Elf_Internal_Shdr * section;
b34976b6 7790 unsigned long i;
015dc7e1 7791 bool found = false;
252b5132 7792
dda8d76d
NC
7793 for (i = 0, section = filedata->section_headers;
7794 i < filedata->file_header.e_shnum;
b34976b6 7795 i++, section++)
252b5132
RH
7796 {
7797 if ( section->sh_type != SHT_RELA
7798 && section->sh_type != SHT_REL)
7799 continue;
7800
7801 rel_offset = section->sh_offset;
7802 rel_size = section->sh_size;
7803
7804 if (rel_size)
7805 {
b34976b6 7806 int is_rela;
d3a49aa8 7807 unsigned long num_rela;
103f02d3 7808
ca0e11aa
NC
7809 if (filedata->is_separate)
7810 printf (_("\nIn linked file '%s' relocation section "),
7811 filedata->file_name);
7812 else
7813 printf (_("\nRelocation section "));
252b5132 7814
dda8d76d 7815 if (filedata->string_table == NULL)
19936277 7816 printf ("%d", section->sh_name);
252b5132 7817 else
dda8d76d 7818 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7819
d3a49aa8
AM
7820 num_rela = rel_size / section->sh_entsize;
7821 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7822 " at offset 0x%lx contains %lu entries:\n",
7823 num_rela),
7824 rel_offset, num_rela);
252b5132 7825
d79b3d50
NC
7826 is_rela = section->sh_type == SHT_RELA;
7827
4fbb74a6 7828 if (section->sh_link != 0
dda8d76d 7829 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7830 {
2cf0635d
NC
7831 Elf_Internal_Shdr * symsec;
7832 Elf_Internal_Sym * symtab;
d79b3d50 7833 unsigned long nsyms;
c256ffe7 7834 unsigned long strtablen = 0;
2cf0635d 7835 char * strtab = NULL;
57346661 7836
dda8d76d 7837 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7838 if (symsec->sh_type != SHT_SYMTAB
7839 && symsec->sh_type != SHT_DYNSYM)
7840 continue;
7841
28d13567
AM
7842 if (!get_symtab (filedata, symsec,
7843 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7844 continue;
252b5132 7845
dda8d76d 7846 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7847 symtab, nsyms, strtab, strtablen,
7848 is_rela,
7849 symsec->sh_type == SHT_DYNSYM);
9db70fc3 7850 free (strtab);
d79b3d50
NC
7851 free (symtab);
7852 }
7853 else
dda8d76d 7854 dump_relocations (filedata, rel_offset, rel_size,
32ec8896 7855 NULL, 0, NULL, 0, is_rela,
015dc7e1 7856 false /* is_dynamic */);
252b5132 7857
015dc7e1 7858 found = true;
252b5132
RH
7859 }
7860 }
7861
7862 if (! found)
45ac8f4f
NC
7863 {
7864 /* Users sometimes forget the -D option, so try to be helpful. */
7865 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7866 {
978c4450 7867 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 7868 {
ca0e11aa
NC
7869 if (filedata->is_separate)
7870 printf (_("\nThere are no static relocations in linked file '%s'."),
7871 filedata->file_name);
7872 else
7873 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
7874 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7875
7876 break;
7877 }
7878 }
7879 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
7880 {
7881 if (filedata->is_separate)
7882 printf (_("\nThere are no relocations in linked file '%s'.\n"),
7883 filedata->file_name);
7884 else
7885 printf (_("\nThere are no relocations in this file.\n"));
7886 }
45ac8f4f 7887 }
252b5132
RH
7888 }
7889
015dc7e1 7890 return true;
252b5132
RH
7891}
7892
4d6ed7c8
NC
7893/* An absolute address consists of a section and an offset. If the
7894 section is NULL, the offset itself is the address, otherwise, the
7895 address equals to LOAD_ADDRESS(section) + offset. */
7896
7897struct absaddr
948f632f
DA
7898{
7899 unsigned short section;
7900 bfd_vma offset;
7901};
4d6ed7c8 7902
948f632f
DA
7903/* Find the nearest symbol at or below ADDR. Returns the symbol
7904 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7905
4d6ed7c8 7906static void
dda8d76d
NC
7907find_symbol_for_address (Filedata * filedata,
7908 Elf_Internal_Sym * symtab,
7909 unsigned long nsyms,
7910 const char * strtab,
7911 unsigned long strtab_size,
7912 struct absaddr addr,
7913 const char ** symname,
7914 bfd_vma * offset)
4d6ed7c8 7915{
d3ba0551 7916 bfd_vma dist = 0x100000;
2cf0635d 7917 Elf_Internal_Sym * sym;
948f632f
DA
7918 Elf_Internal_Sym * beg;
7919 Elf_Internal_Sym * end;
2cf0635d 7920 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7921
0b6ae522 7922 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7923 beg = symtab;
7924 end = symtab + nsyms;
0b6ae522 7925
948f632f 7926 while (beg < end)
4d6ed7c8 7927 {
948f632f
DA
7928 bfd_vma value;
7929
7930 sym = beg + (end - beg) / 2;
0b6ae522 7931
948f632f 7932 value = sym->st_value;
0b6ae522
DJ
7933 REMOVE_ARCH_BITS (value);
7934
948f632f 7935 if (sym->st_name != 0
4d6ed7c8 7936 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7937 && addr.offset >= value
7938 && addr.offset - value < dist)
4d6ed7c8
NC
7939 {
7940 best = sym;
0b6ae522 7941 dist = addr.offset - value;
4d6ed7c8
NC
7942 if (!dist)
7943 break;
7944 }
948f632f
DA
7945
7946 if (addr.offset < value)
7947 end = sym;
7948 else
7949 beg = sym + 1;
4d6ed7c8 7950 }
1b31d05e 7951
4d6ed7c8
NC
7952 if (best)
7953 {
57346661 7954 *symname = (best->st_name >= strtab_size
2b692964 7955 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7956 *offset = dist;
7957 return;
7958 }
1b31d05e 7959
4d6ed7c8
NC
7960 *symname = NULL;
7961 *offset = addr.offset;
7962}
7963
32ec8896 7964static /* signed */ int
948f632f
DA
7965symcmp (const void *p, const void *q)
7966{
7967 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7968 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7969
7970 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7971}
7972
7973/* Process the unwind section. */
7974
7975#include "unwind-ia64.h"
7976
7977struct ia64_unw_table_entry
7978{
7979 struct absaddr start;
7980 struct absaddr end;
7981 struct absaddr info;
7982};
7983
7984struct ia64_unw_aux_info
7985{
32ec8896
NC
7986 struct ia64_unw_table_entry * table; /* Unwind table. */
7987 unsigned long table_len; /* Length of unwind table. */
7988 unsigned char * info; /* Unwind info. */
7989 unsigned long info_size; /* Size of unwind info. */
7990 bfd_vma info_addr; /* Starting address of unwind info. */
7991 bfd_vma seg_base; /* Starting address of segment. */
7992 Elf_Internal_Sym * symtab; /* The symbol table. */
7993 unsigned long nsyms; /* Number of symbols. */
7994 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7995 unsigned long nfuns; /* Number of entries in funtab. */
7996 char * strtab; /* The string table. */
7997 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7998};
7999
015dc7e1 8000static bool
dda8d76d 8001dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8002{
2cf0635d 8003 struct ia64_unw_table_entry * tp;
948f632f 8004 unsigned long j, nfuns;
4d6ed7c8 8005 int in_body;
015dc7e1 8006 bool res = true;
7036c0e1 8007
948f632f
DA
8008 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8009 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8010 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8011 aux->funtab[nfuns++] = aux->symtab[j];
8012 aux->nfuns = nfuns;
8013 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8014
4d6ed7c8
NC
8015 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8016 {
8017 bfd_vma stamp;
8018 bfd_vma offset;
2cf0635d
NC
8019 const unsigned char * dp;
8020 const unsigned char * head;
53774b7e 8021 const unsigned char * end;
2cf0635d 8022 const char * procname;
4d6ed7c8 8023
dda8d76d 8024 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8025 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8026
8027 fputs ("\n<", stdout);
8028
8029 if (procname)
8030 {
8031 fputs (procname, stdout);
8032
8033 if (offset)
8034 printf ("+%lx", (unsigned long) offset);
8035 }
8036
8037 fputs (">: [", stdout);
8038 print_vma (tp->start.offset, PREFIX_HEX);
8039 fputc ('-', stdout);
8040 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 8041 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
8042 (unsigned long) (tp->info.offset - aux->seg_base));
8043
53774b7e
NC
8044 /* PR 17531: file: 86232b32. */
8045 if (aux->info == NULL)
8046 continue;
8047
97c0a079
AM
8048 offset = tp->info.offset;
8049 if (tp->info.section)
8050 {
8051 if (tp->info.section >= filedata->file_header.e_shnum)
8052 {
8053 warn (_("Invalid section %u in table entry %ld\n"),
8054 tp->info.section, (long) (tp - aux->table));
015dc7e1 8055 res = false;
97c0a079
AM
8056 continue;
8057 }
8058 offset += filedata->section_headers[tp->info.section].sh_addr;
8059 }
8060 offset -= aux->info_addr;
53774b7e 8061 /* PR 17531: file: 0997b4d1. */
90679903
AM
8062 if (offset >= aux->info_size
8063 || aux->info_size - offset < 8)
53774b7e
NC
8064 {
8065 warn (_("Invalid offset %lx in table entry %ld\n"),
8066 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8067 res = false;
53774b7e
NC
8068 continue;
8069 }
8070
97c0a079 8071 head = aux->info + offset;
a4a00738 8072 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8073
86f55779 8074 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8075 (unsigned) UNW_VER (stamp),
8076 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8077 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8078 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8079 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8080
8081 if (UNW_VER (stamp) != 1)
8082 {
2b692964 8083 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8084 continue;
8085 }
8086
8087 in_body = 0;
53774b7e
NC
8088 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8089 /* PR 17531: file: 16ceda89. */
8090 if (end > aux->info + aux->info_size)
8091 end = aux->info + aux->info_size;
8092 for (dp = head + 8; dp < end;)
b4477bc8 8093 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8094 }
948f632f
DA
8095
8096 free (aux->funtab);
32ec8896
NC
8097
8098 return res;
4d6ed7c8
NC
8099}
8100
015dc7e1 8101static bool
dda8d76d
NC
8102slurp_ia64_unwind_table (Filedata * filedata,
8103 struct ia64_unw_aux_info * aux,
8104 Elf_Internal_Shdr * sec)
4d6ed7c8 8105{
89fac5e3 8106 unsigned long size, nrelas, i;
2cf0635d
NC
8107 Elf_Internal_Phdr * seg;
8108 struct ia64_unw_table_entry * tep;
8109 Elf_Internal_Shdr * relsec;
8110 Elf_Internal_Rela * rela;
8111 Elf_Internal_Rela * rp;
8112 unsigned char * table;
8113 unsigned char * tp;
8114 Elf_Internal_Sym * sym;
8115 const char * relname;
4d6ed7c8 8116
53774b7e
NC
8117 aux->table_len = 0;
8118
4d6ed7c8
NC
8119 /* First, find the starting address of the segment that includes
8120 this section: */
8121
dda8d76d 8122 if (filedata->file_header.e_phnum)
4d6ed7c8 8123 {
dda8d76d 8124 if (! get_program_headers (filedata))
015dc7e1 8125 return false;
4d6ed7c8 8126
dda8d76d
NC
8127 for (seg = filedata->program_headers;
8128 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8129 ++seg)
4d6ed7c8
NC
8130 {
8131 if (seg->p_type != PT_LOAD)
8132 continue;
8133
8134 if (sec->sh_addr >= seg->p_vaddr
8135 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8136 {
8137 aux->seg_base = seg->p_vaddr;
8138 break;
8139 }
8140 }
4d6ed7c8
NC
8141 }
8142
8143 /* Second, build the unwind table from the contents of the unwind section: */
8144 size = sec->sh_size;
dda8d76d 8145 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8146 _("unwind table"));
a6e9f9df 8147 if (!table)
015dc7e1 8148 return false;
4d6ed7c8 8149
53774b7e 8150 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8151 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8152 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8153 tep = aux->table;
53774b7e
NC
8154
8155 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8156 {
8157 tep->start.section = SHN_UNDEF;
8158 tep->end.section = SHN_UNDEF;
8159 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8160 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8161 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8162 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8163 tep->start.offset += aux->seg_base;
8164 tep->end.offset += aux->seg_base;
8165 tep->info.offset += aux->seg_base;
8166 }
8167 free (table);
8168
41e92641 8169 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8170 for (relsec = filedata->section_headers;
8171 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8172 ++relsec)
8173 {
8174 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8175 || relsec->sh_info >= filedata->file_header.e_shnum
8176 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8177 continue;
8178
dda8d76d 8179 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8180 & rela, & nrelas))
53774b7e
NC
8181 {
8182 free (aux->table);
8183 aux->table = NULL;
8184 aux->table_len = 0;
015dc7e1 8185 return false;
53774b7e 8186 }
4d6ed7c8
NC
8187
8188 for (rp = rela; rp < rela + nrelas; ++rp)
8189 {
4770fb94 8190 unsigned int sym_ndx;
726bd37d
AM
8191 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8192 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8193
82b1b41b
NC
8194 /* PR 17531: file: 9fa67536. */
8195 if (relname == NULL)
8196 {
726bd37d 8197 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8198 continue;
8199 }
948f632f 8200
24d127aa 8201 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8202 {
82b1b41b 8203 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8204 continue;
8205 }
8206
89fac5e3 8207 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8208
53774b7e
NC
8209 /* PR 17531: file: 5bc8d9bf. */
8210 if (i >= aux->table_len)
8211 {
8212 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8213 continue;
8214 }
8215
4770fb94
AM
8216 sym_ndx = get_reloc_symindex (rp->r_info);
8217 if (sym_ndx >= aux->nsyms)
8218 {
8219 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8220 sym_ndx);
8221 continue;
8222 }
8223 sym = aux->symtab + sym_ndx;
8224
53774b7e 8225 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8226 {
8227 case 0:
8228 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8229 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8230 break;
8231 case 1:
8232 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8233 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8234 break;
8235 case 2:
8236 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8237 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8238 break;
8239 default:
8240 break;
8241 }
8242 }
8243
8244 free (rela);
8245 }
8246
015dc7e1 8247 return true;
4d6ed7c8
NC
8248}
8249
015dc7e1 8250static bool
dda8d76d 8251ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8252{
2cf0635d
NC
8253 Elf_Internal_Shdr * sec;
8254 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8255 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8256 struct ia64_unw_aux_info aux;
015dc7e1 8257 bool res = true;
f1467e33 8258
4d6ed7c8
NC
8259 memset (& aux, 0, sizeof (aux));
8260
dda8d76d 8261 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8262 {
28d13567 8263 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8264 {
28d13567 8265 if (aux.symtab)
4082ef84 8266 {
28d13567
AM
8267 error (_("Multiple symbol tables encountered\n"));
8268 free (aux.symtab);
8269 aux.symtab = NULL;
4082ef84 8270 free (aux.strtab);
28d13567 8271 aux.strtab = NULL;
4082ef84 8272 }
28d13567
AM
8273 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8274 &aux.strtab, &aux.strtab_size))
015dc7e1 8275 return false;
4d6ed7c8
NC
8276 }
8277 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8278 unwcount++;
8279 }
8280
8281 if (!unwcount)
8282 printf (_("\nThere are no unwind sections in this file.\n"));
8283
8284 while (unwcount-- > 0)
8285 {
2cf0635d 8286 char * suffix;
579f31ac
JJ
8287 size_t len, len2;
8288
dda8d76d
NC
8289 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8290 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8291 if (sec->sh_type == SHT_IA_64_UNWIND)
8292 {
8293 unwsec = sec;
8294 break;
8295 }
4082ef84
NC
8296 /* We have already counted the number of SHT_IA64_UNWIND
8297 sections so the loop above should never fail. */
8298 assert (unwsec != NULL);
579f31ac
JJ
8299
8300 unwstart = i + 1;
8301 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8302
e4b17d5c
L
8303 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8304 {
8305 /* We need to find which section group it is in. */
4082ef84 8306 struct group_list * g;
e4b17d5c 8307
978c4450
AM
8308 if (filedata->section_headers_groups == NULL
8309 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8310 i = filedata->file_header.e_shnum;
4082ef84 8311 else
e4b17d5c 8312 {
978c4450 8313 g = filedata->section_headers_groups[i]->root;
18bd398b 8314
4082ef84
NC
8315 for (; g != NULL; g = g->next)
8316 {
dda8d76d 8317 sec = filedata->section_headers + g->section_index;
e4b17d5c 8318
b9e920ec
AM
8319 if (SECTION_NAME_VALID (sec)
8320 && streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
4082ef84
NC
8321 break;
8322 }
8323
8324 if (g == NULL)
dda8d76d 8325 i = filedata->file_header.e_shnum;
4082ef84 8326 }
e4b17d5c 8327 }
b9e920ec 8328 else if (SECTION_NAME_VALID (unwsec)
e9b095a5
ML
8329 && startswith (SECTION_NAME (unwsec),
8330 ELF_STRING_ia64_unwind_once))
579f31ac 8331 {
18bd398b 8332 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
8333 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
8334 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8335 for (i = 0, sec = filedata->section_headers;
8336 i < filedata->file_header.e_shnum;
579f31ac 8337 ++i, ++sec)
b9e920ec 8338 if (SECTION_NAME_VALID (sec)
e9b095a5
ML
8339 && startswith (SECTION_NAME (sec),
8340 ELF_STRING_ia64_unwind_info_once)
18bd398b 8341 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8342 break;
8343 }
8344 else
8345 {
8346 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8347 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8348 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8349 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8350 suffix = "";
b9e920ec 8351 if (SECTION_NAME_VALID (unwsec)
e9b095a5 8352 && startswith (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind))
579f31ac 8353 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8354 for (i = 0, sec = filedata->section_headers;
8355 i < filedata->file_header.e_shnum;
579f31ac 8356 ++i, ++sec)
b9e920ec 8357 if (SECTION_NAME_VALID (sec)
e9b095a5 8358 && startswith (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info)
18bd398b 8359 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8360 break;
8361 }
8362
dda8d76d 8363 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8364 {
8365 printf (_("\nCould not find unwind info section for "));
8366
dda8d76d 8367 if (filedata->string_table == NULL)
579f31ac
JJ
8368 printf ("%d", unwsec->sh_name);
8369 else
dda8d76d 8370 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8371 }
8372 else
4d6ed7c8 8373 {
4d6ed7c8 8374 aux.info_addr = sec->sh_addr;
dda8d76d 8375 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8376 sec->sh_size,
8377 _("unwind info"));
59245841 8378 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8379
579f31ac 8380 printf (_("\nUnwind section "));
4d6ed7c8 8381
dda8d76d 8382 if (filedata->string_table == NULL)
579f31ac
JJ
8383 printf ("%d", unwsec->sh_name);
8384 else
dda8d76d 8385 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8386
579f31ac 8387 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8388 (unsigned long) unwsec->sh_offset,
89fac5e3 8389 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8390
dda8d76d 8391 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8392 && aux.table_len > 0)
dda8d76d 8393 dump_ia64_unwind (filedata, & aux);
579f31ac 8394
9db70fc3
AM
8395 free ((char *) aux.table);
8396 free ((char *) aux.info);
579f31ac
JJ
8397 aux.table = NULL;
8398 aux.info = NULL;
8399 }
4d6ed7c8 8400 }
4d6ed7c8 8401
9db70fc3
AM
8402 free (aux.symtab);
8403 free ((char *) aux.strtab);
32ec8896
NC
8404
8405 return res;
4d6ed7c8
NC
8406}
8407
3f5e193b 8408struct hppa_unw_table_entry
32ec8896
NC
8409{
8410 struct absaddr start;
8411 struct absaddr end;
8412 unsigned int Cannot_unwind:1; /* 0 */
8413 unsigned int Millicode:1; /* 1 */
8414 unsigned int Millicode_save_sr0:1; /* 2 */
8415 unsigned int Region_description:2; /* 3..4 */
8416 unsigned int reserved1:1; /* 5 */
8417 unsigned int Entry_SR:1; /* 6 */
8418 unsigned int Entry_FR:4; /* Number saved 7..10 */
8419 unsigned int Entry_GR:5; /* Number saved 11..15 */
8420 unsigned int Args_stored:1; /* 16 */
8421 unsigned int Variable_Frame:1; /* 17 */
8422 unsigned int Separate_Package_Body:1; /* 18 */
8423 unsigned int Frame_Extension_Millicode:1; /* 19 */
8424 unsigned int Stack_Overflow_Check:1; /* 20 */
8425 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8426 unsigned int Ada_Region:1; /* 22 */
8427 unsigned int cxx_info:1; /* 23 */
8428 unsigned int cxx_try_catch:1; /* 24 */
8429 unsigned int sched_entry_seq:1; /* 25 */
8430 unsigned int reserved2:1; /* 26 */
8431 unsigned int Save_SP:1; /* 27 */
8432 unsigned int Save_RP:1; /* 28 */
8433 unsigned int Save_MRP_in_frame:1; /* 29 */
8434 unsigned int extn_ptr_defined:1; /* 30 */
8435 unsigned int Cleanup_defined:1; /* 31 */
8436
8437 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8438 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8439 unsigned int Large_frame:1; /* 2 */
8440 unsigned int Pseudo_SP_Set:1; /* 3 */
8441 unsigned int reserved4:1; /* 4 */
8442 unsigned int Total_frame_size:27; /* 5..31 */
8443};
3f5e193b 8444
57346661 8445struct hppa_unw_aux_info
948f632f 8446{
32ec8896
NC
8447 struct hppa_unw_table_entry * table; /* Unwind table. */
8448 unsigned long table_len; /* Length of unwind table. */
8449 bfd_vma seg_base; /* Starting address of segment. */
8450 Elf_Internal_Sym * symtab; /* The symbol table. */
8451 unsigned long nsyms; /* Number of symbols. */
8452 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8453 unsigned long nfuns; /* Number of entries in funtab. */
8454 char * strtab; /* The string table. */
8455 unsigned long strtab_size; /* Size of string table. */
948f632f 8456};
57346661 8457
015dc7e1 8458static bool
dda8d76d 8459dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8460{
2cf0635d 8461 struct hppa_unw_table_entry * tp;
948f632f 8462 unsigned long j, nfuns;
015dc7e1 8463 bool res = true;
948f632f
DA
8464
8465 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8466 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8467 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8468 aux->funtab[nfuns++] = aux->symtab[j];
8469 aux->nfuns = nfuns;
8470 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8471
57346661
AM
8472 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8473 {
8474 bfd_vma offset;
2cf0635d 8475 const char * procname;
57346661 8476
dda8d76d 8477 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8478 aux->strtab_size, tp->start, &procname,
8479 &offset);
8480
8481 fputs ("\n<", stdout);
8482
8483 if (procname)
8484 {
8485 fputs (procname, stdout);
8486
8487 if (offset)
8488 printf ("+%lx", (unsigned long) offset);
8489 }
8490
8491 fputs (">: [", stdout);
8492 print_vma (tp->start.offset, PREFIX_HEX);
8493 fputc ('-', stdout);
8494 print_vma (tp->end.offset, PREFIX_HEX);
8495 printf ("]\n\t");
8496
18bd398b
NC
8497#define PF(_m) if (tp->_m) printf (#_m " ");
8498#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8499 PF(Cannot_unwind);
8500 PF(Millicode);
8501 PF(Millicode_save_sr0);
18bd398b 8502 /* PV(Region_description); */
57346661
AM
8503 PF(Entry_SR);
8504 PV(Entry_FR);
8505 PV(Entry_GR);
8506 PF(Args_stored);
8507 PF(Variable_Frame);
8508 PF(Separate_Package_Body);
8509 PF(Frame_Extension_Millicode);
8510 PF(Stack_Overflow_Check);
8511 PF(Two_Instruction_SP_Increment);
8512 PF(Ada_Region);
8513 PF(cxx_info);
8514 PF(cxx_try_catch);
8515 PF(sched_entry_seq);
8516 PF(Save_SP);
8517 PF(Save_RP);
8518 PF(Save_MRP_in_frame);
8519 PF(extn_ptr_defined);
8520 PF(Cleanup_defined);
8521 PF(MPE_XL_interrupt_marker);
8522 PF(HP_UX_interrupt_marker);
8523 PF(Large_frame);
8524 PF(Pseudo_SP_Set);
8525 PV(Total_frame_size);
8526#undef PF
8527#undef PV
8528 }
8529
18bd398b 8530 printf ("\n");
948f632f
DA
8531
8532 free (aux->funtab);
32ec8896
NC
8533
8534 return res;
57346661
AM
8535}
8536
015dc7e1 8537static bool
dda8d76d
NC
8538slurp_hppa_unwind_table (Filedata * filedata,
8539 struct hppa_unw_aux_info * aux,
8540 Elf_Internal_Shdr * sec)
57346661 8541{
1c0751b2 8542 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8543 Elf_Internal_Phdr * seg;
8544 struct hppa_unw_table_entry * tep;
8545 Elf_Internal_Shdr * relsec;
8546 Elf_Internal_Rela * rela;
8547 Elf_Internal_Rela * rp;
8548 unsigned char * table;
8549 unsigned char * tp;
8550 Elf_Internal_Sym * sym;
8551 const char * relname;
57346661 8552
57346661
AM
8553 /* First, find the starting address of the segment that includes
8554 this section. */
dda8d76d 8555 if (filedata->file_header.e_phnum)
57346661 8556 {
dda8d76d 8557 if (! get_program_headers (filedata))
015dc7e1 8558 return false;
57346661 8559
dda8d76d
NC
8560 for (seg = filedata->program_headers;
8561 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8562 ++seg)
8563 {
8564 if (seg->p_type != PT_LOAD)
8565 continue;
8566
8567 if (sec->sh_addr >= seg->p_vaddr
8568 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8569 {
8570 aux->seg_base = seg->p_vaddr;
8571 break;
8572 }
8573 }
8574 }
8575
8576 /* Second, build the unwind table from the contents of the unwind
8577 section. */
8578 size = sec->sh_size;
dda8d76d 8579 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8580 _("unwind table"));
57346661 8581 if (!table)
015dc7e1 8582 return false;
57346661 8583
1c0751b2
DA
8584 unw_ent_size = 16;
8585 nentries = size / unw_ent_size;
8586 size = unw_ent_size * nentries;
57346661 8587
e3fdc001 8588 aux->table_len = nentries;
3f5e193b
NC
8589 tep = aux->table = (struct hppa_unw_table_entry *)
8590 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8591
1c0751b2 8592 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8593 {
8594 unsigned int tmp1, tmp2;
8595
8596 tep->start.section = SHN_UNDEF;
8597 tep->end.section = SHN_UNDEF;
8598
1c0751b2
DA
8599 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8600 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8601 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8602 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8603
8604 tep->start.offset += aux->seg_base;
8605 tep->end.offset += aux->seg_base;
57346661
AM
8606
8607 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8608 tep->Millicode = (tmp1 >> 30) & 0x1;
8609 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8610 tep->Region_description = (tmp1 >> 27) & 0x3;
8611 tep->reserved1 = (tmp1 >> 26) & 0x1;
8612 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8613 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8614 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8615 tep->Args_stored = (tmp1 >> 15) & 0x1;
8616 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8617 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8618 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8619 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8620 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8621 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8622 tep->cxx_info = (tmp1 >> 8) & 0x1;
8623 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8624 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8625 tep->reserved2 = (tmp1 >> 5) & 0x1;
8626 tep->Save_SP = (tmp1 >> 4) & 0x1;
8627 tep->Save_RP = (tmp1 >> 3) & 0x1;
8628 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8629 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8630 tep->Cleanup_defined = tmp1 & 0x1;
8631
8632 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8633 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8634 tep->Large_frame = (tmp2 >> 29) & 0x1;
8635 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8636 tep->reserved4 = (tmp2 >> 27) & 0x1;
8637 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8638 }
8639 free (table);
8640
8641 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8642 for (relsec = filedata->section_headers;
8643 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8644 ++relsec)
8645 {
8646 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8647 || relsec->sh_info >= filedata->file_header.e_shnum
8648 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8649 continue;
8650
dda8d76d 8651 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8652 & rela, & nrelas))
015dc7e1 8653 return false;
57346661
AM
8654
8655 for (rp = rela; rp < rela + nrelas; ++rp)
8656 {
4770fb94 8657 unsigned int sym_ndx;
726bd37d
AM
8658 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8659 relname = elf_hppa_reloc_type (r_type);
57346661 8660
726bd37d
AM
8661 if (relname == NULL)
8662 {
8663 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8664 continue;
8665 }
8666
57346661 8667 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 8668 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 8669 {
726bd37d 8670 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8671 continue;
8672 }
8673
8674 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8675 if (i >= aux->table_len)
8676 {
8677 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8678 continue;
8679 }
57346661 8680
4770fb94
AM
8681 sym_ndx = get_reloc_symindex (rp->r_info);
8682 if (sym_ndx >= aux->nsyms)
8683 {
8684 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8685 sym_ndx);
8686 continue;
8687 }
8688 sym = aux->symtab + sym_ndx;
8689
43f6cd05 8690 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8691 {
8692 case 0:
8693 aux->table[i].start.section = sym->st_shndx;
1e456d54 8694 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8695 break;
8696 case 1:
8697 aux->table[i].end.section = sym->st_shndx;
1e456d54 8698 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8699 break;
8700 default:
8701 break;
8702 }
8703 }
8704
8705 free (rela);
8706 }
8707
015dc7e1 8708 return true;
57346661
AM
8709}
8710
015dc7e1 8711static bool
dda8d76d 8712hppa_process_unwind (Filedata * filedata)
57346661 8713{
57346661 8714 struct hppa_unw_aux_info aux;
2cf0635d 8715 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8716 Elf_Internal_Shdr * sec;
18bd398b 8717 unsigned long i;
015dc7e1 8718 bool res = true;
57346661 8719
dda8d76d 8720 if (filedata->string_table == NULL)
015dc7e1 8721 return false;
1b31d05e
NC
8722
8723 memset (& aux, 0, sizeof (aux));
57346661 8724
dda8d76d 8725 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8726 {
28d13567 8727 if (sec->sh_type == SHT_SYMTAB)
57346661 8728 {
28d13567 8729 if (aux.symtab)
4082ef84 8730 {
28d13567
AM
8731 error (_("Multiple symbol tables encountered\n"));
8732 free (aux.symtab);
8733 aux.symtab = NULL;
4082ef84 8734 free (aux.strtab);
28d13567 8735 aux.strtab = NULL;
4082ef84 8736 }
28d13567
AM
8737 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8738 &aux.strtab, &aux.strtab_size))
015dc7e1 8739 return false;
57346661 8740 }
b9e920ec
AM
8741 else if (SECTION_NAME_VALID (sec)
8742 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8743 unwsec = sec;
8744 }
8745
8746 if (!unwsec)
8747 printf (_("\nThere are no unwind sections in this file.\n"));
8748
dda8d76d 8749 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8750 {
b9e920ec
AM
8751 if (SECTION_NAME_VALID (sec)
8752 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8753 {
43f6cd05 8754 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8755
d3a49aa8
AM
8756 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8757 "contains %lu entry:\n",
8758 "\nUnwind section '%s' at offset 0x%lx "
8759 "contains %lu entries:\n",
8760 num_unwind),
dda8d76d 8761 printable_section_name (filedata, sec),
57346661 8762 (unsigned long) sec->sh_offset,
d3a49aa8 8763 num_unwind);
57346661 8764
dda8d76d 8765 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 8766 res = false;
66b09c7e
S
8767
8768 if (res && aux.table_len > 0)
32ec8896 8769 {
dda8d76d 8770 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 8771 res = false;
32ec8896 8772 }
57346661 8773
9db70fc3 8774 free ((char *) aux.table);
57346661
AM
8775 aux.table = NULL;
8776 }
8777 }
8778
9db70fc3
AM
8779 free (aux.symtab);
8780 free ((char *) aux.strtab);
32ec8896
NC
8781
8782 return res;
57346661
AM
8783}
8784
0b6ae522
DJ
8785struct arm_section
8786{
a734115a
NC
8787 unsigned char * data; /* The unwind data. */
8788 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8789 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8790 unsigned long nrelas; /* The number of relocations. */
8791 unsigned int rel_type; /* REL or RELA ? */
8792 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8793};
8794
8795struct arm_unw_aux_info
8796{
dda8d76d 8797 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8798 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8799 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8800 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8801 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8802 char * strtab; /* The file's string table. */
8803 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8804};
8805
8806static const char *
dda8d76d
NC
8807arm_print_vma_and_name (Filedata * filedata,
8808 struct arm_unw_aux_info * aux,
8809 bfd_vma fn,
8810 struct absaddr addr)
0b6ae522
DJ
8811{
8812 const char *procname;
8813 bfd_vma sym_offset;
8814
8815 if (addr.section == SHN_UNDEF)
8816 addr.offset = fn;
8817
dda8d76d 8818 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8819 aux->strtab_size, addr, &procname,
8820 &sym_offset);
8821
8822 print_vma (fn, PREFIX_HEX);
8823
8824 if (procname)
8825 {
8826 fputs (" <", stdout);
8827 fputs (procname, stdout);
8828
8829 if (sym_offset)
8830 printf ("+0x%lx", (unsigned long) sym_offset);
8831 fputc ('>', stdout);
8832 }
8833
8834 return procname;
8835}
8836
8837static void
8838arm_free_section (struct arm_section *arm_sec)
8839{
9db70fc3
AM
8840 free (arm_sec->data);
8841 free (arm_sec->rela);
0b6ae522
DJ
8842}
8843
a734115a
NC
8844/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8845 cached section and install SEC instead.
8846 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8847 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8848 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8849 relocation's offset in ADDR.
1b31d05e
NC
8850 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8851 into the string table of the symbol associated with the reloc. If no
8852 reloc was applied store -1 there.
8853 5) Return TRUE upon success, FALSE otherwise. */
a734115a 8854
015dc7e1 8855static bool
dda8d76d
NC
8856get_unwind_section_word (Filedata * filedata,
8857 struct arm_unw_aux_info * aux,
1b31d05e
NC
8858 struct arm_section * arm_sec,
8859 Elf_Internal_Shdr * sec,
8860 bfd_vma word_offset,
8861 unsigned int * wordp,
8862 struct absaddr * addr,
8863 bfd_vma * sym_name)
0b6ae522
DJ
8864{
8865 Elf_Internal_Rela *rp;
8866 Elf_Internal_Sym *sym;
8867 const char * relname;
8868 unsigned int word;
015dc7e1 8869 bool wrapped;
0b6ae522 8870
e0a31db1 8871 if (sec == NULL || arm_sec == NULL)
015dc7e1 8872 return false;
e0a31db1 8873
0b6ae522
DJ
8874 addr->section = SHN_UNDEF;
8875 addr->offset = 0;
8876
1b31d05e
NC
8877 if (sym_name != NULL)
8878 *sym_name = (bfd_vma) -1;
8879
a734115a 8880 /* If necessary, update the section cache. */
0b6ae522
DJ
8881 if (sec != arm_sec->sec)
8882 {
8883 Elf_Internal_Shdr *relsec;
8884
8885 arm_free_section (arm_sec);
8886
8887 arm_sec->sec = sec;
dda8d76d 8888 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8889 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8890 arm_sec->rela = NULL;
8891 arm_sec->nrelas = 0;
8892
dda8d76d
NC
8893 for (relsec = filedata->section_headers;
8894 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8895 ++relsec)
8896 {
dda8d76d
NC
8897 if (relsec->sh_info >= filedata->file_header.e_shnum
8898 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8899 /* PR 15745: Check the section type as well. */
8900 || (relsec->sh_type != SHT_REL
8901 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8902 continue;
8903
a734115a 8904 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8905 if (relsec->sh_type == SHT_REL)
8906 {
dda8d76d 8907 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8908 relsec->sh_size,
8909 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 8910 return false;
0b6ae522 8911 }
1ae40aa4 8912 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8913 {
dda8d76d 8914 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8915 relsec->sh_size,
8916 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 8917 return false;
0b6ae522 8918 }
1ae40aa4 8919 break;
0b6ae522
DJ
8920 }
8921
8922 arm_sec->next_rela = arm_sec->rela;
8923 }
8924
a734115a 8925 /* If there is no unwind data we can do nothing. */
0b6ae522 8926 if (arm_sec->data == NULL)
015dc7e1 8927 return false;
0b6ae522 8928
e0a31db1 8929 /* If the offset is invalid then fail. */
f32ba729
NC
8930 if (/* PR 21343 *//* PR 18879 */
8931 sec->sh_size < 4
8932 || word_offset > (sec->sh_size - 4)
1a915552 8933 || ((bfd_signed_vma) word_offset) < 0)
015dc7e1 8934 return false;
e0a31db1 8935
a734115a 8936 /* Get the word at the required offset. */
0b6ae522
DJ
8937 word = byte_get (arm_sec->data + word_offset, 4);
8938
0eff7165
NC
8939 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8940 if (arm_sec->rela == NULL)
8941 {
8942 * wordp = word;
015dc7e1 8943 return true;
0eff7165
NC
8944 }
8945
a734115a 8946 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 8947 wrapped = false;
0b6ae522
DJ
8948 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8949 {
8950 bfd_vma prelval, offset;
8951
8952 if (rp->r_offset > word_offset && !wrapped)
8953 {
8954 rp = arm_sec->rela;
015dc7e1 8955 wrapped = true;
0b6ae522
DJ
8956 }
8957 if (rp->r_offset > word_offset)
8958 break;
8959
8960 if (rp->r_offset & 3)
8961 {
8962 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8963 (unsigned long) rp->r_offset);
8964 continue;
8965 }
8966
8967 if (rp->r_offset < word_offset)
8968 continue;
8969
74e1a04b
NC
8970 /* PR 17531: file: 027-161405-0.004 */
8971 if (aux->symtab == NULL)
8972 continue;
8973
0b6ae522
DJ
8974 if (arm_sec->rel_type == SHT_REL)
8975 {
8976 offset = word & 0x7fffffff;
8977 if (offset & 0x40000000)
8978 offset |= ~ (bfd_vma) 0x7fffffff;
8979 }
a734115a 8980 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8981 offset = rp->r_addend;
a734115a 8982 else
74e1a04b
NC
8983 {
8984 error (_("Unknown section relocation type %d encountered\n"),
8985 arm_sec->rel_type);
8986 break;
8987 }
0b6ae522 8988
071436c6
NC
8989 /* PR 17531 file: 027-1241568-0.004. */
8990 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8991 {
8992 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8993 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8994 break;
8995 }
8996
8997 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8998 offset += sym->st_value;
8999 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9000
a734115a 9001 /* Check that we are processing the expected reloc type. */
dda8d76d 9002 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9003 {
9004 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9005 if (relname == NULL)
9006 {
9007 warn (_("Skipping unknown ARM relocation type: %d\n"),
9008 (int) ELF32_R_TYPE (rp->r_info));
9009 continue;
9010 }
a734115a
NC
9011
9012 if (streq (relname, "R_ARM_NONE"))
9013 continue;
0b4362b0 9014
a734115a
NC
9015 if (! streq (relname, "R_ARM_PREL31"))
9016 {
071436c6 9017 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9018 continue;
9019 }
9020 }
dda8d76d 9021 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9022 {
9023 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9024 if (relname == NULL)
9025 {
9026 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9027 (int) ELF32_R_TYPE (rp->r_info));
9028 continue;
9029 }
0b4362b0 9030
a734115a
NC
9031 if (streq (relname, "R_C6000_NONE"))
9032 continue;
9033
9034 if (! streq (relname, "R_C6000_PREL31"))
9035 {
071436c6 9036 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9037 continue;
9038 }
9039
9040 prelval >>= 1;
9041 }
9042 else
74e1a04b
NC
9043 {
9044 /* This function currently only supports ARM and TI unwinders. */
9045 warn (_("Only TI and ARM unwinders are currently supported\n"));
9046 break;
9047 }
fa197c1c 9048
0b6ae522
DJ
9049 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
9050 addr->section = sym->st_shndx;
9051 addr->offset = offset;
74e1a04b 9052
1b31d05e
NC
9053 if (sym_name)
9054 * sym_name = sym->st_name;
0b6ae522
DJ
9055 break;
9056 }
9057
9058 *wordp = word;
9059 arm_sec->next_rela = rp;
9060
015dc7e1 9061 return true;
0b6ae522
DJ
9062}
9063
a734115a
NC
9064static const char *tic6x_unwind_regnames[16] =
9065{
0b4362b0
RM
9066 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9067 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9068 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9069};
fa197c1c 9070
0b6ae522 9071static void
fa197c1c 9072decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9073{
fa197c1c
PB
9074 int i;
9075
9076 for (i = 12; mask; mask >>= 1, i--)
9077 {
9078 if (mask & 1)
9079 {
9080 fputs (tic6x_unwind_regnames[i], stdout);
9081 if (mask > 1)
9082 fputs (", ", stdout);
9083 }
9084 }
9085}
0b6ae522
DJ
9086
9087#define ADVANCE \
9088 if (remaining == 0 && more_words) \
9089 { \
9090 data_offset += 4; \
dda8d76d 9091 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9092 data_offset, & word, & addr, NULL)) \
015dc7e1 9093 return false; \
0b6ae522
DJ
9094 remaining = 4; \
9095 more_words--; \
9096 } \
9097
9098#define GET_OP(OP) \
9099 ADVANCE; \
9100 if (remaining) \
9101 { \
9102 remaining--; \
9103 (OP) = word >> 24; \
9104 word <<= 8; \
9105 } \
9106 else \
9107 { \
2b692964 9108 printf (_("[Truncated opcode]\n")); \
015dc7e1 9109 return false; \
0b6ae522 9110 } \
cc5914eb 9111 printf ("0x%02x ", OP)
0b6ae522 9112
015dc7e1 9113static bool
dda8d76d
NC
9114decode_arm_unwind_bytecode (Filedata * filedata,
9115 struct arm_unw_aux_info * aux,
948f632f
DA
9116 unsigned int word,
9117 unsigned int remaining,
9118 unsigned int more_words,
9119 bfd_vma data_offset,
9120 Elf_Internal_Shdr * data_sec,
9121 struct arm_section * data_arm_sec)
fa197c1c
PB
9122{
9123 struct absaddr addr;
015dc7e1 9124 bool res = true;
0b6ae522
DJ
9125
9126 /* Decode the unwinding instructions. */
9127 while (1)
9128 {
9129 unsigned int op, op2;
9130
9131 ADVANCE;
9132 if (remaining == 0)
9133 break;
9134 remaining--;
9135 op = word >> 24;
9136 word <<= 8;
9137
cc5914eb 9138 printf (" 0x%02x ", op);
0b6ae522
DJ
9139
9140 if ((op & 0xc0) == 0x00)
9141 {
9142 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9143
cc5914eb 9144 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9145 }
9146 else if ((op & 0xc0) == 0x40)
9147 {
9148 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9149
cc5914eb 9150 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9151 }
9152 else if ((op & 0xf0) == 0x80)
9153 {
9154 GET_OP (op2);
9155 if (op == 0x80 && op2 == 0)
9156 printf (_("Refuse to unwind"));
9157 else
9158 {
9159 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9160 bool first = true;
0b6ae522 9161 int i;
2b692964 9162
0b6ae522
DJ
9163 printf ("pop {");
9164 for (i = 0; i < 12; i++)
9165 if (mask & (1 << i))
9166 {
9167 if (first)
015dc7e1 9168 first = false;
0b6ae522
DJ
9169 else
9170 printf (", ");
9171 printf ("r%d", 4 + i);
9172 }
9173 printf ("}");
9174 }
9175 }
9176 else if ((op & 0xf0) == 0x90)
9177 {
9178 if (op == 0x9d || op == 0x9f)
9179 printf (_(" [Reserved]"));
9180 else
cc5914eb 9181 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9182 }
9183 else if ((op & 0xf0) == 0xa0)
9184 {
9185 int end = 4 + (op & 0x07);
015dc7e1 9186 bool first = true;
0b6ae522 9187 int i;
61865e30 9188
0b6ae522
DJ
9189 printf (" pop {");
9190 for (i = 4; i <= end; i++)
9191 {
9192 if (first)
015dc7e1 9193 first = false;
0b6ae522
DJ
9194 else
9195 printf (", ");
9196 printf ("r%d", i);
9197 }
9198 if (op & 0x08)
9199 {
1b31d05e 9200 if (!first)
0b6ae522
DJ
9201 printf (", ");
9202 printf ("r14");
9203 }
9204 printf ("}");
9205 }
9206 else if (op == 0xb0)
9207 printf (_(" finish"));
9208 else if (op == 0xb1)
9209 {
9210 GET_OP (op2);
9211 if (op2 == 0 || (op2 & 0xf0) != 0)
9212 printf (_("[Spare]"));
9213 else
9214 {
9215 unsigned int mask = op2 & 0x0f;
015dc7e1 9216 bool first = true;
0b6ae522 9217 int i;
61865e30 9218
0b6ae522
DJ
9219 printf ("pop {");
9220 for (i = 0; i < 12; i++)
9221 if (mask & (1 << i))
9222 {
9223 if (first)
015dc7e1 9224 first = false;
0b6ae522
DJ
9225 else
9226 printf (", ");
9227 printf ("r%d", i);
9228 }
9229 printf ("}");
9230 }
9231 }
9232 else if (op == 0xb2)
9233 {
b115cf96 9234 unsigned char buf[9];
0b6ae522
DJ
9235 unsigned int i, len;
9236 unsigned long offset;
61865e30 9237
b115cf96 9238 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9239 {
9240 GET_OP (buf[i]);
9241 if ((buf[i] & 0x80) == 0)
9242 break;
9243 }
4082ef84 9244 if (i == sizeof (buf))
32ec8896 9245 {
27a45f42 9246 error (_("corrupt change to vsp\n"));
015dc7e1 9247 res = false;
32ec8896 9248 }
4082ef84
NC
9249 else
9250 {
015dc7e1 9251 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9252 assert (len == i + 1);
9253 offset = offset * 4 + 0x204;
9254 printf ("vsp = vsp + %ld", offset);
9255 }
0b6ae522 9256 }
61865e30 9257 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9258 {
61865e30
NC
9259 unsigned int first, last;
9260
9261 GET_OP (op2);
9262 first = op2 >> 4;
9263 last = op2 & 0x0f;
9264 if (op == 0xc8)
9265 first = first + 16;
9266 printf ("pop {D%d", first);
9267 if (last)
9268 printf ("-D%d", first + last);
9269 printf ("}");
9270 }
9271 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9272 {
9273 unsigned int count = op & 0x07;
9274
9275 printf ("pop {D8");
9276 if (count)
9277 printf ("-D%d", 8 + count);
9278 printf ("}");
9279 }
9280 else if (op >= 0xc0 && op <= 0xc5)
9281 {
9282 unsigned int count = op & 0x07;
9283
9284 printf (" pop {wR10");
9285 if (count)
9286 printf ("-wR%d", 10 + count);
9287 printf ("}");
9288 }
9289 else if (op == 0xc6)
9290 {
9291 unsigned int first, last;
9292
9293 GET_OP (op2);
9294 first = op2 >> 4;
9295 last = op2 & 0x0f;
9296 printf ("pop {wR%d", first);
9297 if (last)
9298 printf ("-wR%d", first + last);
9299 printf ("}");
9300 }
9301 else if (op == 0xc7)
9302 {
9303 GET_OP (op2);
9304 if (op2 == 0 || (op2 & 0xf0) != 0)
9305 printf (_("[Spare]"));
0b6ae522
DJ
9306 else
9307 {
61865e30 9308 unsigned int mask = op2 & 0x0f;
015dc7e1 9309 bool first = true;
61865e30
NC
9310 int i;
9311
9312 printf ("pop {");
9313 for (i = 0; i < 4; i++)
9314 if (mask & (1 << i))
9315 {
9316 if (first)
015dc7e1 9317 first = false;
61865e30
NC
9318 else
9319 printf (", ");
9320 printf ("wCGR%d", i);
9321 }
9322 printf ("}");
0b6ae522
DJ
9323 }
9324 }
61865e30 9325 else
32ec8896
NC
9326 {
9327 printf (_(" [unsupported opcode]"));
015dc7e1 9328 res = false;
32ec8896
NC
9329 }
9330
0b6ae522
DJ
9331 printf ("\n");
9332 }
32ec8896
NC
9333
9334 return res;
fa197c1c
PB
9335}
9336
015dc7e1 9337static bool
dda8d76d
NC
9338decode_tic6x_unwind_bytecode (Filedata * filedata,
9339 struct arm_unw_aux_info * aux,
948f632f
DA
9340 unsigned int word,
9341 unsigned int remaining,
9342 unsigned int more_words,
9343 bfd_vma data_offset,
9344 Elf_Internal_Shdr * data_sec,
9345 struct arm_section * data_arm_sec)
fa197c1c
PB
9346{
9347 struct absaddr addr;
9348
9349 /* Decode the unwinding instructions. */
9350 while (1)
9351 {
9352 unsigned int op, op2;
9353
9354 ADVANCE;
9355 if (remaining == 0)
9356 break;
9357 remaining--;
9358 op = word >> 24;
9359 word <<= 8;
9360
9cf03b7e 9361 printf (" 0x%02x ", op);
fa197c1c
PB
9362
9363 if ((op & 0xc0) == 0x00)
9364 {
9365 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9366 printf (" sp = sp + %d", offset);
fa197c1c
PB
9367 }
9368 else if ((op & 0xc0) == 0x80)
9369 {
9370 GET_OP (op2);
9371 if (op == 0x80 && op2 == 0)
9372 printf (_("Refuse to unwind"));
9373 else
9374 {
9375 unsigned int mask = ((op & 0x1f) << 8) | op2;
9376 if (op & 0x20)
9377 printf ("pop compact {");
9378 else
9379 printf ("pop {");
9380
9381 decode_tic6x_unwind_regmask (mask);
9382 printf("}");
9383 }
9384 }
9385 else if ((op & 0xf0) == 0xc0)
9386 {
9387 unsigned int reg;
9388 unsigned int nregs;
9389 unsigned int i;
9390 const char *name;
a734115a
NC
9391 struct
9392 {
32ec8896
NC
9393 unsigned int offset;
9394 unsigned int reg;
fa197c1c
PB
9395 } regpos[16];
9396
9397 /* Scan entire instruction first so that GET_OP output is not
9398 interleaved with disassembly. */
9399 nregs = 0;
9400 for (i = 0; nregs < (op & 0xf); i++)
9401 {
9402 GET_OP (op2);
9403 reg = op2 >> 4;
9404 if (reg != 0xf)
9405 {
9406 regpos[nregs].offset = i * 2;
9407 regpos[nregs].reg = reg;
9408 nregs++;
9409 }
9410
9411 reg = op2 & 0xf;
9412 if (reg != 0xf)
9413 {
9414 regpos[nregs].offset = i * 2 + 1;
9415 regpos[nregs].reg = reg;
9416 nregs++;
9417 }
9418 }
9419
9420 printf (_("pop frame {"));
18344509 9421 if (nregs == 0)
fa197c1c 9422 {
18344509
NC
9423 printf (_("*corrupt* - no registers specified"));
9424 }
9425 else
9426 {
9427 reg = nregs - 1;
9428 for (i = i * 2; i > 0; i--)
fa197c1c 9429 {
18344509
NC
9430 if (regpos[reg].offset == i - 1)
9431 {
9432 name = tic6x_unwind_regnames[regpos[reg].reg];
9433 if (reg > 0)
9434 reg--;
9435 }
9436 else
9437 name = _("[pad]");
fa197c1c 9438
18344509
NC
9439 fputs (name, stdout);
9440 if (i > 1)
9441 printf (", ");
9442 }
fa197c1c
PB
9443 }
9444
9445 printf ("}");
9446 }
9447 else if (op == 0xd0)
9448 printf (" MOV FP, SP");
9449 else if (op == 0xd1)
9450 printf (" __c6xabi_pop_rts");
9451 else if (op == 0xd2)
9452 {
9453 unsigned char buf[9];
9454 unsigned int i, len;
9455 unsigned long offset;
a734115a 9456
fa197c1c
PB
9457 for (i = 0; i < sizeof (buf); i++)
9458 {
9459 GET_OP (buf[i]);
9460 if ((buf[i] & 0x80) == 0)
9461 break;
9462 }
0eff7165
NC
9463 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9464 if (i == sizeof (buf))
9465 {
0eff7165 9466 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 9467 return false;
0eff7165 9468 }
948f632f 9469
015dc7e1 9470 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
9471 assert (len == i + 1);
9472 offset = offset * 8 + 0x408;
9473 printf (_("sp = sp + %ld"), offset);
9474 }
9475 else if ((op & 0xf0) == 0xe0)
9476 {
9477 if ((op & 0x0f) == 7)
9478 printf (" RETURN");
9479 else
9480 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9481 }
9482 else
9483 {
9484 printf (_(" [unsupported opcode]"));
9485 }
9486 putchar ('\n');
9487 }
32ec8896 9488
015dc7e1 9489 return true;
fa197c1c
PB
9490}
9491
9492static bfd_vma
dda8d76d 9493arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9494{
9495 bfd_vma offset;
9496
9497 offset = word & 0x7fffffff;
9498 if (offset & 0x40000000)
9499 offset |= ~ (bfd_vma) 0x7fffffff;
9500
dda8d76d 9501 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9502 offset <<= 1;
9503
9504 return offset + where;
9505}
9506
015dc7e1 9507static bool
dda8d76d
NC
9508decode_arm_unwind (Filedata * filedata,
9509 struct arm_unw_aux_info * aux,
1b31d05e
NC
9510 unsigned int word,
9511 unsigned int remaining,
9512 bfd_vma data_offset,
9513 Elf_Internal_Shdr * data_sec,
9514 struct arm_section * data_arm_sec)
fa197c1c
PB
9515{
9516 int per_index;
9517 unsigned int more_words = 0;
37e14bc3 9518 struct absaddr addr;
1b31d05e 9519 bfd_vma sym_name = (bfd_vma) -1;
015dc7e1 9520 bool res = true;
fa197c1c
PB
9521
9522 if (remaining == 0)
9523 {
1b31d05e
NC
9524 /* Fetch the first word.
9525 Note - when decoding an object file the address extracted
9526 here will always be 0. So we also pass in the sym_name
9527 parameter so that we can find the symbol associated with
9528 the personality routine. */
dda8d76d 9529 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9530 & word, & addr, & sym_name))
015dc7e1 9531 return false;
1b31d05e 9532
fa197c1c
PB
9533 remaining = 4;
9534 }
c93dbb25
CZ
9535 else
9536 {
9537 addr.section = SHN_UNDEF;
9538 addr.offset = 0;
9539 }
fa197c1c
PB
9540
9541 if ((word & 0x80000000) == 0)
9542 {
9543 /* Expand prel31 for personality routine. */
9544 bfd_vma fn;
9545 const char *procname;
9546
dda8d76d 9547 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9548 printf (_(" Personality routine: "));
1b31d05e
NC
9549 if (fn == 0
9550 && addr.section == SHN_UNDEF && addr.offset == 0
9551 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9552 {
9553 procname = aux->strtab + sym_name;
9554 print_vma (fn, PREFIX_HEX);
9555 if (procname)
9556 {
9557 fputs (" <", stdout);
9558 fputs (procname, stdout);
9559 fputc ('>', stdout);
9560 }
9561 }
9562 else
dda8d76d 9563 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9564 fputc ('\n', stdout);
9565
9566 /* The GCC personality routines use the standard compact
9567 encoding, starting with one byte giving the number of
9568 words. */
9569 if (procname != NULL
24d127aa
ML
9570 && (startswith (procname, "__gcc_personality_v0")
9571 || startswith (procname, "__gxx_personality_v0")
9572 || startswith (procname, "__gcj_personality_v0")
9573 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
9574 {
9575 remaining = 0;
9576 more_words = 1;
9577 ADVANCE;
9578 if (!remaining)
9579 {
9580 printf (_(" [Truncated data]\n"));
015dc7e1 9581 return false;
fa197c1c
PB
9582 }
9583 more_words = word >> 24;
9584 word <<= 8;
9585 remaining--;
9586 per_index = -1;
9587 }
9588 else
015dc7e1 9589 return true;
fa197c1c
PB
9590 }
9591 else
9592 {
1b31d05e 9593 /* ARM EHABI Section 6.3:
0b4362b0 9594
1b31d05e 9595 An exception-handling table entry for the compact model looks like:
0b4362b0 9596
1b31d05e
NC
9597 31 30-28 27-24 23-0
9598 -- ----- ----- ----
9599 1 0 index Data for personalityRoutine[index] */
9600
dda8d76d 9601 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9602 && (word & 0x70000000))
32ec8896
NC
9603 {
9604 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 9605 res = false;
32ec8896 9606 }
1b31d05e 9607
fa197c1c 9608 per_index = (word >> 24) & 0x7f;
1b31d05e 9609 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9610 if (per_index == 0)
9611 {
9612 more_words = 0;
9613 word <<= 8;
9614 remaining--;
9615 }
9616 else if (per_index < 3)
9617 {
9618 more_words = (word >> 16) & 0xff;
9619 word <<= 16;
9620 remaining -= 2;
9621 }
9622 }
9623
dda8d76d 9624 switch (filedata->file_header.e_machine)
fa197c1c
PB
9625 {
9626 case EM_ARM:
9627 if (per_index < 3)
9628 {
dda8d76d 9629 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 9630 data_offset, data_sec, data_arm_sec))
015dc7e1 9631 res = false;
fa197c1c
PB
9632 }
9633 else
1b31d05e
NC
9634 {
9635 warn (_("Unknown ARM compact model index encountered\n"));
9636 printf (_(" [reserved]\n"));
015dc7e1 9637 res = false;
1b31d05e 9638 }
fa197c1c
PB
9639 break;
9640
9641 case EM_TI_C6000:
9642 if (per_index < 3)
9643 {
dda8d76d 9644 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 9645 data_offset, data_sec, data_arm_sec))
015dc7e1 9646 res = false;
fa197c1c
PB
9647 }
9648 else if (per_index < 5)
9649 {
9650 if (((word >> 17) & 0x7f) == 0x7f)
9651 printf (_(" Restore stack from frame pointer\n"));
9652 else
9653 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9654 printf (_(" Registers restored: "));
9655 if (per_index == 4)
9656 printf (" (compact) ");
9657 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9658 putchar ('\n');
9659 printf (_(" Return register: %s\n"),
9660 tic6x_unwind_regnames[word & 0xf]);
9661 }
9662 else
1b31d05e 9663 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9664 break;
9665
9666 default:
74e1a04b 9667 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9668 filedata->file_header.e_machine);
015dc7e1 9669 res = false;
fa197c1c 9670 }
0b6ae522
DJ
9671
9672 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9673
9674 return res;
0b6ae522
DJ
9675}
9676
015dc7e1 9677static bool
dda8d76d
NC
9678dump_arm_unwind (Filedata * filedata,
9679 struct arm_unw_aux_info * aux,
9680 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9681{
9682 struct arm_section exidx_arm_sec, extab_arm_sec;
9683 unsigned int i, exidx_len;
948f632f 9684 unsigned long j, nfuns;
015dc7e1 9685 bool res = true;
0b6ae522
DJ
9686
9687 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9688 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9689 exidx_len = exidx_sec->sh_size / 8;
9690
948f632f
DA
9691 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9692 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9693 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9694 aux->funtab[nfuns++] = aux->symtab[j];
9695 aux->nfuns = nfuns;
9696 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9697
0b6ae522
DJ
9698 for (i = 0; i < exidx_len; i++)
9699 {
9700 unsigned int exidx_fn, exidx_entry;
9701 struct absaddr fn_addr, entry_addr;
9702 bfd_vma fn;
9703
9704 fputc ('\n', stdout);
9705
dda8d76d 9706 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9707 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9708 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9709 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9710 {
948f632f 9711 free (aux->funtab);
1b31d05e
NC
9712 arm_free_section (& exidx_arm_sec);
9713 arm_free_section (& extab_arm_sec);
015dc7e1 9714 return false;
0b6ae522
DJ
9715 }
9716
83c257ca
NC
9717 /* ARM EHABI, Section 5:
9718 An index table entry consists of 2 words.
9719 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9720 if (exidx_fn & 0x80000000)
32ec8896
NC
9721 {
9722 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 9723 res = false;
32ec8896 9724 }
83c257ca 9725
dda8d76d 9726 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9727
dda8d76d 9728 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9729 fputs (": ", stdout);
9730
9731 if (exidx_entry == 1)
9732 {
9733 print_vma (exidx_entry, PREFIX_HEX);
9734 fputs (" [cantunwind]\n", stdout);
9735 }
9736 else if (exidx_entry & 0x80000000)
9737 {
9738 print_vma (exidx_entry, PREFIX_HEX);
9739 fputc ('\n', stdout);
dda8d76d 9740 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9741 }
9742 else
9743 {
8f73510c 9744 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9745 Elf_Internal_Shdr *table_sec;
9746
9747 fputs ("@", stdout);
dda8d76d 9748 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9749 print_vma (table, PREFIX_HEX);
9750 printf ("\n");
9751
9752 /* Locate the matching .ARM.extab. */
9753 if (entry_addr.section != SHN_UNDEF
dda8d76d 9754 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9755 {
dda8d76d 9756 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9757 table_offset = entry_addr.offset;
1a915552
NC
9758 /* PR 18879 */
9759 if (table_offset > table_sec->sh_size
9760 || ((bfd_signed_vma) table_offset) < 0)
9761 {
9762 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9763 (unsigned long) table_offset,
dda8d76d 9764 printable_section_name (filedata, table_sec));
015dc7e1 9765 res = false;
1a915552
NC
9766 continue;
9767 }
0b6ae522
DJ
9768 }
9769 else
9770 {
dda8d76d 9771 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9772 if (table_sec != NULL)
9773 table_offset = table - table_sec->sh_addr;
9774 }
32ec8896 9775
0b6ae522
DJ
9776 if (table_sec == NULL)
9777 {
9778 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9779 (unsigned long) table);
015dc7e1 9780 res = false;
0b6ae522
DJ
9781 continue;
9782 }
32ec8896 9783
dda8d76d 9784 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 9785 &extab_arm_sec))
015dc7e1 9786 res = false;
0b6ae522
DJ
9787 }
9788 }
9789
9790 printf ("\n");
9791
948f632f 9792 free (aux->funtab);
0b6ae522
DJ
9793 arm_free_section (&exidx_arm_sec);
9794 arm_free_section (&extab_arm_sec);
32ec8896
NC
9795
9796 return res;
0b6ae522
DJ
9797}
9798
fa197c1c 9799/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9800
015dc7e1 9801static bool
dda8d76d 9802arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9803{
9804 struct arm_unw_aux_info aux;
9805 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9806 Elf_Internal_Shdr *sec;
9807 unsigned long i;
fa197c1c 9808 unsigned int sec_type;
015dc7e1 9809 bool res = true;
0b6ae522 9810
dda8d76d 9811 switch (filedata->file_header.e_machine)
fa197c1c
PB
9812 {
9813 case EM_ARM:
9814 sec_type = SHT_ARM_EXIDX;
9815 break;
9816
9817 case EM_TI_C6000:
9818 sec_type = SHT_C6000_UNWIND;
9819 break;
9820
0b4362b0 9821 default:
74e1a04b 9822 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9823 filedata->file_header.e_machine);
015dc7e1 9824 return false;
fa197c1c
PB
9825 }
9826
dda8d76d 9827 if (filedata->string_table == NULL)
015dc7e1 9828 return false;
1b31d05e
NC
9829
9830 memset (& aux, 0, sizeof (aux));
dda8d76d 9831 aux.filedata = filedata;
0b6ae522 9832
dda8d76d 9833 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9834 {
28d13567 9835 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9836 {
28d13567 9837 if (aux.symtab)
74e1a04b 9838 {
28d13567
AM
9839 error (_("Multiple symbol tables encountered\n"));
9840 free (aux.symtab);
9841 aux.symtab = NULL;
74e1a04b 9842 free (aux.strtab);
28d13567 9843 aux.strtab = NULL;
74e1a04b 9844 }
28d13567
AM
9845 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9846 &aux.strtab, &aux.strtab_size))
015dc7e1 9847 return false;
0b6ae522 9848 }
fa197c1c 9849 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9850 unwsec = sec;
9851 }
9852
1b31d05e 9853 if (unwsec == NULL)
0b6ae522 9854 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9855 else
dda8d76d 9856 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9857 {
9858 if (sec->sh_type == sec_type)
9859 {
d3a49aa8
AM
9860 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9861 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9862 "contains %lu entry:\n",
9863 "\nUnwind section '%s' at offset 0x%lx "
9864 "contains %lu entries:\n",
9865 num_unwind),
dda8d76d 9866 printable_section_name (filedata, sec),
1b31d05e 9867 (unsigned long) sec->sh_offset,
d3a49aa8 9868 num_unwind);
0b6ae522 9869
dda8d76d 9870 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 9871 res = false;
1b31d05e
NC
9872 }
9873 }
0b6ae522 9874
9db70fc3
AM
9875 free (aux.symtab);
9876 free ((char *) aux.strtab);
32ec8896
NC
9877
9878 return res;
0b6ae522
DJ
9879}
9880
3ecc00ec
NC
9881static bool
9882no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
9883{
9884 printf (_("No processor specific unwind information to decode\n"));
9885 return true;
9886}
9887
015dc7e1 9888static bool
dda8d76d 9889process_unwind (Filedata * filedata)
57346661 9890{
2cf0635d
NC
9891 struct unwind_handler
9892 {
32ec8896 9893 unsigned int machtype;
015dc7e1 9894 bool (* handler)(Filedata *);
2cf0635d
NC
9895 } handlers[] =
9896 {
0b6ae522 9897 { EM_ARM, arm_process_unwind },
57346661
AM
9898 { EM_IA_64, ia64_process_unwind },
9899 { EM_PARISC, hppa_process_unwind },
fa197c1c 9900 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
9901 { EM_386, no_processor_specific_unwind },
9902 { EM_X86_64, no_processor_specific_unwind },
32ec8896 9903 { 0, NULL }
57346661
AM
9904 };
9905 int i;
9906
9907 if (!do_unwind)
015dc7e1 9908 return true;
57346661
AM
9909
9910 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9911 if (filedata->file_header.e_machine == handlers[i].machtype)
9912 return handlers[i].handler (filedata);
57346661 9913
1b31d05e 9914 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9915 get_machine_name (filedata->file_header.e_machine));
015dc7e1 9916 return true;
57346661
AM
9917}
9918
37c18eed
SD
9919static void
9920dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
9921{
9922 switch (entry->d_tag)
9923 {
9924 case DT_AARCH64_BTI_PLT:
1dbade74 9925 case DT_AARCH64_PAC_PLT:
37c18eed
SD
9926 break;
9927 default:
9928 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9929 break;
9930 }
9931 putchar ('\n');
9932}
9933
252b5132 9934static void
978c4450 9935dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
9936{
9937 switch (entry->d_tag)
9938 {
9939 case DT_MIPS_FLAGS:
9940 if (entry->d_un.d_val == 0)
4b68bca3 9941 printf (_("NONE"));
252b5132
RH
9942 else
9943 {
9944 static const char * opts[] =
9945 {
9946 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9947 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9948 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9949 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9950 "RLD_ORDER_SAFE"
9951 };
9952 unsigned int cnt;
015dc7e1 9953 bool first = true;
2b692964 9954
60bca95a 9955 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9956 if (entry->d_un.d_val & (1 << cnt))
9957 {
9958 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 9959 first = false;
252b5132 9960 }
252b5132
RH
9961 }
9962 break;
103f02d3 9963
252b5132 9964 case DT_MIPS_IVERSION:
978c4450
AM
9965 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
9966 printf (_("Interface Version: %s"),
9967 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 9968 else
76ca31c0
NC
9969 {
9970 char buf[40];
9971 sprintf_vma (buf, entry->d_un.d_ptr);
9972 /* Note: coded this way so that there is a single string for translation. */
9973 printf (_("<corrupt: %s>"), buf);
9974 }
252b5132 9975 break;
103f02d3 9976
252b5132
RH
9977 case DT_MIPS_TIME_STAMP:
9978 {
d5b07ef4 9979 char timebuf[128];
2cf0635d 9980 struct tm * tmp;
91d6fa6a 9981 time_t atime = entry->d_un.d_val;
82b1b41b 9982
91d6fa6a 9983 tmp = gmtime (&atime);
82b1b41b
NC
9984 /* PR 17531: file: 6accc532. */
9985 if (tmp == NULL)
9986 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9987 else
9988 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9989 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9990 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9991 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9992 }
9993 break;
103f02d3 9994
252b5132
RH
9995 case DT_MIPS_RLD_VERSION:
9996 case DT_MIPS_LOCAL_GOTNO:
9997 case DT_MIPS_CONFLICTNO:
9998 case DT_MIPS_LIBLISTNO:
9999 case DT_MIPS_SYMTABNO:
10000 case DT_MIPS_UNREFEXTNO:
10001 case DT_MIPS_HIPAGENO:
10002 case DT_MIPS_DELTA_CLASS_NO:
10003 case DT_MIPS_DELTA_INSTANCE_NO:
10004 case DT_MIPS_DELTA_RELOC_NO:
10005 case DT_MIPS_DELTA_SYM_NO:
10006 case DT_MIPS_DELTA_CLASSSYM_NO:
10007 case DT_MIPS_COMPACT_SIZE:
c69075ac 10008 print_vma (entry->d_un.d_val, DEC);
252b5132 10009 break;
103f02d3 10010
f16a9783 10011 case DT_MIPS_XHASH:
978c4450
AM
10012 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10013 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10014 /* Falls through. */
10015
103f02d3 10016 default:
4b68bca3 10017 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10018 }
4b68bca3 10019 putchar ('\n');
103f02d3
UD
10020}
10021
103f02d3 10022static void
2cf0635d 10023dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10024{
10025 switch (entry->d_tag)
10026 {
10027 case DT_HP_DLD_FLAGS:
10028 {
10029 static struct
10030 {
10031 long int bit;
2cf0635d 10032 const char * str;
5e220199
NC
10033 }
10034 flags[] =
10035 {
10036 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10037 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10038 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10039 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10040 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10041 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10042 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10043 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10044 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10045 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10046 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10047 { DT_HP_GST, "HP_GST" },
10048 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10049 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10050 { DT_HP_NODELETE, "HP_NODELETE" },
10051 { DT_HP_GROUP, "HP_GROUP" },
10052 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10053 };
015dc7e1 10054 bool first = true;
5e220199 10055 size_t cnt;
f7a99963 10056 bfd_vma val = entry->d_un.d_val;
103f02d3 10057
60bca95a 10058 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10059 if (val & flags[cnt].bit)
30800947
NC
10060 {
10061 if (! first)
10062 putchar (' ');
10063 fputs (flags[cnt].str, stdout);
015dc7e1 10064 first = false;
30800947
NC
10065 val ^= flags[cnt].bit;
10066 }
76da6bbe 10067
103f02d3 10068 if (val != 0 || first)
f7a99963
NC
10069 {
10070 if (! first)
10071 putchar (' ');
10072 print_vma (val, HEX);
10073 }
103f02d3
UD
10074 }
10075 break;
76da6bbe 10076
252b5132 10077 default:
f7a99963
NC
10078 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10079 break;
252b5132 10080 }
35b1837e 10081 putchar ('\n');
252b5132
RH
10082}
10083
28f997cf
TG
10084#ifdef BFD64
10085
10086/* VMS vs Unix time offset and factor. */
10087
10088#define VMS_EPOCH_OFFSET 35067168000000000LL
10089#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10090#ifndef INT64_MIN
10091#define INT64_MIN (-9223372036854775807LL - 1)
10092#endif
28f997cf
TG
10093
10094/* Display a VMS time in a human readable format. */
10095
10096static void
10097print_vms_time (bfd_int64_t vmstime)
10098{
dccc31de 10099 struct tm *tm = NULL;
28f997cf
TG
10100 time_t unxtime;
10101
dccc31de
AM
10102 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10103 {
10104 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10105 unxtime = vmstime;
10106 if (unxtime == vmstime)
10107 tm = gmtime (&unxtime);
10108 }
10109 if (tm != NULL)
10110 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10111 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10112 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
10113}
10114#endif /* BFD64 */
10115
ecc51f48 10116static void
2cf0635d 10117dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10118{
10119 switch (entry->d_tag)
10120 {
0de14b54 10121 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10122 /* First 3 slots reserved. */
ecc51f48
NC
10123 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10124 printf (" -- ");
10125 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10126 break;
10127
28f997cf
TG
10128 case DT_IA_64_VMS_LINKTIME:
10129#ifdef BFD64
10130 print_vms_time (entry->d_un.d_val);
10131#endif
10132 break;
10133
10134 case DT_IA_64_VMS_LNKFLAGS:
10135 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10136 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10137 printf (" CALL_DEBUG");
10138 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10139 printf (" NOP0BUFS");
10140 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10141 printf (" P0IMAGE");
10142 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10143 printf (" MKTHREADS");
10144 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10145 printf (" UPCALLS");
10146 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10147 printf (" IMGSTA");
10148 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10149 printf (" INITIALIZE");
10150 if (entry->d_un.d_val & VMS_LF_MAIN)
10151 printf (" MAIN");
10152 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10153 printf (" EXE_INIT");
10154 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10155 printf (" TBK_IN_IMG");
10156 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10157 printf (" DBG_IN_IMG");
10158 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10159 printf (" TBK_IN_DSF");
10160 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10161 printf (" DBG_IN_DSF");
10162 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10163 printf (" SIGNATURES");
10164 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10165 printf (" REL_SEG_OFF");
10166 break;
10167
bdf4d63a
JJ
10168 default:
10169 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10170 break;
ecc51f48 10171 }
bdf4d63a 10172 putchar ('\n');
ecc51f48
NC
10173}
10174
015dc7e1 10175static bool
dda8d76d 10176get_32bit_dynamic_section (Filedata * filedata)
252b5132 10177{
2cf0635d
NC
10178 Elf32_External_Dyn * edyn;
10179 Elf32_External_Dyn * ext;
10180 Elf_Internal_Dyn * entry;
103f02d3 10181
978c4450
AM
10182 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10183 filedata->dynamic_addr, 1,
10184 filedata->dynamic_size,
10185 _("dynamic section"));
a6e9f9df 10186 if (!edyn)
015dc7e1 10187 return false;
103f02d3 10188
071436c6
NC
10189 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10190 might not have the luxury of section headers. Look for the DT_NULL
10191 terminator to determine the number of entries. */
978c4450
AM
10192 for (ext = edyn, filedata->dynamic_nent = 0;
10193 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10194 ext++)
10195 {
978c4450 10196 filedata->dynamic_nent++;
ba2685cc
AM
10197 if (BYTE_GET (ext->d_tag) == DT_NULL)
10198 break;
10199 }
252b5132 10200
978c4450
AM
10201 filedata->dynamic_section
10202 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10203 if (filedata->dynamic_section == NULL)
252b5132 10204 {
8b73c356 10205 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10206 (unsigned long) filedata->dynamic_nent);
9ea033b2 10207 free (edyn);
015dc7e1 10208 return false;
9ea033b2 10209 }
252b5132 10210
978c4450
AM
10211 for (ext = edyn, entry = filedata->dynamic_section;
10212 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10213 ext++, entry++)
9ea033b2 10214 {
fb514b26
AM
10215 entry->d_tag = BYTE_GET (ext->d_tag);
10216 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10217 }
10218
9ea033b2
NC
10219 free (edyn);
10220
015dc7e1 10221 return true;
9ea033b2
NC
10222}
10223
015dc7e1 10224static bool
dda8d76d 10225get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10226{
2cf0635d
NC
10227 Elf64_External_Dyn * edyn;
10228 Elf64_External_Dyn * ext;
10229 Elf_Internal_Dyn * entry;
103f02d3 10230
071436c6 10231 /* Read in the data. */
978c4450
AM
10232 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10233 filedata->dynamic_addr, 1,
10234 filedata->dynamic_size,
10235 _("dynamic section"));
a6e9f9df 10236 if (!edyn)
015dc7e1 10237 return false;
103f02d3 10238
071436c6
NC
10239 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10240 might not have the luxury of section headers. Look for the DT_NULL
10241 terminator to determine the number of entries. */
978c4450 10242 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10243 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10244 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10245 ext++)
10246 {
978c4450 10247 filedata->dynamic_nent++;
66543521 10248 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10249 break;
10250 }
252b5132 10251
978c4450
AM
10252 filedata->dynamic_section
10253 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10254 if (filedata->dynamic_section == NULL)
252b5132 10255 {
8b73c356 10256 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10257 (unsigned long) filedata->dynamic_nent);
252b5132 10258 free (edyn);
015dc7e1 10259 return false;
252b5132
RH
10260 }
10261
071436c6 10262 /* Convert from external to internal formats. */
978c4450
AM
10263 for (ext = edyn, entry = filedata->dynamic_section;
10264 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10265 ext++, entry++)
252b5132 10266 {
66543521
AM
10267 entry->d_tag = BYTE_GET (ext->d_tag);
10268 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10269 }
10270
10271 free (edyn);
10272
015dc7e1 10273 return true;
9ea033b2
NC
10274}
10275
4de91c10
AM
10276static bool
10277get_dynamic_section (Filedata *filedata)
10278{
10279 if (filedata->dynamic_section)
10280 return true;
10281
10282 if (is_32bit_elf)
10283 return get_32bit_dynamic_section (filedata);
10284 else
10285 return get_64bit_dynamic_section (filedata);
10286}
10287
e9e44622
JJ
10288static void
10289print_dynamic_flags (bfd_vma flags)
d1133906 10290{
015dc7e1 10291 bool first = true;
13ae64f3 10292
d1133906
NC
10293 while (flags)
10294 {
10295 bfd_vma flag;
10296
10297 flag = flags & - flags;
10298 flags &= ~ flag;
10299
e9e44622 10300 if (first)
015dc7e1 10301 first = false;
e9e44622
JJ
10302 else
10303 putc (' ', stdout);
13ae64f3 10304
d1133906
NC
10305 switch (flag)
10306 {
e9e44622
JJ
10307 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10308 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10309 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10310 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10311 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10312 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10313 }
10314 }
e9e44622 10315 puts ("");
d1133906
NC
10316}
10317
10ca4b04
L
10318static bfd_vma *
10319get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10320{
10321 unsigned char * e_data;
10322 bfd_vma * i_data;
10323
10324 /* If the size_t type is smaller than the bfd_size_type, eg because
10325 you are building a 32-bit tool on a 64-bit host, then make sure
10326 that when (number) is cast to (size_t) no information is lost. */
10327 if (sizeof (size_t) < sizeof (bfd_size_type)
10328 && (bfd_size_type) ((size_t) number) != number)
10329 {
10330 error (_("Size truncation prevents reading %s elements of size %u\n"),
10331 bfd_vmatoa ("u", number), ent_size);
10332 return NULL;
10333 }
10334
10335 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10336 attempting to allocate memory when the read is bound to fail. */
10337 if (ent_size * number > filedata->file_size)
10338 {
10339 error (_("Invalid number of dynamic entries: %s\n"),
10340 bfd_vmatoa ("u", number));
10341 return NULL;
10342 }
10343
10344 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10345 if (e_data == NULL)
10346 {
10347 error (_("Out of memory reading %s dynamic entries\n"),
10348 bfd_vmatoa ("u", number));
10349 return NULL;
10350 }
10351
10352 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10353 {
10354 error (_("Unable to read in %s bytes of dynamic data\n"),
10355 bfd_vmatoa ("u", number * ent_size));
10356 free (e_data);
10357 return NULL;
10358 }
10359
10360 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10361 if (i_data == NULL)
10362 {
10363 error (_("Out of memory allocating space for %s dynamic entries\n"),
10364 bfd_vmatoa ("u", number));
10365 free (e_data);
10366 return NULL;
10367 }
10368
10369 while (number--)
10370 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10371
10372 free (e_data);
10373
10374 return i_data;
10375}
10376
10377static unsigned long
10378get_num_dynamic_syms (Filedata * filedata)
10379{
10380 unsigned long num_of_syms = 0;
10381
10382 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10383 return num_of_syms;
10384
978c4450 10385 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10386 {
10387 unsigned char nb[8];
10388 unsigned char nc[8];
10389 unsigned int hash_ent_size = 4;
10390
10391 if ((filedata->file_header.e_machine == EM_ALPHA
10392 || filedata->file_header.e_machine == EM_S390
10393 || filedata->file_header.e_machine == EM_S390_OLD)
10394 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10395 hash_ent_size = 8;
10396
10397 if (fseek (filedata->handle,
978c4450
AM
10398 (filedata->archive_file_offset
10399 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10400 sizeof nb + sizeof nc)),
10401 SEEK_SET))
10402 {
10403 error (_("Unable to seek to start of dynamic information\n"));
10404 goto no_hash;
10405 }
10406
10407 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10408 {
10409 error (_("Failed to read in number of buckets\n"));
10410 goto no_hash;
10411 }
10412
10413 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10414 {
10415 error (_("Failed to read in number of chains\n"));
10416 goto no_hash;
10417 }
10418
978c4450
AM
10419 filedata->nbuckets = byte_get (nb, hash_ent_size);
10420 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10421
2482f306
AM
10422 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10423 {
10424 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10425 hash_ent_size);
10426 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10427 hash_ent_size);
001890e1 10428
2482f306
AM
10429 if (filedata->buckets != NULL && filedata->chains != NULL)
10430 num_of_syms = filedata->nchains;
10431 }
ceb9bf11 10432 no_hash:
10ca4b04
L
10433 if (num_of_syms == 0)
10434 {
9db70fc3
AM
10435 free (filedata->buckets);
10436 filedata->buckets = NULL;
10437 free (filedata->chains);
10438 filedata->chains = NULL;
978c4450 10439 filedata->nbuckets = 0;
10ca4b04
L
10440 }
10441 }
10442
978c4450 10443 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10444 {
10445 unsigned char nb[16];
10446 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10447 bfd_vma buckets_vma;
10448 unsigned long hn;
10ca4b04
L
10449
10450 if (fseek (filedata->handle,
978c4450
AM
10451 (filedata->archive_file_offset
10452 + offset_from_vma (filedata,
10453 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10454 sizeof nb)),
10455 SEEK_SET))
10456 {
10457 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10458 goto no_gnu_hash;
10459 }
10460
10461 if (fread (nb, 16, 1, filedata->handle) != 1)
10462 {
10463 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10464 goto no_gnu_hash;
10465 }
10466
978c4450
AM
10467 filedata->ngnubuckets = byte_get (nb, 4);
10468 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10469 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10470 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10471 if (is_32bit_elf)
10472 buckets_vma += bitmaskwords * 4;
10473 else
10474 buckets_vma += bitmaskwords * 8;
10475
10476 if (fseek (filedata->handle,
978c4450 10477 (filedata->archive_file_offset
10ca4b04
L
10478 + offset_from_vma (filedata, buckets_vma, 4)),
10479 SEEK_SET))
10480 {
10481 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10482 goto no_gnu_hash;
10483 }
10484
978c4450
AM
10485 filedata->gnubuckets
10486 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10487
978c4450 10488 if (filedata->gnubuckets == NULL)
90837ea7 10489 goto no_gnu_hash;
10ca4b04 10490
978c4450
AM
10491 for (i = 0; i < filedata->ngnubuckets; i++)
10492 if (filedata->gnubuckets[i] != 0)
10ca4b04 10493 {
978c4450 10494 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10495 goto no_gnu_hash;
10ca4b04 10496
978c4450
AM
10497 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10498 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10499 }
10500
10501 if (maxchain == 0xffffffff)
90837ea7 10502 goto no_gnu_hash;
10ca4b04 10503
978c4450 10504 maxchain -= filedata->gnusymidx;
10ca4b04
L
10505
10506 if (fseek (filedata->handle,
978c4450
AM
10507 (filedata->archive_file_offset
10508 + offset_from_vma (filedata,
10509 buckets_vma + 4 * (filedata->ngnubuckets
10510 + maxchain),
10511 4)),
10ca4b04
L
10512 SEEK_SET))
10513 {
10514 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10515 goto no_gnu_hash;
10516 }
10517
10518 do
10519 {
10520 if (fread (nb, 4, 1, filedata->handle) != 1)
10521 {
10522 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10523 goto no_gnu_hash;
10524 }
10525
10526 if (maxchain + 1 == 0)
90837ea7 10527 goto no_gnu_hash;
10ca4b04
L
10528
10529 ++maxchain;
10530 }
10531 while ((byte_get (nb, 4) & 1) == 0);
10532
10533 if (fseek (filedata->handle,
978c4450
AM
10534 (filedata->archive_file_offset
10535 + offset_from_vma (filedata, (buckets_vma
10536 + 4 * filedata->ngnubuckets),
10537 4)),
10ca4b04
L
10538 SEEK_SET))
10539 {
10540 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10541 goto no_gnu_hash;
10542 }
10543
978c4450
AM
10544 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10545 filedata->ngnuchains = maxchain;
10ca4b04 10546
978c4450 10547 if (filedata->gnuchains == NULL)
90837ea7 10548 goto no_gnu_hash;
10ca4b04 10549
978c4450 10550 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10551 {
10552 if (fseek (filedata->handle,
978c4450 10553 (filedata->archive_file_offset
10ca4b04 10554 + offset_from_vma (filedata, (buckets_vma
978c4450 10555 + 4 * (filedata->ngnubuckets
10ca4b04
L
10556 + maxchain)), 4)),
10557 SEEK_SET))
10558 {
10559 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10560 goto no_gnu_hash;
10561 }
10562
978c4450 10563 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10564 if (filedata->mipsxlat == NULL)
10565 goto no_gnu_hash;
10ca4b04
L
10566 }
10567
978c4450
AM
10568 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10569 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10570 {
978c4450
AM
10571 bfd_vma si = filedata->gnubuckets[hn];
10572 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10573
10574 do
10575 {
978c4450 10576 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 10577 {
c31ab5a0
AM
10578 if (off < filedata->ngnuchains
10579 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 10580 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
10581 }
10582 else
10583 {
10584 if (si >= num_of_syms)
10585 num_of_syms = si + 1;
10586 }
10587 si++;
10588 }
978c4450
AM
10589 while (off < filedata->ngnuchains
10590 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
10591 }
10592
90837ea7 10593 if (num_of_syms == 0)
10ca4b04 10594 {
90837ea7 10595 no_gnu_hash:
9db70fc3
AM
10596 free (filedata->mipsxlat);
10597 filedata->mipsxlat = NULL;
10598 free (filedata->gnuchains);
10599 filedata->gnuchains = NULL;
10600 free (filedata->gnubuckets);
10601 filedata->gnubuckets = NULL;
978c4450
AM
10602 filedata->ngnubuckets = 0;
10603 filedata->ngnuchains = 0;
10ca4b04
L
10604 }
10605 }
10606
10607 return num_of_syms;
10608}
10609
b2d38a17
NC
10610/* Parse and display the contents of the dynamic section. */
10611
015dc7e1 10612static bool
dda8d76d 10613process_dynamic_section (Filedata * filedata)
9ea033b2 10614{
2cf0635d 10615 Elf_Internal_Dyn * entry;
9ea033b2 10616
978c4450 10617 if (filedata->dynamic_size == 0)
9ea033b2
NC
10618 {
10619 if (do_dynamic)
ca0e11aa
NC
10620 {
10621 if (filedata->is_separate)
10622 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
10623 filedata->file_name);
10624 else
10625 printf (_("\nThere is no dynamic section in this file.\n"));
10626 }
9ea033b2 10627
015dc7e1 10628 return true;
9ea033b2
NC
10629 }
10630
4de91c10
AM
10631 if (!get_dynamic_section (filedata))
10632 return false;
9ea033b2 10633
252b5132 10634 /* Find the appropriate symbol table. */
978c4450 10635 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 10636 {
2482f306
AM
10637 unsigned long num_of_syms;
10638
978c4450
AM
10639 for (entry = filedata->dynamic_section;
10640 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10641 ++entry)
10ca4b04 10642 if (entry->d_tag == DT_SYMTAB)
978c4450 10643 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 10644 else if (entry->d_tag == DT_SYMENT)
978c4450 10645 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 10646 else if (entry->d_tag == DT_HASH)
978c4450 10647 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 10648 else if (entry->d_tag == DT_GNU_HASH)
978c4450 10649 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
10650 else if ((filedata->file_header.e_machine == EM_MIPS
10651 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10652 && entry->d_tag == DT_MIPS_XHASH)
10653 {
978c4450
AM
10654 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10655 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 10656 }
252b5132 10657
2482f306
AM
10658 num_of_syms = get_num_dynamic_syms (filedata);
10659
10660 if (num_of_syms != 0
10661 && filedata->dynamic_symbols == NULL
10662 && filedata->dynamic_info[DT_SYMTAB]
978c4450 10663 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
10664 {
10665 Elf_Internal_Phdr *seg;
2482f306 10666 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 10667
2482f306
AM
10668 if (! get_program_headers (filedata))
10669 {
10670 error (_("Cannot interpret virtual addresses "
10671 "without program headers.\n"));
015dc7e1 10672 return false;
2482f306 10673 }
252b5132 10674
2482f306
AM
10675 for (seg = filedata->program_headers;
10676 seg < filedata->program_headers + filedata->file_header.e_phnum;
10677 ++seg)
10678 {
10679 if (seg->p_type != PT_LOAD)
10680 continue;
252b5132 10681
2482f306
AM
10682 if (seg->p_offset + seg->p_filesz > filedata->file_size)
10683 {
10684 /* See PR 21379 for a reproducer. */
10685 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 10686 return false;
2482f306 10687 }
252b5132 10688
2482f306
AM
10689 if (vma >= (seg->p_vaddr & -seg->p_align)
10690 && vma < seg->p_vaddr + seg->p_filesz)
10691 {
10692 /* Since we do not know how big the symbol table is,
10693 we default to reading in up to the end of PT_LOAD
10694 segment and processing that. This is overkill, I
10695 know, but it should work. */
10696 Elf_Internal_Shdr section;
10697 section.sh_offset = (vma - seg->p_vaddr
10698 + seg->p_offset);
10699 section.sh_size = (num_of_syms
10700 * filedata->dynamic_info[DT_SYMENT]);
10701 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
10702
10703 if (do_checks
10704 && filedata->dynamic_symtab_section != NULL
10705 && ((filedata->dynamic_symtab_section->sh_offset
10706 != section.sh_offset)
10707 || (filedata->dynamic_symtab_section->sh_size
10708 != section.sh_size)
10709 || (filedata->dynamic_symtab_section->sh_entsize
10710 != section.sh_entsize)))
10711 warn (_("\
10712the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
10713
2482f306
AM
10714 section.sh_name = filedata->string_table_length;
10715 filedata->dynamic_symbols
4de91c10 10716 = get_elf_symbols (filedata, &section,
2482f306
AM
10717 &filedata->num_dynamic_syms);
10718 if (filedata->dynamic_symbols == NULL
10719 || filedata->num_dynamic_syms != num_of_syms)
10720 {
10721 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 10722 return false;
2482f306
AM
10723 }
10724 break;
10725 }
10726 }
10727 }
10728 }
252b5132
RH
10729
10730 /* Similarly find a string table. */
978c4450
AM
10731 if (filedata->dynamic_strings == NULL)
10732 for (entry = filedata->dynamic_section;
10733 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
10734 ++entry)
10735 {
10736 if (entry->d_tag == DT_STRTAB)
978c4450 10737 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 10738
10ca4b04 10739 if (entry->d_tag == DT_STRSZ)
978c4450 10740 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10741
978c4450
AM
10742 if (filedata->dynamic_info[DT_STRTAB]
10743 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
10744 {
10745 unsigned long offset;
978c4450 10746 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
10747
10748 offset = offset_from_vma (filedata,
978c4450 10749 filedata->dynamic_info[DT_STRTAB],
10ca4b04 10750 str_tab_len);
8ac10c5b
L
10751 if (do_checks
10752 && filedata->dynamic_strtab_section
10753 && ((filedata->dynamic_strtab_section->sh_offset
10754 != (file_ptr) offset)
10755 || (filedata->dynamic_strtab_section->sh_size
10756 != str_tab_len)))
10757 warn (_("\
10758the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
10759
978c4450
AM
10760 filedata->dynamic_strings
10761 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
10762 _("dynamic string table"));
10763 if (filedata->dynamic_strings == NULL)
10ca4b04
L
10764 {
10765 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10766 break;
10767 }
e3d39609 10768
978c4450 10769 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
10770 break;
10771 }
10772 }
252b5132
RH
10773
10774 /* And find the syminfo section if available. */
978c4450 10775 if (filedata->dynamic_syminfo == NULL)
252b5132 10776 {
3e8bba36 10777 unsigned long syminsz = 0;
252b5132 10778
978c4450
AM
10779 for (entry = filedata->dynamic_section;
10780 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10781 ++entry)
252b5132
RH
10782 {
10783 if (entry->d_tag == DT_SYMINENT)
10784 {
10785 /* Note: these braces are necessary to avoid a syntax
10786 error from the SunOS4 C compiler. */
049b0c3a
NC
10787 /* PR binutils/17531: A corrupt file can trigger this test.
10788 So do not use an assert, instead generate an error message. */
10789 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10790 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10791 (int) entry->d_un.d_val);
252b5132
RH
10792 }
10793 else if (entry->d_tag == DT_SYMINSZ)
10794 syminsz = entry->d_un.d_val;
10795 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
10796 filedata->dynamic_syminfo_offset
10797 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
10798 }
10799
978c4450 10800 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 10801 {
2cf0635d
NC
10802 Elf_External_Syminfo * extsyminfo;
10803 Elf_External_Syminfo * extsym;
10804 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10805
10806 /* There is a syminfo section. Read the data. */
3f5e193b 10807 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
10808 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
10809 1, syminsz, _("symbol information"));
a6e9f9df 10810 if (!extsyminfo)
015dc7e1 10811 return false;
252b5132 10812
978c4450 10813 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
10814 {
10815 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 10816 free (filedata->dynamic_syminfo);
e3d39609 10817 }
978c4450
AM
10818 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
10819 if (filedata->dynamic_syminfo == NULL)
252b5132 10820 {
2482f306
AM
10821 error (_("Out of memory allocating %lu bytes "
10822 "for dynamic symbol info\n"),
8b73c356 10823 (unsigned long) syminsz);
015dc7e1 10824 return false;
252b5132
RH
10825 }
10826
2482f306
AM
10827 filedata->dynamic_syminfo_nent
10828 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 10829 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
10830 syminfo < (filedata->dynamic_syminfo
10831 + filedata->dynamic_syminfo_nent);
86dba8ee 10832 ++syminfo, ++extsym)
252b5132 10833 {
86dba8ee
AM
10834 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10835 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10836 }
10837
10838 free (extsyminfo);
10839 }
10840 }
10841
978c4450 10842 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa
NC
10843 {
10844 if (filedata->dynamic_nent == 1)
10845 {
10846 if (filedata->is_separate)
10847 printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains 1 entry:\n"),
10848 filedata->file_name,
10849 filedata->dynamic_addr);
10850 else
10851 printf (_("\nDynamic section at offset 0x%lx contains 1 entry:\n"),
10852 filedata->dynamic_addr);
10853 }
10854 else
10855 {
10856 if (filedata->is_separate)
10857 printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n"),
10858 filedata->file_name,
10859 filedata->dynamic_addr,
10860 (unsigned long) filedata->dynamic_nent);
10861 else
10862 printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
10863 filedata->dynamic_addr,
10864 (unsigned long) filedata->dynamic_nent);
10865 }
10866 }
252b5132
RH
10867 if (do_dynamic)
10868 printf (_(" Tag Type Name/Value\n"));
10869
978c4450
AM
10870 for (entry = filedata->dynamic_section;
10871 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10872 entry++)
252b5132
RH
10873 {
10874 if (do_dynamic)
f7a99963 10875 {
2cf0635d 10876 const char * dtype;
e699b9ff 10877
f7a99963
NC
10878 putchar (' ');
10879 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10880 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10881 printf (" (%s)%*s", dtype,
32ec8896 10882 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10883 }
252b5132
RH
10884
10885 switch (entry->d_tag)
10886 {
d1133906
NC
10887 case DT_FLAGS:
10888 if (do_dynamic)
e9e44622 10889 print_dynamic_flags (entry->d_un.d_val);
d1133906 10890 break;
76da6bbe 10891
252b5132
RH
10892 case DT_AUXILIARY:
10893 case DT_FILTER:
019148e4
L
10894 case DT_CONFIG:
10895 case DT_DEPAUDIT:
10896 case DT_AUDIT:
252b5132
RH
10897 if (do_dynamic)
10898 {
019148e4 10899 switch (entry->d_tag)
b34976b6 10900 {
019148e4
L
10901 case DT_AUXILIARY:
10902 printf (_("Auxiliary library"));
10903 break;
10904
10905 case DT_FILTER:
10906 printf (_("Filter library"));
10907 break;
10908
b34976b6 10909 case DT_CONFIG:
019148e4
L
10910 printf (_("Configuration file"));
10911 break;
10912
10913 case DT_DEPAUDIT:
10914 printf (_("Dependency audit library"));
10915 break;
10916
10917 case DT_AUDIT:
10918 printf (_("Audit library"));
10919 break;
10920 }
252b5132 10921
978c4450
AM
10922 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10923 printf (": [%s]\n",
10924 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 10925 else
f7a99963
NC
10926 {
10927 printf (": ");
10928 print_vma (entry->d_un.d_val, PREFIX_HEX);
10929 putchar ('\n');
10930 }
252b5132
RH
10931 }
10932 break;
10933
dcefbbbd 10934 case DT_FEATURE:
252b5132
RH
10935 if (do_dynamic)
10936 {
10937 printf (_("Flags:"));
86f55779 10938
252b5132
RH
10939 if (entry->d_un.d_val == 0)
10940 printf (_(" None\n"));
10941 else
10942 {
10943 unsigned long int val = entry->d_un.d_val;
86f55779 10944
252b5132
RH
10945 if (val & DTF_1_PARINIT)
10946 {
10947 printf (" PARINIT");
10948 val ^= DTF_1_PARINIT;
10949 }
dcefbbbd
L
10950 if (val & DTF_1_CONFEXP)
10951 {
10952 printf (" CONFEXP");
10953 val ^= DTF_1_CONFEXP;
10954 }
252b5132
RH
10955 if (val != 0)
10956 printf (" %lx", val);
10957 puts ("");
10958 }
10959 }
10960 break;
10961
10962 case DT_POSFLAG_1:
10963 if (do_dynamic)
10964 {
10965 printf (_("Flags:"));
86f55779 10966
252b5132
RH
10967 if (entry->d_un.d_val == 0)
10968 printf (_(" None\n"));
10969 else
10970 {
10971 unsigned long int val = entry->d_un.d_val;
86f55779 10972
252b5132
RH
10973 if (val & DF_P1_LAZYLOAD)
10974 {
10975 printf (" LAZYLOAD");
10976 val ^= DF_P1_LAZYLOAD;
10977 }
10978 if (val & DF_P1_GROUPPERM)
10979 {
10980 printf (" GROUPPERM");
10981 val ^= DF_P1_GROUPPERM;
10982 }
10983 if (val != 0)
10984 printf (" %lx", val);
10985 puts ("");
10986 }
10987 }
10988 break;
10989
10990 case DT_FLAGS_1:
10991 if (do_dynamic)
10992 {
10993 printf (_("Flags:"));
10994 if (entry->d_un.d_val == 0)
10995 printf (_(" None\n"));
10996 else
10997 {
10998 unsigned long int val = entry->d_un.d_val;
86f55779 10999
252b5132
RH
11000 if (val & DF_1_NOW)
11001 {
11002 printf (" NOW");
11003 val ^= DF_1_NOW;
11004 }
11005 if (val & DF_1_GLOBAL)
11006 {
11007 printf (" GLOBAL");
11008 val ^= DF_1_GLOBAL;
11009 }
11010 if (val & DF_1_GROUP)
11011 {
11012 printf (" GROUP");
11013 val ^= DF_1_GROUP;
11014 }
11015 if (val & DF_1_NODELETE)
11016 {
11017 printf (" NODELETE");
11018 val ^= DF_1_NODELETE;
11019 }
11020 if (val & DF_1_LOADFLTR)
11021 {
11022 printf (" LOADFLTR");
11023 val ^= DF_1_LOADFLTR;
11024 }
11025 if (val & DF_1_INITFIRST)
11026 {
11027 printf (" INITFIRST");
11028 val ^= DF_1_INITFIRST;
11029 }
11030 if (val & DF_1_NOOPEN)
11031 {
11032 printf (" NOOPEN");
11033 val ^= DF_1_NOOPEN;
11034 }
11035 if (val & DF_1_ORIGIN)
11036 {
11037 printf (" ORIGIN");
11038 val ^= DF_1_ORIGIN;
11039 }
11040 if (val & DF_1_DIRECT)
11041 {
11042 printf (" DIRECT");
11043 val ^= DF_1_DIRECT;
11044 }
11045 if (val & DF_1_TRANS)
11046 {
11047 printf (" TRANS");
11048 val ^= DF_1_TRANS;
11049 }
11050 if (val & DF_1_INTERPOSE)
11051 {
11052 printf (" INTERPOSE");
11053 val ^= DF_1_INTERPOSE;
11054 }
f7db6139 11055 if (val & DF_1_NODEFLIB)
dcefbbbd 11056 {
f7db6139
L
11057 printf (" NODEFLIB");
11058 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11059 }
11060 if (val & DF_1_NODUMP)
11061 {
11062 printf (" NODUMP");
11063 val ^= DF_1_NODUMP;
11064 }
34b60028 11065 if (val & DF_1_CONFALT)
dcefbbbd 11066 {
34b60028
L
11067 printf (" CONFALT");
11068 val ^= DF_1_CONFALT;
11069 }
11070 if (val & DF_1_ENDFILTEE)
11071 {
11072 printf (" ENDFILTEE");
11073 val ^= DF_1_ENDFILTEE;
11074 }
11075 if (val & DF_1_DISPRELDNE)
11076 {
11077 printf (" DISPRELDNE");
11078 val ^= DF_1_DISPRELDNE;
11079 }
11080 if (val & DF_1_DISPRELPND)
11081 {
11082 printf (" DISPRELPND");
11083 val ^= DF_1_DISPRELPND;
11084 }
11085 if (val & DF_1_NODIRECT)
11086 {
11087 printf (" NODIRECT");
11088 val ^= DF_1_NODIRECT;
11089 }
11090 if (val & DF_1_IGNMULDEF)
11091 {
11092 printf (" IGNMULDEF");
11093 val ^= DF_1_IGNMULDEF;
11094 }
11095 if (val & DF_1_NOKSYMS)
11096 {
11097 printf (" NOKSYMS");
11098 val ^= DF_1_NOKSYMS;
11099 }
11100 if (val & DF_1_NOHDR)
11101 {
11102 printf (" NOHDR");
11103 val ^= DF_1_NOHDR;
11104 }
11105 if (val & DF_1_EDITED)
11106 {
11107 printf (" EDITED");
11108 val ^= DF_1_EDITED;
11109 }
11110 if (val & DF_1_NORELOC)
11111 {
11112 printf (" NORELOC");
11113 val ^= DF_1_NORELOC;
11114 }
11115 if (val & DF_1_SYMINTPOSE)
11116 {
11117 printf (" SYMINTPOSE");
11118 val ^= DF_1_SYMINTPOSE;
11119 }
11120 if (val & DF_1_GLOBAUDIT)
11121 {
11122 printf (" GLOBAUDIT");
11123 val ^= DF_1_GLOBAUDIT;
11124 }
11125 if (val & DF_1_SINGLETON)
11126 {
11127 printf (" SINGLETON");
11128 val ^= DF_1_SINGLETON;
dcefbbbd 11129 }
5c383f02
RO
11130 if (val & DF_1_STUB)
11131 {
11132 printf (" STUB");
11133 val ^= DF_1_STUB;
11134 }
11135 if (val & DF_1_PIE)
11136 {
11137 printf (" PIE");
11138 val ^= DF_1_PIE;
11139 }
b1202ffa
L
11140 if (val & DF_1_KMOD)
11141 {
11142 printf (" KMOD");
11143 val ^= DF_1_KMOD;
11144 }
11145 if (val & DF_1_WEAKFILTER)
11146 {
11147 printf (" WEAKFILTER");
11148 val ^= DF_1_WEAKFILTER;
11149 }
11150 if (val & DF_1_NOCOMMON)
11151 {
11152 printf (" NOCOMMON");
11153 val ^= DF_1_NOCOMMON;
11154 }
252b5132
RH
11155 if (val != 0)
11156 printf (" %lx", val);
11157 puts ("");
11158 }
11159 }
11160 break;
11161
11162 case DT_PLTREL:
978c4450 11163 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11164 if (do_dynamic)
dda8d76d 11165 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11166 break;
11167
11168 case DT_NULL :
11169 case DT_NEEDED :
11170 case DT_PLTGOT :
11171 case DT_HASH :
11172 case DT_STRTAB :
11173 case DT_SYMTAB :
11174 case DT_RELA :
11175 case DT_INIT :
11176 case DT_FINI :
11177 case DT_SONAME :
11178 case DT_RPATH :
11179 case DT_SYMBOLIC:
11180 case DT_REL :
11181 case DT_DEBUG :
11182 case DT_TEXTREL :
11183 case DT_JMPREL :
019148e4 11184 case DT_RUNPATH :
978c4450 11185 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11186
11187 if (do_dynamic)
11188 {
2cf0635d 11189 char * name;
252b5132 11190
978c4450
AM
11191 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
11192 name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11193 else
d79b3d50 11194 name = NULL;
252b5132
RH
11195
11196 if (name)
11197 {
11198 switch (entry->d_tag)
11199 {
11200 case DT_NEEDED:
11201 printf (_("Shared library: [%s]"), name);
11202
13acb58d
AM
11203 if (filedata->program_interpreter
11204 && streq (name, filedata->program_interpreter))
f7a99963 11205 printf (_(" program interpreter"));
252b5132
RH
11206 break;
11207
11208 case DT_SONAME:
f7a99963 11209 printf (_("Library soname: [%s]"), name);
252b5132
RH
11210 break;
11211
11212 case DT_RPATH:
f7a99963 11213 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11214 break;
11215
019148e4
L
11216 case DT_RUNPATH:
11217 printf (_("Library runpath: [%s]"), name);
11218 break;
11219
252b5132 11220 default:
f7a99963
NC
11221 print_vma (entry->d_un.d_val, PREFIX_HEX);
11222 break;
252b5132
RH
11223 }
11224 }
11225 else
f7a99963
NC
11226 print_vma (entry->d_un.d_val, PREFIX_HEX);
11227
11228 putchar ('\n');
252b5132
RH
11229 }
11230 break;
11231
11232 case DT_PLTRELSZ:
11233 case DT_RELASZ :
11234 case DT_STRSZ :
11235 case DT_RELSZ :
11236 case DT_RELAENT :
11237 case DT_SYMENT :
11238 case DT_RELENT :
978c4450 11239 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11240 /* Fall through. */
252b5132
RH
11241 case DT_PLTPADSZ:
11242 case DT_MOVEENT :
11243 case DT_MOVESZ :
11244 case DT_INIT_ARRAYSZ:
11245 case DT_FINI_ARRAYSZ:
047b2264
JJ
11246 case DT_GNU_CONFLICTSZ:
11247 case DT_GNU_LIBLISTSZ:
252b5132 11248 if (do_dynamic)
f7a99963
NC
11249 {
11250 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11251 printf (_(" (bytes)\n"));
f7a99963 11252 }
252b5132
RH
11253 break;
11254
11255 case DT_VERDEFNUM:
11256 case DT_VERNEEDNUM:
11257 case DT_RELACOUNT:
11258 case DT_RELCOUNT:
11259 if (do_dynamic)
f7a99963
NC
11260 {
11261 print_vma (entry->d_un.d_val, UNSIGNED);
11262 putchar ('\n');
11263 }
252b5132
RH
11264 break;
11265
11266 case DT_SYMINSZ:
11267 case DT_SYMINENT:
11268 case DT_SYMINFO:
11269 case DT_USED:
11270 case DT_INIT_ARRAY:
11271 case DT_FINI_ARRAY:
11272 if (do_dynamic)
11273 {
d79b3d50 11274 if (entry->d_tag == DT_USED
978c4450 11275 && VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
252b5132 11276 {
978c4450 11277 char * name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11278
b34976b6 11279 if (*name)
252b5132
RH
11280 {
11281 printf (_("Not needed object: [%s]\n"), name);
11282 break;
11283 }
11284 }
103f02d3 11285
f7a99963
NC
11286 print_vma (entry->d_un.d_val, PREFIX_HEX);
11287 putchar ('\n');
252b5132
RH
11288 }
11289 break;
11290
11291 case DT_BIND_NOW:
11292 /* The value of this entry is ignored. */
35b1837e
AM
11293 if (do_dynamic)
11294 putchar ('\n');
252b5132 11295 break;
103f02d3 11296
047b2264
JJ
11297 case DT_GNU_PRELINKED:
11298 if (do_dynamic)
11299 {
2cf0635d 11300 struct tm * tmp;
91d6fa6a 11301 time_t atime = entry->d_un.d_val;
047b2264 11302
91d6fa6a 11303 tmp = gmtime (&atime);
071436c6
NC
11304 /* PR 17533 file: 041-1244816-0.004. */
11305 if (tmp == NULL)
5a2cbcf4
L
11306 printf (_("<corrupt time val: %lx"),
11307 (unsigned long) atime);
071436c6
NC
11308 else
11309 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11310 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11311 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11312
11313 }
11314 break;
11315
fdc90cb4 11316 case DT_GNU_HASH:
978c4450 11317 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11318 if (do_dynamic)
11319 {
11320 print_vma (entry->d_un.d_val, PREFIX_HEX);
11321 putchar ('\n');
11322 }
11323 break;
11324
a5da3dee
VDM
11325 case DT_GNU_FLAGS_1:
11326 if (do_dynamic)
11327 {
11328 printf (_("Flags:"));
11329 if (entry->d_un.d_val == 0)
11330 printf (_(" None\n"));
11331 else
11332 {
11333 unsigned long int val = entry->d_un.d_val;
11334
11335 if (val & DF_GNU_1_UNIQUE)
11336 {
11337 printf (" UNIQUE");
11338 val ^= DF_GNU_1_UNIQUE;
11339 }
11340 if (val != 0)
11341 printf (" %lx", val);
11342 puts ("");
11343 }
11344 }
11345 break;
11346
252b5132
RH
11347 default:
11348 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11349 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11350 = entry->d_un.d_val;
252b5132
RH
11351
11352 if (do_dynamic)
11353 {
dda8d76d 11354 switch (filedata->file_header.e_machine)
252b5132 11355 {
37c18eed
SD
11356 case EM_AARCH64:
11357 dynamic_section_aarch64_val (entry);
11358 break;
252b5132 11359 case EM_MIPS:
4fe85591 11360 case EM_MIPS_RS3_LE:
978c4450 11361 dynamic_section_mips_val (filedata, entry);
252b5132 11362 break;
103f02d3 11363 case EM_PARISC:
b2d38a17 11364 dynamic_section_parisc_val (entry);
103f02d3 11365 break;
ecc51f48 11366 case EM_IA_64:
b2d38a17 11367 dynamic_section_ia64_val (entry);
ecc51f48 11368 break;
252b5132 11369 default:
f7a99963
NC
11370 print_vma (entry->d_un.d_val, PREFIX_HEX);
11371 putchar ('\n');
252b5132
RH
11372 }
11373 }
11374 break;
11375 }
11376 }
11377
015dc7e1 11378 return true;
252b5132
RH
11379}
11380
11381static char *
d3ba0551 11382get_ver_flags (unsigned int flags)
252b5132 11383{
6d4f21f6 11384 static char buff[128];
252b5132
RH
11385
11386 buff[0] = 0;
11387
11388 if (flags == 0)
11389 return _("none");
11390
11391 if (flags & VER_FLG_BASE)
7bb1ad17 11392 strcat (buff, "BASE");
252b5132
RH
11393
11394 if (flags & VER_FLG_WEAK)
11395 {
11396 if (flags & VER_FLG_BASE)
7bb1ad17 11397 strcat (buff, " | ");
252b5132 11398
7bb1ad17 11399 strcat (buff, "WEAK");
252b5132
RH
11400 }
11401
44ec90b9
RO
11402 if (flags & VER_FLG_INFO)
11403 {
11404 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11405 strcat (buff, " | ");
44ec90b9 11406
7bb1ad17 11407 strcat (buff, "INFO");
44ec90b9
RO
11408 }
11409
11410 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11411 {
11412 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11413 strcat (buff, " | ");
11414
11415 strcat (buff, _("<unknown>"));
11416 }
252b5132
RH
11417
11418 return buff;
11419}
11420
11421/* Display the contents of the version sections. */
98fb390a 11422
015dc7e1 11423static bool
dda8d76d 11424process_version_sections (Filedata * filedata)
252b5132 11425{
2cf0635d 11426 Elf_Internal_Shdr * section;
b34976b6 11427 unsigned i;
015dc7e1 11428 bool found = false;
252b5132
RH
11429
11430 if (! do_version)
015dc7e1 11431 return true;
252b5132 11432
dda8d76d
NC
11433 for (i = 0, section = filedata->section_headers;
11434 i < filedata->file_header.e_shnum;
b34976b6 11435 i++, section++)
252b5132
RH
11436 {
11437 switch (section->sh_type)
11438 {
11439 case SHT_GNU_verdef:
11440 {
2cf0635d 11441 Elf_External_Verdef * edefs;
452bf675
AM
11442 unsigned long idx;
11443 unsigned long cnt;
2cf0635d 11444 char * endbuf;
252b5132 11445
015dc7e1 11446 found = true;
252b5132 11447
ca0e11aa
NC
11448 if (filedata->is_separate)
11449 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
11450 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
11451 section->sh_info),
11452 filedata->file_name,
11453 printable_section_name (filedata, section),
11454 section->sh_info);
11455 else
11456 printf (ngettext ("\nVersion definition section '%s' "
11457 "contains %u entry:\n",
11458 "\nVersion definition section '%s' "
11459 "contains %u entries:\n",
11460 section->sh_info),
11461 printable_section_name (filedata, section),
11462 section->sh_info);
047c3dbf 11463
ae9ac79e 11464 printf (_(" Addr: 0x"));
252b5132 11465 printf_vma (section->sh_addr);
233f82cf 11466 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11467 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11468 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11469
3f5e193b 11470 edefs = (Elf_External_Verdef *)
dda8d76d 11471 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11472 _("version definition section"));
a6e9f9df
AM
11473 if (!edefs)
11474 break;
59245841 11475 endbuf = (char *) edefs + section->sh_size;
252b5132 11476
1445030f 11477 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11478 {
2cf0635d
NC
11479 char * vstart;
11480 Elf_External_Verdef * edef;
b34976b6 11481 Elf_Internal_Verdef ent;
2cf0635d 11482 Elf_External_Verdaux * eaux;
b34976b6 11483 Elf_Internal_Verdaux aux;
452bf675 11484 unsigned long isum;
b34976b6 11485 int j;
103f02d3 11486
252b5132 11487 vstart = ((char *) edefs) + idx;
54806181
AM
11488 if (vstart + sizeof (*edef) > endbuf)
11489 break;
252b5132
RH
11490
11491 edef = (Elf_External_Verdef *) vstart;
11492
11493 ent.vd_version = BYTE_GET (edef->vd_version);
11494 ent.vd_flags = BYTE_GET (edef->vd_flags);
11495 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11496 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11497 ent.vd_hash = BYTE_GET (edef->vd_hash);
11498 ent.vd_aux = BYTE_GET (edef->vd_aux);
11499 ent.vd_next = BYTE_GET (edef->vd_next);
11500
452bf675 11501 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11502 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11503
11504 printf (_(" Index: %d Cnt: %d "),
11505 ent.vd_ndx, ent.vd_cnt);
11506
452bf675 11507 /* Check for overflow. */
1445030f 11508 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11509 break;
11510
252b5132
RH
11511 vstart += ent.vd_aux;
11512
1445030f
AM
11513 if (vstart + sizeof (*eaux) > endbuf)
11514 break;
252b5132
RH
11515 eaux = (Elf_External_Verdaux *) vstart;
11516
11517 aux.vda_name = BYTE_GET (eaux->vda_name);
11518 aux.vda_next = BYTE_GET (eaux->vda_next);
11519
978c4450
AM
11520 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
11521 printf (_("Name: %s\n"),
11522 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132
RH
11523 else
11524 printf (_("Name index: %ld\n"), aux.vda_name);
11525
11526 isum = idx + ent.vd_aux;
11527
b34976b6 11528 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11529 {
1445030f
AM
11530 if (aux.vda_next < sizeof (*eaux)
11531 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11532 {
11533 warn (_("Invalid vda_next field of %lx\n"),
11534 aux.vda_next);
11535 j = ent.vd_cnt;
11536 break;
11537 }
dd24e3da 11538 /* Check for overflow. */
7e26601c 11539 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11540 break;
11541
252b5132
RH
11542 isum += aux.vda_next;
11543 vstart += aux.vda_next;
11544
54806181
AM
11545 if (vstart + sizeof (*eaux) > endbuf)
11546 break;
1445030f 11547 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11548
11549 aux.vda_name = BYTE_GET (eaux->vda_name);
11550 aux.vda_next = BYTE_GET (eaux->vda_next);
11551
978c4450 11552 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
452bf675 11553 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450
AM
11554 isum, j,
11555 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132 11556 else
452bf675 11557 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11558 isum, j, aux.vda_name);
11559 }
dd24e3da 11560
54806181
AM
11561 if (j < ent.vd_cnt)
11562 printf (_(" Version def aux past end of section\n"));
252b5132 11563
c9f02c3e
MR
11564 /* PR 17531:
11565 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11566 if (ent.vd_next < sizeof (*edef)
11567 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11568 {
11569 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11570 cnt = section->sh_info;
11571 break;
11572 }
452bf675 11573 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11574 break;
11575
252b5132
RH
11576 idx += ent.vd_next;
11577 }
dd24e3da 11578
54806181
AM
11579 if (cnt < section->sh_info)
11580 printf (_(" Version definition past end of section\n"));
252b5132
RH
11581
11582 free (edefs);
11583 }
11584 break;
103f02d3 11585
252b5132
RH
11586 case SHT_GNU_verneed:
11587 {
2cf0635d 11588 Elf_External_Verneed * eneed;
452bf675
AM
11589 unsigned long idx;
11590 unsigned long cnt;
2cf0635d 11591 char * endbuf;
252b5132 11592
015dc7e1 11593 found = true;
252b5132 11594
ca0e11aa
NC
11595 if (filedata->is_separate)
11596 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
11597 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
11598 section->sh_info),
11599 filedata->file_name,
11600 printable_section_name (filedata, section),
11601 section->sh_info);
11602 else
11603 printf (ngettext ("\nVersion needs section '%s' "
11604 "contains %u entry:\n",
11605 "\nVersion needs section '%s' "
11606 "contains %u entries:\n",
11607 section->sh_info),
11608 printable_section_name (filedata, section),
11609 section->sh_info);
047c3dbf 11610
252b5132
RH
11611 printf (_(" Addr: 0x"));
11612 printf_vma (section->sh_addr);
72de5009 11613 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11614 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11615 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11616
dda8d76d 11617 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11618 section->sh_offset, 1,
11619 section->sh_size,
9cf03b7e 11620 _("Version Needs section"));
a6e9f9df
AM
11621 if (!eneed)
11622 break;
59245841 11623 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11624
11625 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11626 {
2cf0635d 11627 Elf_External_Verneed * entry;
b34976b6 11628 Elf_Internal_Verneed ent;
452bf675 11629 unsigned long isum;
b34976b6 11630 int j;
2cf0635d 11631 char * vstart;
252b5132
RH
11632
11633 vstart = ((char *) eneed) + idx;
54806181
AM
11634 if (vstart + sizeof (*entry) > endbuf)
11635 break;
252b5132
RH
11636
11637 entry = (Elf_External_Verneed *) vstart;
11638
11639 ent.vn_version = BYTE_GET (entry->vn_version);
11640 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11641 ent.vn_file = BYTE_GET (entry->vn_file);
11642 ent.vn_aux = BYTE_GET (entry->vn_aux);
11643 ent.vn_next = BYTE_GET (entry->vn_next);
11644
452bf675 11645 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11646
978c4450
AM
11647 if (VALID_DYNAMIC_NAME (filedata, ent.vn_file))
11648 printf (_(" File: %s"),
11649 GET_DYNAMIC_NAME (filedata, ent.vn_file));
252b5132
RH
11650 else
11651 printf (_(" File: %lx"), ent.vn_file);
11652
11653 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11654
dd24e3da 11655 /* Check for overflow. */
7e26601c 11656 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11657 break;
252b5132
RH
11658 vstart += ent.vn_aux;
11659
11660 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11661 {
2cf0635d 11662 Elf_External_Vernaux * eaux;
b34976b6 11663 Elf_Internal_Vernaux aux;
252b5132 11664
54806181
AM
11665 if (vstart + sizeof (*eaux) > endbuf)
11666 break;
252b5132
RH
11667 eaux = (Elf_External_Vernaux *) vstart;
11668
11669 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11670 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11671 aux.vna_other = BYTE_GET (eaux->vna_other);
11672 aux.vna_name = BYTE_GET (eaux->vna_name);
11673 aux.vna_next = BYTE_GET (eaux->vna_next);
11674
978c4450 11675 if (VALID_DYNAMIC_NAME (filedata, aux.vna_name))
452bf675 11676 printf (_(" %#06lx: Name: %s"),
978c4450 11677 isum, GET_DYNAMIC_NAME (filedata, aux.vna_name));
252b5132 11678 else
452bf675 11679 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11680 isum, aux.vna_name);
11681
11682 printf (_(" Flags: %s Version: %d\n"),
11683 get_ver_flags (aux.vna_flags), aux.vna_other);
11684
1445030f
AM
11685 if (aux.vna_next < sizeof (*eaux)
11686 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11687 {
11688 warn (_("Invalid vna_next field of %lx\n"),
11689 aux.vna_next);
11690 j = ent.vn_cnt;
11691 break;
11692 }
1445030f
AM
11693 /* Check for overflow. */
11694 if (aux.vna_next > (size_t) (endbuf - vstart))
11695 break;
252b5132
RH
11696 isum += aux.vna_next;
11697 vstart += aux.vna_next;
11698 }
9cf03b7e 11699
54806181 11700 if (j < ent.vn_cnt)
f9a6a8f0 11701 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 11702
1445030f
AM
11703 if (ent.vn_next < sizeof (*entry)
11704 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11705 {
452bf675 11706 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11707 cnt = section->sh_info;
11708 break;
11709 }
1445030f
AM
11710 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11711 break;
252b5132
RH
11712 idx += ent.vn_next;
11713 }
9cf03b7e 11714
54806181 11715 if (cnt < section->sh_info)
9cf03b7e 11716 warn (_("Missing Version Needs information\n"));
103f02d3 11717
252b5132
RH
11718 free (eneed);
11719 }
11720 break;
11721
11722 case SHT_GNU_versym:
11723 {
2cf0635d 11724 Elf_Internal_Shdr * link_section;
8b73c356
NC
11725 size_t total;
11726 unsigned int cnt;
2cf0635d
NC
11727 unsigned char * edata;
11728 unsigned short * data;
11729 char * strtab;
11730 Elf_Internal_Sym * symbols;
11731 Elf_Internal_Shdr * string_sec;
ba5cdace 11732 unsigned long num_syms;
d3ba0551 11733 long off;
252b5132 11734
dda8d76d 11735 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11736 break;
11737
dda8d76d 11738 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11739 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11740
dda8d76d 11741 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11742 break;
11743
015dc7e1 11744 found = true;
252b5132 11745
4de91c10 11746 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
11747 if (symbols == NULL)
11748 break;
252b5132 11749
dda8d76d 11750 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11751
dda8d76d 11752 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11753 string_sec->sh_size,
11754 _("version string table"));
a6e9f9df 11755 if (!strtab)
0429c154
MS
11756 {
11757 free (symbols);
11758 break;
11759 }
252b5132 11760
ca0e11aa
NC
11761 if (filedata->is_separate)
11762 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
11763 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
11764 total),
11765 filedata->file_name,
11766 printable_section_name (filedata, section),
11767 (unsigned long) total);
11768 else
11769 printf (ngettext ("\nVersion symbols section '%s' "
11770 "contains %lu entry:\n",
11771 "\nVersion symbols section '%s' "
11772 "contains %lu entries:\n",
11773 total),
11774 printable_section_name (filedata, section),
11775 (unsigned long) total);
252b5132 11776
ae9ac79e 11777 printf (_(" Addr: 0x"));
252b5132 11778 printf_vma (section->sh_addr);
72de5009 11779 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11780 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11781 printable_section_name (filedata, link_section));
252b5132 11782
dda8d76d 11783 off = offset_from_vma (filedata,
978c4450 11784 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11785 total * sizeof (short));
95099889
AM
11786 edata = (unsigned char *) get_data (NULL, filedata, off,
11787 sizeof (short), total,
11788 _("version symbol data"));
a6e9f9df
AM
11789 if (!edata)
11790 {
11791 free (strtab);
0429c154 11792 free (symbols);
a6e9f9df
AM
11793 break;
11794 }
252b5132 11795
3f5e193b 11796 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11797
11798 for (cnt = total; cnt --;)
b34976b6
AM
11799 data[cnt] = byte_get (edata + cnt * sizeof (short),
11800 sizeof (short));
252b5132
RH
11801
11802 free (edata);
11803
11804 for (cnt = 0; cnt < total; cnt += 4)
11805 {
11806 int j, nn;
ab273396
AM
11807 char *name;
11808 char *invalid = _("*invalid*");
252b5132
RH
11809
11810 printf (" %03x:", cnt);
11811
11812 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11813 switch (data[cnt + j])
252b5132
RH
11814 {
11815 case 0:
11816 fputs (_(" 0 (*local*) "), stdout);
11817 break;
11818
11819 case 1:
11820 fputs (_(" 1 (*global*) "), stdout);
11821 break;
11822
11823 default:
c244d050
NC
11824 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11825 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11826
dd24e3da 11827 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11828 array, break to avoid an out-of-bounds read. */
11829 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11830 {
11831 warn (_("invalid index into symbol array\n"));
11832 break;
11833 }
11834
ab273396 11835 name = NULL;
978c4450 11836 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11837 {
b34976b6
AM
11838 Elf_Internal_Verneed ivn;
11839 unsigned long offset;
252b5132 11840
d93f0186 11841 offset = offset_from_vma
978c4450
AM
11842 (filedata,
11843 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11844 sizeof (Elf_External_Verneed));
252b5132 11845
b34976b6 11846 do
252b5132 11847 {
b34976b6
AM
11848 Elf_Internal_Vernaux ivna;
11849 Elf_External_Verneed evn;
11850 Elf_External_Vernaux evna;
11851 unsigned long a_off;
252b5132 11852
dda8d76d 11853 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11854 _("version need")) == NULL)
11855 break;
0b4362b0 11856
252b5132
RH
11857 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11858 ivn.vn_next = BYTE_GET (evn.vn_next);
11859
11860 a_off = offset + ivn.vn_aux;
11861
11862 do
11863 {
dda8d76d 11864 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11865 1, _("version need aux (2)")) == NULL)
11866 {
11867 ivna.vna_next = 0;
11868 ivna.vna_other = 0;
11869 }
11870 else
11871 {
11872 ivna.vna_next = BYTE_GET (evna.vna_next);
11873 ivna.vna_other = BYTE_GET (evna.vna_other);
11874 }
252b5132
RH
11875
11876 a_off += ivna.vna_next;
11877 }
b34976b6 11878 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11879 && ivna.vna_next != 0);
11880
b34976b6 11881 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11882 {
11883 ivna.vna_name = BYTE_GET (evna.vna_name);
11884
54806181 11885 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11886 name = invalid;
54806181
AM
11887 else
11888 name = strtab + ivna.vna_name;
252b5132
RH
11889 break;
11890 }
11891
11892 offset += ivn.vn_next;
11893 }
11894 while (ivn.vn_next);
11895 }
00d93f34 11896
ab273396 11897 if (data[cnt + j] != 0x8001
978c4450 11898 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 11899 {
b34976b6
AM
11900 Elf_Internal_Verdef ivd;
11901 Elf_External_Verdef evd;
11902 unsigned long offset;
252b5132 11903
d93f0186 11904 offset = offset_from_vma
978c4450
AM
11905 (filedata,
11906 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 11907 sizeof evd);
252b5132
RH
11908
11909 do
11910 {
dda8d76d 11911 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
11912 _("version def")) == NULL)
11913 {
11914 ivd.vd_next = 0;
948f632f 11915 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
11916 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
11917 break;
59245841
NC
11918 }
11919 else
11920 {
11921 ivd.vd_next = BYTE_GET (evd.vd_next);
11922 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11923 }
252b5132
RH
11924
11925 offset += ivd.vd_next;
11926 }
c244d050 11927 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
11928 && ivd.vd_next != 0);
11929
c244d050 11930 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 11931 {
b34976b6
AM
11932 Elf_External_Verdaux evda;
11933 Elf_Internal_Verdaux ivda;
252b5132
RH
11934
11935 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11936
dda8d76d 11937 if (get_data (&evda, filedata,
59245841
NC
11938 offset - ivd.vd_next + ivd.vd_aux,
11939 sizeof (evda), 1,
11940 _("version def aux")) == NULL)
11941 break;
252b5132
RH
11942
11943 ivda.vda_name = BYTE_GET (evda.vda_name);
11944
54806181 11945 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
11946 name = invalid;
11947 else if (name != NULL && name != invalid)
11948 name = _("*both*");
54806181
AM
11949 else
11950 name = strtab + ivda.vda_name;
252b5132
RH
11951 }
11952 }
ab273396
AM
11953 if (name != NULL)
11954 nn += printf ("(%s%-*s",
11955 name,
11956 12 - (int) strlen (name),
11957 ")");
252b5132
RH
11958
11959 if (nn < 18)
11960 printf ("%*c", 18 - nn, ' ');
11961 }
11962
11963 putchar ('\n');
11964 }
11965
11966 free (data);
11967 free (strtab);
11968 free (symbols);
11969 }
11970 break;
103f02d3 11971
252b5132
RH
11972 default:
11973 break;
11974 }
11975 }
11976
11977 if (! found)
ca0e11aa
NC
11978 {
11979 if (filedata->is_separate)
11980 printf (_("\nNo version information found in linked file '%s'.\n"),
11981 filedata->file_name);
11982 else
11983 printf (_("\nNo version information found in this file.\n"));
11984 }
252b5132 11985
015dc7e1 11986 return true;
252b5132
RH
11987}
11988
d1133906 11989static const char *
dda8d76d 11990get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 11991{
89246a0e 11992 static char buff[64];
252b5132
RH
11993
11994 switch (binding)
11995 {
b34976b6
AM
11996 case STB_LOCAL: return "LOCAL";
11997 case STB_GLOBAL: return "GLOBAL";
11998 case STB_WEAK: return "WEAK";
252b5132
RH
11999 default:
12000 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12001 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12002 binding);
252b5132 12003 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12004 {
12005 if (binding == STB_GNU_UNIQUE
df3a023b 12006 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12007 return "UNIQUE";
12008 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12009 }
252b5132 12010 else
e9e44622 12011 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12012 return buff;
12013 }
12014}
12015
d1133906 12016static const char *
dda8d76d 12017get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12018{
89246a0e 12019 static char buff[64];
252b5132
RH
12020
12021 switch (type)
12022 {
b34976b6
AM
12023 case STT_NOTYPE: return "NOTYPE";
12024 case STT_OBJECT: return "OBJECT";
12025 case STT_FUNC: return "FUNC";
12026 case STT_SECTION: return "SECTION";
12027 case STT_FILE: return "FILE";
12028 case STT_COMMON: return "COMMON";
12029 case STT_TLS: return "TLS";
15ab5209
DB
12030 case STT_RELC: return "RELC";
12031 case STT_SRELC: return "SRELC";
252b5132
RH
12032 default:
12033 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12034 {
dda8d76d 12035 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12036 return "THUMB_FUNC";
103f02d3 12037
dda8d76d 12038 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12039 return "REGISTER";
12040
dda8d76d 12041 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12042 return "PARISC_MILLI";
12043
e9e44622 12044 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12045 }
252b5132 12046 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12047 {
dda8d76d 12048 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12049 {
12050 if (type == STT_HP_OPAQUE)
12051 return "HP_OPAQUE";
12052 if (type == STT_HP_STUB)
12053 return "HP_STUB";
12054 }
12055
d8045f23 12056 if (type == STT_GNU_IFUNC
dda8d76d 12057 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12058 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12059 return "IFUNC";
12060
e9e44622 12061 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12062 }
252b5132 12063 else
e9e44622 12064 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12065 return buff;
12066 }
12067}
12068
d1133906 12069static const char *
d3ba0551 12070get_symbol_visibility (unsigned int visibility)
d1133906
NC
12071{
12072 switch (visibility)
12073 {
b34976b6
AM
12074 case STV_DEFAULT: return "DEFAULT";
12075 case STV_INTERNAL: return "INTERNAL";
12076 case STV_HIDDEN: return "HIDDEN";
d1133906 12077 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12078 default:
27a45f42 12079 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12080 return _("<unknown>");
d1133906
NC
12081 }
12082}
12083
2057d69d
CZ
12084static const char *
12085get_alpha_symbol_other (unsigned int other)
9abca702 12086{
2057d69d
CZ
12087 switch (other)
12088 {
12089 case STO_ALPHA_NOPV: return "NOPV";
12090 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12091 default:
27a45f42 12092 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12093 return _("<unknown>");
9abca702 12094 }
2057d69d
CZ
12095}
12096
fd85a6a1
NC
12097static const char *
12098get_solaris_symbol_visibility (unsigned int visibility)
12099{
12100 switch (visibility)
12101 {
12102 case 4: return "EXPORTED";
12103 case 5: return "SINGLETON";
12104 case 6: return "ELIMINATE";
12105 default: return get_symbol_visibility (visibility);
12106 }
12107}
12108
2301ed1c
SN
12109static const char *
12110get_aarch64_symbol_other (unsigned int other)
12111{
12112 static char buf[32];
12113
12114 if (other & STO_AARCH64_VARIANT_PCS)
12115 {
12116 other &= ~STO_AARCH64_VARIANT_PCS;
12117 if (other == 0)
12118 return "VARIANT_PCS";
12119 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12120 return buf;
12121 }
12122 return NULL;
12123}
12124
5e2b0d47
NC
12125static const char *
12126get_mips_symbol_other (unsigned int other)
12127{
12128 switch (other)
12129 {
32ec8896
NC
12130 case STO_OPTIONAL: return "OPTIONAL";
12131 case STO_MIPS_PLT: return "MIPS PLT";
12132 case STO_MIPS_PIC: return "MIPS PIC";
12133 case STO_MICROMIPS: return "MICROMIPS";
12134 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12135 case STO_MIPS16: return "MIPS16";
12136 default: return NULL;
5e2b0d47
NC
12137 }
12138}
12139
28f997cf 12140static const char *
dda8d76d 12141get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12142{
dda8d76d 12143 if (is_ia64_vms (filedata))
28f997cf
TG
12144 {
12145 static char res[32];
12146
12147 res[0] = 0;
12148
12149 /* Function types is for images and .STB files only. */
dda8d76d 12150 switch (filedata->file_header.e_type)
28f997cf
TG
12151 {
12152 case ET_DYN:
12153 case ET_EXEC:
12154 switch (VMS_ST_FUNC_TYPE (other))
12155 {
12156 case VMS_SFT_CODE_ADDR:
12157 strcat (res, " CA");
12158 break;
12159 case VMS_SFT_SYMV_IDX:
12160 strcat (res, " VEC");
12161 break;
12162 case VMS_SFT_FD:
12163 strcat (res, " FD");
12164 break;
12165 case VMS_SFT_RESERVE:
12166 strcat (res, " RSV");
12167 break;
12168 default:
bee0ee85
NC
12169 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12170 VMS_ST_FUNC_TYPE (other));
12171 strcat (res, " <unknown>");
12172 break;
28f997cf
TG
12173 }
12174 break;
12175 default:
12176 break;
12177 }
12178 switch (VMS_ST_LINKAGE (other))
12179 {
12180 case VMS_STL_IGNORE:
12181 strcat (res, " IGN");
12182 break;
12183 case VMS_STL_RESERVE:
12184 strcat (res, " RSV");
12185 break;
12186 case VMS_STL_STD:
12187 strcat (res, " STD");
12188 break;
12189 case VMS_STL_LNK:
12190 strcat (res, " LNK");
12191 break;
12192 default:
bee0ee85
NC
12193 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12194 VMS_ST_LINKAGE (other));
12195 strcat (res, " <unknown>");
12196 break;
28f997cf
TG
12197 }
12198
12199 if (res[0] != 0)
12200 return res + 1;
12201 else
12202 return res;
12203 }
12204 return NULL;
12205}
12206
6911b7dc
AM
12207static const char *
12208get_ppc64_symbol_other (unsigned int other)
12209{
14732552
AM
12210 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12211 return NULL;
12212
12213 other >>= STO_PPC64_LOCAL_BIT;
12214 if (other <= 6)
6911b7dc 12215 {
89246a0e 12216 static char buf[64];
14732552
AM
12217 if (other >= 2)
12218 other = ppc64_decode_local_entry (other);
12219 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12220 return buf;
12221 }
12222 return NULL;
12223}
12224
5e2b0d47 12225static const char *
dda8d76d 12226get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12227{
12228 const char * result = NULL;
89246a0e 12229 static char buff [64];
5e2b0d47
NC
12230
12231 if (other == 0)
12232 return "";
12233
dda8d76d 12234 switch (filedata->file_header.e_machine)
5e2b0d47 12235 {
2057d69d
CZ
12236 case EM_ALPHA:
12237 result = get_alpha_symbol_other (other);
12238 break;
2301ed1c
SN
12239 case EM_AARCH64:
12240 result = get_aarch64_symbol_other (other);
12241 break;
5e2b0d47
NC
12242 case EM_MIPS:
12243 result = get_mips_symbol_other (other);
28f997cf
TG
12244 break;
12245 case EM_IA_64:
dda8d76d 12246 result = get_ia64_symbol_other (filedata, other);
28f997cf 12247 break;
6911b7dc
AM
12248 case EM_PPC64:
12249 result = get_ppc64_symbol_other (other);
12250 break;
5e2b0d47 12251 default:
fd85a6a1 12252 result = NULL;
5e2b0d47
NC
12253 break;
12254 }
12255
12256 if (result)
12257 return result;
12258
12259 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12260 return buff;
12261}
12262
d1133906 12263static const char *
dda8d76d 12264get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12265{
b34976b6 12266 static char buff[32];
5cf1065c 12267
252b5132
RH
12268 switch (type)
12269 {
b34976b6
AM
12270 case SHN_UNDEF: return "UND";
12271 case SHN_ABS: return "ABS";
12272 case SHN_COMMON: return "COM";
252b5132 12273 default:
9ce701e2 12274 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12275 && filedata->file_header.e_machine == EM_IA_64
12276 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12277 return "ANSI_COM";
12278 else if ((filedata->file_header.e_machine == EM_X86_64
12279 || filedata->file_header.e_machine == EM_L1OM
12280 || filedata->file_header.e_machine == EM_K1OM)
12281 && type == SHN_X86_64_LCOMMON)
12282 return "LARGE_COM";
12283 else if ((type == SHN_MIPS_SCOMMON
12284 && filedata->file_header.e_machine == EM_MIPS)
12285 || (type == SHN_TIC6X_SCOMMON
12286 && filedata->file_header.e_machine == EM_TI_C6000))
12287 return "SCOM";
12288 else if (type == SHN_MIPS_SUNDEFINED
12289 && filedata->file_header.e_machine == EM_MIPS)
12290 return "SUND";
12291 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12292 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12293 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12294 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12295 else if (type >= SHN_LORESERVE)
12296 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12297 else if (filedata->file_header.e_shnum != 0
12298 && type >= filedata->file_header.e_shnum)
12299 sprintf (buff, _("bad section index[%3d]"), type);
12300 else
12301 sprintf (buff, "%3d", type);
12302 break;
fd85a6a1
NC
12303 }
12304
10ca4b04 12305 return buff;
6bd1a22c
L
12306}
12307
bb4d2ac2 12308static const char *
dda8d76d 12309get_symbol_version_string (Filedata * filedata,
015dc7e1 12310 bool is_dynsym,
1449284b
NC
12311 const char * strtab,
12312 unsigned long int strtab_size,
12313 unsigned int si,
12314 Elf_Internal_Sym * psym,
12315 enum versioned_symbol_info * sym_info,
12316 unsigned short * vna_other)
bb4d2ac2 12317{
ab273396
AM
12318 unsigned char data[2];
12319 unsigned short vers_data;
12320 unsigned long offset;
7a815dd5 12321 unsigned short max_vd_ndx;
bb4d2ac2 12322
ab273396 12323 if (!is_dynsym
978c4450 12324 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12325 return NULL;
bb4d2ac2 12326
978c4450
AM
12327 offset = offset_from_vma (filedata,
12328 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12329 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12330
dda8d76d 12331 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12332 sizeof (data), 1, _("version data")) == NULL)
12333 return NULL;
12334
12335 vers_data = byte_get (data, 2);
bb4d2ac2 12336
1f6f5dba 12337 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12338 return NULL;
bb4d2ac2 12339
0b8b7609 12340 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12341 max_vd_ndx = 0;
12342
ab273396
AM
12343 /* Usually we'd only see verdef for defined symbols, and verneed for
12344 undefined symbols. However, symbols defined by the linker in
12345 .dynbss for variables copied from a shared library in order to
12346 avoid text relocations are defined yet have verneed. We could
12347 use a heuristic to detect the special case, for example, check
12348 for verneed first on symbols defined in SHT_NOBITS sections, but
12349 it is simpler and more reliable to just look for both verdef and
12350 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12351
ab273396
AM
12352 if (psym->st_shndx != SHN_UNDEF
12353 && vers_data != 0x8001
978c4450 12354 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12355 {
12356 Elf_Internal_Verdef ivd;
12357 Elf_Internal_Verdaux ivda;
12358 Elf_External_Verdaux evda;
12359 unsigned long off;
bb4d2ac2 12360
dda8d76d 12361 off = offset_from_vma (filedata,
978c4450 12362 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12363 sizeof (Elf_External_Verdef));
12364
12365 do
bb4d2ac2 12366 {
ab273396
AM
12367 Elf_External_Verdef evd;
12368
dda8d76d 12369 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12370 _("version def")) == NULL)
12371 {
12372 ivd.vd_ndx = 0;
12373 ivd.vd_aux = 0;
12374 ivd.vd_next = 0;
1f6f5dba 12375 ivd.vd_flags = 0;
ab273396
AM
12376 }
12377 else
bb4d2ac2 12378 {
ab273396
AM
12379 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12380 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12381 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12382 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12383 }
bb4d2ac2 12384
7a815dd5
L
12385 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12386 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12387
ab273396
AM
12388 off += ivd.vd_next;
12389 }
12390 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12391
ab273396
AM
12392 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12393 {
9abca702 12394 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12395 return NULL;
12396
ab273396
AM
12397 off -= ivd.vd_next;
12398 off += ivd.vd_aux;
bb4d2ac2 12399
dda8d76d 12400 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12401 _("version def aux")) != NULL)
12402 {
12403 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12404
ab273396 12405 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12406 return (ivda.vda_name < strtab_size
12407 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12408 }
12409 }
12410 }
bb4d2ac2 12411
978c4450 12412 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12413 {
12414 Elf_External_Verneed evn;
12415 Elf_Internal_Verneed ivn;
12416 Elf_Internal_Vernaux ivna;
bb4d2ac2 12417
dda8d76d 12418 offset = offset_from_vma (filedata,
978c4450 12419 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12420 sizeof evn);
12421 do
12422 {
12423 unsigned long vna_off;
bb4d2ac2 12424
dda8d76d 12425 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12426 _("version need")) == NULL)
12427 {
12428 ivna.vna_next = 0;
12429 ivna.vna_other = 0;
12430 ivna.vna_name = 0;
12431 break;
12432 }
bb4d2ac2 12433
ab273396
AM
12434 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12435 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12436
ab273396 12437 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12438
ab273396
AM
12439 do
12440 {
12441 Elf_External_Vernaux evna;
bb4d2ac2 12442
dda8d76d 12443 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12444 _("version need aux (3)")) == NULL)
bb4d2ac2 12445 {
ab273396
AM
12446 ivna.vna_next = 0;
12447 ivna.vna_other = 0;
12448 ivna.vna_name = 0;
bb4d2ac2 12449 }
bb4d2ac2 12450 else
bb4d2ac2 12451 {
ab273396
AM
12452 ivna.vna_other = BYTE_GET (evna.vna_other);
12453 ivna.vna_next = BYTE_GET (evna.vna_next);
12454 ivna.vna_name = BYTE_GET (evna.vna_name);
12455 }
bb4d2ac2 12456
ab273396
AM
12457 vna_off += ivna.vna_next;
12458 }
12459 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12460
ab273396
AM
12461 if (ivna.vna_other == vers_data)
12462 break;
bb4d2ac2 12463
ab273396
AM
12464 offset += ivn.vn_next;
12465 }
12466 while (ivn.vn_next != 0);
bb4d2ac2 12467
ab273396
AM
12468 if (ivna.vna_other == vers_data)
12469 {
12470 *sym_info = symbol_undefined;
12471 *vna_other = ivna.vna_other;
12472 return (ivna.vna_name < strtab_size
12473 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12474 }
7a815dd5
L
12475 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12476 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12477 return _("<corrupt>");
bb4d2ac2 12478 }
ab273396 12479 return NULL;
bb4d2ac2
L
12480}
12481
047c3dbf
NL
12482/* Display a symbol size on stdout. Format is based on --sym-base setting. */
12483
12484static unsigned int
12485print_dynamic_symbol_size (bfd_vma vma, int base)
12486{
12487 switch (base)
12488 {
12489 case 8:
12490 return print_vma (vma, OCTAL_5);
12491
12492 case 10:
12493 return print_vma (vma, UNSIGNED_5);
12494
12495 case 16:
12496 return print_vma (vma, PREFIX_HEX_5);
12497
12498 case 0:
12499 default:
12500 return print_vma (vma, DEC_5);
12501 }
12502}
12503
10ca4b04
L
12504static void
12505print_dynamic_symbol (Filedata *filedata, unsigned long si,
12506 Elf_Internal_Sym *symtab,
12507 Elf_Internal_Shdr *section,
12508 char *strtab, size_t strtab_size)
252b5132 12509{
10ca4b04
L
12510 const char *version_string;
12511 enum versioned_symbol_info sym_info;
12512 unsigned short vna_other;
23356397
NC
12513 bool is_valid;
12514 const char * sstr;
10ca4b04 12515 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 12516
10ca4b04
L
12517 printf ("%6ld: ", si);
12518 print_vma (psym->st_value, LONG_HEX);
12519 putchar (' ');
047c3dbf 12520 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
12521 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12522 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12523 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12524 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12525 else
252b5132 12526 {
10ca4b04 12527 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12528
10ca4b04
L
12529 printf (" %-7s", get_symbol_visibility (vis));
12530 /* Check to see if any other bits in the st_other field are set.
12531 Note - displaying this information disrupts the layout of the
12532 table being generated, but for the moment this case is very rare. */
12533 if (psym->st_other ^ vis)
12534 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12535 }
10ca4b04 12536 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 12537
23356397
NC
12538 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
12539 && psym->st_shndx < filedata->file_header.e_shnum
12540 && psym->st_name == 0)
12541 {
12542 is_valid = SECTION_NAME_VALID (filedata->section_headers + psym->st_shndx);
12543 sstr = is_valid ?
12544 SECTION_NAME_PRINT (filedata->section_headers + psym->st_shndx)
12545 : _("<corrupt>");
12546 }
12547 else
12548 {
12549 is_valid = VALID_SYMBOL_NAME (strtab, strtab_size, psym->st_name);
12550 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
12551 }
10ca4b04
L
12552
12553 version_string
12554 = get_symbol_version_string (filedata,
12555 (section == NULL
12556 || section->sh_type == SHT_DYNSYM),
12557 strtab, strtab_size, si,
12558 psym, &sym_info, &vna_other);
b9e920ec 12559
0942c7ab
NC
12560 int len_avail = 21;
12561 if (! do_wide && version_string != NULL)
12562 {
ddb43bab 12563 char buffer[16];
0942c7ab 12564
ddb43bab 12565 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
12566
12567 if (sym_info == symbol_undefined)
12568 len_avail -= sprintf (buffer," (%d)", vna_other);
12569 else if (sym_info != symbol_hidden)
12570 len_avail -= 1;
12571 }
12572
12573 print_symbol (len_avail, sstr);
b9e920ec 12574
10ca4b04
L
12575 if (version_string)
12576 {
12577 if (sym_info == symbol_undefined)
12578 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12579 else
10ca4b04
L
12580 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12581 version_string);
12582 }
6bd1a22c 12583
10ca4b04 12584 putchar ('\n');
6bd1a22c 12585
10ca4b04
L
12586 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12587 && section != NULL
12588 && si >= section->sh_info
12589 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12590 && filedata->file_header.e_machine != EM_MIPS
12591 /* Solaris binaries have been found to violate this requirement as
12592 well. Not sure if this is a bug or an ABI requirement. */
12593 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12594 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12595 si, printable_section_name (filedata, section), section->sh_info);
12596}
f16a9783 12597
0f03783c
NC
12598static const char *
12599get_lto_kind (unsigned int kind)
12600{
12601 switch (kind)
12602 {
12603 case 0: return "DEF";
12604 case 1: return "WEAKDEF";
12605 case 2: return "UNDEF";
12606 case 3: return "WEAKUNDEF";
12607 case 4: return "COMMON";
12608 default:
12609 break;
12610 }
12611
12612 static char buffer[30];
12613 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
12614 sprintf (buffer, "<unknown: %u>", kind);
12615 return buffer;
12616}
12617
12618static const char *
12619get_lto_visibility (unsigned int visibility)
12620{
12621 switch (visibility)
12622 {
12623 case 0: return "DEFAULT";
12624 case 1: return "PROTECTED";
12625 case 2: return "INTERNAL";
12626 case 3: return "HIDDEN";
12627 default:
12628 break;
12629 }
12630
12631 static char buffer[30];
12632 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
12633 sprintf (buffer, "<unknown: %u>", visibility);
12634 return buffer;
12635}
12636
12637static const char *
12638get_lto_sym_type (unsigned int sym_type)
12639{
12640 switch (sym_type)
12641 {
12642 case 0: return "UNKNOWN";
12643 case 1: return "FUNCTION";
12644 case 2: return "VARIABLE";
12645 default:
12646 break;
12647 }
12648
12649 static char buffer[30];
12650 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
12651 sprintf (buffer, "<unknown: %u>", sym_type);
12652 return buffer;
12653}
12654
12655/* Display an LTO format symbol table.
12656 FIXME: The format of LTO symbol tables is not formalized.
12657 So this code could need changing in the future. */
12658
015dc7e1 12659static bool
0f03783c
NC
12660display_lto_symtab (Filedata * filedata,
12661 Elf_Internal_Shdr * section)
12662{
12663 if (section->sh_size == 0)
12664 {
ca0e11aa
NC
12665 if (filedata->is_separate)
12666 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
12667 printable_section_name (filedata, section),
12668 filedata->file_name);
12669 else
12670 printf (_("\nLTO Symbol table '%s' is empty!\n"),
12671 printable_section_name (filedata, section));
047c3dbf 12672
015dc7e1 12673 return true;
0f03783c
NC
12674 }
12675
12676 if (section->sh_size > filedata->file_size)
12677 {
12678 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
12679 printable_section_name (filedata, section),
12680 (unsigned long) section->sh_size);
015dc7e1 12681 return false;
0f03783c
NC
12682 }
12683
12684 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
12685 section->sh_size, 1, _("LTO symbols"));
12686 if (alloced_data == NULL)
015dc7e1 12687 return false;
0f03783c
NC
12688
12689 /* Look for extended data for the symbol table. */
12690 Elf_Internal_Shdr * ext;
12691 void * ext_data_orig = NULL;
12692 char * ext_data = NULL;
12693 char * ext_data_end = NULL;
12694 char * ext_name = NULL;
12695
12696 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
b9e920ec 12697 SECTION_NAME (section) + sizeof (".gnu.lto_.symtab.") - 1) > 0
0f03783c
NC
12698 && ext_name != NULL /* Paranoia. */
12699 && (ext = find_section (filedata, ext_name)) != NULL)
12700 {
12701 if (ext->sh_size < 3)
12702 error (_("LTO Symbol extension table '%s' is empty!\n"),
12703 printable_section_name (filedata, ext));
12704 else
12705 {
12706 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
12707 ext->sh_size, 1,
12708 _("LTO ext symbol data"));
12709 if (ext_data != NULL)
12710 {
12711 ext_data_end = ext_data + ext->sh_size;
12712 if (* ext_data++ != 1)
12713 error (_("Unexpected version number in symbol extension table\n"));
12714 }
12715 }
12716 }
b9e920ec 12717
0f03783c
NC
12718 const unsigned char * data = (const unsigned char *) alloced_data;
12719 const unsigned char * end = data + section->sh_size;
12720
ca0e11aa
NC
12721 if (filedata->is_separate)
12722 printf (_("\nIn linked file '%s': "), filedata->file_name);
12723 else
12724 printf ("\n");
12725
0f03783c
NC
12726 if (ext_data_orig != NULL)
12727 {
12728 if (do_wide)
ca0e11aa 12729 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
12730 printable_section_name (filedata, section),
12731 printable_section_name (filedata, ext));
12732 else
12733 {
ca0e11aa 12734 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
12735 printable_section_name (filedata, section));
12736 printf (_(" and extension table '%s' contain:\n"),
12737 printable_section_name (filedata, ext));
12738 }
12739 }
12740 else
ca0e11aa 12741 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 12742 printable_section_name (filedata, section));
b9e920ec 12743
0f03783c 12744 /* FIXME: Add a wide version. */
b9e920ec 12745 if (ext_data_orig != NULL)
0f03783c
NC
12746 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
12747 else
12748 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
12749
12750 /* FIXME: We do not handle style prefixes. */
12751
12752 while (data < end)
12753 {
12754 const unsigned char * sym_name = data;
12755 data += strnlen ((const char *) sym_name, end - data) + 1;
12756 if (data >= end)
12757 goto fail;
12758
12759 const unsigned char * comdat_key = data;
12760 data += strnlen ((const char *) comdat_key, end - data) + 1;
12761 if (data >= end)
12762 goto fail;
12763
12764 if (data + 2 + 8 + 4 > end)
12765 goto fail;
12766
12767 unsigned int kind = *data++;
12768 unsigned int visibility = *data++;
12769
12770 elf_vma size = byte_get (data, 8);
12771 data += 8;
12772
12773 elf_vma slot = byte_get (data, 4);
12774 data += 4;
12775
12776 if (ext_data != NULL)
12777 {
12778 if (ext_data < (ext_data_end - 1))
12779 {
12780 unsigned int sym_type = * ext_data ++;
12781 unsigned int sec_kind = * ext_data ++;
12782
12783 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
12784 * comdat_key == 0 ? "-" : (char *) comdat_key,
12785 get_lto_kind (kind),
12786 get_lto_visibility (visibility),
12787 (long) size,
12788 (long) slot,
12789 get_lto_sym_type (sym_type),
12790 (long) sec_kind);
12791 print_symbol (6, (const char *) sym_name);
12792 }
12793 else
12794 {
12795 error (_("Ran out of LTO symbol extension data\n"));
12796 ext_data = NULL;
12797 /* FIXME: return FAIL result ? */
12798 }
12799 }
12800 else
12801 {
12802 printf (" %10s %10s %11s %08lx %08lx _",
12803 * comdat_key == 0 ? "-" : (char *) comdat_key,
12804 get_lto_kind (kind),
12805 get_lto_visibility (visibility),
12806 (long) size,
12807 (long) slot);
12808 print_symbol (21, (const char *) sym_name);
12809 }
12810 putchar ('\n');
12811 }
12812
12813 if (ext_data != NULL && ext_data < ext_data_end)
12814 {
12815 error (_("Data remains in the LTO symbol extension table\n"));
12816 goto fail;
12817 }
12818
12819 free (alloced_data);
12820 free (ext_data_orig);
12821 free (ext_name);
015dc7e1 12822 return true;
b9e920ec 12823
0f03783c
NC
12824 fail:
12825 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
12826 free (alloced_data);
12827 free (ext_data_orig);
12828 free (ext_name);
015dc7e1 12829 return false;
0f03783c
NC
12830}
12831
12832/* Display LTO symbol tables. */
12833
015dc7e1 12834static bool
0f03783c
NC
12835process_lto_symbol_tables (Filedata * filedata)
12836{
12837 Elf_Internal_Shdr * section;
12838 unsigned int i;
015dc7e1 12839 bool res = true;
0f03783c
NC
12840
12841 if (!do_lto_syms)
015dc7e1 12842 return true;
0f03783c
NC
12843
12844 if (filedata->section_headers == NULL)
015dc7e1 12845 return true;
0f03783c
NC
12846
12847 for (i = 0, section = filedata->section_headers;
12848 i < filedata->file_header.e_shnum;
12849 i++, section++)
b9e920ec 12850 if (SECTION_NAME_VALID (section)
08dedd66 12851 && startswith (SECTION_NAME (section), ".gnu.lto_.symtab."))
0f03783c
NC
12852 res &= display_lto_symtab (filedata, section);
12853
b9e920ec 12854 return res;
0f03783c
NC
12855}
12856
10ca4b04 12857/* Dump the symbol table. */
0f03783c 12858
015dc7e1 12859static bool
10ca4b04
L
12860process_symbol_table (Filedata * filedata)
12861{
12862 Elf_Internal_Shdr * section;
f16a9783 12863
10ca4b04 12864 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 12865 return true;
6bd1a22c 12866
978c4450 12867 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
12868 && do_syms
12869 && do_using_dynamic
978c4450
AM
12870 && filedata->dynamic_strings != NULL
12871 && filedata->dynamic_symbols != NULL)
6bd1a22c 12872 {
10ca4b04 12873 unsigned long si;
6bd1a22c 12874
ca0e11aa
NC
12875 if (filedata->is_separate)
12876 {
12877 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
12878 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
12879 filedata->num_dynamic_syms),
12880 filedata->file_name,
12881 filedata->num_dynamic_syms);
12882 }
12883 else
12884 {
12885 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12886 "\nSymbol table for image contains %lu entries:\n",
12887 filedata->num_dynamic_syms),
12888 filedata->num_dynamic_syms);
12889 }
10ca4b04
L
12890 if (is_32bit_elf)
12891 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12892 else
12893 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12894
978c4450
AM
12895 for (si = 0; si < filedata->num_dynamic_syms; si++)
12896 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
12897 filedata->dynamic_strings,
12898 filedata->dynamic_strings_length);
252b5132 12899 }
8b73c356 12900 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 12901 && filedata->section_headers != NULL)
252b5132 12902 {
b34976b6 12903 unsigned int i;
252b5132 12904
dda8d76d
NC
12905 for (i = 0, section = filedata->section_headers;
12906 i < filedata->file_header.e_shnum;
252b5132
RH
12907 i++, section++)
12908 {
2cf0635d 12909 char * strtab = NULL;
c256ffe7 12910 unsigned long int strtab_size = 0;
2cf0635d 12911 Elf_Internal_Sym * symtab;
ef3df110 12912 unsigned long si, num_syms;
252b5132 12913
2c610e4b
L
12914 if ((section->sh_type != SHT_SYMTAB
12915 && section->sh_type != SHT_DYNSYM)
12916 || (!do_syms
12917 && section->sh_type == SHT_SYMTAB))
252b5132
RH
12918 continue;
12919
dd24e3da
NC
12920 if (section->sh_entsize == 0)
12921 {
12922 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 12923 printable_section_name (filedata, section));
dd24e3da
NC
12924 continue;
12925 }
12926
d3a49aa8 12927 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
12928
12929 if (filedata->is_separate)
12930 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
12931 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
12932 num_syms),
12933 filedata->file_name,
12934 printable_section_name (filedata, section),
12935 num_syms);
12936 else
12937 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
12938 "\nSymbol table '%s' contains %lu entries:\n",
12939 num_syms),
12940 printable_section_name (filedata, section),
12941 num_syms);
dd24e3da 12942
f7a99963 12943 if (is_32bit_elf)
ca47b30c 12944 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 12945 else
ca47b30c 12946 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 12947
4de91c10 12948 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
12949 if (symtab == NULL)
12950 continue;
12951
dda8d76d 12952 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 12953 {
dda8d76d
NC
12954 strtab = filedata->string_table;
12955 strtab_size = filedata->string_table_length;
c256ffe7 12956 }
dda8d76d 12957 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 12958 {
2cf0635d 12959 Elf_Internal_Shdr * string_sec;
252b5132 12960
dda8d76d 12961 string_sec = filedata->section_headers + section->sh_link;
252b5132 12962
dda8d76d 12963 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
12964 1, string_sec->sh_size,
12965 _("string table"));
c256ffe7 12966 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
12967 }
12968
10ca4b04
L
12969 for (si = 0; si < num_syms; si++)
12970 print_dynamic_symbol (filedata, si, symtab, section,
12971 strtab, strtab_size);
252b5132
RH
12972
12973 free (symtab);
dda8d76d 12974 if (strtab != filedata->string_table)
252b5132
RH
12975 free (strtab);
12976 }
12977 }
12978 else if (do_syms)
12979 printf
12980 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
12981
978c4450 12982 if (do_histogram && filedata->buckets != NULL)
252b5132 12983 {
2cf0635d
NC
12984 unsigned long * lengths;
12985 unsigned long * counts;
66543521
AM
12986 unsigned long hn;
12987 bfd_vma si;
12988 unsigned long maxlength = 0;
12989 unsigned long nzero_counts = 0;
12990 unsigned long nsyms = 0;
6bd6a03d 12991 char *visited;
252b5132 12992
d3a49aa8
AM
12993 printf (ngettext ("\nHistogram for bucket list length "
12994 "(total of %lu bucket):\n",
12995 "\nHistogram for bucket list length "
12996 "(total of %lu buckets):\n",
978c4450
AM
12997 (unsigned long) filedata->nbuckets),
12998 (unsigned long) filedata->nbuckets);
252b5132 12999
978c4450
AM
13000 lengths = (unsigned long *) calloc (filedata->nbuckets,
13001 sizeof (*lengths));
252b5132
RH
13002 if (lengths == NULL)
13003 {
8b73c356 13004 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13005 goto err_out;
252b5132 13006 }
978c4450
AM
13007 visited = xcmalloc (filedata->nchains, 1);
13008 memset (visited, 0, filedata->nchains);
8b73c356
NC
13009
13010 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13011 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13012 {
978c4450 13013 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13014 {
b34976b6 13015 ++nsyms;
252b5132 13016 if (maxlength < ++lengths[hn])
b34976b6 13017 ++maxlength;
978c4450 13018 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13019 {
13020 error (_("histogram chain is corrupt\n"));
13021 break;
13022 }
13023 visited[si] = 1;
252b5132
RH
13024 }
13025 }
6bd6a03d 13026 free (visited);
252b5132 13027
3f5e193b 13028 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13029 if (counts == NULL)
13030 {
b2e951ec 13031 free (lengths);
8b73c356 13032 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13033 goto err_out;
252b5132
RH
13034 }
13035
978c4450 13036 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13037 ++counts[lengths[hn]];
252b5132 13038
978c4450 13039 if (filedata->nbuckets > 0)
252b5132 13040 {
66543521
AM
13041 unsigned long i;
13042 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13043 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13044 for (i = 1; i <= maxlength; ++i)
103f02d3 13045 {
66543521
AM
13046 nzero_counts += counts[i] * i;
13047 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13048 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13049 (nzero_counts * 100.0) / nsyms);
13050 }
252b5132
RH
13051 }
13052
13053 free (counts);
13054 free (lengths);
13055 }
13056
978c4450
AM
13057 free (filedata->buckets);
13058 filedata->buckets = NULL;
13059 filedata->nbuckets = 0;
13060 free (filedata->chains);
13061 filedata->chains = NULL;
252b5132 13062
978c4450 13063 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13064 {
2cf0635d
NC
13065 unsigned long * lengths;
13066 unsigned long * counts;
fdc90cb4
JJ
13067 unsigned long hn;
13068 unsigned long maxlength = 0;
13069 unsigned long nzero_counts = 0;
13070 unsigned long nsyms = 0;
fdc90cb4 13071
f16a9783 13072 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13073 "(total of %lu bucket):\n",
f16a9783 13074 "\nHistogram for `%s' bucket list length "
d3a49aa8 13075 "(total of %lu buckets):\n",
978c4450
AM
13076 (unsigned long) filedata->ngnubuckets),
13077 GNU_HASH_SECTION_NAME (filedata),
13078 (unsigned long) filedata->ngnubuckets);
8b73c356 13079
978c4450
AM
13080 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13081 sizeof (*lengths));
fdc90cb4
JJ
13082 if (lengths == NULL)
13083 {
8b73c356 13084 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13085 goto err_out;
fdc90cb4
JJ
13086 }
13087
fdc90cb4
JJ
13088 printf (_(" Length Number %% of total Coverage\n"));
13089
978c4450
AM
13090 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13091 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
13092 {
13093 bfd_vma off, length = 1;
13094
978c4450 13095 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13096 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13097 off < filedata->ngnuchains
13098 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13099 ++off)
fdc90cb4
JJ
13100 ++length;
13101 lengths[hn] = length;
13102 if (length > maxlength)
13103 maxlength = length;
13104 nsyms += length;
13105 }
13106
3f5e193b 13107 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13108 if (counts == NULL)
13109 {
b2e951ec 13110 free (lengths);
8b73c356 13111 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13112 goto err_out;
fdc90cb4
JJ
13113 }
13114
978c4450 13115 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13116 ++counts[lengths[hn]];
13117
978c4450 13118 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13119 {
13120 unsigned long j;
13121 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13122 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13123 for (j = 1; j <= maxlength; ++j)
13124 {
13125 nzero_counts += counts[j] * j;
13126 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13127 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13128 (nzero_counts * 100.0) / nsyms);
13129 }
13130 }
13131
13132 free (counts);
13133 free (lengths);
fdc90cb4 13134 }
978c4450
AM
13135 free (filedata->gnubuckets);
13136 filedata->gnubuckets = NULL;
13137 filedata->ngnubuckets = 0;
13138 free (filedata->gnuchains);
13139 filedata->gnuchains = NULL;
13140 filedata->ngnuchains = 0;
13141 free (filedata->mipsxlat);
13142 filedata->mipsxlat = NULL;
015dc7e1 13143 return true;
fd486f32
AM
13144
13145 err_out:
978c4450
AM
13146 free (filedata->gnubuckets);
13147 filedata->gnubuckets = NULL;
13148 filedata->ngnubuckets = 0;
13149 free (filedata->gnuchains);
13150 filedata->gnuchains = NULL;
13151 filedata->ngnuchains = 0;
13152 free (filedata->mipsxlat);
13153 filedata->mipsxlat = NULL;
13154 free (filedata->buckets);
13155 filedata->buckets = NULL;
13156 filedata->nbuckets = 0;
13157 free (filedata->chains);
13158 filedata->chains = NULL;
015dc7e1 13159 return false;
252b5132
RH
13160}
13161
015dc7e1 13162static bool
ca0e11aa 13163process_syminfo (Filedata * filedata)
252b5132 13164{
b4c96d0d 13165 unsigned int i;
252b5132 13166
978c4450 13167 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13168 || !do_dynamic)
13169 /* No syminfo, this is ok. */
015dc7e1 13170 return true;
252b5132
RH
13171
13172 /* There better should be a dynamic symbol section. */
978c4450 13173 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13174 return false;
252b5132 13175
ca0e11aa
NC
13176 if (filedata->is_separate)
13177 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13178 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13179 filedata->dynamic_syminfo_nent),
13180 filedata->file_name,
13181 filedata->dynamic_syminfo_offset,
13182 filedata->dynamic_syminfo_nent);
13183 else
d3a49aa8
AM
13184 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13185 "contains %d entry:\n",
13186 "\nDynamic info segment at offset 0x%lx "
13187 "contains %d entries:\n",
978c4450 13188 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13189 filedata->dynamic_syminfo_offset,
13190 filedata->dynamic_syminfo_nent);
252b5132
RH
13191
13192 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13193 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13194 {
978c4450 13195 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13196
31104126 13197 printf ("%4d: ", i);
978c4450 13198 if (i >= filedata->num_dynamic_syms)
4082ef84 13199 printf (_("<corrupt index>"));
978c4450
AM
13200 else if (VALID_DYNAMIC_NAME (filedata, filedata->dynamic_symbols[i].st_name))
13201 print_symbol (30, GET_DYNAMIC_NAME (filedata,
13202 filedata->dynamic_symbols[i].st_name));
d79b3d50 13203 else
978c4450 13204 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13205 putchar (' ');
252b5132 13206
978c4450 13207 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13208 {
13209 case SYMINFO_BT_SELF:
13210 fputs ("SELF ", stdout);
13211 break;
13212 case SYMINFO_BT_PARENT:
13213 fputs ("PARENT ", stdout);
13214 break;
13215 default:
978c4450
AM
13216 if (filedata->dynamic_syminfo[i].si_boundto > 0
13217 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
13218 && VALID_DYNAMIC_NAME (filedata,
13219 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13220 {
978c4450
AM
13221 print_symbol (10, GET_DYNAMIC_NAME (filedata,
13222 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13223 putchar (' ' );
13224 }
252b5132 13225 else
978c4450 13226 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13227 break;
13228 }
13229
13230 if (flags & SYMINFO_FLG_DIRECT)
13231 printf (" DIRECT");
13232 if (flags & SYMINFO_FLG_PASSTHRU)
13233 printf (" PASSTHRU");
13234 if (flags & SYMINFO_FLG_COPY)
13235 printf (" COPY");
13236 if (flags & SYMINFO_FLG_LAZYLOAD)
13237 printf (" LAZYLOAD");
13238
13239 puts ("");
13240 }
13241
015dc7e1 13242 return true;
252b5132
RH
13243}
13244
75802ccb
CE
13245/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13246 is contained by the region START .. END. The types of ADDR, START
13247 and END should all be the same. Note both ADDR + NELEM and END
13248 point to just beyond the end of the regions that are being tested. */
13249#define IN_RANGE(START,END,ADDR,NELEM) \
13250 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13251
cf13d699
NC
13252/* Check to see if the given reloc needs to be handled in a target specific
13253 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13254 FALSE.
13255
13256 If called with reloc == NULL, then this is a signal that reloc processing
13257 for the current section has finished, and any saved state should be
13258 discarded. */
09c11c86 13259
015dc7e1 13260static bool
dda8d76d
NC
13261target_specific_reloc_handling (Filedata * filedata,
13262 Elf_Internal_Rela * reloc,
13263 unsigned char * start,
13264 unsigned char * end,
13265 Elf_Internal_Sym * symtab,
13266 unsigned long num_syms)
252b5132 13267{
f84ce13b
NC
13268 unsigned int reloc_type = 0;
13269 unsigned long sym_index = 0;
13270
13271 if (reloc)
13272 {
dda8d76d 13273 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13274 sym_index = get_reloc_symindex (reloc->r_info);
13275 }
252b5132 13276
dda8d76d 13277 switch (filedata->file_header.e_machine)
252b5132 13278 {
13761a11
NC
13279 case EM_MSP430:
13280 case EM_MSP430_OLD:
13281 {
13282 static Elf_Internal_Sym * saved_sym = NULL;
13283
f84ce13b
NC
13284 if (reloc == NULL)
13285 {
13286 saved_sym = NULL;
015dc7e1 13287 return true;
f84ce13b
NC
13288 }
13289
13761a11
NC
13290 switch (reloc_type)
13291 {
13292 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13293 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13294 if (uses_msp430x_relocs (filedata))
13761a11 13295 break;
1a0670f3 13296 /* Fall through. */
13761a11 13297 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13298 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13299 /* PR 21139. */
13300 if (sym_index >= num_syms)
13301 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13302 sym_index);
13303 else
13304 saved_sym = symtab + sym_index;
015dc7e1 13305 return true;
13761a11
NC
13306
13307 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13308 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13309 goto handle_sym_diff;
0b4362b0 13310
13761a11
NC
13311 case 5: /* R_MSP430_16_BYTE */
13312 case 9: /* R_MSP430_8 */
7d81bc93 13313 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13314 if (uses_msp430x_relocs (filedata))
13761a11
NC
13315 break;
13316 goto handle_sym_diff;
13317
13318 case 2: /* R_MSP430_ABS16 */
13319 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13320 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13321 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13322 break;
13323 goto handle_sym_diff;
0b4362b0 13324
13761a11
NC
13325 handle_sym_diff:
13326 if (saved_sym != NULL)
13327 {
13328 bfd_vma value;
5a805384 13329 unsigned int reloc_size = 0;
7d81bc93
JL
13330 int leb_ret = 0;
13331 switch (reloc_type)
13332 {
13333 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13334 reloc_size = 4;
13335 break;
13336 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13337 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13338 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13339 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13340 &reloc_size, &leb_ret);
7d81bc93
JL
13341 break;
13342 default:
13343 reloc_size = 2;
13344 break;
13345 }
13761a11 13346
5a805384 13347 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13348 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13349 "ULEB128 value\n"),
13350 (long) reloc->r_offset);
13351 else if (sym_index >= num_syms)
f84ce13b
NC
13352 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13353 sym_index);
03f7786e 13354 else
f84ce13b
NC
13355 {
13356 value = reloc->r_addend + (symtab[sym_index].st_value
13357 - saved_sym->st_value);
13358
b32e566b 13359 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13360 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13361 else
13362 /* PR 21137 */
13363 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13364 (long) reloc->r_offset);
f84ce13b 13365 }
13761a11
NC
13366
13367 saved_sym = NULL;
015dc7e1 13368 return true;
13761a11
NC
13369 }
13370 break;
13371
13372 default:
13373 if (saved_sym != NULL)
071436c6 13374 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
13375 break;
13376 }
13377 break;
13378 }
13379
cf13d699
NC
13380 case EM_MN10300:
13381 case EM_CYGNUS_MN10300:
13382 {
13383 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 13384
f84ce13b
NC
13385 if (reloc == NULL)
13386 {
13387 saved_sym = NULL;
015dc7e1 13388 return true;
f84ce13b
NC
13389 }
13390
cf13d699
NC
13391 switch (reloc_type)
13392 {
13393 case 34: /* R_MN10300_ALIGN */
015dc7e1 13394 return true;
cf13d699 13395 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
13396 if (sym_index >= num_syms)
13397 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
13398 sym_index);
13399 else
13400 saved_sym = symtab + sym_index;
015dc7e1 13401 return true;
f84ce13b 13402
cf13d699
NC
13403 case 1: /* R_MN10300_32 */
13404 case 2: /* R_MN10300_16 */
13405 if (saved_sym != NULL)
13406 {
03f7786e 13407 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 13408 bfd_vma value;
252b5132 13409
f84ce13b
NC
13410 if (sym_index >= num_syms)
13411 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
13412 sym_index);
03f7786e 13413 else
f84ce13b
NC
13414 {
13415 value = reloc->r_addend + (symtab[sym_index].st_value
13416 - saved_sym->st_value);
13417
b32e566b 13418 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13419 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13420 else
13421 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
13422 (long) reloc->r_offset);
f84ce13b 13423 }
252b5132 13424
cf13d699 13425 saved_sym = NULL;
015dc7e1 13426 return true;
cf13d699
NC
13427 }
13428 break;
13429 default:
13430 if (saved_sym != NULL)
071436c6 13431 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
13432 break;
13433 }
13434 break;
13435 }
6ff71e76
NC
13436
13437 case EM_RL78:
13438 {
13439 static bfd_vma saved_sym1 = 0;
13440 static bfd_vma saved_sym2 = 0;
13441 static bfd_vma value;
13442
f84ce13b
NC
13443 if (reloc == NULL)
13444 {
13445 saved_sym1 = saved_sym2 = 0;
015dc7e1 13446 return true;
f84ce13b
NC
13447 }
13448
6ff71e76
NC
13449 switch (reloc_type)
13450 {
13451 case 0x80: /* R_RL78_SYM. */
13452 saved_sym1 = saved_sym2;
f84ce13b
NC
13453 if (sym_index >= num_syms)
13454 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
13455 sym_index);
13456 else
13457 {
13458 saved_sym2 = symtab[sym_index].st_value;
13459 saved_sym2 += reloc->r_addend;
13460 }
015dc7e1 13461 return true;
6ff71e76
NC
13462
13463 case 0x83: /* R_RL78_OPsub. */
13464 value = saved_sym1 - saved_sym2;
13465 saved_sym2 = saved_sym1 = 0;
015dc7e1 13466 return true;
6ff71e76
NC
13467 break;
13468
13469 case 0x41: /* R_RL78_ABS32. */
b32e566b 13470 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 13471 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
13472 else
13473 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13474 (long) reloc->r_offset);
6ff71e76 13475 value = 0;
015dc7e1 13476 return true;
6ff71e76
NC
13477
13478 case 0x43: /* R_RL78_ABS16. */
b32e566b 13479 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 13480 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
13481 else
13482 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13483 (long) reloc->r_offset);
6ff71e76 13484 value = 0;
015dc7e1 13485 return true;
6ff71e76
NC
13486
13487 default:
13488 break;
13489 }
13490 break;
13491 }
252b5132
RH
13492 }
13493
015dc7e1 13494 return false;
252b5132
RH
13495}
13496
aca88567
NC
13497/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
13498 DWARF debug sections. This is a target specific test. Note - we do not
13499 go through the whole including-target-headers-multiple-times route, (as
13500 we have already done with <elf/h8.h>) because this would become very
13501 messy and even then this function would have to contain target specific
13502 information (the names of the relocs instead of their numeric values).
13503 FIXME: This is not the correct way to solve this problem. The proper way
13504 is to have target specific reloc sizing and typing functions created by
13505 the reloc-macros.h header, in the same way that it already creates the
13506 reloc naming functions. */
13507
015dc7e1 13508static bool
dda8d76d 13509is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13510{
d347c9df 13511 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13512 switch (filedata->file_header.e_machine)
aca88567 13513 {
41e92641 13514 case EM_386:
22abe556 13515 case EM_IAMCU:
41e92641 13516 return reloc_type == 1; /* R_386_32. */
aca88567
NC
13517 case EM_68K:
13518 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
13519 case EM_860:
13520 return reloc_type == 1; /* R_860_32. */
13521 case EM_960:
13522 return reloc_type == 2; /* R_960_32. */
a06ea964 13523 case EM_AARCH64:
9282b95a
JW
13524 return (reloc_type == 258
13525 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
13526 case EM_BPF:
13527 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
13528 case EM_ADAPTEVA_EPIPHANY:
13529 return reloc_type == 3;
aca88567 13530 case EM_ALPHA:
137b6b5f 13531 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
13532 case EM_ARC:
13533 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
13534 case EM_ARC_COMPACT:
13535 case EM_ARC_COMPACT2:
13536 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
13537 case EM_ARM:
13538 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 13539 case EM_AVR_OLD:
aca88567
NC
13540 case EM_AVR:
13541 return reloc_type == 1;
13542 case EM_BLACKFIN:
13543 return reloc_type == 0x12; /* R_byte4_data. */
13544 case EM_CRIS:
13545 return reloc_type == 3; /* R_CRIS_32. */
13546 case EM_CR16:
13547 return reloc_type == 3; /* R_CR16_NUM32. */
13548 case EM_CRX:
13549 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
13550 case EM_CSKY:
13551 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
13552 case EM_CYGNUS_FRV:
13553 return reloc_type == 1;
41e92641
NC
13554 case EM_CYGNUS_D10V:
13555 case EM_D10V:
13556 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
13557 case EM_CYGNUS_D30V:
13558 case EM_D30V:
13559 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
13560 case EM_DLX:
13561 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
13562 case EM_CYGNUS_FR30:
13563 case EM_FR30:
13564 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
13565 case EM_FT32:
13566 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
13567 case EM_H8S:
13568 case EM_H8_300:
13569 case EM_H8_300H:
13570 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 13571 case EM_IA_64:
262cdac7
AM
13572 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
13573 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
13574 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
13575 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
13576 case EM_IP2K_OLD:
13577 case EM_IP2K:
13578 return reloc_type == 2; /* R_IP2K_32. */
13579 case EM_IQ2000:
13580 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
13581 case EM_LATTICEMICO32:
13582 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 13583 case EM_M32C_OLD:
aca88567
NC
13584 case EM_M32C:
13585 return reloc_type == 3; /* R_M32C_32. */
13586 case EM_M32R:
13587 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
13588 case EM_68HC11:
13589 case EM_68HC12:
13590 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 13591 case EM_S12Z:
2849d19f
JD
13592 return reloc_type == 7 || /* R_S12Z_EXT32 */
13593 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
13594 case EM_MCORE:
13595 return reloc_type == 1; /* R_MCORE_ADDR32. */
13596 case EM_CYGNUS_MEP:
13597 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
13598 case EM_METAG:
13599 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
13600 case EM_MICROBLAZE:
13601 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
13602 case EM_MIPS:
13603 return reloc_type == 2; /* R_MIPS_32. */
13604 case EM_MMIX:
13605 return reloc_type == 4; /* R_MMIX_32. */
13606 case EM_CYGNUS_MN10200:
13607 case EM_MN10200:
13608 return reloc_type == 1; /* R_MN10200_32. */
13609 case EM_CYGNUS_MN10300:
13610 case EM_MN10300:
13611 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
13612 case EM_MOXIE:
13613 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
13614 case EM_MSP430_OLD:
13615 case EM_MSP430:
13761a11 13616 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
13617 case EM_MT:
13618 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
13619 case EM_NDS32:
13620 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 13621 case EM_ALTERA_NIOS2:
36591ba1 13622 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
13623 case EM_NIOS32:
13624 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
13625 case EM_OR1K:
13626 return reloc_type == 1; /* R_OR1K_32. */
aca88567 13627 case EM_PARISC:
9abca702 13628 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 13629 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 13630 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
13631 case EM_PJ:
13632 case EM_PJ_OLD:
13633 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
13634 case EM_PPC64:
13635 return reloc_type == 1; /* R_PPC64_ADDR32. */
13636 case EM_PPC:
13637 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
13638 case EM_TI_PRU:
13639 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
13640 case EM_RISCV:
13641 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
13642 case EM_RL78:
13643 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
13644 case EM_RX:
13645 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
13646 case EM_S370:
13647 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
13648 case EM_S390_OLD:
13649 case EM_S390:
13650 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
13651 case EM_SCORE:
13652 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
13653 case EM_SH:
13654 return reloc_type == 1; /* R_SH_DIR32. */
13655 case EM_SPARC32PLUS:
13656 case EM_SPARCV9:
13657 case EM_SPARC:
13658 return reloc_type == 3 /* R_SPARC_32. */
13659 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
13660 case EM_SPU:
13661 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
13662 case EM_TI_C6000:
13663 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
13664 case EM_TILEGX:
13665 return reloc_type == 2; /* R_TILEGX_32. */
13666 case EM_TILEPRO:
13667 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
13668 case EM_CYGNUS_V850:
13669 case EM_V850:
13670 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
13671 case EM_V800:
13672 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
13673 case EM_VAX:
13674 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
13675 case EM_VISIUM:
13676 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
13677 case EM_WEBASSEMBLY:
13678 return reloc_type == 1; /* R_WASM32_32. */
aca88567 13679 case EM_X86_64:
8a9036a4 13680 case EM_L1OM:
7a9068fe 13681 case EM_K1OM:
aca88567 13682 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
13683 case EM_XC16X:
13684 case EM_C166:
13685 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
13686 case EM_XGATE:
13687 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
13688 case EM_XSTORMY16:
13689 return reloc_type == 1; /* R_XSTROMY16_32. */
13690 case EM_XTENSA_OLD:
13691 case EM_XTENSA:
13692 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
13693 case EM_Z80:
13694 return reloc_type == 6; /* R_Z80_32. */
aca88567 13695 default:
bee0ee85
NC
13696 {
13697 static unsigned int prev_warn = 0;
13698
13699 /* Avoid repeating the same warning multiple times. */
dda8d76d 13700 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 13701 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
13702 filedata->file_header.e_machine);
13703 prev_warn = filedata->file_header.e_machine;
015dc7e1 13704 return false;
bee0ee85 13705 }
aca88567
NC
13706 }
13707}
13708
13709/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13710 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
13711
015dc7e1 13712static bool
dda8d76d 13713is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13714{
dda8d76d 13715 switch (filedata->file_header.e_machine)
d347c9df 13716 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 13717 {
41e92641 13718 case EM_386:
22abe556 13719 case EM_IAMCU:
3e0873ac 13720 return reloc_type == 2; /* R_386_PC32. */
aca88567 13721 case EM_68K:
3e0873ac 13722 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
13723 case EM_AARCH64:
13724 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
13725 case EM_ADAPTEVA_EPIPHANY:
13726 return reloc_type == 6;
aca88567
NC
13727 case EM_ALPHA:
13728 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
13729 case EM_ARC_COMPACT:
13730 case EM_ARC_COMPACT2:
13731 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 13732 case EM_ARM:
3e0873ac 13733 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
13734 case EM_AVR_OLD:
13735 case EM_AVR:
13736 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
13737 case EM_MICROBLAZE:
13738 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
13739 case EM_OR1K:
13740 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 13741 case EM_PARISC:
85acf597 13742 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
13743 case EM_PPC:
13744 return reloc_type == 26; /* R_PPC_REL32. */
13745 case EM_PPC64:
3e0873ac 13746 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
13747 case EM_RISCV:
13748 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
13749 case EM_S390_OLD:
13750 case EM_S390:
3e0873ac 13751 return reloc_type == 5; /* R_390_PC32. */
aca88567 13752 case EM_SH:
3e0873ac 13753 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
13754 case EM_SPARC32PLUS:
13755 case EM_SPARCV9:
13756 case EM_SPARC:
3e0873ac 13757 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
13758 case EM_SPU:
13759 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
13760 case EM_TILEGX:
13761 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
13762 case EM_TILEPRO:
13763 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
13764 case EM_VISIUM:
13765 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 13766 case EM_X86_64:
8a9036a4 13767 case EM_L1OM:
7a9068fe 13768 case EM_K1OM:
3e0873ac 13769 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
13770 case EM_VAX:
13771 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
13772 case EM_XTENSA_OLD:
13773 case EM_XTENSA:
13774 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
13775 default:
13776 /* Do not abort or issue an error message here. Not all targets use
13777 pc-relative 32-bit relocs in their DWARF debug information and we
13778 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
13779 more helpful warning message will be generated by apply_relocations
13780 anyway, so just return. */
015dc7e1 13781 return false;
aca88567
NC
13782 }
13783}
13784
13785/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13786 a 64-bit absolute RELA relocation used in DWARF debug sections. */
13787
015dc7e1 13788static bool
dda8d76d 13789is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13790{
dda8d76d 13791 switch (filedata->file_header.e_machine)
aca88567 13792 {
a06ea964
NC
13793 case EM_AARCH64:
13794 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
13795 case EM_ALPHA:
13796 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 13797 case EM_IA_64:
262cdac7
AM
13798 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
13799 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
13800 case EM_PARISC:
13801 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
13802 case EM_PPC64:
13803 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
13804 case EM_RISCV:
13805 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
13806 case EM_SPARC32PLUS:
13807 case EM_SPARCV9:
13808 case EM_SPARC:
714da62f
NC
13809 return reloc_type == 32 /* R_SPARC_64. */
13810 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 13811 case EM_X86_64:
8a9036a4 13812 case EM_L1OM:
7a9068fe 13813 case EM_K1OM:
aca88567 13814 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
13815 case EM_S390_OLD:
13816 case EM_S390:
aa137e4d
NC
13817 return reloc_type == 22; /* R_S390_64. */
13818 case EM_TILEGX:
13819 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 13820 case EM_MIPS:
aa137e4d 13821 return reloc_type == 18; /* R_MIPS_64. */
aca88567 13822 default:
015dc7e1 13823 return false;
aca88567
NC
13824 }
13825}
13826
85acf597
RH
13827/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
13828 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
13829
015dc7e1 13830static bool
dda8d76d 13831is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 13832{
dda8d76d 13833 switch (filedata->file_header.e_machine)
85acf597 13834 {
a06ea964
NC
13835 case EM_AARCH64:
13836 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 13837 case EM_ALPHA:
aa137e4d 13838 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 13839 case EM_IA_64:
262cdac7
AM
13840 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
13841 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 13842 case EM_PARISC:
aa137e4d 13843 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 13844 case EM_PPC64:
aa137e4d 13845 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
13846 case EM_SPARC32PLUS:
13847 case EM_SPARCV9:
13848 case EM_SPARC:
aa137e4d 13849 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 13850 case EM_X86_64:
8a9036a4 13851 case EM_L1OM:
7a9068fe 13852 case EM_K1OM:
aa137e4d 13853 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
13854 case EM_S390_OLD:
13855 case EM_S390:
aa137e4d
NC
13856 return reloc_type == 23; /* R_S390_PC64. */
13857 case EM_TILEGX:
13858 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 13859 default:
015dc7e1 13860 return false;
85acf597
RH
13861 }
13862}
13863
4dc3c23d
AM
13864/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13865 a 24-bit absolute RELA relocation used in DWARF debug sections. */
13866
015dc7e1 13867static bool
dda8d76d 13868is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 13869{
dda8d76d 13870 switch (filedata->file_header.e_machine)
4dc3c23d
AM
13871 {
13872 case EM_CYGNUS_MN10200:
13873 case EM_MN10200:
13874 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
13875 case EM_FT32:
13876 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
13877 case EM_Z80:
13878 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 13879 default:
015dc7e1 13880 return false;
4dc3c23d
AM
13881 }
13882}
13883
aca88567
NC
13884/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13885 a 16-bit absolute RELA relocation used in DWARF debug sections. */
13886
015dc7e1 13887static bool
dda8d76d 13888is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 13889{
d347c9df 13890 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13891 switch (filedata->file_header.e_machine)
4b78141a 13892 {
886a2506
NC
13893 case EM_ARC:
13894 case EM_ARC_COMPACT:
13895 case EM_ARC_COMPACT2:
13896 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
13897 case EM_ADAPTEVA_EPIPHANY:
13898 return reloc_type == 5;
aca88567
NC
13899 case EM_AVR_OLD:
13900 case EM_AVR:
13901 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
13902 case EM_CYGNUS_D10V:
13903 case EM_D10V:
13904 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
13905 case EM_FT32:
13906 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
13907 case EM_H8S:
13908 case EM_H8_300:
13909 case EM_H8_300H:
aca88567
NC
13910 return reloc_type == R_H8_DIR16;
13911 case EM_IP2K_OLD:
13912 case EM_IP2K:
13913 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 13914 case EM_M32C_OLD:
f4236fe4
DD
13915 case EM_M32C:
13916 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
13917 case EM_CYGNUS_MN10200:
13918 case EM_MN10200:
13919 return reloc_type == 2; /* R_MN10200_16. */
13920 case EM_CYGNUS_MN10300:
13921 case EM_MN10300:
13922 return reloc_type == 2; /* R_MN10300_16. */
aca88567 13923 case EM_MSP430:
dda8d76d 13924 if (uses_msp430x_relocs (filedata))
13761a11 13925 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 13926 /* Fall through. */
78c8d46c 13927 case EM_MSP430_OLD:
aca88567 13928 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
13929 case EM_NDS32:
13930 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 13931 case EM_ALTERA_NIOS2:
36591ba1 13932 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
13933 case EM_NIOS32:
13934 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
13935 case EM_OR1K:
13936 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
13937 case EM_RISCV:
13938 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
13939 case EM_TI_PRU:
13940 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
13941 case EM_TI_C6000:
13942 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
13943 case EM_VISIUM:
13944 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
13945 case EM_XC16X:
13946 case EM_C166:
13947 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
13948 case EM_XGATE:
13949 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
13950 case EM_Z80:
13951 return reloc_type == 4; /* R_Z80_16. */
4b78141a 13952 default:
015dc7e1 13953 return false;
4b78141a
NC
13954 }
13955}
13956
39e07931
AS
13957/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13958 a 8-bit absolute RELA relocation used in DWARF debug sections. */
13959
015dc7e1 13960static bool
39e07931
AS
13961is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13962{
13963 switch (filedata->file_header.e_machine)
13964 {
13965 case EM_RISCV:
13966 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
13967 case EM_Z80:
13968 return reloc_type == 1; /* R_Z80_8. */
39e07931 13969 default:
015dc7e1 13970 return false;
39e07931
AS
13971 }
13972}
13973
13974/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13975 a 6-bit absolute RELA relocation used in DWARF debug sections. */
13976
015dc7e1 13977static bool
39e07931
AS
13978is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13979{
13980 switch (filedata->file_header.e_machine)
13981 {
13982 case EM_RISCV:
13983 return reloc_type == 53; /* R_RISCV_SET6. */
13984 default:
015dc7e1 13985 return false;
39e07931
AS
13986 }
13987}
13988
03336641
JW
13989/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13990 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
13991
015dc7e1 13992static bool
03336641
JW
13993is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13994{
13995 /* Please keep this table alpha-sorted for ease of visual lookup. */
13996 switch (filedata->file_header.e_machine)
13997 {
13998 case EM_RISCV:
13999 return reloc_type == 35; /* R_RISCV_ADD32. */
14000 default:
015dc7e1 14001 return false;
03336641
JW
14002 }
14003}
14004
14005/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14006 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14007
015dc7e1 14008static bool
03336641
JW
14009is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14010{
14011 /* Please keep this table alpha-sorted for ease of visual lookup. */
14012 switch (filedata->file_header.e_machine)
14013 {
14014 case EM_RISCV:
14015 return reloc_type == 39; /* R_RISCV_SUB32. */
14016 default:
015dc7e1 14017 return false;
03336641
JW
14018 }
14019}
14020
14021/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14022 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14023
015dc7e1 14024static bool
03336641
JW
14025is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14026{
14027 /* Please keep this table alpha-sorted for ease of visual lookup. */
14028 switch (filedata->file_header.e_machine)
14029 {
14030 case EM_RISCV:
14031 return reloc_type == 36; /* R_RISCV_ADD64. */
14032 default:
015dc7e1 14033 return false;
03336641
JW
14034 }
14035}
14036
14037/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14038 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14039
015dc7e1 14040static bool
03336641
JW
14041is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14042{
14043 /* Please keep this table alpha-sorted for ease of visual lookup. */
14044 switch (filedata->file_header.e_machine)
14045 {
14046 case EM_RISCV:
14047 return reloc_type == 40; /* R_RISCV_SUB64. */
14048 default:
015dc7e1 14049 return false;
03336641
JW
14050 }
14051}
14052
14053/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14054 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14055
015dc7e1 14056static bool
03336641
JW
14057is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14058{
14059 /* Please keep this table alpha-sorted for ease of visual lookup. */
14060 switch (filedata->file_header.e_machine)
14061 {
14062 case EM_RISCV:
14063 return reloc_type == 34; /* R_RISCV_ADD16. */
14064 default:
015dc7e1 14065 return false;
03336641
JW
14066 }
14067}
14068
14069/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14070 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14071
015dc7e1 14072static bool
03336641
JW
14073is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14074{
14075 /* Please keep this table alpha-sorted for ease of visual lookup. */
14076 switch (filedata->file_header.e_machine)
14077 {
14078 case EM_RISCV:
14079 return reloc_type == 38; /* R_RISCV_SUB16. */
14080 default:
015dc7e1 14081 return false;
03336641
JW
14082 }
14083}
14084
14085/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14086 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14087
015dc7e1 14088static bool
03336641
JW
14089is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14090{
14091 /* Please keep this table alpha-sorted for ease of visual lookup. */
14092 switch (filedata->file_header.e_machine)
14093 {
14094 case EM_RISCV:
14095 return reloc_type == 33; /* R_RISCV_ADD8. */
14096 default:
015dc7e1 14097 return false;
03336641
JW
14098 }
14099}
14100
14101/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14102 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14103
015dc7e1 14104static bool
03336641
JW
14105is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14106{
14107 /* Please keep this table alpha-sorted for ease of visual lookup. */
14108 switch (filedata->file_header.e_machine)
14109 {
14110 case EM_RISCV:
14111 return reloc_type == 37; /* R_RISCV_SUB8. */
14112 default:
015dc7e1 14113 return false;
03336641
JW
14114 }
14115}
14116
39e07931
AS
14117/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14118 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14119
015dc7e1 14120static bool
39e07931
AS
14121is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14122{
14123 switch (filedata->file_header.e_machine)
14124 {
14125 case EM_RISCV:
14126 return reloc_type == 52; /* R_RISCV_SUB6. */
14127 default:
015dc7e1 14128 return false;
39e07931
AS
14129 }
14130}
14131
2a7b2e88
JK
14132/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14133 relocation entries (possibly formerly used for SHT_GROUP sections). */
14134
015dc7e1 14135static bool
dda8d76d 14136is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14137{
dda8d76d 14138 switch (filedata->file_header.e_machine)
2a7b2e88 14139 {
cb8f3167 14140 case EM_386: /* R_386_NONE. */
d347c9df 14141 case EM_68K: /* R_68K_NONE. */
cfb8c092 14142 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14143 case EM_ALPHA: /* R_ALPHA_NONE. */
14144 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14145 case EM_ARC: /* R_ARC_NONE. */
886a2506 14146 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14147 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14148 case EM_ARM: /* R_ARM_NONE. */
d347c9df 14149 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 14150 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14151 case EM_FT32: /* R_FT32_NONE. */
14152 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14153 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14154 case EM_L1OM: /* R_X86_64_NONE. */
14155 case EM_M32R: /* R_M32R_NONE. */
14156 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14157 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14158 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14159 case EM_NIOS32: /* R_NIOS_NONE. */
14160 case EM_OR1K: /* R_OR1K_NONE. */
14161 case EM_PARISC: /* R_PARISC_NONE. */
14162 case EM_PPC64: /* R_PPC64_NONE. */
14163 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14164 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14165 case EM_S390: /* R_390_NONE. */
14166 case EM_S390_OLD:
14167 case EM_SH: /* R_SH_NONE. */
14168 case EM_SPARC32PLUS:
14169 case EM_SPARC: /* R_SPARC_NONE. */
14170 case EM_SPARCV9:
aa137e4d
NC
14171 case EM_TILEGX: /* R_TILEGX_NONE. */
14172 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14173 case EM_TI_C6000:/* R_C6000_NONE. */
14174 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 14175 case EM_XC16X:
6655dba2 14176 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14177 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14178 return reloc_type == 0;
d347c9df 14179
a06ea964
NC
14180 case EM_AARCH64:
14181 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14182 case EM_AVR_OLD:
14183 case EM_AVR:
14184 return (reloc_type == 0 /* R_AVR_NONE. */
14185 || reloc_type == 30 /* R_AVR_DIFF8. */
14186 || reloc_type == 31 /* R_AVR_DIFF16. */
14187 || reloc_type == 32 /* R_AVR_DIFF32. */);
14188 case EM_METAG:
14189 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
14190 case EM_NDS32:
14191 return (reloc_type == 0 /* R_XTENSA_NONE. */
14192 || reloc_type == 204 /* R_NDS32_DIFF8. */
14193 || reloc_type == 205 /* R_NDS32_DIFF16. */
14194 || reloc_type == 206 /* R_NDS32_DIFF32. */
14195 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
14196 case EM_TI_PRU:
14197 return (reloc_type == 0 /* R_PRU_NONE. */
14198 || reloc_type == 65 /* R_PRU_DIFF8. */
14199 || reloc_type == 66 /* R_PRU_DIFF16. */
14200 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14201 case EM_XTENSA_OLD:
14202 case EM_XTENSA:
4dc3c23d
AM
14203 return (reloc_type == 0 /* R_XTENSA_NONE. */
14204 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14205 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14206 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14207 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14208 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14209 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14210 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14211 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14212 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14213 }
015dc7e1 14214 return false;
2a7b2e88
JK
14215}
14216
d1c4b12b
NC
14217/* Returns TRUE if there is a relocation against
14218 section NAME at OFFSET bytes. */
14219
015dc7e1 14220bool
d1c4b12b
NC
14221reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14222{
14223 Elf_Internal_Rela * relocs;
14224 Elf_Internal_Rela * rp;
14225
14226 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14227 return false;
d1c4b12b
NC
14228
14229 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14230
14231 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14232 if (rp->r_offset == offset)
015dc7e1 14233 return true;
d1c4b12b 14234
015dc7e1 14235 return false;
d1c4b12b
NC
14236}
14237
cf13d699 14238/* Apply relocations to a section.
32ec8896
NC
14239 Returns TRUE upon success, FALSE otherwise.
14240 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14241 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14242 will be set to the number of relocs loaded.
14243
cf13d699 14244 Note: So far support has been added only for those relocations
32ec8896
NC
14245 which can be found in debug sections. FIXME: Add support for
14246 more relocations ? */
1b315056 14247
015dc7e1 14248static bool
dda8d76d 14249apply_relocations (Filedata * filedata,
d1c4b12b
NC
14250 const Elf_Internal_Shdr * section,
14251 unsigned char * start,
14252 bfd_size_type size,
1449284b 14253 void ** relocs_return,
d1c4b12b 14254 unsigned long * num_relocs_return)
1b315056 14255{
cf13d699 14256 Elf_Internal_Shdr * relsec;
0d2a7a93 14257 unsigned char * end = start + size;
cb8f3167 14258
d1c4b12b
NC
14259 if (relocs_return != NULL)
14260 {
14261 * (Elf_Internal_Rela **) relocs_return = NULL;
14262 * num_relocs_return = 0;
14263 }
14264
dda8d76d 14265 if (filedata->file_header.e_type != ET_REL)
32ec8896 14266 /* No relocs to apply. */
015dc7e1 14267 return true;
1b315056 14268
cf13d699 14269 /* Find the reloc section associated with the section. */
dda8d76d
NC
14270 for (relsec = filedata->section_headers;
14271 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14272 ++relsec)
252b5132 14273 {
015dc7e1 14274 bool is_rela;
41e92641 14275 unsigned long num_relocs;
2cf0635d
NC
14276 Elf_Internal_Rela * relocs;
14277 Elf_Internal_Rela * rp;
14278 Elf_Internal_Shdr * symsec;
14279 Elf_Internal_Sym * symtab;
ba5cdace 14280 unsigned long num_syms;
2cf0635d 14281 Elf_Internal_Sym * sym;
252b5132 14282
41e92641 14283 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14284 || relsec->sh_info >= filedata->file_header.e_shnum
14285 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14286 || relsec->sh_size == 0
dda8d76d 14287 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14288 continue;
428409d5 14289
a788aedd
AM
14290 symsec = filedata->section_headers + relsec->sh_link;
14291 if (symsec->sh_type != SHT_SYMTAB
14292 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14293 return false;
a788aedd 14294
41e92641
NC
14295 is_rela = relsec->sh_type == SHT_RELA;
14296
14297 if (is_rela)
14298 {
dda8d76d 14299 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14300 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14301 return false;
41e92641
NC
14302 }
14303 else
14304 {
dda8d76d 14305 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14306 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14307 return false;
41e92641
NC
14308 }
14309
14310 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14311 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14312 is_rela = false;
428409d5 14313
4de91c10 14314 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14315
41e92641 14316 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14317 {
015dc7e1
AM
14318 bfd_vma addend;
14319 unsigned int reloc_type;
14320 unsigned int reloc_size;
14321 bool reloc_inplace = false;
14322 bool reloc_subtract = false;
14323 unsigned char *rloc;
14324 unsigned long sym_index;
4b78141a 14325
dda8d76d 14326 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14327
dda8d76d 14328 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14329 continue;
dda8d76d 14330 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14331 continue;
dda8d76d
NC
14332 else if (is_32bit_abs_reloc (filedata, reloc_type)
14333 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14334 reloc_size = 4;
dda8d76d
NC
14335 else if (is_64bit_abs_reloc (filedata, reloc_type)
14336 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14337 reloc_size = 8;
dda8d76d 14338 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14339 reloc_size = 3;
dda8d76d 14340 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14341 reloc_size = 2;
39e07931
AS
14342 else if (is_8bit_abs_reloc (filedata, reloc_type)
14343 || is_6bit_abs_reloc (filedata, reloc_type))
14344 reloc_size = 1;
03336641
JW
14345 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14346 reloc_type))
14347 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14348 {
14349 reloc_size = 4;
015dc7e1 14350 reloc_inplace = true;
03336641
JW
14351 }
14352 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14353 reloc_type))
14354 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14355 {
14356 reloc_size = 8;
015dc7e1 14357 reloc_inplace = true;
03336641
JW
14358 }
14359 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14360 reloc_type))
14361 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14362 {
14363 reloc_size = 2;
015dc7e1 14364 reloc_inplace = true;
03336641
JW
14365 }
14366 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14367 reloc_type))
14368 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14369 {
14370 reloc_size = 1;
015dc7e1 14371 reloc_inplace = true;
03336641 14372 }
39e07931
AS
14373 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
14374 reloc_type)))
14375 {
14376 reloc_size = 1;
015dc7e1 14377 reloc_inplace = true;
39e07931 14378 }
aca88567 14379 else
4b78141a 14380 {
bee0ee85 14381 static unsigned int prev_reloc = 0;
dda8d76d 14382
bee0ee85
NC
14383 if (reloc_type != prev_reloc)
14384 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 14385 reloc_type, printable_section_name (filedata, section));
bee0ee85 14386 prev_reloc = reloc_type;
4b78141a
NC
14387 continue;
14388 }
103f02d3 14389
91d6fa6a 14390 rloc = start + rp->r_offset;
75802ccb 14391 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
14392 {
14393 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
14394 (unsigned long) rp->r_offset,
dda8d76d 14395 printable_section_name (filedata, section));
700dd8b7
L
14396 continue;
14397 }
103f02d3 14398
ba5cdace
NC
14399 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
14400 if (sym_index >= num_syms)
14401 {
14402 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 14403 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
14404 continue;
14405 }
14406 sym = symtab + sym_index;
41e92641
NC
14407
14408 /* If the reloc has a symbol associated with it,
55f25fc3
L
14409 make sure that it is of an appropriate type.
14410
14411 Relocations against symbols without type can happen.
14412 Gcc -feliminate-dwarf2-dups may generate symbols
14413 without type for debug info.
14414
14415 Icc generates relocations against function symbols
14416 instead of local labels.
14417
14418 Relocations against object symbols can happen, eg when
14419 referencing a global array. For an example of this see
14420 the _clz.o binary in libgcc.a. */
aca88567 14421 if (sym != symtab
b8871f35 14422 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 14423 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 14424 {
d3a49aa8 14425 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
14426 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
14427 printable_section_name (filedata, relsec),
d3a49aa8 14428 (long int)(rp - relocs));
aca88567 14429 continue;
5b18a4bc 14430 }
252b5132 14431
4dc3c23d
AM
14432 addend = 0;
14433 if (is_rela)
14434 addend += rp->r_addend;
c47320c3
AM
14435 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
14436 partial_inplace. */
4dc3c23d 14437 if (!is_rela
dda8d76d 14438 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 14439 && reloc_type == 1)
dda8d76d
NC
14440 || ((filedata->file_header.e_machine == EM_PJ
14441 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 14442 && reloc_type == 1)
dda8d76d
NC
14443 || ((filedata->file_header.e_machine == EM_D30V
14444 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
14445 && reloc_type == 12)
14446 || reloc_inplace)
39e07931
AS
14447 {
14448 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
14449 addend += byte_get (rloc, reloc_size) & 0x3f;
14450 else
14451 addend += byte_get (rloc, reloc_size);
14452 }
cb8f3167 14453
dda8d76d
NC
14454 if (is_32bit_pcrel_reloc (filedata, reloc_type)
14455 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
14456 {
14457 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 14458 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 14459 addend -= 8;
91d6fa6a 14460 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
14461 reloc_size);
14462 }
39e07931
AS
14463 else if (is_6bit_abs_reloc (filedata, reloc_type)
14464 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
14465 {
14466 if (reloc_subtract)
14467 addend -= sym->st_value;
14468 else
14469 addend += sym->st_value;
14470 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
14471 byte_put (rloc, addend, reloc_size);
14472 }
03336641
JW
14473 else if (reloc_subtract)
14474 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 14475 else
91d6fa6a 14476 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 14477 }
252b5132 14478
5b18a4bc 14479 free (symtab);
f84ce13b
NC
14480 /* Let the target specific reloc processing code know that
14481 we have finished with these relocs. */
dda8d76d 14482 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
14483
14484 if (relocs_return)
14485 {
14486 * (Elf_Internal_Rela **) relocs_return = relocs;
14487 * num_relocs_return = num_relocs;
14488 }
14489 else
14490 free (relocs);
14491
5b18a4bc
NC
14492 break;
14493 }
32ec8896 14494
015dc7e1 14495 return true;
5b18a4bc 14496}
103f02d3 14497
cf13d699 14498#ifdef SUPPORT_DISASSEMBLY
015dc7e1 14499static bool
dda8d76d 14500disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14501{
dda8d76d 14502 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 14503
74e1a04b 14504 /* FIXME: XXX -- to be done --- XXX */
cf13d699 14505
015dc7e1 14506 return true;
cf13d699
NC
14507}
14508#endif
14509
14510/* Reads in the contents of SECTION from FILE, returning a pointer
14511 to a malloc'ed buffer or NULL if something went wrong. */
14512
14513static char *
dda8d76d 14514get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14515{
dda8d76d 14516 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
14517
14518 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
14519 {
c6b78c96 14520 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 14521 printable_section_name (filedata, section));
cf13d699
NC
14522 return NULL;
14523 }
14524
dda8d76d 14525 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 14526 _("section contents"));
cf13d699
NC
14527}
14528
0e602686
NC
14529/* Uncompresses a section that was compressed using zlib, in place. */
14530
015dc7e1 14531static bool
dda8d76d
NC
14532uncompress_section_contents (unsigned char ** buffer,
14533 dwarf_size_type uncompressed_size,
14534 dwarf_size_type * size)
0e602686
NC
14535{
14536 dwarf_size_type compressed_size = *size;
14537 unsigned char * compressed_buffer = *buffer;
14538 unsigned char * uncompressed_buffer;
14539 z_stream strm;
14540 int rc;
14541
14542 /* It is possible the section consists of several compressed
14543 buffers concatenated together, so we uncompress in a loop. */
14544 /* PR 18313: The state field in the z_stream structure is supposed
14545 to be invisible to the user (ie us), but some compilers will
14546 still complain about it being used without initialisation. So
14547 we first zero the entire z_stream structure and then set the fields
14548 that we need. */
14549 memset (& strm, 0, sizeof strm);
14550 strm.avail_in = compressed_size;
14551 strm.next_in = (Bytef *) compressed_buffer;
14552 strm.avail_out = uncompressed_size;
14553 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
14554
14555 rc = inflateInit (& strm);
14556 while (strm.avail_in > 0)
14557 {
14558 if (rc != Z_OK)
3624a6c1 14559 break;
0e602686
NC
14560 strm.next_out = ((Bytef *) uncompressed_buffer
14561 + (uncompressed_size - strm.avail_out));
14562 rc = inflate (&strm, Z_FINISH);
14563 if (rc != Z_STREAM_END)
3624a6c1 14564 break;
0e602686
NC
14565 rc = inflateReset (& strm);
14566 }
ad92f33d
AM
14567 if (inflateEnd (& strm) != Z_OK
14568 || rc != Z_OK
0e602686
NC
14569 || strm.avail_out != 0)
14570 goto fail;
14571
14572 *buffer = uncompressed_buffer;
14573 *size = uncompressed_size;
015dc7e1 14574 return true;
0e602686
NC
14575
14576 fail:
14577 free (uncompressed_buffer);
14578 /* Indicate decompression failure. */
14579 *buffer = NULL;
015dc7e1 14580 return false;
0e602686 14581}
dd24e3da 14582
015dc7e1 14583static bool
dda8d76d 14584dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14585{
015dc7e1
AM
14586 Elf_Internal_Shdr *relsec;
14587 bfd_size_type num_bytes;
14588 unsigned char *data;
14589 unsigned char *end;
14590 unsigned char *real_start;
14591 unsigned char *start;
14592 bool some_strings_shown;
cf13d699 14593
dda8d76d 14594 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14595 if (start == NULL)
c6b78c96 14596 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 14597 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 14598
0e602686 14599 num_bytes = section->sh_size;
cf13d699 14600
835f2fae
NC
14601 if (filedata->is_separate)
14602 printf (_("\nString dump of section '%s' in linked file %s:\n"),
14603 printable_section_name (filedata, section),
14604 filedata->file_name);
14605 else
14606 printf (_("\nString dump of section '%s':\n"),
14607 printable_section_name (filedata, section));
cf13d699 14608
0e602686
NC
14609 if (decompress_dumps)
14610 {
14611 dwarf_size_type new_size = num_bytes;
14612 dwarf_size_type uncompressed_size = 0;
14613
14614 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14615 {
14616 Elf_Internal_Chdr chdr;
14617 unsigned int compression_header_size
ebdf1ebf
NC
14618 = get_compression_header (& chdr, (unsigned char *) start,
14619 num_bytes);
5844b465
NC
14620 if (compression_header_size == 0)
14621 /* An error message will have already been generated
14622 by get_compression_header. */
14623 goto error_out;
0e602686 14624
813dabb9 14625 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14626 {
813dabb9 14627 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14628 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14629 goto error_out;
813dabb9 14630 }
813dabb9
L
14631 uncompressed_size = chdr.ch_size;
14632 start += compression_header_size;
14633 new_size -= compression_header_size;
0e602686
NC
14634 }
14635 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14636 {
14637 /* Read the zlib header. In this case, it should be "ZLIB"
14638 followed by the uncompressed section size, 8 bytes in
14639 big-endian order. */
14640 uncompressed_size = start[4]; uncompressed_size <<= 8;
14641 uncompressed_size += start[5]; uncompressed_size <<= 8;
14642 uncompressed_size += start[6]; uncompressed_size <<= 8;
14643 uncompressed_size += start[7]; uncompressed_size <<= 8;
14644 uncompressed_size += start[8]; uncompressed_size <<= 8;
14645 uncompressed_size += start[9]; uncompressed_size <<= 8;
14646 uncompressed_size += start[10]; uncompressed_size <<= 8;
14647 uncompressed_size += start[11];
14648 start += 12;
14649 new_size -= 12;
14650 }
14651
1835f746
NC
14652 if (uncompressed_size)
14653 {
14654 if (uncompress_section_contents (& start,
14655 uncompressed_size, & new_size))
14656 num_bytes = new_size;
14657 else
14658 {
14659 error (_("Unable to decompress section %s\n"),
dda8d76d 14660 printable_section_name (filedata, section));
f761cb13 14661 goto error_out;
1835f746
NC
14662 }
14663 }
bc303e5d
NC
14664 else
14665 start = real_start;
0e602686 14666 }
fd8008d8 14667
cf13d699
NC
14668 /* If the section being dumped has relocations against it the user might
14669 be expecting these relocations to have been applied. Check for this
14670 case and issue a warning message in order to avoid confusion.
14671 FIXME: Maybe we ought to have an option that dumps a section with
14672 relocs applied ? */
dda8d76d
NC
14673 for (relsec = filedata->section_headers;
14674 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14675 ++relsec)
14676 {
14677 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14678 || relsec->sh_info >= filedata->file_header.e_shnum
14679 || filedata->section_headers + relsec->sh_info != section
cf13d699 14680 || relsec->sh_size == 0
dda8d76d 14681 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14682 continue;
14683
14684 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14685 break;
14686 }
14687
cf13d699
NC
14688 data = start;
14689 end = start + num_bytes;
015dc7e1 14690 some_strings_shown = false;
cf13d699 14691
ba3265d0
NC
14692#ifdef HAVE_MBSTATE_T
14693 mbstate_t state;
14694 /* Initialise the multibyte conversion state. */
14695 memset (& state, 0, sizeof (state));
14696#endif
14697
015dc7e1 14698 bool continuing = false;
ba3265d0 14699
cf13d699
NC
14700 while (data < end)
14701 {
14702 while (!ISPRINT (* data))
14703 if (++ data >= end)
14704 break;
14705
14706 if (data < end)
14707 {
071436c6
NC
14708 size_t maxlen = end - data;
14709
ba3265d0
NC
14710 if (continuing)
14711 {
14712 printf (" ");
015dc7e1 14713 continuing = false;
ba3265d0
NC
14714 }
14715 else
14716 {
d1ce973e 14717 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
14718 }
14719
4082ef84
NC
14720 if (maxlen > 0)
14721 {
f3da8a96 14722 char c = 0;
ba3265d0
NC
14723
14724 while (maxlen)
14725 {
14726 c = *data++;
14727
14728 if (c == 0)
14729 break;
14730
14731 /* PR 25543: Treat new-lines as string-ending characters. */
14732 if (c == '\n')
14733 {
14734 printf ("\\n\n");
14735 if (*data != 0)
015dc7e1 14736 continuing = true;
ba3265d0
NC
14737 break;
14738 }
14739
14740 /* Do not print control characters directly as they can affect terminal
14741 settings. Such characters usually appear in the names generated
14742 by the assembler for local labels. */
14743 if (ISCNTRL (c))
14744 {
14745 printf ("^%c", c + 0x40);
14746 }
14747 else if (ISPRINT (c))
14748 {
14749 putchar (c);
14750 }
14751 else
14752 {
14753 size_t n;
14754#ifdef HAVE_MBSTATE_T
14755 wchar_t w;
14756#endif
14757 /* Let printf do the hard work of displaying multibyte characters. */
14758 printf ("%.1s", data - 1);
14759#ifdef HAVE_MBSTATE_T
14760 /* Try to find out how many bytes made up the character that was
14761 just printed. Advance the symbol pointer past the bytes that
14762 were displayed. */
14763 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
14764#else
14765 n = 1;
14766#endif
14767 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
14768 data += (n - 1);
14769 }
14770 }
14771
14772 if (c != '\n')
14773 putchar ('\n');
4082ef84
NC
14774 }
14775 else
14776 {
14777 printf (_("<corrupt>\n"));
14778 data = end;
14779 }
015dc7e1 14780 some_strings_shown = true;
cf13d699
NC
14781 }
14782 }
14783
14784 if (! some_strings_shown)
14785 printf (_(" No strings found in this section."));
14786
0e602686 14787 free (real_start);
cf13d699
NC
14788
14789 putchar ('\n');
015dc7e1 14790 return true;
f761cb13
AM
14791
14792error_out:
14793 free (real_start);
015dc7e1 14794 return false;
cf13d699
NC
14795}
14796
015dc7e1
AM
14797static bool
14798dump_section_as_bytes (Elf_Internal_Shdr *section,
14799 Filedata *filedata,
14800 bool relocate)
cf13d699
NC
14801{
14802 Elf_Internal_Shdr * relsec;
0e602686
NC
14803 bfd_size_type bytes;
14804 bfd_size_type section_size;
14805 bfd_vma addr;
14806 unsigned char * data;
14807 unsigned char * real_start;
14808 unsigned char * start;
14809
dda8d76d 14810 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14811 if (start == NULL)
c6b78c96 14812 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 14813 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 14814
0e602686 14815 section_size = section->sh_size;
cf13d699 14816
835f2fae
NC
14817 if (filedata->is_separate)
14818 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
14819 printable_section_name (filedata, section),
14820 filedata->file_name);
14821 else
14822 printf (_("\nHex dump of section '%s':\n"),
14823 printable_section_name (filedata, section));
cf13d699 14824
0e602686
NC
14825 if (decompress_dumps)
14826 {
14827 dwarf_size_type new_size = section_size;
14828 dwarf_size_type uncompressed_size = 0;
14829
14830 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14831 {
14832 Elf_Internal_Chdr chdr;
14833 unsigned int compression_header_size
ebdf1ebf 14834 = get_compression_header (& chdr, start, section_size);
0e602686 14835
5844b465
NC
14836 if (compression_header_size == 0)
14837 /* An error message will have already been generated
14838 by get_compression_header. */
14839 goto error_out;
14840
813dabb9 14841 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14842 {
813dabb9 14843 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14844 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14845 goto error_out;
0e602686 14846 }
813dabb9
L
14847 uncompressed_size = chdr.ch_size;
14848 start += compression_header_size;
14849 new_size -= compression_header_size;
0e602686
NC
14850 }
14851 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14852 {
14853 /* Read the zlib header. In this case, it should be "ZLIB"
14854 followed by the uncompressed section size, 8 bytes in
14855 big-endian order. */
14856 uncompressed_size = start[4]; uncompressed_size <<= 8;
14857 uncompressed_size += start[5]; uncompressed_size <<= 8;
14858 uncompressed_size += start[6]; uncompressed_size <<= 8;
14859 uncompressed_size += start[7]; uncompressed_size <<= 8;
14860 uncompressed_size += start[8]; uncompressed_size <<= 8;
14861 uncompressed_size += start[9]; uncompressed_size <<= 8;
14862 uncompressed_size += start[10]; uncompressed_size <<= 8;
14863 uncompressed_size += start[11];
14864 start += 12;
14865 new_size -= 12;
14866 }
14867
f055032e
NC
14868 if (uncompressed_size)
14869 {
14870 if (uncompress_section_contents (& start, uncompressed_size,
14871 & new_size))
bc303e5d
NC
14872 {
14873 section_size = new_size;
14874 }
f055032e
NC
14875 else
14876 {
14877 error (_("Unable to decompress section %s\n"),
dda8d76d 14878 printable_section_name (filedata, section));
bc303e5d 14879 /* FIXME: Print the section anyway ? */
f761cb13 14880 goto error_out;
f055032e
NC
14881 }
14882 }
bc303e5d
NC
14883 else
14884 start = real_start;
0e602686 14885 }
14ae95f2 14886
cf13d699
NC
14887 if (relocate)
14888 {
dda8d76d 14889 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 14890 goto error_out;
cf13d699
NC
14891 }
14892 else
14893 {
14894 /* If the section being dumped has relocations against it the user might
14895 be expecting these relocations to have been applied. Check for this
14896 case and issue a warning message in order to avoid confusion.
14897 FIXME: Maybe we ought to have an option that dumps a section with
14898 relocs applied ? */
dda8d76d
NC
14899 for (relsec = filedata->section_headers;
14900 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14901 ++relsec)
14902 {
14903 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14904 || relsec->sh_info >= filedata->file_header.e_shnum
14905 || filedata->section_headers + relsec->sh_info != section
cf13d699 14906 || relsec->sh_size == 0
dda8d76d 14907 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14908 continue;
14909
14910 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14911 break;
14912 }
14913 }
14914
14915 addr = section->sh_addr;
0e602686 14916 bytes = section_size;
cf13d699
NC
14917 data = start;
14918
14919 while (bytes)
14920 {
14921 int j;
14922 int k;
14923 int lbytes;
14924
14925 lbytes = (bytes > 16 ? 16 : bytes);
14926
14927 printf (" 0x%8.8lx ", (unsigned long) addr);
14928
14929 for (j = 0; j < 16; j++)
14930 {
14931 if (j < lbytes)
14932 printf ("%2.2x", data[j]);
14933 else
14934 printf (" ");
14935
14936 if ((j & 3) == 3)
14937 printf (" ");
14938 }
14939
14940 for (j = 0; j < lbytes; j++)
14941 {
14942 k = data[j];
14943 if (k >= ' ' && k < 0x7f)
14944 printf ("%c", k);
14945 else
14946 printf (".");
14947 }
14948
14949 putchar ('\n');
14950
14951 data += lbytes;
14952 addr += lbytes;
14953 bytes -= lbytes;
14954 }
14955
0e602686 14956 free (real_start);
cf13d699
NC
14957
14958 putchar ('\n');
015dc7e1 14959 return true;
f761cb13
AM
14960
14961 error_out:
14962 free (real_start);
015dc7e1 14963 return false;
cf13d699
NC
14964}
14965
094e34f2 14966#ifdef ENABLE_LIBCTF
7d9813f1
NA
14967static ctf_sect_t *
14968shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
14969{
b9e920ec 14970 buf->cts_name = SECTION_NAME_PRINT (shdr);
7d9813f1
NA
14971 buf->cts_size = shdr->sh_size;
14972 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
14973
14974 return buf;
14975}
14976
14977/* Formatting callback function passed to ctf_dump. Returns either the pointer
14978 it is passed, or a pointer to newly-allocated storage, in which case
14979 dump_ctf() will free it when it no longer needs it. */
14980
2f6ecaed
NA
14981static char *
14982dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14983 char *s, void *arg)
7d9813f1 14984{
3e50a591 14985 const char *blanks = arg;
7d9813f1
NA
14986 char *new_s;
14987
3e50a591 14988 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
14989 return s;
14990 return new_s;
14991}
14992
926c9e76
NA
14993/* Dump CTF errors/warnings. */
14994static void
139633c3 14995dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
14996{
14997 ctf_next_t *it = NULL;
14998 char *errtext;
14999 int is_warning;
15000 int err;
15001
15002 /* Dump accumulated errors and warnings. */
15003 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15004 {
5e9b84f7 15005 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15006 errtext);
15007 free (errtext);
15008 }
15009 if (err != ECTF_NEXT_END)
15010 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15011}
15012
2f6ecaed
NA
15013/* Dump one CTF archive member. */
15014
15015static int
139633c3 15016dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
2f6ecaed 15017{
139633c3 15018 ctf_dict_t *parent = (ctf_dict_t *) arg;
2f6ecaed
NA
15019 const char *things[] = {"Header", "Labels", "Data objects",
15020 "Function objects", "Variables", "Types", "Strings",
15021 ""};
15022 const char **thing;
15023 size_t i;
8b37e7b6 15024 int err = 0;
2f6ecaed
NA
15025
15026 /* Only print out the name of non-default-named archive members.
15027 The name .ctf appears everywhere, even for things that aren't
15028 really archives, so printing it out is liable to be confusing.
15029
15030 The parent, if there is one, is the default-owned archive member:
15031 avoid importing it into itself. (This does no harm, but looks
15032 confusing.) */
15033
15034 if (strcmp (name, ".ctf") != 0)
15035 {
15036 printf (_("\nCTF archive member: %s:\n"), name);
15037 ctf_import (ctf, parent);
15038 }
15039
15040 for (i = 0, thing = things; *thing[0]; thing++, i++)
15041 {
15042 ctf_dump_state_t *s = NULL;
15043 char *item;
15044
15045 printf ("\n %s:\n", *thing);
15046 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15047 (void *) " ")) != NULL)
15048 {
15049 printf ("%s\n", item);
15050 free (item);
15051 }
15052
15053 if (ctf_errno (ctf))
15054 {
15055 error (_("Iteration failed: %s, %s\n"), *thing,
15056 ctf_errmsg (ctf_errno (ctf)));
8b37e7b6
NA
15057 err = 1;
15058 goto out;
2f6ecaed
NA
15059 }
15060 }
8b37e7b6
NA
15061
15062 out:
926c9e76 15063 dump_ctf_errs (ctf);
8b37e7b6 15064 return err;
2f6ecaed
NA
15065}
15066
015dc7e1 15067static bool
7d9813f1
NA
15068dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15069{
15070 Elf_Internal_Shdr * parent_sec = NULL;
15071 Elf_Internal_Shdr * symtab_sec = NULL;
15072 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15073 void * data = NULL;
15074 void * symdata = NULL;
15075 void * strdata = NULL;
15076 void * parentdata = NULL;
15077 ctf_sect_t ctfsect, symsect, strsect, parentsect;
15078 ctf_sect_t * symsectp = NULL;
15079 ctf_sect_t * strsectp = NULL;
2f6ecaed
NA
15080 ctf_archive_t * ctfa = NULL;
15081 ctf_archive_t * parenta = NULL, *lookparent;
139633c3 15082 ctf_dict_t * parent = NULL;
7d9813f1 15083
7d9813f1 15084 int err;
015dc7e1 15085 bool ret = false;
7d9813f1
NA
15086
15087 shdr_to_ctf_sect (&ctfsect, section, filedata);
15088 data = get_section_contents (section, filedata);
15089 ctfsect.cts_data = data;
15090
616febde 15091 if (!dump_ctf_symtab_name)
3d16b64e 15092 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15093
15094 if (!dump_ctf_strtab_name)
3d16b64e 15095 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15096
15097 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15098 {
15099 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15100 {
15101 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15102 goto fail;
15103 }
15104 if ((symdata = (void *) get_data (NULL, filedata,
15105 symtab_sec->sh_offset, 1,
15106 symtab_sec->sh_size,
15107 _("symbols"))) == NULL)
15108 goto fail;
15109 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15110 symsect.cts_data = symdata;
15111 }
835f2fae 15112
df16e041 15113 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15114 {
15115 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15116 {
15117 error (_("No string table section named %s\n"),
15118 dump_ctf_strtab_name);
15119 goto fail;
15120 }
15121 if ((strdata = (void *) get_data (NULL, filedata,
15122 strtab_sec->sh_offset, 1,
15123 strtab_sec->sh_size,
15124 _("strings"))) == NULL)
15125 goto fail;
15126 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15127 strsect.cts_data = strdata;
15128 }
835f2fae 15129
7d9813f1
NA
15130 if (dump_ctf_parent_name)
15131 {
15132 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
15133 {
15134 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
15135 goto fail;
15136 }
15137 if ((parentdata = (void *) get_data (NULL, filedata,
15138 parent_sec->sh_offset, 1,
15139 parent_sec->sh_size,
15140 _("CTF parent"))) == NULL)
15141 goto fail;
15142 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
15143 parentsect.cts_data = parentdata;
15144 }
15145
2f6ecaed
NA
15146 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15147 libctf papers over the difference, so we can pretend it is always an
15148 archive. Possibly open the parent as well, if one was specified. */
7d9813f1 15149
2f6ecaed 15150 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15151 {
926c9e76 15152 dump_ctf_errs (NULL);
7d9813f1
NA
15153 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15154 goto fail;
15155 }
15156
96c61be5
NA
15157 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15158 != ELFDATA2MSB);
15159
7d9813f1
NA
15160 if (parentdata)
15161 {
2f6ecaed
NA
15162 if ((parenta = ctf_arc_bufopen (&parentsect, symsectp, strsectp,
15163 &err)) == NULL)
7d9813f1 15164 {
926c9e76 15165 dump_ctf_errs (NULL);
7d9813f1
NA
15166 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15167 goto fail;
15168 }
2f6ecaed
NA
15169 lookparent = parenta;
15170 }
15171 else
15172 lookparent = ctfa;
7d9813f1 15173
2f6ecaed
NA
15174 /* Assume that the applicable parent archive member is the default one.
15175 (This is what all known implementations are expected to do, if they
15176 put CTFs and their parents in archives together.) */
ae41200b 15177 if ((parent = ctf_dict_open (lookparent, NULL, &err)) == NULL)
2f6ecaed 15178 {
926c9e76 15179 dump_ctf_errs (NULL);
2f6ecaed
NA
15180 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15181 goto fail;
7d9813f1
NA
15182 }
15183
015dc7e1 15184 ret = true;
7d9813f1 15185
835f2fae
NC
15186 if (filedata->is_separate)
15187 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15188 printable_section_name (filedata, section),
15189 filedata->file_name);
15190 else
15191 printf (_("\nDump of CTF section '%s':\n"),
15192 printable_section_name (filedata, section));
7d9813f1 15193
83d59285
NA
15194 if ((err = ctf_archive_iter (ctfa, dump_ctf_archive_member, parent)) != 0)
15195 {
15196 dump_ctf_errs (NULL);
15197 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
015dc7e1 15198 ret = false;
83d59285 15199 }
7d9813f1
NA
15200
15201 fail:
139633c3 15202 ctf_dict_close (parent);
2f6ecaed
NA
15203 ctf_close (ctfa);
15204 ctf_close (parenta);
7d9813f1
NA
15205 free (parentdata);
15206 free (data);
15207 free (symdata);
15208 free (strdata);
15209 return ret;
15210}
094e34f2 15211#endif
7d9813f1 15212
015dc7e1 15213static bool
dda8d76d
NC
15214load_specific_debug_section (enum dwarf_section_display_enum debug,
15215 const Elf_Internal_Shdr * sec,
15216 void * data)
1007acb3 15217{
2cf0635d 15218 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15219 char buf [64];
dda8d76d 15220 Filedata * filedata = (Filedata *) data;
9abca702 15221
19e6b90e 15222 if (section->start != NULL)
dda8d76d
NC
15223 {
15224 /* If it is already loaded, do nothing. */
15225 if (streq (section->filename, filedata->file_name))
015dc7e1 15226 return true;
dda8d76d
NC
15227 free (section->start);
15228 }
1007acb3 15229
19e6b90e
L
15230 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15231 section->address = sec->sh_addr;
dda8d76d
NC
15232 section->filename = filedata->file_name;
15233 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15234 sec->sh_offset, 1,
15235 sec->sh_size, buf);
59245841
NC
15236 if (section->start == NULL)
15237 section->size = 0;
15238 else
15239 {
77115a4a
L
15240 unsigned char *start = section->start;
15241 dwarf_size_type size = sec->sh_size;
dab394de 15242 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15243
15244 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15245 {
15246 Elf_Internal_Chdr chdr;
d8024a91
NC
15247 unsigned int compression_header_size;
15248
f53be977
L
15249 if (size < (is_32bit_elf
15250 ? sizeof (Elf32_External_Chdr)
15251 : sizeof (Elf64_External_Chdr)))
d8024a91 15252 {
55be8fd0 15253 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15254 section->name);
015dc7e1 15255 return false;
d8024a91
NC
15256 }
15257
ebdf1ebf 15258 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15259 if (compression_header_size == 0)
15260 /* An error message will have already been generated
15261 by get_compression_header. */
015dc7e1 15262 return false;
d8024a91 15263
813dabb9
L
15264 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15265 {
15266 warn (_("section '%s' has unsupported compress type: %d\n"),
15267 section->name, chdr.ch_type);
015dc7e1 15268 return false;
813dabb9 15269 }
dab394de 15270 uncompressed_size = chdr.ch_size;
77115a4a
L
15271 start += compression_header_size;
15272 size -= compression_header_size;
15273 }
dab394de
L
15274 else if (size > 12 && streq ((char *) start, "ZLIB"))
15275 {
15276 /* Read the zlib header. In this case, it should be "ZLIB"
15277 followed by the uncompressed section size, 8 bytes in
15278 big-endian order. */
15279 uncompressed_size = start[4]; uncompressed_size <<= 8;
15280 uncompressed_size += start[5]; uncompressed_size <<= 8;
15281 uncompressed_size += start[6]; uncompressed_size <<= 8;
15282 uncompressed_size += start[7]; uncompressed_size <<= 8;
15283 uncompressed_size += start[8]; uncompressed_size <<= 8;
15284 uncompressed_size += start[9]; uncompressed_size <<= 8;
15285 uncompressed_size += start[10]; uncompressed_size <<= 8;
15286 uncompressed_size += start[11];
15287 start += 12;
15288 size -= 12;
15289 }
15290
1835f746 15291 if (uncompressed_size)
77115a4a 15292 {
1835f746
NC
15293 if (uncompress_section_contents (&start, uncompressed_size,
15294 &size))
15295 {
15296 /* Free the compressed buffer, update the section buffer
15297 and the section size if uncompress is successful. */
15298 free (section->start);
15299 section->start = start;
15300 }
15301 else
15302 {
15303 error (_("Unable to decompress section %s\n"),
dda8d76d 15304 printable_section_name (filedata, sec));
015dc7e1 15305 return false;
1835f746 15306 }
77115a4a 15307 }
bc303e5d 15308
77115a4a 15309 section->size = size;
59245841 15310 }
4a114e3e 15311
1b315056 15312 if (section->start == NULL)
015dc7e1 15313 return false;
1b315056 15314
19e6b90e 15315 if (debug_displays [debug].relocate)
32ec8896 15316 {
dda8d76d 15317 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15318 & section->reloc_info, & section->num_relocs))
015dc7e1 15319 return false;
32ec8896 15320 }
d1c4b12b
NC
15321 else
15322 {
15323 section->reloc_info = NULL;
15324 section->num_relocs = 0;
15325 }
1007acb3 15326
015dc7e1 15327 return true;
1007acb3
L
15328}
15329
301a9420
AM
15330#if HAVE_LIBDEBUGINFOD
15331/* Return a hex string representation of the build-id. */
15332unsigned char *
15333get_build_id (void * data)
15334{
ca0e11aa 15335 Filedata * filedata = (Filedata *) data;
301a9420
AM
15336 Elf_Internal_Shdr * shdr;
15337 unsigned long i;
15338
55be8fd0
NC
15339 /* Iterate through notes to find note.gnu.build-id.
15340 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15341 for (i = 0, shdr = filedata->section_headers;
15342 i < filedata->file_header.e_shnum && shdr != NULL;
15343 i++, shdr++)
15344 {
15345 if (shdr->sh_type != SHT_NOTE)
15346 continue;
15347
15348 char * next;
15349 char * end;
15350 size_t data_remaining;
15351 size_t min_notesz;
15352 Elf_External_Note * enote;
15353 Elf_Internal_Note inote;
15354
15355 bfd_vma offset = shdr->sh_offset;
15356 bfd_vma align = shdr->sh_addralign;
15357 bfd_vma length = shdr->sh_size;
15358
15359 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15360 if (enote == NULL)
15361 continue;
15362
15363 if (align < 4)
15364 align = 4;
15365 else if (align != 4 && align != 8)
f761cb13
AM
15366 {
15367 free (enote);
15368 continue;
15369 }
301a9420
AM
15370
15371 end = (char *) enote + length;
15372 data_remaining = end - (char *) enote;
15373
15374 if (!is_ia64_vms (filedata))
15375 {
15376 min_notesz = offsetof (Elf_External_Note, name);
15377 if (data_remaining < min_notesz)
15378 {
55be8fd0
NC
15379 warn (_("\
15380malformed note encountered in section %s whilst scanning for build-id note\n"),
15381 printable_section_name (filedata, shdr));
f761cb13 15382 free (enote);
55be8fd0 15383 continue;
301a9420
AM
15384 }
15385 data_remaining -= min_notesz;
15386
15387 inote.type = BYTE_GET (enote->type);
15388 inote.namesz = BYTE_GET (enote->namesz);
15389 inote.namedata = enote->name;
15390 inote.descsz = BYTE_GET (enote->descsz);
15391 inote.descdata = ((char *) enote
15392 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15393 inote.descpos = offset + (inote.descdata - (char *) enote);
15394 next = ((char *) enote
15395 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15396 }
15397 else
15398 {
15399 Elf64_External_VMS_Note *vms_enote;
15400
15401 /* PR binutils/15191
15402 Make sure that there is enough data to read. */
15403 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15404 if (data_remaining < min_notesz)
15405 {
55be8fd0
NC
15406 warn (_("\
15407malformed note encountered in section %s whilst scanning for build-id note\n"),
15408 printable_section_name (filedata, shdr));
f761cb13 15409 free (enote);
55be8fd0 15410 continue;
301a9420
AM
15411 }
15412 data_remaining -= min_notesz;
15413
15414 vms_enote = (Elf64_External_VMS_Note *) enote;
15415 inote.type = BYTE_GET (vms_enote->type);
15416 inote.namesz = BYTE_GET (vms_enote->namesz);
15417 inote.namedata = vms_enote->name;
15418 inote.descsz = BYTE_GET (vms_enote->descsz);
15419 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15420 inote.descpos = offset + (inote.descdata - (char *) enote);
15421 next = inote.descdata + align_power (inote.descsz, 3);
15422 }
15423
15424 /* Skip malformed notes. */
15425 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
15426 || (size_t) (inote.descdata - inote.namedata) > data_remaining
15427 || (size_t) (next - inote.descdata) < inote.descsz
15428 || ((size_t) (next - inote.descdata)
15429 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
15430 {
55be8fd0
NC
15431 warn (_("\
15432malformed note encountered in section %s whilst scanning for build-id note\n"),
15433 printable_section_name (filedata, shdr));
f761cb13 15434 free (enote);
301a9420
AM
15435 continue;
15436 }
15437
15438 /* Check if this is the build-id note. If so then convert the build-id
15439 bytes to a hex string. */
15440 if (inote.namesz > 0
24d127aa 15441 && startswith (inote.namedata, "GNU")
301a9420
AM
15442 && inote.type == NT_GNU_BUILD_ID)
15443 {
15444 unsigned long j;
15445 char * build_id;
15446
15447 build_id = malloc (inote.descsz * 2 + 1);
15448 if (build_id == NULL)
f761cb13
AM
15449 {
15450 free (enote);
15451 return NULL;
15452 }
301a9420
AM
15453
15454 for (j = 0; j < inote.descsz; ++j)
15455 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
15456 build_id[inote.descsz * 2] = '\0';
f761cb13 15457 free (enote);
301a9420 15458
55be8fd0 15459 return (unsigned char *) build_id;
301a9420 15460 }
f761cb13 15461 free (enote);
301a9420
AM
15462 }
15463
15464 return NULL;
15465}
15466#endif /* HAVE_LIBDEBUGINFOD */
15467
657d0d47
CC
15468/* If this is not NULL, load_debug_section will only look for sections
15469 within the list of sections given here. */
32ec8896 15470static unsigned int * section_subset = NULL;
657d0d47 15471
015dc7e1 15472bool
dda8d76d 15473load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 15474{
2cf0635d
NC
15475 struct dwarf_section * section = &debug_displays [debug].section;
15476 Elf_Internal_Shdr * sec;
dda8d76d
NC
15477 Filedata * filedata = (Filedata *) data;
15478
f425ec66
NC
15479 /* Without section headers we cannot find any sections. */
15480 if (filedata->section_headers == NULL)
015dc7e1 15481 return false;
f425ec66 15482
9c1ce108
AM
15483 if (filedata->string_table == NULL
15484 && filedata->file_header.e_shstrndx != SHN_UNDEF
15485 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
15486 {
15487 Elf_Internal_Shdr * strs;
15488
15489 /* Read in the string table, so that we have section names to scan. */
15490 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
15491
4dff97b2 15492 if (strs != NULL && strs->sh_size != 0)
dda8d76d 15493 {
9c1ce108
AM
15494 filedata->string_table
15495 = (char *) get_data (NULL, filedata, strs->sh_offset,
15496 1, strs->sh_size, _("string table"));
dda8d76d 15497
9c1ce108
AM
15498 filedata->string_table_length
15499 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
15500 }
15501 }
d966045b
DJ
15502
15503 /* Locate the debug section. */
dda8d76d 15504 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
15505 if (sec != NULL)
15506 section->name = section->uncompressed_name;
15507 else
15508 {
dda8d76d 15509 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
15510 if (sec != NULL)
15511 section->name = section->compressed_name;
15512 }
15513 if (sec == NULL)
015dc7e1 15514 return false;
d966045b 15515
657d0d47
CC
15516 /* If we're loading from a subset of sections, and we've loaded
15517 a section matching this name before, it's likely that it's a
15518 different one. */
15519 if (section_subset != NULL)
15520 free_debug_section (debug);
15521
dda8d76d 15522 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
15523}
15524
19e6b90e
L
15525void
15526free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 15527{
2cf0635d 15528 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 15529
19e6b90e
L
15530 if (section->start == NULL)
15531 return;
1007acb3 15532
19e6b90e
L
15533 free ((char *) section->start);
15534 section->start = NULL;
15535 section->address = 0;
15536 section->size = 0;
a788aedd 15537
9db70fc3
AM
15538 free (section->reloc_info);
15539 section->reloc_info = NULL;
15540 section->num_relocs = 0;
1007acb3
L
15541}
15542
015dc7e1 15543static bool
dda8d76d 15544display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 15545{
b9e920ec 15546 char * name = SECTION_NAME_VALID (section) ? SECTION_NAME (section) : "";
dda8d76d 15547 const char * print_name = printable_section_name (filedata, section);
19e6b90e 15548 bfd_size_type length;
015dc7e1 15549 bool result = true;
3f5e193b 15550 int i;
1007acb3 15551
19e6b90e
L
15552 length = section->sh_size;
15553 if (length == 0)
1007acb3 15554 {
74e1a04b 15555 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 15556 return true;
1007acb3 15557 }
5dff79d8
NC
15558 if (section->sh_type == SHT_NOBITS)
15559 {
15560 /* There is no point in dumping the contents of a debugging section
15561 which has the NOBITS type - the bits in the file will be random.
15562 This can happen when a file containing a .eh_frame section is
15563 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
15564 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
15565 print_name);
015dc7e1 15566 return false;
5dff79d8 15567 }
1007acb3 15568
24d127aa 15569 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 15570 name = ".debug_info";
1007acb3 15571
19e6b90e
L
15572 /* See if we know how to display the contents of this section. */
15573 for (i = 0; i < max; i++)
d85bf2ba
NC
15574 {
15575 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
15576 struct dwarf_section_display * display = debug_displays + i;
15577 struct dwarf_section * sec = & display->section;
d966045b 15578
d85bf2ba 15579 if (streq (sec->uncompressed_name, name)
24d127aa 15580 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15581 || streq (sec->compressed_name, name))
15582 {
015dc7e1 15583 bool secondary = (section != find_section (filedata, name));
1007acb3 15584
d85bf2ba
NC
15585 if (secondary)
15586 free_debug_section (id);
dda8d76d 15587
24d127aa 15588 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15589 sec->name = name;
15590 else if (streq (sec->uncompressed_name, name))
15591 sec->name = sec->uncompressed_name;
15592 else
15593 sec->name = sec->compressed_name;
657d0d47 15594
d85bf2ba
NC
15595 if (load_specific_debug_section (id, section, filedata))
15596 {
15597 /* If this debug section is part of a CU/TU set in a .dwp file,
15598 restrict load_debug_section to the sections in that set. */
15599 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 15600
d85bf2ba 15601 result &= display->display (sec, filedata);
657d0d47 15602
d85bf2ba 15603 section_subset = NULL;
1007acb3 15604
44266f36 15605 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
15606 free_debug_section (id);
15607 }
15608 break;
15609 }
15610 }
1007acb3 15611
19e6b90e 15612 if (i == max)
1007acb3 15613 {
74e1a04b 15614 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 15615 result = false;
1007acb3
L
15616 }
15617
19e6b90e 15618 return result;
5b18a4bc 15619}
103f02d3 15620
aef1f6d0
DJ
15621/* Set DUMP_SECTS for all sections where dumps were requested
15622 based on section name. */
15623
15624static void
dda8d76d 15625initialise_dumps_byname (Filedata * filedata)
aef1f6d0 15626{
2cf0635d 15627 struct dump_list_entry * cur;
aef1f6d0
DJ
15628
15629 for (cur = dump_sects_byname; cur; cur = cur->next)
15630 {
15631 unsigned int i;
015dc7e1 15632 bool any = false;
aef1f6d0 15633
dda8d76d 15634 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
15635 if (SECTION_NAME_VALID (filedata->section_headers + i)
15636 && streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 15637 {
6431e409 15638 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 15639 any = true;
aef1f6d0
DJ
15640 }
15641
835f2fae
NC
15642 if (!any && !filedata->is_separate)
15643 warn (_("Section '%s' was not dumped because it does not exist\n"),
15644 cur->name);
aef1f6d0
DJ
15645 }
15646}
15647
015dc7e1 15648static bool
dda8d76d 15649process_section_contents (Filedata * filedata)
5b18a4bc 15650{
2cf0635d 15651 Elf_Internal_Shdr * section;
19e6b90e 15652 unsigned int i;
015dc7e1 15653 bool res = true;
103f02d3 15654
19e6b90e 15655 if (! do_dump)
015dc7e1 15656 return true;
103f02d3 15657
dda8d76d 15658 initialise_dumps_byname (filedata);
aef1f6d0 15659
dda8d76d 15660 for (i = 0, section = filedata->section_headers;
6431e409 15661 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
15662 i++, section++)
15663 {
6431e409 15664 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 15665
d6bfbc39
NC
15666 if (filedata->is_separate && ! process_links)
15667 dump &= DEBUG_DUMP;
047c3dbf 15668
19e6b90e 15669#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
15670 if (dump & DISASS_DUMP)
15671 {
15672 if (! disassemble_section (section, filedata))
015dc7e1 15673 res = false;
dda8d76d 15674 }
19e6b90e 15675#endif
dda8d76d 15676 if (dump & HEX_DUMP)
32ec8896 15677 {
015dc7e1
AM
15678 if (! dump_section_as_bytes (section, filedata, false))
15679 res = false;
32ec8896 15680 }
103f02d3 15681
dda8d76d 15682 if (dump & RELOC_DUMP)
32ec8896 15683 {
015dc7e1
AM
15684 if (! dump_section_as_bytes (section, filedata, true))
15685 res = false;
32ec8896 15686 }
09c11c86 15687
dda8d76d 15688 if (dump & STRING_DUMP)
32ec8896 15689 {
dda8d76d 15690 if (! dump_section_as_strings (section, filedata))
015dc7e1 15691 res = false;
32ec8896 15692 }
cf13d699 15693
dda8d76d 15694 if (dump & DEBUG_DUMP)
32ec8896 15695 {
dda8d76d 15696 if (! display_debug_section (i, section, filedata))
015dc7e1 15697 res = false;
32ec8896 15698 }
7d9813f1 15699
094e34f2 15700#ifdef ENABLE_LIBCTF
7d9813f1
NA
15701 if (dump & CTF_DUMP)
15702 {
15703 if (! dump_section_as_ctf (section, filedata))
015dc7e1 15704 res = false;
7d9813f1 15705 }
094e34f2 15706#endif
5b18a4bc 15707 }
103f02d3 15708
835f2fae 15709 if (! filedata->is_separate)
0ee3043f 15710 {
835f2fae
NC
15711 /* Check to see if the user requested a
15712 dump of a section that does not exist. */
15713 for (; i < filedata->dump.num_dump_sects; i++)
15714 if (filedata->dump.dump_sects[i])
15715 {
ca0e11aa 15716 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 15717 res = false;
835f2fae 15718 }
0ee3043f 15719 }
32ec8896
NC
15720
15721 return res;
5b18a4bc 15722}
103f02d3 15723
5b18a4bc 15724static void
19e6b90e 15725process_mips_fpe_exception (int mask)
5b18a4bc 15726{
19e6b90e
L
15727 if (mask)
15728 {
015dc7e1 15729 bool first = true;
32ec8896 15730
19e6b90e 15731 if (mask & OEX_FPU_INEX)
015dc7e1 15732 fputs ("INEX", stdout), first = false;
19e6b90e 15733 if (mask & OEX_FPU_UFLO)
015dc7e1 15734 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 15735 if (mask & OEX_FPU_OFLO)
015dc7e1 15736 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 15737 if (mask & OEX_FPU_DIV0)
015dc7e1 15738 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
15739 if (mask & OEX_FPU_INVAL)
15740 printf ("%sINVAL", first ? "" : "|");
15741 }
5b18a4bc 15742 else
19e6b90e 15743 fputs ("0", stdout);
5b18a4bc 15744}
103f02d3 15745
f6f0e17b
NC
15746/* Display's the value of TAG at location P. If TAG is
15747 greater than 0 it is assumed to be an unknown tag, and
15748 a message is printed to this effect. Otherwise it is
15749 assumed that a message has already been printed.
15750
15751 If the bottom bit of TAG is set it assumed to have a
15752 string value, otherwise it is assumed to have an integer
15753 value.
15754
15755 Returns an updated P pointing to the first unread byte
15756 beyond the end of TAG's value.
15757
15758 Reads at or beyond END will not be made. */
15759
15760static unsigned char *
60abdbed 15761display_tag_value (signed int tag,
f6f0e17b
NC
15762 unsigned char * p,
15763 const unsigned char * const end)
15764{
15765 unsigned long val;
15766
15767 if (tag > 0)
15768 printf (" Tag_unknown_%d: ", tag);
15769
15770 if (p >= end)
15771 {
4082ef84 15772 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
15773 }
15774 else if (tag & 1)
15775 {
071436c6
NC
15776 /* PR 17531 file: 027-19978-0.004. */
15777 size_t maxlen = (end - p) - 1;
15778
15779 putchar ('"');
4082ef84
NC
15780 if (maxlen > 0)
15781 {
15782 print_symbol ((int) maxlen, (const char *) p);
15783 p += strnlen ((char *) p, maxlen) + 1;
15784 }
15785 else
15786 {
15787 printf (_("<corrupt string tag>"));
15788 p = (unsigned char *) end;
15789 }
071436c6 15790 printf ("\"\n");
f6f0e17b
NC
15791 }
15792 else
15793 {
cd30bcef 15794 READ_ULEB (val, p, end);
f6f0e17b
NC
15795 printf ("%ld (0x%lx)\n", val, val);
15796 }
15797
4082ef84 15798 assert (p <= end);
f6f0e17b
NC
15799 return p;
15800}
15801
53a346d8
CZ
15802/* ARC ABI attributes section. */
15803
15804static unsigned char *
15805display_arc_attribute (unsigned char * p,
15806 const unsigned char * const end)
15807{
15808 unsigned int tag;
53a346d8
CZ
15809 unsigned int val;
15810
cd30bcef 15811 READ_ULEB (tag, p, end);
53a346d8
CZ
15812
15813 switch (tag)
15814 {
15815 case Tag_ARC_PCS_config:
cd30bcef 15816 READ_ULEB (val, p, end);
53a346d8
CZ
15817 printf (" Tag_ARC_PCS_config: ");
15818 switch (val)
15819 {
15820 case 0:
15821 printf (_("Absent/Non standard\n"));
15822 break;
15823 case 1:
15824 printf (_("Bare metal/mwdt\n"));
15825 break;
15826 case 2:
15827 printf (_("Bare metal/newlib\n"));
15828 break;
15829 case 3:
15830 printf (_("Linux/uclibc\n"));
15831 break;
15832 case 4:
15833 printf (_("Linux/glibc\n"));
15834 break;
15835 default:
15836 printf (_("Unknown\n"));
15837 break;
15838 }
15839 break;
15840
15841 case Tag_ARC_CPU_base:
cd30bcef 15842 READ_ULEB (val, p, end);
53a346d8
CZ
15843 printf (" Tag_ARC_CPU_base: ");
15844 switch (val)
15845 {
15846 default:
15847 case TAG_CPU_NONE:
15848 printf (_("Absent\n"));
15849 break;
15850 case TAG_CPU_ARC6xx:
15851 printf ("ARC6xx\n");
15852 break;
15853 case TAG_CPU_ARC7xx:
15854 printf ("ARC7xx\n");
15855 break;
15856 case TAG_CPU_ARCEM:
15857 printf ("ARCEM\n");
15858 break;
15859 case TAG_CPU_ARCHS:
15860 printf ("ARCHS\n");
15861 break;
15862 }
15863 break;
15864
15865 case Tag_ARC_CPU_variation:
cd30bcef 15866 READ_ULEB (val, p, end);
53a346d8
CZ
15867 printf (" Tag_ARC_CPU_variation: ");
15868 switch (val)
15869 {
15870 default:
15871 if (val > 0 && val < 16)
53a346d8 15872 printf ("Core%d\n", val);
d8cbc93b
JL
15873 else
15874 printf ("Unknown\n");
15875 break;
15876
53a346d8
CZ
15877 case 0:
15878 printf (_("Absent\n"));
15879 break;
15880 }
15881 break;
15882
15883 case Tag_ARC_CPU_name:
15884 printf (" Tag_ARC_CPU_name: ");
15885 p = display_tag_value (-1, p, end);
15886 break;
15887
15888 case Tag_ARC_ABI_rf16:
cd30bcef 15889 READ_ULEB (val, p, end);
53a346d8
CZ
15890 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
15891 break;
15892
15893 case Tag_ARC_ABI_osver:
cd30bcef 15894 READ_ULEB (val, p, end);
53a346d8
CZ
15895 printf (" Tag_ARC_ABI_osver: v%d\n", val);
15896 break;
15897
15898 case Tag_ARC_ABI_pic:
15899 case Tag_ARC_ABI_sda:
cd30bcef 15900 READ_ULEB (val, p, end);
53a346d8
CZ
15901 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
15902 : " Tag_ARC_ABI_pic: ");
15903 switch (val)
15904 {
15905 case 0:
15906 printf (_("Absent\n"));
15907 break;
15908 case 1:
15909 printf ("MWDT\n");
15910 break;
15911 case 2:
15912 printf ("GNU\n");
15913 break;
15914 default:
15915 printf (_("Unknown\n"));
15916 break;
15917 }
15918 break;
15919
15920 case Tag_ARC_ABI_tls:
cd30bcef 15921 READ_ULEB (val, p, end);
53a346d8
CZ
15922 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
15923 break;
15924
15925 case Tag_ARC_ABI_enumsize:
cd30bcef 15926 READ_ULEB (val, p, end);
53a346d8
CZ
15927 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
15928 _("smallest"));
15929 break;
15930
15931 case Tag_ARC_ABI_exceptions:
cd30bcef 15932 READ_ULEB (val, p, end);
53a346d8
CZ
15933 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
15934 : _("default"));
15935 break;
15936
15937 case Tag_ARC_ABI_double_size:
cd30bcef 15938 READ_ULEB (val, p, end);
53a346d8
CZ
15939 printf (" Tag_ARC_ABI_double_size: %d\n", val);
15940 break;
15941
15942 case Tag_ARC_ISA_config:
15943 printf (" Tag_ARC_ISA_config: ");
15944 p = display_tag_value (-1, p, end);
15945 break;
15946
15947 case Tag_ARC_ISA_apex:
15948 printf (" Tag_ARC_ISA_apex: ");
15949 p = display_tag_value (-1, p, end);
15950 break;
15951
15952 case Tag_ARC_ISA_mpy_option:
cd30bcef 15953 READ_ULEB (val, p, end);
53a346d8
CZ
15954 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
15955 break;
15956
db1e1b45 15957 case Tag_ARC_ATR_version:
cd30bcef 15958 READ_ULEB (val, p, end);
db1e1b45 15959 printf (" Tag_ARC_ATR_version: %d\n", val);
15960 break;
15961
53a346d8
CZ
15962 default:
15963 return display_tag_value (tag & 1, p, end);
15964 }
15965
15966 return p;
15967}
15968
11c1ff18
PB
15969/* ARM EABI attributes section. */
15970typedef struct
15971{
70e99720 15972 unsigned int tag;
2cf0635d 15973 const char * name;
11c1ff18 15974 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 15975 unsigned int type;
288f0ba2 15976 const char *const *table;
11c1ff18
PB
15977} arm_attr_public_tag;
15978
288f0ba2 15979static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 15980 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 15981 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 15982 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
288f0ba2
AM
15983static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
15984static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 15985 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 15986static const char *const arm_attr_tag_FP_arch[] =
bca38921 15987 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 15988 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
15989static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
15990static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
15991 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
15992 "NEON for ARMv8.1"};
288f0ba2 15993static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
15994 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
15995 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 15996static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 15997 {"V6", "SB", "TLS", "Unused"};
288f0ba2 15998static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 15999 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16000static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16001 {"Absolute", "PC-relative", "None"};
288f0ba2 16002static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16003 {"None", "direct", "GOT-indirect"};
288f0ba2 16004static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16005 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16006static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16007static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16008 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16009static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16010static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16011static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16012 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16013static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16014 {"Unused", "small", "int", "forced to int"};
288f0ba2 16015static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16016 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16017static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16018 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16019static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16020 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16021static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16022 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16023 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16024static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16025 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16026 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16027static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16028static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16029 {"Not Allowed", "Allowed"};
288f0ba2 16030static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16031 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16032static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16033 {"Follow architecture", "Allowed"};
288f0ba2 16034static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16035 {"Not Allowed", "Allowed"};
288f0ba2 16036static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16037 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16038 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16039static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16040static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16041 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16042 "TrustZone and Virtualization Extensions"};
288f0ba2 16043static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16044 {"Not Allowed", "Allowed"};
11c1ff18 16045
288f0ba2 16046static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16047 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16048
11c1ff18
PB
16049#define LOOKUP(id, name) \
16050 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16051static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16052{
16053 {4, "CPU_raw_name", 1, NULL},
16054 {5, "CPU_name", 1, NULL},
16055 LOOKUP(6, CPU_arch),
16056 {7, "CPU_arch_profile", 0, NULL},
16057 LOOKUP(8, ARM_ISA_use),
16058 LOOKUP(9, THUMB_ISA_use),
75375b3e 16059 LOOKUP(10, FP_arch),
11c1ff18 16060 LOOKUP(11, WMMX_arch),
f5f53991
AS
16061 LOOKUP(12, Advanced_SIMD_arch),
16062 LOOKUP(13, PCS_config),
11c1ff18
PB
16063 LOOKUP(14, ABI_PCS_R9_use),
16064 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16065 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16066 LOOKUP(17, ABI_PCS_GOT_use),
16067 LOOKUP(18, ABI_PCS_wchar_t),
16068 LOOKUP(19, ABI_FP_rounding),
16069 LOOKUP(20, ABI_FP_denormal),
16070 LOOKUP(21, ABI_FP_exceptions),
16071 LOOKUP(22, ABI_FP_user_exceptions),
16072 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16073 {24, "ABI_align_needed", 0, NULL},
16074 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16075 LOOKUP(26, ABI_enum_size),
16076 LOOKUP(27, ABI_HardFP_use),
16077 LOOKUP(28, ABI_VFP_args),
16078 LOOKUP(29, ABI_WMMX_args),
16079 LOOKUP(30, ABI_optimization_goals),
16080 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16081 {32, "compatibility", 0, NULL},
f5f53991 16082 LOOKUP(34, CPU_unaligned_access),
75375b3e 16083 LOOKUP(36, FP_HP_extension),
8e79c3df 16084 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16085 LOOKUP(42, MPextension_use),
16086 LOOKUP(44, DIV_use),
15afaa63 16087 LOOKUP(46, DSP_extension),
a7ad558c 16088 LOOKUP(48, MVE_arch),
f5f53991
AS
16089 {64, "nodefaults", 0, NULL},
16090 {65, "also_compatible_with", 0, NULL},
16091 LOOKUP(66, T2EE_use),
16092 {67, "conformance", 1, NULL},
16093 LOOKUP(68, Virtualization_use),
cd21e546 16094 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16095};
16096#undef LOOKUP
16097
11c1ff18 16098static unsigned char *
f6f0e17b
NC
16099display_arm_attribute (unsigned char * p,
16100 const unsigned char * const end)
11c1ff18 16101{
70e99720 16102 unsigned int tag;
70e99720 16103 unsigned int val;
2cf0635d 16104 arm_attr_public_tag * attr;
11c1ff18 16105 unsigned i;
70e99720 16106 unsigned int type;
11c1ff18 16107
cd30bcef 16108 READ_ULEB (tag, p, end);
11c1ff18 16109 attr = NULL;
2cf0635d 16110 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16111 {
16112 if (arm_attr_public_tags[i].tag == tag)
16113 {
16114 attr = &arm_attr_public_tags[i];
16115 break;
16116 }
16117 }
16118
16119 if (attr)
16120 {
16121 printf (" Tag_%s: ", attr->name);
16122 switch (attr->type)
16123 {
16124 case 0:
16125 switch (tag)
16126 {
16127 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16128 READ_ULEB (val, p, end);
11c1ff18
PB
16129 switch (val)
16130 {
2b692964
NC
16131 case 0: printf (_("None\n")); break;
16132 case 'A': printf (_("Application\n")); break;
16133 case 'R': printf (_("Realtime\n")); break;
16134 case 'M': printf (_("Microcontroller\n")); break;
16135 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16136 default: printf ("??? (%d)\n", val); break;
16137 }
16138 break;
16139
75375b3e 16140 case 24: /* Tag_align_needed. */
cd30bcef 16141 READ_ULEB (val, p, end);
75375b3e
MGD
16142 switch (val)
16143 {
2b692964
NC
16144 case 0: printf (_("None\n")); break;
16145 case 1: printf (_("8-byte\n")); break;
16146 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16147 case 3: printf ("??? 3\n"); break;
16148 default:
16149 if (val <= 12)
dd24e3da 16150 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16151 1 << val);
16152 else
16153 printf ("??? (%d)\n", val);
16154 break;
16155 }
16156 break;
16157
16158 case 25: /* Tag_align_preserved. */
cd30bcef 16159 READ_ULEB (val, p, end);
75375b3e
MGD
16160 switch (val)
16161 {
2b692964
NC
16162 case 0: printf (_("None\n")); break;
16163 case 1: printf (_("8-byte, except leaf SP\n")); break;
16164 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16165 case 3: printf ("??? 3\n"); break;
16166 default:
16167 if (val <= 12)
dd24e3da 16168 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16169 1 << val);
16170 else
16171 printf ("??? (%d)\n", val);
16172 break;
16173 }
16174 break;
16175
11c1ff18 16176 case 32: /* Tag_compatibility. */
071436c6 16177 {
cd30bcef 16178 READ_ULEB (val, p, end);
071436c6 16179 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16180 if (p < end - 1)
16181 {
16182 size_t maxlen = (end - p) - 1;
16183
16184 print_symbol ((int) maxlen, (const char *) p);
16185 p += strnlen ((char *) p, maxlen) + 1;
16186 }
16187 else
16188 {
16189 printf (_("<corrupt>"));
16190 p = (unsigned char *) end;
16191 }
071436c6 16192 putchar ('\n');
071436c6 16193 }
11c1ff18
PB
16194 break;
16195
f5f53991 16196 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16197 /* PR 17531: file: 001-505008-0.01. */
16198 if (p < end)
16199 p++;
2b692964 16200 printf (_("True\n"));
f5f53991
AS
16201 break;
16202
16203 case 65: /* Tag_also_compatible_with. */
cd30bcef 16204 READ_ULEB (val, p, end);
f5f53991
AS
16205 if (val == 6 /* Tag_CPU_arch. */)
16206 {
cd30bcef 16207 READ_ULEB (val, p, end);
071436c6 16208 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16209 printf ("??? (%d)\n", val);
16210 else
16211 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16212 }
16213 else
16214 printf ("???\n");
071436c6
NC
16215 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16216 ;
f5f53991
AS
16217 break;
16218
11c1ff18 16219 default:
bee0ee85
NC
16220 printf (_("<unknown: %d>\n"), tag);
16221 break;
11c1ff18
PB
16222 }
16223 return p;
16224
16225 case 1:
f6f0e17b 16226 return display_tag_value (-1, p, end);
11c1ff18 16227 case 2:
f6f0e17b 16228 return display_tag_value (0, p, end);
11c1ff18
PB
16229
16230 default:
16231 assert (attr->type & 0x80);
cd30bcef 16232 READ_ULEB (val, p, end);
11c1ff18
PB
16233 type = attr->type & 0x7f;
16234 if (val >= type)
16235 printf ("??? (%d)\n", val);
16236 else
16237 printf ("%s\n", attr->table[val]);
16238 return p;
16239 }
16240 }
11c1ff18 16241
f6f0e17b 16242 return display_tag_value (tag, p, end);
11c1ff18
PB
16243}
16244
104d59d1 16245static unsigned char *
60bca95a 16246display_gnu_attribute (unsigned char * p,
60abdbed 16247 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16248 const unsigned char * const end)
104d59d1 16249{
cd30bcef 16250 unsigned int tag;
60abdbed 16251 unsigned int val;
104d59d1 16252
cd30bcef 16253 READ_ULEB (tag, p, end);
104d59d1
JM
16254
16255 /* Tag_compatibility is the only generic GNU attribute defined at
16256 present. */
16257 if (tag == 32)
16258 {
cd30bcef 16259 READ_ULEB (val, p, end);
071436c6
NC
16260
16261 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16262 if (p == end)
16263 {
071436c6 16264 printf (_("<corrupt>\n"));
f6f0e17b
NC
16265 warn (_("corrupt vendor attribute\n"));
16266 }
16267 else
16268 {
4082ef84
NC
16269 if (p < end - 1)
16270 {
16271 size_t maxlen = (end - p) - 1;
071436c6 16272
4082ef84
NC
16273 print_symbol ((int) maxlen, (const char *) p);
16274 p += strnlen ((char *) p, maxlen) + 1;
16275 }
16276 else
16277 {
16278 printf (_("<corrupt>"));
16279 p = (unsigned char *) end;
16280 }
071436c6 16281 putchar ('\n');
f6f0e17b 16282 }
104d59d1
JM
16283 return p;
16284 }
16285
16286 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16287 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16288
f6f0e17b 16289 return display_tag_value (tag, p, end);
104d59d1
JM
16290}
16291
85f7484a
PB
16292static unsigned char *
16293display_m68k_gnu_attribute (unsigned char * p,
16294 unsigned int tag,
16295 const unsigned char * const end)
16296{
16297 unsigned int val;
16298
16299 if (tag == Tag_GNU_M68K_ABI_FP)
16300 {
16301 printf (" Tag_GNU_M68K_ABI_FP: ");
16302 if (p == end)
16303 {
16304 printf (_("<corrupt>\n"));
16305 return p;
16306 }
16307 READ_ULEB (val, p, end);
16308
16309 if (val > 3)
16310 printf ("(%#x), ", val);
16311
16312 switch (val & 3)
16313 {
16314 case 0:
16315 printf (_("unspecified hard/soft float\n"));
16316 break;
16317 case 1:
16318 printf (_("hard float\n"));
16319 break;
16320 case 2:
16321 printf (_("soft float\n"));
16322 break;
16323 }
16324 return p;
16325 }
16326
16327 return display_tag_value (tag & 1, p, end);
16328}
16329
34c8bcba 16330static unsigned char *
f6f0e17b 16331display_power_gnu_attribute (unsigned char * p,
60abdbed 16332 unsigned int tag,
f6f0e17b 16333 const unsigned char * const end)
34c8bcba 16334{
005d79fd 16335 unsigned int val;
34c8bcba
JM
16336
16337 if (tag == Tag_GNU_Power_ABI_FP)
16338 {
34c8bcba 16339 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16340 if (p == end)
005d79fd
AM
16341 {
16342 printf (_("<corrupt>\n"));
16343 return p;
16344 }
cd30bcef 16345 READ_ULEB (val, p, end);
60bca95a 16346
005d79fd
AM
16347 if (val > 15)
16348 printf ("(%#x), ", val);
16349
16350 switch (val & 3)
34c8bcba
JM
16351 {
16352 case 0:
005d79fd 16353 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16354 break;
16355 case 1:
005d79fd 16356 printf (_("hard float, "));
34c8bcba
JM
16357 break;
16358 case 2:
005d79fd 16359 printf (_("soft float, "));
34c8bcba 16360 break;
3c7b9897 16361 case 3:
005d79fd 16362 printf (_("single-precision hard float, "));
3c7b9897 16363 break;
005d79fd
AM
16364 }
16365
16366 switch (val & 0xC)
16367 {
16368 case 0:
16369 printf (_("unspecified long double\n"));
16370 break;
16371 case 4:
16372 printf (_("128-bit IBM long double\n"));
16373 break;
16374 case 8:
16375 printf (_("64-bit long double\n"));
16376 break;
16377 case 12:
16378 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16379 break;
16380 }
16381 return p;
005d79fd 16382 }
34c8bcba 16383
c6e65352
DJ
16384 if (tag == Tag_GNU_Power_ABI_Vector)
16385 {
c6e65352 16386 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 16387 if (p == end)
005d79fd
AM
16388 {
16389 printf (_("<corrupt>\n"));
16390 return p;
16391 }
cd30bcef 16392 READ_ULEB (val, p, end);
005d79fd
AM
16393
16394 if (val > 3)
16395 printf ("(%#x), ", val);
16396
16397 switch (val & 3)
c6e65352
DJ
16398 {
16399 case 0:
005d79fd 16400 printf (_("unspecified\n"));
c6e65352
DJ
16401 break;
16402 case 1:
005d79fd 16403 printf (_("generic\n"));
c6e65352
DJ
16404 break;
16405 case 2:
16406 printf ("AltiVec\n");
16407 break;
16408 case 3:
16409 printf ("SPE\n");
16410 break;
c6e65352
DJ
16411 }
16412 return p;
005d79fd 16413 }
c6e65352 16414
f82e0623
NF
16415 if (tag == Tag_GNU_Power_ABI_Struct_Return)
16416 {
005d79fd 16417 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 16418 if (p == end)
f6f0e17b 16419 {
005d79fd 16420 printf (_("<corrupt>\n"));
f6f0e17b
NC
16421 return p;
16422 }
cd30bcef 16423 READ_ULEB (val, p, end);
0b4362b0 16424
005d79fd
AM
16425 if (val > 2)
16426 printf ("(%#x), ", val);
16427
16428 switch (val & 3)
16429 {
16430 case 0:
16431 printf (_("unspecified\n"));
16432 break;
16433 case 1:
16434 printf ("r3/r4\n");
16435 break;
16436 case 2:
16437 printf (_("memory\n"));
16438 break;
16439 case 3:
16440 printf ("???\n");
16441 break;
16442 }
f82e0623
NF
16443 return p;
16444 }
16445
f6f0e17b 16446 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
16447}
16448
643f7afb
AK
16449static unsigned char *
16450display_s390_gnu_attribute (unsigned char * p,
60abdbed 16451 unsigned int tag,
643f7afb
AK
16452 const unsigned char * const end)
16453{
cd30bcef 16454 unsigned int val;
643f7afb
AK
16455
16456 if (tag == Tag_GNU_S390_ABI_Vector)
16457 {
643f7afb 16458 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 16459 READ_ULEB (val, p, end);
643f7afb
AK
16460
16461 switch (val)
16462 {
16463 case 0:
16464 printf (_("any\n"));
16465 break;
16466 case 1:
16467 printf (_("software\n"));
16468 break;
16469 case 2:
16470 printf (_("hardware\n"));
16471 break;
16472 default:
16473 printf ("??? (%d)\n", val);
16474 break;
16475 }
16476 return p;
16477 }
16478
16479 return display_tag_value (tag & 1, p, end);
16480}
16481
9e8c70f9 16482static void
60abdbed 16483display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
16484{
16485 if (mask)
16486 {
015dc7e1 16487 bool first = true;
071436c6 16488
9e8c70f9 16489 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 16490 fputs ("mul32", stdout), first = false;
9e8c70f9 16491 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 16492 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 16493 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 16494 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 16495 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 16496 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 16497 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 16498 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 16499 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 16500 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 16501 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 16502 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 16503 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 16504 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 16505 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 16506 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 16507 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 16508 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 16509 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 16510 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 16511 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 16512 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 16513 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 16514 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 16515 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 16516 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 16517 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 16518 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 16519 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 16520 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
16521 }
16522 else
071436c6
NC
16523 fputc ('0', stdout);
16524 fputc ('\n', stdout);
9e8c70f9
DM
16525}
16526
3d68f91c 16527static void
60abdbed 16528display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
16529{
16530 if (mask)
16531 {
015dc7e1 16532 bool first = true;
071436c6 16533
3d68f91c 16534 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 16535 fputs ("fjathplus", stdout), first = false;
3d68f91c 16536 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 16537 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 16538 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 16539 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 16540 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 16541 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 16542 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 16543 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 16544 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 16545 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 16546 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 16547 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 16548 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 16549 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 16550 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 16551 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 16552 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 16553 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 16554 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 16555 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
16556 }
16557 else
071436c6
NC
16558 fputc ('0', stdout);
16559 fputc ('\n', stdout);
3d68f91c
JM
16560}
16561
9e8c70f9 16562static unsigned char *
f6f0e17b 16563display_sparc_gnu_attribute (unsigned char * p,
60abdbed 16564 unsigned int tag,
f6f0e17b 16565 const unsigned char * const end)
9e8c70f9 16566{
cd30bcef 16567 unsigned int val;
3d68f91c 16568
9e8c70f9
DM
16569 if (tag == Tag_GNU_Sparc_HWCAPS)
16570 {
cd30bcef 16571 READ_ULEB (val, p, end);
9e8c70f9 16572 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
16573 display_sparc_hwcaps (val);
16574 return p;
3d68f91c
JM
16575 }
16576 if (tag == Tag_GNU_Sparc_HWCAPS2)
16577 {
cd30bcef 16578 READ_ULEB (val, p, end);
3d68f91c
JM
16579 printf (" Tag_GNU_Sparc_HWCAPS2: ");
16580 display_sparc_hwcaps2 (val);
16581 return p;
16582 }
9e8c70f9 16583
f6f0e17b 16584 return display_tag_value (tag, p, end);
9e8c70f9
DM
16585}
16586
351cdf24 16587static void
32ec8896 16588print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
16589{
16590 switch (val)
16591 {
16592 case Val_GNU_MIPS_ABI_FP_ANY:
16593 printf (_("Hard or soft float\n"));
16594 break;
16595 case Val_GNU_MIPS_ABI_FP_DOUBLE:
16596 printf (_("Hard float (double precision)\n"));
16597 break;
16598 case Val_GNU_MIPS_ABI_FP_SINGLE:
16599 printf (_("Hard float (single precision)\n"));
16600 break;
16601 case Val_GNU_MIPS_ABI_FP_SOFT:
16602 printf (_("Soft float\n"));
16603 break;
16604 case Val_GNU_MIPS_ABI_FP_OLD_64:
16605 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
16606 break;
16607 case Val_GNU_MIPS_ABI_FP_XX:
16608 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
16609 break;
16610 case Val_GNU_MIPS_ABI_FP_64:
16611 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
16612 break;
16613 case Val_GNU_MIPS_ABI_FP_64A:
16614 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
16615 break;
3350cc01
CM
16616 case Val_GNU_MIPS_ABI_FP_NAN2008:
16617 printf (_("NaN 2008 compatibility\n"));
16618 break;
351cdf24
MF
16619 default:
16620 printf ("??? (%d)\n", val);
16621 break;
16622 }
16623}
16624
2cf19d5c 16625static unsigned char *
f6f0e17b 16626display_mips_gnu_attribute (unsigned char * p,
60abdbed 16627 unsigned int tag,
f6f0e17b 16628 const unsigned char * const end)
2cf19d5c 16629{
2cf19d5c
JM
16630 if (tag == Tag_GNU_MIPS_ABI_FP)
16631 {
32ec8896 16632 unsigned int val;
f6f0e17b 16633
2cf19d5c 16634 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 16635 READ_ULEB (val, p, end);
351cdf24 16636 print_mips_fp_abi_value (val);
2cf19d5c
JM
16637 return p;
16638 }
16639
a9f58168
CF
16640 if (tag == Tag_GNU_MIPS_ABI_MSA)
16641 {
32ec8896 16642 unsigned int val;
a9f58168 16643
a9f58168 16644 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 16645 READ_ULEB (val, p, end);
a9f58168
CF
16646
16647 switch (val)
16648 {
16649 case Val_GNU_MIPS_ABI_MSA_ANY:
16650 printf (_("Any MSA or not\n"));
16651 break;
16652 case Val_GNU_MIPS_ABI_MSA_128:
16653 printf (_("128-bit MSA\n"));
16654 break;
16655 default:
16656 printf ("??? (%d)\n", val);
16657 break;
16658 }
16659 return p;
16660 }
16661
f6f0e17b 16662 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
16663}
16664
59e6276b 16665static unsigned char *
f6f0e17b
NC
16666display_tic6x_attribute (unsigned char * p,
16667 const unsigned char * const end)
59e6276b 16668{
60abdbed 16669 unsigned int tag;
cd30bcef 16670 unsigned int val;
59e6276b 16671
cd30bcef 16672 READ_ULEB (tag, p, end);
59e6276b
JM
16673
16674 switch (tag)
16675 {
75fa6dc1 16676 case Tag_ISA:
75fa6dc1 16677 printf (" Tag_ISA: ");
cd30bcef 16678 READ_ULEB (val, p, end);
59e6276b
JM
16679
16680 switch (val)
16681 {
75fa6dc1 16682 case C6XABI_Tag_ISA_none:
59e6276b
JM
16683 printf (_("None\n"));
16684 break;
75fa6dc1 16685 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
16686 printf ("C62x\n");
16687 break;
75fa6dc1 16688 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
16689 printf ("C67x\n");
16690 break;
75fa6dc1 16691 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
16692 printf ("C67x+\n");
16693 break;
75fa6dc1 16694 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
16695 printf ("C64x\n");
16696 break;
75fa6dc1 16697 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
16698 printf ("C64x+\n");
16699 break;
75fa6dc1 16700 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
16701 printf ("C674x\n");
16702 break;
16703 default:
16704 printf ("??? (%d)\n", val);
16705 break;
16706 }
16707 return p;
16708
87779176 16709 case Tag_ABI_wchar_t:
87779176 16710 printf (" Tag_ABI_wchar_t: ");
cd30bcef 16711 READ_ULEB (val, p, end);
87779176
JM
16712 switch (val)
16713 {
16714 case 0:
16715 printf (_("Not used\n"));
16716 break;
16717 case 1:
16718 printf (_("2 bytes\n"));
16719 break;
16720 case 2:
16721 printf (_("4 bytes\n"));
16722 break;
16723 default:
16724 printf ("??? (%d)\n", val);
16725 break;
16726 }
16727 return p;
16728
16729 case Tag_ABI_stack_align_needed:
87779176 16730 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 16731 READ_ULEB (val, p, end);
87779176
JM
16732 switch (val)
16733 {
16734 case 0:
16735 printf (_("8-byte\n"));
16736 break;
16737 case 1:
16738 printf (_("16-byte\n"));
16739 break;
16740 default:
16741 printf ("??? (%d)\n", val);
16742 break;
16743 }
16744 return p;
16745
16746 case Tag_ABI_stack_align_preserved:
cd30bcef 16747 READ_ULEB (val, p, end);
87779176
JM
16748 printf (" Tag_ABI_stack_align_preserved: ");
16749 switch (val)
16750 {
16751 case 0:
16752 printf (_("8-byte\n"));
16753 break;
16754 case 1:
16755 printf (_("16-byte\n"));
16756 break;
16757 default:
16758 printf ("??? (%d)\n", val);
16759 break;
16760 }
16761 return p;
16762
b5593623 16763 case Tag_ABI_DSBT:
cd30bcef 16764 READ_ULEB (val, p, end);
b5593623
JM
16765 printf (" Tag_ABI_DSBT: ");
16766 switch (val)
16767 {
16768 case 0:
16769 printf (_("DSBT addressing not used\n"));
16770 break;
16771 case 1:
16772 printf (_("DSBT addressing used\n"));
16773 break;
16774 default:
16775 printf ("??? (%d)\n", val);
16776 break;
16777 }
16778 return p;
16779
87779176 16780 case Tag_ABI_PID:
cd30bcef 16781 READ_ULEB (val, p, end);
87779176
JM
16782 printf (" Tag_ABI_PID: ");
16783 switch (val)
16784 {
16785 case 0:
16786 printf (_("Data addressing position-dependent\n"));
16787 break;
16788 case 1:
16789 printf (_("Data addressing position-independent, GOT near DP\n"));
16790 break;
16791 case 2:
16792 printf (_("Data addressing position-independent, GOT far from DP\n"));
16793 break;
16794 default:
16795 printf ("??? (%d)\n", val);
16796 break;
16797 }
16798 return p;
16799
16800 case Tag_ABI_PIC:
cd30bcef 16801 READ_ULEB (val, p, end);
87779176
JM
16802 printf (" Tag_ABI_PIC: ");
16803 switch (val)
16804 {
16805 case 0:
16806 printf (_("Code addressing position-dependent\n"));
16807 break;
16808 case 1:
16809 printf (_("Code addressing position-independent\n"));
16810 break;
16811 default:
16812 printf ("??? (%d)\n", val);
16813 break;
16814 }
16815 return p;
16816
16817 case Tag_ABI_array_object_alignment:
cd30bcef 16818 READ_ULEB (val, p, end);
87779176
JM
16819 printf (" Tag_ABI_array_object_alignment: ");
16820 switch (val)
16821 {
16822 case 0:
16823 printf (_("8-byte\n"));
16824 break;
16825 case 1:
16826 printf (_("4-byte\n"));
16827 break;
16828 case 2:
16829 printf (_("16-byte\n"));
16830 break;
16831 default:
16832 printf ("??? (%d)\n", val);
16833 break;
16834 }
16835 return p;
16836
16837 case Tag_ABI_array_object_align_expected:
cd30bcef 16838 READ_ULEB (val, p, end);
87779176
JM
16839 printf (" Tag_ABI_array_object_align_expected: ");
16840 switch (val)
16841 {
16842 case 0:
16843 printf (_("8-byte\n"));
16844 break;
16845 case 1:
16846 printf (_("4-byte\n"));
16847 break;
16848 case 2:
16849 printf (_("16-byte\n"));
16850 break;
16851 default:
16852 printf ("??? (%d)\n", val);
16853 break;
16854 }
16855 return p;
16856
3cbd1c06 16857 case Tag_ABI_compatibility:
071436c6 16858 {
cd30bcef 16859 READ_ULEB (val, p, end);
071436c6 16860 printf (" Tag_ABI_compatibility: ");
071436c6 16861 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16862 if (p < end - 1)
16863 {
16864 size_t maxlen = (end - p) - 1;
16865
16866 print_symbol ((int) maxlen, (const char *) p);
16867 p += strnlen ((char *) p, maxlen) + 1;
16868 }
16869 else
16870 {
16871 printf (_("<corrupt>"));
16872 p = (unsigned char *) end;
16873 }
071436c6 16874 putchar ('\n');
071436c6
NC
16875 return p;
16876 }
87779176
JM
16877
16878 case Tag_ABI_conformance:
071436c6 16879 {
4082ef84
NC
16880 printf (" Tag_ABI_conformance: \"");
16881 if (p < end - 1)
16882 {
16883 size_t maxlen = (end - p) - 1;
071436c6 16884
4082ef84
NC
16885 print_symbol ((int) maxlen, (const char *) p);
16886 p += strnlen ((char *) p, maxlen) + 1;
16887 }
16888 else
16889 {
16890 printf (_("<corrupt>"));
16891 p = (unsigned char *) end;
16892 }
071436c6 16893 printf ("\"\n");
071436c6
NC
16894 return p;
16895 }
59e6276b
JM
16896 }
16897
f6f0e17b
NC
16898 return display_tag_value (tag, p, end);
16899}
59e6276b 16900
f6f0e17b 16901static void
60abdbed 16902display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
16903{
16904 unsigned long addr = 0;
16905 size_t bytes = end - p;
16906
feceaa59 16907 assert (end >= p);
f6f0e17b 16908 while (bytes)
87779176 16909 {
f6f0e17b
NC
16910 int j;
16911 int k;
16912 int lbytes = (bytes > 16 ? 16 : bytes);
16913
16914 printf (" 0x%8.8lx ", addr);
16915
16916 for (j = 0; j < 16; j++)
16917 {
16918 if (j < lbytes)
16919 printf ("%2.2x", p[j]);
16920 else
16921 printf (" ");
16922
16923 if ((j & 3) == 3)
16924 printf (" ");
16925 }
16926
16927 for (j = 0; j < lbytes; j++)
16928 {
16929 k = p[j];
16930 if (k >= ' ' && k < 0x7f)
16931 printf ("%c", k);
16932 else
16933 printf (".");
16934 }
16935
16936 putchar ('\n');
16937
16938 p += lbytes;
16939 bytes -= lbytes;
16940 addr += lbytes;
87779176 16941 }
59e6276b 16942
f6f0e17b 16943 putchar ('\n');
59e6276b
JM
16944}
16945
13761a11 16946static unsigned char *
b0191216 16947display_msp430_attribute (unsigned char * p,
13761a11
NC
16948 const unsigned char * const end)
16949{
60abdbed
NC
16950 unsigned int val;
16951 unsigned int tag;
13761a11 16952
cd30bcef 16953 READ_ULEB (tag, p, end);
0b4362b0 16954
13761a11
NC
16955 switch (tag)
16956 {
16957 case OFBA_MSPABI_Tag_ISA:
13761a11 16958 printf (" Tag_ISA: ");
cd30bcef 16959 READ_ULEB (val, p, end);
13761a11
NC
16960 switch (val)
16961 {
16962 case 0: printf (_("None\n")); break;
16963 case 1: printf (_("MSP430\n")); break;
16964 case 2: printf (_("MSP430X\n")); break;
16965 default: printf ("??? (%d)\n", val); break;
16966 }
16967 break;
16968
16969 case OFBA_MSPABI_Tag_Code_Model:
13761a11 16970 printf (" Tag_Code_Model: ");
cd30bcef 16971 READ_ULEB (val, p, end);
13761a11
NC
16972 switch (val)
16973 {
16974 case 0: printf (_("None\n")); break;
16975 case 1: printf (_("Small\n")); break;
16976 case 2: printf (_("Large\n")); break;
16977 default: printf ("??? (%d)\n", val); break;
16978 }
16979 break;
16980
16981 case OFBA_MSPABI_Tag_Data_Model:
13761a11 16982 printf (" Tag_Data_Model: ");
cd30bcef 16983 READ_ULEB (val, p, end);
13761a11
NC
16984 switch (val)
16985 {
16986 case 0: printf (_("None\n")); break;
16987 case 1: printf (_("Small\n")); break;
16988 case 2: printf (_("Large\n")); break;
16989 case 3: printf (_("Restricted Large\n")); break;
16990 default: printf ("??? (%d)\n", val); break;
16991 }
16992 break;
16993
16994 default:
16995 printf (_(" <unknown tag %d>: "), tag);
16996
16997 if (tag & 1)
16998 {
071436c6 16999 putchar ('"');
4082ef84
NC
17000 if (p < end - 1)
17001 {
17002 size_t maxlen = (end - p) - 1;
17003
17004 print_symbol ((int) maxlen, (const char *) p);
17005 p += strnlen ((char *) p, maxlen) + 1;
17006 }
17007 else
17008 {
17009 printf (_("<corrupt>"));
17010 p = (unsigned char *) end;
17011 }
071436c6 17012 printf ("\"\n");
13761a11
NC
17013 }
17014 else
17015 {
cd30bcef 17016 READ_ULEB (val, p, end);
13761a11
NC
17017 printf ("%d (0x%x)\n", val, val);
17018 }
17019 break;
17020 }
17021
4082ef84 17022 assert (p <= end);
13761a11
NC
17023 return p;
17024}
17025
c0ea7c52
JL
17026static unsigned char *
17027display_msp430_gnu_attribute (unsigned char * p,
17028 unsigned int tag,
17029 const unsigned char * const end)
17030{
17031 if (tag == Tag_GNU_MSP430_Data_Region)
17032 {
cd30bcef 17033 unsigned int val;
c0ea7c52 17034
c0ea7c52 17035 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17036 READ_ULEB (val, p, end);
c0ea7c52
JL
17037
17038 switch (val)
17039 {
17040 case Val_GNU_MSP430_Data_Region_Any:
17041 printf (_("Any Region\n"));
17042 break;
17043 case Val_GNU_MSP430_Data_Region_Lower:
17044 printf (_("Lower Region Only\n"));
17045 break;
17046 default:
cd30bcef 17047 printf ("??? (%u)\n", val);
c0ea7c52
JL
17048 }
17049 return p;
17050 }
17051 return display_tag_value (tag & 1, p, end);
17052}
17053
2dc8dd17
JW
17054struct riscv_attr_tag_t {
17055 const char *name;
cd30bcef 17056 unsigned int tag;
2dc8dd17
JW
17057};
17058
17059static struct riscv_attr_tag_t riscv_attr_tag[] =
17060{
17061#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17062 T(arch),
17063 T(priv_spec),
17064 T(priv_spec_minor),
17065 T(priv_spec_revision),
17066 T(unaligned_access),
17067 T(stack_align),
17068#undef T
17069};
17070
17071static unsigned char *
17072display_riscv_attribute (unsigned char *p,
17073 const unsigned char * const end)
17074{
cd30bcef
AM
17075 unsigned int val;
17076 unsigned int tag;
2dc8dd17
JW
17077 struct riscv_attr_tag_t *attr = NULL;
17078 unsigned i;
17079
cd30bcef 17080 READ_ULEB (tag, p, end);
2dc8dd17
JW
17081
17082 /* Find the name of attribute. */
17083 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17084 {
17085 if (riscv_attr_tag[i].tag == tag)
17086 {
17087 attr = &riscv_attr_tag[i];
17088 break;
17089 }
17090 }
17091
17092 if (attr)
17093 printf (" %s: ", attr->name);
17094 else
17095 return display_tag_value (tag, p, end);
17096
17097 switch (tag)
17098 {
17099 case Tag_RISCV_priv_spec:
17100 case Tag_RISCV_priv_spec_minor:
17101 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17102 READ_ULEB (val, p, end);
17103 printf (_("%u\n"), val);
2dc8dd17
JW
17104 break;
17105 case Tag_RISCV_unaligned_access:
cd30bcef 17106 READ_ULEB (val, p, end);
2dc8dd17
JW
17107 switch (val)
17108 {
17109 case 0:
17110 printf (_("No unaligned access\n"));
17111 break;
17112 case 1:
17113 printf (_("Unaligned access\n"));
17114 break;
17115 }
17116 break;
17117 case Tag_RISCV_stack_align:
cd30bcef
AM
17118 READ_ULEB (val, p, end);
17119 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17120 break;
17121 case Tag_RISCV_arch:
17122 p = display_tag_value (-1, p, end);
17123 break;
17124 default:
17125 return display_tag_value (tag, p, end);
17126 }
17127
17128 return p;
17129}
17130
0861f561
CQ
17131static unsigned char *
17132display_csky_attribute (unsigned char * p,
17133 const unsigned char * const end)
17134{
17135 unsigned int tag;
17136 unsigned int val;
17137 READ_ULEB (tag, p, end);
17138
17139 if (tag >= Tag_CSKY_MAX)
17140 {
17141 return display_tag_value (-1, p, end);
17142 }
17143
17144 switch (tag)
17145 {
17146 case Tag_CSKY_ARCH_NAME:
17147 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17148 return display_tag_value (-1, p, end);
17149 case Tag_CSKY_CPU_NAME:
17150 printf (" Tag_CSKY_CPU_NAME:\t\t");
17151 return display_tag_value (-1, p, end);
17152
17153 case Tag_CSKY_ISA_FLAGS:
17154 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17155 return display_tag_value (0, p, end);
17156 case Tag_CSKY_ISA_EXT_FLAGS:
17157 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17158 return display_tag_value (0, p, end);
17159
17160 case Tag_CSKY_DSP_VERSION:
17161 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17162 READ_ULEB (val, p, end);
17163 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17164 printf ("DSP Extension\n");
17165 else if (val == VAL_CSKY_DSP_VERSION_2)
17166 printf ("DSP 2.0\n");
17167 break;
17168
17169 case Tag_CSKY_VDSP_VERSION:
17170 printf (" Tag_CSKY_VDSP_VERSION:\t");
17171 READ_ULEB (val, p, end);
17172 printf ("VDSP Version %d\n", val);
17173 break;
17174
17175 case Tag_CSKY_FPU_VERSION:
17176 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17177 READ_ULEB (val, p, end);
17178 if (val == VAL_CSKY_FPU_VERSION_1)
17179 printf ("ABIV1 FPU Version 1\n");
17180 else if (val == VAL_CSKY_FPU_VERSION_2)
17181 printf ("FPU Version 2\n");
17182 break;
17183
17184 case Tag_CSKY_FPU_ABI:
17185 printf (" Tag_CSKY_FPU_ABI:\t\t");
17186 READ_ULEB (val, p, end);
17187 if (val == VAL_CSKY_FPU_ABI_HARD)
17188 printf ("Hard\n");
17189 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17190 printf ("SoftFP\n");
17191 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17192 printf ("Soft\n");
17193 break;
17194 case Tag_CSKY_FPU_ROUNDING:
17195 READ_ULEB (val, p, end);
17196 if (val == 1) {
17197 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17198 printf ("Needed\n");
17199 }
17200 break;
17201 case Tag_CSKY_FPU_DENORMAL:
17202 READ_ULEB (val, p, end);
17203 if (val == 1) {
17204 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17205 printf ("Needed\n");
17206 }
17207 break;
17208 case Tag_CSKY_FPU_Exception:
17209 READ_ULEB (val, p, end);
17210 if (val == 1) {
17211 printf (" Tag_CSKY_FPU_Exception:\t");
17212 printf ("Needed\n");
17213 }
17214 break;
17215 case Tag_CSKY_FPU_NUMBER_MODULE:
17216 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17217 return display_tag_value (-1, p, end);
17218 case Tag_CSKY_FPU_HARDFP:
17219 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17220 READ_ULEB (val, p, end);
17221 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17222 printf (" Half");
17223 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17224 printf (" Single");
17225 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17226 printf (" Double");
17227 printf ("\n");
17228 break;
17229 default:
17230 return display_tag_value (tag, p, end);
17231 }
17232 return p;
17233}
17234
015dc7e1 17235static bool
dda8d76d 17236process_attributes (Filedata * filedata,
60bca95a 17237 const char * public_name,
104d59d1 17238 unsigned int proc_type,
f6f0e17b 17239 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17240 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17241{
2cf0635d 17242 Elf_Internal_Shdr * sect;
11c1ff18 17243 unsigned i;
015dc7e1 17244 bool res = true;
11c1ff18
PB
17245
17246 /* Find the section header so that we get the size. */
dda8d76d
NC
17247 for (i = 0, sect = filedata->section_headers;
17248 i < filedata->file_header.e_shnum;
11c1ff18
PB
17249 i++, sect++)
17250 {
071436c6
NC
17251 unsigned char * contents;
17252 unsigned char * p;
17253
104d59d1 17254 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17255 continue;
17256
dda8d76d 17257 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17258 sect->sh_size, _("attributes"));
60bca95a 17259 if (contents == NULL)
32ec8896 17260 {
015dc7e1 17261 res = false;
32ec8896
NC
17262 continue;
17263 }
60bca95a 17264
11c1ff18 17265 p = contents;
60abdbed
NC
17266 /* The first character is the version of the attributes.
17267 Currently only version 1, (aka 'A') is recognised here. */
17268 if (*p != 'A')
32ec8896
NC
17269 {
17270 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17271 res = false;
32ec8896 17272 }
60abdbed 17273 else
11c1ff18 17274 {
071436c6
NC
17275 bfd_vma section_len;
17276
17277 section_len = sect->sh_size - 1;
11c1ff18 17278 p++;
60bca95a 17279
071436c6 17280 while (section_len > 0)
11c1ff18 17281 {
071436c6 17282 bfd_vma attr_len;
e9847026 17283 unsigned int namelen;
015dc7e1
AM
17284 bool public_section;
17285 bool gnu_section;
11c1ff18 17286
071436c6 17287 if (section_len <= 4)
e0a31db1
NC
17288 {
17289 error (_("Tag section ends prematurely\n"));
015dc7e1 17290 res = false;
e0a31db1
NC
17291 break;
17292 }
071436c6 17293 attr_len = byte_get (p, 4);
11c1ff18 17294 p += 4;
60bca95a 17295
071436c6 17296 if (attr_len > section_len)
11c1ff18 17297 {
071436c6
NC
17298 error (_("Bad attribute length (%u > %u)\n"),
17299 (unsigned) attr_len, (unsigned) section_len);
17300 attr_len = section_len;
015dc7e1 17301 res = false;
11c1ff18 17302 }
74e1a04b 17303 /* PR 17531: file: 001-101425-0.004 */
071436c6 17304 else if (attr_len < 5)
74e1a04b 17305 {
071436c6 17306 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17307 res = false;
74e1a04b
NC
17308 break;
17309 }
e9847026 17310
071436c6
NC
17311 section_len -= attr_len;
17312 attr_len -= 4;
17313
17314 namelen = strnlen ((char *) p, attr_len) + 1;
17315 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17316 {
17317 error (_("Corrupt attribute section name\n"));
015dc7e1 17318 res = false;
e9847026
NC
17319 break;
17320 }
17321
071436c6
NC
17322 printf (_("Attribute Section: "));
17323 print_symbol (INT_MAX, (const char *) p);
17324 putchar ('\n');
60bca95a
NC
17325
17326 if (public_name && streq ((char *) p, public_name))
015dc7e1 17327 public_section = true;
11c1ff18 17328 else
015dc7e1 17329 public_section = false;
60bca95a
NC
17330
17331 if (streq ((char *) p, "gnu"))
015dc7e1 17332 gnu_section = true;
104d59d1 17333 else
015dc7e1 17334 gnu_section = false;
60bca95a 17335
11c1ff18 17336 p += namelen;
071436c6 17337 attr_len -= namelen;
e0a31db1 17338
071436c6 17339 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17340 {
e0a31db1 17341 int tag;
cd30bcef 17342 unsigned int val;
11c1ff18 17343 bfd_vma size;
071436c6 17344 unsigned char * end;
60bca95a 17345
e0a31db1 17346 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17347 if (attr_len < 6)
e0a31db1
NC
17348 {
17349 error (_("Unused bytes at end of section\n"));
015dc7e1 17350 res = false;
e0a31db1
NC
17351 section_len = 0;
17352 break;
17353 }
17354
17355 tag = *(p++);
11c1ff18 17356 size = byte_get (p, 4);
071436c6 17357 if (size > attr_len)
11c1ff18 17358 {
e9847026 17359 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17360 (unsigned) size, (unsigned) attr_len);
015dc7e1 17361 res = false;
071436c6 17362 size = attr_len;
11c1ff18 17363 }
e0a31db1
NC
17364 /* PR binutils/17531: Safe handling of corrupt files. */
17365 if (size < 6)
17366 {
17367 error (_("Bad subsection length (%u < 6)\n"),
17368 (unsigned) size);
015dc7e1 17369 res = false;
e0a31db1
NC
17370 section_len = 0;
17371 break;
17372 }
60bca95a 17373
071436c6 17374 attr_len -= size;
11c1ff18 17375 end = p + size - 1;
071436c6 17376 assert (end <= contents + sect->sh_size);
11c1ff18 17377 p += 4;
60bca95a 17378
11c1ff18
PB
17379 switch (tag)
17380 {
17381 case 1:
2b692964 17382 printf (_("File Attributes\n"));
11c1ff18
PB
17383 break;
17384 case 2:
2b692964 17385 printf (_("Section Attributes:"));
11c1ff18
PB
17386 goto do_numlist;
17387 case 3:
2b692964 17388 printf (_("Symbol Attributes:"));
1a0670f3 17389 /* Fall through. */
11c1ff18
PB
17390 do_numlist:
17391 for (;;)
17392 {
cd30bcef 17393 READ_ULEB (val, p, end);
11c1ff18
PB
17394 if (val == 0)
17395 break;
17396 printf (" %d", val);
17397 }
17398 printf ("\n");
17399 break;
17400 default:
2b692964 17401 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 17402 public_section = false;
11c1ff18
PB
17403 break;
17404 }
60bca95a 17405
071436c6 17406 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
17407 {
17408 while (p < end)
f6f0e17b 17409 p = display_pub_attribute (p, end);
60abdbed 17410 assert (p == end);
104d59d1 17411 }
071436c6 17412 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
17413 {
17414 while (p < end)
17415 p = display_gnu_attribute (p,
f6f0e17b
NC
17416 display_proc_gnu_attribute,
17417 end);
60abdbed 17418 assert (p == end);
11c1ff18 17419 }
071436c6 17420 else if (p < end)
11c1ff18 17421 {
071436c6 17422 printf (_(" Unknown attribute:\n"));
f6f0e17b 17423 display_raw_attribute (p, end);
11c1ff18
PB
17424 p = end;
17425 }
071436c6
NC
17426 else
17427 attr_len = 0;
11c1ff18
PB
17428 }
17429 }
17430 }
d70c5fc7 17431
60bca95a 17432 free (contents);
11c1ff18 17433 }
32ec8896
NC
17434
17435 return res;
11c1ff18
PB
17436}
17437
ccb4c951
RS
17438/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
17439 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
17440 and return the VMA of the next entry, or -1 if there was a problem.
17441 Does not read from DATA_END or beyond. */
ccb4c951
RS
17442
17443static bfd_vma
82b1b41b
NC
17444print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
17445 unsigned char * data_end)
ccb4c951
RS
17446{
17447 printf (" ");
17448 print_vma (addr, LONG_HEX);
17449 printf (" ");
17450 if (addr < pltgot + 0xfff0)
17451 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
17452 else
17453 printf ("%10s", "");
17454 printf (" ");
17455 if (data == NULL)
2b692964 17456 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
17457 else
17458 {
17459 bfd_vma entry;
82b1b41b 17460 unsigned char * from = data + addr - pltgot;
ccb4c951 17461
82b1b41b
NC
17462 if (from + (is_32bit_elf ? 4 : 8) > data_end)
17463 {
17464 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
17465 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
17466 return (bfd_vma) -1;
17467 }
17468 else
17469 {
17470 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17471 print_vma (entry, LONG_HEX);
17472 }
ccb4c951
RS
17473 }
17474 return addr + (is_32bit_elf ? 4 : 8);
17475}
17476
861fb55a
DJ
17477/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
17478 PLTGOT. Print the Address and Initial fields of an entry at VMA
17479 ADDR and return the VMA of the next entry. */
17480
17481static bfd_vma
2cf0635d 17482print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
17483{
17484 printf (" ");
17485 print_vma (addr, LONG_HEX);
17486 printf (" ");
17487 if (data == NULL)
2b692964 17488 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
17489 else
17490 {
17491 bfd_vma entry;
17492
17493 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17494 print_vma (entry, LONG_HEX);
17495 }
17496 return addr + (is_32bit_elf ? 4 : 8);
17497}
17498
351cdf24
MF
17499static void
17500print_mips_ases (unsigned int mask)
17501{
17502 if (mask & AFL_ASE_DSP)
17503 fputs ("\n\tDSP ASE", stdout);
17504 if (mask & AFL_ASE_DSPR2)
17505 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
17506 if (mask & AFL_ASE_DSPR3)
17507 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
17508 if (mask & AFL_ASE_EVA)
17509 fputs ("\n\tEnhanced VA Scheme", stdout);
17510 if (mask & AFL_ASE_MCU)
17511 fputs ("\n\tMCU (MicroController) ASE", stdout);
17512 if (mask & AFL_ASE_MDMX)
17513 fputs ("\n\tMDMX ASE", stdout);
17514 if (mask & AFL_ASE_MIPS3D)
17515 fputs ("\n\tMIPS-3D ASE", stdout);
17516 if (mask & AFL_ASE_MT)
17517 fputs ("\n\tMT ASE", stdout);
17518 if (mask & AFL_ASE_SMARTMIPS)
17519 fputs ("\n\tSmartMIPS ASE", stdout);
17520 if (mask & AFL_ASE_VIRT)
17521 fputs ("\n\tVZ ASE", stdout);
17522 if (mask & AFL_ASE_MSA)
17523 fputs ("\n\tMSA ASE", stdout);
17524 if (mask & AFL_ASE_MIPS16)
17525 fputs ("\n\tMIPS16 ASE", stdout);
17526 if (mask & AFL_ASE_MICROMIPS)
17527 fputs ("\n\tMICROMIPS ASE", stdout);
17528 if (mask & AFL_ASE_XPA)
17529 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
17530 if (mask & AFL_ASE_MIPS16E2)
17531 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
17532 if (mask & AFL_ASE_CRC)
17533 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
17534 if (mask & AFL_ASE_GINV)
17535 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
17536 if (mask & AFL_ASE_LOONGSON_MMI)
17537 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
17538 if (mask & AFL_ASE_LOONGSON_CAM)
17539 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
17540 if (mask & AFL_ASE_LOONGSON_EXT)
17541 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
17542 if (mask & AFL_ASE_LOONGSON_EXT2)
17543 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
17544 if (mask == 0)
17545 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
17546 else if ((mask & ~AFL_ASE_MASK) != 0)
17547 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
17548}
17549
17550static void
17551print_mips_isa_ext (unsigned int isa_ext)
17552{
17553 switch (isa_ext)
17554 {
17555 case 0:
17556 fputs (_("None"), stdout);
17557 break;
17558 case AFL_EXT_XLR:
17559 fputs ("RMI XLR", stdout);
17560 break;
2c629856
N
17561 case AFL_EXT_OCTEON3:
17562 fputs ("Cavium Networks Octeon3", stdout);
17563 break;
351cdf24
MF
17564 case AFL_EXT_OCTEON2:
17565 fputs ("Cavium Networks Octeon2", stdout);
17566 break;
17567 case AFL_EXT_OCTEONP:
17568 fputs ("Cavium Networks OcteonP", stdout);
17569 break;
351cdf24
MF
17570 case AFL_EXT_OCTEON:
17571 fputs ("Cavium Networks Octeon", stdout);
17572 break;
17573 case AFL_EXT_5900:
17574 fputs ("Toshiba R5900", stdout);
17575 break;
17576 case AFL_EXT_4650:
17577 fputs ("MIPS R4650", stdout);
17578 break;
17579 case AFL_EXT_4010:
17580 fputs ("LSI R4010", stdout);
17581 break;
17582 case AFL_EXT_4100:
17583 fputs ("NEC VR4100", stdout);
17584 break;
17585 case AFL_EXT_3900:
17586 fputs ("Toshiba R3900", stdout);
17587 break;
17588 case AFL_EXT_10000:
17589 fputs ("MIPS R10000", stdout);
17590 break;
17591 case AFL_EXT_SB1:
17592 fputs ("Broadcom SB-1", stdout);
17593 break;
17594 case AFL_EXT_4111:
17595 fputs ("NEC VR4111/VR4181", stdout);
17596 break;
17597 case AFL_EXT_4120:
17598 fputs ("NEC VR4120", stdout);
17599 break;
17600 case AFL_EXT_5400:
17601 fputs ("NEC VR5400", stdout);
17602 break;
17603 case AFL_EXT_5500:
17604 fputs ("NEC VR5500", stdout);
17605 break;
17606 case AFL_EXT_LOONGSON_2E:
17607 fputs ("ST Microelectronics Loongson 2E", stdout);
17608 break;
17609 case AFL_EXT_LOONGSON_2F:
17610 fputs ("ST Microelectronics Loongson 2F", stdout);
17611 break;
38bf472a
MR
17612 case AFL_EXT_INTERAPTIV_MR2:
17613 fputs ("Imagination interAptiv MR2", stdout);
17614 break;
351cdf24 17615 default:
00ac7aa0 17616 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
17617 }
17618}
17619
32ec8896 17620static signed int
351cdf24
MF
17621get_mips_reg_size (int reg_size)
17622{
17623 return (reg_size == AFL_REG_NONE) ? 0
17624 : (reg_size == AFL_REG_32) ? 32
17625 : (reg_size == AFL_REG_64) ? 64
17626 : (reg_size == AFL_REG_128) ? 128
17627 : -1;
17628}
17629
015dc7e1 17630static bool
dda8d76d 17631process_mips_specific (Filedata * filedata)
5b18a4bc 17632{
2cf0635d 17633 Elf_Internal_Dyn * entry;
351cdf24 17634 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
17635 size_t liblist_offset = 0;
17636 size_t liblistno = 0;
17637 size_t conflictsno = 0;
17638 size_t options_offset = 0;
17639 size_t conflicts_offset = 0;
861fb55a
DJ
17640 size_t pltrelsz = 0;
17641 size_t pltrel = 0;
ccb4c951 17642 bfd_vma pltgot = 0;
861fb55a
DJ
17643 bfd_vma mips_pltgot = 0;
17644 bfd_vma jmprel = 0;
ccb4c951
RS
17645 bfd_vma local_gotno = 0;
17646 bfd_vma gotsym = 0;
17647 bfd_vma symtabno = 0;
015dc7e1 17648 bool res = true;
103f02d3 17649
dda8d76d 17650 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 17651 display_mips_gnu_attribute))
015dc7e1 17652 res = false;
2cf19d5c 17653
dda8d76d 17654 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
17655
17656 if (sect != NULL)
17657 {
17658 Elf_External_ABIFlags_v0 *abiflags_ext;
17659 Elf_Internal_ABIFlags_v0 abiflags_in;
17660
17661 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
17662 {
17663 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 17664 res = false;
32ec8896 17665 }
351cdf24
MF
17666 else
17667 {
dda8d76d 17668 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
17669 sect->sh_size, _("MIPS ABI Flags section"));
17670 if (abiflags_ext)
17671 {
17672 abiflags_in.version = BYTE_GET (abiflags_ext->version);
17673 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
17674 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
17675 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
17676 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
17677 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
17678 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
17679 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
17680 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
17681 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
17682 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
17683
17684 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
17685 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
17686 if (abiflags_in.isa_rev > 1)
17687 printf ("r%d", abiflags_in.isa_rev);
17688 printf ("\nGPR size: %d",
17689 get_mips_reg_size (abiflags_in.gpr_size));
17690 printf ("\nCPR1 size: %d",
17691 get_mips_reg_size (abiflags_in.cpr1_size));
17692 printf ("\nCPR2 size: %d",
17693 get_mips_reg_size (abiflags_in.cpr2_size));
17694 fputs ("\nFP ABI: ", stdout);
17695 print_mips_fp_abi_value (abiflags_in.fp_abi);
17696 fputs ("ISA Extension: ", stdout);
17697 print_mips_isa_ext (abiflags_in.isa_ext);
17698 fputs ("\nASEs:", stdout);
17699 print_mips_ases (abiflags_in.ases);
17700 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
17701 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
17702 fputc ('\n', stdout);
17703 free (abiflags_ext);
17704 }
17705 }
17706 }
17707
19e6b90e 17708 /* We have a lot of special sections. Thanks SGI! */
978c4450 17709 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
17710 {
17711 /* No dynamic information available. See if there is static GOT. */
dda8d76d 17712 sect = find_section (filedata, ".got");
bbdd9a68
MR
17713 if (sect != NULL)
17714 {
17715 unsigned char *data_end;
17716 unsigned char *data;
17717 bfd_vma ent, end;
17718 int addr_size;
17719
17720 pltgot = sect->sh_addr;
17721
17722 ent = pltgot;
17723 addr_size = (is_32bit_elf ? 4 : 8);
17724 end = pltgot + sect->sh_size;
17725
dda8d76d 17726 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
17727 end - pltgot, 1,
17728 _("Global Offset Table data"));
17729 /* PR 12855: Null data is handled gracefully throughout. */
17730 data_end = data + (end - pltgot);
17731
17732 printf (_("\nStatic GOT:\n"));
17733 printf (_(" Canonical gp value: "));
17734 print_vma (ent + 0x7ff0, LONG_HEX);
17735 printf ("\n\n");
17736
17737 /* In a dynamic binary GOT[0] is reserved for the dynamic
17738 loader to store the lazy resolver pointer, however in
17739 a static binary it may well have been omitted and GOT
17740 reduced to a table of addresses.
17741 PR 21344: Check for the entry being fully available
17742 before fetching it. */
17743 if (data
17744 && data + ent - pltgot + addr_size <= data_end
17745 && byte_get (data + ent - pltgot, addr_size) == 0)
17746 {
17747 printf (_(" Reserved entries:\n"));
17748 printf (_(" %*s %10s %*s\n"),
17749 addr_size * 2, _("Address"), _("Access"),
17750 addr_size * 2, _("Value"));
17751 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17752 printf ("\n");
17753 if (ent == (bfd_vma) -1)
17754 goto sgot_print_fail;
17755
17756 /* Check for the MSB of GOT[1] being set, identifying a
17757 GNU object. This entry will be used by some runtime
17758 loaders, to store the module pointer. Otherwise this
17759 is an ordinary local entry.
17760 PR 21344: Check for the entry being fully available
17761 before fetching it. */
17762 if (data
17763 && data + ent - pltgot + addr_size <= data_end
17764 && (byte_get (data + ent - pltgot, addr_size)
17765 >> (addr_size * 8 - 1)) != 0)
17766 {
17767 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17768 printf ("\n");
17769 if (ent == (bfd_vma) -1)
17770 goto sgot_print_fail;
17771 }
17772 printf ("\n");
17773 }
17774
f17e9d8a 17775 if (data != NULL && ent < end)
bbdd9a68
MR
17776 {
17777 printf (_(" Local entries:\n"));
17778 printf (" %*s %10s %*s\n",
17779 addr_size * 2, _("Address"), _("Access"),
17780 addr_size * 2, _("Value"));
17781 while (ent < end)
17782 {
17783 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17784 printf ("\n");
17785 if (ent == (bfd_vma) -1)
17786 goto sgot_print_fail;
17787 }
17788 printf ("\n");
17789 }
17790
17791 sgot_print_fail:
9db70fc3 17792 free (data);
bbdd9a68
MR
17793 }
17794 return res;
17795 }
252b5132 17796
978c4450 17797 for (entry = filedata->dynamic_section;
071436c6 17798 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
17799 (entry < filedata->dynamic_section + filedata->dynamic_nent
17800 && entry->d_tag != DT_NULL);
071436c6 17801 ++entry)
252b5132
RH
17802 switch (entry->d_tag)
17803 {
17804 case DT_MIPS_LIBLIST:
d93f0186 17805 liblist_offset
dda8d76d 17806 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17807 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
17808 break;
17809 case DT_MIPS_LIBLISTNO:
17810 liblistno = entry->d_un.d_val;
17811 break;
17812 case DT_MIPS_OPTIONS:
dda8d76d 17813 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
17814 break;
17815 case DT_MIPS_CONFLICT:
d93f0186 17816 conflicts_offset
dda8d76d 17817 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17818 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
17819 break;
17820 case DT_MIPS_CONFLICTNO:
17821 conflictsno = entry->d_un.d_val;
17822 break;
ccb4c951 17823 case DT_PLTGOT:
861fb55a
DJ
17824 pltgot = entry->d_un.d_ptr;
17825 break;
ccb4c951
RS
17826 case DT_MIPS_LOCAL_GOTNO:
17827 local_gotno = entry->d_un.d_val;
17828 break;
17829 case DT_MIPS_GOTSYM:
17830 gotsym = entry->d_un.d_val;
17831 break;
17832 case DT_MIPS_SYMTABNO:
17833 symtabno = entry->d_un.d_val;
17834 break;
861fb55a
DJ
17835 case DT_MIPS_PLTGOT:
17836 mips_pltgot = entry->d_un.d_ptr;
17837 break;
17838 case DT_PLTREL:
17839 pltrel = entry->d_un.d_val;
17840 break;
17841 case DT_PLTRELSZ:
17842 pltrelsz = entry->d_un.d_val;
17843 break;
17844 case DT_JMPREL:
17845 jmprel = entry->d_un.d_ptr;
17846 break;
252b5132
RH
17847 default:
17848 break;
17849 }
17850
17851 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
17852 {
2cf0635d 17853 Elf32_External_Lib * elib;
252b5132
RH
17854 size_t cnt;
17855
dda8d76d 17856 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
17857 sizeof (Elf32_External_Lib),
17858 liblistno,
17859 _("liblist section data"));
a6e9f9df 17860 if (elib)
252b5132 17861 {
d3a49aa8
AM
17862 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
17863 "\nSection '.liblist' contains %lu entries:\n",
17864 (unsigned long) liblistno),
a6e9f9df 17865 (unsigned long) liblistno);
2b692964 17866 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
17867 stdout);
17868
17869 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 17870 {
a6e9f9df 17871 Elf32_Lib liblist;
91d6fa6a 17872 time_t atime;
d5b07ef4 17873 char timebuf[128];
2cf0635d 17874 struct tm * tmp;
a6e9f9df
AM
17875
17876 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17877 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
17878 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17879 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17880 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17881
91d6fa6a 17882 tmp = gmtime (&atime);
e9e44622
JJ
17883 snprintf (timebuf, sizeof (timebuf),
17884 "%04u-%02u-%02uT%02u:%02u:%02u",
17885 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17886 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 17887
31104126 17888 printf ("%3lu: ", (unsigned long) cnt);
978c4450
AM
17889 if (VALID_DYNAMIC_NAME (filedata, liblist.l_name))
17890 print_symbol (20, GET_DYNAMIC_NAME (filedata, liblist.l_name));
d79b3d50 17891 else
2b692964 17892 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
17893 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
17894 liblist.l_version);
a6e9f9df
AM
17895
17896 if (liblist.l_flags == 0)
2b692964 17897 puts (_(" NONE"));
a6e9f9df
AM
17898 else
17899 {
17900 static const struct
252b5132 17901 {
2cf0635d 17902 const char * name;
a6e9f9df 17903 int bit;
252b5132 17904 }
a6e9f9df
AM
17905 l_flags_vals[] =
17906 {
17907 { " EXACT_MATCH", LL_EXACT_MATCH },
17908 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
17909 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
17910 { " EXPORTS", LL_EXPORTS },
17911 { " DELAY_LOAD", LL_DELAY_LOAD },
17912 { " DELTA", LL_DELTA }
17913 };
17914 int flags = liblist.l_flags;
17915 size_t fcnt;
17916
60bca95a 17917 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
17918 if ((flags & l_flags_vals[fcnt].bit) != 0)
17919 {
17920 fputs (l_flags_vals[fcnt].name, stdout);
17921 flags ^= l_flags_vals[fcnt].bit;
17922 }
17923 if (flags != 0)
17924 printf (" %#x", (unsigned int) flags);
252b5132 17925
a6e9f9df
AM
17926 puts ("");
17927 }
252b5132 17928 }
252b5132 17929
a6e9f9df
AM
17930 free (elib);
17931 }
32ec8896 17932 else
015dc7e1 17933 res = false;
252b5132
RH
17934 }
17935
17936 if (options_offset != 0)
17937 {
2cf0635d 17938 Elf_External_Options * eopt;
252b5132
RH
17939 size_t offset;
17940 int cnt;
dda8d76d 17941 sect = filedata->section_headers;
252b5132
RH
17942
17943 /* Find the section header so that we get the size. */
dda8d76d 17944 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 17945 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
17946 if (sect == NULL)
17947 {
17948 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 17949 return false;
071436c6 17950 }
7fc0c668
NC
17951 /* PR 24243 */
17952 if (sect->sh_size < sizeof (* eopt))
17953 {
17954 error (_("The MIPS options section is too small.\n"));
015dc7e1 17955 return false;
7fc0c668 17956 }
252b5132 17957
dda8d76d 17958 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 17959 sect->sh_size, _("options"));
a6e9f9df 17960 if (eopt)
252b5132 17961 {
fd17d1e6 17962 Elf_Internal_Options option;
76da6bbe 17963
a6e9f9df 17964 offset = cnt = 0;
82b1b41b 17965 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 17966 {
2cf0635d 17967 Elf_External_Options * eoption;
fd17d1e6 17968 unsigned int optsize;
252b5132 17969
a6e9f9df 17970 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 17971
fd17d1e6 17972 optsize = BYTE_GET (eoption->size);
76da6bbe 17973
82b1b41b 17974 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
17975 if (optsize < sizeof (* eopt)
17976 || optsize > sect->sh_size - offset)
82b1b41b 17977 {
645f43a8 17978 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 17979 optsize);
645f43a8 17980 free (eopt);
015dc7e1 17981 return false;
82b1b41b 17982 }
fd17d1e6 17983 offset += optsize;
a6e9f9df
AM
17984 ++cnt;
17985 }
252b5132 17986
d3a49aa8
AM
17987 printf (ngettext ("\nSection '%s' contains %d entry:\n",
17988 "\nSection '%s' contains %d entries:\n",
17989 cnt),
dda8d76d 17990 printable_section_name (filedata, sect), cnt);
76da6bbe 17991
82b1b41b 17992 offset = 0;
a6e9f9df 17993 while (cnt-- > 0)
252b5132 17994 {
a6e9f9df 17995 size_t len;
fd17d1e6
AM
17996 Elf_External_Options * eoption;
17997
17998 eoption = (Elf_External_Options *) ((char *) eopt + offset);
17999
18000 option.kind = BYTE_GET (eoption->kind);
18001 option.size = BYTE_GET (eoption->size);
18002 option.section = BYTE_GET (eoption->section);
18003 option.info = BYTE_GET (eoption->info);
a6e9f9df 18004
fd17d1e6 18005 switch (option.kind)
252b5132 18006 {
a6e9f9df
AM
18007 case ODK_NULL:
18008 /* This shouldn't happen. */
d0c4e780 18009 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18010 option.section, option.info);
a6e9f9df 18011 break;
2e6be59c 18012
a6e9f9df
AM
18013 case ODK_REGINFO:
18014 printf (" REGINFO ");
dda8d76d 18015 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18016 {
2cf0635d 18017 Elf32_External_RegInfo * ereg;
b34976b6 18018 Elf32_RegInfo reginfo;
a6e9f9df 18019
2e6be59c 18020 /* 32bit form. */
fd17d1e6
AM
18021 if (option.size < (sizeof (Elf_External_Options)
18022 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18023 {
18024 printf (_("<corrupt>\n"));
18025 error (_("Truncated MIPS REGINFO option\n"));
18026 cnt = 0;
18027 break;
18028 }
18029
fd17d1e6 18030 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18031
a6e9f9df
AM
18032 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18033 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18034 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18035 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18036 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18037 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18038
d0c4e780
AM
18039 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18040 reginfo.ri_gprmask, reginfo.ri_gp_value);
18041 printf (" "
18042 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18043 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18044 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18045 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18046 }
18047 else
18048 {
18049 /* 64 bit form. */
2cf0635d 18050 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18051 Elf64_Internal_RegInfo reginfo;
18052
fd17d1e6
AM
18053 if (option.size < (sizeof (Elf_External_Options)
18054 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18055 {
18056 printf (_("<corrupt>\n"));
18057 error (_("Truncated MIPS REGINFO option\n"));
18058 cnt = 0;
18059 break;
18060 }
18061
fd17d1e6 18062 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18063 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18064 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18065 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18066 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18067 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18068 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18069
d0c4e780
AM
18070 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18071 reginfo.ri_gprmask, reginfo.ri_gp_value);
18072 printf (" "
18073 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18074 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18075 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18076 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18077 }
fd17d1e6 18078 offset += option.size;
a6e9f9df 18079 continue;
2e6be59c 18080
a6e9f9df
AM
18081 case ODK_EXCEPTIONS:
18082 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18083 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18084 fputs (") fpe_max(", stdout);
fd17d1e6 18085 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18086 fputs (")", stdout);
18087
fd17d1e6 18088 if (option.info & OEX_PAGE0)
a6e9f9df 18089 fputs (" PAGE0", stdout);
fd17d1e6 18090 if (option.info & OEX_SMM)
a6e9f9df 18091 fputs (" SMM", stdout);
fd17d1e6 18092 if (option.info & OEX_FPDBUG)
a6e9f9df 18093 fputs (" FPDBUG", stdout);
fd17d1e6 18094 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18095 fputs (" DISMISS", stdout);
18096 break;
2e6be59c 18097
a6e9f9df
AM
18098 case ODK_PAD:
18099 fputs (" PAD ", stdout);
fd17d1e6 18100 if (option.info & OPAD_PREFIX)
a6e9f9df 18101 fputs (" PREFIX", stdout);
fd17d1e6 18102 if (option.info & OPAD_POSTFIX)
a6e9f9df 18103 fputs (" POSTFIX", stdout);
fd17d1e6 18104 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18105 fputs (" SYMBOL", stdout);
18106 break;
2e6be59c 18107
a6e9f9df
AM
18108 case ODK_HWPATCH:
18109 fputs (" HWPATCH ", stdout);
fd17d1e6 18110 if (option.info & OHW_R4KEOP)
a6e9f9df 18111 fputs (" R4KEOP", stdout);
fd17d1e6 18112 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18113 fputs (" R8KPFETCH", stdout);
fd17d1e6 18114 if (option.info & OHW_R5KEOP)
a6e9f9df 18115 fputs (" R5KEOP", stdout);
fd17d1e6 18116 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18117 fputs (" R5KCVTL", stdout);
18118 break;
2e6be59c 18119
a6e9f9df
AM
18120 case ODK_FILL:
18121 fputs (" FILL ", stdout);
18122 /* XXX Print content of info word? */
18123 break;
2e6be59c 18124
a6e9f9df
AM
18125 case ODK_TAGS:
18126 fputs (" TAGS ", stdout);
18127 /* XXX Print content of info word? */
18128 break;
2e6be59c 18129
a6e9f9df
AM
18130 case ODK_HWAND:
18131 fputs (" HWAND ", stdout);
fd17d1e6 18132 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18133 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18134 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18135 fputs (" R4KEOP_CLEAN", stdout);
18136 break;
2e6be59c 18137
a6e9f9df
AM
18138 case ODK_HWOR:
18139 fputs (" HWOR ", stdout);
fd17d1e6 18140 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18141 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18142 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18143 fputs (" R4KEOP_CLEAN", stdout);
18144 break;
2e6be59c 18145
a6e9f9df 18146 case ODK_GP_GROUP:
d0c4e780 18147 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18148 option.info & OGP_GROUP,
18149 (option.info & OGP_SELF) >> 16);
a6e9f9df 18150 break;
2e6be59c 18151
a6e9f9df 18152 case ODK_IDENT:
d0c4e780 18153 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18154 option.info & OGP_GROUP,
18155 (option.info & OGP_SELF) >> 16);
a6e9f9df 18156 break;
2e6be59c 18157
a6e9f9df
AM
18158 default:
18159 /* This shouldn't happen. */
d0c4e780 18160 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18161 option.kind, option.section, option.info);
a6e9f9df 18162 break;
252b5132 18163 }
a6e9f9df 18164
2cf0635d 18165 len = sizeof (* eopt);
fd17d1e6 18166 while (len < option.size)
82b1b41b 18167 {
fd17d1e6 18168 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18169
82b1b41b
NC
18170 if (ISPRINT (datum))
18171 printf ("%c", datum);
18172 else
18173 printf ("\\%03o", datum);
18174 len ++;
18175 }
a6e9f9df 18176 fputs ("\n", stdout);
82b1b41b 18177
fd17d1e6 18178 offset += option.size;
252b5132 18179 }
a6e9f9df 18180 free (eopt);
252b5132 18181 }
32ec8896 18182 else
015dc7e1 18183 res = false;
252b5132
RH
18184 }
18185
18186 if (conflicts_offset != 0 && conflictsno != 0)
18187 {
2cf0635d 18188 Elf32_Conflict * iconf;
252b5132
RH
18189 size_t cnt;
18190
978c4450 18191 if (filedata->dynamic_symbols == NULL)
252b5132 18192 {
591a748a 18193 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18194 return false;
252b5132
RH
18195 }
18196
7296a62a
NC
18197 /* PR 21345 - print a slightly more helpful error message
18198 if we are sure that the cmalloc will fail. */
645f43a8 18199 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18200 {
18201 error (_("Overlarge number of conflicts detected: %lx\n"),
18202 (long) conflictsno);
015dc7e1 18203 return false;
7296a62a
NC
18204 }
18205
3f5e193b 18206 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18207 if (iconf == NULL)
18208 {
8b73c356 18209 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18210 return false;
252b5132
RH
18211 }
18212
9ea033b2 18213 if (is_32bit_elf)
252b5132 18214 {
2cf0635d 18215 Elf32_External_Conflict * econf32;
a6e9f9df 18216
3f5e193b 18217 econf32 = (Elf32_External_Conflict *)
95099889
AM
18218 get_data (NULL, filedata, conflicts_offset,
18219 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18220 if (!econf32)
5a814d6d
AM
18221 {
18222 free (iconf);
015dc7e1 18223 return false;
5a814d6d 18224 }
252b5132
RH
18225
18226 for (cnt = 0; cnt < conflictsno; ++cnt)
18227 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18228
18229 free (econf32);
252b5132
RH
18230 }
18231 else
18232 {
2cf0635d 18233 Elf64_External_Conflict * econf64;
a6e9f9df 18234
3f5e193b 18235 econf64 = (Elf64_External_Conflict *)
95099889
AM
18236 get_data (NULL, filedata, conflicts_offset,
18237 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18238 if (!econf64)
5a814d6d
AM
18239 {
18240 free (iconf);
015dc7e1 18241 return false;
5a814d6d 18242 }
252b5132
RH
18243
18244 for (cnt = 0; cnt < conflictsno; ++cnt)
18245 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18246
18247 free (econf64);
252b5132
RH
18248 }
18249
d3a49aa8
AM
18250 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18251 "\nSection '.conflict' contains %lu entries:\n",
18252 (unsigned long) conflictsno),
c7e7ca54 18253 (unsigned long) conflictsno);
252b5132
RH
18254 puts (_(" Num: Index Value Name"));
18255
18256 for (cnt = 0; cnt < conflictsno; ++cnt)
18257 {
b34976b6 18258 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18259
978c4450 18260 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18261 printf (_("<corrupt symbol index>"));
d79b3d50 18262 else
e0a31db1
NC
18263 {
18264 Elf_Internal_Sym * psym;
18265
978c4450 18266 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18267 print_vma (psym->st_value, FULL_HEX);
18268 putchar (' ');
978c4450
AM
18269 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18270 print_symbol (25, GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18271 else
18272 printf (_("<corrupt: %14ld>"), psym->st_name);
18273 }
31104126 18274 putchar ('\n');
252b5132
RH
18275 }
18276
252b5132
RH
18277 free (iconf);
18278 }
18279
ccb4c951
RS
18280 if (pltgot != 0 && local_gotno != 0)
18281 {
91d6fa6a 18282 bfd_vma ent, local_end, global_end;
bbeee7ea 18283 size_t i, offset;
2cf0635d 18284 unsigned char * data;
82b1b41b 18285 unsigned char * data_end;
bbeee7ea 18286 int addr_size;
ccb4c951 18287
91d6fa6a 18288 ent = pltgot;
ccb4c951
RS
18289 addr_size = (is_32bit_elf ? 4 : 8);
18290 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18291
74e1a04b
NC
18292 /* PR binutils/17533 file: 012-111227-0.004 */
18293 if (symtabno < gotsym)
18294 {
18295 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18296 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18297 return false;
74e1a04b 18298 }
82b1b41b 18299
74e1a04b 18300 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18301 /* PR 17531: file: 54c91a34. */
18302 if (global_end < local_end)
18303 {
18304 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18305 return false;
82b1b41b 18306 }
948f632f 18307
dda8d76d
NC
18308 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18309 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18310 global_end - pltgot, 1,
18311 _("Global Offset Table data"));
919383ac 18312 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18313 data_end = data + (global_end - pltgot);
59245841 18314
ccb4c951
RS
18315 printf (_("\nPrimary GOT:\n"));
18316 printf (_(" Canonical gp value: "));
18317 print_vma (pltgot + 0x7ff0, LONG_HEX);
18318 printf ("\n\n");
18319
18320 printf (_(" Reserved entries:\n"));
18321 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18322 addr_size * 2, _("Address"), _("Access"),
18323 addr_size * 2, _("Initial"));
82b1b41b 18324 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18325 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18326 if (ent == (bfd_vma) -1)
18327 goto got_print_fail;
75ec1fdb 18328
c4ab9505
MR
18329 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18330 This entry will be used by some runtime loaders, to store the
18331 module pointer. Otherwise this is an ordinary local entry.
18332 PR 21344: Check for the entry being fully available before
18333 fetching it. */
18334 if (data
18335 && data + ent - pltgot + addr_size <= data_end
18336 && (byte_get (data + ent - pltgot, addr_size)
18337 >> (addr_size * 8 - 1)) != 0)
18338 {
18339 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18340 printf (_(" Module pointer (GNU extension)\n"));
18341 if (ent == (bfd_vma) -1)
18342 goto got_print_fail;
ccb4c951
RS
18343 }
18344 printf ("\n");
18345
f17e9d8a 18346 if (data != NULL && ent < local_end)
ccb4c951
RS
18347 {
18348 printf (_(" Local entries:\n"));
cc5914eb 18349 printf (" %*s %10s %*s\n",
2b692964
NC
18350 addr_size * 2, _("Address"), _("Access"),
18351 addr_size * 2, _("Initial"));
91d6fa6a 18352 while (ent < local_end)
ccb4c951 18353 {
82b1b41b 18354 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18355 printf ("\n");
82b1b41b
NC
18356 if (ent == (bfd_vma) -1)
18357 goto got_print_fail;
ccb4c951
RS
18358 }
18359 printf ("\n");
18360 }
18361
f17e9d8a 18362 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18363 {
18364 int sym_width;
18365
18366 printf (_(" Global entries:\n"));
cc5914eb 18367 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18368 addr_size * 2, _("Address"),
18369 _("Access"),
2b692964 18370 addr_size * 2, _("Initial"),
9cf03b7e
NC
18371 addr_size * 2, _("Sym.Val."),
18372 _("Type"),
18373 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18374 _("Ndx"), _("Name"));
0b4362b0 18375
ccb4c951 18376 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18377
ccb4c951
RS
18378 for (i = gotsym; i < symtabno; i++)
18379 {
82b1b41b 18380 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18381 printf (" ");
e0a31db1 18382
978c4450 18383 if (filedata->dynamic_symbols == NULL)
e0a31db1 18384 printf (_("<no dynamic symbols>"));
978c4450 18385 else if (i < filedata->num_dynamic_syms)
e0a31db1 18386 {
978c4450 18387 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
18388
18389 print_vma (psym->st_value, LONG_HEX);
18390 printf (" %-7s %3s ",
dda8d76d
NC
18391 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18392 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 18393
978c4450
AM
18394 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18395 print_symbol (sym_width,
18396 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18397 else
18398 printf (_("<corrupt: %14ld>"), psym->st_name);
18399 }
ccb4c951 18400 else
7fc5ac57
JBG
18401 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
18402 (unsigned long) i);
e0a31db1 18403
ccb4c951 18404 printf ("\n");
82b1b41b
NC
18405 if (ent == (bfd_vma) -1)
18406 break;
ccb4c951
RS
18407 }
18408 printf ("\n");
18409 }
18410
82b1b41b 18411 got_print_fail:
9db70fc3 18412 free (data);
ccb4c951
RS
18413 }
18414
861fb55a
DJ
18415 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
18416 {
91d6fa6a 18417 bfd_vma ent, end;
861fb55a
DJ
18418 size_t offset, rel_offset;
18419 unsigned long count, i;
2cf0635d 18420 unsigned char * data;
861fb55a 18421 int addr_size, sym_width;
2cf0635d 18422 Elf_Internal_Rela * rels;
861fb55a 18423
dda8d76d 18424 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
18425 if (pltrel == DT_RELA)
18426 {
dda8d76d 18427 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18428 return false;
861fb55a
DJ
18429 }
18430 else
18431 {
dda8d76d 18432 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18433 return false;
861fb55a
DJ
18434 }
18435
91d6fa6a 18436 ent = mips_pltgot;
861fb55a
DJ
18437 addr_size = (is_32bit_elf ? 4 : 8);
18438 end = mips_pltgot + (2 + count) * addr_size;
18439
dda8d76d
NC
18440 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
18441 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 18442 1, _("Procedure Linkage Table data"));
59245841 18443 if (data == NULL)
288f0ba2
AM
18444 {
18445 free (rels);
015dc7e1 18446 return false;
288f0ba2 18447 }
59245841 18448
9cf03b7e 18449 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
18450 printf (_(" Reserved entries:\n"));
18451 printf (_(" %*s %*s Purpose\n"),
2b692964 18452 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 18453 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18454 printf (_(" PLT lazy resolver\n"));
91d6fa6a 18455 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18456 printf (_(" Module pointer\n"));
861fb55a
DJ
18457 printf ("\n");
18458
18459 printf (_(" Entries:\n"));
cc5914eb 18460 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
18461 addr_size * 2, _("Address"),
18462 addr_size * 2, _("Initial"),
18463 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
18464 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
18465 for (i = 0; i < count; i++)
18466 {
df97ab2a 18467 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 18468
91d6fa6a 18469 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 18470 printf (" ");
e0a31db1 18471
978c4450 18472 if (idx >= filedata->num_dynamic_syms)
df97ab2a 18473 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 18474 else
e0a31db1 18475 {
978c4450 18476 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
18477
18478 print_vma (psym->st_value, LONG_HEX);
18479 printf (" %-7s %3s ",
dda8d76d
NC
18480 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18481 get_symbol_index_type (filedata, psym->st_shndx));
978c4450
AM
18482 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18483 print_symbol (sym_width,
18484 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18485 else
18486 printf (_("<corrupt: %14ld>"), psym->st_name);
18487 }
861fb55a
DJ
18488 printf ("\n");
18489 }
18490 printf ("\n");
18491
9db70fc3 18492 free (data);
861fb55a
DJ
18493 free (rels);
18494 }
18495
32ec8896 18496 return res;
252b5132
RH
18497}
18498
015dc7e1 18499static bool
dda8d76d 18500process_nds32_specific (Filedata * filedata)
35c08157
KLC
18501{
18502 Elf_Internal_Shdr *sect = NULL;
18503
dda8d76d 18504 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 18505 if (sect != NULL && sect->sh_size >= 4)
35c08157 18506 {
9c7b8e9b
AM
18507 unsigned char *buf;
18508 unsigned int flag;
35c08157
KLC
18509
18510 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
18511 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
18512 _("NDS32 elf flags section"));
35c08157 18513
9c7b8e9b 18514 if (buf == NULL)
015dc7e1 18515 return false;
32ec8896 18516
9c7b8e9b
AM
18517 flag = byte_get (buf, 4);
18518 free (buf);
18519 switch (flag & 0x3)
35c08157
KLC
18520 {
18521 case 0:
18522 printf ("(VEC_SIZE):\tNo entry.\n");
18523 break;
18524 case 1:
18525 printf ("(VEC_SIZE):\t4 bytes\n");
18526 break;
18527 case 2:
18528 printf ("(VEC_SIZE):\t16 bytes\n");
18529 break;
18530 case 3:
18531 printf ("(VEC_SIZE):\treserved\n");
18532 break;
18533 }
18534 }
18535
015dc7e1 18536 return true;
35c08157
KLC
18537}
18538
015dc7e1 18539static bool
dda8d76d 18540process_gnu_liblist (Filedata * filedata)
047b2264 18541{
2cf0635d
NC
18542 Elf_Internal_Shdr * section;
18543 Elf_Internal_Shdr * string_sec;
18544 Elf32_External_Lib * elib;
18545 char * strtab;
c256ffe7 18546 size_t strtab_size;
047b2264 18547 size_t cnt;
d3a49aa8 18548 unsigned long num_liblist;
047b2264 18549 unsigned i;
015dc7e1 18550 bool res = true;
047b2264
JJ
18551
18552 if (! do_arch)
015dc7e1 18553 return true;
047b2264 18554
dda8d76d
NC
18555 for (i = 0, section = filedata->section_headers;
18556 i < filedata->file_header.e_shnum;
b34976b6 18557 i++, section++)
047b2264
JJ
18558 {
18559 switch (section->sh_type)
18560 {
18561 case SHT_GNU_LIBLIST:
dda8d76d 18562 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
18563 break;
18564
3f5e193b 18565 elib = (Elf32_External_Lib *)
dda8d76d 18566 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 18567 _("liblist section data"));
047b2264
JJ
18568
18569 if (elib == NULL)
32ec8896 18570 {
015dc7e1 18571 res = false;
32ec8896
NC
18572 break;
18573 }
047b2264 18574
dda8d76d
NC
18575 string_sec = filedata->section_headers + section->sh_link;
18576 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
18577 string_sec->sh_size,
18578 _("liblist string table"));
047b2264
JJ
18579 if (strtab == NULL
18580 || section->sh_entsize != sizeof (Elf32_External_Lib))
18581 {
18582 free (elib);
2842702f 18583 free (strtab);
015dc7e1 18584 res = false;
047b2264
JJ
18585 break;
18586 }
59245841 18587 strtab_size = string_sec->sh_size;
047b2264 18588
d3a49aa8
AM
18589 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
18590 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
18591 "\nLibrary list section '%s' contains %lu entries:\n",
18592 num_liblist),
dda8d76d 18593 printable_section_name (filedata, section),
d3a49aa8 18594 num_liblist);
047b2264 18595
2b692964 18596 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
18597
18598 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
18599 ++cnt)
18600 {
18601 Elf32_Lib liblist;
91d6fa6a 18602 time_t atime;
d5b07ef4 18603 char timebuf[128];
2cf0635d 18604 struct tm * tmp;
047b2264
JJ
18605
18606 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18607 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
18608 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18609 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18610 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18611
91d6fa6a 18612 tmp = gmtime (&atime);
e9e44622
JJ
18613 snprintf (timebuf, sizeof (timebuf),
18614 "%04u-%02u-%02uT%02u:%02u:%02u",
18615 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18616 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
18617
18618 printf ("%3lu: ", (unsigned long) cnt);
18619 if (do_wide)
c256ffe7 18620 printf ("%-20s", liblist.l_name < strtab_size
2b692964 18621 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 18622 else
c256ffe7 18623 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 18624 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
18625 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
18626 liblist.l_version, liblist.l_flags);
18627 }
18628
18629 free (elib);
2842702f 18630 free (strtab);
047b2264
JJ
18631 }
18632 }
18633
32ec8896 18634 return res;
047b2264
JJ
18635}
18636
9437c45b 18637static const char *
dda8d76d 18638get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
18639{
18640 static char buff[64];
103f02d3 18641
dda8d76d 18642 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
18643 switch (e_type)
18644 {
57346661 18645 case NT_AUXV:
1ec5cd37 18646 return _("NT_AUXV (auxiliary vector)");
57346661 18647 case NT_PRSTATUS:
1ec5cd37 18648 return _("NT_PRSTATUS (prstatus structure)");
57346661 18649 case NT_FPREGSET:
1ec5cd37 18650 return _("NT_FPREGSET (floating point registers)");
57346661 18651 case NT_PRPSINFO:
1ec5cd37 18652 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 18653 case NT_TASKSTRUCT:
1ec5cd37 18654 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
18655 case NT_GDB_TDESC:
18656 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 18657 case NT_PRXFPREG:
1ec5cd37 18658 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
18659 case NT_PPC_VMX:
18660 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
18661 case NT_PPC_VSX:
18662 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
18663 case NT_PPC_TAR:
18664 return _("NT_PPC_TAR (ppc TAR register)");
18665 case NT_PPC_PPR:
18666 return _("NT_PPC_PPR (ppc PPR register)");
18667 case NT_PPC_DSCR:
18668 return _("NT_PPC_DSCR (ppc DSCR register)");
18669 case NT_PPC_EBB:
18670 return _("NT_PPC_EBB (ppc EBB registers)");
18671 case NT_PPC_PMU:
18672 return _("NT_PPC_PMU (ppc PMU registers)");
18673 case NT_PPC_TM_CGPR:
18674 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
18675 case NT_PPC_TM_CFPR:
18676 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
18677 case NT_PPC_TM_CVMX:
18678 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
18679 case NT_PPC_TM_CVSX:
3fd21718 18680 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
18681 case NT_PPC_TM_SPR:
18682 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
18683 case NT_PPC_TM_CTAR:
18684 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
18685 case NT_PPC_TM_CPPR:
18686 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
18687 case NT_PPC_TM_CDSCR:
18688 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
18689 case NT_386_TLS:
18690 return _("NT_386_TLS (x86 TLS information)");
18691 case NT_386_IOPERM:
18692 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
18693 case NT_X86_XSTATE:
18694 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
18695 case NT_X86_CET:
18696 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
18697 case NT_S390_HIGH_GPRS:
18698 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
18699 case NT_S390_TIMER:
18700 return _("NT_S390_TIMER (s390 timer register)");
18701 case NT_S390_TODCMP:
18702 return _("NT_S390_TODCMP (s390 TOD comparator register)");
18703 case NT_S390_TODPREG:
18704 return _("NT_S390_TODPREG (s390 TOD programmable register)");
18705 case NT_S390_CTRS:
18706 return _("NT_S390_CTRS (s390 control registers)");
18707 case NT_S390_PREFIX:
18708 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
18709 case NT_S390_LAST_BREAK:
18710 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
18711 case NT_S390_SYSTEM_CALL:
18712 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
18713 case NT_S390_TDB:
18714 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
18715 case NT_S390_VXRS_LOW:
18716 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
18717 case NT_S390_VXRS_HIGH:
18718 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
18719 case NT_S390_GS_CB:
18720 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
18721 case NT_S390_GS_BC:
18722 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
18723 case NT_ARM_VFP:
18724 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
18725 case NT_ARM_TLS:
18726 return _("NT_ARM_TLS (AArch TLS registers)");
18727 case NT_ARM_HW_BREAK:
18728 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
18729 case NT_ARM_HW_WATCH:
18730 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
3b2bef8b
LM
18731 case NT_ARM_SVE:
18732 return _("NT_ARM_SVE (AArch SVE registers)");
18733 case NT_ARM_PAC_MASK:
18734 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
18735 case NT_ARM_TAGGED_ADDR_CTRL:
18736 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
27456742
AK
18737 case NT_ARC_V2:
18738 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
18739 case NT_RISCV_CSR:
18740 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 18741 case NT_PSTATUS:
1ec5cd37 18742 return _("NT_PSTATUS (pstatus structure)");
57346661 18743 case NT_FPREGS:
1ec5cd37 18744 return _("NT_FPREGS (floating point registers)");
57346661 18745 case NT_PSINFO:
1ec5cd37 18746 return _("NT_PSINFO (psinfo structure)");
57346661 18747 case NT_LWPSTATUS:
1ec5cd37 18748 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 18749 case NT_LWPSINFO:
1ec5cd37 18750 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 18751 case NT_WIN32PSTATUS:
1ec5cd37 18752 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
18753 case NT_SIGINFO:
18754 return _("NT_SIGINFO (siginfo_t data)");
18755 case NT_FILE:
18756 return _("NT_FILE (mapped files)");
894982bf
LM
18757 case NT_MEMTAG:
18758 return _("NT_MEMTAG (memory tags)");
1ec5cd37
NC
18759 default:
18760 break;
18761 }
18762 else
18763 switch (e_type)
18764 {
18765 case NT_VERSION:
18766 return _("NT_VERSION (version)");
18767 case NT_ARCH:
18768 return _("NT_ARCH (architecture)");
9ef920e9 18769 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 18770 return _("OPEN");
9ef920e9 18771 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 18772 return _("func");
1ec5cd37
NC
18773 default:
18774 break;
18775 }
18776
e9e44622 18777 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 18778 return buff;
779fe533
NC
18779}
18780
015dc7e1 18781static bool
9ece1fa9
TT
18782print_core_note (Elf_Internal_Note *pnote)
18783{
18784 unsigned int addr_size = is_32bit_elf ? 4 : 8;
18785 bfd_vma count, page_size;
18786 unsigned char *descdata, *filenames, *descend;
18787
18788 if (pnote->type != NT_FILE)
04ac15ab
AS
18789 {
18790 if (do_wide)
18791 printf ("\n");
015dc7e1 18792 return true;
04ac15ab 18793 }
9ece1fa9
TT
18794
18795#ifndef BFD64
18796 if (!is_32bit_elf)
18797 {
18798 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
18799 /* Still "successful". */
015dc7e1 18800 return true;
9ece1fa9
TT
18801 }
18802#endif
18803
18804 if (pnote->descsz < 2 * addr_size)
18805 {
32ec8896 18806 error (_(" Malformed note - too short for header\n"));
015dc7e1 18807 return false;
9ece1fa9
TT
18808 }
18809
18810 descdata = (unsigned char *) pnote->descdata;
18811 descend = descdata + pnote->descsz;
18812
18813 if (descdata[pnote->descsz - 1] != '\0')
18814 {
32ec8896 18815 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 18816 return false;
9ece1fa9
TT
18817 }
18818
18819 count = byte_get (descdata, addr_size);
18820 descdata += addr_size;
18821
18822 page_size = byte_get (descdata, addr_size);
18823 descdata += addr_size;
18824
5396a86e
AM
18825 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
18826 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 18827 {
32ec8896 18828 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 18829 return false;
9ece1fa9
TT
18830 }
18831
18832 printf (_(" Page size: "));
18833 print_vma (page_size, DEC);
18834 printf ("\n");
18835
18836 printf (_(" %*s%*s%*s\n"),
18837 (int) (2 + 2 * addr_size), _("Start"),
18838 (int) (4 + 2 * addr_size), _("End"),
18839 (int) (4 + 2 * addr_size), _("Page Offset"));
18840 filenames = descdata + count * 3 * addr_size;
595712bb 18841 while (count-- > 0)
9ece1fa9
TT
18842 {
18843 bfd_vma start, end, file_ofs;
18844
18845 if (filenames == descend)
18846 {
32ec8896 18847 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 18848 return false;
9ece1fa9
TT
18849 }
18850
18851 start = byte_get (descdata, addr_size);
18852 descdata += addr_size;
18853 end = byte_get (descdata, addr_size);
18854 descdata += addr_size;
18855 file_ofs = byte_get (descdata, addr_size);
18856 descdata += addr_size;
18857
18858 printf (" ");
18859 print_vma (start, FULL_HEX);
18860 printf (" ");
18861 print_vma (end, FULL_HEX);
18862 printf (" ");
18863 print_vma (file_ofs, FULL_HEX);
18864 printf ("\n %s\n", filenames);
18865
18866 filenames += 1 + strlen ((char *) filenames);
18867 }
18868
015dc7e1 18869 return true;
9ece1fa9
TT
18870}
18871
1118d252
RM
18872static const char *
18873get_gnu_elf_note_type (unsigned e_type)
18874{
1449284b 18875 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
18876 switch (e_type)
18877 {
18878 case NT_GNU_ABI_TAG:
18879 return _("NT_GNU_ABI_TAG (ABI version tag)");
18880 case NT_GNU_HWCAP:
18881 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
18882 case NT_GNU_BUILD_ID:
18883 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
18884 case NT_GNU_GOLD_VERSION:
18885 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
18886 case NT_GNU_PROPERTY_TYPE_0:
18887 return _("NT_GNU_PROPERTY_TYPE_0");
18888 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
18889 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
18890 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
18891 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 18892 default:
1449284b
NC
18893 {
18894 static char buff[64];
1118d252 18895
1449284b
NC
18896 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18897 return buff;
18898 }
18899 }
1118d252
RM
18900}
18901
a9eafb08
L
18902static void
18903decode_x86_compat_isa (unsigned int bitmask)
18904{
18905 while (bitmask)
18906 {
18907 unsigned int bit = bitmask & (- bitmask);
18908
18909 bitmask &= ~ bit;
18910 switch (bit)
18911 {
18912 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
18913 printf ("i486");
18914 break;
18915 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
18916 printf ("586");
18917 break;
18918 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
18919 printf ("686");
18920 break;
18921 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
18922 printf ("SSE");
18923 break;
18924 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
18925 printf ("SSE2");
18926 break;
18927 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
18928 printf ("SSE3");
18929 break;
18930 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
18931 printf ("SSSE3");
18932 break;
18933 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
18934 printf ("SSE4_1");
18935 break;
18936 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
18937 printf ("SSE4_2");
18938 break;
18939 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
18940 printf ("AVX");
18941 break;
18942 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
18943 printf ("AVX2");
18944 break;
18945 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
18946 printf ("AVX512F");
18947 break;
18948 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
18949 printf ("AVX512CD");
18950 break;
18951 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
18952 printf ("AVX512ER");
18953 break;
18954 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
18955 printf ("AVX512PF");
18956 break;
18957 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
18958 printf ("AVX512VL");
18959 break;
18960 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
18961 printf ("AVX512DQ");
18962 break;
18963 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
18964 printf ("AVX512BW");
18965 break;
65b3d26e
L
18966 default:
18967 printf (_("<unknown: %x>"), bit);
18968 break;
a9eafb08
L
18969 }
18970 if (bitmask)
18971 printf (", ");
18972 }
18973}
18974
9ef920e9 18975static void
32930e4e 18976decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 18977{
0a59decb 18978 if (!bitmask)
90c745dc
L
18979 {
18980 printf (_("<None>"));
18981 return;
18982 }
90c745dc 18983
9ef920e9
NC
18984 while (bitmask)
18985 {
1fc87489 18986 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
18987
18988 bitmask &= ~ bit;
18989 switch (bit)
18990 {
32930e4e 18991 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
18992 printf ("CMOV");
18993 break;
32930e4e 18994 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
18995 printf ("SSE");
18996 break;
32930e4e 18997 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
18998 printf ("SSE2");
18999 break;
32930e4e 19000 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19001 printf ("SSE3");
19002 break;
32930e4e 19003 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19004 printf ("SSSE3");
19005 break;
32930e4e 19006 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19007 printf ("SSE4_1");
19008 break;
32930e4e 19009 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19010 printf ("SSE4_2");
19011 break;
32930e4e 19012 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19013 printf ("AVX");
19014 break;
32930e4e 19015 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19016 printf ("AVX2");
19017 break;
32930e4e 19018 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19019 printf ("FMA");
19020 break;
32930e4e 19021 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19022 printf ("AVX512F");
19023 break;
32930e4e 19024 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19025 printf ("AVX512CD");
19026 break;
32930e4e 19027 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19028 printf ("AVX512ER");
19029 break;
32930e4e 19030 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19031 printf ("AVX512PF");
19032 break;
32930e4e 19033 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19034 printf ("AVX512VL");
19035 break;
32930e4e 19036 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19037 printf ("AVX512DQ");
19038 break;
32930e4e 19039 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19040 printf ("AVX512BW");
19041 break;
32930e4e 19042 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19043 printf ("AVX512_4FMAPS");
19044 break;
32930e4e 19045 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19046 printf ("AVX512_4VNNIW");
19047 break;
32930e4e 19048 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19049 printf ("AVX512_BITALG");
19050 break;
32930e4e 19051 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19052 printf ("AVX512_IFMA");
19053 break;
32930e4e 19054 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19055 printf ("AVX512_VBMI");
19056 break;
32930e4e 19057 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19058 printf ("AVX512_VBMI2");
19059 break;
32930e4e 19060 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19061 printf ("AVX512_VNNI");
19062 break;
32930e4e 19063 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19064 printf ("AVX512_BF16");
19065 break;
65b3d26e
L
19066 default:
19067 printf (_("<unknown: %x>"), bit);
19068 break;
9ef920e9
NC
19069 }
19070 if (bitmask)
19071 printf (", ");
19072 }
19073}
19074
32930e4e
L
19075static void
19076decode_x86_isa (unsigned int bitmask)
19077{
32930e4e
L
19078 while (bitmask)
19079 {
19080 unsigned int bit = bitmask & (- bitmask);
19081
19082 bitmask &= ~ bit;
19083 switch (bit)
19084 {
b0ab0693
L
19085 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19086 printf ("x86-64-baseline");
19087 break;
32930e4e
L
19088 case GNU_PROPERTY_X86_ISA_1_V2:
19089 printf ("x86-64-v2");
19090 break;
19091 case GNU_PROPERTY_X86_ISA_1_V3:
19092 printf ("x86-64-v3");
19093 break;
19094 case GNU_PROPERTY_X86_ISA_1_V4:
19095 printf ("x86-64-v4");
19096 break;
19097 default:
19098 printf (_("<unknown: %x>"), bit);
19099 break;
19100 }
19101 if (bitmask)
19102 printf (", ");
19103 }
19104}
19105
ee2fdd6f 19106static void
a9eafb08 19107decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19108{
0a59decb 19109 if (!bitmask)
90c745dc
L
19110 {
19111 printf (_("<None>"));
19112 return;
19113 }
90c745dc 19114
ee2fdd6f
L
19115 while (bitmask)
19116 {
19117 unsigned int bit = bitmask & (- bitmask);
19118
19119 bitmask &= ~ bit;
19120 switch (bit)
19121 {
19122 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19123 printf ("IBT");
ee2fdd6f 19124 break;
48580982 19125 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19126 printf ("SHSTK");
48580982 19127 break;
279d901e
L
19128 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19129 printf ("LAM_U48");
19130 break;
19131 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19132 printf ("LAM_U57");
19133 break;
ee2fdd6f
L
19134 default:
19135 printf (_("<unknown: %x>"), bit);
19136 break;
19137 }
19138 if (bitmask)
19139 printf (", ");
19140 }
19141}
19142
a9eafb08
L
19143static void
19144decode_x86_feature_2 (unsigned int bitmask)
19145{
0a59decb 19146 if (!bitmask)
90c745dc
L
19147 {
19148 printf (_("<None>"));
19149 return;
19150 }
90c745dc 19151
a9eafb08
L
19152 while (bitmask)
19153 {
19154 unsigned int bit = bitmask & (- bitmask);
19155
19156 bitmask &= ~ bit;
19157 switch (bit)
19158 {
19159 case GNU_PROPERTY_X86_FEATURE_2_X86:
19160 printf ("x86");
19161 break;
19162 case GNU_PROPERTY_X86_FEATURE_2_X87:
19163 printf ("x87");
19164 break;
19165 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19166 printf ("MMX");
19167 break;
19168 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19169 printf ("XMM");
19170 break;
19171 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19172 printf ("YMM");
19173 break;
19174 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19175 printf ("ZMM");
19176 break;
a308b89d
L
19177 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19178 printf ("TMM");
19179 break;
32930e4e
L
19180 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19181 printf ("MASK");
19182 break;
a9eafb08
L
19183 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19184 printf ("FXSR");
19185 break;
19186 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19187 printf ("XSAVE");
19188 break;
19189 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19190 printf ("XSAVEOPT");
19191 break;
19192 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19193 printf ("XSAVEC");
19194 break;
65b3d26e
L
19195 default:
19196 printf (_("<unknown: %x>"), bit);
19197 break;
a9eafb08
L
19198 }
19199 if (bitmask)
19200 printf (", ");
19201 }
19202}
19203
cd702818
SD
19204static void
19205decode_aarch64_feature_1_and (unsigned int bitmask)
19206{
19207 while (bitmask)
19208 {
19209 unsigned int bit = bitmask & (- bitmask);
19210
19211 bitmask &= ~ bit;
19212 switch (bit)
19213 {
19214 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19215 printf ("BTI");
19216 break;
19217
19218 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19219 printf ("PAC");
19220 break;
19221
19222 default:
19223 printf (_("<unknown: %x>"), bit);
19224 break;
19225 }
19226 if (bitmask)
19227 printf (", ");
19228 }
19229}
19230
9ef920e9 19231static void
dda8d76d 19232print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19233{
19234 unsigned char * ptr = (unsigned char *) pnote->descdata;
19235 unsigned char * ptr_end = ptr + pnote->descsz;
19236 unsigned int size = is_32bit_elf ? 4 : 8;
19237
19238 printf (_(" Properties: "));
19239
1fc87489 19240 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19241 {
19242 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19243 return;
19244 }
19245
6ab2c4ed 19246 while (ptr < ptr_end)
9ef920e9 19247 {
1fc87489 19248 unsigned int j;
6ab2c4ed
MC
19249 unsigned int type;
19250 unsigned int datasz;
19251
19252 if ((size_t) (ptr_end - ptr) < 8)
19253 {
19254 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19255 break;
19256 }
19257
19258 type = byte_get (ptr, 4);
19259 datasz = byte_get (ptr + 4, 4);
9ef920e9 19260
1fc87489 19261 ptr += 8;
9ef920e9 19262
6ab2c4ed 19263 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19264 {
1fc87489
L
19265 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19266 type, datasz);
9ef920e9 19267 break;
1fc87489 19268 }
9ef920e9 19269
1fc87489
L
19270 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19271 {
dda8d76d
NC
19272 if (filedata->file_header.e_machine == EM_X86_64
19273 || filedata->file_header.e_machine == EM_IAMCU
19274 || filedata->file_header.e_machine == EM_386)
1fc87489 19275 {
aa7bca9b
L
19276 unsigned int bitmask;
19277
19278 if (datasz == 4)
0a59decb 19279 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19280 else
19281 bitmask = 0;
19282
1fc87489
L
19283 switch (type)
19284 {
19285 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19286 if (datasz != 4)
aa7bca9b
L
19287 printf (_("x86 ISA used: <corrupt length: %#x> "),
19288 datasz);
1fc87489 19289 else
aa7bca9b
L
19290 {
19291 printf ("x86 ISA used: ");
19292 decode_x86_isa (bitmask);
19293 }
1fc87489 19294 goto next;
9ef920e9 19295
1fc87489 19296 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19297 if (datasz != 4)
aa7bca9b
L
19298 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19299 datasz);
1fc87489 19300 else
aa7bca9b
L
19301 {
19302 printf ("x86 ISA needed: ");
19303 decode_x86_isa (bitmask);
19304 }
1fc87489 19305 goto next;
9ef920e9 19306
ee2fdd6f 19307 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19308 if (datasz != 4)
aa7bca9b
L
19309 printf (_("x86 feature: <corrupt length: %#x> "),
19310 datasz);
ee2fdd6f 19311 else
aa7bca9b
L
19312 {
19313 printf ("x86 feature: ");
a9eafb08
L
19314 decode_x86_feature_1 (bitmask);
19315 }
19316 goto next;
19317
19318 case GNU_PROPERTY_X86_FEATURE_2_USED:
19319 if (datasz != 4)
19320 printf (_("x86 feature used: <corrupt length: %#x> "),
19321 datasz);
19322 else
19323 {
19324 printf ("x86 feature used: ");
19325 decode_x86_feature_2 (bitmask);
19326 }
19327 goto next;
19328
19329 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
19330 if (datasz != 4)
19331 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
19332 else
19333 {
19334 printf ("x86 feature needed: ");
19335 decode_x86_feature_2 (bitmask);
19336 }
19337 goto next;
19338
19339 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
19340 if (datasz != 4)
19341 printf (_("x86 ISA used: <corrupt length: %#x> "),
19342 datasz);
19343 else
19344 {
19345 printf ("x86 ISA used: ");
19346 decode_x86_compat_isa (bitmask);
19347 }
19348 goto next;
19349
19350 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
19351 if (datasz != 4)
19352 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19353 datasz);
19354 else
19355 {
19356 printf ("x86 ISA needed: ");
19357 decode_x86_compat_isa (bitmask);
aa7bca9b 19358 }
ee2fdd6f
L
19359 goto next;
19360
32930e4e
L
19361 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
19362 if (datasz != 4)
19363 printf (_("x86 ISA used: <corrupt length: %#x> "),
19364 datasz);
19365 else
19366 {
19367 printf ("x86 ISA used: ");
19368 decode_x86_compat_2_isa (bitmask);
19369 }
19370 goto next;
19371
19372 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
19373 if (datasz != 4)
19374 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19375 datasz);
19376 else
19377 {
19378 printf ("x86 ISA needed: ");
19379 decode_x86_compat_2_isa (bitmask);
19380 }
19381 goto next;
19382
1fc87489
L
19383 default:
19384 break;
19385 }
19386 }
cd702818
SD
19387 else if (filedata->file_header.e_machine == EM_AARCH64)
19388 {
19389 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
19390 {
19391 printf ("AArch64 feature: ");
19392 if (datasz != 4)
19393 printf (_("<corrupt length: %#x> "), datasz);
19394 else
19395 decode_aarch64_feature_1_and (byte_get (ptr, 4));
19396 goto next;
19397 }
19398 }
1fc87489
L
19399 }
19400 else
19401 {
19402 switch (type)
9ef920e9 19403 {
1fc87489
L
19404 case GNU_PROPERTY_STACK_SIZE:
19405 printf (_("stack size: "));
19406 if (datasz != size)
19407 printf (_("<corrupt length: %#x> "), datasz);
19408 else
19409 printf ("%#lx", (unsigned long) byte_get (ptr, size));
19410 goto next;
19411
19412 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
19413 printf ("no copy on protected ");
19414 if (datasz)
19415 printf (_("<corrupt length: %#x> "), datasz);
19416 goto next;
19417
19418 default:
9ef920e9
NC
19419 break;
19420 }
9ef920e9
NC
19421 }
19422
1fc87489
L
19423 if (type < GNU_PROPERTY_LOPROC)
19424 printf (_("<unknown type %#x data: "), type);
19425 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 19426 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
19427 else
19428 printf (_("<application-specific type %#x data: "), type);
19429 for (j = 0; j < datasz; ++j)
19430 printf ("%02x ", ptr[j] & 0xff);
19431 printf (">");
19432
dc1e8a47 19433 next:
9ef920e9 19434 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
19435 if (ptr == ptr_end)
19436 break;
1fc87489 19437
6ab2c4ed
MC
19438 if (do_wide)
19439 printf (", ");
19440 else
19441 printf ("\n\t");
9ef920e9
NC
19442 }
19443
19444 printf ("\n");
19445}
19446
015dc7e1 19447static bool
dda8d76d 19448print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 19449{
1449284b 19450 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
19451 switch (pnote->type)
19452 {
19453 case NT_GNU_BUILD_ID:
19454 {
19455 unsigned long i;
19456
19457 printf (_(" Build ID: "));
19458 for (i = 0; i < pnote->descsz; ++i)
19459 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 19460 printf ("\n");
664f90a3
TT
19461 }
19462 break;
19463
19464 case NT_GNU_ABI_TAG:
19465 {
19466 unsigned long os, major, minor, subminor;
19467 const char *osname;
19468
3102e897
NC
19469 /* PR 17531: file: 030-599401-0.004. */
19470 if (pnote->descsz < 16)
19471 {
19472 printf (_(" <corrupt GNU_ABI_TAG>\n"));
19473 break;
19474 }
19475
664f90a3
TT
19476 os = byte_get ((unsigned char *) pnote->descdata, 4);
19477 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19478 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
19479 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
19480
19481 switch (os)
19482 {
19483 case GNU_ABI_TAG_LINUX:
19484 osname = "Linux";
19485 break;
19486 case GNU_ABI_TAG_HURD:
19487 osname = "Hurd";
19488 break;
19489 case GNU_ABI_TAG_SOLARIS:
19490 osname = "Solaris";
19491 break;
19492 case GNU_ABI_TAG_FREEBSD:
19493 osname = "FreeBSD";
19494 break;
19495 case GNU_ABI_TAG_NETBSD:
19496 osname = "NetBSD";
19497 break;
14ae95f2
RM
19498 case GNU_ABI_TAG_SYLLABLE:
19499 osname = "Syllable";
19500 break;
19501 case GNU_ABI_TAG_NACL:
19502 osname = "NaCl";
19503 break;
664f90a3
TT
19504 default:
19505 osname = "Unknown";
19506 break;
19507 }
19508
19509 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
19510 major, minor, subminor);
19511 }
19512 break;
926c5385
CC
19513
19514 case NT_GNU_GOLD_VERSION:
19515 {
19516 unsigned long i;
19517
19518 printf (_(" Version: "));
19519 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
19520 printf ("%c", pnote->descdata[i]);
19521 printf ("\n");
19522 }
19523 break;
1449284b
NC
19524
19525 case NT_GNU_HWCAP:
19526 {
19527 unsigned long num_entries, mask;
19528
19529 /* Hardware capabilities information. Word 0 is the number of entries.
19530 Word 1 is a bitmask of enabled entries. The rest of the descriptor
19531 is a series of entries, where each entry is a single byte followed
19532 by a nul terminated string. The byte gives the bit number to test
19533 if enabled in the bitmask. */
19534 printf (_(" Hardware Capabilities: "));
19535 if (pnote->descsz < 8)
19536 {
32ec8896 19537 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 19538 return false;
1449284b
NC
19539 }
19540 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
19541 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19542 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
19543 /* FIXME: Add code to display the entries... */
19544 }
19545 break;
19546
9ef920e9 19547 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 19548 print_gnu_property_note (filedata, pnote);
9ef920e9 19549 break;
9abca702 19550
1449284b
NC
19551 default:
19552 /* Handle unrecognised types. An error message should have already been
19553 created by get_gnu_elf_note_type(), so all that we need to do is to
19554 display the data. */
19555 {
19556 unsigned long i;
19557
19558 printf (_(" Description data: "));
19559 for (i = 0; i < pnote->descsz; ++i)
19560 printf ("%02x ", pnote->descdata[i] & 0xff);
19561 printf ("\n");
19562 }
19563 break;
664f90a3
TT
19564 }
19565
015dc7e1 19566 return true;
664f90a3
TT
19567}
19568
685080f2
NC
19569static const char *
19570get_v850_elf_note_type (enum v850_notes n_type)
19571{
19572 static char buff[64];
19573
19574 switch (n_type)
19575 {
19576 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
19577 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
19578 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
19579 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
19580 case V850_NOTE_CACHE_INFO: return _("Use of cache");
19581 case V850_NOTE_MMU_INFO: return _("Use of MMU");
19582 default:
19583 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
19584 return buff;
19585 }
19586}
19587
015dc7e1 19588static bool
685080f2
NC
19589print_v850_note (Elf_Internal_Note * pnote)
19590{
19591 unsigned int val;
19592
19593 if (pnote->descsz != 4)
015dc7e1 19594 return false;
32ec8896 19595
685080f2
NC
19596 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
19597
19598 if (val == 0)
19599 {
19600 printf (_("not set\n"));
015dc7e1 19601 return true;
685080f2
NC
19602 }
19603
19604 switch (pnote->type)
19605 {
19606 case V850_NOTE_ALIGNMENT:
19607 switch (val)
19608 {
015dc7e1
AM
19609 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
19610 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
19611 }
19612 break;
14ae95f2 19613
685080f2
NC
19614 case V850_NOTE_DATA_SIZE:
19615 switch (val)
19616 {
015dc7e1
AM
19617 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
19618 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
19619 }
19620 break;
14ae95f2 19621
685080f2
NC
19622 case V850_NOTE_FPU_INFO:
19623 switch (val)
19624 {
015dc7e1
AM
19625 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
19626 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
19627 }
19628 break;
14ae95f2 19629
685080f2
NC
19630 case V850_NOTE_MMU_INFO:
19631 case V850_NOTE_CACHE_INFO:
19632 case V850_NOTE_SIMD_INFO:
19633 if (val == EF_RH850_SIMD)
19634 {
19635 printf (_("yes\n"));
015dc7e1 19636 return true;
685080f2
NC
19637 }
19638 break;
19639
19640 default:
19641 /* An 'unknown note type' message will already have been displayed. */
19642 break;
19643 }
19644
19645 printf (_("unknown value: %x\n"), val);
015dc7e1 19646 return false;
685080f2
NC
19647}
19648
015dc7e1 19649static bool
c6056a74
SF
19650process_netbsd_elf_note (Elf_Internal_Note * pnote)
19651{
19652 unsigned int version;
19653
19654 switch (pnote->type)
19655 {
19656 case NT_NETBSD_IDENT:
b966f55f
AM
19657 if (pnote->descsz < 1)
19658 break;
c6056a74
SF
19659 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19660 if ((version / 10000) % 100)
b966f55f 19661 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
19662 version, version / 100000000, (version / 1000000) % 100,
19663 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 19664 'A' + (version / 10000) % 26);
c6056a74
SF
19665 else
19666 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 19667 version, version / 100000000, (version / 1000000) % 100,
15f205b1 19668 (version / 100) % 100);
015dc7e1 19669 return true;
c6056a74
SF
19670
19671 case NT_NETBSD_MARCH:
9abca702 19672 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 19673 pnote->descdata);
015dc7e1 19674 return true;
c6056a74 19675
9abca702 19676 case NT_NETBSD_PAX:
b966f55f
AM
19677 if (pnote->descsz < 1)
19678 break;
9abca702
CZ
19679 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19680 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
19681 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
19682 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
19683 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
19684 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
19685 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
19686 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 19687 return true;
c6056a74 19688 }
b966f55f
AM
19689
19690 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
19691 pnote->descsz, pnote->type);
015dc7e1 19692 return false;
c6056a74
SF
19693}
19694
f4ddf30f 19695static const char *
dda8d76d 19696get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 19697{
f4ddf30f
JB
19698 switch (e_type)
19699 {
19700 case NT_FREEBSD_THRMISC:
19701 return _("NT_THRMISC (thrmisc structure)");
19702 case NT_FREEBSD_PROCSTAT_PROC:
19703 return _("NT_PROCSTAT_PROC (proc data)");
19704 case NT_FREEBSD_PROCSTAT_FILES:
19705 return _("NT_PROCSTAT_FILES (files data)");
19706 case NT_FREEBSD_PROCSTAT_VMMAP:
19707 return _("NT_PROCSTAT_VMMAP (vmmap data)");
19708 case NT_FREEBSD_PROCSTAT_GROUPS:
19709 return _("NT_PROCSTAT_GROUPS (groups data)");
19710 case NT_FREEBSD_PROCSTAT_UMASK:
19711 return _("NT_PROCSTAT_UMASK (umask data)");
19712 case NT_FREEBSD_PROCSTAT_RLIMIT:
19713 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
19714 case NT_FREEBSD_PROCSTAT_OSREL:
19715 return _("NT_PROCSTAT_OSREL (osreldate data)");
19716 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
19717 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
19718 case NT_FREEBSD_PROCSTAT_AUXV:
19719 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
19720 case NT_FREEBSD_PTLWPINFO:
19721 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 19722 }
dda8d76d 19723 return get_note_type (filedata, e_type);
f4ddf30f
JB
19724}
19725
9437c45b 19726static const char *
dda8d76d 19727get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
19728{
19729 static char buff[64];
19730
540e6170
CZ
19731 switch (e_type)
19732 {
19733 case NT_NETBSDCORE_PROCINFO:
19734 /* NetBSD core "procinfo" structure. */
19735 return _("NetBSD procinfo structure");
9437c45b 19736
540e6170
CZ
19737 case NT_NETBSDCORE_AUXV:
19738 return _("NetBSD ELF auxiliary vector data");
9437c45b 19739
06d949ec
KR
19740 case NT_NETBSDCORE_LWPSTATUS:
19741 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 19742
540e6170 19743 default:
06d949ec 19744 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
19745 defined for NetBSD core files. If the note type is less
19746 than the start of the machine-dependent note types, we don't
19747 understand it. */
19748
19749 if (e_type < NT_NETBSDCORE_FIRSTMACH)
19750 {
19751 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19752 return buff;
19753 }
19754 break;
9437c45b
JT
19755 }
19756
dda8d76d 19757 switch (filedata->file_header.e_machine)
9437c45b
JT
19758 {
19759 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
19760 and PT_GETFPREGS == mach+2. */
19761
19762 case EM_OLD_ALPHA:
19763 case EM_ALPHA:
19764 case EM_SPARC:
19765 case EM_SPARC32PLUS:
19766 case EM_SPARCV9:
19767 switch (e_type)
19768 {
2b692964 19769 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 19770 return _("PT_GETREGS (reg structure)");
2b692964 19771 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 19772 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19773 default:
19774 break;
19775 }
19776 break;
19777
c0d38b0e
CZ
19778 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
19779 There's also old PT___GETREGS40 == mach + 1 for old reg
19780 structure which lacks GBR. */
19781 case EM_SH:
19782 switch (e_type)
19783 {
19784 case NT_NETBSDCORE_FIRSTMACH + 1:
19785 return _("PT___GETREGS40 (old reg structure)");
19786 case NT_NETBSDCORE_FIRSTMACH + 3:
19787 return _("PT_GETREGS (reg structure)");
19788 case NT_NETBSDCORE_FIRSTMACH + 5:
19789 return _("PT_GETFPREGS (fpreg structure)");
19790 default:
19791 break;
19792 }
19793 break;
19794
9437c45b
JT
19795 /* On all other arch's, PT_GETREGS == mach+1 and
19796 PT_GETFPREGS == mach+3. */
19797 default:
19798 switch (e_type)
19799 {
2b692964 19800 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 19801 return _("PT_GETREGS (reg structure)");
2b692964 19802 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 19803 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19804 default:
19805 break;
19806 }
19807 }
19808
9cf03b7e 19809 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 19810 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
19811 return buff;
19812}
19813
70616151
TT
19814static const char *
19815get_stapsdt_note_type (unsigned e_type)
19816{
19817 static char buff[64];
19818
19819 switch (e_type)
19820 {
19821 case NT_STAPSDT:
19822 return _("NT_STAPSDT (SystemTap probe descriptors)");
19823
19824 default:
19825 break;
19826 }
19827
19828 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19829 return buff;
19830}
19831
015dc7e1 19832static bool
c6a9fc58
TT
19833print_stapsdt_note (Elf_Internal_Note *pnote)
19834{
3ca60c57
NC
19835 size_t len, maxlen;
19836 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
19837 char *data = pnote->descdata;
19838 char *data_end = pnote->descdata + pnote->descsz;
19839 bfd_vma pc, base_addr, semaphore;
19840 char *provider, *probe, *arg_fmt;
19841
3ca60c57
NC
19842 if (pnote->descsz < (addr_size * 3))
19843 goto stapdt_note_too_small;
19844
c6a9fc58
TT
19845 pc = byte_get ((unsigned char *) data, addr_size);
19846 data += addr_size;
3ca60c57 19847
c6a9fc58
TT
19848 base_addr = byte_get ((unsigned char *) data, addr_size);
19849 data += addr_size;
3ca60c57 19850
c6a9fc58
TT
19851 semaphore = byte_get ((unsigned char *) data, addr_size);
19852 data += addr_size;
19853
3ca60c57
NC
19854 if (data >= data_end)
19855 goto stapdt_note_too_small;
19856 maxlen = data_end - data;
19857 len = strnlen (data, maxlen);
19858 if (len < maxlen)
19859 {
19860 provider = data;
19861 data += len + 1;
19862 }
19863 else
19864 goto stapdt_note_too_small;
19865
19866 if (data >= data_end)
19867 goto stapdt_note_too_small;
19868 maxlen = data_end - data;
19869 len = strnlen (data, maxlen);
19870 if (len < maxlen)
19871 {
19872 probe = data;
19873 data += len + 1;
19874 }
19875 else
19876 goto stapdt_note_too_small;
9abca702 19877
3ca60c57
NC
19878 if (data >= data_end)
19879 goto stapdt_note_too_small;
19880 maxlen = data_end - data;
19881 len = strnlen (data, maxlen);
19882 if (len < maxlen)
19883 {
19884 arg_fmt = data;
19885 data += len + 1;
19886 }
19887 else
19888 goto stapdt_note_too_small;
c6a9fc58
TT
19889
19890 printf (_(" Provider: %s\n"), provider);
19891 printf (_(" Name: %s\n"), probe);
19892 printf (_(" Location: "));
19893 print_vma (pc, FULL_HEX);
19894 printf (_(", Base: "));
19895 print_vma (base_addr, FULL_HEX);
19896 printf (_(", Semaphore: "));
19897 print_vma (semaphore, FULL_HEX);
9cf03b7e 19898 printf ("\n");
c6a9fc58
TT
19899 printf (_(" Arguments: %s\n"), arg_fmt);
19900
19901 return data == data_end;
3ca60c57
NC
19902
19903 stapdt_note_too_small:
19904 printf (_(" <corrupt - note is too small>\n"));
19905 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 19906 return false;
c6a9fc58
TT
19907}
19908
00e98fc7
TG
19909static const char *
19910get_ia64_vms_note_type (unsigned e_type)
19911{
19912 static char buff[64];
19913
19914 switch (e_type)
19915 {
19916 case NT_VMS_MHD:
19917 return _("NT_VMS_MHD (module header)");
19918 case NT_VMS_LNM:
19919 return _("NT_VMS_LNM (language name)");
19920 case NT_VMS_SRC:
19921 return _("NT_VMS_SRC (source files)");
19922 case NT_VMS_TITLE:
9cf03b7e 19923 return "NT_VMS_TITLE";
00e98fc7
TG
19924 case NT_VMS_EIDC:
19925 return _("NT_VMS_EIDC (consistency check)");
19926 case NT_VMS_FPMODE:
19927 return _("NT_VMS_FPMODE (FP mode)");
19928 case NT_VMS_LINKTIME:
9cf03b7e 19929 return "NT_VMS_LINKTIME";
00e98fc7
TG
19930 case NT_VMS_IMGNAM:
19931 return _("NT_VMS_IMGNAM (image name)");
19932 case NT_VMS_IMGID:
19933 return _("NT_VMS_IMGID (image id)");
19934 case NT_VMS_LINKID:
19935 return _("NT_VMS_LINKID (link id)");
19936 case NT_VMS_IMGBID:
19937 return _("NT_VMS_IMGBID (build id)");
19938 case NT_VMS_GSTNAM:
19939 return _("NT_VMS_GSTNAM (sym table name)");
19940 case NT_VMS_ORIG_DYN:
9cf03b7e 19941 return "NT_VMS_ORIG_DYN";
00e98fc7 19942 case NT_VMS_PATCHTIME:
9cf03b7e 19943 return "NT_VMS_PATCHTIME";
00e98fc7
TG
19944 default:
19945 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19946 return buff;
19947 }
19948}
19949
015dc7e1 19950static bool
00e98fc7
TG
19951print_ia64_vms_note (Elf_Internal_Note * pnote)
19952{
8d18bf79
NC
19953 int maxlen = pnote->descsz;
19954
19955 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
19956 goto desc_size_fail;
19957
00e98fc7
TG
19958 switch (pnote->type)
19959 {
19960 case NT_VMS_MHD:
8d18bf79
NC
19961 if (maxlen <= 36)
19962 goto desc_size_fail;
19963
19964 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
19965
19966 printf (_(" Creation date : %.17s\n"), pnote->descdata);
19967 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
19968 if (l + 34 < maxlen)
19969 {
19970 printf (_(" Module name : %s\n"), pnote->descdata + 34);
19971 if (l + 35 < maxlen)
19972 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
19973 else
19974 printf (_(" Module version : <missing>\n"));
19975 }
00e98fc7 19976 else
8d18bf79
NC
19977 {
19978 printf (_(" Module name : <missing>\n"));
19979 printf (_(" Module version : <missing>\n"));
19980 }
00e98fc7 19981 break;
8d18bf79 19982
00e98fc7 19983 case NT_VMS_LNM:
8d18bf79 19984 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19985 break;
8d18bf79 19986
00e98fc7
TG
19987#ifdef BFD64
19988 case NT_VMS_FPMODE:
9cf03b7e 19989 printf (_(" Floating Point mode: "));
8d18bf79
NC
19990 if (maxlen < 8)
19991 goto desc_size_fail;
19992 /* FIXME: Generate an error if descsz > 8 ? */
19993
4a5cb34f 19994 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 19995 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 19996 break;
8d18bf79 19997
00e98fc7
TG
19998 case NT_VMS_LINKTIME:
19999 printf (_(" Link time: "));
8d18bf79
NC
20000 if (maxlen < 8)
20001 goto desc_size_fail;
20002 /* FIXME: Generate an error if descsz > 8 ? */
20003
00e98fc7 20004 print_vms_time
8d18bf79 20005 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20006 printf ("\n");
20007 break;
8d18bf79 20008
00e98fc7
TG
20009 case NT_VMS_PATCHTIME:
20010 printf (_(" Patch time: "));
8d18bf79
NC
20011 if (maxlen < 8)
20012 goto desc_size_fail;
20013 /* FIXME: Generate an error if descsz > 8 ? */
20014
00e98fc7 20015 print_vms_time
8d18bf79 20016 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20017 printf ("\n");
20018 break;
8d18bf79 20019
00e98fc7 20020 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20021 if (maxlen < 34)
20022 goto desc_size_fail;
20023
00e98fc7
TG
20024 printf (_(" Major id: %u, minor id: %u\n"),
20025 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
20026 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 20027 printf (_(" Last modified : "));
00e98fc7
TG
20028 print_vms_time
20029 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 20030 printf (_("\n Link flags : "));
4a5cb34f 20031 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 20032 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 20033 printf (_(" Header flags: 0x%08x\n"),
948f632f 20034 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 20035 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
20036 break;
20037#endif
8d18bf79 20038
00e98fc7 20039 case NT_VMS_IMGNAM:
8d18bf79 20040 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20041 break;
8d18bf79 20042
00e98fc7 20043 case NT_VMS_GSTNAM:
8d18bf79 20044 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20045 break;
8d18bf79 20046
00e98fc7 20047 case NT_VMS_IMGID:
8d18bf79 20048 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20049 break;
8d18bf79 20050
00e98fc7 20051 case NT_VMS_LINKID:
8d18bf79 20052 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20053 break;
8d18bf79 20054
00e98fc7 20055 default:
015dc7e1 20056 return false;
00e98fc7 20057 }
8d18bf79 20058
015dc7e1 20059 return true;
8d18bf79
NC
20060
20061 desc_size_fail:
20062 printf (_(" <corrupt - data size is too small>\n"));
20063 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20064 return false;
00e98fc7
TG
20065}
20066
fd486f32
AM
20067struct build_attr_cache {
20068 Filedata *filedata;
20069 char *strtab;
20070 unsigned long strtablen;
20071 Elf_Internal_Sym *symtab;
20072 unsigned long nsyms;
20073} ba_cache;
20074
6f156d7a
NC
20075/* Find the symbol associated with a build attribute that is attached
20076 to address OFFSET. If PNAME is non-NULL then store the name of
20077 the symbol (if found) in the provided pointer, Returns NULL if a
20078 symbol could not be found. */
c799a79d 20079
6f156d7a 20080static Elf_Internal_Sym *
015dc7e1
AM
20081get_symbol_for_build_attribute (Filedata *filedata,
20082 unsigned long offset,
20083 bool is_open_attr,
20084 const char **pname)
9ef920e9 20085{
fd486f32
AM
20086 Elf_Internal_Sym *saved_sym = NULL;
20087 Elf_Internal_Sym *sym;
9ef920e9 20088
dda8d76d 20089 if (filedata->section_headers != NULL
fd486f32 20090 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20091 {
c799a79d 20092 Elf_Internal_Shdr * symsec;
9ef920e9 20093
fd486f32
AM
20094 free (ba_cache.strtab);
20095 ba_cache.strtab = NULL;
20096 free (ba_cache.symtab);
20097 ba_cache.symtab = NULL;
20098
c799a79d 20099 /* Load the symbol and string sections. */
dda8d76d
NC
20100 for (symsec = filedata->section_headers;
20101 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20102 symsec ++)
9ef920e9 20103 {
28d13567
AM
20104 if (symsec->sh_type == SHT_SYMTAB
20105 && get_symtab (filedata, symsec,
20106 &ba_cache.symtab, &ba_cache.nsyms,
20107 &ba_cache.strtab, &ba_cache.strtablen))
20108 break;
9ef920e9 20109 }
fd486f32 20110 ba_cache.filedata = filedata;
9ef920e9
NC
20111 }
20112
fd486f32 20113 if (ba_cache.symtab == NULL)
6f156d7a 20114 return NULL;
9ef920e9 20115
c799a79d 20116 /* Find a symbol whose value matches offset. */
fd486f32 20117 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20118 if (sym->st_value == offset)
20119 {
fd486f32 20120 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20121 /* Huh ? This should not happen. */
20122 continue;
9ef920e9 20123
fd486f32 20124 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20125 continue;
9ef920e9 20126
8fd75781
NC
20127 /* The AArch64 and ARM architectures define mapping symbols
20128 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20129 if (ba_cache.strtab[sym->st_name] == '$'
20130 && ba_cache.strtab[sym->st_name + 1] != 0
20131 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20132 continue;
20133
c799a79d
NC
20134 if (is_open_attr)
20135 {
20136 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20137 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20138 FUNC symbols entirely. */
20139 switch (ELF_ST_TYPE (sym->st_info))
20140 {
c799a79d 20141 case STT_OBJECT:
6f156d7a 20142 case STT_FILE:
c799a79d 20143 saved_sym = sym;
6f156d7a
NC
20144 if (sym->st_size)
20145 {
20146 /* If the symbol has a size associated
20147 with it then we can stop searching. */
fd486f32 20148 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20149 }
c799a79d 20150 continue;
9ef920e9 20151
c799a79d
NC
20152 case STT_FUNC:
20153 /* Ignore function symbols. */
20154 continue;
20155
20156 default:
20157 break;
20158 }
20159
20160 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20161 {
c799a79d
NC
20162 case STB_GLOBAL:
20163 if (saved_sym == NULL
20164 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20165 saved_sym = sym;
20166 break;
c871dade 20167
c799a79d
NC
20168 case STB_LOCAL:
20169 if (saved_sym == NULL)
20170 saved_sym = sym;
20171 break;
20172
20173 default:
9ef920e9
NC
20174 break;
20175 }
20176 }
c799a79d
NC
20177 else
20178 {
20179 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20180 continue;
20181
20182 saved_sym = sym;
20183 break;
20184 }
20185 }
20186
6f156d7a 20187 if (saved_sym && pname)
fd486f32 20188 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20189
20190 return saved_sym;
c799a79d
NC
20191}
20192
d20e98ab
NC
20193/* Returns true iff addr1 and addr2 are in the same section. */
20194
015dc7e1 20195static bool
d20e98ab
NC
20196same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20197{
20198 Elf_Internal_Shdr * a1;
20199 Elf_Internal_Shdr * a2;
20200
20201 a1 = find_section_by_address (filedata, addr1);
20202 a2 = find_section_by_address (filedata, addr2);
9abca702 20203
d20e98ab
NC
20204 return a1 == a2 && a1 != NULL;
20205}
20206
015dc7e1 20207static bool
dda8d76d
NC
20208print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20209 Filedata * filedata)
c799a79d 20210{
015dc7e1
AM
20211 static unsigned long global_offset = 0;
20212 static unsigned long global_end = 0;
20213 static unsigned long func_offset = 0;
20214 static unsigned long func_end = 0;
c871dade 20215
015dc7e1
AM
20216 Elf_Internal_Sym *sym;
20217 const char *name;
20218 unsigned long start;
20219 unsigned long end;
20220 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20221
20222 switch (pnote->descsz)
c799a79d 20223 {
6f156d7a
NC
20224 case 0:
20225 /* A zero-length description means that the range of
20226 the previous note of the same type should be used. */
c799a79d 20227 if (is_open_attr)
c871dade 20228 {
6f156d7a
NC
20229 if (global_end > global_offset)
20230 printf (_(" Applies to region from %#lx to %#lx\n"),
20231 global_offset, global_end);
20232 else
20233 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20234 }
20235 else
20236 {
6f156d7a
NC
20237 if (func_end > func_offset)
20238 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20239 else
20240 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20241 }
015dc7e1 20242 return true;
9ef920e9 20243
6f156d7a
NC
20244 case 4:
20245 start = byte_get ((unsigned char *) pnote->descdata, 4);
20246 end = 0;
20247 break;
20248
20249 case 8:
c74147bb
NC
20250 start = byte_get ((unsigned char *) pnote->descdata, 4);
20251 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20252 break;
20253
20254 case 16:
20255 start = byte_get ((unsigned char *) pnote->descdata, 8);
20256 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20257 break;
9abca702 20258
6f156d7a 20259 default:
c799a79d
NC
20260 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
20261 printf (_(" <invalid descsz>"));
015dc7e1 20262 return false;
c799a79d
NC
20263 }
20264
6f156d7a
NC
20265 name = NULL;
20266 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
20267 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
20268 in order to avoid them being confused with the start address of the
20269 first function in the file... */
20270 if (sym == NULL && is_open_attr)
20271 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
20272 & name);
6f156d7a
NC
20273
20274 if (end == 0 && sym != NULL && sym->st_size > 0)
20275 end = start + sym->st_size;
c799a79d
NC
20276
20277 if (is_open_attr)
20278 {
d20e98ab
NC
20279 /* FIXME: Need to properly allow for section alignment.
20280 16 is just the alignment used on x86_64. */
20281 if (global_end > 0
20282 && start > BFD_ALIGN (global_end, 16)
20283 /* Build notes are not guaranteed to be organised in order of
20284 increasing address, but we should find the all of the notes
20285 for one section in the same place. */
20286 && same_section (filedata, start, global_end))
6f156d7a
NC
20287 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
20288 global_end + 1, start - 1);
20289
20290 printf (_(" Applies to region from %#lx"), start);
20291 global_offset = start;
20292
20293 if (end)
20294 {
20295 printf (_(" to %#lx"), end);
20296 global_end = end;
20297 }
c799a79d
NC
20298 }
20299 else
20300 {
6f156d7a
NC
20301 printf (_(" Applies to region from %#lx"), start);
20302 func_offset = start;
20303
20304 if (end)
20305 {
20306 printf (_(" to %#lx"), end);
20307 func_end = end;
20308 }
c799a79d
NC
20309 }
20310
6f156d7a
NC
20311 if (sym && name)
20312 printf (_(" (%s)"), name);
20313
20314 printf ("\n");
015dc7e1 20315 return true;
9ef920e9
NC
20316}
20317
015dc7e1 20318static bool
9ef920e9
NC
20319print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
20320{
1d15e434
NC
20321 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
20322 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
20323 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
20324 char name_type;
20325 char name_attribute;
1d15e434 20326 const char * expected_types;
9ef920e9
NC
20327 const char * name = pnote->namedata;
20328 const char * text;
88305e1b 20329 signed int left;
9ef920e9
NC
20330
20331 if (name == NULL || pnote->namesz < 2)
20332 {
20333 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 20334 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20335 return false;
9ef920e9
NC
20336 }
20337
6f156d7a
NC
20338 if (do_wide)
20339 left = 28;
20340 else
20341 left = 20;
88305e1b
NC
20342
20343 /* Version 2 of the spec adds a "GA" prefix to the name field. */
20344 if (name[0] == 'G' && name[1] == 'A')
20345 {
6f156d7a
NC
20346 if (pnote->namesz < 4)
20347 {
20348 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
20349 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20350 return false;
6f156d7a
NC
20351 }
20352
88305e1b
NC
20353 printf ("GA");
20354 name += 2;
20355 left -= 2;
20356 }
20357
9ef920e9
NC
20358 switch ((name_type = * name))
20359 {
20360 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20361 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20362 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20363 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20364 printf ("%c", * name);
88305e1b 20365 left --;
9ef920e9
NC
20366 break;
20367 default:
20368 error (_("unrecognised attribute type in name field: %d\n"), name_type);
20369 print_symbol (-20, _("<unknown name type>"));
015dc7e1 20370 return false;
9ef920e9
NC
20371 }
20372
9ef920e9
NC
20373 ++ name;
20374 text = NULL;
20375
20376 switch ((name_attribute = * name))
20377 {
20378 case GNU_BUILD_ATTRIBUTE_VERSION:
20379 text = _("<version>");
1d15e434 20380 expected_types = string_expected;
9ef920e9
NC
20381 ++ name;
20382 break;
20383 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20384 text = _("<stack prot>");
75d7d298 20385 expected_types = "!+*";
9ef920e9
NC
20386 ++ name;
20387 break;
20388 case GNU_BUILD_ATTRIBUTE_RELRO:
20389 text = _("<relro>");
1d15e434 20390 expected_types = bool_expected;
9ef920e9
NC
20391 ++ name;
20392 break;
20393 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
20394 text = _("<stack size>");
1d15e434 20395 expected_types = number_expected;
9ef920e9
NC
20396 ++ name;
20397 break;
20398 case GNU_BUILD_ATTRIBUTE_TOOL:
20399 text = _("<tool>");
1d15e434 20400 expected_types = string_expected;
9ef920e9
NC
20401 ++ name;
20402 break;
20403 case GNU_BUILD_ATTRIBUTE_ABI:
20404 text = _("<ABI>");
20405 expected_types = "$*";
20406 ++ name;
20407 break;
20408 case GNU_BUILD_ATTRIBUTE_PIC:
20409 text = _("<PIC>");
1d15e434 20410 expected_types = number_expected;
9ef920e9
NC
20411 ++ name;
20412 break;
a8be5506
NC
20413 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
20414 text = _("<short enum>");
1d15e434 20415 expected_types = bool_expected;
a8be5506
NC
20416 ++ name;
20417 break;
9ef920e9
NC
20418 default:
20419 if (ISPRINT (* name))
20420 {
20421 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
20422
20423 if (len > left && ! do_wide)
20424 len = left;
75d7d298 20425 printf ("%.*s:", len, name);
9ef920e9 20426 left -= len;
0dd6ae21 20427 name += len;
9ef920e9
NC
20428 }
20429 else
20430 {
3e6b6445 20431 static char tmpbuf [128];
88305e1b 20432
3e6b6445
NC
20433 error (_("unrecognised byte in name field: %d\n"), * name);
20434 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
20435 text = tmpbuf;
20436 name ++;
9ef920e9
NC
20437 }
20438 expected_types = "*$!+";
20439 break;
20440 }
20441
20442 if (text)
88305e1b 20443 left -= printf ("%s", text);
9ef920e9
NC
20444
20445 if (strchr (expected_types, name_type) == NULL)
75d7d298 20446 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
20447
20448 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
20449 {
20450 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
20451 (unsigned long) pnote->namesz,
20452 (long) (name - pnote->namedata));
015dc7e1 20453 return false;
9ef920e9
NC
20454 }
20455
20456 if (left < 1 && ! do_wide)
015dc7e1 20457 return true;
9ef920e9
NC
20458
20459 switch (name_type)
20460 {
20461 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20462 {
b06b2c92 20463 unsigned int bytes;
ddef72cd
NC
20464 unsigned long long val = 0;
20465 unsigned int shift = 0;
20466 char * decoded = NULL;
20467
b06b2c92
NC
20468 bytes = pnote->namesz - (name - pnote->namedata);
20469 if (bytes > 0)
20470 /* The -1 is because the name field is always 0 terminated, and we
20471 want to be able to ensure that the shift in the while loop below
20472 will not overflow. */
20473 -- bytes;
20474
ddef72cd
NC
20475 if (bytes > sizeof (val))
20476 {
3e6b6445
NC
20477 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
20478 bytes);
20479 bytes = sizeof (val);
ddef72cd 20480 }
3e6b6445
NC
20481 /* We do not bother to warn if bytes == 0 as this can
20482 happen with some early versions of the gcc plugin. */
9ef920e9
NC
20483
20484 while (bytes --)
20485 {
54b8331d 20486 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
20487
20488 val |= byte << shift;
9ef920e9
NC
20489 shift += 8;
20490 }
20491
75d7d298 20492 switch (name_attribute)
9ef920e9 20493 {
75d7d298 20494 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
20495 switch (val)
20496 {
75d7d298
NC
20497 case 0: decoded = "static"; break;
20498 case 1: decoded = "pic"; break;
20499 case 2: decoded = "PIC"; break;
20500 case 3: decoded = "pie"; break;
20501 case 4: decoded = "PIE"; break;
20502 default: break;
9ef920e9 20503 }
75d7d298
NC
20504 break;
20505 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20506 switch (val)
9ef920e9 20507 {
75d7d298
NC
20508 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
20509 case 0: decoded = "off"; break;
20510 case 1: decoded = "on"; break;
20511 case 2: decoded = "all"; break;
20512 case 3: decoded = "strong"; break;
20513 case 4: decoded = "explicit"; break;
20514 default: break;
9ef920e9 20515 }
75d7d298
NC
20516 break;
20517 default:
20518 break;
9ef920e9
NC
20519 }
20520
75d7d298 20521 if (decoded != NULL)
3e6b6445
NC
20522 {
20523 print_symbol (-left, decoded);
20524 left = 0;
20525 }
20526 else if (val == 0)
20527 {
20528 printf ("0x0");
20529 left -= 3;
20530 }
9ef920e9 20531 else
75d7d298
NC
20532 {
20533 if (do_wide)
ddef72cd 20534 left -= printf ("0x%llx", val);
75d7d298 20535 else
ddef72cd 20536 left -= printf ("0x%-.*llx", left, val);
75d7d298 20537 }
9ef920e9
NC
20538 }
20539 break;
20540 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20541 left -= print_symbol (- left, name);
20542 break;
20543 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20544 left -= print_symbol (- left, "true");
20545 break;
20546 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20547 left -= print_symbol (- left, "false");
20548 break;
20549 }
20550
20551 if (do_wide && left > 0)
20552 printf ("%-*s", left, " ");
9abca702 20553
015dc7e1 20554 return true;
9ef920e9
NC
20555}
20556
6d118b09
NC
20557/* Note that by the ELF standard, the name field is already null byte
20558 terminated, and namesz includes the terminating null byte.
20559 I.E. the value of namesz for the name "FSF" is 4.
20560
e3c8793a 20561 If the value of namesz is zero, there is no name present. */
9ef920e9 20562
015dc7e1 20563static bool
9ef920e9 20564process_note (Elf_Internal_Note * pnote,
dda8d76d 20565 Filedata * filedata)
779fe533 20566{
2cf0635d
NC
20567 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
20568 const char * nt;
9437c45b
JT
20569
20570 if (pnote->namesz == 0)
1ec5cd37
NC
20571 /* If there is no note name, then use the default set of
20572 note type strings. */
dda8d76d 20573 nt = get_note_type (filedata, pnote->type);
1ec5cd37 20574
24d127aa 20575 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
20576 /* GNU-specific object file notes. */
20577 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 20578
24d127aa 20579 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 20580 /* FreeBSD-specific core file notes. */
dda8d76d 20581 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 20582
24d127aa 20583 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 20584 /* NetBSD-specific core file notes. */
dda8d76d 20585 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 20586
24d127aa 20587 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
20588 /* NetBSD-specific core file notes. */
20589 return process_netbsd_elf_note (pnote);
20590
24d127aa 20591 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
20592 /* NetBSD-specific core file notes. */
20593 return process_netbsd_elf_note (pnote);
20594
e9b095a5 20595 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
20596 {
20597 /* SPU-specific core file notes. */
20598 nt = pnote->namedata + 4;
20599 name = "SPU";
20600 }
20601
24d127aa 20602 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
20603 /* VMS/ia64-specific file notes. */
20604 nt = get_ia64_vms_note_type (pnote->type);
20605
24d127aa 20606 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
20607 nt = get_stapsdt_note_type (pnote->type);
20608
9437c45b 20609 else
1ec5cd37
NC
20610 /* Don't recognize this note name; just use the default set of
20611 note type strings. */
dda8d76d 20612 nt = get_note_type (filedata, pnote->type);
9437c45b 20613
1449284b 20614 printf (" ");
9ef920e9 20615
24d127aa 20616 if (((startswith (pnote->namedata, "GA")
483767a3
AM
20617 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20618 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20619 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20620 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
20621 print_gnu_build_attribute_name (pnote);
20622 else
20623 print_symbol (-20, name);
20624
20625 if (do_wide)
20626 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
20627 else
20628 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 20629
24d127aa 20630 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 20631 return print_ia64_vms_note (pnote);
24d127aa 20632 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 20633 return print_gnu_note (filedata, pnote);
24d127aa 20634 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 20635 return print_stapsdt_note (pnote);
24d127aa 20636 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 20637 return print_core_note (pnote);
24d127aa 20638 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
20639 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20640 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20641 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20642 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 20643 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 20644
9ef920e9 20645 if (pnote->descsz)
1449284b
NC
20646 {
20647 unsigned long i;
20648
20649 printf (_(" description data: "));
20650 for (i = 0; i < pnote->descsz; i++)
178d8719 20651 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
20652 if (!do_wide)
20653 printf ("\n");
1449284b
NC
20654 }
20655
9ef920e9
NC
20656 if (do_wide)
20657 printf ("\n");
20658
015dc7e1 20659 return true;
1449284b 20660}
6d118b09 20661
015dc7e1 20662static bool
dda8d76d
NC
20663process_notes_at (Filedata * filedata,
20664 Elf_Internal_Shdr * section,
20665 bfd_vma offset,
82ed9683
L
20666 bfd_vma length,
20667 bfd_vma align)
779fe533 20668{
015dc7e1
AM
20669 Elf_External_Note *pnotes;
20670 Elf_External_Note *external;
20671 char *end;
20672 bool res = true;
103f02d3 20673
779fe533 20674 if (length <= 0)
015dc7e1 20675 return false;
103f02d3 20676
1449284b
NC
20677 if (section)
20678 {
dda8d76d 20679 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 20680 if (pnotes)
32ec8896 20681 {
dda8d76d 20682 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
20683 {
20684 free (pnotes);
015dc7e1 20685 return false;
f761cb13 20686 }
32ec8896 20687 }
1449284b
NC
20688 }
20689 else
82ed9683 20690 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 20691 _("notes"));
4dff97b2 20692
dd24e3da 20693 if (pnotes == NULL)
015dc7e1 20694 return false;
779fe533 20695
103f02d3 20696 external = pnotes;
103f02d3 20697
ca0e11aa
NC
20698 if (filedata->is_separate)
20699 printf (_("In linked file '%s': "), filedata->file_name);
20700 else
20701 printf ("\n");
1449284b 20702 if (section)
ca0e11aa 20703 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 20704 else
ca0e11aa 20705 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
20706 (unsigned long) offset, (unsigned long) length);
20707
82ed9683
L
20708 /* NB: Some note sections may have alignment value of 0 or 1. gABI
20709 specifies that notes should be aligned to 4 bytes in 32-bit
20710 objects and to 8 bytes in 64-bit objects. As a Linux extension,
20711 we also support 4 byte alignment in 64-bit objects. If section
20712 alignment is less than 4, we treate alignment as 4 bytes. */
20713 if (align < 4)
20714 align = 4;
20715 else if (align != 4 && align != 8)
20716 {
20717 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
20718 (long) align);
a788aedd 20719 free (pnotes);
015dc7e1 20720 return false;
82ed9683
L
20721 }
20722
dbe15e4e 20723 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 20724
c8071705
NC
20725 end = (char *) pnotes + length;
20726 while ((char *) external < end)
779fe533 20727 {
b34976b6 20728 Elf_Internal_Note inote;
15b42fb0 20729 size_t min_notesz;
4dff97b2 20730 char * next;
2cf0635d 20731 char * temp = NULL;
c8071705 20732 size_t data_remaining = end - (char *) external;
6d118b09 20733
dda8d76d 20734 if (!is_ia64_vms (filedata))
15b42fb0 20735 {
9dd3a467
NC
20736 /* PR binutils/15191
20737 Make sure that there is enough data to read. */
15b42fb0
AM
20738 min_notesz = offsetof (Elf_External_Note, name);
20739 if (data_remaining < min_notesz)
9dd3a467 20740 {
d3a49aa8
AM
20741 warn (ngettext ("Corrupt note: only %ld byte remains, "
20742 "not enough for a full note\n",
20743 "Corrupt note: only %ld bytes remain, "
20744 "not enough for a full note\n",
20745 data_remaining),
20746 (long) data_remaining);
9dd3a467
NC
20747 break;
20748 }
5396a86e
AM
20749 data_remaining -= min_notesz;
20750
15b42fb0
AM
20751 inote.type = BYTE_GET (external->type);
20752 inote.namesz = BYTE_GET (external->namesz);
20753 inote.namedata = external->name;
20754 inote.descsz = BYTE_GET (external->descsz);
276da9b3 20755 inote.descdata = ((char *) external
4dff97b2 20756 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 20757 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 20758 next = ((char *) external
4dff97b2 20759 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 20760 }
00e98fc7 20761 else
15b42fb0
AM
20762 {
20763 Elf64_External_VMS_Note *vms_external;
00e98fc7 20764
9dd3a467
NC
20765 /* PR binutils/15191
20766 Make sure that there is enough data to read. */
15b42fb0
AM
20767 min_notesz = offsetof (Elf64_External_VMS_Note, name);
20768 if (data_remaining < min_notesz)
9dd3a467 20769 {
d3a49aa8
AM
20770 warn (ngettext ("Corrupt note: only %ld byte remains, "
20771 "not enough for a full note\n",
20772 "Corrupt note: only %ld bytes remain, "
20773 "not enough for a full note\n",
20774 data_remaining),
20775 (long) data_remaining);
9dd3a467
NC
20776 break;
20777 }
5396a86e 20778 data_remaining -= min_notesz;
3e55a963 20779
15b42fb0
AM
20780 vms_external = (Elf64_External_VMS_Note *) external;
20781 inote.type = BYTE_GET (vms_external->type);
20782 inote.namesz = BYTE_GET (vms_external->namesz);
20783 inote.namedata = vms_external->name;
20784 inote.descsz = BYTE_GET (vms_external->descsz);
20785 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
20786 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20787 next = inote.descdata + align_power (inote.descsz, 3);
20788 }
20789
5396a86e
AM
20790 /* PR 17531: file: 3443835e. */
20791 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
20792 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
20793 || (size_t) (inote.descdata - inote.namedata) > data_remaining
20794 || (size_t) (next - inote.descdata) < inote.descsz
20795 || ((size_t) (next - inote.descdata)
20796 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 20797 {
15b42fb0 20798 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 20799 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
20800 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
20801 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
20802 break;
20803 }
20804
15b42fb0 20805 external = (Elf_External_Note *) next;
dd24e3da 20806
6d118b09
NC
20807 /* Verify that name is null terminated. It appears that at least
20808 one version of Linux (RedHat 6.0) generates corefiles that don't
20809 comply with the ELF spec by failing to include the null byte in
20810 namesz. */
18344509 20811 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 20812 {
5396a86e 20813 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 20814 {
5396a86e
AM
20815 temp = (char *) malloc (inote.namesz + 1);
20816 if (temp == NULL)
20817 {
20818 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 20819 res = false;
5396a86e
AM
20820 break;
20821 }
76da6bbe 20822
5396a86e
AM
20823 memcpy (temp, inote.namedata, inote.namesz);
20824 inote.namedata = temp;
20825 }
20826 inote.namedata[inote.namesz] = 0;
6d118b09
NC
20827 }
20828
dda8d76d 20829 if (! process_note (& inote, filedata))
015dc7e1 20830 res = false;
103f02d3 20831
9db70fc3
AM
20832 free (temp);
20833 temp = NULL;
779fe533
NC
20834 }
20835
20836 free (pnotes);
103f02d3 20837
779fe533
NC
20838 return res;
20839}
20840
015dc7e1 20841static bool
dda8d76d 20842process_corefile_note_segments (Filedata * filedata)
779fe533 20843{
015dc7e1 20844 Elf_Internal_Phdr *segment;
b34976b6 20845 unsigned int i;
015dc7e1 20846 bool res = true;
103f02d3 20847
dda8d76d 20848 if (! get_program_headers (filedata))
015dc7e1 20849 return true;
103f02d3 20850
dda8d76d
NC
20851 for (i = 0, segment = filedata->program_headers;
20852 i < filedata->file_header.e_phnum;
b34976b6 20853 i++, segment++)
779fe533
NC
20854 {
20855 if (segment->p_type == PT_NOTE)
dda8d76d 20856 if (! process_notes_at (filedata, NULL,
32ec8896 20857 (bfd_vma) segment->p_offset,
82ed9683
L
20858 (bfd_vma) segment->p_filesz,
20859 (bfd_vma) segment->p_align))
015dc7e1 20860 res = false;
779fe533 20861 }
103f02d3 20862
779fe533
NC
20863 return res;
20864}
20865
015dc7e1 20866static bool
dda8d76d 20867process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
20868{
20869 Elf_External_Note * pnotes;
20870 Elf_External_Note * external;
c8071705 20871 char * end;
015dc7e1 20872 bool res = true;
685080f2
NC
20873
20874 if (length <= 0)
015dc7e1 20875 return false;
685080f2 20876
dda8d76d 20877 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
20878 _("v850 notes"));
20879 if (pnotes == NULL)
015dc7e1 20880 return false;
685080f2
NC
20881
20882 external = pnotes;
c8071705 20883 end = (char*) pnotes + length;
685080f2
NC
20884
20885 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
20886 (unsigned long) offset, (unsigned long) length);
20887
c8071705 20888 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
20889 {
20890 Elf_External_Note * next;
20891 Elf_Internal_Note inote;
20892
20893 inote.type = BYTE_GET (external->type);
20894 inote.namesz = BYTE_GET (external->namesz);
20895 inote.namedata = external->name;
20896 inote.descsz = BYTE_GET (external->descsz);
20897 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
20898 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20899
c8071705
NC
20900 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
20901 {
20902 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
20903 inote.descdata = inote.namedata;
20904 inote.namesz = 0;
20905 }
20906
685080f2
NC
20907 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
20908
c8071705 20909 if ( ((char *) next > end)
685080f2
NC
20910 || ((char *) next < (char *) pnotes))
20911 {
20912 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
20913 (unsigned long) ((char *) external - (char *) pnotes));
20914 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20915 inote.type, inote.namesz, inote.descsz);
20916 break;
20917 }
20918
20919 external = next;
20920
20921 /* Prevent out-of-bounds indexing. */
c8071705 20922 if ( inote.namedata + inote.namesz > end
685080f2
NC
20923 || inote.namedata + inote.namesz < inote.namedata)
20924 {
20925 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
20926 (unsigned long) ((char *) external - (char *) pnotes));
20927 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20928 inote.type, inote.namesz, inote.descsz);
20929 break;
20930 }
20931
20932 printf (" %s: ", get_v850_elf_note_type (inote.type));
20933
20934 if (! print_v850_note (& inote))
20935 {
015dc7e1 20936 res = false;
685080f2
NC
20937 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
20938 inote.namesz, inote.descsz);
20939 }
20940 }
20941
20942 free (pnotes);
20943
20944 return res;
20945}
20946
015dc7e1 20947static bool
dda8d76d 20948process_note_sections (Filedata * filedata)
1ec5cd37 20949{
015dc7e1 20950 Elf_Internal_Shdr *section;
1ec5cd37 20951 unsigned long i;
32ec8896 20952 unsigned int n = 0;
015dc7e1 20953 bool res = true;
1ec5cd37 20954
dda8d76d
NC
20955 for (i = 0, section = filedata->section_headers;
20956 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 20957 i++, section++)
685080f2
NC
20958 {
20959 if (section->sh_type == SHT_NOTE)
20960 {
dda8d76d 20961 if (! process_notes_at (filedata, section,
32ec8896 20962 (bfd_vma) section->sh_offset,
82ed9683
L
20963 (bfd_vma) section->sh_size,
20964 (bfd_vma) section->sh_addralign))
015dc7e1 20965 res = false;
685080f2
NC
20966 n++;
20967 }
20968
dda8d76d
NC
20969 if (( filedata->file_header.e_machine == EM_V800
20970 || filedata->file_header.e_machine == EM_V850
20971 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
20972 && section->sh_type == SHT_RENESAS_INFO)
20973 {
dda8d76d 20974 if (! process_v850_notes (filedata,
32ec8896
NC
20975 (bfd_vma) section->sh_offset,
20976 (bfd_vma) section->sh_size))
015dc7e1 20977 res = false;
685080f2
NC
20978 n++;
20979 }
20980 }
df565f32
NC
20981
20982 if (n == 0)
20983 /* Try processing NOTE segments instead. */
dda8d76d 20984 return process_corefile_note_segments (filedata);
1ec5cd37
NC
20985
20986 return res;
20987}
20988
015dc7e1 20989static bool
dda8d76d 20990process_notes (Filedata * filedata)
779fe533
NC
20991{
20992 /* If we have not been asked to display the notes then do nothing. */
20993 if (! do_notes)
015dc7e1 20994 return true;
103f02d3 20995
dda8d76d
NC
20996 if (filedata->file_header.e_type != ET_CORE)
20997 return process_note_sections (filedata);
103f02d3 20998
779fe533 20999 /* No program headers means no NOTE segment. */
dda8d76d
NC
21000 if (filedata->file_header.e_phnum > 0)
21001 return process_corefile_note_segments (filedata);
779fe533 21002
ca0e11aa
NC
21003 if (filedata->is_separate)
21004 printf (_("No notes found in linked file '%s'.\n"),
21005 filedata->file_name);
21006 else
21007 printf (_("No notes found file.\n"));
21008
015dc7e1 21009 return true;
779fe533
NC
21010}
21011
60abdbed
NC
21012static unsigned char *
21013display_public_gnu_attributes (unsigned char * start,
21014 const unsigned char * const end)
21015{
21016 printf (_(" Unknown GNU attribute: %s\n"), start);
21017
21018 start += strnlen ((char *) start, end - start);
21019 display_raw_attribute (start, end);
21020
21021 return (unsigned char *) end;
21022}
21023
21024static unsigned char *
21025display_generic_attribute (unsigned char * start,
21026 unsigned int tag,
21027 const unsigned char * const end)
21028{
21029 if (tag == 0)
21030 return (unsigned char *) end;
21031
21032 return display_tag_value (tag, start, end);
21033}
21034
015dc7e1 21035static bool
dda8d76d 21036process_arch_specific (Filedata * filedata)
252b5132 21037{
a952a375 21038 if (! do_arch)
015dc7e1 21039 return true;
a952a375 21040
dda8d76d 21041 switch (filedata->file_header.e_machine)
252b5132 21042 {
53a346d8
CZ
21043 case EM_ARC:
21044 case EM_ARC_COMPACT:
21045 case EM_ARC_COMPACT2:
dda8d76d 21046 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
21047 display_arc_attribute,
21048 display_generic_attribute);
11c1ff18 21049 case EM_ARM:
dda8d76d 21050 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
21051 display_arm_attribute,
21052 display_generic_attribute);
21053
252b5132 21054 case EM_MIPS:
4fe85591 21055 case EM_MIPS_RS3_LE:
dda8d76d 21056 return process_mips_specific (filedata);
60abdbed
NC
21057
21058 case EM_MSP430:
dda8d76d 21059 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21060 display_msp430_attribute,
c0ea7c52 21061 display_msp430_gnu_attribute);
60abdbed 21062
2dc8dd17
JW
21063 case EM_RISCV:
21064 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21065 display_riscv_attribute,
21066 display_generic_attribute);
21067
35c08157 21068 case EM_NDS32:
dda8d76d 21069 return process_nds32_specific (filedata);
60abdbed 21070
85f7484a
PB
21071 case EM_68K:
21072 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21073 display_m68k_gnu_attribute);
21074
34c8bcba 21075 case EM_PPC:
b82317dd 21076 case EM_PPC64:
dda8d76d 21077 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21078 display_power_gnu_attribute);
21079
643f7afb
AK
21080 case EM_S390:
21081 case EM_S390_OLD:
dda8d76d 21082 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21083 display_s390_gnu_attribute);
21084
9e8c70f9
DM
21085 case EM_SPARC:
21086 case EM_SPARC32PLUS:
21087 case EM_SPARCV9:
dda8d76d 21088 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21089 display_sparc_gnu_attribute);
21090
59e6276b 21091 case EM_TI_C6000:
dda8d76d 21092 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
21093 display_tic6x_attribute,
21094 display_generic_attribute);
21095
0861f561
CQ
21096 case EM_CSKY:
21097 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
21098 display_csky_attribute, NULL);
21099
252b5132 21100 default:
dda8d76d 21101 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
21102 display_public_gnu_attributes,
21103 display_generic_attribute);
252b5132 21104 }
252b5132
RH
21105}
21106
015dc7e1 21107static bool
dda8d76d 21108get_file_header (Filedata * filedata)
252b5132 21109{
9ea033b2 21110 /* Read in the identity array. */
dda8d76d 21111 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21112 return false;
252b5132 21113
9ea033b2 21114 /* Determine how to read the rest of the header. */
dda8d76d 21115 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 21116 {
1a0670f3
AM
21117 default:
21118 case ELFDATANONE:
adab8cdc
AO
21119 case ELFDATA2LSB:
21120 byte_get = byte_get_little_endian;
21121 byte_put = byte_put_little_endian;
21122 break;
21123 case ELFDATA2MSB:
21124 byte_get = byte_get_big_endian;
21125 byte_put = byte_put_big_endian;
21126 break;
9ea033b2
NC
21127 }
21128
21129 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 21130 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
21131
21132 /* Read in the rest of the header. */
21133 if (is_32bit_elf)
21134 {
21135 Elf32_External_Ehdr ehdr32;
252b5132 21136
dda8d76d 21137 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21138 return false;
103f02d3 21139
dda8d76d
NC
21140 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
21141 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
21142 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
21143 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
21144 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
21145 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
21146 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
21147 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
21148 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
21149 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
21150 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
21151 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
21152 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 21153 }
252b5132 21154 else
9ea033b2
NC
21155 {
21156 Elf64_External_Ehdr ehdr64;
a952a375
NC
21157
21158 /* If we have been compiled with sizeof (bfd_vma) == 4, then
21159 we will not be able to cope with the 64bit data found in
21160 64 ELF files. Detect this now and abort before we start
50c2245b 21161 overwriting things. */
a952a375
NC
21162 if (sizeof (bfd_vma) < 8)
21163 {
e3c8793a
NC
21164 error (_("This instance of readelf has been built without support for a\n\
2116564 bit data type and so it cannot read 64 bit ELF files.\n"));
015dc7e1 21166 return false;
a952a375 21167 }
103f02d3 21168
dda8d76d 21169 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21170 return false;
103f02d3 21171
dda8d76d
NC
21172 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
21173 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
21174 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
21175 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
21176 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
21177 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
21178 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
21179 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
21180 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
21181 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
21182 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
21183 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
21184 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 21185 }
252b5132 21186
015dc7e1 21187 return true;
252b5132
RH
21188}
21189
13acb58d
AM
21190static void
21191free_filedata (Filedata *filedata)
21192{
21193 free (filedata->program_interpreter);
21194 filedata->program_interpreter = NULL;
21195
21196 free (filedata->program_headers);
21197 filedata->program_headers = NULL;
21198
21199 free (filedata->section_headers);
21200 filedata->section_headers = NULL;
21201
21202 free (filedata->string_table);
21203 filedata->string_table = NULL;
21204 filedata->string_table_length = 0;
21205
21206 free (filedata->dump.dump_sects);
21207 filedata->dump.dump_sects = NULL;
21208 filedata->dump.num_dump_sects = 0;
21209
21210 free (filedata->dynamic_strings);
21211 filedata->dynamic_strings = NULL;
21212 filedata->dynamic_strings_length = 0;
21213
21214 free (filedata->dynamic_symbols);
21215 filedata->dynamic_symbols = NULL;
21216 filedata->num_dynamic_syms = 0;
21217
21218 free (filedata->dynamic_syminfo);
21219 filedata->dynamic_syminfo = NULL;
21220
21221 free (filedata->dynamic_section);
21222 filedata->dynamic_section = NULL;
21223
21224 while (filedata->symtab_shndx_list != NULL)
21225 {
21226 elf_section_list *next = filedata->symtab_shndx_list->next;
21227 free (filedata->symtab_shndx_list);
21228 filedata->symtab_shndx_list = next;
21229 }
21230
21231 free (filedata->section_headers_groups);
21232 filedata->section_headers_groups = NULL;
21233
21234 if (filedata->section_groups)
21235 {
21236 size_t i;
21237 struct group_list * g;
21238 struct group_list * next;
21239
21240 for (i = 0; i < filedata->group_count; i++)
21241 {
21242 for (g = filedata->section_groups [i].root; g != NULL; g = next)
21243 {
21244 next = g->next;
21245 free (g);
21246 }
21247 }
21248
21249 free (filedata->section_groups);
21250 filedata->section_groups = NULL;
21251 }
21252}
21253
dda8d76d
NC
21254static void
21255close_file (Filedata * filedata)
21256{
21257 if (filedata)
21258 {
21259 if (filedata->handle)
21260 fclose (filedata->handle);
21261 free (filedata);
21262 }
21263}
21264
21265void
21266close_debug_file (void * data)
21267{
13acb58d 21268 free_filedata ((Filedata *) data);
dda8d76d
NC
21269 close_file ((Filedata *) data);
21270}
21271
21272static Filedata *
015dc7e1 21273open_file (const char * pathname, bool is_separate)
dda8d76d
NC
21274{
21275 struct stat statbuf;
21276 Filedata * filedata = NULL;
21277
21278 if (stat (pathname, & statbuf) < 0
21279 || ! S_ISREG (statbuf.st_mode))
21280 goto fail;
21281
21282 filedata = calloc (1, sizeof * filedata);
21283 if (filedata == NULL)
21284 goto fail;
21285
21286 filedata->handle = fopen (pathname, "rb");
21287 if (filedata->handle == NULL)
21288 goto fail;
21289
21290 filedata->file_size = (bfd_size_type) statbuf.st_size;
21291 filedata->file_name = pathname;
ca0e11aa 21292 filedata->is_separate = is_separate;
dda8d76d
NC
21293
21294 if (! get_file_header (filedata))
21295 goto fail;
21296
4de91c10
AM
21297 if (!get_section_headers (filedata, false))
21298 goto fail;
dda8d76d
NC
21299
21300 return filedata;
21301
21302 fail:
21303 if (filedata)
21304 {
21305 if (filedata->handle)
21306 fclose (filedata->handle);
21307 free (filedata);
21308 }
21309 return NULL;
21310}
21311
21312void *
21313open_debug_file (const char * pathname)
21314{
015dc7e1 21315 return open_file (pathname, true);
dda8d76d
NC
21316}
21317
835f2fae
NC
21318static void
21319initialise_dump_sects (Filedata * filedata)
21320{
21321 /* Initialise the dump_sects array from the cmdline_dump_sects array.
21322 Note we do this even if cmdline_dump_sects is empty because we
21323 must make sure that the dump_sets array is zeroed out before each
21324 object file is processed. */
21325 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
21326 memset (filedata->dump.dump_sects, 0,
21327 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21328
21329 if (cmdline.num_dump_sects > 0)
21330 {
21331 if (filedata->dump.num_dump_sects == 0)
21332 /* A sneaky way of allocating the dump_sects array. */
21333 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
21334
21335 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
21336 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
21337 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21338 }
21339}
21340
fb52b2f4
NC
21341/* Process one ELF object file according to the command line options.
21342 This file may actually be stored in an archive. The file is
32ec8896
NC
21343 positioned at the start of the ELF object. Returns TRUE if no
21344 problems were encountered, FALSE otherwise. */
fb52b2f4 21345
015dc7e1 21346static bool
dda8d76d 21347process_object (Filedata * filedata)
252b5132 21348{
015dc7e1 21349 bool have_separate_files;
252b5132 21350 unsigned int i;
015dc7e1 21351 bool res;
252b5132 21352
dda8d76d 21353 if (! get_file_header (filedata))
252b5132 21354 {
dda8d76d 21355 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 21356 return false;
252b5132
RH
21357 }
21358
21359 /* Initialise per file variables. */
978c4450
AM
21360 for (i = ARRAY_SIZE (filedata->version_info); i--;)
21361 filedata->version_info[i] = 0;
252b5132 21362
978c4450
AM
21363 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
21364 filedata->dynamic_info[i] = 0;
21365 filedata->dynamic_info_DT_GNU_HASH = 0;
21366 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
21367
21368 /* Process the file. */
21369 if (show_name)
dda8d76d 21370 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 21371
835f2fae 21372 initialise_dump_sects (filedata);
d70c5fc7 21373
4de91c10
AM
21374 /* There may be some extensions in the first section header. Don't
21375 bomb if we can't read it. */
21376 get_section_headers (filedata, true);
21377
dda8d76d 21378 if (! process_file_header (filedata))
4de91c10
AM
21379 {
21380 res = false;
21381 goto out;
21382 }
252b5132 21383
dda8d76d 21384 if (! process_section_headers (filedata))
2f62977e 21385 {
32ec8896 21386 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 21387 do_unwind = do_version = do_dump = do_arch = false;
252b5132 21388
2f62977e 21389 if (! do_using_dynamic)
015dc7e1 21390 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 21391 }
252b5132 21392
dda8d76d 21393 if (! process_section_groups (filedata))
32ec8896 21394 /* Without loaded section groups we cannot process unwind. */
015dc7e1 21395 do_unwind = false;
d1f5c6e3 21396
2482f306
AM
21397 res = process_program_headers (filedata);
21398 if (res)
21399 res = process_dynamic_section (filedata);
252b5132 21400
dda8d76d 21401 if (! process_relocs (filedata))
015dc7e1 21402 res = false;
252b5132 21403
dda8d76d 21404 if (! process_unwind (filedata))
015dc7e1 21405 res = false;
4d6ed7c8 21406
dda8d76d 21407 if (! process_symbol_table (filedata))
015dc7e1 21408 res = false;
252b5132 21409
0f03783c 21410 if (! process_lto_symbol_tables (filedata))
015dc7e1 21411 res = false;
b9e920ec 21412
dda8d76d 21413 if (! process_syminfo (filedata))
015dc7e1 21414 res = false;
252b5132 21415
dda8d76d 21416 if (! process_version_sections (filedata))
015dc7e1 21417 res = false;
252b5132 21418
82ed9683 21419 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 21420 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 21421 else
015dc7e1 21422 have_separate_files = false;
dda8d76d
NC
21423
21424 if (! process_section_contents (filedata))
015dc7e1 21425 res = false;
f5842774 21426
24841daa 21427 if (have_separate_files)
dda8d76d 21428 {
24841daa
NC
21429 separate_info * d;
21430
21431 for (d = first_separate_info; d != NULL; d = d->next)
21432 {
835f2fae
NC
21433 initialise_dump_sects (d->handle);
21434
ca0e11aa 21435 if (process_links && ! process_file_header (d->handle))
015dc7e1 21436 res = false;
ca0e11aa 21437 else if (! process_section_headers (d->handle))
015dc7e1 21438 res = false;
d6bfbc39 21439 else if (! process_section_contents (d->handle))
015dc7e1 21440 res = false;
ca0e11aa
NC
21441 else if (process_links)
21442 {
ca0e11aa 21443 if (! process_section_groups (d->handle))
015dc7e1 21444 res = false;
ca0e11aa 21445 if (! process_program_headers (d->handle))
015dc7e1 21446 res = false;
ca0e11aa 21447 if (! process_dynamic_section (d->handle))
015dc7e1 21448 res = false;
ca0e11aa 21449 if (! process_relocs (d->handle))
015dc7e1 21450 res = false;
ca0e11aa 21451 if (! process_unwind (d->handle))
015dc7e1 21452 res = false;
ca0e11aa 21453 if (! process_symbol_table (d->handle))
015dc7e1 21454 res = false;
ca0e11aa 21455 if (! process_lto_symbol_tables (d->handle))
015dc7e1 21456 res = false;
ca0e11aa 21457 if (! process_syminfo (d->handle))
015dc7e1 21458 res = false;
ca0e11aa 21459 if (! process_version_sections (d->handle))
015dc7e1 21460 res = false;
ca0e11aa 21461 if (! process_notes (d->handle))
015dc7e1 21462 res = false;
ca0e11aa 21463 }
24841daa
NC
21464 }
21465
21466 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
21467 }
21468
21469 if (! process_notes (filedata))
015dc7e1 21470 res = false;
103f02d3 21471
dda8d76d 21472 if (! process_gnu_liblist (filedata))
015dc7e1 21473 res = false;
047b2264 21474
dda8d76d 21475 if (! process_arch_specific (filedata))
015dc7e1 21476 res = false;
252b5132 21477
4de91c10 21478 out:
13acb58d 21479 free_filedata (filedata);
e4b17d5c 21480
19e6b90e 21481 free_debug_memory ();
18bd398b 21482
32ec8896 21483 return res;
252b5132
RH
21484}
21485
2cf0635d 21486/* Process an ELF archive.
32ec8896
NC
21487 On entry the file is positioned just after the ARMAG string.
21488 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 21489
015dc7e1
AM
21490static bool
21491process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
21492{
21493 struct archive_info arch;
21494 struct archive_info nested_arch;
21495 size_t got;
015dc7e1 21496 bool ret = true;
2cf0635d 21497
015dc7e1 21498 show_name = true;
2cf0635d
NC
21499
21500 /* The ARCH structure is used to hold information about this archive. */
21501 arch.file_name = NULL;
21502 arch.file = NULL;
21503 arch.index_array = NULL;
21504 arch.sym_table = NULL;
21505 arch.longnames = NULL;
21506
21507 /* The NESTED_ARCH structure is used as a single-item cache of information
21508 about a nested archive (when members of a thin archive reside within
21509 another regular archive file). */
21510 nested_arch.file_name = NULL;
21511 nested_arch.file = NULL;
21512 nested_arch.index_array = NULL;
21513 nested_arch.sym_table = NULL;
21514 nested_arch.longnames = NULL;
21515
dda8d76d 21516 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
21517 filedata->file_size, is_thin_archive,
21518 do_archive_index) != 0)
2cf0635d 21519 {
015dc7e1 21520 ret = false;
2cf0635d 21521 goto out;
4145f1d5 21522 }
fb52b2f4 21523
4145f1d5
NC
21524 if (do_archive_index)
21525 {
2cf0635d 21526 if (arch.sym_table == NULL)
1cb7d8b1
AM
21527 error (_("%s: unable to dump the index as none was found\n"),
21528 filedata->file_name);
4145f1d5
NC
21529 else
21530 {
591f7597 21531 unsigned long i, l;
4145f1d5
NC
21532 unsigned long current_pos;
21533
1cb7d8b1
AM
21534 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
21535 "in the symbol table)\n"),
21536 filedata->file_name, (unsigned long) arch.index_num,
21537 arch.sym_size);
dda8d76d
NC
21538
21539 current_pos = ftell (filedata->handle);
4145f1d5 21540
2cf0635d 21541 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 21542 {
1cb7d8b1
AM
21543 if (i == 0
21544 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
21545 {
21546 char * member_name
21547 = get_archive_member_name_at (&arch, arch.index_array[i],
21548 &nested_arch);
2cf0635d 21549
1cb7d8b1
AM
21550 if (member_name != NULL)
21551 {
21552 char * qualified_name
21553 = make_qualified_name (&arch, &nested_arch,
21554 member_name);
2cf0635d 21555
1cb7d8b1
AM
21556 if (qualified_name != NULL)
21557 {
21558 printf (_("Contents of binary %s at offset "),
21559 qualified_name);
c2a7d3f5
NC
21560 (void) print_vma (arch.index_array[i], PREFIX_HEX);
21561 putchar ('\n');
1cb7d8b1
AM
21562 free (qualified_name);
21563 }
fd486f32 21564 free (member_name);
4145f1d5
NC
21565 }
21566 }
2cf0635d
NC
21567
21568 if (l >= arch.sym_size)
4145f1d5 21569 {
1cb7d8b1
AM
21570 error (_("%s: end of the symbol table reached "
21571 "before the end of the index\n"),
dda8d76d 21572 filedata->file_name);
015dc7e1 21573 ret = false;
cb8f3167 21574 break;
4145f1d5 21575 }
591f7597 21576 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
21577 printf ("\t%.*s\n",
21578 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 21579 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
21580 }
21581
67ce483b 21582 if (arch.uses_64bit_indices)
c2a7d3f5
NC
21583 l = (l + 7) & ~ 7;
21584 else
21585 l += l & 1;
21586
2cf0635d 21587 if (l < arch.sym_size)
32ec8896 21588 {
d3a49aa8
AM
21589 error (ngettext ("%s: %ld byte remains in the symbol table, "
21590 "but without corresponding entries in "
21591 "the index table\n",
21592 "%s: %ld bytes remain in the symbol table, "
21593 "but without corresponding entries in "
21594 "the index table\n",
21595 arch.sym_size - l),
dda8d76d 21596 filedata->file_name, arch.sym_size - l);
015dc7e1 21597 ret = false;
32ec8896 21598 }
4145f1d5 21599
dda8d76d 21600 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 21601 {
1cb7d8b1
AM
21602 error (_("%s: failed to seek back to start of object files "
21603 "in the archive\n"),
dda8d76d 21604 filedata->file_name);
015dc7e1 21605 ret = false;
2cf0635d 21606 goto out;
4145f1d5 21607 }
fb52b2f4 21608 }
4145f1d5
NC
21609
21610 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
21611 && !do_segments && !do_header && !do_dump && !do_version
21612 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 21613 && !do_section_groups && !do_dyn_syms)
2cf0635d 21614 {
015dc7e1 21615 ret = true; /* Archive index only. */
2cf0635d
NC
21616 goto out;
21617 }
fb52b2f4
NC
21618 }
21619
fb52b2f4
NC
21620 while (1)
21621 {
2cf0635d
NC
21622 char * name;
21623 size_t namelen;
21624 char * qualified_name;
21625
21626 /* Read the next archive header. */
dda8d76d 21627 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
21628 {
21629 error (_("%s: failed to seek to next archive header\n"),
21630 arch.file_name);
015dc7e1 21631 ret = false;
1cb7d8b1
AM
21632 break;
21633 }
dda8d76d 21634 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 21635 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
21636 {
21637 if (got == 0)
2cf0635d 21638 break;
28e817cc
NC
21639 /* PR 24049 - we cannot use filedata->file_name as this will
21640 have already been freed. */
21641 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 21642
015dc7e1 21643 ret = false;
1cb7d8b1
AM
21644 break;
21645 }
2cf0635d 21646 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
21647 {
21648 error (_("%s: did not find a valid archive header\n"),
21649 arch.file_name);
015dc7e1 21650 ret = false;
1cb7d8b1
AM
21651 break;
21652 }
2cf0635d
NC
21653
21654 arch.next_arhdr_offset += sizeof arch.arhdr;
21655
978c4450
AM
21656 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
21657 if (filedata->archive_file_size & 01)
21658 ++filedata->archive_file_size;
2cf0635d
NC
21659
21660 name = get_archive_member_name (&arch, &nested_arch);
21661 if (name == NULL)
fb52b2f4 21662 {
28e817cc 21663 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 21664 ret = false;
d989285c 21665 break;
fb52b2f4 21666 }
2cf0635d 21667 namelen = strlen (name);
fb52b2f4 21668
2cf0635d
NC
21669 qualified_name = make_qualified_name (&arch, &nested_arch, name);
21670 if (qualified_name == NULL)
fb52b2f4 21671 {
28e817cc 21672 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 21673 free (name);
015dc7e1 21674 ret = false;
d989285c 21675 break;
fb52b2f4
NC
21676 }
21677
2cf0635d 21678 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
21679 {
21680 /* This is a proxy for an external member of a thin archive. */
21681 Filedata * member_filedata;
21682 char * member_file_name = adjust_relative_path
dda8d76d 21683 (filedata->file_name, name, namelen);
32ec8896 21684
fd486f32 21685 free (name);
1cb7d8b1
AM
21686 if (member_file_name == NULL)
21687 {
fd486f32 21688 free (qualified_name);
015dc7e1 21689 ret = false;
1cb7d8b1
AM
21690 break;
21691 }
2cf0635d 21692
015dc7e1 21693 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
21694 if (member_filedata == NULL)
21695 {
21696 error (_("Input file '%s' is not readable.\n"), member_file_name);
21697 free (member_file_name);
fd486f32 21698 free (qualified_name);
015dc7e1 21699 ret = false;
1cb7d8b1
AM
21700 break;
21701 }
2cf0635d 21702
978c4450 21703 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 21704 member_filedata->file_name = qualified_name;
2cf0635d 21705
1cb7d8b1 21706 if (! process_object (member_filedata))
015dc7e1 21707 ret = false;
2cf0635d 21708
1cb7d8b1
AM
21709 close_file (member_filedata);
21710 free (member_file_name);
1cb7d8b1 21711 }
2cf0635d 21712 else if (is_thin_archive)
1cb7d8b1
AM
21713 {
21714 Filedata thin_filedata;
eb02c04d 21715
1cb7d8b1 21716 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 21717
a043396b
NC
21718 /* PR 15140: Allow for corrupt thin archives. */
21719 if (nested_arch.file == NULL)
21720 {
21721 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 21722 qualified_name, name);
fd486f32
AM
21723 free (qualified_name);
21724 free (name);
015dc7e1 21725 ret = false;
a043396b
NC
21726 break;
21727 }
fd486f32 21728 free (name);
a043396b 21729
1cb7d8b1 21730 /* This is a proxy for a member of a nested archive. */
978c4450
AM
21731 filedata->archive_file_offset
21732 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 21733
1cb7d8b1
AM
21734 /* The nested archive file will have been opened and setup by
21735 get_archive_member_name. */
978c4450
AM
21736 if (fseek (nested_arch.file, filedata->archive_file_offset,
21737 SEEK_SET) != 0)
1cb7d8b1
AM
21738 {
21739 error (_("%s: failed to seek to archive member.\n"),
21740 nested_arch.file_name);
fd486f32 21741 free (qualified_name);
015dc7e1 21742 ret = false;
1cb7d8b1
AM
21743 break;
21744 }
2cf0635d 21745
dda8d76d
NC
21746 thin_filedata.handle = nested_arch.file;
21747 thin_filedata.file_name = qualified_name;
9abca702 21748
1cb7d8b1 21749 if (! process_object (& thin_filedata))
015dc7e1 21750 ret = false;
1cb7d8b1 21751 }
2cf0635d 21752 else
1cb7d8b1 21753 {
fd486f32 21754 free (name);
978c4450 21755 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 21756 filedata->file_name = qualified_name;
1cb7d8b1 21757 if (! process_object (filedata))
015dc7e1 21758 ret = false;
978c4450 21759 arch.next_arhdr_offset += filedata->archive_file_size;
4c836627 21760 /* Stop looping with "negative" archive_file_size. */
978c4450 21761 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 21762 arch.next_arhdr_offset = -1ul;
1cb7d8b1 21763 }
fb52b2f4 21764
2cf0635d 21765 free (qualified_name);
fb52b2f4
NC
21766 }
21767
4145f1d5 21768 out:
2cf0635d
NC
21769 if (nested_arch.file != NULL)
21770 fclose (nested_arch.file);
21771 release_archive (&nested_arch);
21772 release_archive (&arch);
fb52b2f4 21773
d989285c 21774 return ret;
fb52b2f4
NC
21775}
21776
015dc7e1 21777static bool
2cf0635d 21778process_file (char * file_name)
fb52b2f4 21779{
dda8d76d 21780 Filedata * filedata = NULL;
fb52b2f4
NC
21781 struct stat statbuf;
21782 char armag[SARMAG];
015dc7e1 21783 bool ret = true;
fb52b2f4
NC
21784
21785 if (stat (file_name, &statbuf) < 0)
21786 {
f24ddbdd
NC
21787 if (errno == ENOENT)
21788 error (_("'%s': No such file\n"), file_name);
21789 else
21790 error (_("Could not locate '%s'. System error message: %s\n"),
21791 file_name, strerror (errno));
015dc7e1 21792 return false;
f24ddbdd
NC
21793 }
21794
21795 if (! S_ISREG (statbuf.st_mode))
21796 {
21797 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 21798 return false;
fb52b2f4
NC
21799 }
21800
dda8d76d
NC
21801 filedata = calloc (1, sizeof * filedata);
21802 if (filedata == NULL)
21803 {
21804 error (_("Out of memory allocating file data structure\n"));
015dc7e1 21805 return false;
dda8d76d
NC
21806 }
21807
21808 filedata->file_name = file_name;
21809 filedata->handle = fopen (file_name, "rb");
21810 if (filedata->handle == NULL)
fb52b2f4 21811 {
f24ddbdd 21812 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 21813 free (filedata);
015dc7e1 21814 return false;
fb52b2f4
NC
21815 }
21816
dda8d76d 21817 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 21818 {
4145f1d5 21819 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
21820 fclose (filedata->handle);
21821 free (filedata);
015dc7e1 21822 return false;
fb52b2f4
NC
21823 }
21824
dda8d76d 21825 filedata->file_size = (bfd_size_type) statbuf.st_size;
015dc7e1 21826 filedata->is_separate = false;
f54498b4 21827
fb52b2f4 21828 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 21829 {
015dc7e1
AM
21830 if (! process_archive (filedata, false))
21831 ret = false;
32ec8896 21832 }
2cf0635d 21833 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 21834 {
015dc7e1
AM
21835 if ( ! process_archive (filedata, true))
21836 ret = false;
32ec8896 21837 }
fb52b2f4
NC
21838 else
21839 {
1b513401 21840 if (do_archive_index && !check_all)
4145f1d5
NC
21841 error (_("File %s is not an archive so its index cannot be displayed.\n"),
21842 file_name);
21843
dda8d76d 21844 rewind (filedata->handle);
978c4450 21845 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 21846
dda8d76d 21847 if (! process_object (filedata))
015dc7e1 21848 ret = false;
fb52b2f4
NC
21849 }
21850
dda8d76d 21851 fclose (filedata->handle);
8fb879cd
AM
21852 free (filedata->section_headers);
21853 free (filedata->program_headers);
21854 free (filedata->string_table);
6431e409 21855 free (filedata->dump.dump_sects);
dda8d76d 21856 free (filedata);
32ec8896 21857
fd486f32 21858 free (ba_cache.strtab);
1bd6175a 21859 ba_cache.strtab = NULL;
fd486f32 21860 free (ba_cache.symtab);
1bd6175a 21861 ba_cache.symtab = NULL;
fd486f32
AM
21862 ba_cache.filedata = NULL;
21863
fb52b2f4
NC
21864 return ret;
21865}
21866
252b5132
RH
21867#ifdef SUPPORT_DISASSEMBLY
21868/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 21869 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 21870 symbols. */
252b5132
RH
21871
21872void
2cf0635d 21873print_address (unsigned int addr, FILE * outfile)
252b5132
RH
21874{
21875 fprintf (outfile,"0x%8.8x", addr);
21876}
21877
e3c8793a 21878/* Needed by the i386 disassembler. */
dda8d76d 21879
252b5132
RH
21880void
21881db_task_printsym (unsigned int addr)
21882{
21883 print_address (addr, stderr);
21884}
21885#endif
21886
21887int
2cf0635d 21888main (int argc, char ** argv)
252b5132 21889{
ff78d6d6
L
21890 int err;
21891
87b9f255 21892#ifdef HAVE_LC_MESSAGES
252b5132 21893 setlocale (LC_MESSAGES, "");
3882b010 21894#endif
3882b010 21895 setlocale (LC_CTYPE, "");
252b5132
RH
21896 bindtextdomain (PACKAGE, LOCALEDIR);
21897 textdomain (PACKAGE);
21898
869b9d07
MM
21899 expandargv (&argc, &argv);
21900
dda8d76d 21901 parse_args (& cmdline, argc, argv);
59f14fc0 21902
18bd398b 21903 if (optind < (argc - 1))
1b513401
NC
21904 /* When displaying information for more than one file,
21905 prefix the information with the file name. */
015dc7e1 21906 show_name = true;
5656ba2c
L
21907 else if (optind >= argc)
21908 {
1b513401 21909 /* Ensure that the warning is always displayed. */
015dc7e1 21910 do_checks = true;
1b513401 21911
5656ba2c
L
21912 warn (_("Nothing to do.\n"));
21913 usage (stderr);
21914 }
18bd398b 21915
015dc7e1 21916 err = false;
252b5132 21917 while (optind < argc)
32ec8896 21918 if (! process_file (argv[optind++]))
015dc7e1 21919 err = true;
252b5132 21920
9db70fc3 21921 free (cmdline.dump_sects);
252b5132 21922
7d9813f1
NA
21923 free (dump_ctf_symtab_name);
21924 free (dump_ctf_strtab_name);
21925 free (dump_ctf_parent_name);
21926
32ec8896 21927 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 21928}
This page took 4.326426 seconds and 4 git commands to generate.