Automatic date update in version.in
[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;
066f8fbe
AM
266 unsigned long archive_file_offset;
267 unsigned long archive_file_size;
268 /* Everything below this point is cleared out by free_filedata. */
978c4450
AM
269 Elf_Internal_Shdr * section_headers;
270 Elf_Internal_Phdr * program_headers;
271 char * string_table;
272 unsigned long string_table_length;
978c4450
AM
273 unsigned long dynamic_addr;
274 bfd_size_type dynamic_size;
275 size_t dynamic_nent;
276 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 277 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450
AM
278 char * dynamic_strings;
279 unsigned long dynamic_strings_length;
8ac10c5b 280 Elf_Internal_Shdr * dynamic_symtab_section;
978c4450
AM
281 unsigned long num_dynamic_syms;
282 Elf_Internal_Sym * dynamic_symbols;
283 bfd_vma version_info[16];
284 unsigned int dynamic_syminfo_nent;
285 Elf_Internal_Syminfo * dynamic_syminfo;
286 unsigned long dynamic_syminfo_offset;
287 bfd_size_type nbuckets;
288 bfd_size_type nchains;
289 bfd_vma * buckets;
290 bfd_vma * chains;
291 bfd_size_type ngnubuckets;
292 bfd_size_type ngnuchains;
293 bfd_vma * gnubuckets;
294 bfd_vma * gnuchains;
295 bfd_vma * mipsxlat;
296 bfd_vma gnusymidx;
13acb58d 297 char * program_interpreter;
978c4450
AM
298 bfd_vma dynamic_info[DT_ENCODING];
299 bfd_vma dynamic_info_DT_GNU_HASH;
300 bfd_vma dynamic_info_DT_MIPS_XHASH;
301 elf_section_list * symtab_shndx_list;
302 size_t group_count;
303 struct group * section_groups;
304 struct group ** section_headers_groups;
305 /* A dynamic array of flags indicating for which sections a dump of
306 some kind has been requested. It is reset on a per-object file
307 basis and then initialised from the cmdline_dump_sects array,
308 the results of interpreting the -w switch, and the
309 dump_sects_byname list. */
310 struct dump_data dump;
311} Filedata;
aef1f6d0 312
c256ffe7 313/* How to print a vma value. */
843dd992
NC
314typedef enum print_mode
315{
316 HEX,
047c3dbf 317 HEX_5,
843dd992
NC
318 DEC,
319 DEC_5,
320 UNSIGNED,
047c3dbf 321 UNSIGNED_5,
843dd992 322 PREFIX_HEX,
047c3dbf 323 PREFIX_HEX_5,
843dd992 324 FULL_HEX,
047c3dbf
NL
325 LONG_HEX,
326 OCTAL,
327 OCTAL_5
843dd992
NC
328}
329print_mode;
330
bb4d2ac2
L
331/* Versioned symbol info. */
332enum versioned_symbol_info
333{
334 symbol_undefined,
335 symbol_hidden,
336 symbol_public
337};
338
32ec8896 339static const char * get_symbol_version_string
015dc7e1 340 (Filedata *, bool, const char *, unsigned long, unsigned,
32ec8896 341 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 342
9c19a809
NC
343#define UNKNOWN -1
344
b9e920ec
AM
345#define SECTION_NAME(X) \
346 (filedata->string_table + (X)->sh_name)
347
348#define SECTION_NAME_VALID(X) \
349 ((X) != NULL \
350 && filedata->string_table != NULL \
351 && (X)->sh_name < filedata->string_table_length)
352
353#define SECTION_NAME_PRINT(X) \
354 ((X) == NULL ? _("<none>") \
355 : filedata->string_table == NULL ? _("<no-strings>") \
356 : (X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
357 : filedata->string_table + (X)->sh_name)
252b5132 358
ee42cf8c 359#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 360
10ca4b04
L
361#define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
362 (strtab != NULL && offset < strtab_size)
978c4450
AM
363#define VALID_DYNAMIC_NAME(filedata, offset) \
364 VALID_SYMBOL_NAME (filedata->dynamic_strings, \
365 filedata->dynamic_strings_length, offset)
d79b3d50
NC
366/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
367 already been called and verified that the string exists. */
978c4450
AM
368#define GET_DYNAMIC_NAME(filedata, offset) \
369 (filedata->dynamic_strings + offset)
18bd398b 370
61865e30
NC
371#define REMOVE_ARCH_BITS(ADDR) \
372 do \
373 { \
dda8d76d 374 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
375 (ADDR) &= ~1; \
376 } \
377 while (0)
f16a9783
MS
378
379/* Get the correct GNU hash section name. */
978c4450
AM
380#define GNU_HASH_SECTION_NAME(filedata) \
381 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 382\f
66cfc0fd
AM
383/* Print a BFD_VMA to an internal buffer, for use in error messages.
384 BFD_FMA_FMT can't be used in translated strings. */
385
386static const char *
387bfd_vmatoa (char *fmtch, bfd_vma value)
388{
389 /* bfd_vmatoa is used more then once in a printf call for output.
390 Cycle through an array of buffers. */
391 static int buf_pos = 0;
392 static struct bfd_vmatoa_buf
393 {
394 char place[64];
395 } buf[4];
396 char *ret;
397 char fmt[32];
398
399 ret = buf[buf_pos++].place;
400 buf_pos %= ARRAY_SIZE (buf);
401
402 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
403 snprintf (ret, sizeof (buf[0].place), fmt, value);
404 return ret;
405}
406
dda8d76d
NC
407/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
408 OFFSET + the offset of the current archive member, if we are examining an
409 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
410 allocate a buffer using malloc and fill that. In either case return the
411 pointer to the start of the retrieved data or NULL if something went wrong.
412 If something does go wrong and REASON is not NULL then emit an error
413 message using REASON as part of the context. */
59245841 414
c256ffe7 415static void *
dda8d76d
NC
416get_data (void * var,
417 Filedata * filedata,
418 unsigned long offset,
419 bfd_size_type size,
420 bfd_size_type nmemb,
421 const char * reason)
a6e9f9df 422{
2cf0635d 423 void * mvar;
57028622 424 bfd_size_type amt = size * nmemb;
a6e9f9df 425
c256ffe7 426 if (size == 0 || nmemb == 0)
a6e9f9df
AM
427 return NULL;
428
57028622
NC
429 /* If the size_t type is smaller than the bfd_size_type, eg because
430 you are building a 32-bit tool on a 64-bit host, then make sure
431 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
432 if ((size_t) size != size
433 || (size_t) nmemb != nmemb
434 || (size_t) amt != amt)
57028622
NC
435 {
436 if (reason)
66cfc0fd
AM
437 error (_("Size truncation prevents reading %s"
438 " elements of size %s for %s\n"),
439 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
440 return NULL;
441 }
442
443 /* Check for size overflow. */
7c1c1904 444 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
445 {
446 if (reason)
66cfc0fd
AM
447 error (_("Size overflow prevents reading %s"
448 " elements of size %s for %s\n"),
449 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
450 return NULL;
451 }
452
c22b42ce 453 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 454 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
455 if (filedata->archive_file_offset > filedata->file_size
456 || offset > filedata->file_size - filedata->archive_file_offset
457 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 458 {
049b0c3a 459 if (reason)
66cfc0fd
AM
460 error (_("Reading %s bytes extends past end of file for %s\n"),
461 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
462 return NULL;
463 }
464
978c4450
AM
465 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
466 SEEK_SET))
071436c6
NC
467 {
468 if (reason)
c9c1d674 469 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 470 filedata->archive_file_offset + offset, reason);
071436c6
NC
471 return NULL;
472 }
473
a6e9f9df
AM
474 mvar = var;
475 if (mvar == NULL)
476 {
7c1c1904
AM
477 /* + 1 so that we can '\0' terminate invalid string table sections. */
478 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
479
480 if (mvar == NULL)
481 {
049b0c3a 482 if (reason)
66cfc0fd
AM
483 error (_("Out of memory allocating %s bytes for %s\n"),
484 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
485 return NULL;
486 }
c256ffe7 487
c9c1d674 488 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
489 }
490
dda8d76d 491 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 492 {
049b0c3a 493 if (reason)
66cfc0fd
AM
494 error (_("Unable to read in %s bytes of %s\n"),
495 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
496 if (mvar != var)
497 free (mvar);
498 return NULL;
499 }
500
501 return mvar;
502}
503
32ec8896
NC
504/* Print a VMA value in the MODE specified.
505 Returns the number of characters displayed. */
cb8f3167 506
32ec8896 507static unsigned int
14a91970 508print_vma (bfd_vma vma, print_mode mode)
66543521 509{
32ec8896 510 unsigned int nc = 0;
66543521 511
14a91970 512 switch (mode)
66543521 513 {
14a91970
AM
514 case FULL_HEX:
515 nc = printf ("0x");
1a0670f3 516 /* Fall through. */
14a91970 517 case LONG_HEX:
f7a99963 518#ifdef BFD64
14a91970 519 if (is_32bit_elf)
437c2fb7 520 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 521#endif
14a91970
AM
522 printf_vma (vma);
523 return nc + 16;
b19aac67 524
14a91970
AM
525 case DEC_5:
526 if (vma <= 99999)
527 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 528 /* Fall through. */
14a91970
AM
529 case PREFIX_HEX:
530 nc = printf ("0x");
1a0670f3 531 /* Fall through. */
14a91970
AM
532 case HEX:
533 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 534
047c3dbf
NL
535 case PREFIX_HEX_5:
536 nc = printf ("0x");
537 /* Fall through. */
538 case HEX_5:
539 return nc + printf ("%05" BFD_VMA_FMT "x", vma);
540
14a91970
AM
541 case DEC:
542 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 543
14a91970
AM
544 case UNSIGNED:
545 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896 546
047c3dbf
NL
547 case UNSIGNED_5:
548 return printf ("%5" BFD_VMA_FMT "u", vma);
549
550 case OCTAL:
551 return printf ("%" BFD_VMA_FMT "o", vma);
552
553 case OCTAL_5:
554 return printf ("%5" BFD_VMA_FMT "o", vma);
555
32ec8896
NC
556 default:
557 /* FIXME: Report unrecognised mode ? */
558 return 0;
f7a99963 559 }
f7a99963
NC
560}
561
047c3dbf 562
7bfd842d 563/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 564 multibye characters (assuming the host environment supports them).
31104126 565
7bfd842d
NC
566 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
567
0942c7ab
NC
568 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
569 abs(WIDTH) - 5 characters followed by "[...]".
570
7bfd842d
NC
571 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
572 padding as necessary.
171191ba
NC
573
574 Returns the number of emitted characters. */
575
576static unsigned int
0942c7ab 577print_symbol (signed int width, const char * symbol)
31104126 578{
015dc7e1
AM
579 bool extra_padding = false;
580 bool do_dots = false;
32ec8896 581 signed int num_printed = 0;
3bfcb652 582#ifdef HAVE_MBSTATE_T
7bfd842d 583 mbstate_t state;
3bfcb652 584#endif
32ec8896 585 unsigned int width_remaining;
79bc120c 586 const void * alloced_symbol = NULL;
961c521f 587
7bfd842d 588 if (width < 0)
961c521f 589 {
88305e1b 590 /* Keep the width positive. This helps the code below. */
961c521f 591 width = - width;
015dc7e1 592 extra_padding = true;
0b4362b0 593 }
56d8f8a9
NC
594 else if (width == 0)
595 return 0;
961c521f 596
7bfd842d
NC
597 if (do_wide)
598 /* Set the remaining width to a very large value.
599 This simplifies the code below. */
600 width_remaining = INT_MAX;
601 else
0942c7ab
NC
602 {
603 width_remaining = width;
604 if (! do_not_show_symbol_truncation
605 && (int) strlen (symbol) > width)
606 {
607 width_remaining -= 5;
608 if ((int) width_remaining < 0)
609 width_remaining = 0;
015dc7e1 610 do_dots = true;
0942c7ab
NC
611 }
612 }
cb8f3167 613
3bfcb652 614#ifdef HAVE_MBSTATE_T
7bfd842d
NC
615 /* Initialise the multibyte conversion state. */
616 memset (& state, 0, sizeof (state));
3bfcb652 617#endif
961c521f 618
79bc120c
NC
619 if (do_demangle && *symbol)
620 {
621 const char * res = cplus_demangle (symbol, demangle_flags);
622
623 if (res != NULL)
624 alloced_symbol = symbol = res;
625 }
626
7bfd842d
NC
627 while (width_remaining)
628 {
629 size_t n;
7bfd842d 630 const char c = *symbol++;
961c521f 631
7bfd842d 632 if (c == 0)
961c521f
NC
633 break;
634
7bfd842d
NC
635 /* Do not print control characters directly as they can affect terminal
636 settings. Such characters usually appear in the names generated
637 by the assembler for local labels. */
638 if (ISCNTRL (c))
961c521f 639 {
7bfd842d 640 if (width_remaining < 2)
961c521f
NC
641 break;
642
7bfd842d
NC
643 printf ("^%c", c + 0x40);
644 width_remaining -= 2;
171191ba 645 num_printed += 2;
961c521f 646 }
7bfd842d
NC
647 else if (ISPRINT (c))
648 {
649 putchar (c);
650 width_remaining --;
651 num_printed ++;
652 }
961c521f
NC
653 else
654 {
3bfcb652
NC
655#ifdef HAVE_MBSTATE_T
656 wchar_t w;
657#endif
7bfd842d
NC
658 /* Let printf do the hard work of displaying multibyte characters. */
659 printf ("%.1s", symbol - 1);
660 width_remaining --;
661 num_printed ++;
662
3bfcb652 663#ifdef HAVE_MBSTATE_T
7bfd842d
NC
664 /* Try to find out how many bytes made up the character that was
665 just printed. Advance the symbol pointer past the bytes that
666 were displayed. */
667 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
668#else
669 n = 1;
670#endif
7bfd842d
NC
671 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
672 symbol += (n - 1);
961c521f 673 }
961c521f 674 }
171191ba 675
0942c7ab
NC
676 if (do_dots)
677 num_printed += printf ("[...]");
678
7bfd842d 679 if (extra_padding && num_printed < width)
171191ba
NC
680 {
681 /* Fill in the remaining spaces. */
7bfd842d
NC
682 printf ("%-*s", width - num_printed, " ");
683 num_printed = width;
171191ba
NC
684 }
685
79bc120c 686 free ((void *) alloced_symbol);
171191ba 687 return num_printed;
31104126
NC
688}
689
1449284b 690/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
691 the given section's name. Like print_symbol, except that it does not try
692 to print multibyte characters, it just interprets them as hex values. */
693
694static const char *
dda8d76d 695printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 696{
ca0e11aa 697#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 698 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
b9e920ec 699 const char * name = SECTION_NAME_PRINT (sec);
74e1a04b
NC
700 char * buf = sec_name_buf;
701 char c;
702 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
703
704 while ((c = * name ++) != 0)
705 {
706 if (ISCNTRL (c))
707 {
708 if (remaining < 2)
709 break;
948f632f 710
74e1a04b
NC
711 * buf ++ = '^';
712 * buf ++ = c + 0x40;
713 remaining -= 2;
714 }
715 else if (ISPRINT (c))
716 {
717 * buf ++ = c;
718 remaining -= 1;
719 }
720 else
721 {
722 static char hex[17] = "0123456789ABCDEF";
723
724 if (remaining < 4)
725 break;
726 * buf ++ = '<';
727 * buf ++ = hex[(c & 0xf0) >> 4];
728 * buf ++ = hex[c & 0x0f];
729 * buf ++ = '>';
730 remaining -= 4;
731 }
732
733 if (remaining == 0)
734 break;
735 }
736
737 * buf = 0;
738 return sec_name_buf;
739}
740
741static const char *
dda8d76d 742printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 743{
dda8d76d 744 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
745 return _("<corrupt>");
746
dda8d76d 747 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
748}
749
89fac5e3
RS
750/* Return a pointer to section NAME, or NULL if no such section exists. */
751
752static Elf_Internal_Shdr *
dda8d76d 753find_section (Filedata * filedata, const char * name)
89fac5e3
RS
754{
755 unsigned int i;
756
68807c3c
NC
757 if (filedata->section_headers == NULL)
758 return NULL;
dda8d76d
NC
759
760 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
761 if (SECTION_NAME_VALID (filedata->section_headers + i)
762 && streq (SECTION_NAME (filedata->section_headers + i), name))
dda8d76d 763 return filedata->section_headers + i;
89fac5e3
RS
764
765 return NULL;
766}
767
0b6ae522
DJ
768/* Return a pointer to a section containing ADDR, or NULL if no such
769 section exists. */
770
771static Elf_Internal_Shdr *
dda8d76d 772find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
773{
774 unsigned int i;
775
68807c3c
NC
776 if (filedata->section_headers == NULL)
777 return NULL;
778
dda8d76d 779 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 780 {
dda8d76d
NC
781 Elf_Internal_Shdr *sec = filedata->section_headers + i;
782
0b6ae522
DJ
783 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
784 return sec;
785 }
786
787 return NULL;
788}
789
071436c6 790static Elf_Internal_Shdr *
dda8d76d 791find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
792{
793 unsigned int i;
794
68807c3c
NC
795 if (filedata->section_headers == NULL)
796 return NULL;
797
dda8d76d 798 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 799 {
dda8d76d
NC
800 Elf_Internal_Shdr *sec = filedata->section_headers + i;
801
071436c6
NC
802 if (sec->sh_type == type)
803 return sec;
804 }
805
806 return NULL;
807}
808
657d0d47
CC
809/* Return a pointer to section NAME, or NULL if no such section exists,
810 restricted to the list of sections given in SET. */
811
812static Elf_Internal_Shdr *
dda8d76d 813find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
814{
815 unsigned int i;
816
68807c3c
NC
817 if (filedata->section_headers == NULL)
818 return NULL;
819
657d0d47
CC
820 if (set != NULL)
821 {
822 while ((i = *set++) > 0)
b814a36d
NC
823 {
824 /* See PR 21156 for a reproducer. */
dda8d76d 825 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
826 continue; /* FIXME: Should we issue an error message ? */
827
b9e920ec
AM
828 if (SECTION_NAME_VALID (filedata->section_headers + i)
829 && streq (SECTION_NAME (filedata->section_headers + i), name))
dda8d76d 830 return filedata->section_headers + i;
b814a36d 831 }
657d0d47
CC
832 }
833
dda8d76d 834 return find_section (filedata, name);
657d0d47
CC
835}
836
32ec8896 837/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
838 This OS has so many departures from the ELF standard that we test it at
839 many places. */
840
015dc7e1 841static inline bool
dda8d76d 842is_ia64_vms (Filedata * filedata)
28f997cf 843{
dda8d76d
NC
844 return filedata->file_header.e_machine == EM_IA_64
845 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
846}
847
bcedfee6 848/* Guess the relocation size commonly used by the specific machines. */
252b5132 849
015dc7e1 850static bool
2dc4cec1 851guess_is_rela (unsigned int e_machine)
252b5132 852{
9c19a809 853 switch (e_machine)
252b5132
RH
854 {
855 /* Targets that use REL relocations. */
252b5132 856 case EM_386:
22abe556 857 case EM_IAMCU:
f954747f 858 case EM_960:
e9f53129 859 case EM_ARM:
2b0337b0 860 case EM_D10V:
252b5132 861 case EM_CYGNUS_D10V:
e9f53129 862 case EM_DLX:
252b5132 863 case EM_MIPS:
4fe85591 864 case EM_MIPS_RS3_LE:
e9f53129 865 case EM_CYGNUS_M32R:
1c0d3aa6 866 case EM_SCORE:
f6c1a2d5 867 case EM_XGATE:
fe944acf 868 case EM_NFP:
aca4efc7 869 case EM_BPF:
015dc7e1 870 return false;
103f02d3 871
252b5132
RH
872 /* Targets that use RELA relocations. */
873 case EM_68K:
f954747f 874 case EM_860:
a06ea964 875 case EM_AARCH64:
cfb8c092 876 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
877 case EM_ALPHA:
878 case EM_ALTERA_NIOS2:
886a2506
NC
879 case EM_ARC:
880 case EM_ARC_COMPACT:
881 case EM_ARC_COMPACT2:
e9f53129
AM
882 case EM_AVR:
883 case EM_AVR_OLD:
884 case EM_BLACKFIN:
60bca95a 885 case EM_CR16:
e9f53129
AM
886 case EM_CRIS:
887 case EM_CRX:
b8891f8d 888 case EM_CSKY:
2b0337b0 889 case EM_D30V:
252b5132 890 case EM_CYGNUS_D30V:
2b0337b0 891 case EM_FR30:
3f8107ab 892 case EM_FT32:
252b5132 893 case EM_CYGNUS_FR30:
5c70f934 894 case EM_CYGNUS_FRV:
e9f53129
AM
895 case EM_H8S:
896 case EM_H8_300:
897 case EM_H8_300H:
800eeca4 898 case EM_IA_64:
1e4cf259
NC
899 case EM_IP2K:
900 case EM_IP2K_OLD:
3b36097d 901 case EM_IQ2000:
84e94c90 902 case EM_LATTICEMICO32:
ff7eeb89 903 case EM_M32C_OLD:
49f58d10 904 case EM_M32C:
e9f53129
AM
905 case EM_M32R:
906 case EM_MCORE:
15ab5209 907 case EM_CYGNUS_MEP:
a3c62988 908 case EM_METAG:
e9f53129
AM
909 case EM_MMIX:
910 case EM_MN10200:
911 case EM_CYGNUS_MN10200:
912 case EM_MN10300:
913 case EM_CYGNUS_MN10300:
5506d11a 914 case EM_MOXIE:
e9f53129
AM
915 case EM_MSP430:
916 case EM_MSP430_OLD:
d031aafb 917 case EM_MT:
35c08157 918 case EM_NDS32:
64fd6348 919 case EM_NIOS32:
73589c9d 920 case EM_OR1K:
e9f53129
AM
921 case EM_PPC64:
922 case EM_PPC:
2b100bb5 923 case EM_TI_PRU:
e23eba97 924 case EM_RISCV:
99c513f6 925 case EM_RL78:
c7927a3c 926 case EM_RX:
e9f53129
AM
927 case EM_S390:
928 case EM_S390_OLD:
929 case EM_SH:
930 case EM_SPARC:
931 case EM_SPARC32PLUS:
932 case EM_SPARCV9:
933 case EM_SPU:
40b36596 934 case EM_TI_C6000:
aa137e4d
NC
935 case EM_TILEGX:
936 case EM_TILEPRO:
708e2187 937 case EM_V800:
e9f53129
AM
938 case EM_V850:
939 case EM_CYGNUS_V850:
940 case EM_VAX:
619ed720 941 case EM_VISIUM:
e9f53129 942 case EM_X86_64:
8a9036a4 943 case EM_L1OM:
7a9068fe 944 case EM_K1OM:
e9f53129
AM
945 case EM_XSTORMY16:
946 case EM_XTENSA:
947 case EM_XTENSA_OLD:
7ba29e2a
NC
948 case EM_MICROBLAZE:
949 case EM_MICROBLAZE_OLD:
f96bd6c2 950 case EM_WEBASSEMBLY:
015dc7e1 951 return true;
103f02d3 952
e9f53129
AM
953 case EM_68HC05:
954 case EM_68HC08:
955 case EM_68HC11:
956 case EM_68HC16:
957 case EM_FX66:
958 case EM_ME16:
d1133906 959 case EM_MMA:
d1133906
NC
960 case EM_NCPU:
961 case EM_NDR1:
e9f53129 962 case EM_PCP:
d1133906 963 case EM_ST100:
e9f53129 964 case EM_ST19:
d1133906 965 case EM_ST7:
e9f53129
AM
966 case EM_ST9PLUS:
967 case EM_STARCORE:
d1133906 968 case EM_SVX:
e9f53129 969 case EM_TINYJ:
9c19a809
NC
970 default:
971 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 972 return false;
9c19a809
NC
973 }
974}
252b5132 975
dda8d76d 976/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
977 Returns TRUE upon success, FALSE otherwise. If successful then a
978 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
979 and the number of relocs loaded is placed in *NRELASP. It is the caller's
980 responsibility to free the allocated buffer. */
981
015dc7e1 982static bool
dda8d76d
NC
983slurp_rela_relocs (Filedata * filedata,
984 unsigned long rel_offset,
985 unsigned long rel_size,
986 Elf_Internal_Rela ** relasp,
987 unsigned long * nrelasp)
9c19a809 988{
2cf0635d 989 Elf_Internal_Rela * relas;
8b73c356 990 size_t nrelas;
4d6ed7c8 991 unsigned int i;
252b5132 992
4d6ed7c8
NC
993 if (is_32bit_elf)
994 {
2cf0635d 995 Elf32_External_Rela * erelas;
103f02d3 996
dda8d76d 997 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 998 rel_size, _("32-bit relocation data"));
a6e9f9df 999 if (!erelas)
015dc7e1 1000 return false;
252b5132 1001
4d6ed7c8 1002 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1003
3f5e193b
NC
1004 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1005 sizeof (Elf_Internal_Rela));
103f02d3 1006
4d6ed7c8
NC
1007 if (relas == NULL)
1008 {
c256ffe7 1009 free (erelas);
591a748a 1010 error (_("out of memory parsing relocs\n"));
015dc7e1 1011 return false;
4d6ed7c8 1012 }
103f02d3 1013
4d6ed7c8
NC
1014 for (i = 0; i < nrelas; i++)
1015 {
1016 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1017 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1018 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1019 }
103f02d3 1020
4d6ed7c8
NC
1021 free (erelas);
1022 }
1023 else
1024 {
2cf0635d 1025 Elf64_External_Rela * erelas;
103f02d3 1026
dda8d76d 1027 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1028 rel_size, _("64-bit relocation data"));
a6e9f9df 1029 if (!erelas)
015dc7e1 1030 return false;
4d6ed7c8
NC
1031
1032 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1033
3f5e193b
NC
1034 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1035 sizeof (Elf_Internal_Rela));
103f02d3 1036
4d6ed7c8
NC
1037 if (relas == NULL)
1038 {
c256ffe7 1039 free (erelas);
591a748a 1040 error (_("out of memory parsing relocs\n"));
015dc7e1 1041 return false;
9c19a809 1042 }
4d6ed7c8
NC
1043
1044 for (i = 0; i < nrelas; i++)
9c19a809 1045 {
66543521
AM
1046 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1047 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1048 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1049
1050 /* The #ifdef BFD64 below is to prevent a compile time
1051 warning. We know that if we do not have a 64 bit data
1052 type that we will never execute this code anyway. */
1053#ifdef BFD64
dda8d76d
NC
1054 if (filedata->file_header.e_machine == EM_MIPS
1055 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1056 {
1057 /* In little-endian objects, r_info isn't really a
1058 64-bit little-endian value: it has a 32-bit
1059 little-endian symbol index followed by four
1060 individual byte fields. Reorder INFO
1061 accordingly. */
91d6fa6a
NC
1062 bfd_vma inf = relas[i].r_info;
1063 inf = (((inf & 0xffffffff) << 32)
1064 | ((inf >> 56) & 0xff)
1065 | ((inf >> 40) & 0xff00)
1066 | ((inf >> 24) & 0xff0000)
1067 | ((inf >> 8) & 0xff000000));
1068 relas[i].r_info = inf;
861fb55a
DJ
1069 }
1070#endif /* BFD64 */
4d6ed7c8 1071 }
103f02d3 1072
4d6ed7c8
NC
1073 free (erelas);
1074 }
32ec8896 1075
4d6ed7c8
NC
1076 *relasp = relas;
1077 *nrelasp = nrelas;
015dc7e1 1078 return true;
4d6ed7c8 1079}
103f02d3 1080
dda8d76d 1081/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1082 Returns TRUE upon success, FALSE otherwise. If successful then a
1083 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1084 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1085 responsibility to free the allocated buffer. */
1086
015dc7e1 1087static bool
dda8d76d
NC
1088slurp_rel_relocs (Filedata * filedata,
1089 unsigned long rel_offset,
1090 unsigned long rel_size,
1091 Elf_Internal_Rela ** relsp,
1092 unsigned long * nrelsp)
4d6ed7c8 1093{
2cf0635d 1094 Elf_Internal_Rela * rels;
8b73c356 1095 size_t nrels;
4d6ed7c8 1096 unsigned int i;
103f02d3 1097
4d6ed7c8
NC
1098 if (is_32bit_elf)
1099 {
2cf0635d 1100 Elf32_External_Rel * erels;
103f02d3 1101
dda8d76d 1102 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1103 rel_size, _("32-bit relocation data"));
a6e9f9df 1104 if (!erels)
015dc7e1 1105 return false;
103f02d3 1106
4d6ed7c8 1107 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1108
3f5e193b 1109 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1110
4d6ed7c8
NC
1111 if (rels == NULL)
1112 {
c256ffe7 1113 free (erels);
591a748a 1114 error (_("out of memory parsing relocs\n"));
015dc7e1 1115 return false;
4d6ed7c8
NC
1116 }
1117
1118 for (i = 0; i < nrels; i++)
1119 {
1120 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1121 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1122 rels[i].r_addend = 0;
9ea033b2 1123 }
4d6ed7c8
NC
1124
1125 free (erels);
9c19a809
NC
1126 }
1127 else
1128 {
2cf0635d 1129 Elf64_External_Rel * erels;
9ea033b2 1130
dda8d76d 1131 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1132 rel_size, _("64-bit relocation data"));
a6e9f9df 1133 if (!erels)
015dc7e1 1134 return false;
103f02d3 1135
4d6ed7c8 1136 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1137
3f5e193b 1138 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1139
4d6ed7c8 1140 if (rels == NULL)
9c19a809 1141 {
c256ffe7 1142 free (erels);
591a748a 1143 error (_("out of memory parsing relocs\n"));
015dc7e1 1144 return false;
4d6ed7c8 1145 }
103f02d3 1146
4d6ed7c8
NC
1147 for (i = 0; i < nrels; i++)
1148 {
66543521
AM
1149 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1150 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1151 rels[i].r_addend = 0;
861fb55a
DJ
1152
1153 /* The #ifdef BFD64 below is to prevent a compile time
1154 warning. We know that if we do not have a 64 bit data
1155 type that we will never execute this code anyway. */
1156#ifdef BFD64
dda8d76d
NC
1157 if (filedata->file_header.e_machine == EM_MIPS
1158 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1159 {
1160 /* In little-endian objects, r_info isn't really a
1161 64-bit little-endian value: it has a 32-bit
1162 little-endian symbol index followed by four
1163 individual byte fields. Reorder INFO
1164 accordingly. */
91d6fa6a
NC
1165 bfd_vma inf = rels[i].r_info;
1166 inf = (((inf & 0xffffffff) << 32)
1167 | ((inf >> 56) & 0xff)
1168 | ((inf >> 40) & 0xff00)
1169 | ((inf >> 24) & 0xff0000)
1170 | ((inf >> 8) & 0xff000000));
1171 rels[i].r_info = inf;
861fb55a
DJ
1172 }
1173#endif /* BFD64 */
4d6ed7c8 1174 }
103f02d3 1175
4d6ed7c8
NC
1176 free (erels);
1177 }
32ec8896 1178
4d6ed7c8
NC
1179 *relsp = rels;
1180 *nrelsp = nrels;
015dc7e1 1181 return true;
4d6ed7c8 1182}
103f02d3 1183
aca88567
NC
1184/* Returns the reloc type extracted from the reloc info field. */
1185
1186static unsigned int
dda8d76d 1187get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1188{
1189 if (is_32bit_elf)
1190 return ELF32_R_TYPE (reloc_info);
1191
dda8d76d 1192 switch (filedata->file_header.e_machine)
aca88567
NC
1193 {
1194 case EM_MIPS:
1195 /* Note: We assume that reloc_info has already been adjusted for us. */
1196 return ELF64_MIPS_R_TYPE (reloc_info);
1197
1198 case EM_SPARCV9:
1199 return ELF64_R_TYPE_ID (reloc_info);
1200
1201 default:
1202 return ELF64_R_TYPE (reloc_info);
1203 }
1204}
1205
1206/* Return the symbol index extracted from the reloc info field. */
1207
1208static bfd_vma
1209get_reloc_symindex (bfd_vma reloc_info)
1210{
1211 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1212}
1213
015dc7e1 1214static inline bool
dda8d76d 1215uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1216{
1217 return
dda8d76d 1218 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1219 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1220 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1221 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1222 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1223}
1224
d3ba0551
AM
1225/* Display the contents of the relocation data found at the specified
1226 offset. */
ee42cf8c 1227
015dc7e1 1228static bool
dda8d76d
NC
1229dump_relocations (Filedata * filedata,
1230 unsigned long rel_offset,
1231 unsigned long rel_size,
1232 Elf_Internal_Sym * symtab,
1233 unsigned long nsyms,
1234 char * strtab,
1235 unsigned long strtablen,
1236 int is_rela,
015dc7e1 1237 bool is_dynsym)
4d6ed7c8 1238{
32ec8896 1239 unsigned long i;
2cf0635d 1240 Elf_Internal_Rela * rels;
015dc7e1 1241 bool res = true;
103f02d3 1242
4d6ed7c8 1243 if (is_rela == UNKNOWN)
dda8d76d 1244 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1245
4d6ed7c8
NC
1246 if (is_rela)
1247 {
dda8d76d 1248 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1249 return false;
4d6ed7c8
NC
1250 }
1251 else
1252 {
dda8d76d 1253 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1254 return false;
252b5132
RH
1255 }
1256
410f7a12
L
1257 if (is_32bit_elf)
1258 {
1259 if (is_rela)
2c71103e
NC
1260 {
1261 if (do_wide)
1262 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1263 else
1264 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1265 }
410f7a12 1266 else
2c71103e
NC
1267 {
1268 if (do_wide)
1269 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1270 else
1271 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1272 }
410f7a12 1273 }
252b5132 1274 else
410f7a12
L
1275 {
1276 if (is_rela)
2c71103e
NC
1277 {
1278 if (do_wide)
8beeaeb7 1279 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1280 else
1281 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1282 }
410f7a12 1283 else
2c71103e
NC
1284 {
1285 if (do_wide)
8beeaeb7 1286 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1287 else
1288 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1289 }
410f7a12 1290 }
252b5132
RH
1291
1292 for (i = 0; i < rel_size; i++)
1293 {
2cf0635d 1294 const char * rtype;
b34976b6 1295 bfd_vma offset;
91d6fa6a 1296 bfd_vma inf;
b34976b6
AM
1297 bfd_vma symtab_index;
1298 bfd_vma type;
103f02d3 1299
b34976b6 1300 offset = rels[i].r_offset;
91d6fa6a 1301 inf = rels[i].r_info;
103f02d3 1302
dda8d76d 1303 type = get_reloc_type (filedata, inf);
91d6fa6a 1304 symtab_index = get_reloc_symindex (inf);
252b5132 1305
410f7a12
L
1306 if (is_32bit_elf)
1307 {
39dbeff8
AM
1308 printf ("%8.8lx %8.8lx ",
1309 (unsigned long) offset & 0xffffffff,
91d6fa6a 1310 (unsigned long) inf & 0xffffffff);
410f7a12
L
1311 }
1312 else
1313 {
39dbeff8 1314 printf (do_wide
d1ce973e
AM
1315 ? "%16.16" BFD_VMA_FMT "x %16.16" BFD_VMA_FMT "x "
1316 : "%12.12" BFD_VMA_FMT "x %12.12" BFD_VMA_FMT "x ",
91d6fa6a 1317 offset, inf);
410f7a12 1318 }
103f02d3 1319
dda8d76d 1320 switch (filedata->file_header.e_machine)
252b5132
RH
1321 {
1322 default:
1323 rtype = NULL;
1324 break;
1325
a06ea964
NC
1326 case EM_AARCH64:
1327 rtype = elf_aarch64_reloc_type (type);
1328 break;
1329
2b0337b0 1330 case EM_M32R:
252b5132 1331 case EM_CYGNUS_M32R:
9ea033b2 1332 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1333 break;
1334
1335 case EM_386:
22abe556 1336 case EM_IAMCU:
9ea033b2 1337 rtype = elf_i386_reloc_type (type);
252b5132
RH
1338 break;
1339
ba2685cc
AM
1340 case EM_68HC11:
1341 case EM_68HC12:
1342 rtype = elf_m68hc11_reloc_type (type);
1343 break;
75751cd9 1344
7b4ae824
JD
1345 case EM_S12Z:
1346 rtype = elf_s12z_reloc_type (type);
1347 break;
1348
252b5132 1349 case EM_68K:
9ea033b2 1350 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1351 break;
1352
f954747f
AM
1353 case EM_960:
1354 rtype = elf_i960_reloc_type (type);
1355 break;
1356
adde6300 1357 case EM_AVR:
2b0337b0 1358 case EM_AVR_OLD:
adde6300
AM
1359 rtype = elf_avr_reloc_type (type);
1360 break;
1361
9ea033b2
NC
1362 case EM_OLD_SPARCV9:
1363 case EM_SPARC32PLUS:
1364 case EM_SPARCV9:
252b5132 1365 case EM_SPARC:
9ea033b2 1366 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1367 break;
1368
e9f53129
AM
1369 case EM_SPU:
1370 rtype = elf_spu_reloc_type (type);
1371 break;
1372
708e2187
NC
1373 case EM_V800:
1374 rtype = v800_reloc_type (type);
1375 break;
2b0337b0 1376 case EM_V850:
252b5132 1377 case EM_CYGNUS_V850:
9ea033b2 1378 rtype = v850_reloc_type (type);
252b5132
RH
1379 break;
1380
2b0337b0 1381 case EM_D10V:
252b5132 1382 case EM_CYGNUS_D10V:
9ea033b2 1383 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1384 break;
1385
2b0337b0 1386 case EM_D30V:
252b5132 1387 case EM_CYGNUS_D30V:
9ea033b2 1388 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1389 break;
1390
d172d4ba
NC
1391 case EM_DLX:
1392 rtype = elf_dlx_reloc_type (type);
1393 break;
1394
252b5132 1395 case EM_SH:
9ea033b2 1396 rtype = elf_sh_reloc_type (type);
252b5132
RH
1397 break;
1398
2b0337b0 1399 case EM_MN10300:
252b5132 1400 case EM_CYGNUS_MN10300:
9ea033b2 1401 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1402 break;
1403
2b0337b0 1404 case EM_MN10200:
252b5132 1405 case EM_CYGNUS_MN10200:
9ea033b2 1406 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1407 break;
1408
2b0337b0 1409 case EM_FR30:
252b5132 1410 case EM_CYGNUS_FR30:
9ea033b2 1411 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1412 break;
1413
ba2685cc
AM
1414 case EM_CYGNUS_FRV:
1415 rtype = elf_frv_reloc_type (type);
1416 break;
5c70f934 1417
b8891f8d
AJ
1418 case EM_CSKY:
1419 rtype = elf_csky_reloc_type (type);
1420 break;
1421
3f8107ab
AM
1422 case EM_FT32:
1423 rtype = elf_ft32_reloc_type (type);
1424 break;
1425
252b5132 1426 case EM_MCORE:
9ea033b2 1427 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1428 break;
1429
3c3bdf30
NC
1430 case EM_MMIX:
1431 rtype = elf_mmix_reloc_type (type);
1432 break;
1433
5506d11a
AM
1434 case EM_MOXIE:
1435 rtype = elf_moxie_reloc_type (type);
1436 break;
1437
2469cfa2 1438 case EM_MSP430:
dda8d76d 1439 if (uses_msp430x_relocs (filedata))
13761a11
NC
1440 {
1441 rtype = elf_msp430x_reloc_type (type);
1442 break;
1443 }
1a0670f3 1444 /* Fall through. */
2469cfa2
NC
1445 case EM_MSP430_OLD:
1446 rtype = elf_msp430_reloc_type (type);
1447 break;
1448
35c08157
KLC
1449 case EM_NDS32:
1450 rtype = elf_nds32_reloc_type (type);
1451 break;
1452
252b5132 1453 case EM_PPC:
9ea033b2 1454 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1455 break;
1456
c833c019
AM
1457 case EM_PPC64:
1458 rtype = elf_ppc64_reloc_type (type);
1459 break;
1460
252b5132 1461 case EM_MIPS:
4fe85591 1462 case EM_MIPS_RS3_LE:
9ea033b2 1463 rtype = elf_mips_reloc_type (type);
252b5132
RH
1464 break;
1465
e23eba97
NC
1466 case EM_RISCV:
1467 rtype = elf_riscv_reloc_type (type);
1468 break;
1469
252b5132 1470 case EM_ALPHA:
9ea033b2 1471 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1472 break;
1473
1474 case EM_ARM:
9ea033b2 1475 rtype = elf_arm_reloc_type (type);
252b5132
RH
1476 break;
1477
584da044 1478 case EM_ARC:
886a2506
NC
1479 case EM_ARC_COMPACT:
1480 case EM_ARC_COMPACT2:
9ea033b2 1481 rtype = elf_arc_reloc_type (type);
252b5132
RH
1482 break;
1483
1484 case EM_PARISC:
69e617ca 1485 rtype = elf_hppa_reloc_type (type);
252b5132 1486 break;
7d466069 1487
b8720f9d
JL
1488 case EM_H8_300:
1489 case EM_H8_300H:
1490 case EM_H8S:
1491 rtype = elf_h8_reloc_type (type);
1492 break;
1493
73589c9d
CS
1494 case EM_OR1K:
1495 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1496 break;
1497
7d466069 1498 case EM_PJ:
2b0337b0 1499 case EM_PJ_OLD:
7d466069
ILT
1500 rtype = elf_pj_reloc_type (type);
1501 break;
800eeca4
JW
1502 case EM_IA_64:
1503 rtype = elf_ia64_reloc_type (type);
1504 break;
1b61cf92
HPN
1505
1506 case EM_CRIS:
1507 rtype = elf_cris_reloc_type (type);
1508 break;
535c37ff 1509
f954747f
AM
1510 case EM_860:
1511 rtype = elf_i860_reloc_type (type);
1512 break;
1513
bcedfee6 1514 case EM_X86_64:
8a9036a4 1515 case EM_L1OM:
7a9068fe 1516 case EM_K1OM:
bcedfee6
NC
1517 rtype = elf_x86_64_reloc_type (type);
1518 break;
a85d7ed0 1519
f954747f
AM
1520 case EM_S370:
1521 rtype = i370_reloc_type (type);
1522 break;
1523
53c7db4b
KH
1524 case EM_S390_OLD:
1525 case EM_S390:
1526 rtype = elf_s390_reloc_type (type);
1527 break;
93fbbb04 1528
1c0d3aa6
NC
1529 case EM_SCORE:
1530 rtype = elf_score_reloc_type (type);
1531 break;
1532
93fbbb04
GK
1533 case EM_XSTORMY16:
1534 rtype = elf_xstormy16_reloc_type (type);
1535 break;
179d3252 1536
1fe1f39c
NC
1537 case EM_CRX:
1538 rtype = elf_crx_reloc_type (type);
1539 break;
1540
179d3252
JT
1541 case EM_VAX:
1542 rtype = elf_vax_reloc_type (type);
1543 break;
1e4cf259 1544
619ed720
EB
1545 case EM_VISIUM:
1546 rtype = elf_visium_reloc_type (type);
1547 break;
1548
aca4efc7
JM
1549 case EM_BPF:
1550 rtype = elf_bpf_reloc_type (type);
1551 break;
1552
cfb8c092
NC
1553 case EM_ADAPTEVA_EPIPHANY:
1554 rtype = elf_epiphany_reloc_type (type);
1555 break;
1556
1e4cf259
NC
1557 case EM_IP2K:
1558 case EM_IP2K_OLD:
1559 rtype = elf_ip2k_reloc_type (type);
1560 break;
3b36097d
SC
1561
1562 case EM_IQ2000:
1563 rtype = elf_iq2000_reloc_type (type);
1564 break;
88da6820
NC
1565
1566 case EM_XTENSA_OLD:
1567 case EM_XTENSA:
1568 rtype = elf_xtensa_reloc_type (type);
1569 break;
a34e3ecb 1570
84e94c90
NC
1571 case EM_LATTICEMICO32:
1572 rtype = elf_lm32_reloc_type (type);
1573 break;
1574
ff7eeb89 1575 case EM_M32C_OLD:
49f58d10
JB
1576 case EM_M32C:
1577 rtype = elf_m32c_reloc_type (type);
1578 break;
1579
d031aafb
NS
1580 case EM_MT:
1581 rtype = elf_mt_reloc_type (type);
a34e3ecb 1582 break;
1d65ded4
CM
1583
1584 case EM_BLACKFIN:
1585 rtype = elf_bfin_reloc_type (type);
1586 break;
15ab5209
DB
1587
1588 case EM_CYGNUS_MEP:
1589 rtype = elf_mep_reloc_type (type);
1590 break;
60bca95a
NC
1591
1592 case EM_CR16:
1593 rtype = elf_cr16_reloc_type (type);
1594 break;
dd24e3da 1595
7ba29e2a
NC
1596 case EM_MICROBLAZE:
1597 case EM_MICROBLAZE_OLD:
1598 rtype = elf_microblaze_reloc_type (type);
1599 break;
c7927a3c 1600
99c513f6
DD
1601 case EM_RL78:
1602 rtype = elf_rl78_reloc_type (type);
1603 break;
1604
c7927a3c
NC
1605 case EM_RX:
1606 rtype = elf_rx_reloc_type (type);
1607 break;
c29aca4a 1608
a3c62988
NC
1609 case EM_METAG:
1610 rtype = elf_metag_reloc_type (type);
1611 break;
1612
c29aca4a
NC
1613 case EM_XC16X:
1614 case EM_C166:
1615 rtype = elf_xc16x_reloc_type (type);
1616 break;
40b36596
JM
1617
1618 case EM_TI_C6000:
1619 rtype = elf_tic6x_reloc_type (type);
1620 break;
aa137e4d
NC
1621
1622 case EM_TILEGX:
1623 rtype = elf_tilegx_reloc_type (type);
1624 break;
1625
1626 case EM_TILEPRO:
1627 rtype = elf_tilepro_reloc_type (type);
1628 break;
f6c1a2d5 1629
f96bd6c2
PC
1630 case EM_WEBASSEMBLY:
1631 rtype = elf_wasm32_reloc_type (type);
1632 break;
1633
f6c1a2d5
NC
1634 case EM_XGATE:
1635 rtype = elf_xgate_reloc_type (type);
1636 break;
36591ba1
SL
1637
1638 case EM_ALTERA_NIOS2:
1639 rtype = elf_nios2_reloc_type (type);
1640 break;
2b100bb5
DD
1641
1642 case EM_TI_PRU:
1643 rtype = elf_pru_reloc_type (type);
1644 break;
fe944acf
FT
1645
1646 case EM_NFP:
1647 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1648 rtype = elf_nfp3200_reloc_type (type);
1649 else
1650 rtype = elf_nfp_reloc_type (type);
1651 break;
6655dba2
SB
1652
1653 case EM_Z80:
1654 rtype = elf_z80_reloc_type (type);
1655 break;
252b5132
RH
1656 }
1657
1658 if (rtype == NULL)
39dbeff8 1659 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1660 else
5c144731 1661 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1662
dda8d76d 1663 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1664 && rtype != NULL
7ace3541
RH
1665 && streq (rtype, "R_ALPHA_LITUSE")
1666 && is_rela)
1667 {
1668 switch (rels[i].r_addend)
1669 {
1670 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1671 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1672 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1673 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1674 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1675 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1676 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1677 default: rtype = NULL;
1678 }
32ec8896 1679
7ace3541
RH
1680 if (rtype)
1681 printf (" (%s)", rtype);
1682 else
1683 {
1684 putchar (' ');
1685 printf (_("<unknown addend: %lx>"),
1686 (unsigned long) rels[i].r_addend);
015dc7e1 1687 res = false;
7ace3541
RH
1688 }
1689 }
1690 else if (symtab_index)
252b5132 1691 {
af3fc3bc 1692 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1693 {
27a45f42
AS
1694 error (_(" bad symbol index: %08lx in reloc\n"),
1695 (unsigned long) symtab_index);
015dc7e1 1696 res = false;
32ec8896 1697 }
af3fc3bc 1698 else
19936277 1699 {
2cf0635d 1700 Elf_Internal_Sym * psym;
bb4d2ac2
L
1701 const char * version_string;
1702 enum versioned_symbol_info sym_info;
1703 unsigned short vna_other;
19936277 1704
af3fc3bc 1705 psym = symtab + symtab_index;
103f02d3 1706
bb4d2ac2 1707 version_string
dda8d76d 1708 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1709 strtab, strtablen,
1710 symtab_index,
1711 psym,
1712 &sym_info,
1713 &vna_other);
1714
af3fc3bc 1715 printf (" ");
171191ba 1716
d8045f23
NC
1717 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1718 {
1719 const char * name;
1720 unsigned int len;
1721 unsigned int width = is_32bit_elf ? 8 : 14;
1722
1723 /* Relocations against GNU_IFUNC symbols do not use the value
1724 of the symbol as the address to relocate against. Instead
1725 they invoke the function named by the symbol and use its
1726 result as the address for relocation.
1727
1728 To indicate this to the user, do not display the value of
1729 the symbol in the "Symbols's Value" field. Instead show
1730 its name followed by () as a hint that the symbol is
1731 invoked. */
1732
1733 if (strtab == NULL
1734 || psym->st_name == 0
1735 || psym->st_name >= strtablen)
1736 name = "??";
1737 else
1738 name = strtab + psym->st_name;
1739
1740 len = print_symbol (width, name);
bb4d2ac2
L
1741 if (version_string)
1742 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1743 version_string);
d8045f23
NC
1744 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1745 }
1746 else
1747 {
1748 print_vma (psym->st_value, LONG_HEX);
171191ba 1749
d8045f23
NC
1750 printf (is_32bit_elf ? " " : " ");
1751 }
103f02d3 1752
af3fc3bc 1753 if (psym->st_name == 0)
f1ef08cb 1754 {
2cf0635d 1755 const char * sec_name = "<null>";
f1ef08cb
AM
1756 char name_buf[40];
1757
1758 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1759 {
dda8d76d 1760 if (psym->st_shndx < filedata->file_header.e_shnum)
b9e920ec
AM
1761 sec_name = SECTION_NAME_PRINT (filedata->section_headers
1762 + psym->st_shndx);
f1ef08cb
AM
1763 else if (psym->st_shndx == SHN_ABS)
1764 sec_name = "ABS";
1765 else if (psym->st_shndx == SHN_COMMON)
1766 sec_name = "COMMON";
dda8d76d 1767 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1768 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1769 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1770 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1771 sec_name = "SCOMMON";
dda8d76d 1772 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1773 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1774 sec_name = "SUNDEF";
dda8d76d
NC
1775 else if ((filedata->file_header.e_machine == EM_X86_64
1776 || filedata->file_header.e_machine == EM_L1OM
1777 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1778 && psym->st_shndx == SHN_X86_64_LCOMMON)
1779 sec_name = "LARGE_COMMON";
dda8d76d
NC
1780 else if (filedata->file_header.e_machine == EM_IA_64
1781 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1782 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1783 sec_name = "ANSI_COM";
dda8d76d 1784 else if (is_ia64_vms (filedata)
148b93f2
NC
1785 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1786 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1787 else
1788 {
1789 sprintf (name_buf, "<section 0x%x>",
1790 (unsigned int) psym->st_shndx);
1791 sec_name = name_buf;
1792 }
1793 }
1794 print_symbol (22, sec_name);
1795 }
af3fc3bc 1796 else if (strtab == NULL)
d79b3d50 1797 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1798 else if (psym->st_name >= strtablen)
32ec8896 1799 {
27a45f42
AS
1800 error (_("<corrupt string table index: %3ld>\n"),
1801 psym->st_name);
015dc7e1 1802 res = false;
32ec8896 1803 }
af3fc3bc 1804 else
bb4d2ac2
L
1805 {
1806 print_symbol (22, strtab + psym->st_name);
1807 if (version_string)
1808 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1809 version_string);
1810 }
103f02d3 1811
af3fc3bc 1812 if (is_rela)
171191ba 1813 {
7360e63f 1814 bfd_vma off = rels[i].r_addend;
171191ba 1815
7360e63f 1816 if ((bfd_signed_vma) off < 0)
598aaa76 1817 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1818 else
598aaa76 1819 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1820 }
19936277 1821 }
252b5132 1822 }
1b228002 1823 else if (is_rela)
f7a99963 1824 {
7360e63f 1825 bfd_vma off = rels[i].r_addend;
e04d7088
L
1826
1827 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1828 if ((bfd_signed_vma) off < 0)
e04d7088
L
1829 printf ("-%" BFD_VMA_FMT "x", - off);
1830 else
1831 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1832 }
252b5132 1833
dda8d76d 1834 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1835 && rtype != NULL
1836 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1837 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1838
252b5132 1839 putchar ('\n');
2c71103e 1840
aca88567 1841#ifdef BFD64
dda8d76d 1842 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1843 {
91d6fa6a
NC
1844 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1845 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1846 const char * rtype2 = elf_mips_reloc_type (type2);
1847 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1848
2c71103e
NC
1849 printf (" Type2: ");
1850
1851 if (rtype2 == NULL)
39dbeff8
AM
1852 printf (_("unrecognized: %-7lx"),
1853 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1854 else
1855 printf ("%-17.17s", rtype2);
1856
18bd398b 1857 printf ("\n Type3: ");
2c71103e
NC
1858
1859 if (rtype3 == NULL)
39dbeff8
AM
1860 printf (_("unrecognized: %-7lx"),
1861 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1862 else
1863 printf ("%-17.17s", rtype3);
1864
53c7db4b 1865 putchar ('\n');
2c71103e 1866 }
aca88567 1867#endif /* BFD64 */
252b5132
RH
1868 }
1869
c8286bd1 1870 free (rels);
32ec8896
NC
1871
1872 return res;
252b5132
RH
1873}
1874
37c18eed
SD
1875static const char *
1876get_aarch64_dynamic_type (unsigned long type)
1877{
1878 switch (type)
1879 {
1880 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 1881 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 1882 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
1883 default:
1884 return NULL;
1885 }
1886}
1887
252b5132 1888static const char *
d3ba0551 1889get_mips_dynamic_type (unsigned long type)
252b5132
RH
1890{
1891 switch (type)
1892 {
1893 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1894 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1895 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1896 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1897 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1898 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1899 case DT_MIPS_MSYM: return "MIPS_MSYM";
1900 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1901 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1902 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1903 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1904 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1905 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1906 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1907 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1908 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1909 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1910 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1911 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1912 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1913 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1914 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1915 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1916 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1917 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1918 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1919 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1920 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1921 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1922 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1923 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1924 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1925 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1926 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1927 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1928 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1929 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1930 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1931 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1932 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1933 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1934 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1935 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1936 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1937 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1938 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 1939 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
1940 default:
1941 return NULL;
1942 }
1943}
1944
9a097730 1945static const char *
d3ba0551 1946get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1947{
1948 switch (type)
1949 {
1950 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1951 default:
1952 return NULL;
1953 }
103f02d3
UD
1954}
1955
7490d522
AM
1956static const char *
1957get_ppc_dynamic_type (unsigned long type)
1958{
1959 switch (type)
1960 {
a7f2871e 1961 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1962 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1963 default:
1964 return NULL;
1965 }
1966}
1967
f1cb7e17 1968static const char *
d3ba0551 1969get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1970{
1971 switch (type)
1972 {
a7f2871e
AM
1973 case DT_PPC64_GLINK: return "PPC64_GLINK";
1974 case DT_PPC64_OPD: return "PPC64_OPD";
1975 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1976 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1977 default:
1978 return NULL;
1979 }
1980}
1981
103f02d3 1982static const char *
d3ba0551 1983get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1984{
1985 switch (type)
1986 {
1987 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1988 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1989 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1990 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1991 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1992 case DT_HP_PREINIT: return "HP_PREINIT";
1993 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1994 case DT_HP_NEEDED: return "HP_NEEDED";
1995 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1996 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1997 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1998 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1999 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2000 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2001 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2002 case DT_HP_FILTERED: return "HP_FILTERED";
2003 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2004 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2005 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2006 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2007 case DT_PLT: return "PLT";
2008 case DT_PLT_SIZE: return "PLT_SIZE";
2009 case DT_DLT: return "DLT";
2010 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2011 default:
2012 return NULL;
2013 }
2014}
9a097730 2015
ecc51f48 2016static const char *
d3ba0551 2017get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2018{
2019 switch (type)
2020 {
148b93f2
NC
2021 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2022 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2023 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2024 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2025 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2026 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2027 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2028 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2029 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2030 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2031 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2032 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2033 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2034 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2035 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2036 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2037 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2038 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2039 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2040 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2041 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2042 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2043 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2044 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2045 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2046 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2047 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2048 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2049 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2050 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2051 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2052 default:
2053 return NULL;
2054 }
2055}
2056
fd85a6a1
NC
2057static const char *
2058get_solaris_section_type (unsigned long type)
2059{
2060 switch (type)
2061 {
2062 case 0x6fffffee: return "SUNW_ancillary";
2063 case 0x6fffffef: return "SUNW_capchain";
2064 case 0x6ffffff0: return "SUNW_capinfo";
2065 case 0x6ffffff1: return "SUNW_symsort";
2066 case 0x6ffffff2: return "SUNW_tlssort";
2067 case 0x6ffffff3: return "SUNW_LDYNSYM";
2068 case 0x6ffffff4: return "SUNW_dof";
2069 case 0x6ffffff5: return "SUNW_cap";
2070 case 0x6ffffff6: return "SUNW_SIGNATURE";
2071 case 0x6ffffff7: return "SUNW_ANNOTATE";
2072 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2073 case 0x6ffffff9: return "SUNW_DEBUG";
2074 case 0x6ffffffa: return "SUNW_move";
2075 case 0x6ffffffb: return "SUNW_COMDAT";
2076 case 0x6ffffffc: return "SUNW_syminfo";
2077 case 0x6ffffffd: return "SUNW_verdef";
2078 case 0x6ffffffe: return "SUNW_verneed";
2079 case 0x6fffffff: return "SUNW_versym";
2080 case 0x70000000: return "SPARC_GOTDATA";
2081 default: return NULL;
2082 }
2083}
2084
fabcb361
RH
2085static const char *
2086get_alpha_dynamic_type (unsigned long type)
2087{
2088 switch (type)
2089 {
2090 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2091 default: return NULL;
fabcb361
RH
2092 }
2093}
2094
1c0d3aa6
NC
2095static const char *
2096get_score_dynamic_type (unsigned long type)
2097{
2098 switch (type)
2099 {
2100 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2101 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2102 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2103 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2104 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2105 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2106 default: return NULL;
1c0d3aa6
NC
2107 }
2108}
2109
40b36596
JM
2110static const char *
2111get_tic6x_dynamic_type (unsigned long type)
2112{
2113 switch (type)
2114 {
2115 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2116 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2117 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2118 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2119 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2120 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2121 default: return NULL;
40b36596
JM
2122 }
2123}
1c0d3aa6 2124
36591ba1
SL
2125static const char *
2126get_nios2_dynamic_type (unsigned long type)
2127{
2128 switch (type)
2129 {
2130 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2131 default: return NULL;
36591ba1
SL
2132 }
2133}
2134
fd85a6a1
NC
2135static const char *
2136get_solaris_dynamic_type (unsigned long type)
2137{
2138 switch (type)
2139 {
2140 case 0x6000000d: return "SUNW_AUXILIARY";
2141 case 0x6000000e: return "SUNW_RTLDINF";
2142 case 0x6000000f: return "SUNW_FILTER";
2143 case 0x60000010: return "SUNW_CAP";
2144 case 0x60000011: return "SUNW_SYMTAB";
2145 case 0x60000012: return "SUNW_SYMSZ";
2146 case 0x60000013: return "SUNW_SORTENT";
2147 case 0x60000014: return "SUNW_SYMSORT";
2148 case 0x60000015: return "SUNW_SYMSORTSZ";
2149 case 0x60000016: return "SUNW_TLSSORT";
2150 case 0x60000017: return "SUNW_TLSSORTSZ";
2151 case 0x60000018: return "SUNW_CAPINFO";
2152 case 0x60000019: return "SUNW_STRPAD";
2153 case 0x6000001a: return "SUNW_CAPCHAIN";
2154 case 0x6000001b: return "SUNW_LDMACH";
2155 case 0x6000001d: return "SUNW_CAPCHAINENT";
2156 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2157 case 0x60000021: return "SUNW_PARENT";
2158 case 0x60000023: return "SUNW_ASLR";
2159 case 0x60000025: return "SUNW_RELAX";
2160 case 0x60000029: return "SUNW_NXHEAP";
2161 case 0x6000002b: return "SUNW_NXSTACK";
2162
2163 case 0x70000001: return "SPARC_REGISTER";
2164 case 0x7ffffffd: return "AUXILIARY";
2165 case 0x7ffffffe: return "USED";
2166 case 0x7fffffff: return "FILTER";
2167
15f205b1 2168 default: return NULL;
fd85a6a1
NC
2169 }
2170}
2171
252b5132 2172static const char *
dda8d76d 2173get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2174{
e9e44622 2175 static char buff[64];
252b5132
RH
2176
2177 switch (type)
2178 {
2179 case DT_NULL: return "NULL";
2180 case DT_NEEDED: return "NEEDED";
2181 case DT_PLTRELSZ: return "PLTRELSZ";
2182 case DT_PLTGOT: return "PLTGOT";
2183 case DT_HASH: return "HASH";
2184 case DT_STRTAB: return "STRTAB";
2185 case DT_SYMTAB: return "SYMTAB";
2186 case DT_RELA: return "RELA";
2187 case DT_RELASZ: return "RELASZ";
2188 case DT_RELAENT: return "RELAENT";
2189 case DT_STRSZ: return "STRSZ";
2190 case DT_SYMENT: return "SYMENT";
2191 case DT_INIT: return "INIT";
2192 case DT_FINI: return "FINI";
2193 case DT_SONAME: return "SONAME";
2194 case DT_RPATH: return "RPATH";
2195 case DT_SYMBOLIC: return "SYMBOLIC";
2196 case DT_REL: return "REL";
2197 case DT_RELSZ: return "RELSZ";
2198 case DT_RELENT: return "RELENT";
2199 case DT_PLTREL: return "PLTREL";
2200 case DT_DEBUG: return "DEBUG";
2201 case DT_TEXTREL: return "TEXTREL";
2202 case DT_JMPREL: return "JMPREL";
2203 case DT_BIND_NOW: return "BIND_NOW";
2204 case DT_INIT_ARRAY: return "INIT_ARRAY";
2205 case DT_FINI_ARRAY: return "FINI_ARRAY";
2206 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2207 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2208 case DT_RUNPATH: return "RUNPATH";
2209 case DT_FLAGS: return "FLAGS";
2d0e6f43 2210
d1133906
NC
2211 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2212 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2213 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2214
05107a46 2215 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2216 case DT_PLTPADSZ: return "PLTPADSZ";
2217 case DT_MOVEENT: return "MOVEENT";
2218 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2219 case DT_FEATURE: return "FEATURE";
252b5132
RH
2220 case DT_POSFLAG_1: return "POSFLAG_1";
2221 case DT_SYMINSZ: return "SYMINSZ";
2222 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2223
252b5132 2224 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2225 case DT_CONFIG: return "CONFIG";
2226 case DT_DEPAUDIT: return "DEPAUDIT";
2227 case DT_AUDIT: return "AUDIT";
2228 case DT_PLTPAD: return "PLTPAD";
2229 case DT_MOVETAB: return "MOVETAB";
252b5132 2230 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2231
252b5132 2232 case DT_VERSYM: return "VERSYM";
103f02d3 2233
67a4f2b7
AO
2234 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2235 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2236 case DT_RELACOUNT: return "RELACOUNT";
2237 case DT_RELCOUNT: return "RELCOUNT";
2238 case DT_FLAGS_1: return "FLAGS_1";
2239 case DT_VERDEF: return "VERDEF";
2240 case DT_VERDEFNUM: return "VERDEFNUM";
2241 case DT_VERNEED: return "VERNEED";
2242 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2243
019148e4 2244 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2245 case DT_USED: return "USED";
2246 case DT_FILTER: return "FILTER";
103f02d3 2247
047b2264
JJ
2248 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2249 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2250 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2251 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2252 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2253 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2254 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2255
252b5132
RH
2256 default:
2257 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2258 {
2cf0635d 2259 const char * result;
103f02d3 2260
dda8d76d 2261 switch (filedata->file_header.e_machine)
252b5132 2262 {
37c18eed
SD
2263 case EM_AARCH64:
2264 result = get_aarch64_dynamic_type (type);
2265 break;
252b5132 2266 case EM_MIPS:
4fe85591 2267 case EM_MIPS_RS3_LE:
252b5132
RH
2268 result = get_mips_dynamic_type (type);
2269 break;
9a097730
RH
2270 case EM_SPARCV9:
2271 result = get_sparc64_dynamic_type (type);
2272 break;
7490d522
AM
2273 case EM_PPC:
2274 result = get_ppc_dynamic_type (type);
2275 break;
f1cb7e17
AM
2276 case EM_PPC64:
2277 result = get_ppc64_dynamic_type (type);
2278 break;
ecc51f48
NC
2279 case EM_IA_64:
2280 result = get_ia64_dynamic_type (type);
2281 break;
fabcb361
RH
2282 case EM_ALPHA:
2283 result = get_alpha_dynamic_type (type);
2284 break;
1c0d3aa6
NC
2285 case EM_SCORE:
2286 result = get_score_dynamic_type (type);
2287 break;
40b36596
JM
2288 case EM_TI_C6000:
2289 result = get_tic6x_dynamic_type (type);
2290 break;
36591ba1
SL
2291 case EM_ALTERA_NIOS2:
2292 result = get_nios2_dynamic_type (type);
2293 break;
252b5132 2294 default:
dda8d76d 2295 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2296 result = get_solaris_dynamic_type (type);
2297 else
2298 result = NULL;
252b5132
RH
2299 break;
2300 }
2301
2302 if (result != NULL)
2303 return result;
2304
e9e44622 2305 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2306 }
eec8f817 2307 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2308 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2309 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2310 {
2cf0635d 2311 const char * result;
103f02d3 2312
dda8d76d 2313 switch (filedata->file_header.e_machine)
103f02d3
UD
2314 {
2315 case EM_PARISC:
2316 result = get_parisc_dynamic_type (type);
2317 break;
148b93f2
NC
2318 case EM_IA_64:
2319 result = get_ia64_dynamic_type (type);
2320 break;
103f02d3 2321 default:
dda8d76d 2322 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2323 result = get_solaris_dynamic_type (type);
2324 else
2325 result = NULL;
103f02d3
UD
2326 break;
2327 }
2328
2329 if (result != NULL)
2330 return result;
2331
e9e44622
JJ
2332 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2333 type);
103f02d3 2334 }
252b5132 2335 else
e9e44622 2336 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2337
252b5132
RH
2338 return buff;
2339 }
2340}
2341
2342static char *
d3ba0551 2343get_file_type (unsigned e_type)
252b5132 2344{
89246a0e 2345 static char buff[64];
252b5132
RH
2346
2347 switch (e_type)
2348 {
32ec8896
NC
2349 case ET_NONE: return _("NONE (None)");
2350 case ET_REL: return _("REL (Relocatable file)");
2351 case ET_EXEC: return _("EXEC (Executable file)");
2352 case ET_DYN: return _("DYN (Shared object file)");
2353 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2354
2355 default:
2356 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2357 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2358 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2359 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2360 else
e9e44622 2361 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2362 return buff;
2363 }
2364}
2365
2366static char *
d3ba0551 2367get_machine_name (unsigned e_machine)
252b5132 2368{
b34976b6 2369 static char buff[64]; /* XXX */
252b5132
RH
2370
2371 switch (e_machine)
2372 {
55e22ca8
NC
2373 /* Please keep this switch table sorted by increasing EM_ value. */
2374 /* 0 */
c45021f2
NC
2375 case EM_NONE: return _("None");
2376 case EM_M32: return "WE32100";
2377 case EM_SPARC: return "Sparc";
2378 case EM_386: return "Intel 80386";
2379 case EM_68K: return "MC68000";
2380 case EM_88K: return "MC88000";
22abe556 2381 case EM_IAMCU: return "Intel MCU";
fb70ec17 2382 case EM_860: return "Intel 80860";
c45021f2
NC
2383 case EM_MIPS: return "MIPS R3000";
2384 case EM_S370: return "IBM System/370";
55e22ca8 2385 /* 10 */
7036c0e1 2386 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2387 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2388 case EM_PARISC: return "HPPA";
55e22ca8 2389 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2390 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2391 case EM_960: return "Intel 80960";
c45021f2 2392 case EM_PPC: return "PowerPC";
55e22ca8 2393 /* 20 */
285d1771 2394 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2395 case EM_S390_OLD:
2396 case EM_S390: return "IBM S/390";
2397 case EM_SPU: return "SPU";
2398 /* 30 */
2399 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2400 case EM_FR20: return "Fujitsu FR20";
2401 case EM_RH32: return "TRW RH32";
b34976b6 2402 case EM_MCORE: return "MCORE";
55e22ca8 2403 /* 40 */
7036c0e1
AJ
2404 case EM_ARM: return "ARM";
2405 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2406 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2407 case EM_SPARCV9: return "Sparc v9";
2408 case EM_TRICORE: return "Siemens Tricore";
584da044 2409 case EM_ARC: return "ARC";
c2dcd04e
NC
2410 case EM_H8_300: return "Renesas H8/300";
2411 case EM_H8_300H: return "Renesas H8/300H";
2412 case EM_H8S: return "Renesas H8S";
2413 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2414 /* 50 */
30800947 2415 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2416 case EM_MIPS_X: return "Stanford MIPS-X";
2417 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2418 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2419 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2420 case EM_PCP: return "Siemens PCP";
2421 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2422 case EM_NDR1: return "Denso NDR1 microprocesspr";
2423 case EM_STARCORE: return "Motorola Star*Core processor";
2424 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2425 /* 60 */
7036c0e1
AJ
2426 case EM_ST100: return "STMicroelectronics ST100 processor";
2427 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2428 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2429 case EM_PDSP: return "Sony DSP processor";
2430 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2431 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2432 case EM_FX66: return "Siemens FX66 microcontroller";
2433 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2434 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2435 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2436 /* 70 */
7036c0e1
AJ
2437 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2438 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2439 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2440 case EM_SVX: return "Silicon Graphics SVx";
2441 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2442 case EM_VAX: return "Digital VAX";
1b61cf92 2443 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2444 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2445 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2446 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2447 /* 80 */
b34976b6 2448 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2449 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2450 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2451 case EM_AVR_OLD:
2452 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2453 case EM_CYGNUS_FR30:
2454 case EM_FR30: return "Fujitsu FR30";
2455 case EM_CYGNUS_D10V:
2456 case EM_D10V: return "d10v";
2457 case EM_CYGNUS_D30V:
2458 case EM_D30V: return "d30v";
2459 case EM_CYGNUS_V850:
2460 case EM_V850: return "Renesas V850";
2461 case EM_CYGNUS_M32R:
2462 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2463 case EM_CYGNUS_MN10300:
2464 case EM_MN10300: return "mn10300";
2465 /* 90 */
2466 case EM_CYGNUS_MN10200:
2467 case EM_MN10200: return "mn10200";
2468 case EM_PJ: return "picoJava";
73589c9d 2469 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2470 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2471 case EM_XTENSA_OLD:
2472 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2473 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2474 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2475 case EM_NS32K: return "National Semiconductor 32000 series";
2476 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2477 case EM_SNP1K: return "Trebia SNP 1000 processor";
2478 /* 100 */
9abca702 2479 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2480 case EM_IP2K_OLD:
2481 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2482 case EM_MAX: return "MAX Processor";
2483 case EM_CR: return "National Semiconductor CompactRISC";
2484 case EM_F2MC16: return "Fujitsu F2MC16";
2485 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2486 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2487 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2488 case EM_SEP: return "Sharp embedded microprocessor";
2489 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2490 /* 110 */
11636f9e
JM
2491 case EM_UNICORE: return "Unicore";
2492 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2493 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2494 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2495 case EM_CRX: return "National Semiconductor CRX microprocessor";
2496 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2497 case EM_C166:
d70c5fc7 2498 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2499 case EM_M16C: return "Renesas M16C series microprocessors";
2500 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2501 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2502 /* 120 */
2503 case EM_M32C: return "Renesas M32c";
2504 /* 130 */
11636f9e
JM
2505 case EM_TSK3000: return "Altium TSK3000 core";
2506 case EM_RS08: return "Freescale RS08 embedded processor";
2507 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2508 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2509 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2510 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2511 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2512 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2513 /* 140 */
11636f9e
JM
2514 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2515 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2516 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2517 case EM_TI_PRU: return "TI PRU I/O processor";
2518 /* 160 */
11636f9e
JM
2519 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2520 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2521 case EM_R32C: return "Renesas R32C series microprocessors";
2522 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2523 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2524 case EM_8051: return "Intel 8051 and variants";
2525 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2526 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2527 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2528 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2529 /* 170 */
11636f9e
JM
2530 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2531 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2532 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2533 case EM_RX: return "Renesas RX";
a3c62988 2534 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2535 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2536 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2537 case EM_CR16:
2538 case EM_MICROBLAZE:
2539 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2540 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2541 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2542 /* 180 */
2543 case EM_L1OM: return "Intel L1OM";
2544 case EM_K1OM: return "Intel K1OM";
2545 case EM_INTEL182: return "Intel (reserved)";
2546 case EM_AARCH64: return "AArch64";
2547 case EM_ARM184: return "ARM (reserved)";
2548 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2549 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2550 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2551 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2552 /* 190 */
11636f9e 2553 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2554 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2555 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2556 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2557 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2558 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2559 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2560 case EM_RL78: return "Renesas RL78";
6d913794 2561 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2562 case EM_78K0R: return "Renesas 78K0R";
2563 /* 200 */
6d913794 2564 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2565 case EM_BA1: return "Beyond BA1 CPU architecture";
2566 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2567 case EM_XCORE: return "XMOS xCORE processor family";
2568 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2569 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2570 /* 210 */
6d913794
NC
2571 case EM_KM32: return "KM211 KM32 32-bit processor";
2572 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2573 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2574 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2575 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2576 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2577 case EM_COGE: return "Cognitive Smart Memory Processor";
2578 case EM_COOL: return "Bluechip Systems CoolEngine";
2579 case EM_NORC: return "Nanoradio Optimized RISC";
2580 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2581 /* 220 */
15f205b1 2582 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2583 case EM_VISIUM: return "CDS VISIUMcore processor";
2584 case EM_FT32: return "FTDI Chip FT32";
2585 case EM_MOXIE: return "Moxie";
2586 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2587 /* 230 (all reserved) */
2588 /* 240 */
55e22ca8
NC
2589 case EM_RISCV: return "RISC-V";
2590 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2591 case EM_CEVA: return "CEVA Processor Architecture Family";
2592 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2593 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2594 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2595 case EM_IMG1: return "Imagination Technologies";
2596 /* 250 */
fe944acf 2597 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2598 case EM_VE: return "NEC Vector Engine";
2599 case EM_CSKY: return "C-SKY";
2600 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2601 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2602 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2603 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2604 case EM_65816: return "WDC 65816/65C816";
01a8c731 2605 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2606 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2607
2608 /* Large numbers... */
2609 case EM_MT: return "Morpho Techologies MT processor";
2610 case EM_ALPHA: return "Alpha";
2611 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2612 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2613 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2614 case EM_IQ2000: return "Vitesse IQ2000";
2615 case EM_M32C_OLD:
2616 case EM_NIOS32: return "Altera Nios";
2617 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2618 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2619 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2620 case EM_S12Z: return "Freescale S12Z";
55e22ca8 2621
252b5132 2622 default:
35d9dd2f 2623 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2624 return buff;
2625 }
2626}
2627
a9522a21
AB
2628static void
2629decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2630{
2631 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 2632 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
2633 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2634 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2635 architectures.
2636
2637 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2638 but also sets a specific architecture type in the e_flags field.
2639
2640 However, when decoding the flags we don't worry if we see an
2641 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2642 ARCEM architecture type. */
2643
2644 switch (e_flags & EF_ARC_MACH_MSK)
2645 {
2646 /* We only expect these to occur for EM_ARC_COMPACT2. */
2647 case EF_ARC_CPU_ARCV2EM:
2648 strcat (buf, ", ARC EM");
2649 break;
2650 case EF_ARC_CPU_ARCV2HS:
2651 strcat (buf, ", ARC HS");
2652 break;
2653
2654 /* We only expect these to occur for EM_ARC_COMPACT. */
2655 case E_ARC_MACH_ARC600:
2656 strcat (buf, ", ARC600");
2657 break;
2658 case E_ARC_MACH_ARC601:
2659 strcat (buf, ", ARC601");
2660 break;
2661 case E_ARC_MACH_ARC700:
2662 strcat (buf, ", ARC700");
2663 break;
2664
2665 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2666 new ELF with new architecture being read by an old version of
2667 readelf, or (c) An ELF built with non-GNU compiler that does not
2668 set the architecture in the e_flags. */
2669 default:
2670 if (e_machine == EM_ARC_COMPACT)
2671 strcat (buf, ", Unknown ARCompact");
2672 else
2673 strcat (buf, ", Unknown ARC");
2674 break;
2675 }
2676
2677 switch (e_flags & EF_ARC_OSABI_MSK)
2678 {
2679 case E_ARC_OSABI_ORIG:
2680 strcat (buf, ", (ABI:legacy)");
2681 break;
2682 case E_ARC_OSABI_V2:
2683 strcat (buf, ", (ABI:v2)");
2684 break;
2685 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2686 case E_ARC_OSABI_V3:
2687 strcat (buf, ", v3 no-legacy-syscalls ABI");
2688 break;
53a346d8
CZ
2689 case E_ARC_OSABI_V4:
2690 strcat (buf, ", v4 ABI");
2691 break;
a9522a21
AB
2692 default:
2693 strcat (buf, ", unrecognised ARC OSABI flag");
2694 break;
2695 }
2696}
2697
f3485b74 2698static void
d3ba0551 2699decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2700{
2701 unsigned eabi;
015dc7e1 2702 bool unknown = false;
f3485b74
NC
2703
2704 eabi = EF_ARM_EABI_VERSION (e_flags);
2705 e_flags &= ~ EF_ARM_EABIMASK;
2706
2707 /* Handle "generic" ARM flags. */
2708 if (e_flags & EF_ARM_RELEXEC)
2709 {
2710 strcat (buf, ", relocatable executable");
2711 e_flags &= ~ EF_ARM_RELEXEC;
2712 }
76da6bbe 2713
18a20338
CL
2714 if (e_flags & EF_ARM_PIC)
2715 {
2716 strcat (buf, ", position independent");
2717 e_flags &= ~ EF_ARM_PIC;
2718 }
2719
f3485b74
NC
2720 /* Now handle EABI specific flags. */
2721 switch (eabi)
2722 {
2723 default:
2c71103e 2724 strcat (buf, ", <unrecognized EABI>");
f3485b74 2725 if (e_flags)
015dc7e1 2726 unknown = true;
f3485b74
NC
2727 break;
2728
2729 case EF_ARM_EABI_VER1:
a5bcd848 2730 strcat (buf, ", Version1 EABI");
f3485b74
NC
2731 while (e_flags)
2732 {
2733 unsigned flag;
76da6bbe 2734
f3485b74
NC
2735 /* Process flags one bit at a time. */
2736 flag = e_flags & - e_flags;
2737 e_flags &= ~ flag;
76da6bbe 2738
f3485b74
NC
2739 switch (flag)
2740 {
a5bcd848 2741 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2742 strcat (buf, ", sorted symbol tables");
2743 break;
76da6bbe 2744
f3485b74 2745 default:
015dc7e1 2746 unknown = true;
f3485b74
NC
2747 break;
2748 }
2749 }
2750 break;
76da6bbe 2751
a5bcd848
PB
2752 case EF_ARM_EABI_VER2:
2753 strcat (buf, ", Version2 EABI");
2754 while (e_flags)
2755 {
2756 unsigned flag;
2757
2758 /* Process flags one bit at a time. */
2759 flag = e_flags & - e_flags;
2760 e_flags &= ~ flag;
2761
2762 switch (flag)
2763 {
2764 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2765 strcat (buf, ", sorted symbol tables");
2766 break;
2767
2768 case EF_ARM_DYNSYMSUSESEGIDX:
2769 strcat (buf, ", dynamic symbols use segment index");
2770 break;
2771
2772 case EF_ARM_MAPSYMSFIRST:
2773 strcat (buf, ", mapping symbols precede others");
2774 break;
2775
2776 default:
015dc7e1 2777 unknown = true;
a5bcd848
PB
2778 break;
2779 }
2780 }
2781 break;
2782
d507cf36
PB
2783 case EF_ARM_EABI_VER3:
2784 strcat (buf, ", Version3 EABI");
8cb51566
PB
2785 break;
2786
2787 case EF_ARM_EABI_VER4:
2788 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2789 while (e_flags)
2790 {
2791 unsigned flag;
2792
2793 /* Process flags one bit at a time. */
2794 flag = e_flags & - e_flags;
2795 e_flags &= ~ flag;
2796
2797 switch (flag)
2798 {
2799 case EF_ARM_BE8:
2800 strcat (buf, ", BE8");
2801 break;
2802
2803 case EF_ARM_LE8:
2804 strcat (buf, ", LE8");
2805 break;
2806
2807 default:
015dc7e1 2808 unknown = true;
3bfcb652
NC
2809 break;
2810 }
3bfcb652
NC
2811 }
2812 break;
3a4a14e9
PB
2813
2814 case EF_ARM_EABI_VER5:
2815 strcat (buf, ", Version5 EABI");
d507cf36
PB
2816 while (e_flags)
2817 {
2818 unsigned flag;
2819
2820 /* Process flags one bit at a time. */
2821 flag = e_flags & - e_flags;
2822 e_flags &= ~ flag;
2823
2824 switch (flag)
2825 {
2826 case EF_ARM_BE8:
2827 strcat (buf, ", BE8");
2828 break;
2829
2830 case EF_ARM_LE8:
2831 strcat (buf, ", LE8");
2832 break;
2833
3bfcb652
NC
2834 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2835 strcat (buf, ", soft-float ABI");
2836 break;
2837
2838 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2839 strcat (buf, ", hard-float ABI");
2840 break;
2841
d507cf36 2842 default:
015dc7e1 2843 unknown = true;
d507cf36
PB
2844 break;
2845 }
2846 }
2847 break;
2848
f3485b74 2849 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2850 strcat (buf, ", GNU EABI");
f3485b74
NC
2851 while (e_flags)
2852 {
2853 unsigned flag;
76da6bbe 2854
f3485b74
NC
2855 /* Process flags one bit at a time. */
2856 flag = e_flags & - e_flags;
2857 e_flags &= ~ flag;
76da6bbe 2858
f3485b74
NC
2859 switch (flag)
2860 {
a5bcd848 2861 case EF_ARM_INTERWORK:
f3485b74
NC
2862 strcat (buf, ", interworking enabled");
2863 break;
76da6bbe 2864
a5bcd848 2865 case EF_ARM_APCS_26:
f3485b74
NC
2866 strcat (buf, ", uses APCS/26");
2867 break;
76da6bbe 2868
a5bcd848 2869 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2870 strcat (buf, ", uses APCS/float");
2871 break;
76da6bbe 2872
a5bcd848 2873 case EF_ARM_PIC:
f3485b74
NC
2874 strcat (buf, ", position independent");
2875 break;
76da6bbe 2876
a5bcd848 2877 case EF_ARM_ALIGN8:
f3485b74
NC
2878 strcat (buf, ", 8 bit structure alignment");
2879 break;
76da6bbe 2880
a5bcd848 2881 case EF_ARM_NEW_ABI:
f3485b74
NC
2882 strcat (buf, ", uses new ABI");
2883 break;
76da6bbe 2884
a5bcd848 2885 case EF_ARM_OLD_ABI:
f3485b74
NC
2886 strcat (buf, ", uses old ABI");
2887 break;
76da6bbe 2888
a5bcd848 2889 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2890 strcat (buf, ", software FP");
2891 break;
76da6bbe 2892
90e01f86
ILT
2893 case EF_ARM_VFP_FLOAT:
2894 strcat (buf, ", VFP");
2895 break;
2896
fde78edd
NC
2897 case EF_ARM_MAVERICK_FLOAT:
2898 strcat (buf, ", Maverick FP");
2899 break;
2900
f3485b74 2901 default:
015dc7e1 2902 unknown = true;
f3485b74
NC
2903 break;
2904 }
2905 }
2906 }
f3485b74
NC
2907
2908 if (unknown)
2b692964 2909 strcat (buf,_(", <unknown>"));
f3485b74
NC
2910}
2911
343433df
AB
2912static void
2913decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2914{
2915 --size; /* Leave space for null terminator. */
2916
2917 switch (e_flags & EF_AVR_MACH)
2918 {
2919 case E_AVR_MACH_AVR1:
2920 strncat (buf, ", avr:1", size);
2921 break;
2922 case E_AVR_MACH_AVR2:
2923 strncat (buf, ", avr:2", size);
2924 break;
2925 case E_AVR_MACH_AVR25:
2926 strncat (buf, ", avr:25", size);
2927 break;
2928 case E_AVR_MACH_AVR3:
2929 strncat (buf, ", avr:3", size);
2930 break;
2931 case E_AVR_MACH_AVR31:
2932 strncat (buf, ", avr:31", size);
2933 break;
2934 case E_AVR_MACH_AVR35:
2935 strncat (buf, ", avr:35", size);
2936 break;
2937 case E_AVR_MACH_AVR4:
2938 strncat (buf, ", avr:4", size);
2939 break;
2940 case E_AVR_MACH_AVR5:
2941 strncat (buf, ", avr:5", size);
2942 break;
2943 case E_AVR_MACH_AVR51:
2944 strncat (buf, ", avr:51", size);
2945 break;
2946 case E_AVR_MACH_AVR6:
2947 strncat (buf, ", avr:6", size);
2948 break;
2949 case E_AVR_MACH_AVRTINY:
2950 strncat (buf, ", avr:100", size);
2951 break;
2952 case E_AVR_MACH_XMEGA1:
2953 strncat (buf, ", avr:101", size);
2954 break;
2955 case E_AVR_MACH_XMEGA2:
2956 strncat (buf, ", avr:102", size);
2957 break;
2958 case E_AVR_MACH_XMEGA3:
2959 strncat (buf, ", avr:103", size);
2960 break;
2961 case E_AVR_MACH_XMEGA4:
2962 strncat (buf, ", avr:104", size);
2963 break;
2964 case E_AVR_MACH_XMEGA5:
2965 strncat (buf, ", avr:105", size);
2966 break;
2967 case E_AVR_MACH_XMEGA6:
2968 strncat (buf, ", avr:106", size);
2969 break;
2970 case E_AVR_MACH_XMEGA7:
2971 strncat (buf, ", avr:107", size);
2972 break;
2973 default:
2974 strncat (buf, ", avr:<unknown>", size);
2975 break;
2976 }
2977
2978 size -= strlen (buf);
2979 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2980 strncat (buf, ", link-relax", size);
2981}
2982
35c08157
KLC
2983static void
2984decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2985{
2986 unsigned abi;
2987 unsigned arch;
2988 unsigned config;
2989 unsigned version;
015dc7e1 2990 bool has_fpu = false;
32ec8896 2991 unsigned int r = 0;
35c08157
KLC
2992
2993 static const char *ABI_STRINGS[] =
2994 {
2995 "ABI v0", /* use r5 as return register; only used in N1213HC */
2996 "ABI v1", /* use r0 as return register */
2997 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2998 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2999 "AABI",
3000 "ABI2 FP+"
35c08157
KLC
3001 };
3002 static const char *VER_STRINGS[] =
3003 {
3004 "Andes ELF V1.3 or older",
3005 "Andes ELF V1.3.1",
3006 "Andes ELF V1.4"
3007 };
3008 static const char *ARCH_STRINGS[] =
3009 {
3010 "",
3011 "Andes Star v1.0",
3012 "Andes Star v2.0",
3013 "Andes Star v3.0",
3014 "Andes Star v3.0m"
3015 };
3016
3017 abi = EF_NDS_ABI & e_flags;
3018 arch = EF_NDS_ARCH & e_flags;
3019 config = EF_NDS_INST & e_flags;
3020 version = EF_NDS32_ELF_VERSION & e_flags;
3021
3022 memset (buf, 0, size);
3023
3024 switch (abi)
3025 {
3026 case E_NDS_ABI_V0:
3027 case E_NDS_ABI_V1:
3028 case E_NDS_ABI_V2:
3029 case E_NDS_ABI_V2FP:
3030 case E_NDS_ABI_AABI:
40c7a7cb 3031 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3032 /* In case there are holes in the array. */
3033 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3034 break;
3035
3036 default:
3037 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3038 break;
3039 }
3040
3041 switch (version)
3042 {
3043 case E_NDS32_ELF_VER_1_2:
3044 case E_NDS32_ELF_VER_1_3:
3045 case E_NDS32_ELF_VER_1_4:
3046 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3047 break;
3048
3049 default:
3050 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3051 break;
3052 }
3053
3054 if (E_NDS_ABI_V0 == abi)
3055 {
3056 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3057 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3058 if (arch == E_NDS_ARCH_STAR_V1_0)
3059 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3060 return;
3061 }
3062
3063 switch (arch)
3064 {
3065 case E_NDS_ARCH_STAR_V1_0:
3066 case E_NDS_ARCH_STAR_V2_0:
3067 case E_NDS_ARCH_STAR_V3_0:
3068 case E_NDS_ARCH_STAR_V3_M:
3069 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3070 break;
3071
3072 default:
3073 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3074 /* ARCH version determines how the e_flags are interpreted.
3075 If it is unknown, we cannot proceed. */
3076 return;
3077 }
3078
3079 /* Newer ABI; Now handle architecture specific flags. */
3080 if (arch == E_NDS_ARCH_STAR_V1_0)
3081 {
3082 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3083 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3084
3085 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3086 r += snprintf (buf + r, size -r, ", MAC");
3087
3088 if (config & E_NDS32_HAS_DIV_INST)
3089 r += snprintf (buf + r, size -r, ", DIV");
3090
3091 if (config & E_NDS32_HAS_16BIT_INST)
3092 r += snprintf (buf + r, size -r, ", 16b");
3093 }
3094 else
3095 {
3096 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3097 {
3098 if (version <= E_NDS32_ELF_VER_1_3)
3099 r += snprintf (buf + r, size -r, ", [B8]");
3100 else
3101 r += snprintf (buf + r, size -r, ", EX9");
3102 }
3103
3104 if (config & E_NDS32_HAS_MAC_DX_INST)
3105 r += snprintf (buf + r, size -r, ", MAC_DX");
3106
3107 if (config & E_NDS32_HAS_DIV_DX_INST)
3108 r += snprintf (buf + r, size -r, ", DIV_DX");
3109
3110 if (config & E_NDS32_HAS_16BIT_INST)
3111 {
3112 if (version <= E_NDS32_ELF_VER_1_3)
3113 r += snprintf (buf + r, size -r, ", 16b");
3114 else
3115 r += snprintf (buf + r, size -r, ", IFC");
3116 }
3117 }
3118
3119 if (config & E_NDS32_HAS_EXT_INST)
3120 r += snprintf (buf + r, size -r, ", PERF1");
3121
3122 if (config & E_NDS32_HAS_EXT2_INST)
3123 r += snprintf (buf + r, size -r, ", PERF2");
3124
3125 if (config & E_NDS32_HAS_FPU_INST)
3126 {
015dc7e1 3127 has_fpu = true;
35c08157
KLC
3128 r += snprintf (buf + r, size -r, ", FPU_SP");
3129 }
3130
3131 if (config & E_NDS32_HAS_FPU_DP_INST)
3132 {
015dc7e1 3133 has_fpu = true;
35c08157
KLC
3134 r += snprintf (buf + r, size -r, ", FPU_DP");
3135 }
3136
3137 if (config & E_NDS32_HAS_FPU_MAC_INST)
3138 {
015dc7e1 3139 has_fpu = true;
35c08157
KLC
3140 r += snprintf (buf + r, size -r, ", FPU_MAC");
3141 }
3142
3143 if (has_fpu)
3144 {
3145 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3146 {
3147 case E_NDS32_FPU_REG_8SP_4DP:
3148 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3149 break;
3150 case E_NDS32_FPU_REG_16SP_8DP:
3151 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3152 break;
3153 case E_NDS32_FPU_REG_32SP_16DP:
3154 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3155 break;
3156 case E_NDS32_FPU_REG_32SP_32DP:
3157 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3158 break;
3159 }
3160 }
3161
3162 if (config & E_NDS32_HAS_AUDIO_INST)
3163 r += snprintf (buf + r, size -r, ", AUDIO");
3164
3165 if (config & E_NDS32_HAS_STRING_INST)
3166 r += snprintf (buf + r, size -r, ", STR");
3167
3168 if (config & E_NDS32_HAS_REDUCED_REGS)
3169 r += snprintf (buf + r, size -r, ", 16REG");
3170
3171 if (config & E_NDS32_HAS_VIDEO_INST)
3172 {
3173 if (version <= E_NDS32_ELF_VER_1_3)
3174 r += snprintf (buf + r, size -r, ", VIDEO");
3175 else
3176 r += snprintf (buf + r, size -r, ", SATURATION");
3177 }
3178
3179 if (config & E_NDS32_HAS_ENCRIPT_INST)
3180 r += snprintf (buf + r, size -r, ", ENCRP");
3181
3182 if (config & E_NDS32_HAS_L2C_INST)
3183 r += snprintf (buf + r, size -r, ", L2C");
3184}
3185
252b5132 3186static char *
dda8d76d 3187get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3188{
b34976b6 3189 static char buf[1024];
252b5132
RH
3190
3191 buf[0] = '\0';
76da6bbe 3192
252b5132
RH
3193 if (e_flags)
3194 {
3195 switch (e_machine)
3196 {
3197 default:
3198 break;
3199
886a2506 3200 case EM_ARC_COMPACT2:
886a2506 3201 case EM_ARC_COMPACT:
a9522a21
AB
3202 decode_ARC_machine_flags (e_flags, e_machine, buf);
3203 break;
886a2506 3204
f3485b74
NC
3205 case EM_ARM:
3206 decode_ARM_machine_flags (e_flags, buf);
3207 break;
76da6bbe 3208
343433df
AB
3209 case EM_AVR:
3210 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3211 break;
3212
781303ce
MF
3213 case EM_BLACKFIN:
3214 if (e_flags & EF_BFIN_PIC)
3215 strcat (buf, ", PIC");
3216
3217 if (e_flags & EF_BFIN_FDPIC)
3218 strcat (buf, ", FDPIC");
3219
3220 if (e_flags & EF_BFIN_CODE_IN_L1)
3221 strcat (buf, ", code in L1");
3222
3223 if (e_flags & EF_BFIN_DATA_IN_L1)
3224 strcat (buf, ", data in L1");
3225
3226 break;
3227
ec2dfb42
AO
3228 case EM_CYGNUS_FRV:
3229 switch (e_flags & EF_FRV_CPU_MASK)
3230 {
3231 case EF_FRV_CPU_GENERIC:
3232 break;
3233
3234 default:
3235 strcat (buf, ", fr???");
3236 break;
57346661 3237
ec2dfb42
AO
3238 case EF_FRV_CPU_FR300:
3239 strcat (buf, ", fr300");
3240 break;
3241
3242 case EF_FRV_CPU_FR400:
3243 strcat (buf, ", fr400");
3244 break;
3245 case EF_FRV_CPU_FR405:
3246 strcat (buf, ", fr405");
3247 break;
3248
3249 case EF_FRV_CPU_FR450:
3250 strcat (buf, ", fr450");
3251 break;
3252
3253 case EF_FRV_CPU_FR500:
3254 strcat (buf, ", fr500");
3255 break;
3256 case EF_FRV_CPU_FR550:
3257 strcat (buf, ", fr550");
3258 break;
3259
3260 case EF_FRV_CPU_SIMPLE:
3261 strcat (buf, ", simple");
3262 break;
3263 case EF_FRV_CPU_TOMCAT:
3264 strcat (buf, ", tomcat");
3265 break;
3266 }
1c877e87 3267 break;
ec2dfb42 3268
53c7db4b 3269 case EM_68K:
425c6cb0 3270 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3271 strcat (buf, ", m68000");
425c6cb0 3272 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3273 strcat (buf, ", cpu32");
3274 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3275 strcat (buf, ", fido_a");
425c6cb0 3276 else
266abb8f 3277 {
2cf0635d
NC
3278 char const * isa = _("unknown");
3279 char const * mac = _("unknown mac");
3280 char const * additional = NULL;
0112cd26 3281
c694fd50 3282 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3283 {
c694fd50 3284 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3285 isa = "A";
3286 additional = ", nodiv";
3287 break;
c694fd50 3288 case EF_M68K_CF_ISA_A:
266abb8f
NS
3289 isa = "A";
3290 break;
c694fd50 3291 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3292 isa = "A+";
3293 break;
c694fd50 3294 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3295 isa = "B";
3296 additional = ", nousp";
3297 break;
c694fd50 3298 case EF_M68K_CF_ISA_B:
266abb8f
NS
3299 isa = "B";
3300 break;
f608cd77
NS
3301 case EF_M68K_CF_ISA_C:
3302 isa = "C";
3303 break;
3304 case EF_M68K_CF_ISA_C_NODIV:
3305 isa = "C";
3306 additional = ", nodiv";
3307 break;
266abb8f
NS
3308 }
3309 strcat (buf, ", cf, isa ");
3310 strcat (buf, isa);
0b2e31dc
NS
3311 if (additional)
3312 strcat (buf, additional);
c694fd50 3313 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3314 strcat (buf, ", float");
c694fd50 3315 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3316 {
3317 case 0:
3318 mac = NULL;
3319 break;
c694fd50 3320 case EF_M68K_CF_MAC:
266abb8f
NS
3321 mac = "mac";
3322 break;
c694fd50 3323 case EF_M68K_CF_EMAC:
266abb8f
NS
3324 mac = "emac";
3325 break;
f608cd77
NS
3326 case EF_M68K_CF_EMAC_B:
3327 mac = "emac_b";
3328 break;
266abb8f
NS
3329 }
3330 if (mac)
3331 {
3332 strcat (buf, ", ");
3333 strcat (buf, mac);
3334 }
266abb8f 3335 }
53c7db4b 3336 break;
33c63f9d 3337
153a2776
NC
3338 case EM_CYGNUS_MEP:
3339 switch (e_flags & EF_MEP_CPU_MASK)
3340 {
3341 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3342 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3343 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3344 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3345 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3346 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3347 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3348 }
3349
3350 switch (e_flags & EF_MEP_COP_MASK)
3351 {
3352 case EF_MEP_COP_NONE: break;
3353 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3354 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3355 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3356 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3357 default: strcat (buf, _("<unknown MeP copro type>")); break;
3358 }
3359
3360 if (e_flags & EF_MEP_LIBRARY)
3361 strcat (buf, ", Built for Library");
3362
3363 if (e_flags & EF_MEP_INDEX_MASK)
3364 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3365 e_flags & EF_MEP_INDEX_MASK);
3366
3367 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3368 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3369 e_flags & ~ EF_MEP_ALL_FLAGS);
3370 break;
3371
252b5132
RH
3372 case EM_PPC:
3373 if (e_flags & EF_PPC_EMB)
3374 strcat (buf, ", emb");
3375
3376 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3377 strcat (buf, _(", relocatable"));
252b5132
RH
3378
3379 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3380 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3381 break;
3382
ee67d69a
AM
3383 case EM_PPC64:
3384 if (e_flags & EF_PPC64_ABI)
3385 {
3386 char abi[] = ", abiv0";
3387
3388 abi[6] += e_flags & EF_PPC64_ABI;
3389 strcat (buf, abi);
3390 }
3391 break;
3392
708e2187
NC
3393 case EM_V800:
3394 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3395 strcat (buf, ", RH850 ABI");
0b4362b0 3396
708e2187
NC
3397 if (e_flags & EF_V800_850E3)
3398 strcat (buf, ", V3 architecture");
3399
3400 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3401 strcat (buf, ", FPU not used");
3402
3403 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3404 strcat (buf, ", regmode: COMMON");
3405
3406 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3407 strcat (buf, ", r4 not used");
3408
3409 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3410 strcat (buf, ", r30 not used");
3411
3412 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3413 strcat (buf, ", r5 not used");
3414
3415 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3416 strcat (buf, ", r2 not used");
3417
3418 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3419 {
3420 switch (e_flags & - e_flags)
3421 {
3422 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3423 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3424 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3425 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3426 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3427 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3428 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3429 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3430 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3431 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3432 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3433 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3434 default: break;
3435 }
3436 }
3437 break;
3438
2b0337b0 3439 case EM_V850:
252b5132
RH
3440 case EM_CYGNUS_V850:
3441 switch (e_flags & EF_V850_ARCH)
3442 {
78c8d46c
NC
3443 case E_V850E3V5_ARCH:
3444 strcat (buf, ", v850e3v5");
3445 break;
1cd986c5
NC
3446 case E_V850E2V3_ARCH:
3447 strcat (buf, ", v850e2v3");
3448 break;
3449 case E_V850E2_ARCH:
3450 strcat (buf, ", v850e2");
3451 break;
3452 case E_V850E1_ARCH:
3453 strcat (buf, ", v850e1");
8ad30312 3454 break;
252b5132
RH
3455 case E_V850E_ARCH:
3456 strcat (buf, ", v850e");
3457 break;
252b5132
RH
3458 case E_V850_ARCH:
3459 strcat (buf, ", v850");
3460 break;
3461 default:
2b692964 3462 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3463 break;
3464 }
3465 break;
3466
2b0337b0 3467 case EM_M32R:
252b5132
RH
3468 case EM_CYGNUS_M32R:
3469 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3470 strcat (buf, ", m32r");
252b5132
RH
3471 break;
3472
3473 case EM_MIPS:
4fe85591 3474 case EM_MIPS_RS3_LE:
252b5132
RH
3475 if (e_flags & EF_MIPS_NOREORDER)
3476 strcat (buf, ", noreorder");
3477
3478 if (e_flags & EF_MIPS_PIC)
3479 strcat (buf, ", pic");
3480
3481 if (e_flags & EF_MIPS_CPIC)
3482 strcat (buf, ", cpic");
3483
d1bdd336
TS
3484 if (e_flags & EF_MIPS_UCODE)
3485 strcat (buf, ", ugen_reserved");
3486
252b5132
RH
3487 if (e_flags & EF_MIPS_ABI2)
3488 strcat (buf, ", abi2");
3489
43521d43
TS
3490 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3491 strcat (buf, ", odk first");
3492
a5d22d2a
TS
3493 if (e_flags & EF_MIPS_32BITMODE)
3494 strcat (buf, ", 32bitmode");
3495
ba92f887
MR
3496 if (e_flags & EF_MIPS_NAN2008)
3497 strcat (buf, ", nan2008");
3498
fef1b0b3
SE
3499 if (e_flags & EF_MIPS_FP64)
3500 strcat (buf, ", fp64");
3501
156c2f8b
NC
3502 switch ((e_flags & EF_MIPS_MACH))
3503 {
3504 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3505 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3506 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3507 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3508 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3509 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3510 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3511 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3512 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3513 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3514 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3515 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3516 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3517 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3518 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3519 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3520 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3521 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3522 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3523 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3524 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3525 case 0:
3526 /* We simply ignore the field in this case to avoid confusion:
3527 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3528 extension. */
3529 break;
2b692964 3530 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3531 }
43521d43
TS
3532
3533 switch ((e_flags & EF_MIPS_ABI))
3534 {
3535 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3536 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3537 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3538 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3539 case 0:
3540 /* We simply ignore the field in this case to avoid confusion:
3541 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3542 This means it is likely to be an o32 file, but not for
3543 sure. */
3544 break;
2b692964 3545 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3546 }
3547
3548 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3549 strcat (buf, ", mdmx");
3550
3551 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3552 strcat (buf, ", mips16");
3553
df58fc94
RS
3554 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3555 strcat (buf, ", micromips");
3556
43521d43
TS
3557 switch ((e_flags & EF_MIPS_ARCH))
3558 {
3559 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3560 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3561 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3562 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3563 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3564 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3565 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3566 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3567 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3568 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3569 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3570 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3571 }
252b5132 3572 break;
351b4b40 3573
35c08157
KLC
3574 case EM_NDS32:
3575 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3576 break;
3577
fe944acf
FT
3578 case EM_NFP:
3579 switch (EF_NFP_MACH (e_flags))
3580 {
3581 case E_NFP_MACH_3200:
3582 strcat (buf, ", NFP-32xx");
3583 break;
3584 case E_NFP_MACH_6000:
3585 strcat (buf, ", NFP-6xxx");
3586 break;
3587 }
3588 break;
3589
e23eba97
NC
3590 case EM_RISCV:
3591 if (e_flags & EF_RISCV_RVC)
3592 strcat (buf, ", RVC");
2922d21d 3593
7f999549
JW
3594 if (e_flags & EF_RISCV_RVE)
3595 strcat (buf, ", RVE");
3596
2922d21d
AW
3597 switch (e_flags & EF_RISCV_FLOAT_ABI)
3598 {
3599 case EF_RISCV_FLOAT_ABI_SOFT:
3600 strcat (buf, ", soft-float ABI");
3601 break;
3602
3603 case EF_RISCV_FLOAT_ABI_SINGLE:
3604 strcat (buf, ", single-float ABI");
3605 break;
3606
3607 case EF_RISCV_FLOAT_ABI_DOUBLE:
3608 strcat (buf, ", double-float ABI");
3609 break;
3610
3611 case EF_RISCV_FLOAT_ABI_QUAD:
3612 strcat (buf, ", quad-float ABI");
3613 break;
3614 }
e23eba97
NC
3615 break;
3616
ccde1100
AO
3617 case EM_SH:
3618 switch ((e_flags & EF_SH_MACH_MASK))
3619 {
3620 case EF_SH1: strcat (buf, ", sh1"); break;
3621 case EF_SH2: strcat (buf, ", sh2"); break;
3622 case EF_SH3: strcat (buf, ", sh3"); break;
3623 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3624 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3625 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3626 case EF_SH3E: strcat (buf, ", sh3e"); break;
3627 case EF_SH4: strcat (buf, ", sh4"); break;
3628 case EF_SH5: strcat (buf, ", sh5"); break;
3629 case EF_SH2E: strcat (buf, ", sh2e"); break;
3630 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3631 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3632 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3633 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3634 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3635 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3636 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3637 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3638 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3639 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3640 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3641 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3642 }
3643
cec6a5b8
MR
3644 if (e_flags & EF_SH_PIC)
3645 strcat (buf, ", pic");
3646
3647 if (e_flags & EF_SH_FDPIC)
3648 strcat (buf, ", fdpic");
ccde1100 3649 break;
948f632f 3650
73589c9d
CS
3651 case EM_OR1K:
3652 if (e_flags & EF_OR1K_NODELAY)
3653 strcat (buf, ", no delay");
3654 break;
57346661 3655
351b4b40
RH
3656 case EM_SPARCV9:
3657 if (e_flags & EF_SPARC_32PLUS)
3658 strcat (buf, ", v8+");
3659
3660 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3661 strcat (buf, ", ultrasparcI");
3662
3663 if (e_flags & EF_SPARC_SUN_US3)
3664 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3665
3666 if (e_flags & EF_SPARC_HAL_R1)
3667 strcat (buf, ", halr1");
3668
3669 if (e_flags & EF_SPARC_LEDATA)
3670 strcat (buf, ", ledata");
3671
3672 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3673 strcat (buf, ", tso");
3674
3675 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3676 strcat (buf, ", pso");
3677
3678 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3679 strcat (buf, ", rmo");
3680 break;
7d466069 3681
103f02d3
UD
3682 case EM_PARISC:
3683 switch (e_flags & EF_PARISC_ARCH)
3684 {
3685 case EFA_PARISC_1_0:
3686 strcpy (buf, ", PA-RISC 1.0");
3687 break;
3688 case EFA_PARISC_1_1:
3689 strcpy (buf, ", PA-RISC 1.1");
3690 break;
3691 case EFA_PARISC_2_0:
3692 strcpy (buf, ", PA-RISC 2.0");
3693 break;
3694 default:
3695 break;
3696 }
3697 if (e_flags & EF_PARISC_TRAPNIL)
3698 strcat (buf, ", trapnil");
3699 if (e_flags & EF_PARISC_EXT)
3700 strcat (buf, ", ext");
3701 if (e_flags & EF_PARISC_LSB)
3702 strcat (buf, ", lsb");
3703 if (e_flags & EF_PARISC_WIDE)
3704 strcat (buf, ", wide");
3705 if (e_flags & EF_PARISC_NO_KABP)
3706 strcat (buf, ", no kabp");
3707 if (e_flags & EF_PARISC_LAZYSWAP)
3708 strcat (buf, ", lazyswap");
30800947 3709 break;
76da6bbe 3710
7d466069 3711 case EM_PJ:
2b0337b0 3712 case EM_PJ_OLD:
7d466069
ILT
3713 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3714 strcat (buf, ", new calling convention");
3715
3716 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3717 strcat (buf, ", gnu calling convention");
3718 break;
4d6ed7c8
NC
3719
3720 case EM_IA_64:
3721 if ((e_flags & EF_IA_64_ABI64))
3722 strcat (buf, ", 64-bit");
3723 else
3724 strcat (buf, ", 32-bit");
3725 if ((e_flags & EF_IA_64_REDUCEDFP))
3726 strcat (buf, ", reduced fp model");
3727 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3728 strcat (buf, ", no function descriptors, constant gp");
3729 else if ((e_flags & EF_IA_64_CONS_GP))
3730 strcat (buf, ", constant gp");
3731 if ((e_flags & EF_IA_64_ABSOLUTE))
3732 strcat (buf, ", absolute");
dda8d76d 3733 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3734 {
3735 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3736 strcat (buf, ", vms_linkages");
3737 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3738 {
3739 case EF_IA_64_VMS_COMCOD_SUCCESS:
3740 break;
3741 case EF_IA_64_VMS_COMCOD_WARNING:
3742 strcat (buf, ", warning");
3743 break;
3744 case EF_IA_64_VMS_COMCOD_ERROR:
3745 strcat (buf, ", error");
3746 break;
3747 case EF_IA_64_VMS_COMCOD_ABORT:
3748 strcat (buf, ", abort");
3749 break;
3750 default:
bee0ee85
NC
3751 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3752 e_flags & EF_IA_64_VMS_COMCOD);
3753 strcat (buf, ", <unknown>");
28f997cf
TG
3754 }
3755 }
4d6ed7c8 3756 break;
179d3252
JT
3757
3758 case EM_VAX:
3759 if ((e_flags & EF_VAX_NONPIC))
3760 strcat (buf, ", non-PIC");
3761 if ((e_flags & EF_VAX_DFLOAT))
3762 strcat (buf, ", D-Float");
3763 if ((e_flags & EF_VAX_GFLOAT))
3764 strcat (buf, ", G-Float");
3765 break;
c7927a3c 3766
619ed720
EB
3767 case EM_VISIUM:
3768 if (e_flags & EF_VISIUM_ARCH_MCM)
3769 strcat (buf, ", mcm");
3770 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3771 strcat (buf, ", mcm24");
3772 if (e_flags & EF_VISIUM_ARCH_GR6)
3773 strcat (buf, ", gr6");
3774 break;
3775
4046d87a 3776 case EM_RL78:
1740ba0c
NC
3777 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3778 {
3779 case E_FLAG_RL78_ANY_CPU: break;
3780 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3781 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3782 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3783 }
856ea05c
KP
3784 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3785 strcat (buf, ", 64-bit doubles");
4046d87a 3786 break;
0b4362b0 3787
c7927a3c
NC
3788 case EM_RX:
3789 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3790 strcat (buf, ", 64-bit doubles");
3791 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3792 strcat (buf, ", dsp");
d4cb0ea0 3793 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3794 strcat (buf, ", pid");
708e2187
NC
3795 if (e_flags & E_FLAG_RX_ABI)
3796 strcat (buf, ", RX ABI");
3525236c
NC
3797 if (e_flags & E_FLAG_RX_SINSNS_SET)
3798 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3799 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3800 if (e_flags & E_FLAG_RX_V2)
3801 strcat (buf, ", V2");
f87673e0
YS
3802 if (e_flags & E_FLAG_RX_V3)
3803 strcat (buf, ", V3");
d4cb0ea0 3804 break;
55786da2
AK
3805
3806 case EM_S390:
3807 if (e_flags & EF_S390_HIGH_GPRS)
3808 strcat (buf, ", highgprs");
d4cb0ea0 3809 break;
40b36596
JM
3810
3811 case EM_TI_C6000:
3812 if ((e_flags & EF_C6000_REL))
3813 strcat (buf, ", relocatable module");
d4cb0ea0 3814 break;
13761a11
NC
3815
3816 case EM_MSP430:
3817 strcat (buf, _(": architecture variant: "));
3818 switch (e_flags & EF_MSP430_MACH)
3819 {
3820 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3821 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3822 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3823 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3824 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3825 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3826 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3827 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3828 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3829 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3830 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3831 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3832 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3833 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3834 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3835 default:
3836 strcat (buf, _(": unknown")); break;
3837 }
3838
3839 if (e_flags & ~ EF_MSP430_MACH)
3840 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
3841 break;
3842
3843 case EM_Z80:
3844 switch (e_flags & EF_Z80_MACH_MSK)
3845 {
3846 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
3847 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
3848 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
3849 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
3850 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
3851 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 3852 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
3853 default:
3854 strcat (buf, _(", unknown")); break;
3855 }
3856 break;
252b5132
RH
3857 }
3858 }
3859
3860 return buf;
3861}
3862
252b5132 3863static const char *
dda8d76d 3864get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3865{
3866 static char buff[32];
3867
3868 switch (osabi)
3869 {
3870 case ELFOSABI_NONE: return "UNIX - System V";
3871 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3872 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3873 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3874 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3875 case ELFOSABI_AIX: return "UNIX - AIX";
3876 case ELFOSABI_IRIX: return "UNIX - IRIX";
3877 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3878 case ELFOSABI_TRU64: return "UNIX - TRU64";
3879 case ELFOSABI_MODESTO: return "Novell - Modesto";
3880 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3881 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3882 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3883 case ELFOSABI_AROS: return "AROS";
11636f9e 3884 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3885 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3886 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3887 default:
40b36596 3888 if (osabi >= 64)
dda8d76d 3889 switch (filedata->file_header.e_machine)
40b36596
JM
3890 {
3891 case EM_ARM:
3892 switch (osabi)
3893 {
3894 case ELFOSABI_ARM: return "ARM";
18a20338 3895 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3896 default:
3897 break;
3898 }
3899 break;
3900
3901 case EM_MSP430:
3902 case EM_MSP430_OLD:
619ed720 3903 case EM_VISIUM:
40b36596
JM
3904 switch (osabi)
3905 {
3906 case ELFOSABI_STANDALONE: return _("Standalone App");
3907 default:
3908 break;
3909 }
3910 break;
3911
3912 case EM_TI_C6000:
3913 switch (osabi)
3914 {
3915 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3916 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3917 default:
3918 break;
3919 }
3920 break;
3921
3922 default:
3923 break;
3924 }
e9e44622 3925 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3926 return buff;
3927 }
3928}
3929
a06ea964
NC
3930static const char *
3931get_aarch64_segment_type (unsigned long type)
3932{
3933 switch (type)
3934 {
32ec8896
NC
3935 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3936 default: return NULL;
a06ea964 3937 }
a06ea964
NC
3938}
3939
b294bdf8
MM
3940static const char *
3941get_arm_segment_type (unsigned long type)
3942{
3943 switch (type)
3944 {
32ec8896
NC
3945 case PT_ARM_EXIDX: return "EXIDX";
3946 default: return NULL;
b294bdf8 3947 }
b294bdf8
MM
3948}
3949
b4cbbe8f
AK
3950static const char *
3951get_s390_segment_type (unsigned long type)
3952{
3953 switch (type)
3954 {
3955 case PT_S390_PGSTE: return "S390_PGSTE";
3956 default: return NULL;
3957 }
3958}
3959
d3ba0551
AM
3960static const char *
3961get_mips_segment_type (unsigned long type)
252b5132
RH
3962{
3963 switch (type)
3964 {
32ec8896
NC
3965 case PT_MIPS_REGINFO: return "REGINFO";
3966 case PT_MIPS_RTPROC: return "RTPROC";
3967 case PT_MIPS_OPTIONS: return "OPTIONS";
3968 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3969 default: return NULL;
252b5132 3970 }
252b5132
RH
3971}
3972
103f02d3 3973static const char *
d3ba0551 3974get_parisc_segment_type (unsigned long type)
103f02d3
UD
3975{
3976 switch (type)
3977 {
103f02d3
UD
3978 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3979 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3980 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3981 default: return NULL;
103f02d3 3982 }
103f02d3
UD
3983}
3984
4d6ed7c8 3985static const char *
d3ba0551 3986get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3987{
3988 switch (type)
3989 {
3990 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3991 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 3992 default: return NULL;
4d6ed7c8 3993 }
4d6ed7c8
NC
3994}
3995
40b36596
JM
3996static const char *
3997get_tic6x_segment_type (unsigned long type)
3998{
3999 switch (type)
4000 {
32ec8896
NC
4001 case PT_C6000_PHATTR: return "C6000_PHATTR";
4002 default: return NULL;
40b36596 4003 }
40b36596
JM
4004}
4005
df3a023b
AM
4006static const char *
4007get_hpux_segment_type (unsigned long type, unsigned e_machine)
4008{
4009 if (e_machine == EM_PARISC)
4010 switch (type)
4011 {
4012 case PT_HP_TLS: return "HP_TLS";
4013 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4014 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4015 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4016 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4017 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4018 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4019 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4020 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4021 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4022 case PT_HP_PARALLEL: return "HP_PARALLEL";
4023 case PT_HP_FASTBIND: return "HP_FASTBIND";
4024 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4025 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4026 case PT_HP_STACK: return "HP_STACK";
4027 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4028 default: return NULL;
4029 }
4030
4031 if (e_machine == EM_IA_64)
4032 switch (type)
4033 {
4034 case PT_HP_TLS: return "HP_TLS";
4035 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4036 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4037 case PT_IA_64_HP_STACK: return "HP_STACK";
4038 default: return NULL;
4039 }
4040
4041 return NULL;
4042}
4043
5522f910
NC
4044static const char *
4045get_solaris_segment_type (unsigned long type)
4046{
4047 switch (type)
4048 {
4049 case 0x6464e550: return "PT_SUNW_UNWIND";
4050 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4051 case 0x6ffffff7: return "PT_LOSUNW";
4052 case 0x6ffffffa: return "PT_SUNWBSS";
4053 case 0x6ffffffb: return "PT_SUNWSTACK";
4054 case 0x6ffffffc: return "PT_SUNWDTRACE";
4055 case 0x6ffffffd: return "PT_SUNWCAP";
4056 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4057 default: return NULL;
5522f910
NC
4058 }
4059}
4060
252b5132 4061static const char *
dda8d76d 4062get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4063{
b34976b6 4064 static char buff[32];
252b5132
RH
4065
4066 switch (p_type)
4067 {
b34976b6
AM
4068 case PT_NULL: return "NULL";
4069 case PT_LOAD: return "LOAD";
252b5132 4070 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4071 case PT_INTERP: return "INTERP";
4072 case PT_NOTE: return "NOTE";
4073 case PT_SHLIB: return "SHLIB";
4074 case PT_PHDR: return "PHDR";
13ae64f3 4075 case PT_TLS: return "TLS";
32ec8896 4076 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4077 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4078 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4079 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4080
3eba3ef3
NC
4081 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4082 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4083 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4084
252b5132 4085 default:
df3a023b 4086 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4087 {
2cf0635d 4088 const char * result;
103f02d3 4089
dda8d76d 4090 switch (filedata->file_header.e_machine)
252b5132 4091 {
a06ea964
NC
4092 case EM_AARCH64:
4093 result = get_aarch64_segment_type (p_type);
4094 break;
b294bdf8
MM
4095 case EM_ARM:
4096 result = get_arm_segment_type (p_type);
4097 break;
252b5132 4098 case EM_MIPS:
4fe85591 4099 case EM_MIPS_RS3_LE:
252b5132
RH
4100 result = get_mips_segment_type (p_type);
4101 break;
103f02d3
UD
4102 case EM_PARISC:
4103 result = get_parisc_segment_type (p_type);
4104 break;
4d6ed7c8
NC
4105 case EM_IA_64:
4106 result = get_ia64_segment_type (p_type);
4107 break;
40b36596
JM
4108 case EM_TI_C6000:
4109 result = get_tic6x_segment_type (p_type);
4110 break;
b4cbbe8f
AK
4111 case EM_S390:
4112 case EM_S390_OLD:
4113 result = get_s390_segment_type (p_type);
4114 break;
252b5132
RH
4115 default:
4116 result = NULL;
4117 break;
4118 }
103f02d3 4119
252b5132
RH
4120 if (result != NULL)
4121 return result;
103f02d3 4122
1a9ccd70 4123 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4124 }
4125 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4126 {
df3a023b 4127 const char * result = NULL;
103f02d3 4128
df3a023b 4129 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4130 {
df3a023b
AM
4131 case ELFOSABI_GNU:
4132 case ELFOSABI_FREEBSD:
4133 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4134 {
4135 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4136 result = buff;
4137 }
103f02d3 4138 break;
df3a023b
AM
4139 case ELFOSABI_HPUX:
4140 result = get_hpux_segment_type (p_type,
4141 filedata->file_header.e_machine);
4142 break;
4143 case ELFOSABI_SOLARIS:
4144 result = get_solaris_segment_type (p_type);
00428cca 4145 break;
103f02d3 4146 default:
103f02d3
UD
4147 break;
4148 }
103f02d3
UD
4149 if (result != NULL)
4150 return result;
4151
1a9ccd70 4152 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4153 }
252b5132 4154 else
e9e44622 4155 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4156
4157 return buff;
4158 }
4159}
4160
53a346d8
CZ
4161static const char *
4162get_arc_section_type_name (unsigned int sh_type)
4163{
4164 switch (sh_type)
4165 {
4166 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4167 default:
4168 break;
4169 }
4170 return NULL;
4171}
4172
252b5132 4173static const char *
d3ba0551 4174get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4175{
4176 switch (sh_type)
4177 {
b34976b6
AM
4178 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4179 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4180 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4181 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4182 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4183 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4184 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4185 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4186 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4187 case SHT_MIPS_RELD: return "MIPS_RELD";
4188 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4189 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4190 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4191 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4192 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4193 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4194 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4195 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4196 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4197 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4198 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4199 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4200 case SHT_MIPS_LINE: return "MIPS_LINE";
4201 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4202 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4203 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4204 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4205 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4206 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4207 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4208 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4209 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4210 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4211 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4212 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4213 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4214 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4215 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4216 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4217 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4218 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4219 default:
4220 break;
4221 }
4222 return NULL;
4223}
4224
103f02d3 4225static const char *
d3ba0551 4226get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4227{
4228 switch (sh_type)
4229 {
4230 case SHT_PARISC_EXT: return "PARISC_EXT";
4231 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4232 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4233 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4234 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4235 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4236 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4237 default: return NULL;
103f02d3 4238 }
103f02d3
UD
4239}
4240
4d6ed7c8 4241static const char *
dda8d76d 4242get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4243{
18bd398b 4244 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4245 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4246 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4247
4d6ed7c8
NC
4248 switch (sh_type)
4249 {
148b93f2
NC
4250 case SHT_IA_64_EXT: return "IA_64_EXT";
4251 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4252 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4253 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4254 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4255 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4256 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4257 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4258 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4259 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4260 default:
4261 break;
4262 }
4263 return NULL;
4264}
4265
d2b2c203
DJ
4266static const char *
4267get_x86_64_section_type_name (unsigned int sh_type)
4268{
4269 switch (sh_type)
4270 {
4271 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4272 default: return NULL;
d2b2c203 4273 }
d2b2c203
DJ
4274}
4275
a06ea964
NC
4276static const char *
4277get_aarch64_section_type_name (unsigned int sh_type)
4278{
4279 switch (sh_type)
4280 {
32ec8896
NC
4281 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4282 default: return NULL;
a06ea964 4283 }
a06ea964
NC
4284}
4285
40a18ebd
NC
4286static const char *
4287get_arm_section_type_name (unsigned int sh_type)
4288{
4289 switch (sh_type)
4290 {
7f6fed87
NC
4291 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4292 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4293 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4294 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4295 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4296 default: return NULL;
40a18ebd 4297 }
40a18ebd
NC
4298}
4299
40b36596
JM
4300static const char *
4301get_tic6x_section_type_name (unsigned int sh_type)
4302{
4303 switch (sh_type)
4304 {
32ec8896
NC
4305 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4306 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4307 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4308 case SHT_TI_ICODE: return "TI_ICODE";
4309 case SHT_TI_XREF: return "TI_XREF";
4310 case SHT_TI_HANDLER: return "TI_HANDLER";
4311 case SHT_TI_INITINFO: return "TI_INITINFO";
4312 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4313 default: return NULL;
40b36596 4314 }
40b36596
JM
4315}
4316
13761a11 4317static const char *
b0191216 4318get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4319{
4320 switch (sh_type)
4321 {
32ec8896
NC
4322 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4323 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4324 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4325 default: return NULL;
13761a11
NC
4326 }
4327}
4328
fe944acf
FT
4329static const char *
4330get_nfp_section_type_name (unsigned int sh_type)
4331{
4332 switch (sh_type)
4333 {
4334 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4335 case SHT_NFP_INITREG: return "NFP_INITREG";
4336 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4337 default: return NULL;
4338 }
4339}
4340
685080f2
NC
4341static const char *
4342get_v850_section_type_name (unsigned int sh_type)
4343{
4344 switch (sh_type)
4345 {
32ec8896
NC
4346 case SHT_V850_SCOMMON: return "V850 Small Common";
4347 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4348 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4349 case SHT_RENESAS_IOP: return "RENESAS IOP";
4350 case SHT_RENESAS_INFO: return "RENESAS INFO";
4351 default: return NULL;
685080f2
NC
4352 }
4353}
4354
2dc8dd17
JW
4355static const char *
4356get_riscv_section_type_name (unsigned int sh_type)
4357{
4358 switch (sh_type)
4359 {
4360 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4361 default: return NULL;
4362 }
4363}
4364
0861f561
CQ
4365static const char *
4366get_csky_section_type_name (unsigned int sh_type)
4367{
4368 switch (sh_type)
4369 {
4370 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4371 default: return NULL;
4372 }
4373}
4374
252b5132 4375static const char *
dda8d76d 4376get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4377{
b34976b6 4378 static char buff[32];
9fb71ee4 4379 const char * result;
252b5132
RH
4380
4381 switch (sh_type)
4382 {
4383 case SHT_NULL: return "NULL";
4384 case SHT_PROGBITS: return "PROGBITS";
4385 case SHT_SYMTAB: return "SYMTAB";
4386 case SHT_STRTAB: return "STRTAB";
4387 case SHT_RELA: return "RELA";
4388 case SHT_HASH: return "HASH";
4389 case SHT_DYNAMIC: return "DYNAMIC";
4390 case SHT_NOTE: return "NOTE";
4391 case SHT_NOBITS: return "NOBITS";
4392 case SHT_REL: return "REL";
4393 case SHT_SHLIB: return "SHLIB";
4394 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4395 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4396 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4397 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4398 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4399 case SHT_GROUP: return "GROUP";
67ce483b 4400 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4401 case SHT_GNU_verdef: return "VERDEF";
4402 case SHT_GNU_verneed: return "VERNEED";
4403 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4404 case 0x6ffffff0: return "VERSYM";
4405 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4406 case 0x7ffffffd: return "AUXILIARY";
4407 case 0x7fffffff: return "FILTER";
047b2264 4408 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4409
4410 default:
4411 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4412 {
dda8d76d 4413 switch (filedata->file_header.e_machine)
252b5132 4414 {
53a346d8
CZ
4415 case EM_ARC:
4416 case EM_ARC_COMPACT:
4417 case EM_ARC_COMPACT2:
4418 result = get_arc_section_type_name (sh_type);
4419 break;
252b5132 4420 case EM_MIPS:
4fe85591 4421 case EM_MIPS_RS3_LE:
252b5132
RH
4422 result = get_mips_section_type_name (sh_type);
4423 break;
103f02d3
UD
4424 case EM_PARISC:
4425 result = get_parisc_section_type_name (sh_type);
4426 break;
4d6ed7c8 4427 case EM_IA_64:
dda8d76d 4428 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4429 break;
d2b2c203 4430 case EM_X86_64:
8a9036a4 4431 case EM_L1OM:
7a9068fe 4432 case EM_K1OM:
d2b2c203
DJ
4433 result = get_x86_64_section_type_name (sh_type);
4434 break;
a06ea964
NC
4435 case EM_AARCH64:
4436 result = get_aarch64_section_type_name (sh_type);
4437 break;
40a18ebd
NC
4438 case EM_ARM:
4439 result = get_arm_section_type_name (sh_type);
4440 break;
40b36596
JM
4441 case EM_TI_C6000:
4442 result = get_tic6x_section_type_name (sh_type);
4443 break;
13761a11 4444 case EM_MSP430:
b0191216 4445 result = get_msp430_section_type_name (sh_type);
13761a11 4446 break;
fe944acf
FT
4447 case EM_NFP:
4448 result = get_nfp_section_type_name (sh_type);
4449 break;
685080f2
NC
4450 case EM_V800:
4451 case EM_V850:
4452 case EM_CYGNUS_V850:
4453 result = get_v850_section_type_name (sh_type);
4454 break;
2dc8dd17
JW
4455 case EM_RISCV:
4456 result = get_riscv_section_type_name (sh_type);
4457 break;
0861f561
CQ
4458 case EM_CSKY:
4459 result = get_csky_section_type_name (sh_type);
4460 break;
252b5132
RH
4461 default:
4462 result = NULL;
4463 break;
4464 }
4465
4466 if (result != NULL)
4467 return result;
4468
9fb71ee4 4469 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4470 }
4471 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4472 {
dda8d76d 4473 switch (filedata->file_header.e_machine)
148b93f2
NC
4474 {
4475 case EM_IA_64:
dda8d76d 4476 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4477 break;
4478 default:
dda8d76d 4479 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4480 result = get_solaris_section_type (sh_type);
4481 else
1b4b80bf
NC
4482 {
4483 switch (sh_type)
4484 {
4485 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4486 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4487 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4488 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4489 default:
4490 result = NULL;
4491 break;
4492 }
4493 }
148b93f2
NC
4494 break;
4495 }
4496
4497 if (result != NULL)
4498 return result;
4499
9fb71ee4 4500 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4501 }
252b5132 4502 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4503 {
dda8d76d 4504 switch (filedata->file_header.e_machine)
685080f2
NC
4505 {
4506 case EM_V800:
4507 case EM_V850:
4508 case EM_CYGNUS_V850:
9fb71ee4 4509 result = get_v850_section_type_name (sh_type);
a9fb83be 4510 break;
685080f2 4511 default:
9fb71ee4 4512 result = NULL;
685080f2
NC
4513 break;
4514 }
4515
9fb71ee4
NC
4516 if (result != NULL)
4517 return result;
4518
4519 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4520 }
252b5132 4521 else
a7dbfd1c
NC
4522 /* This message is probably going to be displayed in a 15
4523 character wide field, so put the hex value first. */
4524 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4525
252b5132
RH
4526 return buff;
4527 }
4528}
4529
79bc120c
NC
4530enum long_option_values
4531{
4532 OPTION_DEBUG_DUMP = 512,
4533 OPTION_DYN_SYMS,
0f03783c 4534 OPTION_LTO_SYMS,
79bc120c
NC
4535 OPTION_DWARF_DEPTH,
4536 OPTION_DWARF_START,
4537 OPTION_DWARF_CHECK,
4538 OPTION_CTF_DUMP,
4539 OPTION_CTF_PARENT,
4540 OPTION_CTF_SYMBOLS,
4541 OPTION_CTF_STRINGS,
4542 OPTION_WITH_SYMBOL_VERSIONS,
4543 OPTION_RECURSE_LIMIT,
4544 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
4545 OPTION_NO_DEMANGLING,
4546 OPTION_SYM_BASE
79bc120c 4547};
2979dc34 4548
85b1c36d 4549static struct option options[] =
252b5132 4550{
79bc120c
NC
4551 /* Note - This table is alpha-sorted on the 'val'
4552 field in order to make adding new options easier. */
4553 {"arch-specific", no_argument, 0, 'A'},
b34976b6 4554 {"all", no_argument, 0, 'a'},
79bc120c
NC
4555 {"demangle", optional_argument, 0, 'C'},
4556 {"archive-index", no_argument, 0, 'c'},
4557 {"use-dynamic", no_argument, 0, 'D'},
4558 {"dynamic", no_argument, 0, 'd'},
b34976b6 4559 {"headers", no_argument, 0, 'e'},
79bc120c
NC
4560 {"section-groups", no_argument, 0, 'g'},
4561 {"help", no_argument, 0, 'H'},
4562 {"file-header", no_argument, 0, 'h'},
b34976b6 4563 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
4564 {"lint", no_argument, 0, 'L'},
4565 {"enable-checks", no_argument, 0, 'L'},
4566 {"program-headers", no_argument, 0, 'l'},
b34976b6 4567 {"segments", no_argument, 0, 'l'},
595cf52e 4568 {"full-section-name",no_argument, 0, 'N'},
79bc120c 4569 {"notes", no_argument, 0, 'n'},
ca0e11aa 4570 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
4571 {"string-dump", required_argument, 0, 'p'},
4572 {"relocated-dump", required_argument, 0, 'R'},
4573 {"relocs", no_argument, 0, 'r'},
4574 {"section-headers", no_argument, 0, 'S'},
4575 {"sections", no_argument, 0, 'S'},
b34976b6
AM
4576 {"symbols", no_argument, 0, 's'},
4577 {"syms", no_argument, 0, 's'},
79bc120c
NC
4578 {"silent-truncation",no_argument, 0, 'T'},
4579 {"section-details", no_argument, 0, 't'},
09c11c86 4580 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
4581 {"version-info", no_argument, 0, 'V'},
4582 {"version", no_argument, 0, 'v'},
4583 {"wide", no_argument, 0, 'W'},
b34976b6 4584 {"hex-dump", required_argument, 0, 'x'},
0e602686 4585 {"decompress", no_argument, 0, 'z'},
252b5132 4586
79bc120c
NC
4587 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
4588 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
4589 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4590 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4591 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 4592 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 4593 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
4594 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4595 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4596 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 4597#ifdef ENABLE_LIBCTF
d344b407 4598 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
4599 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
4600 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
4601 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 4602#endif
047c3dbf 4603 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 4604
b34976b6 4605 {0, no_argument, 0, 0}
252b5132
RH
4606};
4607
4608static void
2cf0635d 4609usage (FILE * stream)
252b5132 4610{
92f01d61
JM
4611 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4612 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
4613 fprintf (stream, _(" Options are:\n"));
4614 fprintf (stream, _("\
4615 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
4616 fprintf (stream, _("\
4617 -h --file-header Display the ELF file header\n"));
4618 fprintf (stream, _("\
4619 -l --program-headers Display the program headers\n"));
4620 fprintf (stream, _("\
4621 --segments An alias for --program-headers\n"));
4622 fprintf (stream, _("\
4623 -S --section-headers Display the sections' header\n"));
4624 fprintf (stream, _("\
4625 --sections An alias for --section-headers\n"));
4626 fprintf (stream, _("\
4627 -g --section-groups Display the section groups\n"));
4628 fprintf (stream, _("\
4629 -t --section-details Display the section details\n"));
4630 fprintf (stream, _("\
4631 -e --headers Equivalent to: -h -l -S\n"));
4632 fprintf (stream, _("\
4633 -s --syms Display the symbol table\n"));
4634 fprintf (stream, _("\
4635 --symbols An alias for --syms\n"));
4636 fprintf (stream, _("\
4637 --dyn-syms Display the dynamic symbol table\n"));
4638 fprintf (stream, _("\
4639 --lto-syms Display LTO symbol tables\n"));
4640 fprintf (stream, _("\
047c3dbf
NL
4641 --sym-base=[0|8|10|16] \n\
4642 Force base for symbol sizes. The options are \n\
d6249f5f
AM
4643 mixed (the default), octal, decimal, hexadecimal.\n"));
4644 fprintf (stream, _("\
79bc120c
NC
4645 -C --demangle[=STYLE] Decode low-level symbol names into user-level names\n\
4646 The STYLE, if specified, can be `auto' (the default),\n\
4647 `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
d6249f5f
AM
4648 or `gnat'\n"));
4649 fprintf (stream, _("\
4650 --no-demangle Do not demangle low-level symbol names. (default)\n"));
4651 fprintf (stream, _("\
4652 --recurse-limit Enable a demangling recursion limit. (default)\n"));
4653 fprintf (stream, _("\
4654 --no-recurse-limit Disable a demangling recursion limit\n"));
4655 fprintf (stream, _("\
4656 -n --notes Display the core notes (if present)\n"));
4657 fprintf (stream, _("\
4658 -r --relocs Display the relocations (if present)\n"));
4659 fprintf (stream, _("\
4660 -u --unwind Display the unwind info (if present)\n"));
4661 fprintf (stream, _("\
4662 -d --dynamic Display the dynamic section (if present)\n"));
4663 fprintf (stream, _("\
4664 -V --version-info Display the version sections (if present)\n"));
4665 fprintf (stream, _("\
4666 -A --arch-specific Display architecture specific information (if any)\n"));
4667 fprintf (stream, _("\
4668 -c --archive-index Display the symbol/file index in an archive\n"));
4669 fprintf (stream, _("\
4670 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
4671 fprintf (stream, _("\
4672 -L --lint|--enable-checks\n\
4673 Display warning messages for possible problems\n"));
4674 fprintf (stream, _("\
09c11c86 4675 -x --hex-dump=<number|name>\n\
d6249f5f
AM
4676 Dump the contents of section <number|name> as bytes\n"));
4677 fprintf (stream, _("\
09c11c86 4678 -p --string-dump=<number|name>\n\
d6249f5f
AM
4679 Dump the contents of section <number|name> as strings\n"));
4680 fprintf (stream, _("\
cf13d699 4681 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
4682 Dump the relocated contents of section <number|name>\n"));
4683 fprintf (stream, _("\
4684 -z --decompress Decompress section before dumping it\n"));
4685 fprintf (stream, _("\
4686 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
4687 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
4688 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
4689 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
4690 U/=trace_info]\n\
4691 Display the contents of DWARF debug sections\n"));
4692 fprintf (stream, _("\
4693 -wk --debug-dump=links Display the contents of sections that link to separate\n\
4694 debuginfo files\n"));
4695 fprintf (stream, _("\
4696 -P --process-links Display the contents of non-debug sections in separate\n\
4697 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
4698#if DEFAULT_FOR_FOLLOW_LINKS
4699 fprintf (stream, _("\
d6249f5f
AM
4700 -wK --debug-dump=follow-links\n\
4701 Follow links to separate debug info files (default)\n"));
4702 fprintf (stream, _("\
4703 -wN --debug-dump=no-follow-links\n\
4704 Do not follow links to separate debug info files\n"));
c46b7066
NC
4705#else
4706 fprintf (stream, _("\
d6249f5f
AM
4707 -wK --debug-dump=follow-links\n\
4708 Follow links to separate debug info files\n"));
4709 fprintf (stream, _("\
4710 -wN --debug-dump=no-follow-links\n\
4711 Do not follow links to separate debug info files\n\
4712 (default)\n"));
c46b7066 4713#endif
fd2f0033 4714 fprintf (stream, _("\
d6249f5f
AM
4715 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
4716 fprintf (stream, _("\
4717 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 4718#ifdef ENABLE_LIBCTF
7d9813f1 4719 fprintf (stream, _("\
d6249f5f
AM
4720 --ctf=<number|name> Display CTF info from section <number|name>\n"));
4721 fprintf (stream, _("\
7d9813f1 4722 --ctf-parent=<number|name>\n\
d6249f5f
AM
4723 Use section <number|name> as the CTF parent\n"));
4724 fprintf (stream, _("\
7d9813f1 4725 --ctf-symbols=<number|name>\n\
d6249f5f
AM
4726 Use section <number|name> as the CTF external symtab\n"));
4727 fprintf (stream, _("\
7d9813f1 4728 --ctf-strings=<number|name>\n\
d6249f5f 4729 Use section <number|name> as the CTF external strtab\n"));
094e34f2 4730#endif
7d9813f1 4731
252b5132 4732#ifdef SUPPORT_DISASSEMBLY
92f01d61 4733 fprintf (stream, _("\
09c11c86
NC
4734 -i --instruction-dump=<number|name>\n\
4735 Disassemble the contents of section <number|name>\n"));
252b5132 4736#endif
92f01d61 4737 fprintf (stream, _("\
d6249f5f
AM
4738 -I --histogram Display histogram of bucket list lengths\n"));
4739 fprintf (stream, _("\
4740 -W --wide Allow output width to exceed 80 characters\n"));
4741 fprintf (stream, _("\
4742 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
4743 fprintf (stream, _("\
4744 @<file> Read options from <file>\n"));
4745 fprintf (stream, _("\
4746 -H --help Display this information\n"));
4747 fprintf (stream, _("\
8b53311e 4748 -v --version Display the version number of readelf\n"));
1118d252 4749
92f01d61
JM
4750 if (REPORT_BUGS_TO[0] && stream == stdout)
4751 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4752
92f01d61 4753 exit (stream == stdout ? 0 : 1);
252b5132
RH
4754}
4755
18bd398b
NC
4756/* Record the fact that the user wants the contents of section number
4757 SECTION to be displayed using the method(s) encoded as flags bits
4758 in TYPE. Note, TYPE can be zero if we are creating the array for
4759 the first time. */
4760
252b5132 4761static void
6431e409
AM
4762request_dump_bynumber (struct dump_data *dumpdata,
4763 unsigned int section, dump_type type)
252b5132 4764{
6431e409 4765 if (section >= dumpdata->num_dump_sects)
252b5132 4766 {
2cf0635d 4767 dump_type * new_dump_sects;
252b5132 4768
3f5e193b 4769 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4770 sizeof (* new_dump_sects));
252b5132
RH
4771
4772 if (new_dump_sects == NULL)
591a748a 4773 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4774 else
4775 {
6431e409 4776 if (dumpdata->dump_sects)
21b65bac
NC
4777 {
4778 /* Copy current flag settings. */
6431e409
AM
4779 memcpy (new_dump_sects, dumpdata->dump_sects,
4780 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4781
6431e409 4782 free (dumpdata->dump_sects);
21b65bac 4783 }
252b5132 4784
6431e409
AM
4785 dumpdata->dump_sects = new_dump_sects;
4786 dumpdata->num_dump_sects = section + 1;
252b5132
RH
4787 }
4788 }
4789
6431e409
AM
4790 if (dumpdata->dump_sects)
4791 dumpdata->dump_sects[section] |= type;
252b5132
RH
4792}
4793
aef1f6d0
DJ
4794/* Request a dump by section name. */
4795
4796static void
2cf0635d 4797request_dump_byname (const char * section, dump_type type)
aef1f6d0 4798{
2cf0635d 4799 struct dump_list_entry * new_request;
aef1f6d0 4800
3f5e193b
NC
4801 new_request = (struct dump_list_entry *)
4802 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4803 if (!new_request)
591a748a 4804 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4805
4806 new_request->name = strdup (section);
4807 if (!new_request->name)
591a748a 4808 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4809
4810 new_request->type = type;
4811
4812 new_request->next = dump_sects_byname;
4813 dump_sects_byname = new_request;
4814}
4815
cf13d699 4816static inline void
6431e409 4817request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
4818{
4819 int section;
4820 char * cp;
4821
015dc7e1 4822 do_dump = true;
cf13d699
NC
4823 section = strtoul (optarg, & cp, 0);
4824
4825 if (! *cp && section >= 0)
6431e409 4826 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
4827 else
4828 request_dump_byname (optarg, type);
4829}
4830
252b5132 4831static void
6431e409 4832parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
4833{
4834 int c;
4835
4836 if (argc < 2)
92f01d61 4837 usage (stderr);
252b5132
RH
4838
4839 while ((c = getopt_long
ca0e11aa 4840 (argc, argv, "ACDHILNPR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4841 {
252b5132
RH
4842 switch (c)
4843 {
4844 case 0:
4845 /* Long options. */
4846 break;
4847 case 'H':
92f01d61 4848 usage (stdout);
252b5132
RH
4849 break;
4850
4851 case 'a':
015dc7e1
AM
4852 do_syms = true;
4853 do_reloc = true;
4854 do_unwind = true;
4855 do_dynamic = true;
4856 do_header = true;
4857 do_sections = true;
4858 do_section_groups = true;
4859 do_segments = true;
4860 do_version = true;
4861 do_histogram = true;
4862 do_arch = true;
4863 do_notes = true;
252b5132 4864 break;
79bc120c 4865
f5842774 4866 case 'g':
015dc7e1 4867 do_section_groups = true;
f5842774 4868 break;
5477e8a0 4869 case 't':
595cf52e 4870 case 'N':
015dc7e1
AM
4871 do_sections = true;
4872 do_section_details = true;
595cf52e 4873 break;
252b5132 4874 case 'e':
015dc7e1
AM
4875 do_header = true;
4876 do_sections = true;
4877 do_segments = true;
252b5132 4878 break;
a952a375 4879 case 'A':
015dc7e1 4880 do_arch = true;
a952a375 4881 break;
252b5132 4882 case 'D':
015dc7e1 4883 do_using_dynamic = true;
252b5132
RH
4884 break;
4885 case 'r':
015dc7e1 4886 do_reloc = true;
252b5132 4887 break;
4d6ed7c8 4888 case 'u':
015dc7e1 4889 do_unwind = true;
4d6ed7c8 4890 break;
252b5132 4891 case 'h':
015dc7e1 4892 do_header = true;
252b5132
RH
4893 break;
4894 case 'l':
015dc7e1 4895 do_segments = true;
252b5132
RH
4896 break;
4897 case 's':
015dc7e1 4898 do_syms = true;
252b5132
RH
4899 break;
4900 case 'S':
015dc7e1 4901 do_sections = true;
252b5132
RH
4902 break;
4903 case 'd':
015dc7e1 4904 do_dynamic = true;
252b5132 4905 break;
a952a375 4906 case 'I':
015dc7e1 4907 do_histogram = true;
a952a375 4908 break;
779fe533 4909 case 'n':
015dc7e1 4910 do_notes = true;
779fe533 4911 break;
4145f1d5 4912 case 'c':
015dc7e1 4913 do_archive_index = true;
4145f1d5 4914 break;
1b513401 4915 case 'L':
015dc7e1 4916 do_checks = true;
1b513401 4917 break;
ca0e11aa 4918 case 'P':
015dc7e1
AM
4919 process_links = true;
4920 do_follow_links = true;
ca0e11aa 4921 break;
252b5132 4922 case 'x':
6431e409 4923 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 4924 break;
09c11c86 4925 case 'p':
6431e409 4926 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
4927 break;
4928 case 'R':
6431e409 4929 request_dump (dumpdata, RELOC_DUMP);
09c11c86 4930 break;
0e602686 4931 case 'z':
015dc7e1 4932 decompress_dumps = true;
0e602686 4933 break;
252b5132 4934 case 'w':
015dc7e1 4935 do_dump = true;
0f03783c 4936 if (optarg == NULL)
613ff48b 4937 {
015dc7e1 4938 do_debugging = true;
613ff48b
CC
4939 dwarf_select_sections_all ();
4940 }
252b5132
RH
4941 else
4942 {
015dc7e1 4943 do_debugging = false;
4cb93e3b 4944 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4945 }
4946 break;
2979dc34 4947 case OPTION_DEBUG_DUMP:
015dc7e1 4948 do_dump = true;
0f03783c 4949 if (optarg == NULL)
d6249f5f
AM
4950 {
4951 do_debugging = true;
4952 dwarf_select_sections_all ();
4953 }
2979dc34
JJ
4954 else
4955 {
015dc7e1 4956 do_debugging = false;
4cb93e3b 4957 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4958 }
4959 break;
fd2f0033
TT
4960 case OPTION_DWARF_DEPTH:
4961 {
4962 char *cp;
4963
4964 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4965 }
4966 break;
4967 case OPTION_DWARF_START:
4968 {
4969 char *cp;
4970
4971 dwarf_start_die = strtoul (optarg, & cp, 0);
4972 }
4973 break;
4723351a 4974 case OPTION_DWARF_CHECK:
015dc7e1 4975 dwarf_check = true;
4723351a 4976 break;
7d9813f1 4977 case OPTION_CTF_DUMP:
015dc7e1 4978 do_ctf = true;
6431e409 4979 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
4980 break;
4981 case OPTION_CTF_SYMBOLS:
df16e041 4982 free (dump_ctf_symtab_name);
7d9813f1
NA
4983 dump_ctf_symtab_name = strdup (optarg);
4984 break;
4985 case OPTION_CTF_STRINGS:
df16e041 4986 free (dump_ctf_strtab_name);
7d9813f1
NA
4987 dump_ctf_strtab_name = strdup (optarg);
4988 break;
4989 case OPTION_CTF_PARENT:
df16e041 4990 free (dump_ctf_parent_name);
7d9813f1
NA
4991 dump_ctf_parent_name = strdup (optarg);
4992 break;
2c610e4b 4993 case OPTION_DYN_SYMS:
015dc7e1 4994 do_dyn_syms = true;
2c610e4b 4995 break;
0f03783c 4996 case OPTION_LTO_SYMS:
015dc7e1 4997 do_lto_syms = true;
0f03783c 4998 break;
252b5132
RH
4999#ifdef SUPPORT_DISASSEMBLY
5000 case 'i':
6431e409 5001 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5002 break;
252b5132
RH
5003#endif
5004 case 'v':
5005 print_version (program_name);
5006 break;
5007 case 'V':
015dc7e1 5008 do_version = true;
252b5132 5009 break;
d974e256 5010 case 'W':
015dc7e1 5011 do_wide = true;
d974e256 5012 break;
0942c7ab 5013 case 'T':
015dc7e1 5014 do_not_show_symbol_truncation = true;
0942c7ab 5015 break;
79bc120c 5016 case 'C':
015dc7e1 5017 do_demangle = true;
79bc120c
NC
5018 if (optarg != NULL)
5019 {
5020 enum demangling_styles style;
5021
5022 style = cplus_demangle_name_to_style (optarg);
5023 if (style == unknown_demangling)
5024 error (_("unknown demangling style `%s'"), optarg);
5025
5026 cplus_demangle_set_style (style);
5027 }
5028 break;
5029 case OPTION_NO_DEMANGLING:
015dc7e1 5030 do_demangle = false;
79bc120c
NC
5031 break;
5032 case OPTION_RECURSE_LIMIT:
5033 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5034 break;
5035 case OPTION_NO_RECURSE_LIMIT:
5036 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5037 break;
5038 case OPTION_WITH_SYMBOL_VERSIONS:
5039 /* Ignored for backward compatibility. */
5040 break;
b9e920ec 5041
047c3dbf
NL
5042 case OPTION_SYM_BASE:
5043 sym_base = 0;
5044 if (optarg != NULL)
5045 {
5046 sym_base = strtoul (optarg, NULL, 0);
5047 switch (sym_base)
5048 {
5049 case 0:
5050 case 8:
5051 case 10:
5052 case 16:
5053 break;
5054
5055 default:
5056 sym_base = 0;
5057 break;
5058 }
5059 }
5060 break;
5061
252b5132 5062 default:
252b5132
RH
5063 /* xgettext:c-format */
5064 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5065 /* Fall through. */
252b5132 5066 case '?':
92f01d61 5067 usage (stderr);
252b5132
RH
5068 }
5069 }
5070
4d6ed7c8 5071 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5072 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5073 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5074 && !do_section_groups && !do_archive_index
0f03783c 5075 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5076 {
5077 if (do_checks)
5078 {
015dc7e1
AM
5079 check_all = true;
5080 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5081 do_segments = do_header = do_dump = do_version = true;
5082 do_histogram = do_debugging = do_arch = do_notes = true;
5083 do_section_groups = do_archive_index = do_dyn_syms = true;
5084 do_lto_syms = true;
1b513401
NC
5085 }
5086 else
5087 usage (stderr);
5088 }
252b5132
RH
5089}
5090
5091static const char *
d3ba0551 5092get_elf_class (unsigned int elf_class)
252b5132 5093{
b34976b6 5094 static char buff[32];
103f02d3 5095
252b5132
RH
5096 switch (elf_class)
5097 {
5098 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5099 case ELFCLASS32: return "ELF32";
5100 case ELFCLASS64: return "ELF64";
ab5e7794 5101 default:
e9e44622 5102 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5103 return buff;
252b5132
RH
5104 }
5105}
5106
5107static const char *
d3ba0551 5108get_data_encoding (unsigned int encoding)
252b5132 5109{
b34976b6 5110 static char buff[32];
103f02d3 5111
252b5132
RH
5112 switch (encoding)
5113 {
5114 case ELFDATANONE: return _("none");
33c63f9d
CM
5115 case ELFDATA2LSB: return _("2's complement, little endian");
5116 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5117 default:
e9e44622 5118 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5119 return buff;
252b5132
RH
5120 }
5121}
5122
dda8d76d 5123/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5124
015dc7e1 5125static bool
dda8d76d 5126process_file_header (Filedata * filedata)
252b5132 5127{
dda8d76d
NC
5128 Elf_Internal_Ehdr * header = & filedata->file_header;
5129
5130 if ( header->e_ident[EI_MAG0] != ELFMAG0
5131 || header->e_ident[EI_MAG1] != ELFMAG1
5132 || header->e_ident[EI_MAG2] != ELFMAG2
5133 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5134 {
5135 error
5136 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
015dc7e1 5137 return false;
252b5132
RH
5138 }
5139
ca0e11aa
NC
5140 if (! filedata->is_separate)
5141 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5142
252b5132
RH
5143 if (do_header)
5144 {
32ec8896 5145 unsigned i;
252b5132 5146
ca0e11aa
NC
5147 if (filedata->is_separate)
5148 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5149 else
5150 printf (_("ELF Header:\n"));
252b5132 5151 printf (_(" Magic: "));
b34976b6 5152 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5153 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5154 printf ("\n");
5155 printf (_(" Class: %s\n"),
dda8d76d 5156 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5157 printf (_(" Data: %s\n"),
dda8d76d 5158 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5159 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5160 header->e_ident[EI_VERSION],
5161 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5162 ? _(" (current)")
dda8d76d 5163 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5164 ? _(" <unknown>")
789be9f7 5165 : "")));
252b5132 5166 printf (_(" OS/ABI: %s\n"),
dda8d76d 5167 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5168 printf (_(" ABI Version: %d\n"),
dda8d76d 5169 header->e_ident[EI_ABIVERSION]);
252b5132 5170 printf (_(" Type: %s\n"),
dda8d76d 5171 get_file_type (header->e_type));
252b5132 5172 printf (_(" Machine: %s\n"),
dda8d76d 5173 get_machine_name (header->e_machine));
252b5132 5174 printf (_(" Version: 0x%lx\n"),
e8a64888 5175 header->e_version);
76da6bbe 5176
f7a99963 5177 printf (_(" Entry point address: "));
e8a64888 5178 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5179 printf (_("\n Start of program headers: "));
e8a64888 5180 print_vma (header->e_phoff, DEC);
f7a99963 5181 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5182 print_vma (header->e_shoff, DEC);
f7a99963 5183 printf (_(" (bytes into file)\n"));
76da6bbe 5184
252b5132 5185 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5186 header->e_flags,
dda8d76d 5187 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5188 printf (_(" Size of this header: %u (bytes)\n"),
5189 header->e_ehsize);
5190 printf (_(" Size of program headers: %u (bytes)\n"),
5191 header->e_phentsize);
5192 printf (_(" Number of program headers: %u"),
5193 header->e_phnum);
dda8d76d
NC
5194 if (filedata->section_headers != NULL
5195 && header->e_phnum == PN_XNUM
5196 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
5197 {
5198 header->e_phnum = filedata->section_headers[0].sh_info;
5199 printf (" (%u)", header->e_phnum);
5200 }
2046a35d 5201 putc ('\n', stdout);
e8a64888
AM
5202 printf (_(" Size of section headers: %u (bytes)\n"),
5203 header->e_shentsize);
5204 printf (_(" Number of section headers: %u"),
5205 header->e_shnum);
dda8d76d 5206 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5207 {
5208 header->e_shnum = filedata->section_headers[0].sh_size;
5209 printf (" (%u)", header->e_shnum);
5210 }
560f3c1c 5211 putc ('\n', stdout);
e8a64888
AM
5212 printf (_(" Section header string table index: %u"),
5213 header->e_shstrndx);
dda8d76d
NC
5214 if (filedata->section_headers != NULL
5215 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5216 {
5217 header->e_shstrndx = filedata->section_headers[0].sh_link;
5218 printf (" (%u)", header->e_shstrndx);
5219 }
5220 if (header->e_shstrndx != SHN_UNDEF
5221 && header->e_shstrndx >= header->e_shnum)
5222 {
5223 header->e_shstrndx = SHN_UNDEF;
5224 printf (_(" <corrupt: out of range>"));
5225 }
560f3c1c
AM
5226 putc ('\n', stdout);
5227 }
5228
dda8d76d 5229 if (filedata->section_headers != NULL)
560f3c1c 5230 {
dda8d76d
NC
5231 if (header->e_phnum == PN_XNUM
5232 && filedata->section_headers[0].sh_info != 0)
5233 header->e_phnum = filedata->section_headers[0].sh_info;
5234 if (header->e_shnum == SHN_UNDEF)
5235 header->e_shnum = filedata->section_headers[0].sh_size;
5236 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5237 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5238 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
5239 header->e_shstrndx = SHN_UNDEF;
5240 free (filedata->section_headers);
5241 filedata->section_headers = NULL;
252b5132 5242 }
103f02d3 5243
015dc7e1 5244 return true;
9ea033b2
NC
5245}
5246
dda8d76d
NC
5247/* Read in the program headers from FILEDATA and store them in PHEADERS.
5248 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5249
015dc7e1 5250static bool
dda8d76d 5251get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5252{
2cf0635d
NC
5253 Elf32_External_Phdr * phdrs;
5254 Elf32_External_Phdr * external;
5255 Elf_Internal_Phdr * internal;
b34976b6 5256 unsigned int i;
dda8d76d
NC
5257 unsigned int size = filedata->file_header.e_phentsize;
5258 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5259
5260 /* PR binutils/17531: Cope with unexpected section header sizes. */
5261 if (size == 0 || num == 0)
015dc7e1 5262 return false;
e0a31db1
NC
5263 if (size < sizeof * phdrs)
5264 {
5265 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5266 return false;
e0a31db1
NC
5267 }
5268 if (size > sizeof * phdrs)
5269 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5270
dda8d76d 5271 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5272 size, num, _("program headers"));
5273 if (phdrs == NULL)
015dc7e1 5274 return false;
9ea033b2 5275
91d6fa6a 5276 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5277 i < filedata->file_header.e_phnum;
b34976b6 5278 i++, internal++, external++)
252b5132 5279 {
9ea033b2
NC
5280 internal->p_type = BYTE_GET (external->p_type);
5281 internal->p_offset = BYTE_GET (external->p_offset);
5282 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5283 internal->p_paddr = BYTE_GET (external->p_paddr);
5284 internal->p_filesz = BYTE_GET (external->p_filesz);
5285 internal->p_memsz = BYTE_GET (external->p_memsz);
5286 internal->p_flags = BYTE_GET (external->p_flags);
5287 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5288 }
5289
9ea033b2 5290 free (phdrs);
015dc7e1 5291 return true;
252b5132
RH
5292}
5293
dda8d76d
NC
5294/* Read in the program headers from FILEDATA and store them in PHEADERS.
5295 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5296
015dc7e1 5297static bool
dda8d76d 5298get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5299{
2cf0635d
NC
5300 Elf64_External_Phdr * phdrs;
5301 Elf64_External_Phdr * external;
5302 Elf_Internal_Phdr * internal;
b34976b6 5303 unsigned int i;
dda8d76d
NC
5304 unsigned int size = filedata->file_header.e_phentsize;
5305 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5306
5307 /* PR binutils/17531: Cope with unexpected section header sizes. */
5308 if (size == 0 || num == 0)
015dc7e1 5309 return false;
e0a31db1
NC
5310 if (size < sizeof * phdrs)
5311 {
5312 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5313 return false;
e0a31db1
NC
5314 }
5315 if (size > sizeof * phdrs)
5316 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5317
dda8d76d 5318 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5319 size, num, _("program headers"));
a6e9f9df 5320 if (!phdrs)
015dc7e1 5321 return false;
9ea033b2 5322
91d6fa6a 5323 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5324 i < filedata->file_header.e_phnum;
b34976b6 5325 i++, internal++, external++)
9ea033b2
NC
5326 {
5327 internal->p_type = BYTE_GET (external->p_type);
5328 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5329 internal->p_offset = BYTE_GET (external->p_offset);
5330 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5331 internal->p_paddr = BYTE_GET (external->p_paddr);
5332 internal->p_filesz = BYTE_GET (external->p_filesz);
5333 internal->p_memsz = BYTE_GET (external->p_memsz);
5334 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5335 }
5336
5337 free (phdrs);
015dc7e1 5338 return true;
9ea033b2 5339}
252b5132 5340
32ec8896 5341/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5342
015dc7e1 5343static bool
dda8d76d 5344get_program_headers (Filedata * filedata)
d93f0186 5345{
2cf0635d 5346 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5347
5348 /* Check cache of prior read. */
dda8d76d 5349 if (filedata->program_headers != NULL)
015dc7e1 5350 return true;
d93f0186 5351
82156ab7
NC
5352 /* Be kind to memory checkers by looking for
5353 e_phnum values which we know must be invalid. */
dda8d76d 5354 if (filedata->file_header.e_phnum
82156ab7 5355 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5356 >= filedata->file_size)
82156ab7
NC
5357 {
5358 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5359 filedata->file_header.e_phnum);
015dc7e1 5360 return false;
82156ab7 5361 }
d93f0186 5362
dda8d76d 5363 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5364 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5365 if (phdrs == NULL)
5366 {
8b73c356 5367 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5368 filedata->file_header.e_phnum);
015dc7e1 5369 return false;
d93f0186
NC
5370 }
5371
5372 if (is_32bit_elf
dda8d76d
NC
5373 ? get_32bit_program_headers (filedata, phdrs)
5374 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5375 {
dda8d76d 5376 filedata->program_headers = phdrs;
015dc7e1 5377 return true;
d93f0186
NC
5378 }
5379
5380 free (phdrs);
015dc7e1 5381 return false;
d93f0186
NC
5382}
5383
32ec8896 5384/* Returns TRUE if the program headers were loaded. */
2f62977e 5385
015dc7e1 5386static bool
dda8d76d 5387process_program_headers (Filedata * filedata)
252b5132 5388{
2cf0635d 5389 Elf_Internal_Phdr * segment;
b34976b6 5390 unsigned int i;
1a9ccd70 5391 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5392
978c4450
AM
5393 filedata->dynamic_addr = 0;
5394 filedata->dynamic_size = 0;
663f67df 5395
dda8d76d 5396 if (filedata->file_header.e_phnum == 0)
252b5132 5397 {
82f2dbf7 5398 /* PR binutils/12467. */
dda8d76d 5399 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5400 {
5401 warn (_("possibly corrupt ELF header - it has a non-zero program"
5402 " header offset, but no program headers\n"));
015dc7e1 5403 return false;
32ec8896 5404 }
82f2dbf7 5405 else if (do_segments)
ca0e11aa
NC
5406 {
5407 if (filedata->is_separate)
5408 printf (_("\nThere are no program headers in linked file '%s'.\n"),
5409 filedata->file_name);
5410 else
5411 printf (_("\nThere are no program headers in this file.\n"));
5412 }
015dc7e1 5413 return true;
252b5132
RH
5414 }
5415
5416 if (do_segments && !do_header)
5417 {
ca0e11aa
NC
5418 if (filedata->is_separate)
5419 printf ("\nIn linked file '%s' the ELF file type is %s\n",
5420 filedata->file_name,
5421 get_file_type (filedata->file_header.e_type));
5422 else
5423 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
dda8d76d 5424 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5425 printf (ngettext ("There is %d program header, starting at offset %s\n",
5426 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5427 filedata->file_header.e_phnum),
5428 filedata->file_header.e_phnum,
5429 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5430 }
5431
dda8d76d 5432 if (! get_program_headers (filedata))
015dc7e1 5433 return true;
103f02d3 5434
252b5132
RH
5435 if (do_segments)
5436 {
dda8d76d 5437 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5438 printf (_("\nProgram Headers:\n"));
5439 else
5440 printf (_("\nProgram Headers:\n"));
76da6bbe 5441
f7a99963
NC
5442 if (is_32bit_elf)
5443 printf
5444 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5445 else if (do_wide)
5446 printf
5447 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5448 else
5449 {
5450 printf
5451 (_(" Type Offset VirtAddr PhysAddr\n"));
5452 printf
5453 (_(" FileSiz MemSiz Flags Align\n"));
5454 }
252b5132
RH
5455 }
5456
dda8d76d
NC
5457 for (i = 0, segment = filedata->program_headers;
5458 i < filedata->file_header.e_phnum;
b34976b6 5459 i++, segment++)
252b5132
RH
5460 {
5461 if (do_segments)
5462 {
dda8d76d 5463 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5464
5465 if (is_32bit_elf)
5466 {
5467 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5468 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5469 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5470 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5471 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5472 printf ("%c%c%c ",
5473 (segment->p_flags & PF_R ? 'R' : ' '),
5474 (segment->p_flags & PF_W ? 'W' : ' '),
5475 (segment->p_flags & PF_X ? 'E' : ' '));
5476 printf ("%#lx", (unsigned long) segment->p_align);
5477 }
d974e256
JJ
5478 else if (do_wide)
5479 {
5480 if ((unsigned long) segment->p_offset == segment->p_offset)
5481 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5482 else
5483 {
5484 print_vma (segment->p_offset, FULL_HEX);
5485 putchar (' ');
5486 }
5487
5488 print_vma (segment->p_vaddr, FULL_HEX);
5489 putchar (' ');
5490 print_vma (segment->p_paddr, FULL_HEX);
5491 putchar (' ');
5492
5493 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5494 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5495 else
5496 {
5497 print_vma (segment->p_filesz, FULL_HEX);
5498 putchar (' ');
5499 }
5500
5501 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5502 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5503 else
5504 {
f48e6c45 5505 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5506 }
5507
5508 printf (" %c%c%c ",
5509 (segment->p_flags & PF_R ? 'R' : ' '),
5510 (segment->p_flags & PF_W ? 'W' : ' '),
5511 (segment->p_flags & PF_X ? 'E' : ' '));
5512
5513 if ((unsigned long) segment->p_align == segment->p_align)
5514 printf ("%#lx", (unsigned long) segment->p_align);
5515 else
5516 {
5517 print_vma (segment->p_align, PREFIX_HEX);
5518 }
5519 }
f7a99963
NC
5520 else
5521 {
5522 print_vma (segment->p_offset, FULL_HEX);
5523 putchar (' ');
5524 print_vma (segment->p_vaddr, FULL_HEX);
5525 putchar (' ');
5526 print_vma (segment->p_paddr, FULL_HEX);
5527 printf ("\n ");
5528 print_vma (segment->p_filesz, FULL_HEX);
5529 putchar (' ');
5530 print_vma (segment->p_memsz, FULL_HEX);
5531 printf (" %c%c%c ",
5532 (segment->p_flags & PF_R ? 'R' : ' '),
5533 (segment->p_flags & PF_W ? 'W' : ' '),
5534 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5535 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5536 }
252b5132 5537
1a9ccd70
NC
5538 putc ('\n', stdout);
5539 }
f54498b4 5540
252b5132
RH
5541 switch (segment->p_type)
5542 {
1a9ccd70 5543 case PT_LOAD:
502d895c
NC
5544#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5545 required by the ELF standard, several programs, including the Linux
5546 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5547 if (previous_load
5548 && previous_load->p_vaddr > segment->p_vaddr)
5549 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5550#endif
1a9ccd70
NC
5551 if (segment->p_memsz < segment->p_filesz)
5552 error (_("the segment's file size is larger than its memory size\n"));
5553 previous_load = segment;
5554 break;
5555
5556 case PT_PHDR:
5557 /* PR 20815 - Verify that the program header is loaded into memory. */
5558 if (i > 0 && previous_load != NULL)
5559 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5560 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5561 {
5562 unsigned int j;
5563
dda8d76d 5564 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5565 {
5566 Elf_Internal_Phdr *load = filedata->program_headers + j;
5567 if (load->p_type == PT_LOAD
5568 && load->p_offset <= segment->p_offset
5569 && (load->p_offset + load->p_filesz
5570 >= segment->p_offset + segment->p_filesz)
5571 && load->p_vaddr <= segment->p_vaddr
5572 && (load->p_vaddr + load->p_filesz
5573 >= segment->p_vaddr + segment->p_filesz))
5574 break;
5575 }
dda8d76d 5576 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5577 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5578 }
5579 break;
5580
252b5132 5581 case PT_DYNAMIC:
978c4450 5582 if (filedata->dynamic_addr)
252b5132
RH
5583 error (_("more than one dynamic segment\n"));
5584
20737c13
AM
5585 /* By default, assume that the .dynamic section is the first
5586 section in the DYNAMIC segment. */
978c4450
AM
5587 filedata->dynamic_addr = segment->p_offset;
5588 filedata->dynamic_size = segment->p_filesz;
20737c13 5589
b2d38a17
NC
5590 /* Try to locate the .dynamic section. If there is
5591 a section header table, we can easily locate it. */
dda8d76d 5592 if (filedata->section_headers != NULL)
b2d38a17 5593 {
2cf0635d 5594 Elf_Internal_Shdr * sec;
b2d38a17 5595
dda8d76d 5596 sec = find_section (filedata, ".dynamic");
89fac5e3 5597 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5598 {
28f997cf
TG
5599 /* A corresponding .dynamic section is expected, but on
5600 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5601 if (!is_ia64_vms (filedata))
28f997cf 5602 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5603 break;
5604 }
5605
42bb2e33 5606 if (sec->sh_type == SHT_NOBITS)
20737c13 5607 {
978c4450 5608 filedata->dynamic_size = 0;
20737c13
AM
5609 break;
5610 }
42bb2e33 5611
978c4450
AM
5612 filedata->dynamic_addr = sec->sh_offset;
5613 filedata->dynamic_size = sec->sh_size;
b2d38a17 5614
8ac10c5b
L
5615 /* The PT_DYNAMIC segment, which is used by the run-time
5616 loader, should exactly match the .dynamic section. */
5617 if (do_checks
5618 && (filedata->dynamic_addr != segment->p_offset
5619 || filedata->dynamic_size != segment->p_filesz))
5620 warn (_("\
5621the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 5622 }
39e224f6
MW
5623
5624 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5625 segment. Check this after matching against the section headers
5626 so we don't warn on debuginfo file (which have NOBITS .dynamic
5627 sections). */
978c4450
AM
5628 if (filedata->dynamic_addr > filedata->file_size
5629 || (filedata->dynamic_size
5630 > filedata->file_size - filedata->dynamic_addr))
39e224f6
MW
5631 {
5632 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
978c4450 5633 filedata->dynamic_addr = filedata->dynamic_size = 0;
39e224f6 5634 }
252b5132
RH
5635 break;
5636
5637 case PT_INTERP:
13acb58d
AM
5638 if (segment->p_offset >= filedata->file_size
5639 || segment->p_filesz > filedata->file_size - segment->p_offset
5640 || segment->p_filesz - 1 >= (size_t) -2
5641 || fseek (filedata->handle,
5642 filedata->archive_file_offset + (long) segment->p_offset,
5643 SEEK_SET))
252b5132
RH
5644 error (_("Unable to find program interpreter name\n"));
5645 else
5646 {
13acb58d
AM
5647 size_t len = segment->p_filesz;
5648 free (filedata->program_interpreter);
5649 filedata->program_interpreter = xmalloc (len + 1);
5650 len = fread (filedata->program_interpreter, 1, len,
5651 filedata->handle);
5652 filedata->program_interpreter[len] = 0;
252b5132
RH
5653
5654 if (do_segments)
f54498b4 5655 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 5656 filedata->program_interpreter);
252b5132
RH
5657 }
5658 break;
5659 }
252b5132
RH
5660 }
5661
dda8d76d
NC
5662 if (do_segments
5663 && filedata->section_headers != NULL
5664 && filedata->string_table != NULL)
252b5132
RH
5665 {
5666 printf (_("\n Section to Segment mapping:\n"));
5667 printf (_(" Segment Sections...\n"));
5668
dda8d76d 5669 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5670 {
9ad5cbcf 5671 unsigned int j;
2cf0635d 5672 Elf_Internal_Shdr * section;
252b5132 5673
dda8d76d
NC
5674 segment = filedata->program_headers + i;
5675 section = filedata->section_headers + 1;
252b5132
RH
5676
5677 printf (" %2.2d ", i);
5678
dda8d76d 5679 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5680 {
f4638467
AM
5681 if (!ELF_TBSS_SPECIAL (section, segment)
5682 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5683 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5684 }
5685
5686 putc ('\n',stdout);
5687 }
5688 }
5689
015dc7e1 5690 return true;
252b5132
RH
5691}
5692
5693
d93f0186
NC
5694/* Find the file offset corresponding to VMA by using the program headers. */
5695
5696static long
dda8d76d 5697offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5698{
2cf0635d 5699 Elf_Internal_Phdr * seg;
d93f0186 5700
dda8d76d 5701 if (! get_program_headers (filedata))
d93f0186
NC
5702 {
5703 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5704 return (long) vma;
5705 }
5706
dda8d76d
NC
5707 for (seg = filedata->program_headers;
5708 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5709 ++seg)
5710 {
5711 if (seg->p_type != PT_LOAD)
5712 continue;
5713
5714 if (vma >= (seg->p_vaddr & -seg->p_align)
5715 && vma + size <= seg->p_vaddr + seg->p_filesz)
5716 return vma - seg->p_vaddr + seg->p_offset;
5717 }
5718
5719 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5720 (unsigned long) vma);
d93f0186
NC
5721 return (long) vma;
5722}
5723
5724
dda8d76d
NC
5725/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5726 If PROBE is true, this is just a probe and we do not generate any error
5727 messages if the load fails. */
049b0c3a 5728
015dc7e1
AM
5729static bool
5730get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 5731{
2cf0635d
NC
5732 Elf32_External_Shdr * shdrs;
5733 Elf_Internal_Shdr * internal;
dda8d76d
NC
5734 unsigned int i;
5735 unsigned int size = filedata->file_header.e_shentsize;
5736 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5737
5738 /* PR binutils/17531: Cope with unexpected section header sizes. */
5739 if (size == 0 || num == 0)
015dc7e1 5740 return false;
049b0c3a
NC
5741 if (size < sizeof * shdrs)
5742 {
5743 if (! probe)
5744 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 5745 return false;
049b0c3a
NC
5746 }
5747 if (!probe && size > sizeof * shdrs)
5748 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5749
dda8d76d 5750 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5751 size, num,
5752 probe ? NULL : _("section headers"));
5753 if (shdrs == NULL)
015dc7e1 5754 return false;
252b5132 5755
dda8d76d
NC
5756 filedata->section_headers = (Elf_Internal_Shdr *)
5757 cmalloc (num, sizeof (Elf_Internal_Shdr));
5758 if (filedata->section_headers == NULL)
252b5132 5759 {
049b0c3a 5760 if (!probe)
8b73c356 5761 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5762 free (shdrs);
015dc7e1 5763 return false;
252b5132
RH
5764 }
5765
dda8d76d 5766 for (i = 0, internal = filedata->section_headers;
560f3c1c 5767 i < num;
b34976b6 5768 i++, internal++)
252b5132
RH
5769 {
5770 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5771 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5772 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5773 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5774 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5775 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5776 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5777 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5778 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5779 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5780 if (!probe && internal->sh_link > num)
5781 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5782 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5783 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5784 }
5785
5786 free (shdrs);
015dc7e1 5787 return true;
252b5132
RH
5788}
5789
dda8d76d
NC
5790/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5791
015dc7e1
AM
5792static bool
5793get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 5794{
dda8d76d
NC
5795 Elf64_External_Shdr * shdrs;
5796 Elf_Internal_Shdr * internal;
5797 unsigned int i;
5798 unsigned int size = filedata->file_header.e_shentsize;
5799 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5800
5801 /* PR binutils/17531: Cope with unexpected section header sizes. */
5802 if (size == 0 || num == 0)
015dc7e1 5803 return false;
dda8d76d 5804
049b0c3a
NC
5805 if (size < sizeof * shdrs)
5806 {
5807 if (! probe)
5808 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 5809 return false;
049b0c3a 5810 }
dda8d76d 5811
049b0c3a
NC
5812 if (! probe && size > sizeof * shdrs)
5813 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5814
dda8d76d
NC
5815 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5816 filedata->file_header.e_shoff,
049b0c3a
NC
5817 size, num,
5818 probe ? NULL : _("section headers"));
5819 if (shdrs == NULL)
015dc7e1 5820 return false;
9ea033b2 5821
dda8d76d
NC
5822 filedata->section_headers = (Elf_Internal_Shdr *)
5823 cmalloc (num, sizeof (Elf_Internal_Shdr));
5824 if (filedata->section_headers == NULL)
9ea033b2 5825 {
049b0c3a 5826 if (! probe)
8b73c356 5827 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5828 free (shdrs);
015dc7e1 5829 return false;
9ea033b2
NC
5830 }
5831
dda8d76d 5832 for (i = 0, internal = filedata->section_headers;
560f3c1c 5833 i < num;
b34976b6 5834 i++, internal++)
9ea033b2
NC
5835 {
5836 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5837 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5838 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5839 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5840 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5841 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5842 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5843 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5844 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5845 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5846 if (!probe && internal->sh_link > num)
5847 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5848 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5849 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5850 }
5851
5852 free (shdrs);
015dc7e1 5853 return true;
9ea033b2
NC
5854}
5855
4de91c10
AM
5856static bool
5857get_section_headers (Filedata *filedata, bool probe)
5858{
5859 if (filedata->section_headers != NULL)
5860 return true;
5861
5862 if (filedata->file_header.e_shoff == 0)
5863 return true;
5864
5865 if (is_32bit_elf)
5866 return get_32bit_section_headers (filedata, probe);
5867 else
5868 return get_64bit_section_headers (filedata, probe);
5869}
5870
252b5132 5871static Elf_Internal_Sym *
dda8d76d
NC
5872get_32bit_elf_symbols (Filedata * filedata,
5873 Elf_Internal_Shdr * section,
5874 unsigned long * num_syms_return)
252b5132 5875{
ba5cdace 5876 unsigned long number = 0;
dd24e3da 5877 Elf32_External_Sym * esyms = NULL;
ba5cdace 5878 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5879 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5880 Elf_Internal_Sym * psym;
b34976b6 5881 unsigned int j;
e3d39609 5882 elf_section_list * entry;
252b5132 5883
c9c1d674
EG
5884 if (section->sh_size == 0)
5885 {
5886 if (num_syms_return != NULL)
5887 * num_syms_return = 0;
5888 return NULL;
5889 }
5890
dd24e3da 5891 /* Run some sanity checks first. */
c9c1d674 5892 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5893 {
c9c1d674 5894 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5895 printable_section_name (filedata, section),
5896 (unsigned long) section->sh_entsize);
ba5cdace 5897 goto exit_point;
dd24e3da
NC
5898 }
5899
dda8d76d 5900 if (section->sh_size > filedata->file_size)
f54498b4
NC
5901 {
5902 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5903 printable_section_name (filedata, section),
5904 (unsigned long) section->sh_size);
f54498b4
NC
5905 goto exit_point;
5906 }
5907
dd24e3da
NC
5908 number = section->sh_size / section->sh_entsize;
5909
5910 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5911 {
c9c1d674 5912 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5913 (unsigned long) section->sh_size,
dda8d76d 5914 printable_section_name (filedata, section),
8066deb1 5915 (unsigned long) section->sh_entsize);
ba5cdace 5916 goto exit_point;
dd24e3da
NC
5917 }
5918
dda8d76d 5919 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5920 section->sh_size, _("symbols"));
dd24e3da 5921 if (esyms == NULL)
ba5cdace 5922 goto exit_point;
252b5132 5923
e3d39609 5924 shndx = NULL;
978c4450 5925 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5926 {
5927 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5928 continue;
5929
5930 if (shndx != NULL)
5931 {
5932 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5933 free (shndx);
5934 }
5935
5936 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5937 entry->hdr->sh_offset,
5938 1, entry->hdr->sh_size,
5939 _("symbol table section indices"));
5940 if (shndx == NULL)
5941 goto exit_point;
5942
5943 /* PR17531: file: heap-buffer-overflow */
5944 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5945 {
5946 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5947 printable_section_name (filedata, entry->hdr),
5948 (unsigned long) entry->hdr->sh_size,
5949 (unsigned long) section->sh_size);
5950 goto exit_point;
c9c1d674 5951 }
e3d39609 5952 }
9ad5cbcf 5953
3f5e193b 5954 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5955
5956 if (isyms == NULL)
5957 {
8b73c356
NC
5958 error (_("Out of memory reading %lu symbols\n"),
5959 (unsigned long) number);
dd24e3da 5960 goto exit_point;
252b5132
RH
5961 }
5962
dd24e3da 5963 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5964 {
5965 psym->st_name = BYTE_GET (esyms[j].st_name);
5966 psym->st_value = BYTE_GET (esyms[j].st_value);
5967 psym->st_size = BYTE_GET (esyms[j].st_size);
5968 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5969 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5970 psym->st_shndx
5971 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5972 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5973 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5974 psym->st_info = BYTE_GET (esyms[j].st_info);
5975 psym->st_other = BYTE_GET (esyms[j].st_other);
5976 }
5977
dd24e3da 5978 exit_point:
e3d39609
NC
5979 free (shndx);
5980 free (esyms);
252b5132 5981
ba5cdace
NC
5982 if (num_syms_return != NULL)
5983 * num_syms_return = isyms == NULL ? 0 : number;
5984
252b5132
RH
5985 return isyms;
5986}
5987
9ea033b2 5988static Elf_Internal_Sym *
dda8d76d
NC
5989get_64bit_elf_symbols (Filedata * filedata,
5990 Elf_Internal_Shdr * section,
5991 unsigned long * num_syms_return)
9ea033b2 5992{
ba5cdace
NC
5993 unsigned long number = 0;
5994 Elf64_External_Sym * esyms = NULL;
5995 Elf_External_Sym_Shndx * shndx = NULL;
5996 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5997 Elf_Internal_Sym * psym;
b34976b6 5998 unsigned int j;
e3d39609 5999 elf_section_list * entry;
9ea033b2 6000
c9c1d674
EG
6001 if (section->sh_size == 0)
6002 {
6003 if (num_syms_return != NULL)
6004 * num_syms_return = 0;
6005 return NULL;
6006 }
6007
dd24e3da 6008 /* Run some sanity checks first. */
c9c1d674 6009 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6010 {
c9c1d674 6011 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 6012 printable_section_name (filedata, section),
8066deb1 6013 (unsigned long) section->sh_entsize);
ba5cdace 6014 goto exit_point;
dd24e3da
NC
6015 }
6016
dda8d76d 6017 if (section->sh_size > filedata->file_size)
f54498b4
NC
6018 {
6019 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 6020 printable_section_name (filedata, section),
8066deb1 6021 (unsigned long) section->sh_size);
f54498b4
NC
6022 goto exit_point;
6023 }
6024
dd24e3da
NC
6025 number = section->sh_size / section->sh_entsize;
6026
6027 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6028 {
c9c1d674 6029 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6030 (unsigned long) section->sh_size,
dda8d76d 6031 printable_section_name (filedata, section),
8066deb1 6032 (unsigned long) section->sh_entsize);
ba5cdace 6033 goto exit_point;
dd24e3da
NC
6034 }
6035
dda8d76d 6036 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6037 section->sh_size, _("symbols"));
a6e9f9df 6038 if (!esyms)
ba5cdace 6039 goto exit_point;
9ea033b2 6040
e3d39609 6041 shndx = NULL;
978c4450 6042 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6043 {
6044 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6045 continue;
6046
6047 if (shndx != NULL)
6048 {
6049 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6050 free (shndx);
c9c1d674 6051 }
e3d39609
NC
6052
6053 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6054 entry->hdr->sh_offset,
6055 1, entry->hdr->sh_size,
6056 _("symbol table section indices"));
6057 if (shndx == NULL)
6058 goto exit_point;
6059
6060 /* PR17531: file: heap-buffer-overflow */
6061 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6062 {
6063 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6064 printable_section_name (filedata, entry->hdr),
6065 (unsigned long) entry->hdr->sh_size,
6066 (unsigned long) section->sh_size);
6067 goto exit_point;
6068 }
6069 }
9ad5cbcf 6070
3f5e193b 6071 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6072
6073 if (isyms == NULL)
6074 {
8b73c356
NC
6075 error (_("Out of memory reading %lu symbols\n"),
6076 (unsigned long) number);
ba5cdace 6077 goto exit_point;
9ea033b2
NC
6078 }
6079
ba5cdace 6080 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6081 {
6082 psym->st_name = BYTE_GET (esyms[j].st_name);
6083 psym->st_info = BYTE_GET (esyms[j].st_info);
6084 psym->st_other = BYTE_GET (esyms[j].st_other);
6085 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6086
4fbb74a6 6087 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6088 psym->st_shndx
6089 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6090 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6091 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6092
66543521
AM
6093 psym->st_value = BYTE_GET (esyms[j].st_value);
6094 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6095 }
6096
ba5cdace 6097 exit_point:
e3d39609
NC
6098 free (shndx);
6099 free (esyms);
ba5cdace
NC
6100
6101 if (num_syms_return != NULL)
6102 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6103
6104 return isyms;
6105}
6106
4de91c10
AM
6107static Elf_Internal_Sym *
6108get_elf_symbols (Filedata *filedata,
6109 Elf_Internal_Shdr *section,
6110 unsigned long *num_syms_return)
6111{
6112 if (is_32bit_elf)
6113 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6114 else
6115 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6116}
6117
d1133906 6118static const char *
dda8d76d 6119get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 6120{
5477e8a0 6121 static char buff[1024];
2cf0635d 6122 char * p = buff;
32ec8896
NC
6123 unsigned int field_size = is_32bit_elf ? 8 : 16;
6124 signed int sindex;
6125 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
6126 bfd_vma os_flags = 0;
6127 bfd_vma proc_flags = 0;
6128 bfd_vma unknown_flags = 0;
148b93f2 6129 static const struct
5477e8a0 6130 {
2cf0635d 6131 const char * str;
32ec8896 6132 unsigned int len;
5477e8a0
L
6133 }
6134 flags [] =
6135 {
cfcac11d
NC
6136 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6137 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6138 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6139 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6140 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6141 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6142 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6143 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6144 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6145 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6146 /* IA-64 specific. */
6147 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6148 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6149 /* IA-64 OpenVMS specific. */
6150 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6151 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6152 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6153 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6154 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6155 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6156 /* Generic. */
cfcac11d 6157 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6158 /* SPARC specific. */
77115a4a 6159 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6160 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6161 /* ARM specific. */
6162 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6163 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6164 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6165 /* GNU specific. */
6166 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6167 /* VLE specific. */
6168 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6169 /* GNU specific. */
6170 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6171 };
6172
6173 if (do_section_details)
6174 {
8d5ff12c
L
6175 sprintf (buff, "[%*.*lx]: ",
6176 field_size, field_size, (unsigned long) sh_flags);
6177 p += field_size + 4;
5477e8a0 6178 }
76da6bbe 6179
d1133906
NC
6180 while (sh_flags)
6181 {
6182 bfd_vma flag;
6183
6184 flag = sh_flags & - sh_flags;
6185 sh_flags &= ~ flag;
76da6bbe 6186
5477e8a0 6187 if (do_section_details)
d1133906 6188 {
5477e8a0
L
6189 switch (flag)
6190 {
91d6fa6a
NC
6191 case SHF_WRITE: sindex = 0; break;
6192 case SHF_ALLOC: sindex = 1; break;
6193 case SHF_EXECINSTR: sindex = 2; break;
6194 case SHF_MERGE: sindex = 3; break;
6195 case SHF_STRINGS: sindex = 4; break;
6196 case SHF_INFO_LINK: sindex = 5; break;
6197 case SHF_LINK_ORDER: sindex = 6; break;
6198 case SHF_OS_NONCONFORMING: sindex = 7; break;
6199 case SHF_GROUP: sindex = 8; break;
6200 case SHF_TLS: sindex = 9; break;
18ae9cc1 6201 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6202 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6203
5477e8a0 6204 default:
91d6fa6a 6205 sindex = -1;
dda8d76d 6206 switch (filedata->file_header.e_machine)
148b93f2 6207 {
cfcac11d 6208 case EM_IA_64:
148b93f2 6209 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6210 sindex = 10;
148b93f2 6211 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6212 sindex = 11;
148b93f2 6213#ifdef BFD64
dda8d76d 6214 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6215 switch (flag)
6216 {
91d6fa6a
NC
6217 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6218 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6219 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6220 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6221 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6222 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6223 default: break;
6224 }
6225#endif
cfcac11d
NC
6226 break;
6227
caa83f8b 6228 case EM_386:
22abe556 6229 case EM_IAMCU:
caa83f8b 6230 case EM_X86_64:
7f502d6c 6231 case EM_L1OM:
7a9068fe 6232 case EM_K1OM:
cfcac11d
NC
6233 case EM_OLD_SPARCV9:
6234 case EM_SPARC32PLUS:
6235 case EM_SPARCV9:
6236 case EM_SPARC:
18ae9cc1 6237 if (flag == SHF_ORDERED)
91d6fa6a 6238 sindex = 19;
cfcac11d 6239 break;
ac4c9b04
MG
6240
6241 case EM_ARM:
6242 switch (flag)
6243 {
6244 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6245 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6246 case SHF_COMDEF: sindex = 23; break;
6247 default: break;
6248 }
6249 break;
83eef883
AFB
6250 case EM_PPC:
6251 if (flag == SHF_PPC_VLE)
6252 sindex = 25;
6253 break;
99fabbc9
JL
6254 default:
6255 break;
6256 }
ac4c9b04 6257
99fabbc9
JL
6258 switch (filedata->file_header.e_ident[EI_OSABI])
6259 {
6260 case ELFOSABI_GNU:
6261 case ELFOSABI_FREEBSD:
6262 if (flag == SHF_GNU_RETAIN)
6263 sindex = 26;
6264 /* Fall through */
6265 case ELFOSABI_NONE:
6266 if (flag == SHF_GNU_MBIND)
6267 /* We should not recognize SHF_GNU_MBIND for
6268 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6269 not set the EI_OSABI header byte. */
6270 sindex = 24;
6271 break;
cfcac11d
NC
6272 default:
6273 break;
148b93f2 6274 }
99fabbc9 6275 break;
5477e8a0
L
6276 }
6277
91d6fa6a 6278 if (sindex != -1)
5477e8a0 6279 {
8d5ff12c
L
6280 if (p != buff + field_size + 4)
6281 {
6282 if (size < (10 + 2))
bee0ee85
NC
6283 {
6284 warn (_("Internal error: not enough buffer room for section flag info"));
6285 return _("<unknown>");
6286 }
8d5ff12c
L
6287 size -= 2;
6288 *p++ = ',';
6289 *p++ = ' ';
6290 }
6291
91d6fa6a
NC
6292 size -= flags [sindex].len;
6293 p = stpcpy (p, flags [sindex].str);
5477e8a0 6294 }
3b22753a 6295 else if (flag & SHF_MASKOS)
8d5ff12c 6296 os_flags |= flag;
d1133906 6297 else if (flag & SHF_MASKPROC)
8d5ff12c 6298 proc_flags |= flag;
d1133906 6299 else
8d5ff12c 6300 unknown_flags |= flag;
5477e8a0
L
6301 }
6302 else
6303 {
6304 switch (flag)
6305 {
6306 case SHF_WRITE: *p = 'W'; break;
6307 case SHF_ALLOC: *p = 'A'; break;
6308 case SHF_EXECINSTR: *p = 'X'; break;
6309 case SHF_MERGE: *p = 'M'; break;
6310 case SHF_STRINGS: *p = 'S'; break;
6311 case SHF_INFO_LINK: *p = 'I'; break;
6312 case SHF_LINK_ORDER: *p = 'L'; break;
6313 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6314 case SHF_GROUP: *p = 'G'; break;
6315 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6316 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6317 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6318
6319 default:
dda8d76d
NC
6320 if ((filedata->file_header.e_machine == EM_X86_64
6321 || filedata->file_header.e_machine == EM_L1OM
6322 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6323 && flag == SHF_X86_64_LARGE)
6324 *p = 'l';
dda8d76d 6325 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6326 && flag == SHF_ARM_PURECODE)
99fabbc9 6327 *p = 'y';
dda8d76d 6328 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6329 && flag == SHF_PPC_VLE)
99fabbc9 6330 *p = 'v';
5477e8a0
L
6331 else if (flag & SHF_MASKOS)
6332 {
99fabbc9
JL
6333 switch (filedata->file_header.e_ident[EI_OSABI])
6334 {
6335 case ELFOSABI_GNU:
6336 case ELFOSABI_FREEBSD:
6337 if (flag == SHF_GNU_RETAIN)
6338 {
6339 *p = 'R';
6340 break;
6341 }
6342 /* Fall through */
6343 case ELFOSABI_NONE:
6344 if (flag == SHF_GNU_MBIND)
6345 {
6346 /* We should not recognize SHF_GNU_MBIND for
6347 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6348 not set the EI_OSABI header byte. */
6349 *p = 'D';
6350 break;
6351 }
6352 /* Fall through */
6353 default:
6354 *p = 'o';
6355 sh_flags &= ~SHF_MASKOS;
6356 break;
6357 }
5477e8a0
L
6358 }
6359 else if (flag & SHF_MASKPROC)
6360 {
6361 *p = 'p';
6362 sh_flags &= ~ SHF_MASKPROC;
6363 }
6364 else
6365 *p = 'x';
6366 break;
6367 }
6368 p++;
d1133906
NC
6369 }
6370 }
76da6bbe 6371
8d5ff12c
L
6372 if (do_section_details)
6373 {
6374 if (os_flags)
6375 {
6376 size -= 5 + field_size;
6377 if (p != buff + field_size + 4)
6378 {
6379 if (size < (2 + 1))
bee0ee85
NC
6380 {
6381 warn (_("Internal error: not enough buffer room for section flag info"));
6382 return _("<unknown>");
6383 }
8d5ff12c
L
6384 size -= 2;
6385 *p++ = ',';
6386 *p++ = ' ';
6387 }
6388 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6389 (unsigned long) os_flags);
6390 p += 5 + field_size;
6391 }
6392 if (proc_flags)
6393 {
6394 size -= 7 + field_size;
6395 if (p != buff + field_size + 4)
6396 {
6397 if (size < (2 + 1))
bee0ee85
NC
6398 {
6399 warn (_("Internal error: not enough buffer room for section flag info"));
6400 return _("<unknown>");
6401 }
8d5ff12c
L
6402 size -= 2;
6403 *p++ = ',';
6404 *p++ = ' ';
6405 }
6406 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6407 (unsigned long) proc_flags);
6408 p += 7 + field_size;
6409 }
6410 if (unknown_flags)
6411 {
6412 size -= 10 + field_size;
6413 if (p != buff + field_size + 4)
6414 {
6415 if (size < (2 + 1))
bee0ee85
NC
6416 {
6417 warn (_("Internal error: not enough buffer room for section flag info"));
6418 return _("<unknown>");
6419 }
8d5ff12c
L
6420 size -= 2;
6421 *p++ = ',';
6422 *p++ = ' ';
6423 }
2b692964 6424 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6425 (unsigned long) unknown_flags);
6426 p += 10 + field_size;
6427 }
6428 }
6429
e9e44622 6430 *p = '\0';
d1133906
NC
6431 return buff;
6432}
6433
5844b465 6434static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6435get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6436{
6437 if (is_32bit_elf)
6438 {
6439 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6440
ebdf1ebf
NC
6441 if (size < sizeof (* echdr))
6442 {
6443 error (_("Compressed section is too small even for a compression header\n"));
6444 return 0;
6445 }
6446
77115a4a
L
6447 chdr->ch_type = BYTE_GET (echdr->ch_type);
6448 chdr->ch_size = BYTE_GET (echdr->ch_size);
6449 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6450 return sizeof (*echdr);
6451 }
6452 else
6453 {
6454 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6455
ebdf1ebf
NC
6456 if (size < sizeof (* echdr))
6457 {
6458 error (_("Compressed section is too small even for a compression header\n"));
6459 return 0;
6460 }
6461
77115a4a
L
6462 chdr->ch_type = BYTE_GET (echdr->ch_type);
6463 chdr->ch_size = BYTE_GET (echdr->ch_size);
6464 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6465 return sizeof (*echdr);
6466 }
6467}
6468
015dc7e1 6469static bool
dda8d76d 6470process_section_headers (Filedata * filedata)
252b5132 6471{
2cf0635d 6472 Elf_Internal_Shdr * section;
b34976b6 6473 unsigned int i;
252b5132 6474
dda8d76d 6475 if (filedata->file_header.e_shnum == 0)
252b5132 6476 {
82f2dbf7 6477 /* PR binutils/12467. */
dda8d76d 6478 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6479 {
6480 warn (_("possibly corrupt ELF file header - it has a non-zero"
6481 " section header offset, but no section headers\n"));
015dc7e1 6482 return false;
32ec8896 6483 }
82f2dbf7 6484 else if (do_sections)
252b5132
RH
6485 printf (_("\nThere are no sections in this file.\n"));
6486
015dc7e1 6487 return true;
252b5132
RH
6488 }
6489
6490 if (do_sections && !do_header)
ca0e11aa
NC
6491 {
6492 if (filedata->is_separate && process_links)
6493 printf (_("In linked file '%s': "), filedata->file_name);
6494 if (! filedata->is_separate || process_links)
6495 printf (ngettext ("There is %d section header, "
6496 "starting at offset 0x%lx:\n",
6497 "There are %d section headers, "
6498 "starting at offset 0x%lx:\n",
6499 filedata->file_header.e_shnum),
6500 filedata->file_header.e_shnum,
6501 (unsigned long) filedata->file_header.e_shoff);
6502 }
252b5132 6503
4de91c10
AM
6504 if (!get_section_headers (filedata, false))
6505 return false;
252b5132
RH
6506
6507 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6508 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6509 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6510 {
dda8d76d 6511 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6512
c256ffe7
JJ
6513 if (section->sh_size != 0)
6514 {
dda8d76d
NC
6515 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6516 1, section->sh_size,
6517 _("string table"));
0de14b54 6518
dda8d76d 6519 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6520 }
252b5132
RH
6521 }
6522
6523 /* Scan the sections for the dynamic symbol table
e3c8793a 6524 and dynamic string table and debug sections. */
89fac5e3 6525 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6526 switch (filedata->file_header.e_machine)
89fac5e3
RS
6527 {
6528 case EM_MIPS:
6529 case EM_MIPS_RS3_LE:
6530 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6531 FDE addresses. However, the ABI also has a semi-official ILP32
6532 variant for which the normal FDE address size rules apply.
6533
6534 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6535 section, where XX is the size of longs in bits. Unfortunately,
6536 earlier compilers provided no way of distinguishing ILP32 objects
6537 from LP64 objects, so if there's any doubt, we should assume that
6538 the official LP64 form is being used. */
dda8d76d
NC
6539 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6540 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6541 eh_addr_size = 8;
6542 break;
0f56a26a
DD
6543
6544 case EM_H8_300:
6545 case EM_H8_300H:
dda8d76d 6546 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6547 {
6548 case E_H8_MACH_H8300:
6549 case E_H8_MACH_H8300HN:
6550 case E_H8_MACH_H8300SN:
6551 case E_H8_MACH_H8300SXN:
6552 eh_addr_size = 2;
6553 break;
6554 case E_H8_MACH_H8300H:
6555 case E_H8_MACH_H8300S:
6556 case E_H8_MACH_H8300SX:
6557 eh_addr_size = 4;
6558 break;
6559 }
f4236fe4
DD
6560 break;
6561
ff7eeb89 6562 case EM_M32C_OLD:
f4236fe4 6563 case EM_M32C:
dda8d76d 6564 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6565 {
6566 case EF_M32C_CPU_M16C:
6567 eh_addr_size = 2;
6568 break;
6569 }
6570 break;
89fac5e3
RS
6571 }
6572
76ca31c0
NC
6573#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6574 do \
6575 { \
6576 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6577 if (section->sh_entsize != expected_entsize) \
9dd3a467 6578 { \
76ca31c0
NC
6579 char buf[40]; \
6580 sprintf_vma (buf, section->sh_entsize); \
6581 /* Note: coded this way so that there is a single string for \
6582 translation. */ \
6583 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6584 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6585 (unsigned) expected_entsize); \
9dd3a467 6586 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6587 } \
6588 } \
08d8fa11 6589 while (0)
9dd3a467
NC
6590
6591#define CHECK_ENTSIZE(section, i, type) \
1b513401 6592 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
6593 sizeof (Elf64_External_##type))
6594
dda8d76d
NC
6595 for (i = 0, section = filedata->section_headers;
6596 i < filedata->file_header.e_shnum;
b34976b6 6597 i++, section++)
252b5132 6598 {
b9e920ec 6599 char * name = SECTION_NAME_PRINT (section);
252b5132 6600
1b513401
NC
6601 /* Run some sanity checks on the headers and
6602 possibly fill in some file data as well. */
6603 switch (section->sh_type)
252b5132 6604 {
1b513401 6605 case SHT_DYNSYM:
978c4450 6606 if (filedata->dynamic_symbols != NULL)
252b5132
RH
6607 {
6608 error (_("File contains multiple dynamic symbol tables\n"));
6609 continue;
6610 }
6611
08d8fa11 6612 CHECK_ENTSIZE (section, i, Sym);
978c4450 6613 filedata->dynamic_symbols
4de91c10 6614 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 6615 filedata->dynamic_symtab_section = section;
1b513401
NC
6616 break;
6617
6618 case SHT_STRTAB:
6619 if (streq (name, ".dynstr"))
252b5132 6620 {
1b513401
NC
6621 if (filedata->dynamic_strings != NULL)
6622 {
6623 error (_("File contains multiple dynamic string tables\n"));
6624 continue;
6625 }
6626
6627 filedata->dynamic_strings
6628 = (char *) get_data (NULL, filedata, section->sh_offset,
6629 1, section->sh_size, _("dynamic strings"));
6630 filedata->dynamic_strings_length
6631 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 6632 filedata->dynamic_strtab_section = section;
252b5132 6633 }
1b513401
NC
6634 break;
6635
6636 case SHT_SYMTAB_SHNDX:
6637 {
6638 elf_section_list * entry = xmalloc (sizeof * entry);
6639
6640 entry->hdr = section;
6641 entry->next = filedata->symtab_shndx_list;
6642 filedata->symtab_shndx_list = entry;
6643 }
6644 break;
6645
6646 case SHT_SYMTAB:
6647 CHECK_ENTSIZE (section, i, Sym);
6648 break;
6649
6650 case SHT_GROUP:
6651 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6652 break;
252b5132 6653
1b513401
NC
6654 case SHT_REL:
6655 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 6656 if (do_checks && section->sh_size == 0)
1b513401
NC
6657 warn (_("Section '%s': zero-sized relocation section\n"), name);
6658 break;
6659
6660 case SHT_RELA:
6661 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 6662 if (do_checks && section->sh_size == 0)
1b513401
NC
6663 warn (_("Section '%s': zero-sized relocation section\n"), name);
6664 break;
6665
6666 case SHT_NOTE:
6667 case SHT_PROGBITS:
546cb2d8
NC
6668 /* Having a zero sized section is not illegal according to the
6669 ELF standard, but it might be an indication that something
6670 is wrong. So issue a warning if we are running in lint mode. */
6671 if (do_checks && section->sh_size == 0)
1b513401
NC
6672 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
6673 break;
6674
6675 default:
6676 break;
6677 }
6678
6679 if ((do_debugging || do_debug_info || do_debug_abbrevs
6680 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
6681 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
6682 || do_debug_str || do_debug_str_offsets || do_debug_loc
6683 || do_debug_ranges
1b513401 6684 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
6685 && (startswith (name, ".debug_")
6686 || startswith (name, ".zdebug_")))
252b5132 6687 {
1b315056
CS
6688 if (name[1] == 'z')
6689 name += sizeof (".zdebug_") - 1;
6690 else
6691 name += sizeof (".debug_") - 1;
252b5132
RH
6692
6693 if (do_debugging
24d127aa
ML
6694 || (do_debug_info && startswith (name, "info"))
6695 || (do_debug_info && startswith (name, "types"))
6696 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 6697 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
6698 || (do_debug_lines && startswith (name, "line."))
6699 || (do_debug_pubnames && startswith (name, "pubnames"))
6700 || (do_debug_pubtypes && startswith (name, "pubtypes"))
6701 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
6702 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
6703 || (do_debug_aranges && startswith (name, "aranges"))
6704 || (do_debug_ranges && startswith (name, "ranges"))
6705 || (do_debug_ranges && startswith (name, "rnglists"))
6706 || (do_debug_frames && startswith (name, "frame"))
6707 || (do_debug_macinfo && startswith (name, "macinfo"))
6708 || (do_debug_macinfo && startswith (name, "macro"))
6709 || (do_debug_str && startswith (name, "str"))
6710 || (do_debug_links && startswith (name, "sup"))
6711 || (do_debug_str_offsets && startswith (name, "str_offsets"))
6712 || (do_debug_loc && startswith (name, "loc"))
6713 || (do_debug_loc && startswith (name, "loclists"))
6714 || (do_debug_addr && startswith (name, "addr"))
6715 || (do_debug_cu_index && startswith (name, "cu_index"))
6716 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 6717 )
6431e409 6718 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6719 }
a262ae96 6720 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6721 else if ((do_debugging || do_debug_info)
24d127aa 6722 && startswith (name, ".gnu.linkonce.wi."))
6431e409 6723 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6724 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6725 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6726 else if (do_gdb_index && (streq (name, ".gdb_index")
6727 || streq (name, ".debug_names")))
6431e409 6728 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6729 /* Trace sections for Itanium VMS. */
6730 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6731 || do_trace_aranges)
24d127aa 6732 && startswith (name, ".trace_"))
6f875884
TG
6733 {
6734 name += sizeof (".trace_") - 1;
6735
6736 if (do_debugging
6737 || (do_trace_info && streq (name, "info"))
6738 || (do_trace_abbrevs && streq (name, "abbrev"))
6739 || (do_trace_aranges && streq (name, "aranges"))
6740 )
6431e409 6741 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6742 }
dda8d76d 6743 else if ((do_debugging || do_debug_links)
24d127aa
ML
6744 && (startswith (name, ".gnu_debuglink")
6745 || startswith (name, ".gnu_debugaltlink")))
6431e409 6746 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6747 }
6748
6749 if (! do_sections)
015dc7e1 6750 return true;
252b5132 6751
ca0e11aa 6752 if (filedata->is_separate && ! process_links)
015dc7e1 6753 return true;
ca0e11aa
NC
6754
6755 if (filedata->is_separate)
6756 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
6757 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6758 printf (_("\nSection Headers:\n"));
6759 else
6760 printf (_("\nSection Header:\n"));
76da6bbe 6761
f7a99963 6762 if (is_32bit_elf)
595cf52e 6763 {
5477e8a0 6764 if (do_section_details)
595cf52e
L
6765 {
6766 printf (_(" [Nr] Name\n"));
5477e8a0 6767 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6768 }
6769 else
6770 printf
6771 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6772 }
d974e256 6773 else if (do_wide)
595cf52e 6774 {
5477e8a0 6775 if (do_section_details)
595cf52e
L
6776 {
6777 printf (_(" [Nr] Name\n"));
5477e8a0 6778 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6779 }
6780 else
6781 printf
6782 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6783 }
f7a99963
NC
6784 else
6785 {
5477e8a0 6786 if (do_section_details)
595cf52e
L
6787 {
6788 printf (_(" [Nr] Name\n"));
5477e8a0
L
6789 printf (_(" Type Address Offset Link\n"));
6790 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6791 }
6792 else
6793 {
6794 printf (_(" [Nr] Name Type Address Offset\n"));
6795 printf (_(" Size EntSize Flags Link Info Align\n"));
6796 }
f7a99963 6797 }
252b5132 6798
5477e8a0
L
6799 if (do_section_details)
6800 printf (_(" Flags\n"));
6801
dda8d76d
NC
6802 for (i = 0, section = filedata->section_headers;
6803 i < filedata->file_header.e_shnum;
b34976b6 6804 i++, section++)
252b5132 6805 {
dd905818
NC
6806 /* Run some sanity checks on the section header. */
6807
6808 /* Check the sh_link field. */
6809 switch (section->sh_type)
6810 {
285e3f99
AM
6811 case SHT_REL:
6812 case SHT_RELA:
6813 if (section->sh_link == 0
6814 && (filedata->file_header.e_type == ET_EXEC
6815 || filedata->file_header.e_type == ET_DYN))
6816 /* A dynamic relocation section where all entries use a
6817 zero symbol index need not specify a symtab section. */
6818 break;
6819 /* Fall through. */
dd905818
NC
6820 case SHT_SYMTAB_SHNDX:
6821 case SHT_GROUP:
6822 case SHT_HASH:
6823 case SHT_GNU_HASH:
6824 case SHT_GNU_versym:
285e3f99 6825 if (section->sh_link == 0
dda8d76d
NC
6826 || section->sh_link >= filedata->file_header.e_shnum
6827 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6828 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6829 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6830 i, section->sh_link);
6831 break;
6832
6833 case SHT_DYNAMIC:
6834 case SHT_SYMTAB:
6835 case SHT_DYNSYM:
6836 case SHT_GNU_verneed:
6837 case SHT_GNU_verdef:
6838 case SHT_GNU_LIBLIST:
285e3f99 6839 if (section->sh_link == 0
dda8d76d
NC
6840 || section->sh_link >= filedata->file_header.e_shnum
6841 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6842 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6843 i, section->sh_link);
6844 break;
6845
6846 case SHT_INIT_ARRAY:
6847 case SHT_FINI_ARRAY:
6848 case SHT_PREINIT_ARRAY:
6849 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6850 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6851 i, section->sh_link);
6852 break;
6853
6854 default:
6855 /* FIXME: Add support for target specific section types. */
6856#if 0 /* Currently we do not check other section types as there are too
6857 many special cases. Stab sections for example have a type
6858 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6859 section. */
6860 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6861 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6862 i, section->sh_link);
6863#endif
6864 break;
6865 }
6866
6867 /* Check the sh_info field. */
6868 switch (section->sh_type)
6869 {
6870 case SHT_REL:
6871 case SHT_RELA:
285e3f99
AM
6872 if (section->sh_info == 0
6873 && (filedata->file_header.e_type == ET_EXEC
6874 || filedata->file_header.e_type == ET_DYN))
6875 /* Dynamic relocations apply to segments, so they do not
6876 need to specify the section they relocate. */
6877 break;
6878 if (section->sh_info == 0
dda8d76d
NC
6879 || section->sh_info >= filedata->file_header.e_shnum
6880 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6881 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6882 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6883 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6884 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6885 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6886 /* FIXME: Are other section types valid ? */
dda8d76d 6887 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6888 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6889 i, section->sh_info);
dd905818
NC
6890 break;
6891
6892 case SHT_DYNAMIC:
6893 case SHT_HASH:
6894 case SHT_SYMTAB_SHNDX:
6895 case SHT_INIT_ARRAY:
6896 case SHT_FINI_ARRAY:
6897 case SHT_PREINIT_ARRAY:
6898 if (section->sh_info != 0)
6899 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6900 i, section->sh_info);
6901 break;
6902
6903 case SHT_GROUP:
6904 case SHT_SYMTAB:
6905 case SHT_DYNSYM:
6906 /* A symbol index - we assume that it is valid. */
6907 break;
6908
6909 default:
6910 /* FIXME: Add support for target specific section types. */
6911 if (section->sh_type == SHT_NOBITS)
6912 /* NOBITS section headers with non-zero sh_info fields can be
6913 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6914 information. The stripped sections have their headers
6915 preserved but their types set to SHT_NOBITS. So do not check
6916 this type of section. */
dd905818
NC
6917 ;
6918 else if (section->sh_flags & SHF_INFO_LINK)
6919 {
dda8d76d 6920 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6921 warn (_("[%2u]: Expected link to another section in info field"), i);
6922 }
a91e1603
L
6923 else if (section->sh_type < SHT_LOOS
6924 && (section->sh_flags & SHF_GNU_MBIND) == 0
6925 && section->sh_info != 0)
dd905818
NC
6926 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6927 i, section->sh_info);
6928 break;
6929 }
6930
3e6b6445 6931 /* Check the sh_size field. */
dda8d76d 6932 if (section->sh_size > filedata->file_size
3e6b6445
NC
6933 && section->sh_type != SHT_NOBITS
6934 && section->sh_type != SHT_NULL
6935 && section->sh_type < SHT_LOOS)
6936 warn (_("Size of section %u is larger than the entire file!\n"), i);
6937
7bfd842d 6938 printf (" [%2u] ", i);
5477e8a0 6939 if (do_section_details)
dda8d76d 6940 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6941 else
b9e920ec 6942 print_symbol (-17, SECTION_NAME_PRINT (section));
0b4362b0 6943
ea52a088 6944 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6945 get_section_type_name (filedata, section->sh_type));
0b4362b0 6946
f7a99963
NC
6947 if (is_32bit_elf)
6948 {
cfcac11d
NC
6949 const char * link_too_big = NULL;
6950
f7a99963 6951 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6952
f7a99963
NC
6953 printf ( " %6.6lx %6.6lx %2.2lx",
6954 (unsigned long) section->sh_offset,
6955 (unsigned long) section->sh_size,
6956 (unsigned long) section->sh_entsize);
d1133906 6957
5477e8a0
L
6958 if (do_section_details)
6959 fputs (" ", stdout);
6960 else
dda8d76d 6961 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6962
dda8d76d 6963 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6964 {
6965 link_too_big = "";
6966 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6967 an error but it can have special values in Solaris binaries. */
dda8d76d 6968 switch (filedata->file_header.e_machine)
cfcac11d 6969 {
caa83f8b 6970 case EM_386:
22abe556 6971 case EM_IAMCU:
caa83f8b 6972 case EM_X86_64:
7f502d6c 6973 case EM_L1OM:
7a9068fe 6974 case EM_K1OM:
cfcac11d
NC
6975 case EM_OLD_SPARCV9:
6976 case EM_SPARC32PLUS:
6977 case EM_SPARCV9:
6978 case EM_SPARC:
6979 if (section->sh_link == (SHN_BEFORE & 0xffff))
6980 link_too_big = "BEFORE";
6981 else if (section->sh_link == (SHN_AFTER & 0xffff))
6982 link_too_big = "AFTER";
6983 break;
6984 default:
6985 break;
6986 }
6987 }
6988
6989 if (do_section_details)
6990 {
6991 if (link_too_big != NULL && * link_too_big)
6992 printf ("<%s> ", link_too_big);
6993 else
6994 printf ("%2u ", section->sh_link);
6995 printf ("%3u %2lu\n", section->sh_info,
6996 (unsigned long) section->sh_addralign);
6997 }
6998 else
6999 printf ("%2u %3u %2lu\n",
7000 section->sh_link,
7001 section->sh_info,
7002 (unsigned long) section->sh_addralign);
7003
7004 if (link_too_big && ! * link_too_big)
7005 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7006 i, section->sh_link);
f7a99963 7007 }
d974e256
JJ
7008 else if (do_wide)
7009 {
7010 print_vma (section->sh_addr, LONG_HEX);
7011
7012 if ((long) section->sh_offset == section->sh_offset)
7013 printf (" %6.6lx", (unsigned long) section->sh_offset);
7014 else
7015 {
7016 putchar (' ');
7017 print_vma (section->sh_offset, LONG_HEX);
7018 }
7019
7020 if ((unsigned long) section->sh_size == section->sh_size)
7021 printf (" %6.6lx", (unsigned long) section->sh_size);
7022 else
7023 {
7024 putchar (' ');
7025 print_vma (section->sh_size, LONG_HEX);
7026 }
7027
7028 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7029 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7030 else
7031 {
7032 putchar (' ');
7033 print_vma (section->sh_entsize, LONG_HEX);
7034 }
7035
5477e8a0
L
7036 if (do_section_details)
7037 fputs (" ", stdout);
7038 else
dda8d76d 7039 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7040
72de5009 7041 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7042
7043 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7044 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7045 else
7046 {
7047 print_vma (section->sh_addralign, DEC);
7048 putchar ('\n');
7049 }
7050 }
5477e8a0 7051 else if (do_section_details)
595cf52e 7052 {
55cc53e9 7053 putchar (' ');
595cf52e
L
7054 print_vma (section->sh_addr, LONG_HEX);
7055 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7056 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7057 else
7058 {
7059 printf (" ");
7060 print_vma (section->sh_offset, LONG_HEX);
7061 }
72de5009 7062 printf (" %u\n ", section->sh_link);
595cf52e 7063 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7064 putchar (' ');
595cf52e
L
7065 print_vma (section->sh_entsize, LONG_HEX);
7066
72de5009
AM
7067 printf (" %-16u %lu\n",
7068 section->sh_info,
595cf52e
L
7069 (unsigned long) section->sh_addralign);
7070 }
f7a99963
NC
7071 else
7072 {
7073 putchar (' ');
7074 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7075 if ((long) section->sh_offset == section->sh_offset)
7076 printf (" %8.8lx", (unsigned long) section->sh_offset);
7077 else
7078 {
7079 printf (" ");
7080 print_vma (section->sh_offset, LONG_HEX);
7081 }
f7a99963
NC
7082 printf ("\n ");
7083 print_vma (section->sh_size, LONG_HEX);
7084 printf (" ");
7085 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7086
dda8d76d 7087 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7088
72de5009
AM
7089 printf (" %2u %3u %lu\n",
7090 section->sh_link,
7091 section->sh_info,
f7a99963
NC
7092 (unsigned long) section->sh_addralign);
7093 }
5477e8a0
L
7094
7095 if (do_section_details)
77115a4a 7096 {
dda8d76d 7097 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7098 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7099 {
7100 /* Minimum section size is 12 bytes for 32-bit compression
7101 header + 12 bytes for compressed data header. */
7102 unsigned char buf[24];
d8024a91 7103
77115a4a 7104 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7105 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7106 sizeof (buf), _("compression header")))
7107 {
7108 Elf_Internal_Chdr chdr;
d8024a91 7109
5844b465
NC
7110 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7111 printf (_(" [<corrupt>]\n"));
77115a4a 7112 else
5844b465
NC
7113 {
7114 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7115 printf (" ZLIB, ");
7116 else
7117 printf (_(" [<unknown>: 0x%x], "),
7118 chdr.ch_type);
7119 print_vma (chdr.ch_size, LONG_HEX);
7120 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7121 }
77115a4a
L
7122 }
7123 }
7124 }
252b5132
RH
7125 }
7126
5477e8a0 7127 if (!do_section_details)
3dbcc61d 7128 {
9fb71ee4
NC
7129 /* The ordering of the letters shown here matches the ordering of the
7130 corresponding SHF_xxx values, and hence the order in which these
7131 letters will be displayed to the user. */
7132 printf (_("Key to Flags:\n\
7133 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7134 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7135 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7136 switch (filedata->file_header.e_ident[EI_OSABI])
7137 {
7138 case ELFOSABI_GNU:
7139 case ELFOSABI_FREEBSD:
7140 printf (_("R (retain), "));
7141 /* Fall through */
7142 case ELFOSABI_NONE:
7143 printf (_("D (mbind), "));
7144 break;
7145 default:
7146 break;
7147 }
dda8d76d
NC
7148 if (filedata->file_header.e_machine == EM_X86_64
7149 || filedata->file_header.e_machine == EM_L1OM
7150 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7151 printf (_("l (large), "));
dda8d76d 7152 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7153 printf (_("y (purecode), "));
dda8d76d 7154 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7155 printf (_("v (VLE), "));
9fb71ee4 7156 printf ("p (processor specific)\n");
0b4362b0 7157 }
d1133906 7158
015dc7e1 7159 return true;
252b5132
RH
7160}
7161
015dc7e1 7162static bool
28d13567
AM
7163get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7164 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7165 char **strtab, unsigned long *strtablen)
7166{
7167 *strtab = NULL;
7168 *strtablen = 0;
4de91c10 7169 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7170
7171 if (*symtab == NULL)
015dc7e1 7172 return false;
28d13567
AM
7173
7174 if (symsec->sh_link != 0)
7175 {
7176 Elf_Internal_Shdr *strsec;
7177
7178 if (symsec->sh_link >= filedata->file_header.e_shnum)
7179 {
7180 error (_("Bad sh_link in symbol table section\n"));
7181 free (*symtab);
7182 *symtab = NULL;
7183 *nsyms = 0;
015dc7e1 7184 return false;
28d13567
AM
7185 }
7186
7187 strsec = filedata->section_headers + symsec->sh_link;
7188
7189 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7190 1, strsec->sh_size, _("string table"));
7191 if (*strtab == NULL)
7192 {
7193 free (*symtab);
7194 *symtab = NULL;
7195 *nsyms = 0;
015dc7e1 7196 return false;
28d13567
AM
7197 }
7198 *strtablen = strsec->sh_size;
7199 }
015dc7e1 7200 return true;
28d13567
AM
7201}
7202
f5842774
L
7203static const char *
7204get_group_flags (unsigned int flags)
7205{
1449284b 7206 static char buff[128];
220453ec 7207
6d913794
NC
7208 if (flags == 0)
7209 return "";
7210 else if (flags == GRP_COMDAT)
7211 return "COMDAT ";
f5842774 7212
89246a0e
AM
7213 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7214 flags,
7215 flags & GRP_MASKOS ? _("<OS specific>") : "",
7216 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7217 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7218 ? _("<unknown>") : ""));
6d913794 7219
f5842774
L
7220 return buff;
7221}
7222
015dc7e1 7223static bool
dda8d76d 7224process_section_groups (Filedata * filedata)
f5842774 7225{
2cf0635d 7226 Elf_Internal_Shdr * section;
f5842774 7227 unsigned int i;
2cf0635d
NC
7228 struct group * group;
7229 Elf_Internal_Shdr * symtab_sec;
7230 Elf_Internal_Shdr * strtab_sec;
7231 Elf_Internal_Sym * symtab;
ba5cdace 7232 unsigned long num_syms;
2cf0635d 7233 char * strtab;
c256ffe7 7234 size_t strtab_size;
d1f5c6e3
L
7235
7236 /* Don't process section groups unless needed. */
7237 if (!do_unwind && !do_section_groups)
015dc7e1 7238 return true;
f5842774 7239
dda8d76d 7240 if (filedata->file_header.e_shnum == 0)
f5842774
L
7241 {
7242 if (do_section_groups)
ca0e11aa
NC
7243 {
7244 if (filedata->is_separate)
7245 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7246 filedata->file_name);
7247 else
7248 printf (_("\nThere are no section groups in this file.\n"));
7249 }
015dc7e1 7250 return true;
f5842774
L
7251 }
7252
dda8d76d 7253 if (filedata->section_headers == NULL)
f5842774
L
7254 {
7255 error (_("Section headers are not available!\n"));
fa1908fd 7256 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7257 return false;
f5842774
L
7258 }
7259
978c4450
AM
7260 filedata->section_headers_groups
7261 = (struct group **) calloc (filedata->file_header.e_shnum,
7262 sizeof (struct group *));
e4b17d5c 7263
978c4450 7264 if (filedata->section_headers_groups == NULL)
e4b17d5c 7265 {
8b73c356 7266 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7267 filedata->file_header.e_shnum);
015dc7e1 7268 return false;
e4b17d5c
L
7269 }
7270
f5842774 7271 /* Scan the sections for the group section. */
978c4450 7272 filedata->group_count = 0;
dda8d76d
NC
7273 for (i = 0, section = filedata->section_headers;
7274 i < filedata->file_header.e_shnum;
f5842774 7275 i++, section++)
e4b17d5c 7276 if (section->sh_type == SHT_GROUP)
978c4450 7277 filedata->group_count++;
e4b17d5c 7278
978c4450 7279 if (filedata->group_count == 0)
d1f5c6e3
L
7280 {
7281 if (do_section_groups)
ca0e11aa
NC
7282 {
7283 if (filedata->is_separate)
7284 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7285 filedata->file_name);
7286 else
7287 printf (_("\nThere are no section groups in this file.\n"));
7288 }
d1f5c6e3 7289
015dc7e1 7290 return true;
d1f5c6e3
L
7291 }
7292
978c4450
AM
7293 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7294 sizeof (struct group));
e4b17d5c 7295
978c4450 7296 if (filedata->section_groups == NULL)
e4b17d5c 7297 {
8b73c356 7298 error (_("Out of memory reading %lu groups\n"),
978c4450 7299 (unsigned long) filedata->group_count);
015dc7e1 7300 return false;
e4b17d5c
L
7301 }
7302
d1f5c6e3
L
7303 symtab_sec = NULL;
7304 strtab_sec = NULL;
7305 symtab = NULL;
ba5cdace 7306 num_syms = 0;
d1f5c6e3 7307 strtab = NULL;
c256ffe7 7308 strtab_size = 0;
ca0e11aa
NC
7309
7310 if (filedata->is_separate)
7311 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7312
978c4450 7313 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7314 i < filedata->file_header.e_shnum;
e4b17d5c 7315 i++, section++)
f5842774
L
7316 {
7317 if (section->sh_type == SHT_GROUP)
7318 {
dda8d76d 7319 const char * name = printable_section_name (filedata, section);
74e1a04b 7320 const char * group_name;
2cf0635d
NC
7321 unsigned char * start;
7322 unsigned char * indices;
f5842774 7323 unsigned int entry, j, size;
2cf0635d
NC
7324 Elf_Internal_Shdr * sec;
7325 Elf_Internal_Sym * sym;
f5842774
L
7326
7327 /* Get the symbol table. */
dda8d76d
NC
7328 if (section->sh_link >= filedata->file_header.e_shnum
7329 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7330 != SHT_SYMTAB))
f5842774
L
7331 {
7332 error (_("Bad sh_link in group section `%s'\n"), name);
7333 continue;
7334 }
d1f5c6e3
L
7335
7336 if (symtab_sec != sec)
7337 {
7338 symtab_sec = sec;
9db70fc3 7339 free (symtab);
4de91c10 7340 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 7341 }
f5842774 7342
dd24e3da
NC
7343 if (symtab == NULL)
7344 {
7345 error (_("Corrupt header in group section `%s'\n"), name);
7346 continue;
7347 }
7348
ba5cdace
NC
7349 if (section->sh_info >= num_syms)
7350 {
7351 error (_("Bad sh_info in group section `%s'\n"), name);
7352 continue;
7353 }
7354
f5842774
L
7355 sym = symtab + section->sh_info;
7356
7357 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7358 {
4fbb74a6 7359 if (sym->st_shndx == 0
dda8d76d 7360 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7361 {
7362 error (_("Bad sh_info in group section `%s'\n"), name);
7363 continue;
7364 }
ba2685cc 7365
b9e920ec
AM
7366 group_name = SECTION_NAME_PRINT (filedata->section_headers
7367 + sym->st_shndx);
c256ffe7 7368 strtab_sec = NULL;
9db70fc3 7369 free (strtab);
f5842774 7370 strtab = NULL;
c256ffe7 7371 strtab_size = 0;
f5842774
L
7372 }
7373 else
7374 {
7375 /* Get the string table. */
dda8d76d 7376 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7377 {
7378 strtab_sec = NULL;
9db70fc3 7379 free (strtab);
c256ffe7
JJ
7380 strtab = NULL;
7381 strtab_size = 0;
7382 }
7383 else if (strtab_sec
dda8d76d 7384 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7385 {
7386 strtab_sec = sec;
9db70fc3 7387 free (strtab);
071436c6 7388
dda8d76d 7389 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7390 1, strtab_sec->sh_size,
7391 _("string table"));
c256ffe7 7392 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7393 }
c256ffe7 7394 group_name = sym->st_name < strtab_size
2b692964 7395 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7396 }
7397
c9c1d674
EG
7398 /* PR 17531: file: loop. */
7399 if (section->sh_entsize > section->sh_size)
7400 {
7401 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7402 printable_section_name (filedata, section),
8066deb1
AM
7403 (unsigned long) section->sh_entsize,
7404 (unsigned long) section->sh_size);
61dd8e19 7405 continue;
c9c1d674
EG
7406 }
7407
dda8d76d 7408 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7409 1, section->sh_size,
7410 _("section data"));
59245841
NC
7411 if (start == NULL)
7412 continue;
f5842774
L
7413
7414 indices = start;
7415 size = (section->sh_size / section->sh_entsize) - 1;
7416 entry = byte_get (indices, 4);
7417 indices += 4;
e4b17d5c
L
7418
7419 if (do_section_groups)
7420 {
2b692964 7421 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7422 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7423
e4b17d5c
L
7424 printf (_(" [Index] Name\n"));
7425 }
7426
7427 group->group_index = i;
7428
f5842774
L
7429 for (j = 0; j < size; j++)
7430 {
2cf0635d 7431 struct group_list * g;
e4b17d5c 7432
f5842774
L
7433 entry = byte_get (indices, 4);
7434 indices += 4;
7435
dda8d76d 7436 if (entry >= filedata->file_header.e_shnum)
391cb864 7437 {
57028622
NC
7438 static unsigned num_group_errors = 0;
7439
7440 if (num_group_errors ++ < 10)
7441 {
7442 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7443 entry, i, filedata->file_header.e_shnum - 1);
57028622 7444 if (num_group_errors == 10)
67ce483b 7445 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7446 }
391cb864
L
7447 continue;
7448 }
391cb864 7449
978c4450 7450 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7451 {
d1f5c6e3
L
7452 if (entry)
7453 {
57028622
NC
7454 static unsigned num_errs = 0;
7455
7456 if (num_errs ++ < 10)
7457 {
7458 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7459 entry, i,
978c4450 7460 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7461 if (num_errs == 10)
7462 warn (_("Further error messages about already contained group sections suppressed\n"));
7463 }
d1f5c6e3
L
7464 continue;
7465 }
7466 else
7467 {
7468 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7469 section group. We just warn it the first time
d1f5c6e3 7470 and ignore it afterwards. */
015dc7e1 7471 static bool warned = false;
d1f5c6e3
L
7472 if (!warned)
7473 {
7474 error (_("section 0 in group section [%5u]\n"),
978c4450 7475 filedata->section_headers_groups [entry]->group_index);
015dc7e1 7476 warned = true;
d1f5c6e3
L
7477 }
7478 }
e4b17d5c
L
7479 }
7480
978c4450 7481 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7482
7483 if (do_section_groups)
7484 {
dda8d76d
NC
7485 sec = filedata->section_headers + entry;
7486 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7487 }
7488
3f5e193b 7489 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7490 g->section_index = entry;
7491 g->next = group->root;
7492 group->root = g;
f5842774
L
7493 }
7494
9db70fc3 7495 free (start);
e4b17d5c
L
7496
7497 group++;
f5842774
L
7498 }
7499 }
7500
9db70fc3
AM
7501 free (symtab);
7502 free (strtab);
015dc7e1 7503 return true;
f5842774
L
7504}
7505
28f997cf
TG
7506/* Data used to display dynamic fixups. */
7507
7508struct ia64_vms_dynfixup
7509{
7510 bfd_vma needed_ident; /* Library ident number. */
7511 bfd_vma needed; /* Index in the dstrtab of the library name. */
7512 bfd_vma fixup_needed; /* Index of the library. */
7513 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7514 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7515};
7516
7517/* Data used to display dynamic relocations. */
7518
7519struct ia64_vms_dynimgrela
7520{
7521 bfd_vma img_rela_cnt; /* Number of relocations. */
7522 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7523};
7524
7525/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7526 library). */
7527
015dc7e1 7528static bool
dda8d76d
NC
7529dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7530 struct ia64_vms_dynfixup * fixup,
7531 const char * strtab,
7532 unsigned int strtab_sz)
28f997cf 7533{
32ec8896 7534 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7535 long i;
32ec8896 7536 const char * lib_name;
28f997cf 7537
978c4450
AM
7538 imfs = get_data (NULL, filedata,
7539 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7540 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7541 _("dynamic section image fixups"));
7542 if (!imfs)
015dc7e1 7543 return false;
28f997cf
TG
7544
7545 if (fixup->needed < strtab_sz)
7546 lib_name = strtab + fixup->needed;
7547 else
7548 {
32ec8896 7549 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7550 (unsigned long) fixup->needed);
28f997cf
TG
7551 lib_name = "???";
7552 }
736990c4 7553
28f997cf
TG
7554 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7555 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7556 printf
7557 (_("Seg Offset Type SymVec DataType\n"));
7558
7559 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7560 {
7561 unsigned int type;
7562 const char *rtype;
7563
7564 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7565 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7566 type = BYTE_GET (imfs [i].type);
7567 rtype = elf_ia64_reloc_type (type);
7568 if (rtype == NULL)
7569 printf (" 0x%08x ", type);
7570 else
7571 printf (" %-32s ", rtype);
7572 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7573 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7574 }
7575
7576 free (imfs);
015dc7e1 7577 return true;
28f997cf
TG
7578}
7579
7580/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7581
015dc7e1 7582static bool
dda8d76d 7583dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7584{
7585 Elf64_External_VMS_IMAGE_RELA *imrs;
7586 long i;
7587
978c4450
AM
7588 imrs = get_data (NULL, filedata,
7589 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 7590 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7591 _("dynamic section image relocations"));
28f997cf 7592 if (!imrs)
015dc7e1 7593 return false;
28f997cf
TG
7594
7595 printf (_("\nImage relocs\n"));
7596 printf
7597 (_("Seg Offset Type Addend Seg Sym Off\n"));
7598
7599 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7600 {
7601 unsigned int type;
7602 const char *rtype;
7603
7604 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7605 printf ("%08" BFD_VMA_FMT "x ",
7606 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7607 type = BYTE_GET (imrs [i].type);
7608 rtype = elf_ia64_reloc_type (type);
7609 if (rtype == NULL)
7610 printf ("0x%08x ", type);
7611 else
7612 printf ("%-31s ", rtype);
7613 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7614 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7615 printf ("%08" BFD_VMA_FMT "x\n",
7616 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7617 }
7618
7619 free (imrs);
015dc7e1 7620 return true;
28f997cf
TG
7621}
7622
7623/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7624
015dc7e1 7625static bool
dda8d76d 7626process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7627{
7628 struct ia64_vms_dynfixup fixup;
7629 struct ia64_vms_dynimgrela imgrela;
7630 Elf_Internal_Dyn *entry;
28f997cf
TG
7631 bfd_vma strtab_off = 0;
7632 bfd_vma strtab_sz = 0;
7633 char *strtab = NULL;
015dc7e1 7634 bool res = true;
28f997cf
TG
7635
7636 memset (&fixup, 0, sizeof (fixup));
7637 memset (&imgrela, 0, sizeof (imgrela));
7638
7639 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
7640 for (entry = filedata->dynamic_section;
7641 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
7642 entry++)
7643 {
7644 switch (entry->d_tag)
7645 {
7646 case DT_IA_64_VMS_STRTAB_OFFSET:
7647 strtab_off = entry->d_un.d_val;
7648 break;
7649 case DT_STRSZ:
7650 strtab_sz = entry->d_un.d_val;
7651 if (strtab == NULL)
978c4450
AM
7652 strtab = get_data (NULL, filedata,
7653 filedata->dynamic_addr + strtab_off,
28f997cf 7654 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7655 if (strtab == NULL)
7656 strtab_sz = 0;
28f997cf
TG
7657 break;
7658
7659 case DT_IA_64_VMS_NEEDED_IDENT:
7660 fixup.needed_ident = entry->d_un.d_val;
7661 break;
7662 case DT_NEEDED:
7663 fixup.needed = entry->d_un.d_val;
7664 break;
7665 case DT_IA_64_VMS_FIXUP_NEEDED:
7666 fixup.fixup_needed = entry->d_un.d_val;
7667 break;
7668 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7669 fixup.fixup_rela_cnt = entry->d_un.d_val;
7670 break;
7671 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7672 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7673 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 7674 res = false;
28f997cf 7675 break;
28f997cf
TG
7676 case DT_IA_64_VMS_IMG_RELA_CNT:
7677 imgrela.img_rela_cnt = entry->d_un.d_val;
7678 break;
7679 case DT_IA_64_VMS_IMG_RELA_OFF:
7680 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7681 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 7682 res = false;
28f997cf
TG
7683 break;
7684
7685 default:
7686 break;
7687 }
7688 }
7689
9db70fc3 7690 free (strtab);
28f997cf
TG
7691
7692 return res;
7693}
7694
85b1c36d 7695static struct
566b0d53 7696{
2cf0635d 7697 const char * name;
566b0d53
L
7698 int reloc;
7699 int size;
7700 int rela;
32ec8896
NC
7701}
7702 dynamic_relocations [] =
566b0d53 7703{
015dc7e1
AM
7704 { "REL", DT_REL, DT_RELSZ, false },
7705 { "RELA", DT_RELA, DT_RELASZ, true },
32ec8896 7706 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7707};
7708
252b5132 7709/* Process the reloc section. */
18bd398b 7710
015dc7e1 7711static bool
dda8d76d 7712process_relocs (Filedata * filedata)
252b5132 7713{
b34976b6
AM
7714 unsigned long rel_size;
7715 unsigned long rel_offset;
252b5132 7716
252b5132 7717 if (!do_reloc)
015dc7e1 7718 return true;
252b5132
RH
7719
7720 if (do_using_dynamic)
7721 {
32ec8896 7722 int is_rela;
2cf0635d 7723 const char * name;
015dc7e1 7724 bool has_dynamic_reloc;
566b0d53 7725 unsigned int i;
0de14b54 7726
015dc7e1 7727 has_dynamic_reloc = false;
252b5132 7728
566b0d53 7729 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7730 {
566b0d53
L
7731 is_rela = dynamic_relocations [i].rela;
7732 name = dynamic_relocations [i].name;
978c4450
AM
7733 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
7734 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 7735
32ec8896 7736 if (rel_size)
015dc7e1 7737 has_dynamic_reloc = true;
566b0d53
L
7738
7739 if (is_rela == UNKNOWN)
aa903cfb 7740 {
566b0d53 7741 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 7742 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
7743 {
7744 case DT_REL:
015dc7e1 7745 is_rela = false;
566b0d53
L
7746 break;
7747 case DT_RELA:
015dc7e1 7748 is_rela = true;
566b0d53
L
7749 break;
7750 }
aa903cfb 7751 }
252b5132 7752
566b0d53
L
7753 if (rel_size)
7754 {
ca0e11aa
NC
7755 if (filedata->is_separate)
7756 printf
7757 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
7758 filedata->file_name, name, rel_offset, rel_size);
7759 else
7760 printf
7761 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7762 name, rel_offset, rel_size);
252b5132 7763
dda8d76d
NC
7764 dump_relocations (filedata,
7765 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7766 rel_size,
978c4450
AM
7767 filedata->dynamic_symbols,
7768 filedata->num_dynamic_syms,
7769 filedata->dynamic_strings,
7770 filedata->dynamic_strings_length,
015dc7e1 7771 is_rela, true /* is_dynamic */);
566b0d53 7772 }
252b5132 7773 }
566b0d53 7774
dda8d76d
NC
7775 if (is_ia64_vms (filedata))
7776 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 7777 has_dynamic_reloc = true;
28f997cf 7778
566b0d53 7779 if (! has_dynamic_reloc)
ca0e11aa
NC
7780 {
7781 if (filedata->is_separate)
7782 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
7783 filedata->file_name);
7784 else
7785 printf (_("\nThere are no dynamic relocations in this file.\n"));
7786 }
252b5132
RH
7787 }
7788 else
7789 {
2cf0635d 7790 Elf_Internal_Shdr * section;
b34976b6 7791 unsigned long i;
015dc7e1 7792 bool found = false;
252b5132 7793
dda8d76d
NC
7794 for (i = 0, section = filedata->section_headers;
7795 i < filedata->file_header.e_shnum;
b34976b6 7796 i++, section++)
252b5132
RH
7797 {
7798 if ( section->sh_type != SHT_RELA
7799 && section->sh_type != SHT_REL)
7800 continue;
7801
7802 rel_offset = section->sh_offset;
7803 rel_size = section->sh_size;
7804
7805 if (rel_size)
7806 {
b34976b6 7807 int is_rela;
d3a49aa8 7808 unsigned long num_rela;
103f02d3 7809
ca0e11aa
NC
7810 if (filedata->is_separate)
7811 printf (_("\nIn linked file '%s' relocation section "),
7812 filedata->file_name);
7813 else
7814 printf (_("\nRelocation section "));
252b5132 7815
dda8d76d 7816 if (filedata->string_table == NULL)
19936277 7817 printf ("%d", section->sh_name);
252b5132 7818 else
dda8d76d 7819 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7820
d3a49aa8
AM
7821 num_rela = rel_size / section->sh_entsize;
7822 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7823 " at offset 0x%lx contains %lu entries:\n",
7824 num_rela),
7825 rel_offset, num_rela);
252b5132 7826
d79b3d50
NC
7827 is_rela = section->sh_type == SHT_RELA;
7828
4fbb74a6 7829 if (section->sh_link != 0
dda8d76d 7830 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7831 {
2cf0635d
NC
7832 Elf_Internal_Shdr * symsec;
7833 Elf_Internal_Sym * symtab;
d79b3d50 7834 unsigned long nsyms;
c256ffe7 7835 unsigned long strtablen = 0;
2cf0635d 7836 char * strtab = NULL;
57346661 7837
dda8d76d 7838 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7839 if (symsec->sh_type != SHT_SYMTAB
7840 && symsec->sh_type != SHT_DYNSYM)
7841 continue;
7842
28d13567
AM
7843 if (!get_symtab (filedata, symsec,
7844 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7845 continue;
252b5132 7846
dda8d76d 7847 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7848 symtab, nsyms, strtab, strtablen,
7849 is_rela,
7850 symsec->sh_type == SHT_DYNSYM);
9db70fc3 7851 free (strtab);
d79b3d50
NC
7852 free (symtab);
7853 }
7854 else
dda8d76d 7855 dump_relocations (filedata, rel_offset, rel_size,
32ec8896 7856 NULL, 0, NULL, 0, is_rela,
015dc7e1 7857 false /* is_dynamic */);
252b5132 7858
015dc7e1 7859 found = true;
252b5132
RH
7860 }
7861 }
7862
7863 if (! found)
45ac8f4f
NC
7864 {
7865 /* Users sometimes forget the -D option, so try to be helpful. */
7866 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7867 {
978c4450 7868 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 7869 {
ca0e11aa
NC
7870 if (filedata->is_separate)
7871 printf (_("\nThere are no static relocations in linked file '%s'."),
7872 filedata->file_name);
7873 else
7874 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
7875 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7876
7877 break;
7878 }
7879 }
7880 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
7881 {
7882 if (filedata->is_separate)
7883 printf (_("\nThere are no relocations in linked file '%s'.\n"),
7884 filedata->file_name);
7885 else
7886 printf (_("\nThere are no relocations in this file.\n"));
7887 }
45ac8f4f 7888 }
252b5132
RH
7889 }
7890
015dc7e1 7891 return true;
252b5132
RH
7892}
7893
4d6ed7c8
NC
7894/* An absolute address consists of a section and an offset. If the
7895 section is NULL, the offset itself is the address, otherwise, the
7896 address equals to LOAD_ADDRESS(section) + offset. */
7897
7898struct absaddr
948f632f
DA
7899{
7900 unsigned short section;
7901 bfd_vma offset;
7902};
4d6ed7c8 7903
948f632f
DA
7904/* Find the nearest symbol at or below ADDR. Returns the symbol
7905 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7906
4d6ed7c8 7907static void
dda8d76d
NC
7908find_symbol_for_address (Filedata * filedata,
7909 Elf_Internal_Sym * symtab,
7910 unsigned long nsyms,
7911 const char * strtab,
7912 unsigned long strtab_size,
7913 struct absaddr addr,
7914 const char ** symname,
7915 bfd_vma * offset)
4d6ed7c8 7916{
d3ba0551 7917 bfd_vma dist = 0x100000;
2cf0635d 7918 Elf_Internal_Sym * sym;
948f632f
DA
7919 Elf_Internal_Sym * beg;
7920 Elf_Internal_Sym * end;
2cf0635d 7921 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7922
0b6ae522 7923 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7924 beg = symtab;
7925 end = symtab + nsyms;
0b6ae522 7926
948f632f 7927 while (beg < end)
4d6ed7c8 7928 {
948f632f
DA
7929 bfd_vma value;
7930
7931 sym = beg + (end - beg) / 2;
0b6ae522 7932
948f632f 7933 value = sym->st_value;
0b6ae522
DJ
7934 REMOVE_ARCH_BITS (value);
7935
948f632f 7936 if (sym->st_name != 0
4d6ed7c8 7937 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7938 && addr.offset >= value
7939 && addr.offset - value < dist)
4d6ed7c8
NC
7940 {
7941 best = sym;
0b6ae522 7942 dist = addr.offset - value;
4d6ed7c8
NC
7943 if (!dist)
7944 break;
7945 }
948f632f
DA
7946
7947 if (addr.offset < value)
7948 end = sym;
7949 else
7950 beg = sym + 1;
4d6ed7c8 7951 }
1b31d05e 7952
4d6ed7c8
NC
7953 if (best)
7954 {
57346661 7955 *symname = (best->st_name >= strtab_size
2b692964 7956 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7957 *offset = dist;
7958 return;
7959 }
1b31d05e 7960
4d6ed7c8
NC
7961 *symname = NULL;
7962 *offset = addr.offset;
7963}
7964
32ec8896 7965static /* signed */ int
948f632f
DA
7966symcmp (const void *p, const void *q)
7967{
7968 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7969 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7970
7971 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7972}
7973
7974/* Process the unwind section. */
7975
7976#include "unwind-ia64.h"
7977
7978struct ia64_unw_table_entry
7979{
7980 struct absaddr start;
7981 struct absaddr end;
7982 struct absaddr info;
7983};
7984
7985struct ia64_unw_aux_info
7986{
32ec8896
NC
7987 struct ia64_unw_table_entry * table; /* Unwind table. */
7988 unsigned long table_len; /* Length of unwind table. */
7989 unsigned char * info; /* Unwind info. */
7990 unsigned long info_size; /* Size of unwind info. */
7991 bfd_vma info_addr; /* Starting address of unwind info. */
7992 bfd_vma seg_base; /* Starting address of segment. */
7993 Elf_Internal_Sym * symtab; /* The symbol table. */
7994 unsigned long nsyms; /* Number of symbols. */
7995 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7996 unsigned long nfuns; /* Number of entries in funtab. */
7997 char * strtab; /* The string table. */
7998 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7999};
8000
015dc7e1 8001static bool
dda8d76d 8002dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8003{
2cf0635d 8004 struct ia64_unw_table_entry * tp;
948f632f 8005 unsigned long j, nfuns;
4d6ed7c8 8006 int in_body;
015dc7e1 8007 bool res = true;
7036c0e1 8008
948f632f
DA
8009 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8010 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8011 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8012 aux->funtab[nfuns++] = aux->symtab[j];
8013 aux->nfuns = nfuns;
8014 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8015
4d6ed7c8
NC
8016 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8017 {
8018 bfd_vma stamp;
8019 bfd_vma offset;
2cf0635d
NC
8020 const unsigned char * dp;
8021 const unsigned char * head;
53774b7e 8022 const unsigned char * end;
2cf0635d 8023 const char * procname;
4d6ed7c8 8024
dda8d76d 8025 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8026 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8027
8028 fputs ("\n<", stdout);
8029
8030 if (procname)
8031 {
8032 fputs (procname, stdout);
8033
8034 if (offset)
8035 printf ("+%lx", (unsigned long) offset);
8036 }
8037
8038 fputs (">: [", stdout);
8039 print_vma (tp->start.offset, PREFIX_HEX);
8040 fputc ('-', stdout);
8041 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 8042 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
8043 (unsigned long) (tp->info.offset - aux->seg_base));
8044
53774b7e
NC
8045 /* PR 17531: file: 86232b32. */
8046 if (aux->info == NULL)
8047 continue;
8048
97c0a079
AM
8049 offset = tp->info.offset;
8050 if (tp->info.section)
8051 {
8052 if (tp->info.section >= filedata->file_header.e_shnum)
8053 {
8054 warn (_("Invalid section %u in table entry %ld\n"),
8055 tp->info.section, (long) (tp - aux->table));
015dc7e1 8056 res = false;
97c0a079
AM
8057 continue;
8058 }
8059 offset += filedata->section_headers[tp->info.section].sh_addr;
8060 }
8061 offset -= aux->info_addr;
53774b7e 8062 /* PR 17531: file: 0997b4d1. */
90679903
AM
8063 if (offset >= aux->info_size
8064 || aux->info_size - offset < 8)
53774b7e
NC
8065 {
8066 warn (_("Invalid offset %lx in table entry %ld\n"),
8067 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8068 res = false;
53774b7e
NC
8069 continue;
8070 }
8071
97c0a079 8072 head = aux->info + offset;
a4a00738 8073 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8074
86f55779 8075 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8076 (unsigned) UNW_VER (stamp),
8077 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8078 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8079 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8080 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8081
8082 if (UNW_VER (stamp) != 1)
8083 {
2b692964 8084 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8085 continue;
8086 }
8087
8088 in_body = 0;
53774b7e
NC
8089 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8090 /* PR 17531: file: 16ceda89. */
8091 if (end > aux->info + aux->info_size)
8092 end = aux->info + aux->info_size;
8093 for (dp = head + 8; dp < end;)
b4477bc8 8094 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8095 }
948f632f
DA
8096
8097 free (aux->funtab);
32ec8896
NC
8098
8099 return res;
4d6ed7c8
NC
8100}
8101
015dc7e1 8102static bool
dda8d76d
NC
8103slurp_ia64_unwind_table (Filedata * filedata,
8104 struct ia64_unw_aux_info * aux,
8105 Elf_Internal_Shdr * sec)
4d6ed7c8 8106{
89fac5e3 8107 unsigned long size, nrelas, i;
2cf0635d
NC
8108 Elf_Internal_Phdr * seg;
8109 struct ia64_unw_table_entry * tep;
8110 Elf_Internal_Shdr * relsec;
8111 Elf_Internal_Rela * rela;
8112 Elf_Internal_Rela * rp;
8113 unsigned char * table;
8114 unsigned char * tp;
8115 Elf_Internal_Sym * sym;
8116 const char * relname;
4d6ed7c8 8117
53774b7e
NC
8118 aux->table_len = 0;
8119
4d6ed7c8
NC
8120 /* First, find the starting address of the segment that includes
8121 this section: */
8122
dda8d76d 8123 if (filedata->file_header.e_phnum)
4d6ed7c8 8124 {
dda8d76d 8125 if (! get_program_headers (filedata))
015dc7e1 8126 return false;
4d6ed7c8 8127
dda8d76d
NC
8128 for (seg = filedata->program_headers;
8129 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8130 ++seg)
4d6ed7c8
NC
8131 {
8132 if (seg->p_type != PT_LOAD)
8133 continue;
8134
8135 if (sec->sh_addr >= seg->p_vaddr
8136 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8137 {
8138 aux->seg_base = seg->p_vaddr;
8139 break;
8140 }
8141 }
4d6ed7c8
NC
8142 }
8143
8144 /* Second, build the unwind table from the contents of the unwind section: */
8145 size = sec->sh_size;
dda8d76d 8146 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8147 _("unwind table"));
a6e9f9df 8148 if (!table)
015dc7e1 8149 return false;
4d6ed7c8 8150
53774b7e 8151 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8152 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8153 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8154 tep = aux->table;
53774b7e
NC
8155
8156 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8157 {
8158 tep->start.section = SHN_UNDEF;
8159 tep->end.section = SHN_UNDEF;
8160 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8161 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8162 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8163 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8164 tep->start.offset += aux->seg_base;
8165 tep->end.offset += aux->seg_base;
8166 tep->info.offset += aux->seg_base;
8167 }
8168 free (table);
8169
41e92641 8170 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8171 for (relsec = filedata->section_headers;
8172 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8173 ++relsec)
8174 {
8175 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8176 || relsec->sh_info >= filedata->file_header.e_shnum
8177 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8178 continue;
8179
dda8d76d 8180 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8181 & rela, & nrelas))
53774b7e
NC
8182 {
8183 free (aux->table);
8184 aux->table = NULL;
8185 aux->table_len = 0;
015dc7e1 8186 return false;
53774b7e 8187 }
4d6ed7c8
NC
8188
8189 for (rp = rela; rp < rela + nrelas; ++rp)
8190 {
4770fb94 8191 unsigned int sym_ndx;
726bd37d
AM
8192 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8193 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8194
82b1b41b
NC
8195 /* PR 17531: file: 9fa67536. */
8196 if (relname == NULL)
8197 {
726bd37d 8198 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8199 continue;
8200 }
948f632f 8201
24d127aa 8202 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8203 {
82b1b41b 8204 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8205 continue;
8206 }
8207
89fac5e3 8208 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8209
53774b7e
NC
8210 /* PR 17531: file: 5bc8d9bf. */
8211 if (i >= aux->table_len)
8212 {
8213 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8214 continue;
8215 }
8216
4770fb94
AM
8217 sym_ndx = get_reloc_symindex (rp->r_info);
8218 if (sym_ndx >= aux->nsyms)
8219 {
8220 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8221 sym_ndx);
8222 continue;
8223 }
8224 sym = aux->symtab + sym_ndx;
8225
53774b7e 8226 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8227 {
8228 case 0:
8229 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8230 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8231 break;
8232 case 1:
8233 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8234 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8235 break;
8236 case 2:
8237 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8238 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8239 break;
8240 default:
8241 break;
8242 }
8243 }
8244
8245 free (rela);
8246 }
8247
015dc7e1 8248 return true;
4d6ed7c8
NC
8249}
8250
015dc7e1 8251static bool
dda8d76d 8252ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8253{
2cf0635d
NC
8254 Elf_Internal_Shdr * sec;
8255 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8256 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8257 struct ia64_unw_aux_info aux;
015dc7e1 8258 bool res = true;
f1467e33 8259
4d6ed7c8
NC
8260 memset (& aux, 0, sizeof (aux));
8261
dda8d76d 8262 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8263 {
28d13567 8264 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8265 {
28d13567 8266 if (aux.symtab)
4082ef84 8267 {
28d13567
AM
8268 error (_("Multiple symbol tables encountered\n"));
8269 free (aux.symtab);
8270 aux.symtab = NULL;
4082ef84 8271 free (aux.strtab);
28d13567 8272 aux.strtab = NULL;
4082ef84 8273 }
28d13567
AM
8274 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8275 &aux.strtab, &aux.strtab_size))
015dc7e1 8276 return false;
4d6ed7c8
NC
8277 }
8278 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8279 unwcount++;
8280 }
8281
8282 if (!unwcount)
8283 printf (_("\nThere are no unwind sections in this file.\n"));
8284
8285 while (unwcount-- > 0)
8286 {
2cf0635d 8287 char * suffix;
579f31ac
JJ
8288 size_t len, len2;
8289
dda8d76d
NC
8290 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8291 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8292 if (sec->sh_type == SHT_IA_64_UNWIND)
8293 {
8294 unwsec = sec;
8295 break;
8296 }
4082ef84
NC
8297 /* We have already counted the number of SHT_IA64_UNWIND
8298 sections so the loop above should never fail. */
8299 assert (unwsec != NULL);
579f31ac
JJ
8300
8301 unwstart = i + 1;
8302 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8303
e4b17d5c
L
8304 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8305 {
8306 /* We need to find which section group it is in. */
4082ef84 8307 struct group_list * g;
e4b17d5c 8308
978c4450
AM
8309 if (filedata->section_headers_groups == NULL
8310 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8311 i = filedata->file_header.e_shnum;
4082ef84 8312 else
e4b17d5c 8313 {
978c4450 8314 g = filedata->section_headers_groups[i]->root;
18bd398b 8315
4082ef84
NC
8316 for (; g != NULL; g = g->next)
8317 {
dda8d76d 8318 sec = filedata->section_headers + g->section_index;
e4b17d5c 8319
b9e920ec
AM
8320 if (SECTION_NAME_VALID (sec)
8321 && streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
4082ef84
NC
8322 break;
8323 }
8324
8325 if (g == NULL)
dda8d76d 8326 i = filedata->file_header.e_shnum;
4082ef84 8327 }
e4b17d5c 8328 }
b9e920ec 8329 else if (SECTION_NAME_VALID (unwsec)
e9b095a5
ML
8330 && startswith (SECTION_NAME (unwsec),
8331 ELF_STRING_ia64_unwind_once))
579f31ac 8332 {
18bd398b 8333 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
8334 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
8335 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8336 for (i = 0, sec = filedata->section_headers;
8337 i < filedata->file_header.e_shnum;
579f31ac 8338 ++i, ++sec)
b9e920ec 8339 if (SECTION_NAME_VALID (sec)
e9b095a5
ML
8340 && startswith (SECTION_NAME (sec),
8341 ELF_STRING_ia64_unwind_info_once)
18bd398b 8342 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8343 break;
8344 }
8345 else
8346 {
8347 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8348 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8349 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8350 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8351 suffix = "";
b9e920ec 8352 if (SECTION_NAME_VALID (unwsec)
e9b095a5 8353 && startswith (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind))
579f31ac 8354 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8355 for (i = 0, sec = filedata->section_headers;
8356 i < filedata->file_header.e_shnum;
579f31ac 8357 ++i, ++sec)
b9e920ec 8358 if (SECTION_NAME_VALID (sec)
e9b095a5 8359 && startswith (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info)
18bd398b 8360 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8361 break;
8362 }
8363
dda8d76d 8364 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8365 {
8366 printf (_("\nCould not find unwind info section for "));
8367
dda8d76d 8368 if (filedata->string_table == NULL)
579f31ac
JJ
8369 printf ("%d", unwsec->sh_name);
8370 else
dda8d76d 8371 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8372 }
8373 else
4d6ed7c8 8374 {
4d6ed7c8 8375 aux.info_addr = sec->sh_addr;
dda8d76d 8376 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8377 sec->sh_size,
8378 _("unwind info"));
59245841 8379 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8380
579f31ac 8381 printf (_("\nUnwind section "));
4d6ed7c8 8382
dda8d76d 8383 if (filedata->string_table == NULL)
579f31ac
JJ
8384 printf ("%d", unwsec->sh_name);
8385 else
dda8d76d 8386 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8387
579f31ac 8388 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8389 (unsigned long) unwsec->sh_offset,
89fac5e3 8390 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8391
dda8d76d 8392 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8393 && aux.table_len > 0)
dda8d76d 8394 dump_ia64_unwind (filedata, & aux);
579f31ac 8395
9db70fc3
AM
8396 free ((char *) aux.table);
8397 free ((char *) aux.info);
579f31ac
JJ
8398 aux.table = NULL;
8399 aux.info = NULL;
8400 }
4d6ed7c8 8401 }
4d6ed7c8 8402
9db70fc3
AM
8403 free (aux.symtab);
8404 free ((char *) aux.strtab);
32ec8896
NC
8405
8406 return res;
4d6ed7c8
NC
8407}
8408
3f5e193b 8409struct hppa_unw_table_entry
32ec8896
NC
8410{
8411 struct absaddr start;
8412 struct absaddr end;
8413 unsigned int Cannot_unwind:1; /* 0 */
8414 unsigned int Millicode:1; /* 1 */
8415 unsigned int Millicode_save_sr0:1; /* 2 */
8416 unsigned int Region_description:2; /* 3..4 */
8417 unsigned int reserved1:1; /* 5 */
8418 unsigned int Entry_SR:1; /* 6 */
8419 unsigned int Entry_FR:4; /* Number saved 7..10 */
8420 unsigned int Entry_GR:5; /* Number saved 11..15 */
8421 unsigned int Args_stored:1; /* 16 */
8422 unsigned int Variable_Frame:1; /* 17 */
8423 unsigned int Separate_Package_Body:1; /* 18 */
8424 unsigned int Frame_Extension_Millicode:1; /* 19 */
8425 unsigned int Stack_Overflow_Check:1; /* 20 */
8426 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8427 unsigned int Ada_Region:1; /* 22 */
8428 unsigned int cxx_info:1; /* 23 */
8429 unsigned int cxx_try_catch:1; /* 24 */
8430 unsigned int sched_entry_seq:1; /* 25 */
8431 unsigned int reserved2:1; /* 26 */
8432 unsigned int Save_SP:1; /* 27 */
8433 unsigned int Save_RP:1; /* 28 */
8434 unsigned int Save_MRP_in_frame:1; /* 29 */
8435 unsigned int extn_ptr_defined:1; /* 30 */
8436 unsigned int Cleanup_defined:1; /* 31 */
8437
8438 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8439 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8440 unsigned int Large_frame:1; /* 2 */
8441 unsigned int Pseudo_SP_Set:1; /* 3 */
8442 unsigned int reserved4:1; /* 4 */
8443 unsigned int Total_frame_size:27; /* 5..31 */
8444};
3f5e193b 8445
57346661 8446struct hppa_unw_aux_info
948f632f 8447{
32ec8896
NC
8448 struct hppa_unw_table_entry * table; /* Unwind table. */
8449 unsigned long table_len; /* Length of unwind table. */
8450 bfd_vma seg_base; /* Starting address of segment. */
8451 Elf_Internal_Sym * symtab; /* The symbol table. */
8452 unsigned long nsyms; /* Number of symbols. */
8453 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8454 unsigned long nfuns; /* Number of entries in funtab. */
8455 char * strtab; /* The string table. */
8456 unsigned long strtab_size; /* Size of string table. */
948f632f 8457};
57346661 8458
015dc7e1 8459static bool
dda8d76d 8460dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8461{
2cf0635d 8462 struct hppa_unw_table_entry * tp;
948f632f 8463 unsigned long j, nfuns;
015dc7e1 8464 bool res = true;
948f632f
DA
8465
8466 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8467 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8468 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8469 aux->funtab[nfuns++] = aux->symtab[j];
8470 aux->nfuns = nfuns;
8471 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8472
57346661
AM
8473 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8474 {
8475 bfd_vma offset;
2cf0635d 8476 const char * procname;
57346661 8477
dda8d76d 8478 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8479 aux->strtab_size, tp->start, &procname,
8480 &offset);
8481
8482 fputs ("\n<", stdout);
8483
8484 if (procname)
8485 {
8486 fputs (procname, stdout);
8487
8488 if (offset)
8489 printf ("+%lx", (unsigned long) offset);
8490 }
8491
8492 fputs (">: [", stdout);
8493 print_vma (tp->start.offset, PREFIX_HEX);
8494 fputc ('-', stdout);
8495 print_vma (tp->end.offset, PREFIX_HEX);
8496 printf ("]\n\t");
8497
18bd398b
NC
8498#define PF(_m) if (tp->_m) printf (#_m " ");
8499#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8500 PF(Cannot_unwind);
8501 PF(Millicode);
8502 PF(Millicode_save_sr0);
18bd398b 8503 /* PV(Region_description); */
57346661
AM
8504 PF(Entry_SR);
8505 PV(Entry_FR);
8506 PV(Entry_GR);
8507 PF(Args_stored);
8508 PF(Variable_Frame);
8509 PF(Separate_Package_Body);
8510 PF(Frame_Extension_Millicode);
8511 PF(Stack_Overflow_Check);
8512 PF(Two_Instruction_SP_Increment);
8513 PF(Ada_Region);
8514 PF(cxx_info);
8515 PF(cxx_try_catch);
8516 PF(sched_entry_seq);
8517 PF(Save_SP);
8518 PF(Save_RP);
8519 PF(Save_MRP_in_frame);
8520 PF(extn_ptr_defined);
8521 PF(Cleanup_defined);
8522 PF(MPE_XL_interrupt_marker);
8523 PF(HP_UX_interrupt_marker);
8524 PF(Large_frame);
8525 PF(Pseudo_SP_Set);
8526 PV(Total_frame_size);
8527#undef PF
8528#undef PV
8529 }
8530
18bd398b 8531 printf ("\n");
948f632f
DA
8532
8533 free (aux->funtab);
32ec8896
NC
8534
8535 return res;
57346661
AM
8536}
8537
015dc7e1 8538static bool
dda8d76d
NC
8539slurp_hppa_unwind_table (Filedata * filedata,
8540 struct hppa_unw_aux_info * aux,
8541 Elf_Internal_Shdr * sec)
57346661 8542{
1c0751b2 8543 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8544 Elf_Internal_Phdr * seg;
8545 struct hppa_unw_table_entry * tep;
8546 Elf_Internal_Shdr * relsec;
8547 Elf_Internal_Rela * rela;
8548 Elf_Internal_Rela * rp;
8549 unsigned char * table;
8550 unsigned char * tp;
8551 Elf_Internal_Sym * sym;
8552 const char * relname;
57346661 8553
57346661
AM
8554 /* First, find the starting address of the segment that includes
8555 this section. */
dda8d76d 8556 if (filedata->file_header.e_phnum)
57346661 8557 {
dda8d76d 8558 if (! get_program_headers (filedata))
015dc7e1 8559 return false;
57346661 8560
dda8d76d
NC
8561 for (seg = filedata->program_headers;
8562 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8563 ++seg)
8564 {
8565 if (seg->p_type != PT_LOAD)
8566 continue;
8567
8568 if (sec->sh_addr >= seg->p_vaddr
8569 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8570 {
8571 aux->seg_base = seg->p_vaddr;
8572 break;
8573 }
8574 }
8575 }
8576
8577 /* Second, build the unwind table from the contents of the unwind
8578 section. */
8579 size = sec->sh_size;
dda8d76d 8580 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8581 _("unwind table"));
57346661 8582 if (!table)
015dc7e1 8583 return false;
57346661 8584
1c0751b2
DA
8585 unw_ent_size = 16;
8586 nentries = size / unw_ent_size;
8587 size = unw_ent_size * nentries;
57346661 8588
e3fdc001 8589 aux->table_len = nentries;
3f5e193b
NC
8590 tep = aux->table = (struct hppa_unw_table_entry *)
8591 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8592
1c0751b2 8593 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8594 {
8595 unsigned int tmp1, tmp2;
8596
8597 tep->start.section = SHN_UNDEF;
8598 tep->end.section = SHN_UNDEF;
8599
1c0751b2
DA
8600 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8601 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8602 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8603 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8604
8605 tep->start.offset += aux->seg_base;
8606 tep->end.offset += aux->seg_base;
57346661
AM
8607
8608 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8609 tep->Millicode = (tmp1 >> 30) & 0x1;
8610 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8611 tep->Region_description = (tmp1 >> 27) & 0x3;
8612 tep->reserved1 = (tmp1 >> 26) & 0x1;
8613 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8614 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8615 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8616 tep->Args_stored = (tmp1 >> 15) & 0x1;
8617 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8618 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8619 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8620 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8621 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8622 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8623 tep->cxx_info = (tmp1 >> 8) & 0x1;
8624 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8625 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8626 tep->reserved2 = (tmp1 >> 5) & 0x1;
8627 tep->Save_SP = (tmp1 >> 4) & 0x1;
8628 tep->Save_RP = (tmp1 >> 3) & 0x1;
8629 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8630 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8631 tep->Cleanup_defined = tmp1 & 0x1;
8632
8633 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8634 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8635 tep->Large_frame = (tmp2 >> 29) & 0x1;
8636 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8637 tep->reserved4 = (tmp2 >> 27) & 0x1;
8638 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8639 }
8640 free (table);
8641
8642 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8643 for (relsec = filedata->section_headers;
8644 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8645 ++relsec)
8646 {
8647 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8648 || relsec->sh_info >= filedata->file_header.e_shnum
8649 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8650 continue;
8651
dda8d76d 8652 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8653 & rela, & nrelas))
015dc7e1 8654 return false;
57346661
AM
8655
8656 for (rp = rela; rp < rela + nrelas; ++rp)
8657 {
4770fb94 8658 unsigned int sym_ndx;
726bd37d
AM
8659 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8660 relname = elf_hppa_reloc_type (r_type);
57346661 8661
726bd37d
AM
8662 if (relname == NULL)
8663 {
8664 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8665 continue;
8666 }
8667
57346661 8668 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 8669 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 8670 {
726bd37d 8671 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8672 continue;
8673 }
8674
8675 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8676 if (i >= aux->table_len)
8677 {
8678 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8679 continue;
8680 }
57346661 8681
4770fb94
AM
8682 sym_ndx = get_reloc_symindex (rp->r_info);
8683 if (sym_ndx >= aux->nsyms)
8684 {
8685 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8686 sym_ndx);
8687 continue;
8688 }
8689 sym = aux->symtab + sym_ndx;
8690
43f6cd05 8691 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8692 {
8693 case 0:
8694 aux->table[i].start.section = sym->st_shndx;
1e456d54 8695 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8696 break;
8697 case 1:
8698 aux->table[i].end.section = sym->st_shndx;
1e456d54 8699 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8700 break;
8701 default:
8702 break;
8703 }
8704 }
8705
8706 free (rela);
8707 }
8708
015dc7e1 8709 return true;
57346661
AM
8710}
8711
015dc7e1 8712static bool
dda8d76d 8713hppa_process_unwind (Filedata * filedata)
57346661 8714{
57346661 8715 struct hppa_unw_aux_info aux;
2cf0635d 8716 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8717 Elf_Internal_Shdr * sec;
18bd398b 8718 unsigned long i;
015dc7e1 8719 bool res = true;
57346661 8720
dda8d76d 8721 if (filedata->string_table == NULL)
015dc7e1 8722 return false;
1b31d05e
NC
8723
8724 memset (& aux, 0, sizeof (aux));
57346661 8725
dda8d76d 8726 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8727 {
28d13567 8728 if (sec->sh_type == SHT_SYMTAB)
57346661 8729 {
28d13567 8730 if (aux.symtab)
4082ef84 8731 {
28d13567
AM
8732 error (_("Multiple symbol tables encountered\n"));
8733 free (aux.symtab);
8734 aux.symtab = NULL;
4082ef84 8735 free (aux.strtab);
28d13567 8736 aux.strtab = NULL;
4082ef84 8737 }
28d13567
AM
8738 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8739 &aux.strtab, &aux.strtab_size))
015dc7e1 8740 return false;
57346661 8741 }
b9e920ec
AM
8742 else if (SECTION_NAME_VALID (sec)
8743 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8744 unwsec = sec;
8745 }
8746
8747 if (!unwsec)
8748 printf (_("\nThere are no unwind sections in this file.\n"));
8749
dda8d76d 8750 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8751 {
b9e920ec
AM
8752 if (SECTION_NAME_VALID (sec)
8753 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8754 {
43f6cd05 8755 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8756
d3a49aa8
AM
8757 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8758 "contains %lu entry:\n",
8759 "\nUnwind section '%s' at offset 0x%lx "
8760 "contains %lu entries:\n",
8761 num_unwind),
dda8d76d 8762 printable_section_name (filedata, sec),
57346661 8763 (unsigned long) sec->sh_offset,
d3a49aa8 8764 num_unwind);
57346661 8765
dda8d76d 8766 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 8767 res = false;
66b09c7e
S
8768
8769 if (res && aux.table_len > 0)
32ec8896 8770 {
dda8d76d 8771 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 8772 res = false;
32ec8896 8773 }
57346661 8774
9db70fc3 8775 free ((char *) aux.table);
57346661
AM
8776 aux.table = NULL;
8777 }
8778 }
8779
9db70fc3
AM
8780 free (aux.symtab);
8781 free ((char *) aux.strtab);
32ec8896
NC
8782
8783 return res;
57346661
AM
8784}
8785
0b6ae522
DJ
8786struct arm_section
8787{
a734115a
NC
8788 unsigned char * data; /* The unwind data. */
8789 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8790 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8791 unsigned long nrelas; /* The number of relocations. */
8792 unsigned int rel_type; /* REL or RELA ? */
8793 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8794};
8795
8796struct arm_unw_aux_info
8797{
dda8d76d 8798 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8799 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8800 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8801 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8802 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8803 char * strtab; /* The file's string table. */
8804 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8805};
8806
8807static const char *
dda8d76d
NC
8808arm_print_vma_and_name (Filedata * filedata,
8809 struct arm_unw_aux_info * aux,
8810 bfd_vma fn,
8811 struct absaddr addr)
0b6ae522
DJ
8812{
8813 const char *procname;
8814 bfd_vma sym_offset;
8815
8816 if (addr.section == SHN_UNDEF)
8817 addr.offset = fn;
8818
dda8d76d 8819 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8820 aux->strtab_size, addr, &procname,
8821 &sym_offset);
8822
8823 print_vma (fn, PREFIX_HEX);
8824
8825 if (procname)
8826 {
8827 fputs (" <", stdout);
8828 fputs (procname, stdout);
8829
8830 if (sym_offset)
8831 printf ("+0x%lx", (unsigned long) sym_offset);
8832 fputc ('>', stdout);
8833 }
8834
8835 return procname;
8836}
8837
8838static void
8839arm_free_section (struct arm_section *arm_sec)
8840{
9db70fc3
AM
8841 free (arm_sec->data);
8842 free (arm_sec->rela);
0b6ae522
DJ
8843}
8844
a734115a
NC
8845/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8846 cached section and install SEC instead.
8847 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8848 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8849 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8850 relocation's offset in ADDR.
1b31d05e
NC
8851 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8852 into the string table of the symbol associated with the reloc. If no
8853 reloc was applied store -1 there.
8854 5) Return TRUE upon success, FALSE otherwise. */
a734115a 8855
015dc7e1 8856static bool
dda8d76d
NC
8857get_unwind_section_word (Filedata * filedata,
8858 struct arm_unw_aux_info * aux,
1b31d05e
NC
8859 struct arm_section * arm_sec,
8860 Elf_Internal_Shdr * sec,
8861 bfd_vma word_offset,
8862 unsigned int * wordp,
8863 struct absaddr * addr,
8864 bfd_vma * sym_name)
0b6ae522
DJ
8865{
8866 Elf_Internal_Rela *rp;
8867 Elf_Internal_Sym *sym;
8868 const char * relname;
8869 unsigned int word;
015dc7e1 8870 bool wrapped;
0b6ae522 8871
e0a31db1 8872 if (sec == NULL || arm_sec == NULL)
015dc7e1 8873 return false;
e0a31db1 8874
0b6ae522
DJ
8875 addr->section = SHN_UNDEF;
8876 addr->offset = 0;
8877
1b31d05e
NC
8878 if (sym_name != NULL)
8879 *sym_name = (bfd_vma) -1;
8880
a734115a 8881 /* If necessary, update the section cache. */
0b6ae522
DJ
8882 if (sec != arm_sec->sec)
8883 {
8884 Elf_Internal_Shdr *relsec;
8885
8886 arm_free_section (arm_sec);
8887
8888 arm_sec->sec = sec;
dda8d76d 8889 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8890 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8891 arm_sec->rela = NULL;
8892 arm_sec->nrelas = 0;
8893
dda8d76d
NC
8894 for (relsec = filedata->section_headers;
8895 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8896 ++relsec)
8897 {
dda8d76d
NC
8898 if (relsec->sh_info >= filedata->file_header.e_shnum
8899 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8900 /* PR 15745: Check the section type as well. */
8901 || (relsec->sh_type != SHT_REL
8902 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8903 continue;
8904
a734115a 8905 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8906 if (relsec->sh_type == SHT_REL)
8907 {
dda8d76d 8908 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8909 relsec->sh_size,
8910 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 8911 return false;
0b6ae522 8912 }
1ae40aa4 8913 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8914 {
dda8d76d 8915 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8916 relsec->sh_size,
8917 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 8918 return false;
0b6ae522 8919 }
1ae40aa4 8920 break;
0b6ae522
DJ
8921 }
8922
8923 arm_sec->next_rela = arm_sec->rela;
8924 }
8925
a734115a 8926 /* If there is no unwind data we can do nothing. */
0b6ae522 8927 if (arm_sec->data == NULL)
015dc7e1 8928 return false;
0b6ae522 8929
e0a31db1 8930 /* If the offset is invalid then fail. */
f32ba729
NC
8931 if (/* PR 21343 *//* PR 18879 */
8932 sec->sh_size < 4
8933 || word_offset > (sec->sh_size - 4)
1a915552 8934 || ((bfd_signed_vma) word_offset) < 0)
015dc7e1 8935 return false;
e0a31db1 8936
a734115a 8937 /* Get the word at the required offset. */
0b6ae522
DJ
8938 word = byte_get (arm_sec->data + word_offset, 4);
8939
0eff7165
NC
8940 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8941 if (arm_sec->rela == NULL)
8942 {
8943 * wordp = word;
015dc7e1 8944 return true;
0eff7165
NC
8945 }
8946
a734115a 8947 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 8948 wrapped = false;
0b6ae522
DJ
8949 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8950 {
8951 bfd_vma prelval, offset;
8952
8953 if (rp->r_offset > word_offset && !wrapped)
8954 {
8955 rp = arm_sec->rela;
015dc7e1 8956 wrapped = true;
0b6ae522
DJ
8957 }
8958 if (rp->r_offset > word_offset)
8959 break;
8960
8961 if (rp->r_offset & 3)
8962 {
8963 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8964 (unsigned long) rp->r_offset);
8965 continue;
8966 }
8967
8968 if (rp->r_offset < word_offset)
8969 continue;
8970
74e1a04b
NC
8971 /* PR 17531: file: 027-161405-0.004 */
8972 if (aux->symtab == NULL)
8973 continue;
8974
0b6ae522
DJ
8975 if (arm_sec->rel_type == SHT_REL)
8976 {
8977 offset = word & 0x7fffffff;
8978 if (offset & 0x40000000)
8979 offset |= ~ (bfd_vma) 0x7fffffff;
8980 }
a734115a 8981 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8982 offset = rp->r_addend;
a734115a 8983 else
74e1a04b
NC
8984 {
8985 error (_("Unknown section relocation type %d encountered\n"),
8986 arm_sec->rel_type);
8987 break;
8988 }
0b6ae522 8989
071436c6
NC
8990 /* PR 17531 file: 027-1241568-0.004. */
8991 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8992 {
8993 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8994 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8995 break;
8996 }
8997
8998 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8999 offset += sym->st_value;
9000 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9001
a734115a 9002 /* Check that we are processing the expected reloc type. */
dda8d76d 9003 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9004 {
9005 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9006 if (relname == NULL)
9007 {
9008 warn (_("Skipping unknown ARM relocation type: %d\n"),
9009 (int) ELF32_R_TYPE (rp->r_info));
9010 continue;
9011 }
a734115a
NC
9012
9013 if (streq (relname, "R_ARM_NONE"))
9014 continue;
0b4362b0 9015
a734115a
NC
9016 if (! streq (relname, "R_ARM_PREL31"))
9017 {
071436c6 9018 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9019 continue;
9020 }
9021 }
dda8d76d 9022 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9023 {
9024 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9025 if (relname == NULL)
9026 {
9027 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9028 (int) ELF32_R_TYPE (rp->r_info));
9029 continue;
9030 }
0b4362b0 9031
a734115a
NC
9032 if (streq (relname, "R_C6000_NONE"))
9033 continue;
9034
9035 if (! streq (relname, "R_C6000_PREL31"))
9036 {
071436c6 9037 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9038 continue;
9039 }
9040
9041 prelval >>= 1;
9042 }
9043 else
74e1a04b
NC
9044 {
9045 /* This function currently only supports ARM and TI unwinders. */
9046 warn (_("Only TI and ARM unwinders are currently supported\n"));
9047 break;
9048 }
fa197c1c 9049
0b6ae522
DJ
9050 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
9051 addr->section = sym->st_shndx;
9052 addr->offset = offset;
74e1a04b 9053
1b31d05e
NC
9054 if (sym_name)
9055 * sym_name = sym->st_name;
0b6ae522
DJ
9056 break;
9057 }
9058
9059 *wordp = word;
9060 arm_sec->next_rela = rp;
9061
015dc7e1 9062 return true;
0b6ae522
DJ
9063}
9064
a734115a
NC
9065static const char *tic6x_unwind_regnames[16] =
9066{
0b4362b0
RM
9067 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9068 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9069 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9070};
fa197c1c 9071
0b6ae522 9072static void
fa197c1c 9073decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9074{
fa197c1c
PB
9075 int i;
9076
9077 for (i = 12; mask; mask >>= 1, i--)
9078 {
9079 if (mask & 1)
9080 {
9081 fputs (tic6x_unwind_regnames[i], stdout);
9082 if (mask > 1)
9083 fputs (", ", stdout);
9084 }
9085 }
9086}
0b6ae522
DJ
9087
9088#define ADVANCE \
9089 if (remaining == 0 && more_words) \
9090 { \
9091 data_offset += 4; \
dda8d76d 9092 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9093 data_offset, & word, & addr, NULL)) \
015dc7e1 9094 return false; \
0b6ae522
DJ
9095 remaining = 4; \
9096 more_words--; \
9097 } \
9098
9099#define GET_OP(OP) \
9100 ADVANCE; \
9101 if (remaining) \
9102 { \
9103 remaining--; \
9104 (OP) = word >> 24; \
9105 word <<= 8; \
9106 } \
9107 else \
9108 { \
2b692964 9109 printf (_("[Truncated opcode]\n")); \
015dc7e1 9110 return false; \
0b6ae522 9111 } \
cc5914eb 9112 printf ("0x%02x ", OP)
0b6ae522 9113
015dc7e1 9114static bool
dda8d76d
NC
9115decode_arm_unwind_bytecode (Filedata * filedata,
9116 struct arm_unw_aux_info * aux,
948f632f
DA
9117 unsigned int word,
9118 unsigned int remaining,
9119 unsigned int more_words,
9120 bfd_vma data_offset,
9121 Elf_Internal_Shdr * data_sec,
9122 struct arm_section * data_arm_sec)
fa197c1c
PB
9123{
9124 struct absaddr addr;
015dc7e1 9125 bool res = true;
0b6ae522
DJ
9126
9127 /* Decode the unwinding instructions. */
9128 while (1)
9129 {
9130 unsigned int op, op2;
9131
9132 ADVANCE;
9133 if (remaining == 0)
9134 break;
9135 remaining--;
9136 op = word >> 24;
9137 word <<= 8;
9138
cc5914eb 9139 printf (" 0x%02x ", op);
0b6ae522
DJ
9140
9141 if ((op & 0xc0) == 0x00)
9142 {
9143 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9144
cc5914eb 9145 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9146 }
9147 else if ((op & 0xc0) == 0x40)
9148 {
9149 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9150
cc5914eb 9151 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9152 }
9153 else if ((op & 0xf0) == 0x80)
9154 {
9155 GET_OP (op2);
9156 if (op == 0x80 && op2 == 0)
9157 printf (_("Refuse to unwind"));
9158 else
9159 {
9160 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9161 bool first = true;
0b6ae522 9162 int i;
2b692964 9163
0b6ae522
DJ
9164 printf ("pop {");
9165 for (i = 0; i < 12; i++)
9166 if (mask & (1 << i))
9167 {
9168 if (first)
015dc7e1 9169 first = false;
0b6ae522
DJ
9170 else
9171 printf (", ");
9172 printf ("r%d", 4 + i);
9173 }
9174 printf ("}");
9175 }
9176 }
9177 else if ((op & 0xf0) == 0x90)
9178 {
9179 if (op == 0x9d || op == 0x9f)
9180 printf (_(" [Reserved]"));
9181 else
cc5914eb 9182 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9183 }
9184 else if ((op & 0xf0) == 0xa0)
9185 {
9186 int end = 4 + (op & 0x07);
015dc7e1 9187 bool first = true;
0b6ae522 9188 int i;
61865e30 9189
0b6ae522
DJ
9190 printf (" pop {");
9191 for (i = 4; i <= end; i++)
9192 {
9193 if (first)
015dc7e1 9194 first = false;
0b6ae522
DJ
9195 else
9196 printf (", ");
9197 printf ("r%d", i);
9198 }
9199 if (op & 0x08)
9200 {
1b31d05e 9201 if (!first)
0b6ae522
DJ
9202 printf (", ");
9203 printf ("r14");
9204 }
9205 printf ("}");
9206 }
9207 else if (op == 0xb0)
9208 printf (_(" finish"));
9209 else if (op == 0xb1)
9210 {
9211 GET_OP (op2);
9212 if (op2 == 0 || (op2 & 0xf0) != 0)
9213 printf (_("[Spare]"));
9214 else
9215 {
9216 unsigned int mask = op2 & 0x0f;
015dc7e1 9217 bool first = true;
0b6ae522 9218 int i;
61865e30 9219
0b6ae522
DJ
9220 printf ("pop {");
9221 for (i = 0; i < 12; i++)
9222 if (mask & (1 << i))
9223 {
9224 if (first)
015dc7e1 9225 first = false;
0b6ae522
DJ
9226 else
9227 printf (", ");
9228 printf ("r%d", i);
9229 }
9230 printf ("}");
9231 }
9232 }
9233 else if (op == 0xb2)
9234 {
b115cf96 9235 unsigned char buf[9];
0b6ae522
DJ
9236 unsigned int i, len;
9237 unsigned long offset;
61865e30 9238
b115cf96 9239 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9240 {
9241 GET_OP (buf[i]);
9242 if ((buf[i] & 0x80) == 0)
9243 break;
9244 }
4082ef84 9245 if (i == sizeof (buf))
32ec8896 9246 {
27a45f42 9247 error (_("corrupt change to vsp\n"));
015dc7e1 9248 res = false;
32ec8896 9249 }
4082ef84
NC
9250 else
9251 {
015dc7e1 9252 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9253 assert (len == i + 1);
9254 offset = offset * 4 + 0x204;
9255 printf ("vsp = vsp + %ld", offset);
9256 }
0b6ae522 9257 }
61865e30 9258 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9259 {
61865e30
NC
9260 unsigned int first, last;
9261
9262 GET_OP (op2);
9263 first = op2 >> 4;
9264 last = op2 & 0x0f;
9265 if (op == 0xc8)
9266 first = first + 16;
9267 printf ("pop {D%d", first);
9268 if (last)
9269 printf ("-D%d", first + last);
9270 printf ("}");
9271 }
9272 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9273 {
9274 unsigned int count = op & 0x07;
9275
9276 printf ("pop {D8");
9277 if (count)
9278 printf ("-D%d", 8 + count);
9279 printf ("}");
9280 }
9281 else if (op >= 0xc0 && op <= 0xc5)
9282 {
9283 unsigned int count = op & 0x07;
9284
9285 printf (" pop {wR10");
9286 if (count)
9287 printf ("-wR%d", 10 + count);
9288 printf ("}");
9289 }
9290 else if (op == 0xc6)
9291 {
9292 unsigned int first, last;
9293
9294 GET_OP (op2);
9295 first = op2 >> 4;
9296 last = op2 & 0x0f;
9297 printf ("pop {wR%d", first);
9298 if (last)
9299 printf ("-wR%d", first + last);
9300 printf ("}");
9301 }
9302 else if (op == 0xc7)
9303 {
9304 GET_OP (op2);
9305 if (op2 == 0 || (op2 & 0xf0) != 0)
9306 printf (_("[Spare]"));
0b6ae522
DJ
9307 else
9308 {
61865e30 9309 unsigned int mask = op2 & 0x0f;
015dc7e1 9310 bool first = true;
61865e30
NC
9311 int i;
9312
9313 printf ("pop {");
9314 for (i = 0; i < 4; i++)
9315 if (mask & (1 << i))
9316 {
9317 if (first)
015dc7e1 9318 first = false;
61865e30
NC
9319 else
9320 printf (", ");
9321 printf ("wCGR%d", i);
9322 }
9323 printf ("}");
0b6ae522
DJ
9324 }
9325 }
61865e30 9326 else
32ec8896
NC
9327 {
9328 printf (_(" [unsupported opcode]"));
015dc7e1 9329 res = false;
32ec8896
NC
9330 }
9331
0b6ae522
DJ
9332 printf ("\n");
9333 }
32ec8896
NC
9334
9335 return res;
fa197c1c
PB
9336}
9337
015dc7e1 9338static bool
dda8d76d
NC
9339decode_tic6x_unwind_bytecode (Filedata * filedata,
9340 struct arm_unw_aux_info * aux,
948f632f
DA
9341 unsigned int word,
9342 unsigned int remaining,
9343 unsigned int more_words,
9344 bfd_vma data_offset,
9345 Elf_Internal_Shdr * data_sec,
9346 struct arm_section * data_arm_sec)
fa197c1c
PB
9347{
9348 struct absaddr addr;
9349
9350 /* Decode the unwinding instructions. */
9351 while (1)
9352 {
9353 unsigned int op, op2;
9354
9355 ADVANCE;
9356 if (remaining == 0)
9357 break;
9358 remaining--;
9359 op = word >> 24;
9360 word <<= 8;
9361
9cf03b7e 9362 printf (" 0x%02x ", op);
fa197c1c
PB
9363
9364 if ((op & 0xc0) == 0x00)
9365 {
9366 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9367 printf (" sp = sp + %d", offset);
fa197c1c
PB
9368 }
9369 else if ((op & 0xc0) == 0x80)
9370 {
9371 GET_OP (op2);
9372 if (op == 0x80 && op2 == 0)
9373 printf (_("Refuse to unwind"));
9374 else
9375 {
9376 unsigned int mask = ((op & 0x1f) << 8) | op2;
9377 if (op & 0x20)
9378 printf ("pop compact {");
9379 else
9380 printf ("pop {");
9381
9382 decode_tic6x_unwind_regmask (mask);
9383 printf("}");
9384 }
9385 }
9386 else if ((op & 0xf0) == 0xc0)
9387 {
9388 unsigned int reg;
9389 unsigned int nregs;
9390 unsigned int i;
9391 const char *name;
a734115a
NC
9392 struct
9393 {
32ec8896
NC
9394 unsigned int offset;
9395 unsigned int reg;
fa197c1c
PB
9396 } regpos[16];
9397
9398 /* Scan entire instruction first so that GET_OP output is not
9399 interleaved with disassembly. */
9400 nregs = 0;
9401 for (i = 0; nregs < (op & 0xf); i++)
9402 {
9403 GET_OP (op2);
9404 reg = op2 >> 4;
9405 if (reg != 0xf)
9406 {
9407 regpos[nregs].offset = i * 2;
9408 regpos[nregs].reg = reg;
9409 nregs++;
9410 }
9411
9412 reg = op2 & 0xf;
9413 if (reg != 0xf)
9414 {
9415 regpos[nregs].offset = i * 2 + 1;
9416 regpos[nregs].reg = reg;
9417 nregs++;
9418 }
9419 }
9420
9421 printf (_("pop frame {"));
18344509 9422 if (nregs == 0)
fa197c1c 9423 {
18344509
NC
9424 printf (_("*corrupt* - no registers specified"));
9425 }
9426 else
9427 {
9428 reg = nregs - 1;
9429 for (i = i * 2; i > 0; i--)
fa197c1c 9430 {
18344509
NC
9431 if (regpos[reg].offset == i - 1)
9432 {
9433 name = tic6x_unwind_regnames[regpos[reg].reg];
9434 if (reg > 0)
9435 reg--;
9436 }
9437 else
9438 name = _("[pad]");
fa197c1c 9439
18344509
NC
9440 fputs (name, stdout);
9441 if (i > 1)
9442 printf (", ");
9443 }
fa197c1c
PB
9444 }
9445
9446 printf ("}");
9447 }
9448 else if (op == 0xd0)
9449 printf (" MOV FP, SP");
9450 else if (op == 0xd1)
9451 printf (" __c6xabi_pop_rts");
9452 else if (op == 0xd2)
9453 {
9454 unsigned char buf[9];
9455 unsigned int i, len;
9456 unsigned long offset;
a734115a 9457
fa197c1c
PB
9458 for (i = 0; i < sizeof (buf); i++)
9459 {
9460 GET_OP (buf[i]);
9461 if ((buf[i] & 0x80) == 0)
9462 break;
9463 }
0eff7165
NC
9464 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9465 if (i == sizeof (buf))
9466 {
0eff7165 9467 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 9468 return false;
0eff7165 9469 }
948f632f 9470
015dc7e1 9471 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
9472 assert (len == i + 1);
9473 offset = offset * 8 + 0x408;
9474 printf (_("sp = sp + %ld"), offset);
9475 }
9476 else if ((op & 0xf0) == 0xe0)
9477 {
9478 if ((op & 0x0f) == 7)
9479 printf (" RETURN");
9480 else
9481 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9482 }
9483 else
9484 {
9485 printf (_(" [unsupported opcode]"));
9486 }
9487 putchar ('\n');
9488 }
32ec8896 9489
015dc7e1 9490 return true;
fa197c1c
PB
9491}
9492
9493static bfd_vma
dda8d76d 9494arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9495{
9496 bfd_vma offset;
9497
9498 offset = word & 0x7fffffff;
9499 if (offset & 0x40000000)
9500 offset |= ~ (bfd_vma) 0x7fffffff;
9501
dda8d76d 9502 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9503 offset <<= 1;
9504
9505 return offset + where;
9506}
9507
015dc7e1 9508static bool
dda8d76d
NC
9509decode_arm_unwind (Filedata * filedata,
9510 struct arm_unw_aux_info * aux,
1b31d05e
NC
9511 unsigned int word,
9512 unsigned int remaining,
9513 bfd_vma data_offset,
9514 Elf_Internal_Shdr * data_sec,
9515 struct arm_section * data_arm_sec)
fa197c1c
PB
9516{
9517 int per_index;
9518 unsigned int more_words = 0;
37e14bc3 9519 struct absaddr addr;
1b31d05e 9520 bfd_vma sym_name = (bfd_vma) -1;
015dc7e1 9521 bool res = true;
fa197c1c
PB
9522
9523 if (remaining == 0)
9524 {
1b31d05e
NC
9525 /* Fetch the first word.
9526 Note - when decoding an object file the address extracted
9527 here will always be 0. So we also pass in the sym_name
9528 parameter so that we can find the symbol associated with
9529 the personality routine. */
dda8d76d 9530 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9531 & word, & addr, & sym_name))
015dc7e1 9532 return false;
1b31d05e 9533
fa197c1c
PB
9534 remaining = 4;
9535 }
c93dbb25
CZ
9536 else
9537 {
9538 addr.section = SHN_UNDEF;
9539 addr.offset = 0;
9540 }
fa197c1c
PB
9541
9542 if ((word & 0x80000000) == 0)
9543 {
9544 /* Expand prel31 for personality routine. */
9545 bfd_vma fn;
9546 const char *procname;
9547
dda8d76d 9548 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9549 printf (_(" Personality routine: "));
1b31d05e
NC
9550 if (fn == 0
9551 && addr.section == SHN_UNDEF && addr.offset == 0
9552 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9553 {
9554 procname = aux->strtab + sym_name;
9555 print_vma (fn, PREFIX_HEX);
9556 if (procname)
9557 {
9558 fputs (" <", stdout);
9559 fputs (procname, stdout);
9560 fputc ('>', stdout);
9561 }
9562 }
9563 else
dda8d76d 9564 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9565 fputc ('\n', stdout);
9566
9567 /* The GCC personality routines use the standard compact
9568 encoding, starting with one byte giving the number of
9569 words. */
9570 if (procname != NULL
24d127aa
ML
9571 && (startswith (procname, "__gcc_personality_v0")
9572 || startswith (procname, "__gxx_personality_v0")
9573 || startswith (procname, "__gcj_personality_v0")
9574 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
9575 {
9576 remaining = 0;
9577 more_words = 1;
9578 ADVANCE;
9579 if (!remaining)
9580 {
9581 printf (_(" [Truncated data]\n"));
015dc7e1 9582 return false;
fa197c1c
PB
9583 }
9584 more_words = word >> 24;
9585 word <<= 8;
9586 remaining--;
9587 per_index = -1;
9588 }
9589 else
015dc7e1 9590 return true;
fa197c1c
PB
9591 }
9592 else
9593 {
1b31d05e 9594 /* ARM EHABI Section 6.3:
0b4362b0 9595
1b31d05e 9596 An exception-handling table entry for the compact model looks like:
0b4362b0 9597
1b31d05e
NC
9598 31 30-28 27-24 23-0
9599 -- ----- ----- ----
9600 1 0 index Data for personalityRoutine[index] */
9601
dda8d76d 9602 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9603 && (word & 0x70000000))
32ec8896
NC
9604 {
9605 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 9606 res = false;
32ec8896 9607 }
1b31d05e 9608
fa197c1c 9609 per_index = (word >> 24) & 0x7f;
1b31d05e 9610 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9611 if (per_index == 0)
9612 {
9613 more_words = 0;
9614 word <<= 8;
9615 remaining--;
9616 }
9617 else if (per_index < 3)
9618 {
9619 more_words = (word >> 16) & 0xff;
9620 word <<= 16;
9621 remaining -= 2;
9622 }
9623 }
9624
dda8d76d 9625 switch (filedata->file_header.e_machine)
fa197c1c
PB
9626 {
9627 case EM_ARM:
9628 if (per_index < 3)
9629 {
dda8d76d 9630 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 9631 data_offset, data_sec, data_arm_sec))
015dc7e1 9632 res = false;
fa197c1c
PB
9633 }
9634 else
1b31d05e
NC
9635 {
9636 warn (_("Unknown ARM compact model index encountered\n"));
9637 printf (_(" [reserved]\n"));
015dc7e1 9638 res = false;
1b31d05e 9639 }
fa197c1c
PB
9640 break;
9641
9642 case EM_TI_C6000:
9643 if (per_index < 3)
9644 {
dda8d76d 9645 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 9646 data_offset, data_sec, data_arm_sec))
015dc7e1 9647 res = false;
fa197c1c
PB
9648 }
9649 else if (per_index < 5)
9650 {
9651 if (((word >> 17) & 0x7f) == 0x7f)
9652 printf (_(" Restore stack from frame pointer\n"));
9653 else
9654 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9655 printf (_(" Registers restored: "));
9656 if (per_index == 4)
9657 printf (" (compact) ");
9658 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9659 putchar ('\n');
9660 printf (_(" Return register: %s\n"),
9661 tic6x_unwind_regnames[word & 0xf]);
9662 }
9663 else
1b31d05e 9664 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9665 break;
9666
9667 default:
74e1a04b 9668 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9669 filedata->file_header.e_machine);
015dc7e1 9670 res = false;
fa197c1c 9671 }
0b6ae522
DJ
9672
9673 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9674
9675 return res;
0b6ae522
DJ
9676}
9677
015dc7e1 9678static bool
dda8d76d
NC
9679dump_arm_unwind (Filedata * filedata,
9680 struct arm_unw_aux_info * aux,
9681 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9682{
9683 struct arm_section exidx_arm_sec, extab_arm_sec;
9684 unsigned int i, exidx_len;
948f632f 9685 unsigned long j, nfuns;
015dc7e1 9686 bool res = true;
0b6ae522
DJ
9687
9688 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9689 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9690 exidx_len = exidx_sec->sh_size / 8;
9691
948f632f
DA
9692 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9693 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9694 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9695 aux->funtab[nfuns++] = aux->symtab[j];
9696 aux->nfuns = nfuns;
9697 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9698
0b6ae522
DJ
9699 for (i = 0; i < exidx_len; i++)
9700 {
9701 unsigned int exidx_fn, exidx_entry;
9702 struct absaddr fn_addr, entry_addr;
9703 bfd_vma fn;
9704
9705 fputc ('\n', stdout);
9706
dda8d76d 9707 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9708 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9709 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9710 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9711 {
948f632f 9712 free (aux->funtab);
1b31d05e
NC
9713 arm_free_section (& exidx_arm_sec);
9714 arm_free_section (& extab_arm_sec);
015dc7e1 9715 return false;
0b6ae522
DJ
9716 }
9717
83c257ca
NC
9718 /* ARM EHABI, Section 5:
9719 An index table entry consists of 2 words.
9720 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9721 if (exidx_fn & 0x80000000)
32ec8896
NC
9722 {
9723 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 9724 res = false;
32ec8896 9725 }
83c257ca 9726
dda8d76d 9727 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9728
dda8d76d 9729 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9730 fputs (": ", stdout);
9731
9732 if (exidx_entry == 1)
9733 {
9734 print_vma (exidx_entry, PREFIX_HEX);
9735 fputs (" [cantunwind]\n", stdout);
9736 }
9737 else if (exidx_entry & 0x80000000)
9738 {
9739 print_vma (exidx_entry, PREFIX_HEX);
9740 fputc ('\n', stdout);
dda8d76d 9741 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9742 }
9743 else
9744 {
8f73510c 9745 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9746 Elf_Internal_Shdr *table_sec;
9747
9748 fputs ("@", stdout);
dda8d76d 9749 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9750 print_vma (table, PREFIX_HEX);
9751 printf ("\n");
9752
9753 /* Locate the matching .ARM.extab. */
9754 if (entry_addr.section != SHN_UNDEF
dda8d76d 9755 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9756 {
dda8d76d 9757 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9758 table_offset = entry_addr.offset;
1a915552
NC
9759 /* PR 18879 */
9760 if (table_offset > table_sec->sh_size
9761 || ((bfd_signed_vma) table_offset) < 0)
9762 {
9763 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9764 (unsigned long) table_offset,
dda8d76d 9765 printable_section_name (filedata, table_sec));
015dc7e1 9766 res = false;
1a915552
NC
9767 continue;
9768 }
0b6ae522
DJ
9769 }
9770 else
9771 {
dda8d76d 9772 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9773 if (table_sec != NULL)
9774 table_offset = table - table_sec->sh_addr;
9775 }
32ec8896 9776
0b6ae522
DJ
9777 if (table_sec == NULL)
9778 {
9779 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9780 (unsigned long) table);
015dc7e1 9781 res = false;
0b6ae522
DJ
9782 continue;
9783 }
32ec8896 9784
dda8d76d 9785 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 9786 &extab_arm_sec))
015dc7e1 9787 res = false;
0b6ae522
DJ
9788 }
9789 }
9790
9791 printf ("\n");
9792
948f632f 9793 free (aux->funtab);
0b6ae522
DJ
9794 arm_free_section (&exidx_arm_sec);
9795 arm_free_section (&extab_arm_sec);
32ec8896
NC
9796
9797 return res;
0b6ae522
DJ
9798}
9799
fa197c1c 9800/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9801
015dc7e1 9802static bool
dda8d76d 9803arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9804{
9805 struct arm_unw_aux_info aux;
9806 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9807 Elf_Internal_Shdr *sec;
9808 unsigned long i;
fa197c1c 9809 unsigned int sec_type;
015dc7e1 9810 bool res = true;
0b6ae522 9811
dda8d76d 9812 switch (filedata->file_header.e_machine)
fa197c1c
PB
9813 {
9814 case EM_ARM:
9815 sec_type = SHT_ARM_EXIDX;
9816 break;
9817
9818 case EM_TI_C6000:
9819 sec_type = SHT_C6000_UNWIND;
9820 break;
9821
0b4362b0 9822 default:
74e1a04b 9823 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9824 filedata->file_header.e_machine);
015dc7e1 9825 return false;
fa197c1c
PB
9826 }
9827
dda8d76d 9828 if (filedata->string_table == NULL)
015dc7e1 9829 return false;
1b31d05e
NC
9830
9831 memset (& aux, 0, sizeof (aux));
dda8d76d 9832 aux.filedata = filedata;
0b6ae522 9833
dda8d76d 9834 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9835 {
28d13567 9836 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9837 {
28d13567 9838 if (aux.symtab)
74e1a04b 9839 {
28d13567
AM
9840 error (_("Multiple symbol tables encountered\n"));
9841 free (aux.symtab);
9842 aux.symtab = NULL;
74e1a04b 9843 free (aux.strtab);
28d13567 9844 aux.strtab = NULL;
74e1a04b 9845 }
28d13567
AM
9846 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9847 &aux.strtab, &aux.strtab_size))
015dc7e1 9848 return false;
0b6ae522 9849 }
fa197c1c 9850 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9851 unwsec = sec;
9852 }
9853
1b31d05e 9854 if (unwsec == NULL)
0b6ae522 9855 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9856 else
dda8d76d 9857 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9858 {
9859 if (sec->sh_type == sec_type)
9860 {
d3a49aa8
AM
9861 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9862 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9863 "contains %lu entry:\n",
9864 "\nUnwind section '%s' at offset 0x%lx "
9865 "contains %lu entries:\n",
9866 num_unwind),
dda8d76d 9867 printable_section_name (filedata, sec),
1b31d05e 9868 (unsigned long) sec->sh_offset,
d3a49aa8 9869 num_unwind);
0b6ae522 9870
dda8d76d 9871 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 9872 res = false;
1b31d05e
NC
9873 }
9874 }
0b6ae522 9875
9db70fc3
AM
9876 free (aux.symtab);
9877 free ((char *) aux.strtab);
32ec8896
NC
9878
9879 return res;
0b6ae522
DJ
9880}
9881
3ecc00ec
NC
9882static bool
9883no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
9884{
9885 printf (_("No processor specific unwind information to decode\n"));
9886 return true;
9887}
9888
015dc7e1 9889static bool
dda8d76d 9890process_unwind (Filedata * filedata)
57346661 9891{
2cf0635d
NC
9892 struct unwind_handler
9893 {
32ec8896 9894 unsigned int machtype;
015dc7e1 9895 bool (* handler)(Filedata *);
2cf0635d
NC
9896 } handlers[] =
9897 {
0b6ae522 9898 { EM_ARM, arm_process_unwind },
57346661
AM
9899 { EM_IA_64, ia64_process_unwind },
9900 { EM_PARISC, hppa_process_unwind },
fa197c1c 9901 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
9902 { EM_386, no_processor_specific_unwind },
9903 { EM_X86_64, no_processor_specific_unwind },
32ec8896 9904 { 0, NULL }
57346661
AM
9905 };
9906 int i;
9907
9908 if (!do_unwind)
015dc7e1 9909 return true;
57346661
AM
9910
9911 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9912 if (filedata->file_header.e_machine == handlers[i].machtype)
9913 return handlers[i].handler (filedata);
57346661 9914
1b31d05e 9915 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9916 get_machine_name (filedata->file_header.e_machine));
015dc7e1 9917 return true;
57346661
AM
9918}
9919
37c18eed
SD
9920static void
9921dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
9922{
9923 switch (entry->d_tag)
9924 {
9925 case DT_AARCH64_BTI_PLT:
1dbade74 9926 case DT_AARCH64_PAC_PLT:
37c18eed
SD
9927 break;
9928 default:
9929 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9930 break;
9931 }
9932 putchar ('\n');
9933}
9934
252b5132 9935static void
978c4450 9936dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
9937{
9938 switch (entry->d_tag)
9939 {
9940 case DT_MIPS_FLAGS:
9941 if (entry->d_un.d_val == 0)
4b68bca3 9942 printf (_("NONE"));
252b5132
RH
9943 else
9944 {
9945 static const char * opts[] =
9946 {
9947 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9948 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9949 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9950 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9951 "RLD_ORDER_SAFE"
9952 };
9953 unsigned int cnt;
015dc7e1 9954 bool first = true;
2b692964 9955
60bca95a 9956 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9957 if (entry->d_un.d_val & (1 << cnt))
9958 {
9959 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 9960 first = false;
252b5132 9961 }
252b5132
RH
9962 }
9963 break;
103f02d3 9964
252b5132 9965 case DT_MIPS_IVERSION:
978c4450
AM
9966 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
9967 printf (_("Interface Version: %s"),
9968 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 9969 else
76ca31c0
NC
9970 {
9971 char buf[40];
9972 sprintf_vma (buf, entry->d_un.d_ptr);
9973 /* Note: coded this way so that there is a single string for translation. */
9974 printf (_("<corrupt: %s>"), buf);
9975 }
252b5132 9976 break;
103f02d3 9977
252b5132
RH
9978 case DT_MIPS_TIME_STAMP:
9979 {
d5b07ef4 9980 char timebuf[128];
2cf0635d 9981 struct tm * tmp;
91d6fa6a 9982 time_t atime = entry->d_un.d_val;
82b1b41b 9983
91d6fa6a 9984 tmp = gmtime (&atime);
82b1b41b
NC
9985 /* PR 17531: file: 6accc532. */
9986 if (tmp == NULL)
9987 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9988 else
9989 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9990 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9991 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9992 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9993 }
9994 break;
103f02d3 9995
252b5132
RH
9996 case DT_MIPS_RLD_VERSION:
9997 case DT_MIPS_LOCAL_GOTNO:
9998 case DT_MIPS_CONFLICTNO:
9999 case DT_MIPS_LIBLISTNO:
10000 case DT_MIPS_SYMTABNO:
10001 case DT_MIPS_UNREFEXTNO:
10002 case DT_MIPS_HIPAGENO:
10003 case DT_MIPS_DELTA_CLASS_NO:
10004 case DT_MIPS_DELTA_INSTANCE_NO:
10005 case DT_MIPS_DELTA_RELOC_NO:
10006 case DT_MIPS_DELTA_SYM_NO:
10007 case DT_MIPS_DELTA_CLASSSYM_NO:
10008 case DT_MIPS_COMPACT_SIZE:
c69075ac 10009 print_vma (entry->d_un.d_val, DEC);
252b5132 10010 break;
103f02d3 10011
f16a9783 10012 case DT_MIPS_XHASH:
978c4450
AM
10013 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10014 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10015 /* Falls through. */
10016
103f02d3 10017 default:
4b68bca3 10018 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10019 }
4b68bca3 10020 putchar ('\n');
103f02d3
UD
10021}
10022
103f02d3 10023static void
2cf0635d 10024dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10025{
10026 switch (entry->d_tag)
10027 {
10028 case DT_HP_DLD_FLAGS:
10029 {
10030 static struct
10031 {
10032 long int bit;
2cf0635d 10033 const char * str;
5e220199
NC
10034 }
10035 flags[] =
10036 {
10037 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10038 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10039 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10040 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10041 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10042 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10043 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10044 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10045 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10046 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10047 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10048 { DT_HP_GST, "HP_GST" },
10049 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10050 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10051 { DT_HP_NODELETE, "HP_NODELETE" },
10052 { DT_HP_GROUP, "HP_GROUP" },
10053 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10054 };
015dc7e1 10055 bool first = true;
5e220199 10056 size_t cnt;
f7a99963 10057 bfd_vma val = entry->d_un.d_val;
103f02d3 10058
60bca95a 10059 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10060 if (val & flags[cnt].bit)
30800947
NC
10061 {
10062 if (! first)
10063 putchar (' ');
10064 fputs (flags[cnt].str, stdout);
015dc7e1 10065 first = false;
30800947
NC
10066 val ^= flags[cnt].bit;
10067 }
76da6bbe 10068
103f02d3 10069 if (val != 0 || first)
f7a99963
NC
10070 {
10071 if (! first)
10072 putchar (' ');
10073 print_vma (val, HEX);
10074 }
103f02d3
UD
10075 }
10076 break;
76da6bbe 10077
252b5132 10078 default:
f7a99963
NC
10079 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10080 break;
252b5132 10081 }
35b1837e 10082 putchar ('\n');
252b5132
RH
10083}
10084
28f997cf
TG
10085#ifdef BFD64
10086
10087/* VMS vs Unix time offset and factor. */
10088
10089#define VMS_EPOCH_OFFSET 35067168000000000LL
10090#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10091#ifndef INT64_MIN
10092#define INT64_MIN (-9223372036854775807LL - 1)
10093#endif
28f997cf
TG
10094
10095/* Display a VMS time in a human readable format. */
10096
10097static void
10098print_vms_time (bfd_int64_t vmstime)
10099{
dccc31de 10100 struct tm *tm = NULL;
28f997cf
TG
10101 time_t unxtime;
10102
dccc31de
AM
10103 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10104 {
10105 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10106 unxtime = vmstime;
10107 if (unxtime == vmstime)
10108 tm = gmtime (&unxtime);
10109 }
10110 if (tm != NULL)
10111 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10112 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10113 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
10114}
10115#endif /* BFD64 */
10116
ecc51f48 10117static void
2cf0635d 10118dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10119{
10120 switch (entry->d_tag)
10121 {
0de14b54 10122 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10123 /* First 3 slots reserved. */
ecc51f48
NC
10124 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10125 printf (" -- ");
10126 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10127 break;
10128
28f997cf
TG
10129 case DT_IA_64_VMS_LINKTIME:
10130#ifdef BFD64
10131 print_vms_time (entry->d_un.d_val);
10132#endif
10133 break;
10134
10135 case DT_IA_64_VMS_LNKFLAGS:
10136 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10137 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10138 printf (" CALL_DEBUG");
10139 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10140 printf (" NOP0BUFS");
10141 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10142 printf (" P0IMAGE");
10143 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10144 printf (" MKTHREADS");
10145 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10146 printf (" UPCALLS");
10147 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10148 printf (" IMGSTA");
10149 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10150 printf (" INITIALIZE");
10151 if (entry->d_un.d_val & VMS_LF_MAIN)
10152 printf (" MAIN");
10153 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10154 printf (" EXE_INIT");
10155 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10156 printf (" TBK_IN_IMG");
10157 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10158 printf (" DBG_IN_IMG");
10159 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10160 printf (" TBK_IN_DSF");
10161 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10162 printf (" DBG_IN_DSF");
10163 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10164 printf (" SIGNATURES");
10165 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10166 printf (" REL_SEG_OFF");
10167 break;
10168
bdf4d63a
JJ
10169 default:
10170 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10171 break;
ecc51f48 10172 }
bdf4d63a 10173 putchar ('\n');
ecc51f48
NC
10174}
10175
015dc7e1 10176static bool
dda8d76d 10177get_32bit_dynamic_section (Filedata * filedata)
252b5132 10178{
2cf0635d
NC
10179 Elf32_External_Dyn * edyn;
10180 Elf32_External_Dyn * ext;
10181 Elf_Internal_Dyn * entry;
103f02d3 10182
978c4450
AM
10183 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10184 filedata->dynamic_addr, 1,
10185 filedata->dynamic_size,
10186 _("dynamic section"));
a6e9f9df 10187 if (!edyn)
015dc7e1 10188 return false;
103f02d3 10189
071436c6
NC
10190 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10191 might not have the luxury of section headers. Look for the DT_NULL
10192 terminator to determine the number of entries. */
978c4450
AM
10193 for (ext = edyn, filedata->dynamic_nent = 0;
10194 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10195 ext++)
10196 {
978c4450 10197 filedata->dynamic_nent++;
ba2685cc
AM
10198 if (BYTE_GET (ext->d_tag) == DT_NULL)
10199 break;
10200 }
252b5132 10201
978c4450
AM
10202 filedata->dynamic_section
10203 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10204 if (filedata->dynamic_section == NULL)
252b5132 10205 {
8b73c356 10206 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10207 (unsigned long) filedata->dynamic_nent);
9ea033b2 10208 free (edyn);
015dc7e1 10209 return false;
9ea033b2 10210 }
252b5132 10211
978c4450
AM
10212 for (ext = edyn, entry = filedata->dynamic_section;
10213 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10214 ext++, entry++)
9ea033b2 10215 {
fb514b26
AM
10216 entry->d_tag = BYTE_GET (ext->d_tag);
10217 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10218 }
10219
9ea033b2
NC
10220 free (edyn);
10221
015dc7e1 10222 return true;
9ea033b2
NC
10223}
10224
015dc7e1 10225static bool
dda8d76d 10226get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10227{
2cf0635d
NC
10228 Elf64_External_Dyn * edyn;
10229 Elf64_External_Dyn * ext;
10230 Elf_Internal_Dyn * entry;
103f02d3 10231
071436c6 10232 /* Read in the data. */
978c4450
AM
10233 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10234 filedata->dynamic_addr, 1,
10235 filedata->dynamic_size,
10236 _("dynamic section"));
a6e9f9df 10237 if (!edyn)
015dc7e1 10238 return false;
103f02d3 10239
071436c6
NC
10240 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10241 might not have the luxury of section headers. Look for the DT_NULL
10242 terminator to determine the number of entries. */
978c4450 10243 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10244 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10245 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10246 ext++)
10247 {
978c4450 10248 filedata->dynamic_nent++;
66543521 10249 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10250 break;
10251 }
252b5132 10252
978c4450
AM
10253 filedata->dynamic_section
10254 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10255 if (filedata->dynamic_section == NULL)
252b5132 10256 {
8b73c356 10257 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10258 (unsigned long) filedata->dynamic_nent);
252b5132 10259 free (edyn);
015dc7e1 10260 return false;
252b5132
RH
10261 }
10262
071436c6 10263 /* Convert from external to internal formats. */
978c4450
AM
10264 for (ext = edyn, entry = filedata->dynamic_section;
10265 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10266 ext++, entry++)
252b5132 10267 {
66543521
AM
10268 entry->d_tag = BYTE_GET (ext->d_tag);
10269 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10270 }
10271
10272 free (edyn);
10273
015dc7e1 10274 return true;
9ea033b2
NC
10275}
10276
4de91c10
AM
10277static bool
10278get_dynamic_section (Filedata *filedata)
10279{
10280 if (filedata->dynamic_section)
10281 return true;
10282
10283 if (is_32bit_elf)
10284 return get_32bit_dynamic_section (filedata);
10285 else
10286 return get_64bit_dynamic_section (filedata);
10287}
10288
e9e44622
JJ
10289static void
10290print_dynamic_flags (bfd_vma flags)
d1133906 10291{
015dc7e1 10292 bool first = true;
13ae64f3 10293
d1133906
NC
10294 while (flags)
10295 {
10296 bfd_vma flag;
10297
10298 flag = flags & - flags;
10299 flags &= ~ flag;
10300
e9e44622 10301 if (first)
015dc7e1 10302 first = false;
e9e44622
JJ
10303 else
10304 putc (' ', stdout);
13ae64f3 10305
d1133906
NC
10306 switch (flag)
10307 {
e9e44622
JJ
10308 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10309 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10310 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10311 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10312 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10313 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10314 }
10315 }
e9e44622 10316 puts ("");
d1133906
NC
10317}
10318
10ca4b04
L
10319static bfd_vma *
10320get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10321{
10322 unsigned char * e_data;
10323 bfd_vma * i_data;
10324
10325 /* If the size_t type is smaller than the bfd_size_type, eg because
10326 you are building a 32-bit tool on a 64-bit host, then make sure
10327 that when (number) is cast to (size_t) no information is lost. */
10328 if (sizeof (size_t) < sizeof (bfd_size_type)
10329 && (bfd_size_type) ((size_t) number) != number)
10330 {
10331 error (_("Size truncation prevents reading %s elements of size %u\n"),
10332 bfd_vmatoa ("u", number), ent_size);
10333 return NULL;
10334 }
10335
10336 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10337 attempting to allocate memory when the read is bound to fail. */
10338 if (ent_size * number > filedata->file_size)
10339 {
10340 error (_("Invalid number of dynamic entries: %s\n"),
10341 bfd_vmatoa ("u", number));
10342 return NULL;
10343 }
10344
10345 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10346 if (e_data == NULL)
10347 {
10348 error (_("Out of memory reading %s dynamic entries\n"),
10349 bfd_vmatoa ("u", number));
10350 return NULL;
10351 }
10352
10353 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10354 {
10355 error (_("Unable to read in %s bytes of dynamic data\n"),
10356 bfd_vmatoa ("u", number * ent_size));
10357 free (e_data);
10358 return NULL;
10359 }
10360
10361 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10362 if (i_data == NULL)
10363 {
10364 error (_("Out of memory allocating space for %s dynamic entries\n"),
10365 bfd_vmatoa ("u", number));
10366 free (e_data);
10367 return NULL;
10368 }
10369
10370 while (number--)
10371 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10372
10373 free (e_data);
10374
10375 return i_data;
10376}
10377
10378static unsigned long
10379get_num_dynamic_syms (Filedata * filedata)
10380{
10381 unsigned long num_of_syms = 0;
10382
10383 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10384 return num_of_syms;
10385
978c4450 10386 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10387 {
10388 unsigned char nb[8];
10389 unsigned char nc[8];
10390 unsigned int hash_ent_size = 4;
10391
10392 if ((filedata->file_header.e_machine == EM_ALPHA
10393 || filedata->file_header.e_machine == EM_S390
10394 || filedata->file_header.e_machine == EM_S390_OLD)
10395 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10396 hash_ent_size = 8;
10397
10398 if (fseek (filedata->handle,
978c4450
AM
10399 (filedata->archive_file_offset
10400 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10401 sizeof nb + sizeof nc)),
10402 SEEK_SET))
10403 {
10404 error (_("Unable to seek to start of dynamic information\n"));
10405 goto no_hash;
10406 }
10407
10408 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10409 {
10410 error (_("Failed to read in number of buckets\n"));
10411 goto no_hash;
10412 }
10413
10414 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10415 {
10416 error (_("Failed to read in number of chains\n"));
10417 goto no_hash;
10418 }
10419
978c4450
AM
10420 filedata->nbuckets = byte_get (nb, hash_ent_size);
10421 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10422
2482f306
AM
10423 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10424 {
10425 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10426 hash_ent_size);
10427 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10428 hash_ent_size);
001890e1 10429
2482f306
AM
10430 if (filedata->buckets != NULL && filedata->chains != NULL)
10431 num_of_syms = filedata->nchains;
10432 }
ceb9bf11 10433 no_hash:
10ca4b04
L
10434 if (num_of_syms == 0)
10435 {
9db70fc3
AM
10436 free (filedata->buckets);
10437 filedata->buckets = NULL;
10438 free (filedata->chains);
10439 filedata->chains = NULL;
978c4450 10440 filedata->nbuckets = 0;
10ca4b04
L
10441 }
10442 }
10443
978c4450 10444 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10445 {
10446 unsigned char nb[16];
10447 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10448 bfd_vma buckets_vma;
10449 unsigned long hn;
10ca4b04
L
10450
10451 if (fseek (filedata->handle,
978c4450
AM
10452 (filedata->archive_file_offset
10453 + offset_from_vma (filedata,
10454 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10455 sizeof nb)),
10456 SEEK_SET))
10457 {
10458 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10459 goto no_gnu_hash;
10460 }
10461
10462 if (fread (nb, 16, 1, filedata->handle) != 1)
10463 {
10464 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10465 goto no_gnu_hash;
10466 }
10467
978c4450
AM
10468 filedata->ngnubuckets = byte_get (nb, 4);
10469 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10470 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10471 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10472 if (is_32bit_elf)
10473 buckets_vma += bitmaskwords * 4;
10474 else
10475 buckets_vma += bitmaskwords * 8;
10476
10477 if (fseek (filedata->handle,
978c4450 10478 (filedata->archive_file_offset
10ca4b04
L
10479 + offset_from_vma (filedata, buckets_vma, 4)),
10480 SEEK_SET))
10481 {
10482 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10483 goto no_gnu_hash;
10484 }
10485
978c4450
AM
10486 filedata->gnubuckets
10487 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10488
978c4450 10489 if (filedata->gnubuckets == NULL)
90837ea7 10490 goto no_gnu_hash;
10ca4b04 10491
978c4450
AM
10492 for (i = 0; i < filedata->ngnubuckets; i++)
10493 if (filedata->gnubuckets[i] != 0)
10ca4b04 10494 {
978c4450 10495 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10496 goto no_gnu_hash;
10ca4b04 10497
978c4450
AM
10498 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10499 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10500 }
10501
10502 if (maxchain == 0xffffffff)
90837ea7 10503 goto no_gnu_hash;
10ca4b04 10504
978c4450 10505 maxchain -= filedata->gnusymidx;
10ca4b04
L
10506
10507 if (fseek (filedata->handle,
978c4450
AM
10508 (filedata->archive_file_offset
10509 + offset_from_vma (filedata,
10510 buckets_vma + 4 * (filedata->ngnubuckets
10511 + maxchain),
10512 4)),
10ca4b04
L
10513 SEEK_SET))
10514 {
10515 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10516 goto no_gnu_hash;
10517 }
10518
10519 do
10520 {
10521 if (fread (nb, 4, 1, filedata->handle) != 1)
10522 {
10523 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10524 goto no_gnu_hash;
10525 }
10526
10527 if (maxchain + 1 == 0)
90837ea7 10528 goto no_gnu_hash;
10ca4b04
L
10529
10530 ++maxchain;
10531 }
10532 while ((byte_get (nb, 4) & 1) == 0);
10533
10534 if (fseek (filedata->handle,
978c4450
AM
10535 (filedata->archive_file_offset
10536 + offset_from_vma (filedata, (buckets_vma
10537 + 4 * filedata->ngnubuckets),
10538 4)),
10ca4b04
L
10539 SEEK_SET))
10540 {
10541 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10542 goto no_gnu_hash;
10543 }
10544
978c4450
AM
10545 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10546 filedata->ngnuchains = maxchain;
10ca4b04 10547
978c4450 10548 if (filedata->gnuchains == NULL)
90837ea7 10549 goto no_gnu_hash;
10ca4b04 10550
978c4450 10551 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10552 {
10553 if (fseek (filedata->handle,
978c4450 10554 (filedata->archive_file_offset
10ca4b04 10555 + offset_from_vma (filedata, (buckets_vma
978c4450 10556 + 4 * (filedata->ngnubuckets
10ca4b04
L
10557 + maxchain)), 4)),
10558 SEEK_SET))
10559 {
10560 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10561 goto no_gnu_hash;
10562 }
10563
978c4450 10564 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10565 if (filedata->mipsxlat == NULL)
10566 goto no_gnu_hash;
10ca4b04
L
10567 }
10568
978c4450
AM
10569 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10570 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10571 {
978c4450
AM
10572 bfd_vma si = filedata->gnubuckets[hn];
10573 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10574
10575 do
10576 {
978c4450 10577 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 10578 {
c31ab5a0
AM
10579 if (off < filedata->ngnuchains
10580 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 10581 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
10582 }
10583 else
10584 {
10585 if (si >= num_of_syms)
10586 num_of_syms = si + 1;
10587 }
10588 si++;
10589 }
978c4450
AM
10590 while (off < filedata->ngnuchains
10591 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
10592 }
10593
90837ea7 10594 if (num_of_syms == 0)
10ca4b04 10595 {
90837ea7 10596 no_gnu_hash:
9db70fc3
AM
10597 free (filedata->mipsxlat);
10598 filedata->mipsxlat = NULL;
10599 free (filedata->gnuchains);
10600 filedata->gnuchains = NULL;
10601 free (filedata->gnubuckets);
10602 filedata->gnubuckets = NULL;
978c4450
AM
10603 filedata->ngnubuckets = 0;
10604 filedata->ngnuchains = 0;
10ca4b04
L
10605 }
10606 }
10607
10608 return num_of_syms;
10609}
10610
b2d38a17
NC
10611/* Parse and display the contents of the dynamic section. */
10612
015dc7e1 10613static bool
dda8d76d 10614process_dynamic_section (Filedata * filedata)
9ea033b2 10615{
2cf0635d 10616 Elf_Internal_Dyn * entry;
9ea033b2 10617
978c4450 10618 if (filedata->dynamic_size == 0)
9ea033b2
NC
10619 {
10620 if (do_dynamic)
ca0e11aa
NC
10621 {
10622 if (filedata->is_separate)
10623 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
10624 filedata->file_name);
10625 else
10626 printf (_("\nThere is no dynamic section in this file.\n"));
10627 }
9ea033b2 10628
015dc7e1 10629 return true;
9ea033b2
NC
10630 }
10631
4de91c10
AM
10632 if (!get_dynamic_section (filedata))
10633 return false;
9ea033b2 10634
252b5132 10635 /* Find the appropriate symbol table. */
978c4450 10636 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 10637 {
2482f306
AM
10638 unsigned long num_of_syms;
10639
978c4450
AM
10640 for (entry = filedata->dynamic_section;
10641 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10642 ++entry)
10ca4b04 10643 if (entry->d_tag == DT_SYMTAB)
978c4450 10644 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 10645 else if (entry->d_tag == DT_SYMENT)
978c4450 10646 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 10647 else if (entry->d_tag == DT_HASH)
978c4450 10648 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 10649 else if (entry->d_tag == DT_GNU_HASH)
978c4450 10650 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
10651 else if ((filedata->file_header.e_machine == EM_MIPS
10652 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10653 && entry->d_tag == DT_MIPS_XHASH)
10654 {
978c4450
AM
10655 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10656 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 10657 }
252b5132 10658
2482f306
AM
10659 num_of_syms = get_num_dynamic_syms (filedata);
10660
10661 if (num_of_syms != 0
10662 && filedata->dynamic_symbols == NULL
10663 && filedata->dynamic_info[DT_SYMTAB]
978c4450 10664 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
10665 {
10666 Elf_Internal_Phdr *seg;
2482f306 10667 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 10668
2482f306
AM
10669 if (! get_program_headers (filedata))
10670 {
10671 error (_("Cannot interpret virtual addresses "
10672 "without program headers.\n"));
015dc7e1 10673 return false;
2482f306 10674 }
252b5132 10675
2482f306
AM
10676 for (seg = filedata->program_headers;
10677 seg < filedata->program_headers + filedata->file_header.e_phnum;
10678 ++seg)
10679 {
10680 if (seg->p_type != PT_LOAD)
10681 continue;
252b5132 10682
2482f306
AM
10683 if (seg->p_offset + seg->p_filesz > filedata->file_size)
10684 {
10685 /* See PR 21379 for a reproducer. */
10686 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 10687 return false;
2482f306 10688 }
252b5132 10689
2482f306
AM
10690 if (vma >= (seg->p_vaddr & -seg->p_align)
10691 && vma < seg->p_vaddr + seg->p_filesz)
10692 {
10693 /* Since we do not know how big the symbol table is,
10694 we default to reading in up to the end of PT_LOAD
10695 segment and processing that. This is overkill, I
10696 know, but it should work. */
10697 Elf_Internal_Shdr section;
10698 section.sh_offset = (vma - seg->p_vaddr
10699 + seg->p_offset);
10700 section.sh_size = (num_of_syms
10701 * filedata->dynamic_info[DT_SYMENT]);
10702 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
10703
10704 if (do_checks
10705 && filedata->dynamic_symtab_section != NULL
10706 && ((filedata->dynamic_symtab_section->sh_offset
10707 != section.sh_offset)
10708 || (filedata->dynamic_symtab_section->sh_size
10709 != section.sh_size)
10710 || (filedata->dynamic_symtab_section->sh_entsize
10711 != section.sh_entsize)))
10712 warn (_("\
10713the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
10714
2482f306
AM
10715 section.sh_name = filedata->string_table_length;
10716 filedata->dynamic_symbols
4de91c10 10717 = get_elf_symbols (filedata, &section,
2482f306
AM
10718 &filedata->num_dynamic_syms);
10719 if (filedata->dynamic_symbols == NULL
10720 || filedata->num_dynamic_syms != num_of_syms)
10721 {
10722 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 10723 return false;
2482f306
AM
10724 }
10725 break;
10726 }
10727 }
10728 }
10729 }
252b5132
RH
10730
10731 /* Similarly find a string table. */
978c4450
AM
10732 if (filedata->dynamic_strings == NULL)
10733 for (entry = filedata->dynamic_section;
10734 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
10735 ++entry)
10736 {
10737 if (entry->d_tag == DT_STRTAB)
978c4450 10738 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 10739
10ca4b04 10740 if (entry->d_tag == DT_STRSZ)
978c4450 10741 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10742
978c4450
AM
10743 if (filedata->dynamic_info[DT_STRTAB]
10744 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
10745 {
10746 unsigned long offset;
978c4450 10747 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
10748
10749 offset = offset_from_vma (filedata,
978c4450 10750 filedata->dynamic_info[DT_STRTAB],
10ca4b04 10751 str_tab_len);
8ac10c5b
L
10752 if (do_checks
10753 && filedata->dynamic_strtab_section
10754 && ((filedata->dynamic_strtab_section->sh_offset
10755 != (file_ptr) offset)
10756 || (filedata->dynamic_strtab_section->sh_size
10757 != str_tab_len)))
10758 warn (_("\
10759the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
10760
978c4450
AM
10761 filedata->dynamic_strings
10762 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
10763 _("dynamic string table"));
10764 if (filedata->dynamic_strings == NULL)
10ca4b04
L
10765 {
10766 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10767 break;
10768 }
e3d39609 10769
978c4450 10770 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
10771 break;
10772 }
10773 }
252b5132
RH
10774
10775 /* And find the syminfo section if available. */
978c4450 10776 if (filedata->dynamic_syminfo == NULL)
252b5132 10777 {
3e8bba36 10778 unsigned long syminsz = 0;
252b5132 10779
978c4450
AM
10780 for (entry = filedata->dynamic_section;
10781 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10782 ++entry)
252b5132
RH
10783 {
10784 if (entry->d_tag == DT_SYMINENT)
10785 {
10786 /* Note: these braces are necessary to avoid a syntax
10787 error from the SunOS4 C compiler. */
049b0c3a
NC
10788 /* PR binutils/17531: A corrupt file can trigger this test.
10789 So do not use an assert, instead generate an error message. */
10790 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10791 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10792 (int) entry->d_un.d_val);
252b5132
RH
10793 }
10794 else if (entry->d_tag == DT_SYMINSZ)
10795 syminsz = entry->d_un.d_val;
10796 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
10797 filedata->dynamic_syminfo_offset
10798 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
10799 }
10800
978c4450 10801 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 10802 {
2cf0635d
NC
10803 Elf_External_Syminfo * extsyminfo;
10804 Elf_External_Syminfo * extsym;
10805 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10806
10807 /* There is a syminfo section. Read the data. */
3f5e193b 10808 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
10809 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
10810 1, syminsz, _("symbol information"));
a6e9f9df 10811 if (!extsyminfo)
015dc7e1 10812 return false;
252b5132 10813
978c4450 10814 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
10815 {
10816 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 10817 free (filedata->dynamic_syminfo);
e3d39609 10818 }
978c4450
AM
10819 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
10820 if (filedata->dynamic_syminfo == NULL)
252b5132 10821 {
2482f306
AM
10822 error (_("Out of memory allocating %lu bytes "
10823 "for dynamic symbol info\n"),
8b73c356 10824 (unsigned long) syminsz);
015dc7e1 10825 return false;
252b5132
RH
10826 }
10827
2482f306
AM
10828 filedata->dynamic_syminfo_nent
10829 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 10830 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
10831 syminfo < (filedata->dynamic_syminfo
10832 + filedata->dynamic_syminfo_nent);
86dba8ee 10833 ++syminfo, ++extsym)
252b5132 10834 {
86dba8ee
AM
10835 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10836 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10837 }
10838
10839 free (extsyminfo);
10840 }
10841 }
10842
978c4450 10843 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa
NC
10844 {
10845 if (filedata->dynamic_nent == 1)
10846 {
10847 if (filedata->is_separate)
10848 printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains 1 entry:\n"),
10849 filedata->file_name,
10850 filedata->dynamic_addr);
10851 else
10852 printf (_("\nDynamic section at offset 0x%lx contains 1 entry:\n"),
10853 filedata->dynamic_addr);
10854 }
10855 else
10856 {
10857 if (filedata->is_separate)
10858 printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n"),
10859 filedata->file_name,
10860 filedata->dynamic_addr,
10861 (unsigned long) filedata->dynamic_nent);
10862 else
10863 printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
10864 filedata->dynamic_addr,
10865 (unsigned long) filedata->dynamic_nent);
10866 }
10867 }
252b5132
RH
10868 if (do_dynamic)
10869 printf (_(" Tag Type Name/Value\n"));
10870
978c4450
AM
10871 for (entry = filedata->dynamic_section;
10872 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10873 entry++)
252b5132
RH
10874 {
10875 if (do_dynamic)
f7a99963 10876 {
2cf0635d 10877 const char * dtype;
e699b9ff 10878
f7a99963
NC
10879 putchar (' ');
10880 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10881 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10882 printf (" (%s)%*s", dtype,
32ec8896 10883 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10884 }
252b5132
RH
10885
10886 switch (entry->d_tag)
10887 {
d1133906
NC
10888 case DT_FLAGS:
10889 if (do_dynamic)
e9e44622 10890 print_dynamic_flags (entry->d_un.d_val);
d1133906 10891 break;
76da6bbe 10892
252b5132
RH
10893 case DT_AUXILIARY:
10894 case DT_FILTER:
019148e4
L
10895 case DT_CONFIG:
10896 case DT_DEPAUDIT:
10897 case DT_AUDIT:
252b5132
RH
10898 if (do_dynamic)
10899 {
019148e4 10900 switch (entry->d_tag)
b34976b6 10901 {
019148e4
L
10902 case DT_AUXILIARY:
10903 printf (_("Auxiliary library"));
10904 break;
10905
10906 case DT_FILTER:
10907 printf (_("Filter library"));
10908 break;
10909
b34976b6 10910 case DT_CONFIG:
019148e4
L
10911 printf (_("Configuration file"));
10912 break;
10913
10914 case DT_DEPAUDIT:
10915 printf (_("Dependency audit library"));
10916 break;
10917
10918 case DT_AUDIT:
10919 printf (_("Audit library"));
10920 break;
10921 }
252b5132 10922
978c4450
AM
10923 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10924 printf (": [%s]\n",
10925 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 10926 else
f7a99963
NC
10927 {
10928 printf (": ");
10929 print_vma (entry->d_un.d_val, PREFIX_HEX);
10930 putchar ('\n');
10931 }
252b5132
RH
10932 }
10933 break;
10934
dcefbbbd 10935 case DT_FEATURE:
252b5132
RH
10936 if (do_dynamic)
10937 {
10938 printf (_("Flags:"));
86f55779 10939
252b5132
RH
10940 if (entry->d_un.d_val == 0)
10941 printf (_(" None\n"));
10942 else
10943 {
10944 unsigned long int val = entry->d_un.d_val;
86f55779 10945
252b5132
RH
10946 if (val & DTF_1_PARINIT)
10947 {
10948 printf (" PARINIT");
10949 val ^= DTF_1_PARINIT;
10950 }
dcefbbbd
L
10951 if (val & DTF_1_CONFEXP)
10952 {
10953 printf (" CONFEXP");
10954 val ^= DTF_1_CONFEXP;
10955 }
252b5132
RH
10956 if (val != 0)
10957 printf (" %lx", val);
10958 puts ("");
10959 }
10960 }
10961 break;
10962
10963 case DT_POSFLAG_1:
10964 if (do_dynamic)
10965 {
10966 printf (_("Flags:"));
86f55779 10967
252b5132
RH
10968 if (entry->d_un.d_val == 0)
10969 printf (_(" None\n"));
10970 else
10971 {
10972 unsigned long int val = entry->d_un.d_val;
86f55779 10973
252b5132
RH
10974 if (val & DF_P1_LAZYLOAD)
10975 {
10976 printf (" LAZYLOAD");
10977 val ^= DF_P1_LAZYLOAD;
10978 }
10979 if (val & DF_P1_GROUPPERM)
10980 {
10981 printf (" GROUPPERM");
10982 val ^= DF_P1_GROUPPERM;
10983 }
10984 if (val != 0)
10985 printf (" %lx", val);
10986 puts ("");
10987 }
10988 }
10989 break;
10990
10991 case DT_FLAGS_1:
10992 if (do_dynamic)
10993 {
10994 printf (_("Flags:"));
10995 if (entry->d_un.d_val == 0)
10996 printf (_(" None\n"));
10997 else
10998 {
10999 unsigned long int val = entry->d_un.d_val;
86f55779 11000
252b5132
RH
11001 if (val & DF_1_NOW)
11002 {
11003 printf (" NOW");
11004 val ^= DF_1_NOW;
11005 }
11006 if (val & DF_1_GLOBAL)
11007 {
11008 printf (" GLOBAL");
11009 val ^= DF_1_GLOBAL;
11010 }
11011 if (val & DF_1_GROUP)
11012 {
11013 printf (" GROUP");
11014 val ^= DF_1_GROUP;
11015 }
11016 if (val & DF_1_NODELETE)
11017 {
11018 printf (" NODELETE");
11019 val ^= DF_1_NODELETE;
11020 }
11021 if (val & DF_1_LOADFLTR)
11022 {
11023 printf (" LOADFLTR");
11024 val ^= DF_1_LOADFLTR;
11025 }
11026 if (val & DF_1_INITFIRST)
11027 {
11028 printf (" INITFIRST");
11029 val ^= DF_1_INITFIRST;
11030 }
11031 if (val & DF_1_NOOPEN)
11032 {
11033 printf (" NOOPEN");
11034 val ^= DF_1_NOOPEN;
11035 }
11036 if (val & DF_1_ORIGIN)
11037 {
11038 printf (" ORIGIN");
11039 val ^= DF_1_ORIGIN;
11040 }
11041 if (val & DF_1_DIRECT)
11042 {
11043 printf (" DIRECT");
11044 val ^= DF_1_DIRECT;
11045 }
11046 if (val & DF_1_TRANS)
11047 {
11048 printf (" TRANS");
11049 val ^= DF_1_TRANS;
11050 }
11051 if (val & DF_1_INTERPOSE)
11052 {
11053 printf (" INTERPOSE");
11054 val ^= DF_1_INTERPOSE;
11055 }
f7db6139 11056 if (val & DF_1_NODEFLIB)
dcefbbbd 11057 {
f7db6139
L
11058 printf (" NODEFLIB");
11059 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11060 }
11061 if (val & DF_1_NODUMP)
11062 {
11063 printf (" NODUMP");
11064 val ^= DF_1_NODUMP;
11065 }
34b60028 11066 if (val & DF_1_CONFALT)
dcefbbbd 11067 {
34b60028
L
11068 printf (" CONFALT");
11069 val ^= DF_1_CONFALT;
11070 }
11071 if (val & DF_1_ENDFILTEE)
11072 {
11073 printf (" ENDFILTEE");
11074 val ^= DF_1_ENDFILTEE;
11075 }
11076 if (val & DF_1_DISPRELDNE)
11077 {
11078 printf (" DISPRELDNE");
11079 val ^= DF_1_DISPRELDNE;
11080 }
11081 if (val & DF_1_DISPRELPND)
11082 {
11083 printf (" DISPRELPND");
11084 val ^= DF_1_DISPRELPND;
11085 }
11086 if (val & DF_1_NODIRECT)
11087 {
11088 printf (" NODIRECT");
11089 val ^= DF_1_NODIRECT;
11090 }
11091 if (val & DF_1_IGNMULDEF)
11092 {
11093 printf (" IGNMULDEF");
11094 val ^= DF_1_IGNMULDEF;
11095 }
11096 if (val & DF_1_NOKSYMS)
11097 {
11098 printf (" NOKSYMS");
11099 val ^= DF_1_NOKSYMS;
11100 }
11101 if (val & DF_1_NOHDR)
11102 {
11103 printf (" NOHDR");
11104 val ^= DF_1_NOHDR;
11105 }
11106 if (val & DF_1_EDITED)
11107 {
11108 printf (" EDITED");
11109 val ^= DF_1_EDITED;
11110 }
11111 if (val & DF_1_NORELOC)
11112 {
11113 printf (" NORELOC");
11114 val ^= DF_1_NORELOC;
11115 }
11116 if (val & DF_1_SYMINTPOSE)
11117 {
11118 printf (" SYMINTPOSE");
11119 val ^= DF_1_SYMINTPOSE;
11120 }
11121 if (val & DF_1_GLOBAUDIT)
11122 {
11123 printf (" GLOBAUDIT");
11124 val ^= DF_1_GLOBAUDIT;
11125 }
11126 if (val & DF_1_SINGLETON)
11127 {
11128 printf (" SINGLETON");
11129 val ^= DF_1_SINGLETON;
dcefbbbd 11130 }
5c383f02
RO
11131 if (val & DF_1_STUB)
11132 {
11133 printf (" STUB");
11134 val ^= DF_1_STUB;
11135 }
11136 if (val & DF_1_PIE)
11137 {
11138 printf (" PIE");
11139 val ^= DF_1_PIE;
11140 }
b1202ffa
L
11141 if (val & DF_1_KMOD)
11142 {
11143 printf (" KMOD");
11144 val ^= DF_1_KMOD;
11145 }
11146 if (val & DF_1_WEAKFILTER)
11147 {
11148 printf (" WEAKFILTER");
11149 val ^= DF_1_WEAKFILTER;
11150 }
11151 if (val & DF_1_NOCOMMON)
11152 {
11153 printf (" NOCOMMON");
11154 val ^= DF_1_NOCOMMON;
11155 }
252b5132
RH
11156 if (val != 0)
11157 printf (" %lx", val);
11158 puts ("");
11159 }
11160 }
11161 break;
11162
11163 case DT_PLTREL:
978c4450 11164 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11165 if (do_dynamic)
dda8d76d 11166 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11167 break;
11168
11169 case DT_NULL :
11170 case DT_NEEDED :
11171 case DT_PLTGOT :
11172 case DT_HASH :
11173 case DT_STRTAB :
11174 case DT_SYMTAB :
11175 case DT_RELA :
11176 case DT_INIT :
11177 case DT_FINI :
11178 case DT_SONAME :
11179 case DT_RPATH :
11180 case DT_SYMBOLIC:
11181 case DT_REL :
11182 case DT_DEBUG :
11183 case DT_TEXTREL :
11184 case DT_JMPREL :
019148e4 11185 case DT_RUNPATH :
978c4450 11186 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11187
11188 if (do_dynamic)
11189 {
2cf0635d 11190 char * name;
252b5132 11191
978c4450
AM
11192 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
11193 name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11194 else
d79b3d50 11195 name = NULL;
252b5132
RH
11196
11197 if (name)
11198 {
11199 switch (entry->d_tag)
11200 {
11201 case DT_NEEDED:
11202 printf (_("Shared library: [%s]"), name);
11203
13acb58d
AM
11204 if (filedata->program_interpreter
11205 && streq (name, filedata->program_interpreter))
f7a99963 11206 printf (_(" program interpreter"));
252b5132
RH
11207 break;
11208
11209 case DT_SONAME:
f7a99963 11210 printf (_("Library soname: [%s]"), name);
252b5132
RH
11211 break;
11212
11213 case DT_RPATH:
f7a99963 11214 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11215 break;
11216
019148e4
L
11217 case DT_RUNPATH:
11218 printf (_("Library runpath: [%s]"), name);
11219 break;
11220
252b5132 11221 default:
f7a99963
NC
11222 print_vma (entry->d_un.d_val, PREFIX_HEX);
11223 break;
252b5132
RH
11224 }
11225 }
11226 else
f7a99963
NC
11227 print_vma (entry->d_un.d_val, PREFIX_HEX);
11228
11229 putchar ('\n');
252b5132
RH
11230 }
11231 break;
11232
11233 case DT_PLTRELSZ:
11234 case DT_RELASZ :
11235 case DT_STRSZ :
11236 case DT_RELSZ :
11237 case DT_RELAENT :
11238 case DT_SYMENT :
11239 case DT_RELENT :
978c4450 11240 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11241 /* Fall through. */
252b5132
RH
11242 case DT_PLTPADSZ:
11243 case DT_MOVEENT :
11244 case DT_MOVESZ :
11245 case DT_INIT_ARRAYSZ:
11246 case DT_FINI_ARRAYSZ:
047b2264
JJ
11247 case DT_GNU_CONFLICTSZ:
11248 case DT_GNU_LIBLISTSZ:
252b5132 11249 if (do_dynamic)
f7a99963
NC
11250 {
11251 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11252 printf (_(" (bytes)\n"));
f7a99963 11253 }
252b5132
RH
11254 break;
11255
11256 case DT_VERDEFNUM:
11257 case DT_VERNEEDNUM:
11258 case DT_RELACOUNT:
11259 case DT_RELCOUNT:
11260 if (do_dynamic)
f7a99963
NC
11261 {
11262 print_vma (entry->d_un.d_val, UNSIGNED);
11263 putchar ('\n');
11264 }
252b5132
RH
11265 break;
11266
11267 case DT_SYMINSZ:
11268 case DT_SYMINENT:
11269 case DT_SYMINFO:
11270 case DT_USED:
11271 case DT_INIT_ARRAY:
11272 case DT_FINI_ARRAY:
11273 if (do_dynamic)
11274 {
d79b3d50 11275 if (entry->d_tag == DT_USED
978c4450 11276 && VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
252b5132 11277 {
978c4450 11278 char * name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11279
b34976b6 11280 if (*name)
252b5132
RH
11281 {
11282 printf (_("Not needed object: [%s]\n"), name);
11283 break;
11284 }
11285 }
103f02d3 11286
f7a99963
NC
11287 print_vma (entry->d_un.d_val, PREFIX_HEX);
11288 putchar ('\n');
252b5132
RH
11289 }
11290 break;
11291
11292 case DT_BIND_NOW:
11293 /* The value of this entry is ignored. */
35b1837e
AM
11294 if (do_dynamic)
11295 putchar ('\n');
252b5132 11296 break;
103f02d3 11297
047b2264
JJ
11298 case DT_GNU_PRELINKED:
11299 if (do_dynamic)
11300 {
2cf0635d 11301 struct tm * tmp;
91d6fa6a 11302 time_t atime = entry->d_un.d_val;
047b2264 11303
91d6fa6a 11304 tmp = gmtime (&atime);
071436c6
NC
11305 /* PR 17533 file: 041-1244816-0.004. */
11306 if (tmp == NULL)
5a2cbcf4
L
11307 printf (_("<corrupt time val: %lx"),
11308 (unsigned long) atime);
071436c6
NC
11309 else
11310 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11311 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11312 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11313
11314 }
11315 break;
11316
fdc90cb4 11317 case DT_GNU_HASH:
978c4450 11318 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11319 if (do_dynamic)
11320 {
11321 print_vma (entry->d_un.d_val, PREFIX_HEX);
11322 putchar ('\n');
11323 }
11324 break;
11325
a5da3dee
VDM
11326 case DT_GNU_FLAGS_1:
11327 if (do_dynamic)
11328 {
11329 printf (_("Flags:"));
11330 if (entry->d_un.d_val == 0)
11331 printf (_(" None\n"));
11332 else
11333 {
11334 unsigned long int val = entry->d_un.d_val;
11335
11336 if (val & DF_GNU_1_UNIQUE)
11337 {
11338 printf (" UNIQUE");
11339 val ^= DF_GNU_1_UNIQUE;
11340 }
11341 if (val != 0)
11342 printf (" %lx", val);
11343 puts ("");
11344 }
11345 }
11346 break;
11347
252b5132
RH
11348 default:
11349 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11350 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11351 = entry->d_un.d_val;
252b5132
RH
11352
11353 if (do_dynamic)
11354 {
dda8d76d 11355 switch (filedata->file_header.e_machine)
252b5132 11356 {
37c18eed
SD
11357 case EM_AARCH64:
11358 dynamic_section_aarch64_val (entry);
11359 break;
252b5132 11360 case EM_MIPS:
4fe85591 11361 case EM_MIPS_RS3_LE:
978c4450 11362 dynamic_section_mips_val (filedata, entry);
252b5132 11363 break;
103f02d3 11364 case EM_PARISC:
b2d38a17 11365 dynamic_section_parisc_val (entry);
103f02d3 11366 break;
ecc51f48 11367 case EM_IA_64:
b2d38a17 11368 dynamic_section_ia64_val (entry);
ecc51f48 11369 break;
252b5132 11370 default:
f7a99963
NC
11371 print_vma (entry->d_un.d_val, PREFIX_HEX);
11372 putchar ('\n');
252b5132
RH
11373 }
11374 }
11375 break;
11376 }
11377 }
11378
015dc7e1 11379 return true;
252b5132
RH
11380}
11381
11382static char *
d3ba0551 11383get_ver_flags (unsigned int flags)
252b5132 11384{
6d4f21f6 11385 static char buff[128];
252b5132
RH
11386
11387 buff[0] = 0;
11388
11389 if (flags == 0)
11390 return _("none");
11391
11392 if (flags & VER_FLG_BASE)
7bb1ad17 11393 strcat (buff, "BASE");
252b5132
RH
11394
11395 if (flags & VER_FLG_WEAK)
11396 {
11397 if (flags & VER_FLG_BASE)
7bb1ad17 11398 strcat (buff, " | ");
252b5132 11399
7bb1ad17 11400 strcat (buff, "WEAK");
252b5132
RH
11401 }
11402
44ec90b9
RO
11403 if (flags & VER_FLG_INFO)
11404 {
11405 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11406 strcat (buff, " | ");
44ec90b9 11407
7bb1ad17 11408 strcat (buff, "INFO");
44ec90b9
RO
11409 }
11410
11411 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11412 {
11413 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11414 strcat (buff, " | ");
11415
11416 strcat (buff, _("<unknown>"));
11417 }
252b5132
RH
11418
11419 return buff;
11420}
11421
11422/* Display the contents of the version sections. */
98fb390a 11423
015dc7e1 11424static bool
dda8d76d 11425process_version_sections (Filedata * filedata)
252b5132 11426{
2cf0635d 11427 Elf_Internal_Shdr * section;
b34976b6 11428 unsigned i;
015dc7e1 11429 bool found = false;
252b5132
RH
11430
11431 if (! do_version)
015dc7e1 11432 return true;
252b5132 11433
dda8d76d
NC
11434 for (i = 0, section = filedata->section_headers;
11435 i < filedata->file_header.e_shnum;
b34976b6 11436 i++, section++)
252b5132
RH
11437 {
11438 switch (section->sh_type)
11439 {
11440 case SHT_GNU_verdef:
11441 {
2cf0635d 11442 Elf_External_Verdef * edefs;
452bf675
AM
11443 unsigned long idx;
11444 unsigned long cnt;
2cf0635d 11445 char * endbuf;
252b5132 11446
015dc7e1 11447 found = true;
252b5132 11448
ca0e11aa
NC
11449 if (filedata->is_separate)
11450 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
11451 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
11452 section->sh_info),
11453 filedata->file_name,
11454 printable_section_name (filedata, section),
11455 section->sh_info);
11456 else
11457 printf (ngettext ("\nVersion definition section '%s' "
11458 "contains %u entry:\n",
11459 "\nVersion definition section '%s' "
11460 "contains %u entries:\n",
11461 section->sh_info),
11462 printable_section_name (filedata, section),
11463 section->sh_info);
047c3dbf 11464
ae9ac79e 11465 printf (_(" Addr: 0x"));
252b5132 11466 printf_vma (section->sh_addr);
233f82cf 11467 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11468 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11469 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11470
3f5e193b 11471 edefs = (Elf_External_Verdef *)
dda8d76d 11472 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11473 _("version definition section"));
a6e9f9df
AM
11474 if (!edefs)
11475 break;
59245841 11476 endbuf = (char *) edefs + section->sh_size;
252b5132 11477
1445030f 11478 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11479 {
2cf0635d
NC
11480 char * vstart;
11481 Elf_External_Verdef * edef;
b34976b6 11482 Elf_Internal_Verdef ent;
2cf0635d 11483 Elf_External_Verdaux * eaux;
b34976b6 11484 Elf_Internal_Verdaux aux;
452bf675 11485 unsigned long isum;
b34976b6 11486 int j;
103f02d3 11487
252b5132 11488 vstart = ((char *) edefs) + idx;
54806181
AM
11489 if (vstart + sizeof (*edef) > endbuf)
11490 break;
252b5132
RH
11491
11492 edef = (Elf_External_Verdef *) vstart;
11493
11494 ent.vd_version = BYTE_GET (edef->vd_version);
11495 ent.vd_flags = BYTE_GET (edef->vd_flags);
11496 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11497 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11498 ent.vd_hash = BYTE_GET (edef->vd_hash);
11499 ent.vd_aux = BYTE_GET (edef->vd_aux);
11500 ent.vd_next = BYTE_GET (edef->vd_next);
11501
452bf675 11502 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11503 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11504
11505 printf (_(" Index: %d Cnt: %d "),
11506 ent.vd_ndx, ent.vd_cnt);
11507
452bf675 11508 /* Check for overflow. */
1445030f 11509 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11510 break;
11511
252b5132
RH
11512 vstart += ent.vd_aux;
11513
1445030f
AM
11514 if (vstart + sizeof (*eaux) > endbuf)
11515 break;
252b5132
RH
11516 eaux = (Elf_External_Verdaux *) vstart;
11517
11518 aux.vda_name = BYTE_GET (eaux->vda_name);
11519 aux.vda_next = BYTE_GET (eaux->vda_next);
11520
978c4450
AM
11521 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
11522 printf (_("Name: %s\n"),
11523 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132
RH
11524 else
11525 printf (_("Name index: %ld\n"), aux.vda_name);
11526
11527 isum = idx + ent.vd_aux;
11528
b34976b6 11529 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11530 {
1445030f
AM
11531 if (aux.vda_next < sizeof (*eaux)
11532 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11533 {
11534 warn (_("Invalid vda_next field of %lx\n"),
11535 aux.vda_next);
11536 j = ent.vd_cnt;
11537 break;
11538 }
dd24e3da 11539 /* Check for overflow. */
7e26601c 11540 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11541 break;
11542
252b5132
RH
11543 isum += aux.vda_next;
11544 vstart += aux.vda_next;
11545
54806181
AM
11546 if (vstart + sizeof (*eaux) > endbuf)
11547 break;
1445030f 11548 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11549
11550 aux.vda_name = BYTE_GET (eaux->vda_name);
11551 aux.vda_next = BYTE_GET (eaux->vda_next);
11552
978c4450 11553 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
452bf675 11554 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450
AM
11555 isum, j,
11556 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132 11557 else
452bf675 11558 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11559 isum, j, aux.vda_name);
11560 }
dd24e3da 11561
54806181
AM
11562 if (j < ent.vd_cnt)
11563 printf (_(" Version def aux past end of section\n"));
252b5132 11564
c9f02c3e
MR
11565 /* PR 17531:
11566 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11567 if (ent.vd_next < sizeof (*edef)
11568 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11569 {
11570 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11571 cnt = section->sh_info;
11572 break;
11573 }
452bf675 11574 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11575 break;
11576
252b5132
RH
11577 idx += ent.vd_next;
11578 }
dd24e3da 11579
54806181
AM
11580 if (cnt < section->sh_info)
11581 printf (_(" Version definition past end of section\n"));
252b5132
RH
11582
11583 free (edefs);
11584 }
11585 break;
103f02d3 11586
252b5132
RH
11587 case SHT_GNU_verneed:
11588 {
2cf0635d 11589 Elf_External_Verneed * eneed;
452bf675
AM
11590 unsigned long idx;
11591 unsigned long cnt;
2cf0635d 11592 char * endbuf;
252b5132 11593
015dc7e1 11594 found = true;
252b5132 11595
ca0e11aa
NC
11596 if (filedata->is_separate)
11597 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
11598 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
11599 section->sh_info),
11600 filedata->file_name,
11601 printable_section_name (filedata, section),
11602 section->sh_info);
11603 else
11604 printf (ngettext ("\nVersion needs section '%s' "
11605 "contains %u entry:\n",
11606 "\nVersion needs section '%s' "
11607 "contains %u entries:\n",
11608 section->sh_info),
11609 printable_section_name (filedata, section),
11610 section->sh_info);
047c3dbf 11611
252b5132
RH
11612 printf (_(" Addr: 0x"));
11613 printf_vma (section->sh_addr);
72de5009 11614 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11615 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11616 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11617
dda8d76d 11618 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11619 section->sh_offset, 1,
11620 section->sh_size,
9cf03b7e 11621 _("Version Needs section"));
a6e9f9df
AM
11622 if (!eneed)
11623 break;
59245841 11624 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11625
11626 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11627 {
2cf0635d 11628 Elf_External_Verneed * entry;
b34976b6 11629 Elf_Internal_Verneed ent;
452bf675 11630 unsigned long isum;
b34976b6 11631 int j;
2cf0635d 11632 char * vstart;
252b5132
RH
11633
11634 vstart = ((char *) eneed) + idx;
54806181
AM
11635 if (vstart + sizeof (*entry) > endbuf)
11636 break;
252b5132
RH
11637
11638 entry = (Elf_External_Verneed *) vstart;
11639
11640 ent.vn_version = BYTE_GET (entry->vn_version);
11641 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11642 ent.vn_file = BYTE_GET (entry->vn_file);
11643 ent.vn_aux = BYTE_GET (entry->vn_aux);
11644 ent.vn_next = BYTE_GET (entry->vn_next);
11645
452bf675 11646 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11647
978c4450
AM
11648 if (VALID_DYNAMIC_NAME (filedata, ent.vn_file))
11649 printf (_(" File: %s"),
11650 GET_DYNAMIC_NAME (filedata, ent.vn_file));
252b5132
RH
11651 else
11652 printf (_(" File: %lx"), ent.vn_file);
11653
11654 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11655
dd24e3da 11656 /* Check for overflow. */
7e26601c 11657 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11658 break;
252b5132
RH
11659 vstart += ent.vn_aux;
11660
11661 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11662 {
2cf0635d 11663 Elf_External_Vernaux * eaux;
b34976b6 11664 Elf_Internal_Vernaux aux;
252b5132 11665
54806181
AM
11666 if (vstart + sizeof (*eaux) > endbuf)
11667 break;
252b5132
RH
11668 eaux = (Elf_External_Vernaux *) vstart;
11669
11670 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11671 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11672 aux.vna_other = BYTE_GET (eaux->vna_other);
11673 aux.vna_name = BYTE_GET (eaux->vna_name);
11674 aux.vna_next = BYTE_GET (eaux->vna_next);
11675
978c4450 11676 if (VALID_DYNAMIC_NAME (filedata, aux.vna_name))
452bf675 11677 printf (_(" %#06lx: Name: %s"),
978c4450 11678 isum, GET_DYNAMIC_NAME (filedata, aux.vna_name));
252b5132 11679 else
452bf675 11680 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11681 isum, aux.vna_name);
11682
11683 printf (_(" Flags: %s Version: %d\n"),
11684 get_ver_flags (aux.vna_flags), aux.vna_other);
11685
1445030f
AM
11686 if (aux.vna_next < sizeof (*eaux)
11687 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11688 {
11689 warn (_("Invalid vna_next field of %lx\n"),
11690 aux.vna_next);
11691 j = ent.vn_cnt;
11692 break;
11693 }
1445030f
AM
11694 /* Check for overflow. */
11695 if (aux.vna_next > (size_t) (endbuf - vstart))
11696 break;
252b5132
RH
11697 isum += aux.vna_next;
11698 vstart += aux.vna_next;
11699 }
9cf03b7e 11700
54806181 11701 if (j < ent.vn_cnt)
f9a6a8f0 11702 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 11703
1445030f
AM
11704 if (ent.vn_next < sizeof (*entry)
11705 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11706 {
452bf675 11707 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11708 cnt = section->sh_info;
11709 break;
11710 }
1445030f
AM
11711 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11712 break;
252b5132
RH
11713 idx += ent.vn_next;
11714 }
9cf03b7e 11715
54806181 11716 if (cnt < section->sh_info)
9cf03b7e 11717 warn (_("Missing Version Needs information\n"));
103f02d3 11718
252b5132
RH
11719 free (eneed);
11720 }
11721 break;
11722
11723 case SHT_GNU_versym:
11724 {
2cf0635d 11725 Elf_Internal_Shdr * link_section;
8b73c356
NC
11726 size_t total;
11727 unsigned int cnt;
2cf0635d
NC
11728 unsigned char * edata;
11729 unsigned short * data;
11730 char * strtab;
11731 Elf_Internal_Sym * symbols;
11732 Elf_Internal_Shdr * string_sec;
ba5cdace 11733 unsigned long num_syms;
d3ba0551 11734 long off;
252b5132 11735
dda8d76d 11736 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11737 break;
11738
dda8d76d 11739 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11740 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11741
dda8d76d 11742 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11743 break;
11744
015dc7e1 11745 found = true;
252b5132 11746
4de91c10 11747 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
11748 if (symbols == NULL)
11749 break;
252b5132 11750
dda8d76d 11751 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11752
dda8d76d 11753 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11754 string_sec->sh_size,
11755 _("version string table"));
a6e9f9df 11756 if (!strtab)
0429c154
MS
11757 {
11758 free (symbols);
11759 break;
11760 }
252b5132 11761
ca0e11aa
NC
11762 if (filedata->is_separate)
11763 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
11764 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
11765 total),
11766 filedata->file_name,
11767 printable_section_name (filedata, section),
11768 (unsigned long) total);
11769 else
11770 printf (ngettext ("\nVersion symbols section '%s' "
11771 "contains %lu entry:\n",
11772 "\nVersion symbols section '%s' "
11773 "contains %lu entries:\n",
11774 total),
11775 printable_section_name (filedata, section),
11776 (unsigned long) total);
252b5132 11777
ae9ac79e 11778 printf (_(" Addr: 0x"));
252b5132 11779 printf_vma (section->sh_addr);
72de5009 11780 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11781 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11782 printable_section_name (filedata, link_section));
252b5132 11783
dda8d76d 11784 off = offset_from_vma (filedata,
978c4450 11785 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11786 total * sizeof (short));
95099889
AM
11787 edata = (unsigned char *) get_data (NULL, filedata, off,
11788 sizeof (short), total,
11789 _("version symbol data"));
a6e9f9df
AM
11790 if (!edata)
11791 {
11792 free (strtab);
0429c154 11793 free (symbols);
a6e9f9df
AM
11794 break;
11795 }
252b5132 11796
3f5e193b 11797 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11798
11799 for (cnt = total; cnt --;)
b34976b6
AM
11800 data[cnt] = byte_get (edata + cnt * sizeof (short),
11801 sizeof (short));
252b5132
RH
11802
11803 free (edata);
11804
11805 for (cnt = 0; cnt < total; cnt += 4)
11806 {
11807 int j, nn;
ab273396
AM
11808 char *name;
11809 char *invalid = _("*invalid*");
252b5132
RH
11810
11811 printf (" %03x:", cnt);
11812
11813 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11814 switch (data[cnt + j])
252b5132
RH
11815 {
11816 case 0:
11817 fputs (_(" 0 (*local*) "), stdout);
11818 break;
11819
11820 case 1:
11821 fputs (_(" 1 (*global*) "), stdout);
11822 break;
11823
11824 default:
c244d050
NC
11825 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11826 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11827
dd24e3da 11828 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11829 array, break to avoid an out-of-bounds read. */
11830 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11831 {
11832 warn (_("invalid index into symbol array\n"));
11833 break;
11834 }
11835
ab273396 11836 name = NULL;
978c4450 11837 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11838 {
b34976b6
AM
11839 Elf_Internal_Verneed ivn;
11840 unsigned long offset;
252b5132 11841
d93f0186 11842 offset = offset_from_vma
978c4450
AM
11843 (filedata,
11844 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11845 sizeof (Elf_External_Verneed));
252b5132 11846
b34976b6 11847 do
252b5132 11848 {
b34976b6
AM
11849 Elf_Internal_Vernaux ivna;
11850 Elf_External_Verneed evn;
11851 Elf_External_Vernaux evna;
11852 unsigned long a_off;
252b5132 11853
dda8d76d 11854 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11855 _("version need")) == NULL)
11856 break;
0b4362b0 11857
252b5132
RH
11858 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11859 ivn.vn_next = BYTE_GET (evn.vn_next);
11860
11861 a_off = offset + ivn.vn_aux;
11862
11863 do
11864 {
dda8d76d 11865 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11866 1, _("version need aux (2)")) == NULL)
11867 {
11868 ivna.vna_next = 0;
11869 ivna.vna_other = 0;
11870 }
11871 else
11872 {
11873 ivna.vna_next = BYTE_GET (evna.vna_next);
11874 ivna.vna_other = BYTE_GET (evna.vna_other);
11875 }
252b5132
RH
11876
11877 a_off += ivna.vna_next;
11878 }
b34976b6 11879 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11880 && ivna.vna_next != 0);
11881
b34976b6 11882 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11883 {
11884 ivna.vna_name = BYTE_GET (evna.vna_name);
11885
54806181 11886 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11887 name = invalid;
54806181
AM
11888 else
11889 name = strtab + ivna.vna_name;
252b5132
RH
11890 break;
11891 }
11892
11893 offset += ivn.vn_next;
11894 }
11895 while (ivn.vn_next);
11896 }
00d93f34 11897
ab273396 11898 if (data[cnt + j] != 0x8001
978c4450 11899 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 11900 {
b34976b6
AM
11901 Elf_Internal_Verdef ivd;
11902 Elf_External_Verdef evd;
11903 unsigned long offset;
252b5132 11904
d93f0186 11905 offset = offset_from_vma
978c4450
AM
11906 (filedata,
11907 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 11908 sizeof evd);
252b5132
RH
11909
11910 do
11911 {
dda8d76d 11912 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
11913 _("version def")) == NULL)
11914 {
11915 ivd.vd_next = 0;
948f632f 11916 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
11917 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
11918 break;
59245841
NC
11919 }
11920 else
11921 {
11922 ivd.vd_next = BYTE_GET (evd.vd_next);
11923 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11924 }
252b5132
RH
11925
11926 offset += ivd.vd_next;
11927 }
c244d050 11928 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
11929 && ivd.vd_next != 0);
11930
c244d050 11931 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 11932 {
b34976b6
AM
11933 Elf_External_Verdaux evda;
11934 Elf_Internal_Verdaux ivda;
252b5132
RH
11935
11936 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11937
dda8d76d 11938 if (get_data (&evda, filedata,
59245841
NC
11939 offset - ivd.vd_next + ivd.vd_aux,
11940 sizeof (evda), 1,
11941 _("version def aux")) == NULL)
11942 break;
252b5132
RH
11943
11944 ivda.vda_name = BYTE_GET (evda.vda_name);
11945
54806181 11946 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
11947 name = invalid;
11948 else if (name != NULL && name != invalid)
11949 name = _("*both*");
54806181
AM
11950 else
11951 name = strtab + ivda.vda_name;
252b5132
RH
11952 }
11953 }
ab273396
AM
11954 if (name != NULL)
11955 nn += printf ("(%s%-*s",
11956 name,
11957 12 - (int) strlen (name),
11958 ")");
252b5132
RH
11959
11960 if (nn < 18)
11961 printf ("%*c", 18 - nn, ' ');
11962 }
11963
11964 putchar ('\n');
11965 }
11966
11967 free (data);
11968 free (strtab);
11969 free (symbols);
11970 }
11971 break;
103f02d3 11972
252b5132
RH
11973 default:
11974 break;
11975 }
11976 }
11977
11978 if (! found)
ca0e11aa
NC
11979 {
11980 if (filedata->is_separate)
11981 printf (_("\nNo version information found in linked file '%s'.\n"),
11982 filedata->file_name);
11983 else
11984 printf (_("\nNo version information found in this file.\n"));
11985 }
252b5132 11986
015dc7e1 11987 return true;
252b5132
RH
11988}
11989
d1133906 11990static const char *
dda8d76d 11991get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 11992{
89246a0e 11993 static char buff[64];
252b5132
RH
11994
11995 switch (binding)
11996 {
b34976b6
AM
11997 case STB_LOCAL: return "LOCAL";
11998 case STB_GLOBAL: return "GLOBAL";
11999 case STB_WEAK: return "WEAK";
252b5132
RH
12000 default:
12001 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12002 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12003 binding);
252b5132 12004 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12005 {
12006 if (binding == STB_GNU_UNIQUE
df3a023b 12007 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12008 return "UNIQUE";
12009 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12010 }
252b5132 12011 else
e9e44622 12012 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12013 return buff;
12014 }
12015}
12016
d1133906 12017static const char *
dda8d76d 12018get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12019{
89246a0e 12020 static char buff[64];
252b5132
RH
12021
12022 switch (type)
12023 {
b34976b6
AM
12024 case STT_NOTYPE: return "NOTYPE";
12025 case STT_OBJECT: return "OBJECT";
12026 case STT_FUNC: return "FUNC";
12027 case STT_SECTION: return "SECTION";
12028 case STT_FILE: return "FILE";
12029 case STT_COMMON: return "COMMON";
12030 case STT_TLS: return "TLS";
15ab5209
DB
12031 case STT_RELC: return "RELC";
12032 case STT_SRELC: return "SRELC";
252b5132
RH
12033 default:
12034 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12035 {
dda8d76d 12036 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12037 return "THUMB_FUNC";
103f02d3 12038
dda8d76d 12039 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12040 return "REGISTER";
12041
dda8d76d 12042 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12043 return "PARISC_MILLI";
12044
e9e44622 12045 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12046 }
252b5132 12047 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12048 {
dda8d76d 12049 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12050 {
12051 if (type == STT_HP_OPAQUE)
12052 return "HP_OPAQUE";
12053 if (type == STT_HP_STUB)
12054 return "HP_STUB";
12055 }
12056
d8045f23 12057 if (type == STT_GNU_IFUNC
dda8d76d 12058 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12059 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12060 return "IFUNC";
12061
e9e44622 12062 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12063 }
252b5132 12064 else
e9e44622 12065 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12066 return buff;
12067 }
12068}
12069
d1133906 12070static const char *
d3ba0551 12071get_symbol_visibility (unsigned int visibility)
d1133906
NC
12072{
12073 switch (visibility)
12074 {
b34976b6
AM
12075 case STV_DEFAULT: return "DEFAULT";
12076 case STV_INTERNAL: return "INTERNAL";
12077 case STV_HIDDEN: return "HIDDEN";
d1133906 12078 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12079 default:
27a45f42 12080 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12081 return _("<unknown>");
d1133906
NC
12082 }
12083}
12084
2057d69d
CZ
12085static const char *
12086get_alpha_symbol_other (unsigned int other)
9abca702 12087{
2057d69d
CZ
12088 switch (other)
12089 {
12090 case STO_ALPHA_NOPV: return "NOPV";
12091 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12092 default:
27a45f42 12093 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12094 return _("<unknown>");
9abca702 12095 }
2057d69d
CZ
12096}
12097
fd85a6a1
NC
12098static const char *
12099get_solaris_symbol_visibility (unsigned int visibility)
12100{
12101 switch (visibility)
12102 {
12103 case 4: return "EXPORTED";
12104 case 5: return "SINGLETON";
12105 case 6: return "ELIMINATE";
12106 default: return get_symbol_visibility (visibility);
12107 }
12108}
12109
2301ed1c
SN
12110static const char *
12111get_aarch64_symbol_other (unsigned int other)
12112{
12113 static char buf[32];
12114
12115 if (other & STO_AARCH64_VARIANT_PCS)
12116 {
12117 other &= ~STO_AARCH64_VARIANT_PCS;
12118 if (other == 0)
12119 return "VARIANT_PCS";
12120 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12121 return buf;
12122 }
12123 return NULL;
12124}
12125
5e2b0d47
NC
12126static const char *
12127get_mips_symbol_other (unsigned int other)
12128{
12129 switch (other)
12130 {
32ec8896
NC
12131 case STO_OPTIONAL: return "OPTIONAL";
12132 case STO_MIPS_PLT: return "MIPS PLT";
12133 case STO_MIPS_PIC: return "MIPS PIC";
12134 case STO_MICROMIPS: return "MICROMIPS";
12135 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12136 case STO_MIPS16: return "MIPS16";
12137 default: return NULL;
5e2b0d47
NC
12138 }
12139}
12140
28f997cf 12141static const char *
dda8d76d 12142get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12143{
dda8d76d 12144 if (is_ia64_vms (filedata))
28f997cf
TG
12145 {
12146 static char res[32];
12147
12148 res[0] = 0;
12149
12150 /* Function types is for images and .STB files only. */
dda8d76d 12151 switch (filedata->file_header.e_type)
28f997cf
TG
12152 {
12153 case ET_DYN:
12154 case ET_EXEC:
12155 switch (VMS_ST_FUNC_TYPE (other))
12156 {
12157 case VMS_SFT_CODE_ADDR:
12158 strcat (res, " CA");
12159 break;
12160 case VMS_SFT_SYMV_IDX:
12161 strcat (res, " VEC");
12162 break;
12163 case VMS_SFT_FD:
12164 strcat (res, " FD");
12165 break;
12166 case VMS_SFT_RESERVE:
12167 strcat (res, " RSV");
12168 break;
12169 default:
bee0ee85
NC
12170 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12171 VMS_ST_FUNC_TYPE (other));
12172 strcat (res, " <unknown>");
12173 break;
28f997cf
TG
12174 }
12175 break;
12176 default:
12177 break;
12178 }
12179 switch (VMS_ST_LINKAGE (other))
12180 {
12181 case VMS_STL_IGNORE:
12182 strcat (res, " IGN");
12183 break;
12184 case VMS_STL_RESERVE:
12185 strcat (res, " RSV");
12186 break;
12187 case VMS_STL_STD:
12188 strcat (res, " STD");
12189 break;
12190 case VMS_STL_LNK:
12191 strcat (res, " LNK");
12192 break;
12193 default:
bee0ee85
NC
12194 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12195 VMS_ST_LINKAGE (other));
12196 strcat (res, " <unknown>");
12197 break;
28f997cf
TG
12198 }
12199
12200 if (res[0] != 0)
12201 return res + 1;
12202 else
12203 return res;
12204 }
12205 return NULL;
12206}
12207
6911b7dc
AM
12208static const char *
12209get_ppc64_symbol_other (unsigned int other)
12210{
14732552
AM
12211 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12212 return NULL;
12213
12214 other >>= STO_PPC64_LOCAL_BIT;
12215 if (other <= 6)
6911b7dc 12216 {
89246a0e 12217 static char buf[64];
14732552
AM
12218 if (other >= 2)
12219 other = ppc64_decode_local_entry (other);
12220 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12221 return buf;
12222 }
12223 return NULL;
12224}
12225
5e2b0d47 12226static const char *
dda8d76d 12227get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12228{
12229 const char * result = NULL;
89246a0e 12230 static char buff [64];
5e2b0d47
NC
12231
12232 if (other == 0)
12233 return "";
12234
dda8d76d 12235 switch (filedata->file_header.e_machine)
5e2b0d47 12236 {
2057d69d
CZ
12237 case EM_ALPHA:
12238 result = get_alpha_symbol_other (other);
12239 break;
2301ed1c
SN
12240 case EM_AARCH64:
12241 result = get_aarch64_symbol_other (other);
12242 break;
5e2b0d47
NC
12243 case EM_MIPS:
12244 result = get_mips_symbol_other (other);
28f997cf
TG
12245 break;
12246 case EM_IA_64:
dda8d76d 12247 result = get_ia64_symbol_other (filedata, other);
28f997cf 12248 break;
6911b7dc
AM
12249 case EM_PPC64:
12250 result = get_ppc64_symbol_other (other);
12251 break;
5e2b0d47 12252 default:
fd85a6a1 12253 result = NULL;
5e2b0d47
NC
12254 break;
12255 }
12256
12257 if (result)
12258 return result;
12259
12260 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12261 return buff;
12262}
12263
d1133906 12264static const char *
dda8d76d 12265get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12266{
b34976b6 12267 static char buff[32];
5cf1065c 12268
252b5132
RH
12269 switch (type)
12270 {
b34976b6
AM
12271 case SHN_UNDEF: return "UND";
12272 case SHN_ABS: return "ABS";
12273 case SHN_COMMON: return "COM";
252b5132 12274 default:
9ce701e2 12275 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12276 && filedata->file_header.e_machine == EM_IA_64
12277 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12278 return "ANSI_COM";
12279 else if ((filedata->file_header.e_machine == EM_X86_64
12280 || filedata->file_header.e_machine == EM_L1OM
12281 || filedata->file_header.e_machine == EM_K1OM)
12282 && type == SHN_X86_64_LCOMMON)
12283 return "LARGE_COM";
12284 else if ((type == SHN_MIPS_SCOMMON
12285 && filedata->file_header.e_machine == EM_MIPS)
12286 || (type == SHN_TIC6X_SCOMMON
12287 && filedata->file_header.e_machine == EM_TI_C6000))
12288 return "SCOM";
12289 else if (type == SHN_MIPS_SUNDEFINED
12290 && filedata->file_header.e_machine == EM_MIPS)
12291 return "SUND";
12292 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12293 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12294 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12295 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12296 else if (type >= SHN_LORESERVE)
12297 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12298 else if (filedata->file_header.e_shnum != 0
12299 && type >= filedata->file_header.e_shnum)
12300 sprintf (buff, _("bad section index[%3d]"), type);
12301 else
12302 sprintf (buff, "%3d", type);
12303 break;
fd85a6a1
NC
12304 }
12305
10ca4b04 12306 return buff;
6bd1a22c
L
12307}
12308
bb4d2ac2 12309static const char *
dda8d76d 12310get_symbol_version_string (Filedata * filedata,
015dc7e1 12311 bool is_dynsym,
1449284b
NC
12312 const char * strtab,
12313 unsigned long int strtab_size,
12314 unsigned int si,
12315 Elf_Internal_Sym * psym,
12316 enum versioned_symbol_info * sym_info,
12317 unsigned short * vna_other)
bb4d2ac2 12318{
ab273396
AM
12319 unsigned char data[2];
12320 unsigned short vers_data;
12321 unsigned long offset;
7a815dd5 12322 unsigned short max_vd_ndx;
bb4d2ac2 12323
ab273396 12324 if (!is_dynsym
978c4450 12325 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12326 return NULL;
bb4d2ac2 12327
978c4450
AM
12328 offset = offset_from_vma (filedata,
12329 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12330 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12331
dda8d76d 12332 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12333 sizeof (data), 1, _("version data")) == NULL)
12334 return NULL;
12335
12336 vers_data = byte_get (data, 2);
bb4d2ac2 12337
1f6f5dba 12338 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12339 return NULL;
bb4d2ac2 12340
0b8b7609 12341 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12342 max_vd_ndx = 0;
12343
ab273396
AM
12344 /* Usually we'd only see verdef for defined symbols, and verneed for
12345 undefined symbols. However, symbols defined by the linker in
12346 .dynbss for variables copied from a shared library in order to
12347 avoid text relocations are defined yet have verneed. We could
12348 use a heuristic to detect the special case, for example, check
12349 for verneed first on symbols defined in SHT_NOBITS sections, but
12350 it is simpler and more reliable to just look for both verdef and
12351 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12352
ab273396
AM
12353 if (psym->st_shndx != SHN_UNDEF
12354 && vers_data != 0x8001
978c4450 12355 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12356 {
12357 Elf_Internal_Verdef ivd;
12358 Elf_Internal_Verdaux ivda;
12359 Elf_External_Verdaux evda;
12360 unsigned long off;
bb4d2ac2 12361
dda8d76d 12362 off = offset_from_vma (filedata,
978c4450 12363 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12364 sizeof (Elf_External_Verdef));
12365
12366 do
bb4d2ac2 12367 {
ab273396
AM
12368 Elf_External_Verdef evd;
12369
dda8d76d 12370 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12371 _("version def")) == NULL)
12372 {
12373 ivd.vd_ndx = 0;
12374 ivd.vd_aux = 0;
12375 ivd.vd_next = 0;
1f6f5dba 12376 ivd.vd_flags = 0;
ab273396
AM
12377 }
12378 else
bb4d2ac2 12379 {
ab273396
AM
12380 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12381 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12382 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12383 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12384 }
bb4d2ac2 12385
7a815dd5
L
12386 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12387 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12388
ab273396
AM
12389 off += ivd.vd_next;
12390 }
12391 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12392
ab273396
AM
12393 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12394 {
9abca702 12395 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12396 return NULL;
12397
ab273396
AM
12398 off -= ivd.vd_next;
12399 off += ivd.vd_aux;
bb4d2ac2 12400
dda8d76d 12401 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12402 _("version def aux")) != NULL)
12403 {
12404 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12405
ab273396 12406 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12407 return (ivda.vda_name < strtab_size
12408 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12409 }
12410 }
12411 }
bb4d2ac2 12412
978c4450 12413 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12414 {
12415 Elf_External_Verneed evn;
12416 Elf_Internal_Verneed ivn;
12417 Elf_Internal_Vernaux ivna;
bb4d2ac2 12418
dda8d76d 12419 offset = offset_from_vma (filedata,
978c4450 12420 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12421 sizeof evn);
12422 do
12423 {
12424 unsigned long vna_off;
bb4d2ac2 12425
dda8d76d 12426 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12427 _("version need")) == NULL)
12428 {
12429 ivna.vna_next = 0;
12430 ivna.vna_other = 0;
12431 ivna.vna_name = 0;
12432 break;
12433 }
bb4d2ac2 12434
ab273396
AM
12435 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12436 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12437
ab273396 12438 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12439
ab273396
AM
12440 do
12441 {
12442 Elf_External_Vernaux evna;
bb4d2ac2 12443
dda8d76d 12444 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12445 _("version need aux (3)")) == NULL)
bb4d2ac2 12446 {
ab273396
AM
12447 ivna.vna_next = 0;
12448 ivna.vna_other = 0;
12449 ivna.vna_name = 0;
bb4d2ac2 12450 }
bb4d2ac2 12451 else
bb4d2ac2 12452 {
ab273396
AM
12453 ivna.vna_other = BYTE_GET (evna.vna_other);
12454 ivna.vna_next = BYTE_GET (evna.vna_next);
12455 ivna.vna_name = BYTE_GET (evna.vna_name);
12456 }
bb4d2ac2 12457
ab273396
AM
12458 vna_off += ivna.vna_next;
12459 }
12460 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12461
ab273396
AM
12462 if (ivna.vna_other == vers_data)
12463 break;
bb4d2ac2 12464
ab273396
AM
12465 offset += ivn.vn_next;
12466 }
12467 while (ivn.vn_next != 0);
bb4d2ac2 12468
ab273396
AM
12469 if (ivna.vna_other == vers_data)
12470 {
12471 *sym_info = symbol_undefined;
12472 *vna_other = ivna.vna_other;
12473 return (ivna.vna_name < strtab_size
12474 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12475 }
7a815dd5
L
12476 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12477 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12478 return _("<corrupt>");
bb4d2ac2 12479 }
ab273396 12480 return NULL;
bb4d2ac2
L
12481}
12482
047c3dbf
NL
12483/* Display a symbol size on stdout. Format is based on --sym-base setting. */
12484
12485static unsigned int
12486print_dynamic_symbol_size (bfd_vma vma, int base)
12487{
12488 switch (base)
12489 {
12490 case 8:
12491 return print_vma (vma, OCTAL_5);
12492
12493 case 10:
12494 return print_vma (vma, UNSIGNED_5);
12495
12496 case 16:
12497 return print_vma (vma, PREFIX_HEX_5);
12498
12499 case 0:
12500 default:
12501 return print_vma (vma, DEC_5);
12502 }
12503}
12504
10ca4b04
L
12505static void
12506print_dynamic_symbol (Filedata *filedata, unsigned long si,
12507 Elf_Internal_Sym *symtab,
12508 Elf_Internal_Shdr *section,
12509 char *strtab, size_t strtab_size)
252b5132 12510{
10ca4b04
L
12511 const char *version_string;
12512 enum versioned_symbol_info sym_info;
12513 unsigned short vna_other;
23356397
NC
12514 bool is_valid;
12515 const char * sstr;
10ca4b04 12516 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 12517
10ca4b04
L
12518 printf ("%6ld: ", si);
12519 print_vma (psym->st_value, LONG_HEX);
12520 putchar (' ');
047c3dbf 12521 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
12522 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12523 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12524 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12525 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12526 else
252b5132 12527 {
10ca4b04 12528 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12529
10ca4b04
L
12530 printf (" %-7s", get_symbol_visibility (vis));
12531 /* Check to see if any other bits in the st_other field are set.
12532 Note - displaying this information disrupts the layout of the
12533 table being generated, but for the moment this case is very rare. */
12534 if (psym->st_other ^ vis)
12535 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12536 }
10ca4b04 12537 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 12538
23356397
NC
12539 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
12540 && psym->st_shndx < filedata->file_header.e_shnum
12541 && psym->st_name == 0)
12542 {
12543 is_valid = SECTION_NAME_VALID (filedata->section_headers + psym->st_shndx);
12544 sstr = is_valid ?
12545 SECTION_NAME_PRINT (filedata->section_headers + psym->st_shndx)
12546 : _("<corrupt>");
12547 }
12548 else
12549 {
12550 is_valid = VALID_SYMBOL_NAME (strtab, strtab_size, psym->st_name);
12551 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
12552 }
10ca4b04
L
12553
12554 version_string
12555 = get_symbol_version_string (filedata,
12556 (section == NULL
12557 || section->sh_type == SHT_DYNSYM),
12558 strtab, strtab_size, si,
12559 psym, &sym_info, &vna_other);
b9e920ec 12560
0942c7ab
NC
12561 int len_avail = 21;
12562 if (! do_wide && version_string != NULL)
12563 {
ddb43bab 12564 char buffer[16];
0942c7ab 12565
ddb43bab 12566 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
12567
12568 if (sym_info == symbol_undefined)
12569 len_avail -= sprintf (buffer," (%d)", vna_other);
12570 else if (sym_info != symbol_hidden)
12571 len_avail -= 1;
12572 }
12573
12574 print_symbol (len_avail, sstr);
b9e920ec 12575
10ca4b04
L
12576 if (version_string)
12577 {
12578 if (sym_info == symbol_undefined)
12579 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12580 else
10ca4b04
L
12581 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12582 version_string);
12583 }
6bd1a22c 12584
10ca4b04 12585 putchar ('\n');
6bd1a22c 12586
10ca4b04
L
12587 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12588 && section != NULL
12589 && si >= section->sh_info
12590 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12591 && filedata->file_header.e_machine != EM_MIPS
12592 /* Solaris binaries have been found to violate this requirement as
12593 well. Not sure if this is a bug or an ABI requirement. */
12594 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12595 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12596 si, printable_section_name (filedata, section), section->sh_info);
12597}
f16a9783 12598
0f03783c
NC
12599static const char *
12600get_lto_kind (unsigned int kind)
12601{
12602 switch (kind)
12603 {
12604 case 0: return "DEF";
12605 case 1: return "WEAKDEF";
12606 case 2: return "UNDEF";
12607 case 3: return "WEAKUNDEF";
12608 case 4: return "COMMON";
12609 default:
12610 break;
12611 }
12612
12613 static char buffer[30];
12614 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
12615 sprintf (buffer, "<unknown: %u>", kind);
12616 return buffer;
12617}
12618
12619static const char *
12620get_lto_visibility (unsigned int visibility)
12621{
12622 switch (visibility)
12623 {
12624 case 0: return "DEFAULT";
12625 case 1: return "PROTECTED";
12626 case 2: return "INTERNAL";
12627 case 3: return "HIDDEN";
12628 default:
12629 break;
12630 }
12631
12632 static char buffer[30];
12633 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
12634 sprintf (buffer, "<unknown: %u>", visibility);
12635 return buffer;
12636}
12637
12638static const char *
12639get_lto_sym_type (unsigned int sym_type)
12640{
12641 switch (sym_type)
12642 {
12643 case 0: return "UNKNOWN";
12644 case 1: return "FUNCTION";
12645 case 2: return "VARIABLE";
12646 default:
12647 break;
12648 }
12649
12650 static char buffer[30];
12651 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
12652 sprintf (buffer, "<unknown: %u>", sym_type);
12653 return buffer;
12654}
12655
12656/* Display an LTO format symbol table.
12657 FIXME: The format of LTO symbol tables is not formalized.
12658 So this code could need changing in the future. */
12659
015dc7e1 12660static bool
0f03783c
NC
12661display_lto_symtab (Filedata * filedata,
12662 Elf_Internal_Shdr * section)
12663{
12664 if (section->sh_size == 0)
12665 {
ca0e11aa
NC
12666 if (filedata->is_separate)
12667 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
12668 printable_section_name (filedata, section),
12669 filedata->file_name);
12670 else
12671 printf (_("\nLTO Symbol table '%s' is empty!\n"),
12672 printable_section_name (filedata, section));
047c3dbf 12673
015dc7e1 12674 return true;
0f03783c
NC
12675 }
12676
12677 if (section->sh_size > filedata->file_size)
12678 {
12679 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
12680 printable_section_name (filedata, section),
12681 (unsigned long) section->sh_size);
015dc7e1 12682 return false;
0f03783c
NC
12683 }
12684
12685 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
12686 section->sh_size, 1, _("LTO symbols"));
12687 if (alloced_data == NULL)
015dc7e1 12688 return false;
0f03783c
NC
12689
12690 /* Look for extended data for the symbol table. */
12691 Elf_Internal_Shdr * ext;
12692 void * ext_data_orig = NULL;
12693 char * ext_data = NULL;
12694 char * ext_data_end = NULL;
12695 char * ext_name = NULL;
12696
12697 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
b9e920ec 12698 SECTION_NAME (section) + sizeof (".gnu.lto_.symtab.") - 1) > 0
0f03783c
NC
12699 && ext_name != NULL /* Paranoia. */
12700 && (ext = find_section (filedata, ext_name)) != NULL)
12701 {
12702 if (ext->sh_size < 3)
12703 error (_("LTO Symbol extension table '%s' is empty!\n"),
12704 printable_section_name (filedata, ext));
12705 else
12706 {
12707 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
12708 ext->sh_size, 1,
12709 _("LTO ext symbol data"));
12710 if (ext_data != NULL)
12711 {
12712 ext_data_end = ext_data + ext->sh_size;
12713 if (* ext_data++ != 1)
12714 error (_("Unexpected version number in symbol extension table\n"));
12715 }
12716 }
12717 }
b9e920ec 12718
0f03783c
NC
12719 const unsigned char * data = (const unsigned char *) alloced_data;
12720 const unsigned char * end = data + section->sh_size;
12721
ca0e11aa
NC
12722 if (filedata->is_separate)
12723 printf (_("\nIn linked file '%s': "), filedata->file_name);
12724 else
12725 printf ("\n");
12726
0f03783c
NC
12727 if (ext_data_orig != NULL)
12728 {
12729 if (do_wide)
ca0e11aa 12730 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
12731 printable_section_name (filedata, section),
12732 printable_section_name (filedata, ext));
12733 else
12734 {
ca0e11aa 12735 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
12736 printable_section_name (filedata, section));
12737 printf (_(" and extension table '%s' contain:\n"),
12738 printable_section_name (filedata, ext));
12739 }
12740 }
12741 else
ca0e11aa 12742 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 12743 printable_section_name (filedata, section));
b9e920ec 12744
0f03783c 12745 /* FIXME: Add a wide version. */
b9e920ec 12746 if (ext_data_orig != NULL)
0f03783c
NC
12747 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
12748 else
12749 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
12750
12751 /* FIXME: We do not handle style prefixes. */
12752
12753 while (data < end)
12754 {
12755 const unsigned char * sym_name = data;
12756 data += strnlen ((const char *) sym_name, end - data) + 1;
12757 if (data >= end)
12758 goto fail;
12759
12760 const unsigned char * comdat_key = data;
12761 data += strnlen ((const char *) comdat_key, end - data) + 1;
12762 if (data >= end)
12763 goto fail;
12764
12765 if (data + 2 + 8 + 4 > end)
12766 goto fail;
12767
12768 unsigned int kind = *data++;
12769 unsigned int visibility = *data++;
12770
12771 elf_vma size = byte_get (data, 8);
12772 data += 8;
12773
12774 elf_vma slot = byte_get (data, 4);
12775 data += 4;
12776
12777 if (ext_data != NULL)
12778 {
12779 if (ext_data < (ext_data_end - 1))
12780 {
12781 unsigned int sym_type = * ext_data ++;
12782 unsigned int sec_kind = * ext_data ++;
12783
12784 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
12785 * comdat_key == 0 ? "-" : (char *) comdat_key,
12786 get_lto_kind (kind),
12787 get_lto_visibility (visibility),
12788 (long) size,
12789 (long) slot,
12790 get_lto_sym_type (sym_type),
12791 (long) sec_kind);
12792 print_symbol (6, (const char *) sym_name);
12793 }
12794 else
12795 {
12796 error (_("Ran out of LTO symbol extension data\n"));
12797 ext_data = NULL;
12798 /* FIXME: return FAIL result ? */
12799 }
12800 }
12801 else
12802 {
12803 printf (" %10s %10s %11s %08lx %08lx _",
12804 * comdat_key == 0 ? "-" : (char *) comdat_key,
12805 get_lto_kind (kind),
12806 get_lto_visibility (visibility),
12807 (long) size,
12808 (long) slot);
12809 print_symbol (21, (const char *) sym_name);
12810 }
12811 putchar ('\n');
12812 }
12813
12814 if (ext_data != NULL && ext_data < ext_data_end)
12815 {
12816 error (_("Data remains in the LTO symbol extension table\n"));
12817 goto fail;
12818 }
12819
12820 free (alloced_data);
12821 free (ext_data_orig);
12822 free (ext_name);
015dc7e1 12823 return true;
b9e920ec 12824
0f03783c
NC
12825 fail:
12826 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
12827 free (alloced_data);
12828 free (ext_data_orig);
12829 free (ext_name);
015dc7e1 12830 return false;
0f03783c
NC
12831}
12832
12833/* Display LTO symbol tables. */
12834
015dc7e1 12835static bool
0f03783c
NC
12836process_lto_symbol_tables (Filedata * filedata)
12837{
12838 Elf_Internal_Shdr * section;
12839 unsigned int i;
015dc7e1 12840 bool res = true;
0f03783c
NC
12841
12842 if (!do_lto_syms)
015dc7e1 12843 return true;
0f03783c
NC
12844
12845 if (filedata->section_headers == NULL)
015dc7e1 12846 return true;
0f03783c
NC
12847
12848 for (i = 0, section = filedata->section_headers;
12849 i < filedata->file_header.e_shnum;
12850 i++, section++)
b9e920ec 12851 if (SECTION_NAME_VALID (section)
08dedd66 12852 && startswith (SECTION_NAME (section), ".gnu.lto_.symtab."))
0f03783c
NC
12853 res &= display_lto_symtab (filedata, section);
12854
b9e920ec 12855 return res;
0f03783c
NC
12856}
12857
10ca4b04 12858/* Dump the symbol table. */
0f03783c 12859
015dc7e1 12860static bool
10ca4b04
L
12861process_symbol_table (Filedata * filedata)
12862{
12863 Elf_Internal_Shdr * section;
f16a9783 12864
10ca4b04 12865 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 12866 return true;
6bd1a22c 12867
978c4450 12868 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
12869 && do_syms
12870 && do_using_dynamic
978c4450
AM
12871 && filedata->dynamic_strings != NULL
12872 && filedata->dynamic_symbols != NULL)
6bd1a22c 12873 {
10ca4b04 12874 unsigned long si;
6bd1a22c 12875
ca0e11aa
NC
12876 if (filedata->is_separate)
12877 {
12878 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
12879 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
12880 filedata->num_dynamic_syms),
12881 filedata->file_name,
12882 filedata->num_dynamic_syms);
12883 }
12884 else
12885 {
12886 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12887 "\nSymbol table for image contains %lu entries:\n",
12888 filedata->num_dynamic_syms),
12889 filedata->num_dynamic_syms);
12890 }
10ca4b04
L
12891 if (is_32bit_elf)
12892 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12893 else
12894 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12895
978c4450
AM
12896 for (si = 0; si < filedata->num_dynamic_syms; si++)
12897 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
12898 filedata->dynamic_strings,
12899 filedata->dynamic_strings_length);
252b5132 12900 }
8b73c356 12901 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 12902 && filedata->section_headers != NULL)
252b5132 12903 {
b34976b6 12904 unsigned int i;
252b5132 12905
dda8d76d
NC
12906 for (i = 0, section = filedata->section_headers;
12907 i < filedata->file_header.e_shnum;
252b5132
RH
12908 i++, section++)
12909 {
2cf0635d 12910 char * strtab = NULL;
c256ffe7 12911 unsigned long int strtab_size = 0;
2cf0635d 12912 Elf_Internal_Sym * symtab;
ef3df110 12913 unsigned long si, num_syms;
252b5132 12914
2c610e4b
L
12915 if ((section->sh_type != SHT_SYMTAB
12916 && section->sh_type != SHT_DYNSYM)
12917 || (!do_syms
12918 && section->sh_type == SHT_SYMTAB))
252b5132
RH
12919 continue;
12920
dd24e3da
NC
12921 if (section->sh_entsize == 0)
12922 {
12923 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 12924 printable_section_name (filedata, section));
dd24e3da
NC
12925 continue;
12926 }
12927
d3a49aa8 12928 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
12929
12930 if (filedata->is_separate)
12931 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
12932 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
12933 num_syms),
12934 filedata->file_name,
12935 printable_section_name (filedata, section),
12936 num_syms);
12937 else
12938 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
12939 "\nSymbol table '%s' contains %lu entries:\n",
12940 num_syms),
12941 printable_section_name (filedata, section),
12942 num_syms);
dd24e3da 12943
f7a99963 12944 if (is_32bit_elf)
ca47b30c 12945 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 12946 else
ca47b30c 12947 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 12948
4de91c10 12949 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
12950 if (symtab == NULL)
12951 continue;
12952
dda8d76d 12953 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 12954 {
dda8d76d
NC
12955 strtab = filedata->string_table;
12956 strtab_size = filedata->string_table_length;
c256ffe7 12957 }
dda8d76d 12958 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 12959 {
2cf0635d 12960 Elf_Internal_Shdr * string_sec;
252b5132 12961
dda8d76d 12962 string_sec = filedata->section_headers + section->sh_link;
252b5132 12963
dda8d76d 12964 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
12965 1, string_sec->sh_size,
12966 _("string table"));
c256ffe7 12967 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
12968 }
12969
10ca4b04
L
12970 for (si = 0; si < num_syms; si++)
12971 print_dynamic_symbol (filedata, si, symtab, section,
12972 strtab, strtab_size);
252b5132
RH
12973
12974 free (symtab);
dda8d76d 12975 if (strtab != filedata->string_table)
252b5132
RH
12976 free (strtab);
12977 }
12978 }
12979 else if (do_syms)
12980 printf
12981 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
12982
978c4450 12983 if (do_histogram && filedata->buckets != NULL)
252b5132 12984 {
2cf0635d
NC
12985 unsigned long * lengths;
12986 unsigned long * counts;
66543521
AM
12987 unsigned long hn;
12988 bfd_vma si;
12989 unsigned long maxlength = 0;
12990 unsigned long nzero_counts = 0;
12991 unsigned long nsyms = 0;
6bd6a03d 12992 char *visited;
252b5132 12993
d3a49aa8
AM
12994 printf (ngettext ("\nHistogram for bucket list length "
12995 "(total of %lu bucket):\n",
12996 "\nHistogram for bucket list length "
12997 "(total of %lu buckets):\n",
978c4450
AM
12998 (unsigned long) filedata->nbuckets),
12999 (unsigned long) filedata->nbuckets);
252b5132 13000
978c4450
AM
13001 lengths = (unsigned long *) calloc (filedata->nbuckets,
13002 sizeof (*lengths));
252b5132
RH
13003 if (lengths == NULL)
13004 {
8b73c356 13005 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13006 goto err_out;
252b5132 13007 }
978c4450
AM
13008 visited = xcmalloc (filedata->nchains, 1);
13009 memset (visited, 0, filedata->nchains);
8b73c356
NC
13010
13011 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13012 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13013 {
978c4450 13014 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13015 {
b34976b6 13016 ++nsyms;
252b5132 13017 if (maxlength < ++lengths[hn])
b34976b6 13018 ++maxlength;
978c4450 13019 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13020 {
13021 error (_("histogram chain is corrupt\n"));
13022 break;
13023 }
13024 visited[si] = 1;
252b5132
RH
13025 }
13026 }
6bd6a03d 13027 free (visited);
252b5132 13028
3f5e193b 13029 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13030 if (counts == NULL)
13031 {
b2e951ec 13032 free (lengths);
8b73c356 13033 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13034 goto err_out;
252b5132
RH
13035 }
13036
978c4450 13037 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13038 ++counts[lengths[hn]];
252b5132 13039
978c4450 13040 if (filedata->nbuckets > 0)
252b5132 13041 {
66543521
AM
13042 unsigned long i;
13043 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13044 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13045 for (i = 1; i <= maxlength; ++i)
103f02d3 13046 {
66543521
AM
13047 nzero_counts += counts[i] * i;
13048 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13049 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13050 (nzero_counts * 100.0) / nsyms);
13051 }
252b5132
RH
13052 }
13053
13054 free (counts);
13055 free (lengths);
13056 }
13057
978c4450
AM
13058 free (filedata->buckets);
13059 filedata->buckets = NULL;
13060 filedata->nbuckets = 0;
13061 free (filedata->chains);
13062 filedata->chains = NULL;
252b5132 13063
978c4450 13064 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13065 {
2cf0635d
NC
13066 unsigned long * lengths;
13067 unsigned long * counts;
fdc90cb4
JJ
13068 unsigned long hn;
13069 unsigned long maxlength = 0;
13070 unsigned long nzero_counts = 0;
13071 unsigned long nsyms = 0;
fdc90cb4 13072
f16a9783 13073 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13074 "(total of %lu bucket):\n",
f16a9783 13075 "\nHistogram for `%s' bucket list length "
d3a49aa8 13076 "(total of %lu buckets):\n",
978c4450
AM
13077 (unsigned long) filedata->ngnubuckets),
13078 GNU_HASH_SECTION_NAME (filedata),
13079 (unsigned long) filedata->ngnubuckets);
8b73c356 13080
978c4450
AM
13081 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13082 sizeof (*lengths));
fdc90cb4
JJ
13083 if (lengths == NULL)
13084 {
8b73c356 13085 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13086 goto err_out;
fdc90cb4
JJ
13087 }
13088
fdc90cb4
JJ
13089 printf (_(" Length Number %% of total Coverage\n"));
13090
978c4450
AM
13091 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13092 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
13093 {
13094 bfd_vma off, length = 1;
13095
978c4450 13096 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13097 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13098 off < filedata->ngnuchains
13099 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13100 ++off)
fdc90cb4
JJ
13101 ++length;
13102 lengths[hn] = length;
13103 if (length > maxlength)
13104 maxlength = length;
13105 nsyms += length;
13106 }
13107
3f5e193b 13108 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13109 if (counts == NULL)
13110 {
b2e951ec 13111 free (lengths);
8b73c356 13112 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13113 goto err_out;
fdc90cb4
JJ
13114 }
13115
978c4450 13116 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13117 ++counts[lengths[hn]];
13118
978c4450 13119 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13120 {
13121 unsigned long j;
13122 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13123 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13124 for (j = 1; j <= maxlength; ++j)
13125 {
13126 nzero_counts += counts[j] * j;
13127 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13128 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13129 (nzero_counts * 100.0) / nsyms);
13130 }
13131 }
13132
13133 free (counts);
13134 free (lengths);
fdc90cb4 13135 }
978c4450
AM
13136 free (filedata->gnubuckets);
13137 filedata->gnubuckets = NULL;
13138 filedata->ngnubuckets = 0;
13139 free (filedata->gnuchains);
13140 filedata->gnuchains = NULL;
13141 filedata->ngnuchains = 0;
13142 free (filedata->mipsxlat);
13143 filedata->mipsxlat = NULL;
015dc7e1 13144 return true;
fd486f32
AM
13145
13146 err_out:
978c4450
AM
13147 free (filedata->gnubuckets);
13148 filedata->gnubuckets = NULL;
13149 filedata->ngnubuckets = 0;
13150 free (filedata->gnuchains);
13151 filedata->gnuchains = NULL;
13152 filedata->ngnuchains = 0;
13153 free (filedata->mipsxlat);
13154 filedata->mipsxlat = NULL;
13155 free (filedata->buckets);
13156 filedata->buckets = NULL;
13157 filedata->nbuckets = 0;
13158 free (filedata->chains);
13159 filedata->chains = NULL;
015dc7e1 13160 return false;
252b5132
RH
13161}
13162
015dc7e1 13163static bool
ca0e11aa 13164process_syminfo (Filedata * filedata)
252b5132 13165{
b4c96d0d 13166 unsigned int i;
252b5132 13167
978c4450 13168 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13169 || !do_dynamic)
13170 /* No syminfo, this is ok. */
015dc7e1 13171 return true;
252b5132
RH
13172
13173 /* There better should be a dynamic symbol section. */
978c4450 13174 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13175 return false;
252b5132 13176
ca0e11aa
NC
13177 if (filedata->is_separate)
13178 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13179 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13180 filedata->dynamic_syminfo_nent),
13181 filedata->file_name,
13182 filedata->dynamic_syminfo_offset,
13183 filedata->dynamic_syminfo_nent);
13184 else
d3a49aa8
AM
13185 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13186 "contains %d entry:\n",
13187 "\nDynamic info segment at offset 0x%lx "
13188 "contains %d entries:\n",
978c4450 13189 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13190 filedata->dynamic_syminfo_offset,
13191 filedata->dynamic_syminfo_nent);
252b5132
RH
13192
13193 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13194 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13195 {
978c4450 13196 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13197
31104126 13198 printf ("%4d: ", i);
978c4450 13199 if (i >= filedata->num_dynamic_syms)
4082ef84 13200 printf (_("<corrupt index>"));
978c4450
AM
13201 else if (VALID_DYNAMIC_NAME (filedata, filedata->dynamic_symbols[i].st_name))
13202 print_symbol (30, GET_DYNAMIC_NAME (filedata,
13203 filedata->dynamic_symbols[i].st_name));
d79b3d50 13204 else
978c4450 13205 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13206 putchar (' ');
252b5132 13207
978c4450 13208 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13209 {
13210 case SYMINFO_BT_SELF:
13211 fputs ("SELF ", stdout);
13212 break;
13213 case SYMINFO_BT_PARENT:
13214 fputs ("PARENT ", stdout);
13215 break;
13216 default:
978c4450
AM
13217 if (filedata->dynamic_syminfo[i].si_boundto > 0
13218 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
13219 && VALID_DYNAMIC_NAME (filedata,
13220 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13221 {
978c4450
AM
13222 print_symbol (10, GET_DYNAMIC_NAME (filedata,
13223 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13224 putchar (' ' );
13225 }
252b5132 13226 else
978c4450 13227 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13228 break;
13229 }
13230
13231 if (flags & SYMINFO_FLG_DIRECT)
13232 printf (" DIRECT");
13233 if (flags & SYMINFO_FLG_PASSTHRU)
13234 printf (" PASSTHRU");
13235 if (flags & SYMINFO_FLG_COPY)
13236 printf (" COPY");
13237 if (flags & SYMINFO_FLG_LAZYLOAD)
13238 printf (" LAZYLOAD");
13239
13240 puts ("");
13241 }
13242
015dc7e1 13243 return true;
252b5132
RH
13244}
13245
75802ccb
CE
13246/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13247 is contained by the region START .. END. The types of ADDR, START
13248 and END should all be the same. Note both ADDR + NELEM and END
13249 point to just beyond the end of the regions that are being tested. */
13250#define IN_RANGE(START,END,ADDR,NELEM) \
13251 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13252
cf13d699
NC
13253/* Check to see if the given reloc needs to be handled in a target specific
13254 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13255 FALSE.
13256
13257 If called with reloc == NULL, then this is a signal that reloc processing
13258 for the current section has finished, and any saved state should be
13259 discarded. */
09c11c86 13260
015dc7e1 13261static bool
dda8d76d
NC
13262target_specific_reloc_handling (Filedata * filedata,
13263 Elf_Internal_Rela * reloc,
13264 unsigned char * start,
13265 unsigned char * end,
13266 Elf_Internal_Sym * symtab,
13267 unsigned long num_syms)
252b5132 13268{
f84ce13b
NC
13269 unsigned int reloc_type = 0;
13270 unsigned long sym_index = 0;
13271
13272 if (reloc)
13273 {
dda8d76d 13274 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13275 sym_index = get_reloc_symindex (reloc->r_info);
13276 }
252b5132 13277
dda8d76d 13278 switch (filedata->file_header.e_machine)
252b5132 13279 {
13761a11
NC
13280 case EM_MSP430:
13281 case EM_MSP430_OLD:
13282 {
13283 static Elf_Internal_Sym * saved_sym = NULL;
13284
f84ce13b
NC
13285 if (reloc == NULL)
13286 {
13287 saved_sym = NULL;
015dc7e1 13288 return true;
f84ce13b
NC
13289 }
13290
13761a11
NC
13291 switch (reloc_type)
13292 {
13293 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13294 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13295 if (uses_msp430x_relocs (filedata))
13761a11 13296 break;
1a0670f3 13297 /* Fall through. */
13761a11 13298 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13299 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13300 /* PR 21139. */
13301 if (sym_index >= num_syms)
13302 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13303 sym_index);
13304 else
13305 saved_sym = symtab + sym_index;
015dc7e1 13306 return true;
13761a11
NC
13307
13308 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13309 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13310 goto handle_sym_diff;
0b4362b0 13311
13761a11
NC
13312 case 5: /* R_MSP430_16_BYTE */
13313 case 9: /* R_MSP430_8 */
7d81bc93 13314 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13315 if (uses_msp430x_relocs (filedata))
13761a11
NC
13316 break;
13317 goto handle_sym_diff;
13318
13319 case 2: /* R_MSP430_ABS16 */
13320 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13321 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13322 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13323 break;
13324 goto handle_sym_diff;
0b4362b0 13325
13761a11
NC
13326 handle_sym_diff:
13327 if (saved_sym != NULL)
13328 {
13329 bfd_vma value;
5a805384 13330 unsigned int reloc_size = 0;
7d81bc93
JL
13331 int leb_ret = 0;
13332 switch (reloc_type)
13333 {
13334 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13335 reloc_size = 4;
13336 break;
13337 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13338 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13339 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13340 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13341 &reloc_size, &leb_ret);
7d81bc93
JL
13342 break;
13343 default:
13344 reloc_size = 2;
13345 break;
13346 }
13761a11 13347
5a805384 13348 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13349 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13350 "ULEB128 value\n"),
13351 (long) reloc->r_offset);
13352 else if (sym_index >= num_syms)
f84ce13b
NC
13353 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13354 sym_index);
03f7786e 13355 else
f84ce13b
NC
13356 {
13357 value = reloc->r_addend + (symtab[sym_index].st_value
13358 - saved_sym->st_value);
13359
b32e566b 13360 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13361 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13362 else
13363 /* PR 21137 */
13364 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13365 (long) reloc->r_offset);
f84ce13b 13366 }
13761a11
NC
13367
13368 saved_sym = NULL;
015dc7e1 13369 return true;
13761a11
NC
13370 }
13371 break;
13372
13373 default:
13374 if (saved_sym != NULL)
071436c6 13375 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
13376 break;
13377 }
13378 break;
13379 }
13380
cf13d699
NC
13381 case EM_MN10300:
13382 case EM_CYGNUS_MN10300:
13383 {
13384 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 13385
f84ce13b
NC
13386 if (reloc == NULL)
13387 {
13388 saved_sym = NULL;
015dc7e1 13389 return true;
f84ce13b
NC
13390 }
13391
cf13d699
NC
13392 switch (reloc_type)
13393 {
13394 case 34: /* R_MN10300_ALIGN */
015dc7e1 13395 return true;
cf13d699 13396 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
13397 if (sym_index >= num_syms)
13398 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
13399 sym_index);
13400 else
13401 saved_sym = symtab + sym_index;
015dc7e1 13402 return true;
f84ce13b 13403
cf13d699
NC
13404 case 1: /* R_MN10300_32 */
13405 case 2: /* R_MN10300_16 */
13406 if (saved_sym != NULL)
13407 {
03f7786e 13408 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 13409 bfd_vma value;
252b5132 13410
f84ce13b
NC
13411 if (sym_index >= num_syms)
13412 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
13413 sym_index);
03f7786e 13414 else
f84ce13b
NC
13415 {
13416 value = reloc->r_addend + (symtab[sym_index].st_value
13417 - saved_sym->st_value);
13418
b32e566b 13419 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13420 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13421 else
13422 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
13423 (long) reloc->r_offset);
f84ce13b 13424 }
252b5132 13425
cf13d699 13426 saved_sym = NULL;
015dc7e1 13427 return true;
cf13d699
NC
13428 }
13429 break;
13430 default:
13431 if (saved_sym != NULL)
071436c6 13432 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
13433 break;
13434 }
13435 break;
13436 }
6ff71e76
NC
13437
13438 case EM_RL78:
13439 {
13440 static bfd_vma saved_sym1 = 0;
13441 static bfd_vma saved_sym2 = 0;
13442 static bfd_vma value;
13443
f84ce13b
NC
13444 if (reloc == NULL)
13445 {
13446 saved_sym1 = saved_sym2 = 0;
015dc7e1 13447 return true;
f84ce13b
NC
13448 }
13449
6ff71e76
NC
13450 switch (reloc_type)
13451 {
13452 case 0x80: /* R_RL78_SYM. */
13453 saved_sym1 = saved_sym2;
f84ce13b
NC
13454 if (sym_index >= num_syms)
13455 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
13456 sym_index);
13457 else
13458 {
13459 saved_sym2 = symtab[sym_index].st_value;
13460 saved_sym2 += reloc->r_addend;
13461 }
015dc7e1 13462 return true;
6ff71e76
NC
13463
13464 case 0x83: /* R_RL78_OPsub. */
13465 value = saved_sym1 - saved_sym2;
13466 saved_sym2 = saved_sym1 = 0;
015dc7e1 13467 return true;
6ff71e76
NC
13468 break;
13469
13470 case 0x41: /* R_RL78_ABS32. */
b32e566b 13471 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 13472 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
13473 else
13474 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13475 (long) reloc->r_offset);
6ff71e76 13476 value = 0;
015dc7e1 13477 return true;
6ff71e76
NC
13478
13479 case 0x43: /* R_RL78_ABS16. */
b32e566b 13480 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 13481 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
13482 else
13483 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13484 (long) reloc->r_offset);
6ff71e76 13485 value = 0;
015dc7e1 13486 return true;
6ff71e76
NC
13487
13488 default:
13489 break;
13490 }
13491 break;
13492 }
252b5132
RH
13493 }
13494
015dc7e1 13495 return false;
252b5132
RH
13496}
13497
aca88567
NC
13498/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
13499 DWARF debug sections. This is a target specific test. Note - we do not
13500 go through the whole including-target-headers-multiple-times route, (as
13501 we have already done with <elf/h8.h>) because this would become very
13502 messy and even then this function would have to contain target specific
13503 information (the names of the relocs instead of their numeric values).
13504 FIXME: This is not the correct way to solve this problem. The proper way
13505 is to have target specific reloc sizing and typing functions created by
13506 the reloc-macros.h header, in the same way that it already creates the
13507 reloc naming functions. */
13508
015dc7e1 13509static bool
dda8d76d 13510is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13511{
d347c9df 13512 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13513 switch (filedata->file_header.e_machine)
aca88567 13514 {
41e92641 13515 case EM_386:
22abe556 13516 case EM_IAMCU:
41e92641 13517 return reloc_type == 1; /* R_386_32. */
aca88567
NC
13518 case EM_68K:
13519 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
13520 case EM_860:
13521 return reloc_type == 1; /* R_860_32. */
13522 case EM_960:
13523 return reloc_type == 2; /* R_960_32. */
a06ea964 13524 case EM_AARCH64:
9282b95a
JW
13525 return (reloc_type == 258
13526 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
13527 case EM_BPF:
13528 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
13529 case EM_ADAPTEVA_EPIPHANY:
13530 return reloc_type == 3;
aca88567 13531 case EM_ALPHA:
137b6b5f 13532 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
13533 case EM_ARC:
13534 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
13535 case EM_ARC_COMPACT:
13536 case EM_ARC_COMPACT2:
13537 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
13538 case EM_ARM:
13539 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 13540 case EM_AVR_OLD:
aca88567
NC
13541 case EM_AVR:
13542 return reloc_type == 1;
13543 case EM_BLACKFIN:
13544 return reloc_type == 0x12; /* R_byte4_data. */
13545 case EM_CRIS:
13546 return reloc_type == 3; /* R_CRIS_32. */
13547 case EM_CR16:
13548 return reloc_type == 3; /* R_CR16_NUM32. */
13549 case EM_CRX:
13550 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
13551 case EM_CSKY:
13552 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
13553 case EM_CYGNUS_FRV:
13554 return reloc_type == 1;
41e92641
NC
13555 case EM_CYGNUS_D10V:
13556 case EM_D10V:
13557 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
13558 case EM_CYGNUS_D30V:
13559 case EM_D30V:
13560 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
13561 case EM_DLX:
13562 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
13563 case EM_CYGNUS_FR30:
13564 case EM_FR30:
13565 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
13566 case EM_FT32:
13567 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
13568 case EM_H8S:
13569 case EM_H8_300:
13570 case EM_H8_300H:
13571 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 13572 case EM_IA_64:
262cdac7
AM
13573 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
13574 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
13575 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
13576 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
13577 case EM_IP2K_OLD:
13578 case EM_IP2K:
13579 return reloc_type == 2; /* R_IP2K_32. */
13580 case EM_IQ2000:
13581 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
13582 case EM_LATTICEMICO32:
13583 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 13584 case EM_M32C_OLD:
aca88567
NC
13585 case EM_M32C:
13586 return reloc_type == 3; /* R_M32C_32. */
13587 case EM_M32R:
13588 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
13589 case EM_68HC11:
13590 case EM_68HC12:
13591 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 13592 case EM_S12Z:
2849d19f
JD
13593 return reloc_type == 7 || /* R_S12Z_EXT32 */
13594 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
13595 case EM_MCORE:
13596 return reloc_type == 1; /* R_MCORE_ADDR32. */
13597 case EM_CYGNUS_MEP:
13598 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
13599 case EM_METAG:
13600 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
13601 case EM_MICROBLAZE:
13602 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
13603 case EM_MIPS:
13604 return reloc_type == 2; /* R_MIPS_32. */
13605 case EM_MMIX:
13606 return reloc_type == 4; /* R_MMIX_32. */
13607 case EM_CYGNUS_MN10200:
13608 case EM_MN10200:
13609 return reloc_type == 1; /* R_MN10200_32. */
13610 case EM_CYGNUS_MN10300:
13611 case EM_MN10300:
13612 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
13613 case EM_MOXIE:
13614 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
13615 case EM_MSP430_OLD:
13616 case EM_MSP430:
13761a11 13617 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
13618 case EM_MT:
13619 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
13620 case EM_NDS32:
13621 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 13622 case EM_ALTERA_NIOS2:
36591ba1 13623 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
13624 case EM_NIOS32:
13625 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
13626 case EM_OR1K:
13627 return reloc_type == 1; /* R_OR1K_32. */
aca88567 13628 case EM_PARISC:
9abca702 13629 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 13630 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 13631 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
13632 case EM_PJ:
13633 case EM_PJ_OLD:
13634 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
13635 case EM_PPC64:
13636 return reloc_type == 1; /* R_PPC64_ADDR32. */
13637 case EM_PPC:
13638 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
13639 case EM_TI_PRU:
13640 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
13641 case EM_RISCV:
13642 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
13643 case EM_RL78:
13644 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
13645 case EM_RX:
13646 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
13647 case EM_S370:
13648 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
13649 case EM_S390_OLD:
13650 case EM_S390:
13651 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
13652 case EM_SCORE:
13653 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
13654 case EM_SH:
13655 return reloc_type == 1; /* R_SH_DIR32. */
13656 case EM_SPARC32PLUS:
13657 case EM_SPARCV9:
13658 case EM_SPARC:
13659 return reloc_type == 3 /* R_SPARC_32. */
13660 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
13661 case EM_SPU:
13662 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
13663 case EM_TI_C6000:
13664 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
13665 case EM_TILEGX:
13666 return reloc_type == 2; /* R_TILEGX_32. */
13667 case EM_TILEPRO:
13668 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
13669 case EM_CYGNUS_V850:
13670 case EM_V850:
13671 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
13672 case EM_V800:
13673 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
13674 case EM_VAX:
13675 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
13676 case EM_VISIUM:
13677 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
13678 case EM_WEBASSEMBLY:
13679 return reloc_type == 1; /* R_WASM32_32. */
aca88567 13680 case EM_X86_64:
8a9036a4 13681 case EM_L1OM:
7a9068fe 13682 case EM_K1OM:
aca88567 13683 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
13684 case EM_XC16X:
13685 case EM_C166:
13686 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
13687 case EM_XGATE:
13688 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
13689 case EM_XSTORMY16:
13690 return reloc_type == 1; /* R_XSTROMY16_32. */
13691 case EM_XTENSA_OLD:
13692 case EM_XTENSA:
13693 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
13694 case EM_Z80:
13695 return reloc_type == 6; /* R_Z80_32. */
aca88567 13696 default:
bee0ee85
NC
13697 {
13698 static unsigned int prev_warn = 0;
13699
13700 /* Avoid repeating the same warning multiple times. */
dda8d76d 13701 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 13702 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
13703 filedata->file_header.e_machine);
13704 prev_warn = filedata->file_header.e_machine;
015dc7e1 13705 return false;
bee0ee85 13706 }
aca88567
NC
13707 }
13708}
13709
13710/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13711 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
13712
015dc7e1 13713static bool
dda8d76d 13714is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13715{
dda8d76d 13716 switch (filedata->file_header.e_machine)
d347c9df 13717 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 13718 {
41e92641 13719 case EM_386:
22abe556 13720 case EM_IAMCU:
3e0873ac 13721 return reloc_type == 2; /* R_386_PC32. */
aca88567 13722 case EM_68K:
3e0873ac 13723 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
13724 case EM_AARCH64:
13725 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
13726 case EM_ADAPTEVA_EPIPHANY:
13727 return reloc_type == 6;
aca88567
NC
13728 case EM_ALPHA:
13729 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
13730 case EM_ARC_COMPACT:
13731 case EM_ARC_COMPACT2:
13732 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 13733 case EM_ARM:
3e0873ac 13734 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
13735 case EM_AVR_OLD:
13736 case EM_AVR:
13737 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
13738 case EM_MICROBLAZE:
13739 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
13740 case EM_OR1K:
13741 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 13742 case EM_PARISC:
85acf597 13743 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
13744 case EM_PPC:
13745 return reloc_type == 26; /* R_PPC_REL32. */
13746 case EM_PPC64:
3e0873ac 13747 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
13748 case EM_RISCV:
13749 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
13750 case EM_S390_OLD:
13751 case EM_S390:
3e0873ac 13752 return reloc_type == 5; /* R_390_PC32. */
aca88567 13753 case EM_SH:
3e0873ac 13754 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
13755 case EM_SPARC32PLUS:
13756 case EM_SPARCV9:
13757 case EM_SPARC:
3e0873ac 13758 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
13759 case EM_SPU:
13760 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
13761 case EM_TILEGX:
13762 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
13763 case EM_TILEPRO:
13764 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
13765 case EM_VISIUM:
13766 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 13767 case EM_X86_64:
8a9036a4 13768 case EM_L1OM:
7a9068fe 13769 case EM_K1OM:
3e0873ac 13770 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
13771 case EM_VAX:
13772 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
13773 case EM_XTENSA_OLD:
13774 case EM_XTENSA:
13775 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
13776 default:
13777 /* Do not abort or issue an error message here. Not all targets use
13778 pc-relative 32-bit relocs in their DWARF debug information and we
13779 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
13780 more helpful warning message will be generated by apply_relocations
13781 anyway, so just return. */
015dc7e1 13782 return false;
aca88567
NC
13783 }
13784}
13785
13786/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13787 a 64-bit absolute RELA relocation used in DWARF debug sections. */
13788
015dc7e1 13789static bool
dda8d76d 13790is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13791{
dda8d76d 13792 switch (filedata->file_header.e_machine)
aca88567 13793 {
a06ea964
NC
13794 case EM_AARCH64:
13795 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
13796 case EM_ALPHA:
13797 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 13798 case EM_IA_64:
262cdac7
AM
13799 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
13800 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
13801 case EM_PARISC:
13802 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
13803 case EM_PPC64:
13804 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
13805 case EM_RISCV:
13806 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
13807 case EM_SPARC32PLUS:
13808 case EM_SPARCV9:
13809 case EM_SPARC:
714da62f
NC
13810 return reloc_type == 32 /* R_SPARC_64. */
13811 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 13812 case EM_X86_64:
8a9036a4 13813 case EM_L1OM:
7a9068fe 13814 case EM_K1OM:
aca88567 13815 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
13816 case EM_S390_OLD:
13817 case EM_S390:
aa137e4d
NC
13818 return reloc_type == 22; /* R_S390_64. */
13819 case EM_TILEGX:
13820 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 13821 case EM_MIPS:
aa137e4d 13822 return reloc_type == 18; /* R_MIPS_64. */
aca88567 13823 default:
015dc7e1 13824 return false;
aca88567
NC
13825 }
13826}
13827
85acf597
RH
13828/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
13829 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
13830
015dc7e1 13831static bool
dda8d76d 13832is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 13833{
dda8d76d 13834 switch (filedata->file_header.e_machine)
85acf597 13835 {
a06ea964
NC
13836 case EM_AARCH64:
13837 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 13838 case EM_ALPHA:
aa137e4d 13839 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 13840 case EM_IA_64:
262cdac7
AM
13841 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
13842 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 13843 case EM_PARISC:
aa137e4d 13844 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 13845 case EM_PPC64:
aa137e4d 13846 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
13847 case EM_SPARC32PLUS:
13848 case EM_SPARCV9:
13849 case EM_SPARC:
aa137e4d 13850 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 13851 case EM_X86_64:
8a9036a4 13852 case EM_L1OM:
7a9068fe 13853 case EM_K1OM:
aa137e4d 13854 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
13855 case EM_S390_OLD:
13856 case EM_S390:
aa137e4d
NC
13857 return reloc_type == 23; /* R_S390_PC64. */
13858 case EM_TILEGX:
13859 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 13860 default:
015dc7e1 13861 return false;
85acf597
RH
13862 }
13863}
13864
4dc3c23d
AM
13865/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13866 a 24-bit absolute RELA relocation used in DWARF debug sections. */
13867
015dc7e1 13868static bool
dda8d76d 13869is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 13870{
dda8d76d 13871 switch (filedata->file_header.e_machine)
4dc3c23d
AM
13872 {
13873 case EM_CYGNUS_MN10200:
13874 case EM_MN10200:
13875 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
13876 case EM_FT32:
13877 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
13878 case EM_Z80:
13879 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 13880 default:
015dc7e1 13881 return false;
4dc3c23d
AM
13882 }
13883}
13884
aca88567
NC
13885/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13886 a 16-bit absolute RELA relocation used in DWARF debug sections. */
13887
015dc7e1 13888static bool
dda8d76d 13889is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 13890{
d347c9df 13891 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13892 switch (filedata->file_header.e_machine)
4b78141a 13893 {
886a2506
NC
13894 case EM_ARC:
13895 case EM_ARC_COMPACT:
13896 case EM_ARC_COMPACT2:
13897 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
13898 case EM_ADAPTEVA_EPIPHANY:
13899 return reloc_type == 5;
aca88567
NC
13900 case EM_AVR_OLD:
13901 case EM_AVR:
13902 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
13903 case EM_CYGNUS_D10V:
13904 case EM_D10V:
13905 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
13906 case EM_FT32:
13907 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
13908 case EM_H8S:
13909 case EM_H8_300:
13910 case EM_H8_300H:
aca88567
NC
13911 return reloc_type == R_H8_DIR16;
13912 case EM_IP2K_OLD:
13913 case EM_IP2K:
13914 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 13915 case EM_M32C_OLD:
f4236fe4
DD
13916 case EM_M32C:
13917 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
13918 case EM_CYGNUS_MN10200:
13919 case EM_MN10200:
13920 return reloc_type == 2; /* R_MN10200_16. */
13921 case EM_CYGNUS_MN10300:
13922 case EM_MN10300:
13923 return reloc_type == 2; /* R_MN10300_16. */
aca88567 13924 case EM_MSP430:
dda8d76d 13925 if (uses_msp430x_relocs (filedata))
13761a11 13926 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 13927 /* Fall through. */
78c8d46c 13928 case EM_MSP430_OLD:
aca88567 13929 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
13930 case EM_NDS32:
13931 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 13932 case EM_ALTERA_NIOS2:
36591ba1 13933 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
13934 case EM_NIOS32:
13935 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
13936 case EM_OR1K:
13937 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
13938 case EM_RISCV:
13939 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
13940 case EM_TI_PRU:
13941 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
13942 case EM_TI_C6000:
13943 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
13944 case EM_VISIUM:
13945 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
13946 case EM_XC16X:
13947 case EM_C166:
13948 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
13949 case EM_XGATE:
13950 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
13951 case EM_Z80:
13952 return reloc_type == 4; /* R_Z80_16. */
4b78141a 13953 default:
015dc7e1 13954 return false;
4b78141a
NC
13955 }
13956}
13957
39e07931
AS
13958/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13959 a 8-bit absolute RELA relocation used in DWARF debug sections. */
13960
015dc7e1 13961static bool
39e07931
AS
13962is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13963{
13964 switch (filedata->file_header.e_machine)
13965 {
13966 case EM_RISCV:
13967 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
13968 case EM_Z80:
13969 return reloc_type == 1; /* R_Z80_8. */
39e07931 13970 default:
015dc7e1 13971 return false;
39e07931
AS
13972 }
13973}
13974
13975/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13976 a 6-bit absolute RELA relocation used in DWARF debug sections. */
13977
015dc7e1 13978static bool
39e07931
AS
13979is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13980{
13981 switch (filedata->file_header.e_machine)
13982 {
13983 case EM_RISCV:
13984 return reloc_type == 53; /* R_RISCV_SET6. */
13985 default:
015dc7e1 13986 return false;
39e07931
AS
13987 }
13988}
13989
03336641
JW
13990/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13991 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
13992
015dc7e1 13993static bool
03336641
JW
13994is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13995{
13996 /* Please keep this table alpha-sorted for ease of visual lookup. */
13997 switch (filedata->file_header.e_machine)
13998 {
13999 case EM_RISCV:
14000 return reloc_type == 35; /* R_RISCV_ADD32. */
14001 default:
015dc7e1 14002 return false;
03336641
JW
14003 }
14004}
14005
14006/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14007 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14008
015dc7e1 14009static bool
03336641
JW
14010is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14011{
14012 /* Please keep this table alpha-sorted for ease of visual lookup. */
14013 switch (filedata->file_header.e_machine)
14014 {
14015 case EM_RISCV:
14016 return reloc_type == 39; /* R_RISCV_SUB32. */
14017 default:
015dc7e1 14018 return false;
03336641
JW
14019 }
14020}
14021
14022/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14023 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14024
015dc7e1 14025static bool
03336641
JW
14026is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14027{
14028 /* Please keep this table alpha-sorted for ease of visual lookup. */
14029 switch (filedata->file_header.e_machine)
14030 {
14031 case EM_RISCV:
14032 return reloc_type == 36; /* R_RISCV_ADD64. */
14033 default:
015dc7e1 14034 return false;
03336641
JW
14035 }
14036}
14037
14038/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14039 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14040
015dc7e1 14041static bool
03336641
JW
14042is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14043{
14044 /* Please keep this table alpha-sorted for ease of visual lookup. */
14045 switch (filedata->file_header.e_machine)
14046 {
14047 case EM_RISCV:
14048 return reloc_type == 40; /* R_RISCV_SUB64. */
14049 default:
015dc7e1 14050 return false;
03336641
JW
14051 }
14052}
14053
14054/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14055 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14056
015dc7e1 14057static bool
03336641
JW
14058is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14059{
14060 /* Please keep this table alpha-sorted for ease of visual lookup. */
14061 switch (filedata->file_header.e_machine)
14062 {
14063 case EM_RISCV:
14064 return reloc_type == 34; /* R_RISCV_ADD16. */
14065 default:
015dc7e1 14066 return false;
03336641
JW
14067 }
14068}
14069
14070/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14071 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14072
015dc7e1 14073static bool
03336641
JW
14074is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14075{
14076 /* Please keep this table alpha-sorted for ease of visual lookup. */
14077 switch (filedata->file_header.e_machine)
14078 {
14079 case EM_RISCV:
14080 return reloc_type == 38; /* R_RISCV_SUB16. */
14081 default:
015dc7e1 14082 return false;
03336641
JW
14083 }
14084}
14085
14086/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14087 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14088
015dc7e1 14089static bool
03336641
JW
14090is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14091{
14092 /* Please keep this table alpha-sorted for ease of visual lookup. */
14093 switch (filedata->file_header.e_machine)
14094 {
14095 case EM_RISCV:
14096 return reloc_type == 33; /* R_RISCV_ADD8. */
14097 default:
015dc7e1 14098 return false;
03336641
JW
14099 }
14100}
14101
14102/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14103 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14104
015dc7e1 14105static bool
03336641
JW
14106is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14107{
14108 /* Please keep this table alpha-sorted for ease of visual lookup. */
14109 switch (filedata->file_header.e_machine)
14110 {
14111 case EM_RISCV:
14112 return reloc_type == 37; /* R_RISCV_SUB8. */
14113 default:
015dc7e1 14114 return false;
03336641
JW
14115 }
14116}
14117
39e07931
AS
14118/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14119 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14120
015dc7e1 14121static bool
39e07931
AS
14122is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14123{
14124 switch (filedata->file_header.e_machine)
14125 {
14126 case EM_RISCV:
14127 return reloc_type == 52; /* R_RISCV_SUB6. */
14128 default:
015dc7e1 14129 return false;
39e07931
AS
14130 }
14131}
14132
2a7b2e88
JK
14133/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14134 relocation entries (possibly formerly used for SHT_GROUP sections). */
14135
015dc7e1 14136static bool
dda8d76d 14137is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14138{
dda8d76d 14139 switch (filedata->file_header.e_machine)
2a7b2e88 14140 {
cb8f3167 14141 case EM_386: /* R_386_NONE. */
d347c9df 14142 case EM_68K: /* R_68K_NONE. */
cfb8c092 14143 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14144 case EM_ALPHA: /* R_ALPHA_NONE. */
14145 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14146 case EM_ARC: /* R_ARC_NONE. */
886a2506 14147 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14148 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14149 case EM_ARM: /* R_ARM_NONE. */
d347c9df 14150 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 14151 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14152 case EM_FT32: /* R_FT32_NONE. */
14153 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14154 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14155 case EM_L1OM: /* R_X86_64_NONE. */
14156 case EM_M32R: /* R_M32R_NONE. */
14157 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14158 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14159 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14160 case EM_NIOS32: /* R_NIOS_NONE. */
14161 case EM_OR1K: /* R_OR1K_NONE. */
14162 case EM_PARISC: /* R_PARISC_NONE. */
14163 case EM_PPC64: /* R_PPC64_NONE. */
14164 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14165 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14166 case EM_S390: /* R_390_NONE. */
14167 case EM_S390_OLD:
14168 case EM_SH: /* R_SH_NONE. */
14169 case EM_SPARC32PLUS:
14170 case EM_SPARC: /* R_SPARC_NONE. */
14171 case EM_SPARCV9:
aa137e4d
NC
14172 case EM_TILEGX: /* R_TILEGX_NONE. */
14173 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14174 case EM_TI_C6000:/* R_C6000_NONE. */
14175 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 14176 case EM_XC16X:
6655dba2 14177 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14178 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14179 return reloc_type == 0;
d347c9df 14180
a06ea964
NC
14181 case EM_AARCH64:
14182 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14183 case EM_AVR_OLD:
14184 case EM_AVR:
14185 return (reloc_type == 0 /* R_AVR_NONE. */
14186 || reloc_type == 30 /* R_AVR_DIFF8. */
14187 || reloc_type == 31 /* R_AVR_DIFF16. */
14188 || reloc_type == 32 /* R_AVR_DIFF32. */);
14189 case EM_METAG:
14190 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
14191 case EM_NDS32:
14192 return (reloc_type == 0 /* R_XTENSA_NONE. */
14193 || reloc_type == 204 /* R_NDS32_DIFF8. */
14194 || reloc_type == 205 /* R_NDS32_DIFF16. */
14195 || reloc_type == 206 /* R_NDS32_DIFF32. */
14196 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
14197 case EM_TI_PRU:
14198 return (reloc_type == 0 /* R_PRU_NONE. */
14199 || reloc_type == 65 /* R_PRU_DIFF8. */
14200 || reloc_type == 66 /* R_PRU_DIFF16. */
14201 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14202 case EM_XTENSA_OLD:
14203 case EM_XTENSA:
4dc3c23d
AM
14204 return (reloc_type == 0 /* R_XTENSA_NONE. */
14205 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14206 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14207 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14208 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14209 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14210 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14211 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14212 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14213 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14214 }
015dc7e1 14215 return false;
2a7b2e88
JK
14216}
14217
d1c4b12b
NC
14218/* Returns TRUE if there is a relocation against
14219 section NAME at OFFSET bytes. */
14220
015dc7e1 14221bool
d1c4b12b
NC
14222reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14223{
14224 Elf_Internal_Rela * relocs;
14225 Elf_Internal_Rela * rp;
14226
14227 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14228 return false;
d1c4b12b
NC
14229
14230 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14231
14232 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14233 if (rp->r_offset == offset)
015dc7e1 14234 return true;
d1c4b12b 14235
015dc7e1 14236 return false;
d1c4b12b
NC
14237}
14238
cf13d699 14239/* Apply relocations to a section.
32ec8896
NC
14240 Returns TRUE upon success, FALSE otherwise.
14241 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14242 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14243 will be set to the number of relocs loaded.
14244
cf13d699 14245 Note: So far support has been added only for those relocations
32ec8896
NC
14246 which can be found in debug sections. FIXME: Add support for
14247 more relocations ? */
1b315056 14248
015dc7e1 14249static bool
dda8d76d 14250apply_relocations (Filedata * filedata,
d1c4b12b
NC
14251 const Elf_Internal_Shdr * section,
14252 unsigned char * start,
14253 bfd_size_type size,
1449284b 14254 void ** relocs_return,
d1c4b12b 14255 unsigned long * num_relocs_return)
1b315056 14256{
cf13d699 14257 Elf_Internal_Shdr * relsec;
0d2a7a93 14258 unsigned char * end = start + size;
cb8f3167 14259
d1c4b12b
NC
14260 if (relocs_return != NULL)
14261 {
14262 * (Elf_Internal_Rela **) relocs_return = NULL;
14263 * num_relocs_return = 0;
14264 }
14265
dda8d76d 14266 if (filedata->file_header.e_type != ET_REL)
32ec8896 14267 /* No relocs to apply. */
015dc7e1 14268 return true;
1b315056 14269
cf13d699 14270 /* Find the reloc section associated with the section. */
dda8d76d
NC
14271 for (relsec = filedata->section_headers;
14272 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14273 ++relsec)
252b5132 14274 {
015dc7e1 14275 bool is_rela;
41e92641 14276 unsigned long num_relocs;
2cf0635d
NC
14277 Elf_Internal_Rela * relocs;
14278 Elf_Internal_Rela * rp;
14279 Elf_Internal_Shdr * symsec;
14280 Elf_Internal_Sym * symtab;
ba5cdace 14281 unsigned long num_syms;
2cf0635d 14282 Elf_Internal_Sym * sym;
252b5132 14283
41e92641 14284 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14285 || relsec->sh_info >= filedata->file_header.e_shnum
14286 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14287 || relsec->sh_size == 0
dda8d76d 14288 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14289 continue;
428409d5 14290
a788aedd
AM
14291 symsec = filedata->section_headers + relsec->sh_link;
14292 if (symsec->sh_type != SHT_SYMTAB
14293 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14294 return false;
a788aedd 14295
41e92641
NC
14296 is_rela = relsec->sh_type == SHT_RELA;
14297
14298 if (is_rela)
14299 {
dda8d76d 14300 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14301 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14302 return false;
41e92641
NC
14303 }
14304 else
14305 {
dda8d76d 14306 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14307 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14308 return false;
41e92641
NC
14309 }
14310
14311 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14312 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14313 is_rela = false;
428409d5 14314
4de91c10 14315 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14316
41e92641 14317 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14318 {
015dc7e1
AM
14319 bfd_vma addend;
14320 unsigned int reloc_type;
14321 unsigned int reloc_size;
14322 bool reloc_inplace = false;
14323 bool reloc_subtract = false;
14324 unsigned char *rloc;
14325 unsigned long sym_index;
4b78141a 14326
dda8d76d 14327 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14328
dda8d76d 14329 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14330 continue;
dda8d76d 14331 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14332 continue;
dda8d76d
NC
14333 else if (is_32bit_abs_reloc (filedata, reloc_type)
14334 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14335 reloc_size = 4;
dda8d76d
NC
14336 else if (is_64bit_abs_reloc (filedata, reloc_type)
14337 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14338 reloc_size = 8;
dda8d76d 14339 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14340 reloc_size = 3;
dda8d76d 14341 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14342 reloc_size = 2;
39e07931
AS
14343 else if (is_8bit_abs_reloc (filedata, reloc_type)
14344 || is_6bit_abs_reloc (filedata, reloc_type))
14345 reloc_size = 1;
03336641
JW
14346 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14347 reloc_type))
14348 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14349 {
14350 reloc_size = 4;
015dc7e1 14351 reloc_inplace = true;
03336641
JW
14352 }
14353 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14354 reloc_type))
14355 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14356 {
14357 reloc_size = 8;
015dc7e1 14358 reloc_inplace = true;
03336641
JW
14359 }
14360 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14361 reloc_type))
14362 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14363 {
14364 reloc_size = 2;
015dc7e1 14365 reloc_inplace = true;
03336641
JW
14366 }
14367 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14368 reloc_type))
14369 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14370 {
14371 reloc_size = 1;
015dc7e1 14372 reloc_inplace = true;
03336641 14373 }
39e07931
AS
14374 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
14375 reloc_type)))
14376 {
14377 reloc_size = 1;
015dc7e1 14378 reloc_inplace = true;
39e07931 14379 }
aca88567 14380 else
4b78141a 14381 {
bee0ee85 14382 static unsigned int prev_reloc = 0;
dda8d76d 14383
bee0ee85
NC
14384 if (reloc_type != prev_reloc)
14385 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 14386 reloc_type, printable_section_name (filedata, section));
bee0ee85 14387 prev_reloc = reloc_type;
4b78141a
NC
14388 continue;
14389 }
103f02d3 14390
91d6fa6a 14391 rloc = start + rp->r_offset;
75802ccb 14392 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
14393 {
14394 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
14395 (unsigned long) rp->r_offset,
dda8d76d 14396 printable_section_name (filedata, section));
700dd8b7
L
14397 continue;
14398 }
103f02d3 14399
ba5cdace
NC
14400 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
14401 if (sym_index >= num_syms)
14402 {
14403 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 14404 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
14405 continue;
14406 }
14407 sym = symtab + sym_index;
41e92641
NC
14408
14409 /* If the reloc has a symbol associated with it,
55f25fc3
L
14410 make sure that it is of an appropriate type.
14411
14412 Relocations against symbols without type can happen.
14413 Gcc -feliminate-dwarf2-dups may generate symbols
14414 without type for debug info.
14415
14416 Icc generates relocations against function symbols
14417 instead of local labels.
14418
14419 Relocations against object symbols can happen, eg when
14420 referencing a global array. For an example of this see
14421 the _clz.o binary in libgcc.a. */
aca88567 14422 if (sym != symtab
b8871f35 14423 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 14424 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 14425 {
d3a49aa8 14426 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
14427 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
14428 printable_section_name (filedata, relsec),
d3a49aa8 14429 (long int)(rp - relocs));
aca88567 14430 continue;
5b18a4bc 14431 }
252b5132 14432
4dc3c23d
AM
14433 addend = 0;
14434 if (is_rela)
14435 addend += rp->r_addend;
c47320c3
AM
14436 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
14437 partial_inplace. */
4dc3c23d 14438 if (!is_rela
dda8d76d 14439 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 14440 && reloc_type == 1)
dda8d76d
NC
14441 || ((filedata->file_header.e_machine == EM_PJ
14442 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 14443 && reloc_type == 1)
dda8d76d
NC
14444 || ((filedata->file_header.e_machine == EM_D30V
14445 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
14446 && reloc_type == 12)
14447 || reloc_inplace)
39e07931
AS
14448 {
14449 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
14450 addend += byte_get (rloc, reloc_size) & 0x3f;
14451 else
14452 addend += byte_get (rloc, reloc_size);
14453 }
cb8f3167 14454
dda8d76d
NC
14455 if (is_32bit_pcrel_reloc (filedata, reloc_type)
14456 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
14457 {
14458 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 14459 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 14460 addend -= 8;
91d6fa6a 14461 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
14462 reloc_size);
14463 }
39e07931
AS
14464 else if (is_6bit_abs_reloc (filedata, reloc_type)
14465 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
14466 {
14467 if (reloc_subtract)
14468 addend -= sym->st_value;
14469 else
14470 addend += sym->st_value;
14471 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
14472 byte_put (rloc, addend, reloc_size);
14473 }
03336641
JW
14474 else if (reloc_subtract)
14475 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 14476 else
91d6fa6a 14477 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 14478 }
252b5132 14479
5b18a4bc 14480 free (symtab);
f84ce13b
NC
14481 /* Let the target specific reloc processing code know that
14482 we have finished with these relocs. */
dda8d76d 14483 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
14484
14485 if (relocs_return)
14486 {
14487 * (Elf_Internal_Rela **) relocs_return = relocs;
14488 * num_relocs_return = num_relocs;
14489 }
14490 else
14491 free (relocs);
14492
5b18a4bc
NC
14493 break;
14494 }
32ec8896 14495
015dc7e1 14496 return true;
5b18a4bc 14497}
103f02d3 14498
cf13d699 14499#ifdef SUPPORT_DISASSEMBLY
015dc7e1 14500static bool
dda8d76d 14501disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14502{
dda8d76d 14503 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 14504
74e1a04b 14505 /* FIXME: XXX -- to be done --- XXX */
cf13d699 14506
015dc7e1 14507 return true;
cf13d699
NC
14508}
14509#endif
14510
14511/* Reads in the contents of SECTION from FILE, returning a pointer
14512 to a malloc'ed buffer or NULL if something went wrong. */
14513
14514static char *
dda8d76d 14515get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14516{
dda8d76d 14517 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
14518
14519 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
14520 {
c6b78c96 14521 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 14522 printable_section_name (filedata, section));
cf13d699
NC
14523 return NULL;
14524 }
14525
dda8d76d 14526 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 14527 _("section contents"));
cf13d699
NC
14528}
14529
0e602686
NC
14530/* Uncompresses a section that was compressed using zlib, in place. */
14531
015dc7e1 14532static bool
dda8d76d
NC
14533uncompress_section_contents (unsigned char ** buffer,
14534 dwarf_size_type uncompressed_size,
14535 dwarf_size_type * size)
0e602686
NC
14536{
14537 dwarf_size_type compressed_size = *size;
14538 unsigned char * compressed_buffer = *buffer;
14539 unsigned char * uncompressed_buffer;
14540 z_stream strm;
14541 int rc;
14542
14543 /* It is possible the section consists of several compressed
14544 buffers concatenated together, so we uncompress in a loop. */
14545 /* PR 18313: The state field in the z_stream structure is supposed
14546 to be invisible to the user (ie us), but some compilers will
14547 still complain about it being used without initialisation. So
14548 we first zero the entire z_stream structure and then set the fields
14549 that we need. */
14550 memset (& strm, 0, sizeof strm);
14551 strm.avail_in = compressed_size;
14552 strm.next_in = (Bytef *) compressed_buffer;
14553 strm.avail_out = uncompressed_size;
14554 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
14555
14556 rc = inflateInit (& strm);
14557 while (strm.avail_in > 0)
14558 {
14559 if (rc != Z_OK)
3624a6c1 14560 break;
0e602686
NC
14561 strm.next_out = ((Bytef *) uncompressed_buffer
14562 + (uncompressed_size - strm.avail_out));
14563 rc = inflate (&strm, Z_FINISH);
14564 if (rc != Z_STREAM_END)
3624a6c1 14565 break;
0e602686
NC
14566 rc = inflateReset (& strm);
14567 }
ad92f33d
AM
14568 if (inflateEnd (& strm) != Z_OK
14569 || rc != Z_OK
0e602686
NC
14570 || strm.avail_out != 0)
14571 goto fail;
14572
14573 *buffer = uncompressed_buffer;
14574 *size = uncompressed_size;
015dc7e1 14575 return true;
0e602686
NC
14576
14577 fail:
14578 free (uncompressed_buffer);
14579 /* Indicate decompression failure. */
14580 *buffer = NULL;
015dc7e1 14581 return false;
0e602686 14582}
dd24e3da 14583
015dc7e1 14584static bool
dda8d76d 14585dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14586{
015dc7e1
AM
14587 Elf_Internal_Shdr *relsec;
14588 bfd_size_type num_bytes;
14589 unsigned char *data;
14590 unsigned char *end;
14591 unsigned char *real_start;
14592 unsigned char *start;
14593 bool some_strings_shown;
cf13d699 14594
dda8d76d 14595 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14596 if (start == NULL)
c6b78c96 14597 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 14598 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 14599
0e602686 14600 num_bytes = section->sh_size;
cf13d699 14601
835f2fae
NC
14602 if (filedata->is_separate)
14603 printf (_("\nString dump of section '%s' in linked file %s:\n"),
14604 printable_section_name (filedata, section),
14605 filedata->file_name);
14606 else
14607 printf (_("\nString dump of section '%s':\n"),
14608 printable_section_name (filedata, section));
cf13d699 14609
0e602686
NC
14610 if (decompress_dumps)
14611 {
14612 dwarf_size_type new_size = num_bytes;
14613 dwarf_size_type uncompressed_size = 0;
14614
14615 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14616 {
14617 Elf_Internal_Chdr chdr;
14618 unsigned int compression_header_size
ebdf1ebf
NC
14619 = get_compression_header (& chdr, (unsigned char *) start,
14620 num_bytes);
5844b465
NC
14621 if (compression_header_size == 0)
14622 /* An error message will have already been generated
14623 by get_compression_header. */
14624 goto error_out;
0e602686 14625
813dabb9 14626 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14627 {
813dabb9 14628 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14629 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14630 goto error_out;
813dabb9 14631 }
813dabb9
L
14632 uncompressed_size = chdr.ch_size;
14633 start += compression_header_size;
14634 new_size -= compression_header_size;
0e602686
NC
14635 }
14636 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14637 {
14638 /* Read the zlib header. In this case, it should be "ZLIB"
14639 followed by the uncompressed section size, 8 bytes in
14640 big-endian order. */
14641 uncompressed_size = start[4]; uncompressed_size <<= 8;
14642 uncompressed_size += start[5]; uncompressed_size <<= 8;
14643 uncompressed_size += start[6]; uncompressed_size <<= 8;
14644 uncompressed_size += start[7]; uncompressed_size <<= 8;
14645 uncompressed_size += start[8]; uncompressed_size <<= 8;
14646 uncompressed_size += start[9]; uncompressed_size <<= 8;
14647 uncompressed_size += start[10]; uncompressed_size <<= 8;
14648 uncompressed_size += start[11];
14649 start += 12;
14650 new_size -= 12;
14651 }
14652
1835f746
NC
14653 if (uncompressed_size)
14654 {
14655 if (uncompress_section_contents (& start,
14656 uncompressed_size, & new_size))
14657 num_bytes = new_size;
14658 else
14659 {
14660 error (_("Unable to decompress section %s\n"),
dda8d76d 14661 printable_section_name (filedata, section));
f761cb13 14662 goto error_out;
1835f746
NC
14663 }
14664 }
bc303e5d
NC
14665 else
14666 start = real_start;
0e602686 14667 }
fd8008d8 14668
cf13d699
NC
14669 /* If the section being dumped has relocations against it the user might
14670 be expecting these relocations to have been applied. Check for this
14671 case and issue a warning message in order to avoid confusion.
14672 FIXME: Maybe we ought to have an option that dumps a section with
14673 relocs applied ? */
dda8d76d
NC
14674 for (relsec = filedata->section_headers;
14675 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14676 ++relsec)
14677 {
14678 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14679 || relsec->sh_info >= filedata->file_header.e_shnum
14680 || filedata->section_headers + relsec->sh_info != section
cf13d699 14681 || relsec->sh_size == 0
dda8d76d 14682 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14683 continue;
14684
14685 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14686 break;
14687 }
14688
cf13d699
NC
14689 data = start;
14690 end = start + num_bytes;
015dc7e1 14691 some_strings_shown = false;
cf13d699 14692
ba3265d0
NC
14693#ifdef HAVE_MBSTATE_T
14694 mbstate_t state;
14695 /* Initialise the multibyte conversion state. */
14696 memset (& state, 0, sizeof (state));
14697#endif
14698
015dc7e1 14699 bool continuing = false;
ba3265d0 14700
cf13d699
NC
14701 while (data < end)
14702 {
14703 while (!ISPRINT (* data))
14704 if (++ data >= end)
14705 break;
14706
14707 if (data < end)
14708 {
071436c6
NC
14709 size_t maxlen = end - data;
14710
ba3265d0
NC
14711 if (continuing)
14712 {
14713 printf (" ");
015dc7e1 14714 continuing = false;
ba3265d0
NC
14715 }
14716 else
14717 {
d1ce973e 14718 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
14719 }
14720
4082ef84
NC
14721 if (maxlen > 0)
14722 {
f3da8a96 14723 char c = 0;
ba3265d0
NC
14724
14725 while (maxlen)
14726 {
14727 c = *data++;
14728
14729 if (c == 0)
14730 break;
14731
14732 /* PR 25543: Treat new-lines as string-ending characters. */
14733 if (c == '\n')
14734 {
14735 printf ("\\n\n");
14736 if (*data != 0)
015dc7e1 14737 continuing = true;
ba3265d0
NC
14738 break;
14739 }
14740
14741 /* Do not print control characters directly as they can affect terminal
14742 settings. Such characters usually appear in the names generated
14743 by the assembler for local labels. */
14744 if (ISCNTRL (c))
14745 {
14746 printf ("^%c", c + 0x40);
14747 }
14748 else if (ISPRINT (c))
14749 {
14750 putchar (c);
14751 }
14752 else
14753 {
14754 size_t n;
14755#ifdef HAVE_MBSTATE_T
14756 wchar_t w;
14757#endif
14758 /* Let printf do the hard work of displaying multibyte characters. */
14759 printf ("%.1s", data - 1);
14760#ifdef HAVE_MBSTATE_T
14761 /* Try to find out how many bytes made up the character that was
14762 just printed. Advance the symbol pointer past the bytes that
14763 were displayed. */
14764 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
14765#else
14766 n = 1;
14767#endif
14768 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
14769 data += (n - 1);
14770 }
14771 }
14772
14773 if (c != '\n')
14774 putchar ('\n');
4082ef84
NC
14775 }
14776 else
14777 {
14778 printf (_("<corrupt>\n"));
14779 data = end;
14780 }
015dc7e1 14781 some_strings_shown = true;
cf13d699
NC
14782 }
14783 }
14784
14785 if (! some_strings_shown)
14786 printf (_(" No strings found in this section."));
14787
0e602686 14788 free (real_start);
cf13d699
NC
14789
14790 putchar ('\n');
015dc7e1 14791 return true;
f761cb13
AM
14792
14793error_out:
14794 free (real_start);
015dc7e1 14795 return false;
cf13d699
NC
14796}
14797
015dc7e1
AM
14798static bool
14799dump_section_as_bytes (Elf_Internal_Shdr *section,
14800 Filedata *filedata,
14801 bool relocate)
cf13d699
NC
14802{
14803 Elf_Internal_Shdr * relsec;
0e602686
NC
14804 bfd_size_type bytes;
14805 bfd_size_type section_size;
14806 bfd_vma addr;
14807 unsigned char * data;
14808 unsigned char * real_start;
14809 unsigned char * start;
14810
dda8d76d 14811 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14812 if (start == NULL)
c6b78c96 14813 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 14814 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 14815
0e602686 14816 section_size = section->sh_size;
cf13d699 14817
835f2fae
NC
14818 if (filedata->is_separate)
14819 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
14820 printable_section_name (filedata, section),
14821 filedata->file_name);
14822 else
14823 printf (_("\nHex dump of section '%s':\n"),
14824 printable_section_name (filedata, section));
cf13d699 14825
0e602686
NC
14826 if (decompress_dumps)
14827 {
14828 dwarf_size_type new_size = section_size;
14829 dwarf_size_type uncompressed_size = 0;
14830
14831 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14832 {
14833 Elf_Internal_Chdr chdr;
14834 unsigned int compression_header_size
ebdf1ebf 14835 = get_compression_header (& chdr, start, section_size);
0e602686 14836
5844b465
NC
14837 if (compression_header_size == 0)
14838 /* An error message will have already been generated
14839 by get_compression_header. */
14840 goto error_out;
14841
813dabb9 14842 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14843 {
813dabb9 14844 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14845 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14846 goto error_out;
0e602686 14847 }
813dabb9
L
14848 uncompressed_size = chdr.ch_size;
14849 start += compression_header_size;
14850 new_size -= compression_header_size;
0e602686
NC
14851 }
14852 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14853 {
14854 /* Read the zlib header. In this case, it should be "ZLIB"
14855 followed by the uncompressed section size, 8 bytes in
14856 big-endian order. */
14857 uncompressed_size = start[4]; uncompressed_size <<= 8;
14858 uncompressed_size += start[5]; uncompressed_size <<= 8;
14859 uncompressed_size += start[6]; uncompressed_size <<= 8;
14860 uncompressed_size += start[7]; uncompressed_size <<= 8;
14861 uncompressed_size += start[8]; uncompressed_size <<= 8;
14862 uncompressed_size += start[9]; uncompressed_size <<= 8;
14863 uncompressed_size += start[10]; uncompressed_size <<= 8;
14864 uncompressed_size += start[11];
14865 start += 12;
14866 new_size -= 12;
14867 }
14868
f055032e
NC
14869 if (uncompressed_size)
14870 {
14871 if (uncompress_section_contents (& start, uncompressed_size,
14872 & new_size))
bc303e5d
NC
14873 {
14874 section_size = new_size;
14875 }
f055032e
NC
14876 else
14877 {
14878 error (_("Unable to decompress section %s\n"),
dda8d76d 14879 printable_section_name (filedata, section));
bc303e5d 14880 /* FIXME: Print the section anyway ? */
f761cb13 14881 goto error_out;
f055032e
NC
14882 }
14883 }
bc303e5d
NC
14884 else
14885 start = real_start;
0e602686 14886 }
14ae95f2 14887
cf13d699
NC
14888 if (relocate)
14889 {
dda8d76d 14890 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 14891 goto error_out;
cf13d699
NC
14892 }
14893 else
14894 {
14895 /* If the section being dumped has relocations against it the user might
14896 be expecting these relocations to have been applied. Check for this
14897 case and issue a warning message in order to avoid confusion.
14898 FIXME: Maybe we ought to have an option that dumps a section with
14899 relocs applied ? */
dda8d76d
NC
14900 for (relsec = filedata->section_headers;
14901 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14902 ++relsec)
14903 {
14904 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14905 || relsec->sh_info >= filedata->file_header.e_shnum
14906 || filedata->section_headers + relsec->sh_info != section
cf13d699 14907 || relsec->sh_size == 0
dda8d76d 14908 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14909 continue;
14910
14911 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14912 break;
14913 }
14914 }
14915
14916 addr = section->sh_addr;
0e602686 14917 bytes = section_size;
cf13d699
NC
14918 data = start;
14919
14920 while (bytes)
14921 {
14922 int j;
14923 int k;
14924 int lbytes;
14925
14926 lbytes = (bytes > 16 ? 16 : bytes);
14927
14928 printf (" 0x%8.8lx ", (unsigned long) addr);
14929
14930 for (j = 0; j < 16; j++)
14931 {
14932 if (j < lbytes)
14933 printf ("%2.2x", data[j]);
14934 else
14935 printf (" ");
14936
14937 if ((j & 3) == 3)
14938 printf (" ");
14939 }
14940
14941 for (j = 0; j < lbytes; j++)
14942 {
14943 k = data[j];
14944 if (k >= ' ' && k < 0x7f)
14945 printf ("%c", k);
14946 else
14947 printf (".");
14948 }
14949
14950 putchar ('\n');
14951
14952 data += lbytes;
14953 addr += lbytes;
14954 bytes -= lbytes;
14955 }
14956
0e602686 14957 free (real_start);
cf13d699
NC
14958
14959 putchar ('\n');
015dc7e1 14960 return true;
f761cb13
AM
14961
14962 error_out:
14963 free (real_start);
015dc7e1 14964 return false;
cf13d699
NC
14965}
14966
094e34f2 14967#ifdef ENABLE_LIBCTF
7d9813f1
NA
14968static ctf_sect_t *
14969shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
14970{
b9e920ec 14971 buf->cts_name = SECTION_NAME_PRINT (shdr);
7d9813f1
NA
14972 buf->cts_size = shdr->sh_size;
14973 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
14974
14975 return buf;
14976}
14977
14978/* Formatting callback function passed to ctf_dump. Returns either the pointer
14979 it is passed, or a pointer to newly-allocated storage, in which case
14980 dump_ctf() will free it when it no longer needs it. */
14981
2f6ecaed
NA
14982static char *
14983dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14984 char *s, void *arg)
7d9813f1 14985{
3e50a591 14986 const char *blanks = arg;
7d9813f1
NA
14987 char *new_s;
14988
3e50a591 14989 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
14990 return s;
14991 return new_s;
14992}
14993
926c9e76
NA
14994/* Dump CTF errors/warnings. */
14995static void
139633c3 14996dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
14997{
14998 ctf_next_t *it = NULL;
14999 char *errtext;
15000 int is_warning;
15001 int err;
15002
15003 /* Dump accumulated errors and warnings. */
15004 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15005 {
5e9b84f7 15006 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15007 errtext);
15008 free (errtext);
15009 }
15010 if (err != ECTF_NEXT_END)
15011 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15012}
15013
2f6ecaed
NA
15014/* Dump one CTF archive member. */
15015
15016static int
139633c3 15017dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
2f6ecaed 15018{
139633c3 15019 ctf_dict_t *parent = (ctf_dict_t *) arg;
2f6ecaed
NA
15020 const char *things[] = {"Header", "Labels", "Data objects",
15021 "Function objects", "Variables", "Types", "Strings",
15022 ""};
15023 const char **thing;
15024 size_t i;
8b37e7b6 15025 int err = 0;
2f6ecaed
NA
15026
15027 /* Only print out the name of non-default-named archive members.
15028 The name .ctf appears everywhere, even for things that aren't
15029 really archives, so printing it out is liable to be confusing.
15030
15031 The parent, if there is one, is the default-owned archive member:
15032 avoid importing it into itself. (This does no harm, but looks
15033 confusing.) */
15034
15035 if (strcmp (name, ".ctf") != 0)
15036 {
15037 printf (_("\nCTF archive member: %s:\n"), name);
15038 ctf_import (ctf, parent);
15039 }
15040
15041 for (i = 0, thing = things; *thing[0]; thing++, i++)
15042 {
15043 ctf_dump_state_t *s = NULL;
15044 char *item;
15045
15046 printf ("\n %s:\n", *thing);
15047 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15048 (void *) " ")) != NULL)
15049 {
15050 printf ("%s\n", item);
15051 free (item);
15052 }
15053
15054 if (ctf_errno (ctf))
15055 {
15056 error (_("Iteration failed: %s, %s\n"), *thing,
15057 ctf_errmsg (ctf_errno (ctf)));
8b37e7b6
NA
15058 err = 1;
15059 goto out;
2f6ecaed
NA
15060 }
15061 }
8b37e7b6
NA
15062
15063 out:
926c9e76 15064 dump_ctf_errs (ctf);
8b37e7b6 15065 return err;
2f6ecaed
NA
15066}
15067
015dc7e1 15068static bool
7d9813f1
NA
15069dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15070{
15071 Elf_Internal_Shdr * parent_sec = NULL;
15072 Elf_Internal_Shdr * symtab_sec = NULL;
15073 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15074 void * data = NULL;
15075 void * symdata = NULL;
15076 void * strdata = NULL;
15077 void * parentdata = NULL;
15078 ctf_sect_t ctfsect, symsect, strsect, parentsect;
15079 ctf_sect_t * symsectp = NULL;
15080 ctf_sect_t * strsectp = NULL;
2f6ecaed
NA
15081 ctf_archive_t * ctfa = NULL;
15082 ctf_archive_t * parenta = NULL, *lookparent;
139633c3 15083 ctf_dict_t * parent = NULL;
7d9813f1 15084
7d9813f1 15085 int err;
015dc7e1 15086 bool ret = false;
7d9813f1
NA
15087
15088 shdr_to_ctf_sect (&ctfsect, section, filedata);
15089 data = get_section_contents (section, filedata);
15090 ctfsect.cts_data = data;
15091
616febde 15092 if (!dump_ctf_symtab_name)
3d16b64e 15093 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15094
15095 if (!dump_ctf_strtab_name)
3d16b64e 15096 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15097
15098 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15099 {
15100 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15101 {
15102 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15103 goto fail;
15104 }
15105 if ((symdata = (void *) get_data (NULL, filedata,
15106 symtab_sec->sh_offset, 1,
15107 symtab_sec->sh_size,
15108 _("symbols"))) == NULL)
15109 goto fail;
15110 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15111 symsect.cts_data = symdata;
15112 }
835f2fae 15113
df16e041 15114 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15115 {
15116 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15117 {
15118 error (_("No string table section named %s\n"),
15119 dump_ctf_strtab_name);
15120 goto fail;
15121 }
15122 if ((strdata = (void *) get_data (NULL, filedata,
15123 strtab_sec->sh_offset, 1,
15124 strtab_sec->sh_size,
15125 _("strings"))) == NULL)
15126 goto fail;
15127 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15128 strsect.cts_data = strdata;
15129 }
835f2fae 15130
7d9813f1
NA
15131 if (dump_ctf_parent_name)
15132 {
15133 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
15134 {
15135 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
15136 goto fail;
15137 }
15138 if ((parentdata = (void *) get_data (NULL, filedata,
15139 parent_sec->sh_offset, 1,
15140 parent_sec->sh_size,
15141 _("CTF parent"))) == NULL)
15142 goto fail;
15143 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
15144 parentsect.cts_data = parentdata;
15145 }
15146
2f6ecaed
NA
15147 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15148 libctf papers over the difference, so we can pretend it is always an
15149 archive. Possibly open the parent as well, if one was specified. */
7d9813f1 15150
2f6ecaed 15151 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15152 {
926c9e76 15153 dump_ctf_errs (NULL);
7d9813f1
NA
15154 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15155 goto fail;
15156 }
15157
96c61be5
NA
15158 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15159 != ELFDATA2MSB);
15160
7d9813f1
NA
15161 if (parentdata)
15162 {
2f6ecaed
NA
15163 if ((parenta = ctf_arc_bufopen (&parentsect, symsectp, strsectp,
15164 &err)) == NULL)
7d9813f1 15165 {
926c9e76 15166 dump_ctf_errs (NULL);
7d9813f1
NA
15167 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15168 goto fail;
15169 }
2f6ecaed
NA
15170 lookparent = parenta;
15171 }
15172 else
15173 lookparent = ctfa;
7d9813f1 15174
2f6ecaed
NA
15175 /* Assume that the applicable parent archive member is the default one.
15176 (This is what all known implementations are expected to do, if they
15177 put CTFs and their parents in archives together.) */
ae41200b 15178 if ((parent = ctf_dict_open (lookparent, NULL, &err)) == NULL)
2f6ecaed 15179 {
926c9e76 15180 dump_ctf_errs (NULL);
2f6ecaed
NA
15181 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15182 goto fail;
7d9813f1
NA
15183 }
15184
015dc7e1 15185 ret = true;
7d9813f1 15186
835f2fae
NC
15187 if (filedata->is_separate)
15188 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15189 printable_section_name (filedata, section),
15190 filedata->file_name);
15191 else
15192 printf (_("\nDump of CTF section '%s':\n"),
15193 printable_section_name (filedata, section));
7d9813f1 15194
83d59285
NA
15195 if ((err = ctf_archive_iter (ctfa, dump_ctf_archive_member, parent)) != 0)
15196 {
15197 dump_ctf_errs (NULL);
15198 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
015dc7e1 15199 ret = false;
83d59285 15200 }
7d9813f1
NA
15201
15202 fail:
139633c3 15203 ctf_dict_close (parent);
2f6ecaed
NA
15204 ctf_close (ctfa);
15205 ctf_close (parenta);
7d9813f1
NA
15206 free (parentdata);
15207 free (data);
15208 free (symdata);
15209 free (strdata);
15210 return ret;
15211}
094e34f2 15212#endif
7d9813f1 15213
015dc7e1 15214static bool
dda8d76d
NC
15215load_specific_debug_section (enum dwarf_section_display_enum debug,
15216 const Elf_Internal_Shdr * sec,
15217 void * data)
1007acb3 15218{
2cf0635d 15219 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15220 char buf [64];
dda8d76d 15221 Filedata * filedata = (Filedata *) data;
9abca702 15222
19e6b90e 15223 if (section->start != NULL)
dda8d76d
NC
15224 {
15225 /* If it is already loaded, do nothing. */
15226 if (streq (section->filename, filedata->file_name))
015dc7e1 15227 return true;
dda8d76d
NC
15228 free (section->start);
15229 }
1007acb3 15230
19e6b90e
L
15231 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15232 section->address = sec->sh_addr;
dda8d76d
NC
15233 section->filename = filedata->file_name;
15234 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15235 sec->sh_offset, 1,
15236 sec->sh_size, buf);
59245841
NC
15237 if (section->start == NULL)
15238 section->size = 0;
15239 else
15240 {
77115a4a
L
15241 unsigned char *start = section->start;
15242 dwarf_size_type size = sec->sh_size;
dab394de 15243 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15244
15245 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15246 {
15247 Elf_Internal_Chdr chdr;
d8024a91
NC
15248 unsigned int compression_header_size;
15249
f53be977
L
15250 if (size < (is_32bit_elf
15251 ? sizeof (Elf32_External_Chdr)
15252 : sizeof (Elf64_External_Chdr)))
d8024a91 15253 {
55be8fd0 15254 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15255 section->name);
015dc7e1 15256 return false;
d8024a91
NC
15257 }
15258
ebdf1ebf 15259 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15260 if (compression_header_size == 0)
15261 /* An error message will have already been generated
15262 by get_compression_header. */
015dc7e1 15263 return false;
d8024a91 15264
813dabb9
L
15265 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15266 {
15267 warn (_("section '%s' has unsupported compress type: %d\n"),
15268 section->name, chdr.ch_type);
015dc7e1 15269 return false;
813dabb9 15270 }
dab394de 15271 uncompressed_size = chdr.ch_size;
77115a4a
L
15272 start += compression_header_size;
15273 size -= compression_header_size;
15274 }
dab394de
L
15275 else if (size > 12 && streq ((char *) start, "ZLIB"))
15276 {
15277 /* Read the zlib header. In this case, it should be "ZLIB"
15278 followed by the uncompressed section size, 8 bytes in
15279 big-endian order. */
15280 uncompressed_size = start[4]; uncompressed_size <<= 8;
15281 uncompressed_size += start[5]; uncompressed_size <<= 8;
15282 uncompressed_size += start[6]; uncompressed_size <<= 8;
15283 uncompressed_size += start[7]; uncompressed_size <<= 8;
15284 uncompressed_size += start[8]; uncompressed_size <<= 8;
15285 uncompressed_size += start[9]; uncompressed_size <<= 8;
15286 uncompressed_size += start[10]; uncompressed_size <<= 8;
15287 uncompressed_size += start[11];
15288 start += 12;
15289 size -= 12;
15290 }
15291
1835f746 15292 if (uncompressed_size)
77115a4a 15293 {
1835f746
NC
15294 if (uncompress_section_contents (&start, uncompressed_size,
15295 &size))
15296 {
15297 /* Free the compressed buffer, update the section buffer
15298 and the section size if uncompress is successful. */
15299 free (section->start);
15300 section->start = start;
15301 }
15302 else
15303 {
15304 error (_("Unable to decompress section %s\n"),
dda8d76d 15305 printable_section_name (filedata, sec));
015dc7e1 15306 return false;
1835f746 15307 }
77115a4a 15308 }
bc303e5d 15309
77115a4a 15310 section->size = size;
59245841 15311 }
4a114e3e 15312
1b315056 15313 if (section->start == NULL)
015dc7e1 15314 return false;
1b315056 15315
19e6b90e 15316 if (debug_displays [debug].relocate)
32ec8896 15317 {
dda8d76d 15318 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15319 & section->reloc_info, & section->num_relocs))
015dc7e1 15320 return false;
32ec8896 15321 }
d1c4b12b
NC
15322 else
15323 {
15324 section->reloc_info = NULL;
15325 section->num_relocs = 0;
15326 }
1007acb3 15327
015dc7e1 15328 return true;
1007acb3
L
15329}
15330
301a9420
AM
15331#if HAVE_LIBDEBUGINFOD
15332/* Return a hex string representation of the build-id. */
15333unsigned char *
15334get_build_id (void * data)
15335{
ca0e11aa 15336 Filedata * filedata = (Filedata *) data;
301a9420
AM
15337 Elf_Internal_Shdr * shdr;
15338 unsigned long i;
15339
55be8fd0
NC
15340 /* Iterate through notes to find note.gnu.build-id.
15341 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15342 for (i = 0, shdr = filedata->section_headers;
15343 i < filedata->file_header.e_shnum && shdr != NULL;
15344 i++, shdr++)
15345 {
15346 if (shdr->sh_type != SHT_NOTE)
15347 continue;
15348
15349 char * next;
15350 char * end;
15351 size_t data_remaining;
15352 size_t min_notesz;
15353 Elf_External_Note * enote;
15354 Elf_Internal_Note inote;
15355
15356 bfd_vma offset = shdr->sh_offset;
15357 bfd_vma align = shdr->sh_addralign;
15358 bfd_vma length = shdr->sh_size;
15359
15360 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15361 if (enote == NULL)
15362 continue;
15363
15364 if (align < 4)
15365 align = 4;
15366 else if (align != 4 && align != 8)
f761cb13
AM
15367 {
15368 free (enote);
15369 continue;
15370 }
301a9420
AM
15371
15372 end = (char *) enote + length;
15373 data_remaining = end - (char *) enote;
15374
15375 if (!is_ia64_vms (filedata))
15376 {
15377 min_notesz = offsetof (Elf_External_Note, name);
15378 if (data_remaining < min_notesz)
15379 {
55be8fd0
NC
15380 warn (_("\
15381malformed note encountered in section %s whilst scanning for build-id note\n"),
15382 printable_section_name (filedata, shdr));
f761cb13 15383 free (enote);
55be8fd0 15384 continue;
301a9420
AM
15385 }
15386 data_remaining -= min_notesz;
15387
15388 inote.type = BYTE_GET (enote->type);
15389 inote.namesz = BYTE_GET (enote->namesz);
15390 inote.namedata = enote->name;
15391 inote.descsz = BYTE_GET (enote->descsz);
15392 inote.descdata = ((char *) enote
15393 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15394 inote.descpos = offset + (inote.descdata - (char *) enote);
15395 next = ((char *) enote
15396 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15397 }
15398 else
15399 {
15400 Elf64_External_VMS_Note *vms_enote;
15401
15402 /* PR binutils/15191
15403 Make sure that there is enough data to read. */
15404 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15405 if (data_remaining < min_notesz)
15406 {
55be8fd0
NC
15407 warn (_("\
15408malformed note encountered in section %s whilst scanning for build-id note\n"),
15409 printable_section_name (filedata, shdr));
f761cb13 15410 free (enote);
55be8fd0 15411 continue;
301a9420
AM
15412 }
15413 data_remaining -= min_notesz;
15414
15415 vms_enote = (Elf64_External_VMS_Note *) enote;
15416 inote.type = BYTE_GET (vms_enote->type);
15417 inote.namesz = BYTE_GET (vms_enote->namesz);
15418 inote.namedata = vms_enote->name;
15419 inote.descsz = BYTE_GET (vms_enote->descsz);
15420 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15421 inote.descpos = offset + (inote.descdata - (char *) enote);
15422 next = inote.descdata + align_power (inote.descsz, 3);
15423 }
15424
15425 /* Skip malformed notes. */
15426 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
15427 || (size_t) (inote.descdata - inote.namedata) > data_remaining
15428 || (size_t) (next - inote.descdata) < inote.descsz
15429 || ((size_t) (next - inote.descdata)
15430 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
15431 {
55be8fd0
NC
15432 warn (_("\
15433malformed note encountered in section %s whilst scanning for build-id note\n"),
15434 printable_section_name (filedata, shdr));
f761cb13 15435 free (enote);
301a9420
AM
15436 continue;
15437 }
15438
15439 /* Check if this is the build-id note. If so then convert the build-id
15440 bytes to a hex string. */
15441 if (inote.namesz > 0
24d127aa 15442 && startswith (inote.namedata, "GNU")
301a9420
AM
15443 && inote.type == NT_GNU_BUILD_ID)
15444 {
15445 unsigned long j;
15446 char * build_id;
15447
15448 build_id = malloc (inote.descsz * 2 + 1);
15449 if (build_id == NULL)
f761cb13
AM
15450 {
15451 free (enote);
15452 return NULL;
15453 }
301a9420
AM
15454
15455 for (j = 0; j < inote.descsz; ++j)
15456 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
15457 build_id[inote.descsz * 2] = '\0';
f761cb13 15458 free (enote);
301a9420 15459
55be8fd0 15460 return (unsigned char *) build_id;
301a9420 15461 }
f761cb13 15462 free (enote);
301a9420
AM
15463 }
15464
15465 return NULL;
15466}
15467#endif /* HAVE_LIBDEBUGINFOD */
15468
657d0d47
CC
15469/* If this is not NULL, load_debug_section will only look for sections
15470 within the list of sections given here. */
32ec8896 15471static unsigned int * section_subset = NULL;
657d0d47 15472
015dc7e1 15473bool
dda8d76d 15474load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 15475{
2cf0635d
NC
15476 struct dwarf_section * section = &debug_displays [debug].section;
15477 Elf_Internal_Shdr * sec;
dda8d76d
NC
15478 Filedata * filedata = (Filedata *) data;
15479
f425ec66
NC
15480 /* Without section headers we cannot find any sections. */
15481 if (filedata->section_headers == NULL)
015dc7e1 15482 return false;
f425ec66 15483
9c1ce108
AM
15484 if (filedata->string_table == NULL
15485 && filedata->file_header.e_shstrndx != SHN_UNDEF
15486 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
15487 {
15488 Elf_Internal_Shdr * strs;
15489
15490 /* Read in the string table, so that we have section names to scan. */
15491 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
15492
4dff97b2 15493 if (strs != NULL && strs->sh_size != 0)
dda8d76d 15494 {
9c1ce108
AM
15495 filedata->string_table
15496 = (char *) get_data (NULL, filedata, strs->sh_offset,
15497 1, strs->sh_size, _("string table"));
dda8d76d 15498
9c1ce108
AM
15499 filedata->string_table_length
15500 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
15501 }
15502 }
d966045b
DJ
15503
15504 /* Locate the debug section. */
dda8d76d 15505 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
15506 if (sec != NULL)
15507 section->name = section->uncompressed_name;
15508 else
15509 {
dda8d76d 15510 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
15511 if (sec != NULL)
15512 section->name = section->compressed_name;
15513 }
15514 if (sec == NULL)
015dc7e1 15515 return false;
d966045b 15516
657d0d47
CC
15517 /* If we're loading from a subset of sections, and we've loaded
15518 a section matching this name before, it's likely that it's a
15519 different one. */
15520 if (section_subset != NULL)
15521 free_debug_section (debug);
15522
dda8d76d 15523 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
15524}
15525
19e6b90e
L
15526void
15527free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 15528{
2cf0635d 15529 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 15530
19e6b90e
L
15531 if (section->start == NULL)
15532 return;
1007acb3 15533
19e6b90e
L
15534 free ((char *) section->start);
15535 section->start = NULL;
15536 section->address = 0;
15537 section->size = 0;
a788aedd 15538
9db70fc3
AM
15539 free (section->reloc_info);
15540 section->reloc_info = NULL;
15541 section->num_relocs = 0;
1007acb3
L
15542}
15543
015dc7e1 15544static bool
dda8d76d 15545display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 15546{
b9e920ec 15547 char * name = SECTION_NAME_VALID (section) ? SECTION_NAME (section) : "";
dda8d76d 15548 const char * print_name = printable_section_name (filedata, section);
19e6b90e 15549 bfd_size_type length;
015dc7e1 15550 bool result = true;
3f5e193b 15551 int i;
1007acb3 15552
19e6b90e
L
15553 length = section->sh_size;
15554 if (length == 0)
1007acb3 15555 {
74e1a04b 15556 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 15557 return true;
1007acb3 15558 }
5dff79d8
NC
15559 if (section->sh_type == SHT_NOBITS)
15560 {
15561 /* There is no point in dumping the contents of a debugging section
15562 which has the NOBITS type - the bits in the file will be random.
15563 This can happen when a file containing a .eh_frame section is
15564 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
15565 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
15566 print_name);
015dc7e1 15567 return false;
5dff79d8 15568 }
1007acb3 15569
24d127aa 15570 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 15571 name = ".debug_info";
1007acb3 15572
19e6b90e
L
15573 /* See if we know how to display the contents of this section. */
15574 for (i = 0; i < max; i++)
d85bf2ba
NC
15575 {
15576 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
15577 struct dwarf_section_display * display = debug_displays + i;
15578 struct dwarf_section * sec = & display->section;
d966045b 15579
d85bf2ba 15580 if (streq (sec->uncompressed_name, name)
24d127aa 15581 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15582 || streq (sec->compressed_name, name))
15583 {
015dc7e1 15584 bool secondary = (section != find_section (filedata, name));
1007acb3 15585
d85bf2ba
NC
15586 if (secondary)
15587 free_debug_section (id);
dda8d76d 15588
24d127aa 15589 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15590 sec->name = name;
15591 else if (streq (sec->uncompressed_name, name))
15592 sec->name = sec->uncompressed_name;
15593 else
15594 sec->name = sec->compressed_name;
657d0d47 15595
d85bf2ba
NC
15596 if (load_specific_debug_section (id, section, filedata))
15597 {
15598 /* If this debug section is part of a CU/TU set in a .dwp file,
15599 restrict load_debug_section to the sections in that set. */
15600 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 15601
d85bf2ba 15602 result &= display->display (sec, filedata);
657d0d47 15603
d85bf2ba 15604 section_subset = NULL;
1007acb3 15605
44266f36 15606 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
15607 free_debug_section (id);
15608 }
15609 break;
15610 }
15611 }
1007acb3 15612
19e6b90e 15613 if (i == max)
1007acb3 15614 {
74e1a04b 15615 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 15616 result = false;
1007acb3
L
15617 }
15618
19e6b90e 15619 return result;
5b18a4bc 15620}
103f02d3 15621
aef1f6d0
DJ
15622/* Set DUMP_SECTS for all sections where dumps were requested
15623 based on section name. */
15624
15625static void
dda8d76d 15626initialise_dumps_byname (Filedata * filedata)
aef1f6d0 15627{
2cf0635d 15628 struct dump_list_entry * cur;
aef1f6d0
DJ
15629
15630 for (cur = dump_sects_byname; cur; cur = cur->next)
15631 {
15632 unsigned int i;
015dc7e1 15633 bool any = false;
aef1f6d0 15634
dda8d76d 15635 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
15636 if (SECTION_NAME_VALID (filedata->section_headers + i)
15637 && streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 15638 {
6431e409 15639 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 15640 any = true;
aef1f6d0
DJ
15641 }
15642
835f2fae
NC
15643 if (!any && !filedata->is_separate)
15644 warn (_("Section '%s' was not dumped because it does not exist\n"),
15645 cur->name);
aef1f6d0
DJ
15646 }
15647}
15648
015dc7e1 15649static bool
dda8d76d 15650process_section_contents (Filedata * filedata)
5b18a4bc 15651{
2cf0635d 15652 Elf_Internal_Shdr * section;
19e6b90e 15653 unsigned int i;
015dc7e1 15654 bool res = true;
103f02d3 15655
19e6b90e 15656 if (! do_dump)
015dc7e1 15657 return true;
103f02d3 15658
dda8d76d 15659 initialise_dumps_byname (filedata);
aef1f6d0 15660
dda8d76d 15661 for (i = 0, section = filedata->section_headers;
6431e409 15662 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
15663 i++, section++)
15664 {
6431e409 15665 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 15666
d6bfbc39
NC
15667 if (filedata->is_separate && ! process_links)
15668 dump &= DEBUG_DUMP;
047c3dbf 15669
19e6b90e 15670#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
15671 if (dump & DISASS_DUMP)
15672 {
15673 if (! disassemble_section (section, filedata))
015dc7e1 15674 res = false;
dda8d76d 15675 }
19e6b90e 15676#endif
dda8d76d 15677 if (dump & HEX_DUMP)
32ec8896 15678 {
015dc7e1
AM
15679 if (! dump_section_as_bytes (section, filedata, false))
15680 res = false;
32ec8896 15681 }
103f02d3 15682
dda8d76d 15683 if (dump & RELOC_DUMP)
32ec8896 15684 {
015dc7e1
AM
15685 if (! dump_section_as_bytes (section, filedata, true))
15686 res = false;
32ec8896 15687 }
09c11c86 15688
dda8d76d 15689 if (dump & STRING_DUMP)
32ec8896 15690 {
dda8d76d 15691 if (! dump_section_as_strings (section, filedata))
015dc7e1 15692 res = false;
32ec8896 15693 }
cf13d699 15694
dda8d76d 15695 if (dump & DEBUG_DUMP)
32ec8896 15696 {
dda8d76d 15697 if (! display_debug_section (i, section, filedata))
015dc7e1 15698 res = false;
32ec8896 15699 }
7d9813f1 15700
094e34f2 15701#ifdef ENABLE_LIBCTF
7d9813f1
NA
15702 if (dump & CTF_DUMP)
15703 {
15704 if (! dump_section_as_ctf (section, filedata))
015dc7e1 15705 res = false;
7d9813f1 15706 }
094e34f2 15707#endif
5b18a4bc 15708 }
103f02d3 15709
835f2fae 15710 if (! filedata->is_separate)
0ee3043f 15711 {
835f2fae
NC
15712 /* Check to see if the user requested a
15713 dump of a section that does not exist. */
15714 for (; i < filedata->dump.num_dump_sects; i++)
15715 if (filedata->dump.dump_sects[i])
15716 {
ca0e11aa 15717 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 15718 res = false;
835f2fae 15719 }
0ee3043f 15720 }
32ec8896
NC
15721
15722 return res;
5b18a4bc 15723}
103f02d3 15724
5b18a4bc 15725static void
19e6b90e 15726process_mips_fpe_exception (int mask)
5b18a4bc 15727{
19e6b90e
L
15728 if (mask)
15729 {
015dc7e1 15730 bool first = true;
32ec8896 15731
19e6b90e 15732 if (mask & OEX_FPU_INEX)
015dc7e1 15733 fputs ("INEX", stdout), first = false;
19e6b90e 15734 if (mask & OEX_FPU_UFLO)
015dc7e1 15735 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 15736 if (mask & OEX_FPU_OFLO)
015dc7e1 15737 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 15738 if (mask & OEX_FPU_DIV0)
015dc7e1 15739 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
15740 if (mask & OEX_FPU_INVAL)
15741 printf ("%sINVAL", first ? "" : "|");
15742 }
5b18a4bc 15743 else
19e6b90e 15744 fputs ("0", stdout);
5b18a4bc 15745}
103f02d3 15746
f6f0e17b
NC
15747/* Display's the value of TAG at location P. If TAG is
15748 greater than 0 it is assumed to be an unknown tag, and
15749 a message is printed to this effect. Otherwise it is
15750 assumed that a message has already been printed.
15751
15752 If the bottom bit of TAG is set it assumed to have a
15753 string value, otherwise it is assumed to have an integer
15754 value.
15755
15756 Returns an updated P pointing to the first unread byte
15757 beyond the end of TAG's value.
15758
15759 Reads at or beyond END will not be made. */
15760
15761static unsigned char *
60abdbed 15762display_tag_value (signed int tag,
f6f0e17b
NC
15763 unsigned char * p,
15764 const unsigned char * const end)
15765{
15766 unsigned long val;
15767
15768 if (tag > 0)
15769 printf (" Tag_unknown_%d: ", tag);
15770
15771 if (p >= end)
15772 {
4082ef84 15773 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
15774 }
15775 else if (tag & 1)
15776 {
071436c6
NC
15777 /* PR 17531 file: 027-19978-0.004. */
15778 size_t maxlen = (end - p) - 1;
15779
15780 putchar ('"');
4082ef84
NC
15781 if (maxlen > 0)
15782 {
15783 print_symbol ((int) maxlen, (const char *) p);
15784 p += strnlen ((char *) p, maxlen) + 1;
15785 }
15786 else
15787 {
15788 printf (_("<corrupt string tag>"));
15789 p = (unsigned char *) end;
15790 }
071436c6 15791 printf ("\"\n");
f6f0e17b
NC
15792 }
15793 else
15794 {
cd30bcef 15795 READ_ULEB (val, p, end);
f6f0e17b
NC
15796 printf ("%ld (0x%lx)\n", val, val);
15797 }
15798
4082ef84 15799 assert (p <= end);
f6f0e17b
NC
15800 return p;
15801}
15802
53a346d8
CZ
15803/* ARC ABI attributes section. */
15804
15805static unsigned char *
15806display_arc_attribute (unsigned char * p,
15807 const unsigned char * const end)
15808{
15809 unsigned int tag;
53a346d8
CZ
15810 unsigned int val;
15811
cd30bcef 15812 READ_ULEB (tag, p, end);
53a346d8
CZ
15813
15814 switch (tag)
15815 {
15816 case Tag_ARC_PCS_config:
cd30bcef 15817 READ_ULEB (val, p, end);
53a346d8
CZ
15818 printf (" Tag_ARC_PCS_config: ");
15819 switch (val)
15820 {
15821 case 0:
15822 printf (_("Absent/Non standard\n"));
15823 break;
15824 case 1:
15825 printf (_("Bare metal/mwdt\n"));
15826 break;
15827 case 2:
15828 printf (_("Bare metal/newlib\n"));
15829 break;
15830 case 3:
15831 printf (_("Linux/uclibc\n"));
15832 break;
15833 case 4:
15834 printf (_("Linux/glibc\n"));
15835 break;
15836 default:
15837 printf (_("Unknown\n"));
15838 break;
15839 }
15840 break;
15841
15842 case Tag_ARC_CPU_base:
cd30bcef 15843 READ_ULEB (val, p, end);
53a346d8
CZ
15844 printf (" Tag_ARC_CPU_base: ");
15845 switch (val)
15846 {
15847 default:
15848 case TAG_CPU_NONE:
15849 printf (_("Absent\n"));
15850 break;
15851 case TAG_CPU_ARC6xx:
15852 printf ("ARC6xx\n");
15853 break;
15854 case TAG_CPU_ARC7xx:
15855 printf ("ARC7xx\n");
15856 break;
15857 case TAG_CPU_ARCEM:
15858 printf ("ARCEM\n");
15859 break;
15860 case TAG_CPU_ARCHS:
15861 printf ("ARCHS\n");
15862 break;
15863 }
15864 break;
15865
15866 case Tag_ARC_CPU_variation:
cd30bcef 15867 READ_ULEB (val, p, end);
53a346d8
CZ
15868 printf (" Tag_ARC_CPU_variation: ");
15869 switch (val)
15870 {
15871 default:
15872 if (val > 0 && val < 16)
53a346d8 15873 printf ("Core%d\n", val);
d8cbc93b
JL
15874 else
15875 printf ("Unknown\n");
15876 break;
15877
53a346d8
CZ
15878 case 0:
15879 printf (_("Absent\n"));
15880 break;
15881 }
15882 break;
15883
15884 case Tag_ARC_CPU_name:
15885 printf (" Tag_ARC_CPU_name: ");
15886 p = display_tag_value (-1, p, end);
15887 break;
15888
15889 case Tag_ARC_ABI_rf16:
cd30bcef 15890 READ_ULEB (val, p, end);
53a346d8
CZ
15891 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
15892 break;
15893
15894 case Tag_ARC_ABI_osver:
cd30bcef 15895 READ_ULEB (val, p, end);
53a346d8
CZ
15896 printf (" Tag_ARC_ABI_osver: v%d\n", val);
15897 break;
15898
15899 case Tag_ARC_ABI_pic:
15900 case Tag_ARC_ABI_sda:
cd30bcef 15901 READ_ULEB (val, p, end);
53a346d8
CZ
15902 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
15903 : " Tag_ARC_ABI_pic: ");
15904 switch (val)
15905 {
15906 case 0:
15907 printf (_("Absent\n"));
15908 break;
15909 case 1:
15910 printf ("MWDT\n");
15911 break;
15912 case 2:
15913 printf ("GNU\n");
15914 break;
15915 default:
15916 printf (_("Unknown\n"));
15917 break;
15918 }
15919 break;
15920
15921 case Tag_ARC_ABI_tls:
cd30bcef 15922 READ_ULEB (val, p, end);
53a346d8
CZ
15923 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
15924 break;
15925
15926 case Tag_ARC_ABI_enumsize:
cd30bcef 15927 READ_ULEB (val, p, end);
53a346d8
CZ
15928 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
15929 _("smallest"));
15930 break;
15931
15932 case Tag_ARC_ABI_exceptions:
cd30bcef 15933 READ_ULEB (val, p, end);
53a346d8
CZ
15934 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
15935 : _("default"));
15936 break;
15937
15938 case Tag_ARC_ABI_double_size:
cd30bcef 15939 READ_ULEB (val, p, end);
53a346d8
CZ
15940 printf (" Tag_ARC_ABI_double_size: %d\n", val);
15941 break;
15942
15943 case Tag_ARC_ISA_config:
15944 printf (" Tag_ARC_ISA_config: ");
15945 p = display_tag_value (-1, p, end);
15946 break;
15947
15948 case Tag_ARC_ISA_apex:
15949 printf (" Tag_ARC_ISA_apex: ");
15950 p = display_tag_value (-1, p, end);
15951 break;
15952
15953 case Tag_ARC_ISA_mpy_option:
cd30bcef 15954 READ_ULEB (val, p, end);
53a346d8
CZ
15955 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
15956 break;
15957
db1e1b45 15958 case Tag_ARC_ATR_version:
cd30bcef 15959 READ_ULEB (val, p, end);
db1e1b45 15960 printf (" Tag_ARC_ATR_version: %d\n", val);
15961 break;
15962
53a346d8
CZ
15963 default:
15964 return display_tag_value (tag & 1, p, end);
15965 }
15966
15967 return p;
15968}
15969
11c1ff18
PB
15970/* ARM EABI attributes section. */
15971typedef struct
15972{
70e99720 15973 unsigned int tag;
2cf0635d 15974 const char * name;
11c1ff18 15975 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 15976 unsigned int type;
288f0ba2 15977 const char *const *table;
11c1ff18
PB
15978} arm_attr_public_tag;
15979
288f0ba2 15980static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 15981 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 15982 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 15983 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
288f0ba2
AM
15984static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
15985static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 15986 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 15987static const char *const arm_attr_tag_FP_arch[] =
bca38921 15988 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 15989 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
15990static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
15991static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
15992 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
15993 "NEON for ARMv8.1"};
288f0ba2 15994static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
15995 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
15996 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 15997static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 15998 {"V6", "SB", "TLS", "Unused"};
288f0ba2 15999static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16000 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16001static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16002 {"Absolute", "PC-relative", "None"};
288f0ba2 16003static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16004 {"None", "direct", "GOT-indirect"};
288f0ba2 16005static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16006 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16007static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16008static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16009 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16010static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16011static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16012static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16013 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16014static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16015 {"Unused", "small", "int", "forced to int"};
288f0ba2 16016static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16017 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16018static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16019 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16020static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16021 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16022static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16023 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16024 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16025static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16026 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16027 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16028static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16029static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16030 {"Not Allowed", "Allowed"};
288f0ba2 16031static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16032 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16033static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16034 {"Follow architecture", "Allowed"};
288f0ba2 16035static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16036 {"Not Allowed", "Allowed"};
288f0ba2 16037static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16038 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16039 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16040static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16041static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16042 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16043 "TrustZone and Virtualization Extensions"};
288f0ba2 16044static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16045 {"Not Allowed", "Allowed"};
11c1ff18 16046
288f0ba2 16047static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16048 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16049
11c1ff18
PB
16050#define LOOKUP(id, name) \
16051 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16052static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16053{
16054 {4, "CPU_raw_name", 1, NULL},
16055 {5, "CPU_name", 1, NULL},
16056 LOOKUP(6, CPU_arch),
16057 {7, "CPU_arch_profile", 0, NULL},
16058 LOOKUP(8, ARM_ISA_use),
16059 LOOKUP(9, THUMB_ISA_use),
75375b3e 16060 LOOKUP(10, FP_arch),
11c1ff18 16061 LOOKUP(11, WMMX_arch),
f5f53991
AS
16062 LOOKUP(12, Advanced_SIMD_arch),
16063 LOOKUP(13, PCS_config),
11c1ff18
PB
16064 LOOKUP(14, ABI_PCS_R9_use),
16065 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16066 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16067 LOOKUP(17, ABI_PCS_GOT_use),
16068 LOOKUP(18, ABI_PCS_wchar_t),
16069 LOOKUP(19, ABI_FP_rounding),
16070 LOOKUP(20, ABI_FP_denormal),
16071 LOOKUP(21, ABI_FP_exceptions),
16072 LOOKUP(22, ABI_FP_user_exceptions),
16073 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16074 {24, "ABI_align_needed", 0, NULL},
16075 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16076 LOOKUP(26, ABI_enum_size),
16077 LOOKUP(27, ABI_HardFP_use),
16078 LOOKUP(28, ABI_VFP_args),
16079 LOOKUP(29, ABI_WMMX_args),
16080 LOOKUP(30, ABI_optimization_goals),
16081 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16082 {32, "compatibility", 0, NULL},
f5f53991 16083 LOOKUP(34, CPU_unaligned_access),
75375b3e 16084 LOOKUP(36, FP_HP_extension),
8e79c3df 16085 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16086 LOOKUP(42, MPextension_use),
16087 LOOKUP(44, DIV_use),
15afaa63 16088 LOOKUP(46, DSP_extension),
a7ad558c 16089 LOOKUP(48, MVE_arch),
f5f53991
AS
16090 {64, "nodefaults", 0, NULL},
16091 {65, "also_compatible_with", 0, NULL},
16092 LOOKUP(66, T2EE_use),
16093 {67, "conformance", 1, NULL},
16094 LOOKUP(68, Virtualization_use),
cd21e546 16095 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16096};
16097#undef LOOKUP
16098
11c1ff18 16099static unsigned char *
f6f0e17b
NC
16100display_arm_attribute (unsigned char * p,
16101 const unsigned char * const end)
11c1ff18 16102{
70e99720 16103 unsigned int tag;
70e99720 16104 unsigned int val;
2cf0635d 16105 arm_attr_public_tag * attr;
11c1ff18 16106 unsigned i;
70e99720 16107 unsigned int type;
11c1ff18 16108
cd30bcef 16109 READ_ULEB (tag, p, end);
11c1ff18 16110 attr = NULL;
2cf0635d 16111 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16112 {
16113 if (arm_attr_public_tags[i].tag == tag)
16114 {
16115 attr = &arm_attr_public_tags[i];
16116 break;
16117 }
16118 }
16119
16120 if (attr)
16121 {
16122 printf (" Tag_%s: ", attr->name);
16123 switch (attr->type)
16124 {
16125 case 0:
16126 switch (tag)
16127 {
16128 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16129 READ_ULEB (val, p, end);
11c1ff18
PB
16130 switch (val)
16131 {
2b692964
NC
16132 case 0: printf (_("None\n")); break;
16133 case 'A': printf (_("Application\n")); break;
16134 case 'R': printf (_("Realtime\n")); break;
16135 case 'M': printf (_("Microcontroller\n")); break;
16136 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16137 default: printf ("??? (%d)\n", val); break;
16138 }
16139 break;
16140
75375b3e 16141 case 24: /* Tag_align_needed. */
cd30bcef 16142 READ_ULEB (val, p, end);
75375b3e
MGD
16143 switch (val)
16144 {
2b692964
NC
16145 case 0: printf (_("None\n")); break;
16146 case 1: printf (_("8-byte\n")); break;
16147 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16148 case 3: printf ("??? 3\n"); break;
16149 default:
16150 if (val <= 12)
dd24e3da 16151 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16152 1 << val);
16153 else
16154 printf ("??? (%d)\n", val);
16155 break;
16156 }
16157 break;
16158
16159 case 25: /* Tag_align_preserved. */
cd30bcef 16160 READ_ULEB (val, p, end);
75375b3e
MGD
16161 switch (val)
16162 {
2b692964
NC
16163 case 0: printf (_("None\n")); break;
16164 case 1: printf (_("8-byte, except leaf SP\n")); break;
16165 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16166 case 3: printf ("??? 3\n"); break;
16167 default:
16168 if (val <= 12)
dd24e3da 16169 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16170 1 << val);
16171 else
16172 printf ("??? (%d)\n", val);
16173 break;
16174 }
16175 break;
16176
11c1ff18 16177 case 32: /* Tag_compatibility. */
071436c6 16178 {
cd30bcef 16179 READ_ULEB (val, p, end);
071436c6 16180 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16181 if (p < end - 1)
16182 {
16183 size_t maxlen = (end - p) - 1;
16184
16185 print_symbol ((int) maxlen, (const char *) p);
16186 p += strnlen ((char *) p, maxlen) + 1;
16187 }
16188 else
16189 {
16190 printf (_("<corrupt>"));
16191 p = (unsigned char *) end;
16192 }
071436c6 16193 putchar ('\n');
071436c6 16194 }
11c1ff18
PB
16195 break;
16196
f5f53991 16197 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16198 /* PR 17531: file: 001-505008-0.01. */
16199 if (p < end)
16200 p++;
2b692964 16201 printf (_("True\n"));
f5f53991
AS
16202 break;
16203
16204 case 65: /* Tag_also_compatible_with. */
cd30bcef 16205 READ_ULEB (val, p, end);
f5f53991
AS
16206 if (val == 6 /* Tag_CPU_arch. */)
16207 {
cd30bcef 16208 READ_ULEB (val, p, end);
071436c6 16209 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16210 printf ("??? (%d)\n", val);
16211 else
16212 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16213 }
16214 else
16215 printf ("???\n");
071436c6
NC
16216 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16217 ;
f5f53991
AS
16218 break;
16219
11c1ff18 16220 default:
bee0ee85
NC
16221 printf (_("<unknown: %d>\n"), tag);
16222 break;
11c1ff18
PB
16223 }
16224 return p;
16225
16226 case 1:
f6f0e17b 16227 return display_tag_value (-1, p, end);
11c1ff18 16228 case 2:
f6f0e17b 16229 return display_tag_value (0, p, end);
11c1ff18
PB
16230
16231 default:
16232 assert (attr->type & 0x80);
cd30bcef 16233 READ_ULEB (val, p, end);
11c1ff18
PB
16234 type = attr->type & 0x7f;
16235 if (val >= type)
16236 printf ("??? (%d)\n", val);
16237 else
16238 printf ("%s\n", attr->table[val]);
16239 return p;
16240 }
16241 }
11c1ff18 16242
f6f0e17b 16243 return display_tag_value (tag, p, end);
11c1ff18
PB
16244}
16245
104d59d1 16246static unsigned char *
60bca95a 16247display_gnu_attribute (unsigned char * p,
60abdbed 16248 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16249 const unsigned char * const end)
104d59d1 16250{
cd30bcef 16251 unsigned int tag;
60abdbed 16252 unsigned int val;
104d59d1 16253
cd30bcef 16254 READ_ULEB (tag, p, end);
104d59d1
JM
16255
16256 /* Tag_compatibility is the only generic GNU attribute defined at
16257 present. */
16258 if (tag == 32)
16259 {
cd30bcef 16260 READ_ULEB (val, p, end);
071436c6
NC
16261
16262 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16263 if (p == end)
16264 {
071436c6 16265 printf (_("<corrupt>\n"));
f6f0e17b
NC
16266 warn (_("corrupt vendor attribute\n"));
16267 }
16268 else
16269 {
4082ef84
NC
16270 if (p < end - 1)
16271 {
16272 size_t maxlen = (end - p) - 1;
071436c6 16273
4082ef84
NC
16274 print_symbol ((int) maxlen, (const char *) p);
16275 p += strnlen ((char *) p, maxlen) + 1;
16276 }
16277 else
16278 {
16279 printf (_("<corrupt>"));
16280 p = (unsigned char *) end;
16281 }
071436c6 16282 putchar ('\n');
f6f0e17b 16283 }
104d59d1
JM
16284 return p;
16285 }
16286
16287 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16288 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16289
f6f0e17b 16290 return display_tag_value (tag, p, end);
104d59d1
JM
16291}
16292
85f7484a
PB
16293static unsigned char *
16294display_m68k_gnu_attribute (unsigned char * p,
16295 unsigned int tag,
16296 const unsigned char * const end)
16297{
16298 unsigned int val;
16299
16300 if (tag == Tag_GNU_M68K_ABI_FP)
16301 {
16302 printf (" Tag_GNU_M68K_ABI_FP: ");
16303 if (p == end)
16304 {
16305 printf (_("<corrupt>\n"));
16306 return p;
16307 }
16308 READ_ULEB (val, p, end);
16309
16310 if (val > 3)
16311 printf ("(%#x), ", val);
16312
16313 switch (val & 3)
16314 {
16315 case 0:
16316 printf (_("unspecified hard/soft float\n"));
16317 break;
16318 case 1:
16319 printf (_("hard float\n"));
16320 break;
16321 case 2:
16322 printf (_("soft float\n"));
16323 break;
16324 }
16325 return p;
16326 }
16327
16328 return display_tag_value (tag & 1, p, end);
16329}
16330
34c8bcba 16331static unsigned char *
f6f0e17b 16332display_power_gnu_attribute (unsigned char * p,
60abdbed 16333 unsigned int tag,
f6f0e17b 16334 const unsigned char * const end)
34c8bcba 16335{
005d79fd 16336 unsigned int val;
34c8bcba
JM
16337
16338 if (tag == Tag_GNU_Power_ABI_FP)
16339 {
34c8bcba 16340 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16341 if (p == end)
005d79fd
AM
16342 {
16343 printf (_("<corrupt>\n"));
16344 return p;
16345 }
cd30bcef 16346 READ_ULEB (val, p, end);
60bca95a 16347
005d79fd
AM
16348 if (val > 15)
16349 printf ("(%#x), ", val);
16350
16351 switch (val & 3)
34c8bcba
JM
16352 {
16353 case 0:
005d79fd 16354 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16355 break;
16356 case 1:
005d79fd 16357 printf (_("hard float, "));
34c8bcba
JM
16358 break;
16359 case 2:
005d79fd 16360 printf (_("soft float, "));
34c8bcba 16361 break;
3c7b9897 16362 case 3:
005d79fd 16363 printf (_("single-precision hard float, "));
3c7b9897 16364 break;
005d79fd
AM
16365 }
16366
16367 switch (val & 0xC)
16368 {
16369 case 0:
16370 printf (_("unspecified long double\n"));
16371 break;
16372 case 4:
16373 printf (_("128-bit IBM long double\n"));
16374 break;
16375 case 8:
16376 printf (_("64-bit long double\n"));
16377 break;
16378 case 12:
16379 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16380 break;
16381 }
16382 return p;
005d79fd 16383 }
34c8bcba 16384
c6e65352
DJ
16385 if (tag == Tag_GNU_Power_ABI_Vector)
16386 {
c6e65352 16387 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 16388 if (p == end)
005d79fd
AM
16389 {
16390 printf (_("<corrupt>\n"));
16391 return p;
16392 }
cd30bcef 16393 READ_ULEB (val, p, end);
005d79fd
AM
16394
16395 if (val > 3)
16396 printf ("(%#x), ", val);
16397
16398 switch (val & 3)
c6e65352
DJ
16399 {
16400 case 0:
005d79fd 16401 printf (_("unspecified\n"));
c6e65352
DJ
16402 break;
16403 case 1:
005d79fd 16404 printf (_("generic\n"));
c6e65352
DJ
16405 break;
16406 case 2:
16407 printf ("AltiVec\n");
16408 break;
16409 case 3:
16410 printf ("SPE\n");
16411 break;
c6e65352
DJ
16412 }
16413 return p;
005d79fd 16414 }
c6e65352 16415
f82e0623
NF
16416 if (tag == Tag_GNU_Power_ABI_Struct_Return)
16417 {
005d79fd 16418 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 16419 if (p == end)
f6f0e17b 16420 {
005d79fd 16421 printf (_("<corrupt>\n"));
f6f0e17b
NC
16422 return p;
16423 }
cd30bcef 16424 READ_ULEB (val, p, end);
0b4362b0 16425
005d79fd
AM
16426 if (val > 2)
16427 printf ("(%#x), ", val);
16428
16429 switch (val & 3)
16430 {
16431 case 0:
16432 printf (_("unspecified\n"));
16433 break;
16434 case 1:
16435 printf ("r3/r4\n");
16436 break;
16437 case 2:
16438 printf (_("memory\n"));
16439 break;
16440 case 3:
16441 printf ("???\n");
16442 break;
16443 }
f82e0623
NF
16444 return p;
16445 }
16446
f6f0e17b 16447 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
16448}
16449
643f7afb
AK
16450static unsigned char *
16451display_s390_gnu_attribute (unsigned char * p,
60abdbed 16452 unsigned int tag,
643f7afb
AK
16453 const unsigned char * const end)
16454{
cd30bcef 16455 unsigned int val;
643f7afb
AK
16456
16457 if (tag == Tag_GNU_S390_ABI_Vector)
16458 {
643f7afb 16459 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 16460 READ_ULEB (val, p, end);
643f7afb
AK
16461
16462 switch (val)
16463 {
16464 case 0:
16465 printf (_("any\n"));
16466 break;
16467 case 1:
16468 printf (_("software\n"));
16469 break;
16470 case 2:
16471 printf (_("hardware\n"));
16472 break;
16473 default:
16474 printf ("??? (%d)\n", val);
16475 break;
16476 }
16477 return p;
16478 }
16479
16480 return display_tag_value (tag & 1, p, end);
16481}
16482
9e8c70f9 16483static void
60abdbed 16484display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
16485{
16486 if (mask)
16487 {
015dc7e1 16488 bool first = true;
071436c6 16489
9e8c70f9 16490 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 16491 fputs ("mul32", stdout), first = false;
9e8c70f9 16492 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 16493 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 16494 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 16495 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 16496 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 16497 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 16498 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 16499 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 16500 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 16501 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 16502 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 16503 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 16504 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 16505 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 16506 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 16507 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 16508 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 16509 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 16510 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 16511 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 16512 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 16513 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 16514 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 16515 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 16516 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 16517 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 16518 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 16519 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 16520 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 16521 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
16522 }
16523 else
071436c6
NC
16524 fputc ('0', stdout);
16525 fputc ('\n', stdout);
9e8c70f9
DM
16526}
16527
3d68f91c 16528static void
60abdbed 16529display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
16530{
16531 if (mask)
16532 {
015dc7e1 16533 bool first = true;
071436c6 16534
3d68f91c 16535 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 16536 fputs ("fjathplus", stdout), first = false;
3d68f91c 16537 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 16538 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 16539 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 16540 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 16541 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 16542 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 16543 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 16544 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 16545 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 16546 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 16547 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 16548 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 16549 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 16550 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 16551 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 16552 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 16553 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 16554 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 16555 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 16556 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
16557 }
16558 else
071436c6
NC
16559 fputc ('0', stdout);
16560 fputc ('\n', stdout);
3d68f91c
JM
16561}
16562
9e8c70f9 16563static unsigned char *
f6f0e17b 16564display_sparc_gnu_attribute (unsigned char * p,
60abdbed 16565 unsigned int tag,
f6f0e17b 16566 const unsigned char * const end)
9e8c70f9 16567{
cd30bcef 16568 unsigned int val;
3d68f91c 16569
9e8c70f9
DM
16570 if (tag == Tag_GNU_Sparc_HWCAPS)
16571 {
cd30bcef 16572 READ_ULEB (val, p, end);
9e8c70f9 16573 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
16574 display_sparc_hwcaps (val);
16575 return p;
3d68f91c
JM
16576 }
16577 if (tag == Tag_GNU_Sparc_HWCAPS2)
16578 {
cd30bcef 16579 READ_ULEB (val, p, end);
3d68f91c
JM
16580 printf (" Tag_GNU_Sparc_HWCAPS2: ");
16581 display_sparc_hwcaps2 (val);
16582 return p;
16583 }
9e8c70f9 16584
f6f0e17b 16585 return display_tag_value (tag, p, end);
9e8c70f9
DM
16586}
16587
351cdf24 16588static void
32ec8896 16589print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
16590{
16591 switch (val)
16592 {
16593 case Val_GNU_MIPS_ABI_FP_ANY:
16594 printf (_("Hard or soft float\n"));
16595 break;
16596 case Val_GNU_MIPS_ABI_FP_DOUBLE:
16597 printf (_("Hard float (double precision)\n"));
16598 break;
16599 case Val_GNU_MIPS_ABI_FP_SINGLE:
16600 printf (_("Hard float (single precision)\n"));
16601 break;
16602 case Val_GNU_MIPS_ABI_FP_SOFT:
16603 printf (_("Soft float\n"));
16604 break;
16605 case Val_GNU_MIPS_ABI_FP_OLD_64:
16606 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
16607 break;
16608 case Val_GNU_MIPS_ABI_FP_XX:
16609 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
16610 break;
16611 case Val_GNU_MIPS_ABI_FP_64:
16612 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
16613 break;
16614 case Val_GNU_MIPS_ABI_FP_64A:
16615 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
16616 break;
3350cc01
CM
16617 case Val_GNU_MIPS_ABI_FP_NAN2008:
16618 printf (_("NaN 2008 compatibility\n"));
16619 break;
351cdf24
MF
16620 default:
16621 printf ("??? (%d)\n", val);
16622 break;
16623 }
16624}
16625
2cf19d5c 16626static unsigned char *
f6f0e17b 16627display_mips_gnu_attribute (unsigned char * p,
60abdbed 16628 unsigned int tag,
f6f0e17b 16629 const unsigned char * const end)
2cf19d5c 16630{
2cf19d5c
JM
16631 if (tag == Tag_GNU_MIPS_ABI_FP)
16632 {
32ec8896 16633 unsigned int val;
f6f0e17b 16634
2cf19d5c 16635 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 16636 READ_ULEB (val, p, end);
351cdf24 16637 print_mips_fp_abi_value (val);
2cf19d5c
JM
16638 return p;
16639 }
16640
a9f58168
CF
16641 if (tag == Tag_GNU_MIPS_ABI_MSA)
16642 {
32ec8896 16643 unsigned int val;
a9f58168 16644
a9f58168 16645 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 16646 READ_ULEB (val, p, end);
a9f58168
CF
16647
16648 switch (val)
16649 {
16650 case Val_GNU_MIPS_ABI_MSA_ANY:
16651 printf (_("Any MSA or not\n"));
16652 break;
16653 case Val_GNU_MIPS_ABI_MSA_128:
16654 printf (_("128-bit MSA\n"));
16655 break;
16656 default:
16657 printf ("??? (%d)\n", val);
16658 break;
16659 }
16660 return p;
16661 }
16662
f6f0e17b 16663 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
16664}
16665
59e6276b 16666static unsigned char *
f6f0e17b
NC
16667display_tic6x_attribute (unsigned char * p,
16668 const unsigned char * const end)
59e6276b 16669{
60abdbed 16670 unsigned int tag;
cd30bcef 16671 unsigned int val;
59e6276b 16672
cd30bcef 16673 READ_ULEB (tag, p, end);
59e6276b
JM
16674
16675 switch (tag)
16676 {
75fa6dc1 16677 case Tag_ISA:
75fa6dc1 16678 printf (" Tag_ISA: ");
cd30bcef 16679 READ_ULEB (val, p, end);
59e6276b
JM
16680
16681 switch (val)
16682 {
75fa6dc1 16683 case C6XABI_Tag_ISA_none:
59e6276b
JM
16684 printf (_("None\n"));
16685 break;
75fa6dc1 16686 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
16687 printf ("C62x\n");
16688 break;
75fa6dc1 16689 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
16690 printf ("C67x\n");
16691 break;
75fa6dc1 16692 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
16693 printf ("C67x+\n");
16694 break;
75fa6dc1 16695 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
16696 printf ("C64x\n");
16697 break;
75fa6dc1 16698 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
16699 printf ("C64x+\n");
16700 break;
75fa6dc1 16701 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
16702 printf ("C674x\n");
16703 break;
16704 default:
16705 printf ("??? (%d)\n", val);
16706 break;
16707 }
16708 return p;
16709
87779176 16710 case Tag_ABI_wchar_t:
87779176 16711 printf (" Tag_ABI_wchar_t: ");
cd30bcef 16712 READ_ULEB (val, p, end);
87779176
JM
16713 switch (val)
16714 {
16715 case 0:
16716 printf (_("Not used\n"));
16717 break;
16718 case 1:
16719 printf (_("2 bytes\n"));
16720 break;
16721 case 2:
16722 printf (_("4 bytes\n"));
16723 break;
16724 default:
16725 printf ("??? (%d)\n", val);
16726 break;
16727 }
16728 return p;
16729
16730 case Tag_ABI_stack_align_needed:
87779176 16731 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 16732 READ_ULEB (val, p, end);
87779176
JM
16733 switch (val)
16734 {
16735 case 0:
16736 printf (_("8-byte\n"));
16737 break;
16738 case 1:
16739 printf (_("16-byte\n"));
16740 break;
16741 default:
16742 printf ("??? (%d)\n", val);
16743 break;
16744 }
16745 return p;
16746
16747 case Tag_ABI_stack_align_preserved:
cd30bcef 16748 READ_ULEB (val, p, end);
87779176
JM
16749 printf (" Tag_ABI_stack_align_preserved: ");
16750 switch (val)
16751 {
16752 case 0:
16753 printf (_("8-byte\n"));
16754 break;
16755 case 1:
16756 printf (_("16-byte\n"));
16757 break;
16758 default:
16759 printf ("??? (%d)\n", val);
16760 break;
16761 }
16762 return p;
16763
b5593623 16764 case Tag_ABI_DSBT:
cd30bcef 16765 READ_ULEB (val, p, end);
b5593623
JM
16766 printf (" Tag_ABI_DSBT: ");
16767 switch (val)
16768 {
16769 case 0:
16770 printf (_("DSBT addressing not used\n"));
16771 break;
16772 case 1:
16773 printf (_("DSBT addressing used\n"));
16774 break;
16775 default:
16776 printf ("??? (%d)\n", val);
16777 break;
16778 }
16779 return p;
16780
87779176 16781 case Tag_ABI_PID:
cd30bcef 16782 READ_ULEB (val, p, end);
87779176
JM
16783 printf (" Tag_ABI_PID: ");
16784 switch (val)
16785 {
16786 case 0:
16787 printf (_("Data addressing position-dependent\n"));
16788 break;
16789 case 1:
16790 printf (_("Data addressing position-independent, GOT near DP\n"));
16791 break;
16792 case 2:
16793 printf (_("Data addressing position-independent, GOT far from DP\n"));
16794 break;
16795 default:
16796 printf ("??? (%d)\n", val);
16797 break;
16798 }
16799 return p;
16800
16801 case Tag_ABI_PIC:
cd30bcef 16802 READ_ULEB (val, p, end);
87779176
JM
16803 printf (" Tag_ABI_PIC: ");
16804 switch (val)
16805 {
16806 case 0:
16807 printf (_("Code addressing position-dependent\n"));
16808 break;
16809 case 1:
16810 printf (_("Code addressing position-independent\n"));
16811 break;
16812 default:
16813 printf ("??? (%d)\n", val);
16814 break;
16815 }
16816 return p;
16817
16818 case Tag_ABI_array_object_alignment:
cd30bcef 16819 READ_ULEB (val, p, end);
87779176
JM
16820 printf (" Tag_ABI_array_object_alignment: ");
16821 switch (val)
16822 {
16823 case 0:
16824 printf (_("8-byte\n"));
16825 break;
16826 case 1:
16827 printf (_("4-byte\n"));
16828 break;
16829 case 2:
16830 printf (_("16-byte\n"));
16831 break;
16832 default:
16833 printf ("??? (%d)\n", val);
16834 break;
16835 }
16836 return p;
16837
16838 case Tag_ABI_array_object_align_expected:
cd30bcef 16839 READ_ULEB (val, p, end);
87779176
JM
16840 printf (" Tag_ABI_array_object_align_expected: ");
16841 switch (val)
16842 {
16843 case 0:
16844 printf (_("8-byte\n"));
16845 break;
16846 case 1:
16847 printf (_("4-byte\n"));
16848 break;
16849 case 2:
16850 printf (_("16-byte\n"));
16851 break;
16852 default:
16853 printf ("??? (%d)\n", val);
16854 break;
16855 }
16856 return p;
16857
3cbd1c06 16858 case Tag_ABI_compatibility:
071436c6 16859 {
cd30bcef 16860 READ_ULEB (val, p, end);
071436c6 16861 printf (" Tag_ABI_compatibility: ");
071436c6 16862 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16863 if (p < end - 1)
16864 {
16865 size_t maxlen = (end - p) - 1;
16866
16867 print_symbol ((int) maxlen, (const char *) p);
16868 p += strnlen ((char *) p, maxlen) + 1;
16869 }
16870 else
16871 {
16872 printf (_("<corrupt>"));
16873 p = (unsigned char *) end;
16874 }
071436c6 16875 putchar ('\n');
071436c6
NC
16876 return p;
16877 }
87779176
JM
16878
16879 case Tag_ABI_conformance:
071436c6 16880 {
4082ef84
NC
16881 printf (" Tag_ABI_conformance: \"");
16882 if (p < end - 1)
16883 {
16884 size_t maxlen = (end - p) - 1;
071436c6 16885
4082ef84
NC
16886 print_symbol ((int) maxlen, (const char *) p);
16887 p += strnlen ((char *) p, maxlen) + 1;
16888 }
16889 else
16890 {
16891 printf (_("<corrupt>"));
16892 p = (unsigned char *) end;
16893 }
071436c6 16894 printf ("\"\n");
071436c6
NC
16895 return p;
16896 }
59e6276b
JM
16897 }
16898
f6f0e17b
NC
16899 return display_tag_value (tag, p, end);
16900}
59e6276b 16901
f6f0e17b 16902static void
60abdbed 16903display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
16904{
16905 unsigned long addr = 0;
16906 size_t bytes = end - p;
16907
feceaa59 16908 assert (end >= p);
f6f0e17b 16909 while (bytes)
87779176 16910 {
f6f0e17b
NC
16911 int j;
16912 int k;
16913 int lbytes = (bytes > 16 ? 16 : bytes);
16914
16915 printf (" 0x%8.8lx ", addr);
16916
16917 for (j = 0; j < 16; j++)
16918 {
16919 if (j < lbytes)
16920 printf ("%2.2x", p[j]);
16921 else
16922 printf (" ");
16923
16924 if ((j & 3) == 3)
16925 printf (" ");
16926 }
16927
16928 for (j = 0; j < lbytes; j++)
16929 {
16930 k = p[j];
16931 if (k >= ' ' && k < 0x7f)
16932 printf ("%c", k);
16933 else
16934 printf (".");
16935 }
16936
16937 putchar ('\n');
16938
16939 p += lbytes;
16940 bytes -= lbytes;
16941 addr += lbytes;
87779176 16942 }
59e6276b 16943
f6f0e17b 16944 putchar ('\n');
59e6276b
JM
16945}
16946
13761a11 16947static unsigned char *
b0191216 16948display_msp430_attribute (unsigned char * p,
13761a11
NC
16949 const unsigned char * const end)
16950{
60abdbed
NC
16951 unsigned int val;
16952 unsigned int tag;
13761a11 16953
cd30bcef 16954 READ_ULEB (tag, p, end);
0b4362b0 16955
13761a11
NC
16956 switch (tag)
16957 {
16958 case OFBA_MSPABI_Tag_ISA:
13761a11 16959 printf (" Tag_ISA: ");
cd30bcef 16960 READ_ULEB (val, p, end);
13761a11
NC
16961 switch (val)
16962 {
16963 case 0: printf (_("None\n")); break;
16964 case 1: printf (_("MSP430\n")); break;
16965 case 2: printf (_("MSP430X\n")); break;
16966 default: printf ("??? (%d)\n", val); break;
16967 }
16968 break;
16969
16970 case OFBA_MSPABI_Tag_Code_Model:
13761a11 16971 printf (" Tag_Code_Model: ");
cd30bcef 16972 READ_ULEB (val, p, end);
13761a11
NC
16973 switch (val)
16974 {
16975 case 0: printf (_("None\n")); break;
16976 case 1: printf (_("Small\n")); break;
16977 case 2: printf (_("Large\n")); break;
16978 default: printf ("??? (%d)\n", val); break;
16979 }
16980 break;
16981
16982 case OFBA_MSPABI_Tag_Data_Model:
13761a11 16983 printf (" Tag_Data_Model: ");
cd30bcef 16984 READ_ULEB (val, p, end);
13761a11
NC
16985 switch (val)
16986 {
16987 case 0: printf (_("None\n")); break;
16988 case 1: printf (_("Small\n")); break;
16989 case 2: printf (_("Large\n")); break;
16990 case 3: printf (_("Restricted Large\n")); break;
16991 default: printf ("??? (%d)\n", val); break;
16992 }
16993 break;
16994
16995 default:
16996 printf (_(" <unknown tag %d>: "), tag);
16997
16998 if (tag & 1)
16999 {
071436c6 17000 putchar ('"');
4082ef84
NC
17001 if (p < end - 1)
17002 {
17003 size_t maxlen = (end - p) - 1;
17004
17005 print_symbol ((int) maxlen, (const char *) p);
17006 p += strnlen ((char *) p, maxlen) + 1;
17007 }
17008 else
17009 {
17010 printf (_("<corrupt>"));
17011 p = (unsigned char *) end;
17012 }
071436c6 17013 printf ("\"\n");
13761a11
NC
17014 }
17015 else
17016 {
cd30bcef 17017 READ_ULEB (val, p, end);
13761a11
NC
17018 printf ("%d (0x%x)\n", val, val);
17019 }
17020 break;
17021 }
17022
4082ef84 17023 assert (p <= end);
13761a11
NC
17024 return p;
17025}
17026
c0ea7c52
JL
17027static unsigned char *
17028display_msp430_gnu_attribute (unsigned char * p,
17029 unsigned int tag,
17030 const unsigned char * const end)
17031{
17032 if (tag == Tag_GNU_MSP430_Data_Region)
17033 {
cd30bcef 17034 unsigned int val;
c0ea7c52 17035
c0ea7c52 17036 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17037 READ_ULEB (val, p, end);
c0ea7c52
JL
17038
17039 switch (val)
17040 {
17041 case Val_GNU_MSP430_Data_Region_Any:
17042 printf (_("Any Region\n"));
17043 break;
17044 case Val_GNU_MSP430_Data_Region_Lower:
17045 printf (_("Lower Region Only\n"));
17046 break;
17047 default:
cd30bcef 17048 printf ("??? (%u)\n", val);
c0ea7c52
JL
17049 }
17050 return p;
17051 }
17052 return display_tag_value (tag & 1, p, end);
17053}
17054
2dc8dd17
JW
17055struct riscv_attr_tag_t {
17056 const char *name;
cd30bcef 17057 unsigned int tag;
2dc8dd17
JW
17058};
17059
17060static struct riscv_attr_tag_t riscv_attr_tag[] =
17061{
17062#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17063 T(arch),
17064 T(priv_spec),
17065 T(priv_spec_minor),
17066 T(priv_spec_revision),
17067 T(unaligned_access),
17068 T(stack_align),
17069#undef T
17070};
17071
17072static unsigned char *
17073display_riscv_attribute (unsigned char *p,
17074 const unsigned char * const end)
17075{
cd30bcef
AM
17076 unsigned int val;
17077 unsigned int tag;
2dc8dd17
JW
17078 struct riscv_attr_tag_t *attr = NULL;
17079 unsigned i;
17080
cd30bcef 17081 READ_ULEB (tag, p, end);
2dc8dd17
JW
17082
17083 /* Find the name of attribute. */
17084 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17085 {
17086 if (riscv_attr_tag[i].tag == tag)
17087 {
17088 attr = &riscv_attr_tag[i];
17089 break;
17090 }
17091 }
17092
17093 if (attr)
17094 printf (" %s: ", attr->name);
17095 else
17096 return display_tag_value (tag, p, end);
17097
17098 switch (tag)
17099 {
17100 case Tag_RISCV_priv_spec:
17101 case Tag_RISCV_priv_spec_minor:
17102 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17103 READ_ULEB (val, p, end);
17104 printf (_("%u\n"), val);
2dc8dd17
JW
17105 break;
17106 case Tag_RISCV_unaligned_access:
cd30bcef 17107 READ_ULEB (val, p, end);
2dc8dd17
JW
17108 switch (val)
17109 {
17110 case 0:
17111 printf (_("No unaligned access\n"));
17112 break;
17113 case 1:
17114 printf (_("Unaligned access\n"));
17115 break;
17116 }
17117 break;
17118 case Tag_RISCV_stack_align:
cd30bcef
AM
17119 READ_ULEB (val, p, end);
17120 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17121 break;
17122 case Tag_RISCV_arch:
17123 p = display_tag_value (-1, p, end);
17124 break;
17125 default:
17126 return display_tag_value (tag, p, end);
17127 }
17128
17129 return p;
17130}
17131
0861f561
CQ
17132static unsigned char *
17133display_csky_attribute (unsigned char * p,
17134 const unsigned char * const end)
17135{
17136 unsigned int tag;
17137 unsigned int val;
17138 READ_ULEB (tag, p, end);
17139
17140 if (tag >= Tag_CSKY_MAX)
17141 {
17142 return display_tag_value (-1, p, end);
17143 }
17144
17145 switch (tag)
17146 {
17147 case Tag_CSKY_ARCH_NAME:
17148 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17149 return display_tag_value (-1, p, end);
17150 case Tag_CSKY_CPU_NAME:
17151 printf (" Tag_CSKY_CPU_NAME:\t\t");
17152 return display_tag_value (-1, p, end);
17153
17154 case Tag_CSKY_ISA_FLAGS:
17155 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17156 return display_tag_value (0, p, end);
17157 case Tag_CSKY_ISA_EXT_FLAGS:
17158 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17159 return display_tag_value (0, p, end);
17160
17161 case Tag_CSKY_DSP_VERSION:
17162 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17163 READ_ULEB (val, p, end);
17164 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17165 printf ("DSP Extension\n");
17166 else if (val == VAL_CSKY_DSP_VERSION_2)
17167 printf ("DSP 2.0\n");
17168 break;
17169
17170 case Tag_CSKY_VDSP_VERSION:
17171 printf (" Tag_CSKY_VDSP_VERSION:\t");
17172 READ_ULEB (val, p, end);
17173 printf ("VDSP Version %d\n", val);
17174 break;
17175
17176 case Tag_CSKY_FPU_VERSION:
17177 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17178 READ_ULEB (val, p, end);
17179 if (val == VAL_CSKY_FPU_VERSION_1)
17180 printf ("ABIV1 FPU Version 1\n");
17181 else if (val == VAL_CSKY_FPU_VERSION_2)
17182 printf ("FPU Version 2\n");
17183 break;
17184
17185 case Tag_CSKY_FPU_ABI:
17186 printf (" Tag_CSKY_FPU_ABI:\t\t");
17187 READ_ULEB (val, p, end);
17188 if (val == VAL_CSKY_FPU_ABI_HARD)
17189 printf ("Hard\n");
17190 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17191 printf ("SoftFP\n");
17192 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17193 printf ("Soft\n");
17194 break;
17195 case Tag_CSKY_FPU_ROUNDING:
17196 READ_ULEB (val, p, end);
17197 if (val == 1) {
17198 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17199 printf ("Needed\n");
17200 }
17201 break;
17202 case Tag_CSKY_FPU_DENORMAL:
17203 READ_ULEB (val, p, end);
17204 if (val == 1) {
17205 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17206 printf ("Needed\n");
17207 }
17208 break;
17209 case Tag_CSKY_FPU_Exception:
17210 READ_ULEB (val, p, end);
17211 if (val == 1) {
17212 printf (" Tag_CSKY_FPU_Exception:\t");
17213 printf ("Needed\n");
17214 }
17215 break;
17216 case Tag_CSKY_FPU_NUMBER_MODULE:
17217 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17218 return display_tag_value (-1, p, end);
17219 case Tag_CSKY_FPU_HARDFP:
17220 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17221 READ_ULEB (val, p, end);
17222 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17223 printf (" Half");
17224 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17225 printf (" Single");
17226 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17227 printf (" Double");
17228 printf ("\n");
17229 break;
17230 default:
17231 return display_tag_value (tag, p, end);
17232 }
17233 return p;
17234}
17235
015dc7e1 17236static bool
dda8d76d 17237process_attributes (Filedata * filedata,
60bca95a 17238 const char * public_name,
104d59d1 17239 unsigned int proc_type,
f6f0e17b 17240 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17241 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17242{
2cf0635d 17243 Elf_Internal_Shdr * sect;
11c1ff18 17244 unsigned i;
015dc7e1 17245 bool res = true;
11c1ff18
PB
17246
17247 /* Find the section header so that we get the size. */
dda8d76d
NC
17248 for (i = 0, sect = filedata->section_headers;
17249 i < filedata->file_header.e_shnum;
11c1ff18
PB
17250 i++, sect++)
17251 {
071436c6
NC
17252 unsigned char * contents;
17253 unsigned char * p;
17254
104d59d1 17255 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17256 continue;
17257
dda8d76d 17258 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17259 sect->sh_size, _("attributes"));
60bca95a 17260 if (contents == NULL)
32ec8896 17261 {
015dc7e1 17262 res = false;
32ec8896
NC
17263 continue;
17264 }
60bca95a 17265
11c1ff18 17266 p = contents;
60abdbed
NC
17267 /* The first character is the version of the attributes.
17268 Currently only version 1, (aka 'A') is recognised here. */
17269 if (*p != 'A')
32ec8896
NC
17270 {
17271 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17272 res = false;
32ec8896 17273 }
60abdbed 17274 else
11c1ff18 17275 {
071436c6
NC
17276 bfd_vma section_len;
17277
17278 section_len = sect->sh_size - 1;
11c1ff18 17279 p++;
60bca95a 17280
071436c6 17281 while (section_len > 0)
11c1ff18 17282 {
071436c6 17283 bfd_vma attr_len;
e9847026 17284 unsigned int namelen;
015dc7e1
AM
17285 bool public_section;
17286 bool gnu_section;
11c1ff18 17287
071436c6 17288 if (section_len <= 4)
e0a31db1
NC
17289 {
17290 error (_("Tag section ends prematurely\n"));
015dc7e1 17291 res = false;
e0a31db1
NC
17292 break;
17293 }
071436c6 17294 attr_len = byte_get (p, 4);
11c1ff18 17295 p += 4;
60bca95a 17296
071436c6 17297 if (attr_len > section_len)
11c1ff18 17298 {
071436c6
NC
17299 error (_("Bad attribute length (%u > %u)\n"),
17300 (unsigned) attr_len, (unsigned) section_len);
17301 attr_len = section_len;
015dc7e1 17302 res = false;
11c1ff18 17303 }
74e1a04b 17304 /* PR 17531: file: 001-101425-0.004 */
071436c6 17305 else if (attr_len < 5)
74e1a04b 17306 {
071436c6 17307 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17308 res = false;
74e1a04b
NC
17309 break;
17310 }
e9847026 17311
071436c6
NC
17312 section_len -= attr_len;
17313 attr_len -= 4;
17314
17315 namelen = strnlen ((char *) p, attr_len) + 1;
17316 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17317 {
17318 error (_("Corrupt attribute section name\n"));
015dc7e1 17319 res = false;
e9847026
NC
17320 break;
17321 }
17322
071436c6
NC
17323 printf (_("Attribute Section: "));
17324 print_symbol (INT_MAX, (const char *) p);
17325 putchar ('\n');
60bca95a
NC
17326
17327 if (public_name && streq ((char *) p, public_name))
015dc7e1 17328 public_section = true;
11c1ff18 17329 else
015dc7e1 17330 public_section = false;
60bca95a
NC
17331
17332 if (streq ((char *) p, "gnu"))
015dc7e1 17333 gnu_section = true;
104d59d1 17334 else
015dc7e1 17335 gnu_section = false;
60bca95a 17336
11c1ff18 17337 p += namelen;
071436c6 17338 attr_len -= namelen;
e0a31db1 17339
071436c6 17340 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17341 {
e0a31db1 17342 int tag;
cd30bcef 17343 unsigned int val;
11c1ff18 17344 bfd_vma size;
071436c6 17345 unsigned char * end;
60bca95a 17346
e0a31db1 17347 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17348 if (attr_len < 6)
e0a31db1
NC
17349 {
17350 error (_("Unused bytes at end of section\n"));
015dc7e1 17351 res = false;
e0a31db1
NC
17352 section_len = 0;
17353 break;
17354 }
17355
17356 tag = *(p++);
11c1ff18 17357 size = byte_get (p, 4);
071436c6 17358 if (size > attr_len)
11c1ff18 17359 {
e9847026 17360 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17361 (unsigned) size, (unsigned) attr_len);
015dc7e1 17362 res = false;
071436c6 17363 size = attr_len;
11c1ff18 17364 }
e0a31db1
NC
17365 /* PR binutils/17531: Safe handling of corrupt files. */
17366 if (size < 6)
17367 {
17368 error (_("Bad subsection length (%u < 6)\n"),
17369 (unsigned) size);
015dc7e1 17370 res = false;
e0a31db1
NC
17371 section_len = 0;
17372 break;
17373 }
60bca95a 17374
071436c6 17375 attr_len -= size;
11c1ff18 17376 end = p + size - 1;
071436c6 17377 assert (end <= contents + sect->sh_size);
11c1ff18 17378 p += 4;
60bca95a 17379
11c1ff18
PB
17380 switch (tag)
17381 {
17382 case 1:
2b692964 17383 printf (_("File Attributes\n"));
11c1ff18
PB
17384 break;
17385 case 2:
2b692964 17386 printf (_("Section Attributes:"));
11c1ff18
PB
17387 goto do_numlist;
17388 case 3:
2b692964 17389 printf (_("Symbol Attributes:"));
1a0670f3 17390 /* Fall through. */
11c1ff18
PB
17391 do_numlist:
17392 for (;;)
17393 {
cd30bcef 17394 READ_ULEB (val, p, end);
11c1ff18
PB
17395 if (val == 0)
17396 break;
17397 printf (" %d", val);
17398 }
17399 printf ("\n");
17400 break;
17401 default:
2b692964 17402 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 17403 public_section = false;
11c1ff18
PB
17404 break;
17405 }
60bca95a 17406
071436c6 17407 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
17408 {
17409 while (p < end)
f6f0e17b 17410 p = display_pub_attribute (p, end);
60abdbed 17411 assert (p == end);
104d59d1 17412 }
071436c6 17413 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
17414 {
17415 while (p < end)
17416 p = display_gnu_attribute (p,
f6f0e17b
NC
17417 display_proc_gnu_attribute,
17418 end);
60abdbed 17419 assert (p == end);
11c1ff18 17420 }
071436c6 17421 else if (p < end)
11c1ff18 17422 {
071436c6 17423 printf (_(" Unknown attribute:\n"));
f6f0e17b 17424 display_raw_attribute (p, end);
11c1ff18
PB
17425 p = end;
17426 }
071436c6
NC
17427 else
17428 attr_len = 0;
11c1ff18
PB
17429 }
17430 }
17431 }
d70c5fc7 17432
60bca95a 17433 free (contents);
11c1ff18 17434 }
32ec8896
NC
17435
17436 return res;
11c1ff18
PB
17437}
17438
ccb4c951
RS
17439/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
17440 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
17441 and return the VMA of the next entry, or -1 if there was a problem.
17442 Does not read from DATA_END or beyond. */
ccb4c951
RS
17443
17444static bfd_vma
82b1b41b
NC
17445print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
17446 unsigned char * data_end)
ccb4c951
RS
17447{
17448 printf (" ");
17449 print_vma (addr, LONG_HEX);
17450 printf (" ");
17451 if (addr < pltgot + 0xfff0)
17452 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
17453 else
17454 printf ("%10s", "");
17455 printf (" ");
17456 if (data == NULL)
2b692964 17457 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
17458 else
17459 {
17460 bfd_vma entry;
82b1b41b 17461 unsigned char * from = data + addr - pltgot;
ccb4c951 17462
82b1b41b
NC
17463 if (from + (is_32bit_elf ? 4 : 8) > data_end)
17464 {
17465 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
17466 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
17467 return (bfd_vma) -1;
17468 }
17469 else
17470 {
17471 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17472 print_vma (entry, LONG_HEX);
17473 }
ccb4c951
RS
17474 }
17475 return addr + (is_32bit_elf ? 4 : 8);
17476}
17477
861fb55a
DJ
17478/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
17479 PLTGOT. Print the Address and Initial fields of an entry at VMA
17480 ADDR and return the VMA of the next entry. */
17481
17482static bfd_vma
2cf0635d 17483print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
17484{
17485 printf (" ");
17486 print_vma (addr, LONG_HEX);
17487 printf (" ");
17488 if (data == NULL)
2b692964 17489 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
17490 else
17491 {
17492 bfd_vma entry;
17493
17494 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17495 print_vma (entry, LONG_HEX);
17496 }
17497 return addr + (is_32bit_elf ? 4 : 8);
17498}
17499
351cdf24
MF
17500static void
17501print_mips_ases (unsigned int mask)
17502{
17503 if (mask & AFL_ASE_DSP)
17504 fputs ("\n\tDSP ASE", stdout);
17505 if (mask & AFL_ASE_DSPR2)
17506 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
17507 if (mask & AFL_ASE_DSPR3)
17508 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
17509 if (mask & AFL_ASE_EVA)
17510 fputs ("\n\tEnhanced VA Scheme", stdout);
17511 if (mask & AFL_ASE_MCU)
17512 fputs ("\n\tMCU (MicroController) ASE", stdout);
17513 if (mask & AFL_ASE_MDMX)
17514 fputs ("\n\tMDMX ASE", stdout);
17515 if (mask & AFL_ASE_MIPS3D)
17516 fputs ("\n\tMIPS-3D ASE", stdout);
17517 if (mask & AFL_ASE_MT)
17518 fputs ("\n\tMT ASE", stdout);
17519 if (mask & AFL_ASE_SMARTMIPS)
17520 fputs ("\n\tSmartMIPS ASE", stdout);
17521 if (mask & AFL_ASE_VIRT)
17522 fputs ("\n\tVZ ASE", stdout);
17523 if (mask & AFL_ASE_MSA)
17524 fputs ("\n\tMSA ASE", stdout);
17525 if (mask & AFL_ASE_MIPS16)
17526 fputs ("\n\tMIPS16 ASE", stdout);
17527 if (mask & AFL_ASE_MICROMIPS)
17528 fputs ("\n\tMICROMIPS ASE", stdout);
17529 if (mask & AFL_ASE_XPA)
17530 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
17531 if (mask & AFL_ASE_MIPS16E2)
17532 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
17533 if (mask & AFL_ASE_CRC)
17534 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
17535 if (mask & AFL_ASE_GINV)
17536 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
17537 if (mask & AFL_ASE_LOONGSON_MMI)
17538 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
17539 if (mask & AFL_ASE_LOONGSON_CAM)
17540 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
17541 if (mask & AFL_ASE_LOONGSON_EXT)
17542 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
17543 if (mask & AFL_ASE_LOONGSON_EXT2)
17544 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
17545 if (mask == 0)
17546 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
17547 else if ((mask & ~AFL_ASE_MASK) != 0)
17548 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
17549}
17550
17551static void
17552print_mips_isa_ext (unsigned int isa_ext)
17553{
17554 switch (isa_ext)
17555 {
17556 case 0:
17557 fputs (_("None"), stdout);
17558 break;
17559 case AFL_EXT_XLR:
17560 fputs ("RMI XLR", stdout);
17561 break;
2c629856
N
17562 case AFL_EXT_OCTEON3:
17563 fputs ("Cavium Networks Octeon3", stdout);
17564 break;
351cdf24
MF
17565 case AFL_EXT_OCTEON2:
17566 fputs ("Cavium Networks Octeon2", stdout);
17567 break;
17568 case AFL_EXT_OCTEONP:
17569 fputs ("Cavium Networks OcteonP", stdout);
17570 break;
351cdf24
MF
17571 case AFL_EXT_OCTEON:
17572 fputs ("Cavium Networks Octeon", stdout);
17573 break;
17574 case AFL_EXT_5900:
17575 fputs ("Toshiba R5900", stdout);
17576 break;
17577 case AFL_EXT_4650:
17578 fputs ("MIPS R4650", stdout);
17579 break;
17580 case AFL_EXT_4010:
17581 fputs ("LSI R4010", stdout);
17582 break;
17583 case AFL_EXT_4100:
17584 fputs ("NEC VR4100", stdout);
17585 break;
17586 case AFL_EXT_3900:
17587 fputs ("Toshiba R3900", stdout);
17588 break;
17589 case AFL_EXT_10000:
17590 fputs ("MIPS R10000", stdout);
17591 break;
17592 case AFL_EXT_SB1:
17593 fputs ("Broadcom SB-1", stdout);
17594 break;
17595 case AFL_EXT_4111:
17596 fputs ("NEC VR4111/VR4181", stdout);
17597 break;
17598 case AFL_EXT_4120:
17599 fputs ("NEC VR4120", stdout);
17600 break;
17601 case AFL_EXT_5400:
17602 fputs ("NEC VR5400", stdout);
17603 break;
17604 case AFL_EXT_5500:
17605 fputs ("NEC VR5500", stdout);
17606 break;
17607 case AFL_EXT_LOONGSON_2E:
17608 fputs ("ST Microelectronics Loongson 2E", stdout);
17609 break;
17610 case AFL_EXT_LOONGSON_2F:
17611 fputs ("ST Microelectronics Loongson 2F", stdout);
17612 break;
38bf472a
MR
17613 case AFL_EXT_INTERAPTIV_MR2:
17614 fputs ("Imagination interAptiv MR2", stdout);
17615 break;
351cdf24 17616 default:
00ac7aa0 17617 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
17618 }
17619}
17620
32ec8896 17621static signed int
351cdf24
MF
17622get_mips_reg_size (int reg_size)
17623{
17624 return (reg_size == AFL_REG_NONE) ? 0
17625 : (reg_size == AFL_REG_32) ? 32
17626 : (reg_size == AFL_REG_64) ? 64
17627 : (reg_size == AFL_REG_128) ? 128
17628 : -1;
17629}
17630
015dc7e1 17631static bool
dda8d76d 17632process_mips_specific (Filedata * filedata)
5b18a4bc 17633{
2cf0635d 17634 Elf_Internal_Dyn * entry;
351cdf24 17635 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
17636 size_t liblist_offset = 0;
17637 size_t liblistno = 0;
17638 size_t conflictsno = 0;
17639 size_t options_offset = 0;
17640 size_t conflicts_offset = 0;
861fb55a
DJ
17641 size_t pltrelsz = 0;
17642 size_t pltrel = 0;
ccb4c951 17643 bfd_vma pltgot = 0;
861fb55a
DJ
17644 bfd_vma mips_pltgot = 0;
17645 bfd_vma jmprel = 0;
ccb4c951
RS
17646 bfd_vma local_gotno = 0;
17647 bfd_vma gotsym = 0;
17648 bfd_vma symtabno = 0;
015dc7e1 17649 bool res = true;
103f02d3 17650
dda8d76d 17651 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 17652 display_mips_gnu_attribute))
015dc7e1 17653 res = false;
2cf19d5c 17654
dda8d76d 17655 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
17656
17657 if (sect != NULL)
17658 {
17659 Elf_External_ABIFlags_v0 *abiflags_ext;
17660 Elf_Internal_ABIFlags_v0 abiflags_in;
17661
17662 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
17663 {
17664 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 17665 res = false;
32ec8896 17666 }
351cdf24
MF
17667 else
17668 {
dda8d76d 17669 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
17670 sect->sh_size, _("MIPS ABI Flags section"));
17671 if (abiflags_ext)
17672 {
17673 abiflags_in.version = BYTE_GET (abiflags_ext->version);
17674 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
17675 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
17676 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
17677 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
17678 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
17679 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
17680 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
17681 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
17682 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
17683 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
17684
17685 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
17686 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
17687 if (abiflags_in.isa_rev > 1)
17688 printf ("r%d", abiflags_in.isa_rev);
17689 printf ("\nGPR size: %d",
17690 get_mips_reg_size (abiflags_in.gpr_size));
17691 printf ("\nCPR1 size: %d",
17692 get_mips_reg_size (abiflags_in.cpr1_size));
17693 printf ("\nCPR2 size: %d",
17694 get_mips_reg_size (abiflags_in.cpr2_size));
17695 fputs ("\nFP ABI: ", stdout);
17696 print_mips_fp_abi_value (abiflags_in.fp_abi);
17697 fputs ("ISA Extension: ", stdout);
17698 print_mips_isa_ext (abiflags_in.isa_ext);
17699 fputs ("\nASEs:", stdout);
17700 print_mips_ases (abiflags_in.ases);
17701 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
17702 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
17703 fputc ('\n', stdout);
17704 free (abiflags_ext);
17705 }
17706 }
17707 }
17708
19e6b90e 17709 /* We have a lot of special sections. Thanks SGI! */
978c4450 17710 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
17711 {
17712 /* No dynamic information available. See if there is static GOT. */
dda8d76d 17713 sect = find_section (filedata, ".got");
bbdd9a68
MR
17714 if (sect != NULL)
17715 {
17716 unsigned char *data_end;
17717 unsigned char *data;
17718 bfd_vma ent, end;
17719 int addr_size;
17720
17721 pltgot = sect->sh_addr;
17722
17723 ent = pltgot;
17724 addr_size = (is_32bit_elf ? 4 : 8);
17725 end = pltgot + sect->sh_size;
17726
dda8d76d 17727 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
17728 end - pltgot, 1,
17729 _("Global Offset Table data"));
17730 /* PR 12855: Null data is handled gracefully throughout. */
17731 data_end = data + (end - pltgot);
17732
17733 printf (_("\nStatic GOT:\n"));
17734 printf (_(" Canonical gp value: "));
17735 print_vma (ent + 0x7ff0, LONG_HEX);
17736 printf ("\n\n");
17737
17738 /* In a dynamic binary GOT[0] is reserved for the dynamic
17739 loader to store the lazy resolver pointer, however in
17740 a static binary it may well have been omitted and GOT
17741 reduced to a table of addresses.
17742 PR 21344: Check for the entry being fully available
17743 before fetching it. */
17744 if (data
17745 && data + ent - pltgot + addr_size <= data_end
17746 && byte_get (data + ent - pltgot, addr_size) == 0)
17747 {
17748 printf (_(" Reserved entries:\n"));
17749 printf (_(" %*s %10s %*s\n"),
17750 addr_size * 2, _("Address"), _("Access"),
17751 addr_size * 2, _("Value"));
17752 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17753 printf ("\n");
17754 if (ent == (bfd_vma) -1)
17755 goto sgot_print_fail;
17756
17757 /* Check for the MSB of GOT[1] being set, identifying a
17758 GNU object. This entry will be used by some runtime
17759 loaders, to store the module pointer. Otherwise this
17760 is an ordinary local entry.
17761 PR 21344: Check for the entry being fully available
17762 before fetching it. */
17763 if (data
17764 && data + ent - pltgot + addr_size <= data_end
17765 && (byte_get (data + ent - pltgot, addr_size)
17766 >> (addr_size * 8 - 1)) != 0)
17767 {
17768 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17769 printf ("\n");
17770 if (ent == (bfd_vma) -1)
17771 goto sgot_print_fail;
17772 }
17773 printf ("\n");
17774 }
17775
f17e9d8a 17776 if (data != NULL && ent < end)
bbdd9a68
MR
17777 {
17778 printf (_(" Local entries:\n"));
17779 printf (" %*s %10s %*s\n",
17780 addr_size * 2, _("Address"), _("Access"),
17781 addr_size * 2, _("Value"));
17782 while (ent < end)
17783 {
17784 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17785 printf ("\n");
17786 if (ent == (bfd_vma) -1)
17787 goto sgot_print_fail;
17788 }
17789 printf ("\n");
17790 }
17791
17792 sgot_print_fail:
9db70fc3 17793 free (data);
bbdd9a68
MR
17794 }
17795 return res;
17796 }
252b5132 17797
978c4450 17798 for (entry = filedata->dynamic_section;
071436c6 17799 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
17800 (entry < filedata->dynamic_section + filedata->dynamic_nent
17801 && entry->d_tag != DT_NULL);
071436c6 17802 ++entry)
252b5132
RH
17803 switch (entry->d_tag)
17804 {
17805 case DT_MIPS_LIBLIST:
d93f0186 17806 liblist_offset
dda8d76d 17807 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17808 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
17809 break;
17810 case DT_MIPS_LIBLISTNO:
17811 liblistno = entry->d_un.d_val;
17812 break;
17813 case DT_MIPS_OPTIONS:
dda8d76d 17814 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
17815 break;
17816 case DT_MIPS_CONFLICT:
d93f0186 17817 conflicts_offset
dda8d76d 17818 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17819 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
17820 break;
17821 case DT_MIPS_CONFLICTNO:
17822 conflictsno = entry->d_un.d_val;
17823 break;
ccb4c951 17824 case DT_PLTGOT:
861fb55a
DJ
17825 pltgot = entry->d_un.d_ptr;
17826 break;
ccb4c951
RS
17827 case DT_MIPS_LOCAL_GOTNO:
17828 local_gotno = entry->d_un.d_val;
17829 break;
17830 case DT_MIPS_GOTSYM:
17831 gotsym = entry->d_un.d_val;
17832 break;
17833 case DT_MIPS_SYMTABNO:
17834 symtabno = entry->d_un.d_val;
17835 break;
861fb55a
DJ
17836 case DT_MIPS_PLTGOT:
17837 mips_pltgot = entry->d_un.d_ptr;
17838 break;
17839 case DT_PLTREL:
17840 pltrel = entry->d_un.d_val;
17841 break;
17842 case DT_PLTRELSZ:
17843 pltrelsz = entry->d_un.d_val;
17844 break;
17845 case DT_JMPREL:
17846 jmprel = entry->d_un.d_ptr;
17847 break;
252b5132
RH
17848 default:
17849 break;
17850 }
17851
17852 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
17853 {
2cf0635d 17854 Elf32_External_Lib * elib;
252b5132
RH
17855 size_t cnt;
17856
dda8d76d 17857 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
17858 sizeof (Elf32_External_Lib),
17859 liblistno,
17860 _("liblist section data"));
a6e9f9df 17861 if (elib)
252b5132 17862 {
d3a49aa8
AM
17863 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
17864 "\nSection '.liblist' contains %lu entries:\n",
17865 (unsigned long) liblistno),
a6e9f9df 17866 (unsigned long) liblistno);
2b692964 17867 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
17868 stdout);
17869
17870 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 17871 {
a6e9f9df 17872 Elf32_Lib liblist;
91d6fa6a 17873 time_t atime;
d5b07ef4 17874 char timebuf[128];
2cf0635d 17875 struct tm * tmp;
a6e9f9df
AM
17876
17877 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17878 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
17879 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17880 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17881 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17882
91d6fa6a 17883 tmp = gmtime (&atime);
e9e44622
JJ
17884 snprintf (timebuf, sizeof (timebuf),
17885 "%04u-%02u-%02uT%02u:%02u:%02u",
17886 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17887 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 17888
31104126 17889 printf ("%3lu: ", (unsigned long) cnt);
978c4450
AM
17890 if (VALID_DYNAMIC_NAME (filedata, liblist.l_name))
17891 print_symbol (20, GET_DYNAMIC_NAME (filedata, liblist.l_name));
d79b3d50 17892 else
2b692964 17893 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
17894 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
17895 liblist.l_version);
a6e9f9df
AM
17896
17897 if (liblist.l_flags == 0)
2b692964 17898 puts (_(" NONE"));
a6e9f9df
AM
17899 else
17900 {
17901 static const struct
252b5132 17902 {
2cf0635d 17903 const char * name;
a6e9f9df 17904 int bit;
252b5132 17905 }
a6e9f9df
AM
17906 l_flags_vals[] =
17907 {
17908 { " EXACT_MATCH", LL_EXACT_MATCH },
17909 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
17910 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
17911 { " EXPORTS", LL_EXPORTS },
17912 { " DELAY_LOAD", LL_DELAY_LOAD },
17913 { " DELTA", LL_DELTA }
17914 };
17915 int flags = liblist.l_flags;
17916 size_t fcnt;
17917
60bca95a 17918 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
17919 if ((flags & l_flags_vals[fcnt].bit) != 0)
17920 {
17921 fputs (l_flags_vals[fcnt].name, stdout);
17922 flags ^= l_flags_vals[fcnt].bit;
17923 }
17924 if (flags != 0)
17925 printf (" %#x", (unsigned int) flags);
252b5132 17926
a6e9f9df
AM
17927 puts ("");
17928 }
252b5132 17929 }
252b5132 17930
a6e9f9df
AM
17931 free (elib);
17932 }
32ec8896 17933 else
015dc7e1 17934 res = false;
252b5132
RH
17935 }
17936
17937 if (options_offset != 0)
17938 {
2cf0635d 17939 Elf_External_Options * eopt;
252b5132
RH
17940 size_t offset;
17941 int cnt;
dda8d76d 17942 sect = filedata->section_headers;
252b5132
RH
17943
17944 /* Find the section header so that we get the size. */
dda8d76d 17945 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 17946 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
17947 if (sect == NULL)
17948 {
17949 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 17950 return false;
071436c6 17951 }
7fc0c668
NC
17952 /* PR 24243 */
17953 if (sect->sh_size < sizeof (* eopt))
17954 {
17955 error (_("The MIPS options section is too small.\n"));
015dc7e1 17956 return false;
7fc0c668 17957 }
252b5132 17958
dda8d76d 17959 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 17960 sect->sh_size, _("options"));
a6e9f9df 17961 if (eopt)
252b5132 17962 {
fd17d1e6 17963 Elf_Internal_Options option;
76da6bbe 17964
a6e9f9df 17965 offset = cnt = 0;
82b1b41b 17966 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 17967 {
2cf0635d 17968 Elf_External_Options * eoption;
fd17d1e6 17969 unsigned int optsize;
252b5132 17970
a6e9f9df 17971 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 17972
fd17d1e6 17973 optsize = BYTE_GET (eoption->size);
76da6bbe 17974
82b1b41b 17975 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
17976 if (optsize < sizeof (* eopt)
17977 || optsize > sect->sh_size - offset)
82b1b41b 17978 {
645f43a8 17979 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 17980 optsize);
645f43a8 17981 free (eopt);
015dc7e1 17982 return false;
82b1b41b 17983 }
fd17d1e6 17984 offset += optsize;
a6e9f9df
AM
17985 ++cnt;
17986 }
252b5132 17987
d3a49aa8
AM
17988 printf (ngettext ("\nSection '%s' contains %d entry:\n",
17989 "\nSection '%s' contains %d entries:\n",
17990 cnt),
dda8d76d 17991 printable_section_name (filedata, sect), cnt);
76da6bbe 17992
82b1b41b 17993 offset = 0;
a6e9f9df 17994 while (cnt-- > 0)
252b5132 17995 {
a6e9f9df 17996 size_t len;
fd17d1e6
AM
17997 Elf_External_Options * eoption;
17998
17999 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18000
18001 option.kind = BYTE_GET (eoption->kind);
18002 option.size = BYTE_GET (eoption->size);
18003 option.section = BYTE_GET (eoption->section);
18004 option.info = BYTE_GET (eoption->info);
a6e9f9df 18005
fd17d1e6 18006 switch (option.kind)
252b5132 18007 {
a6e9f9df
AM
18008 case ODK_NULL:
18009 /* This shouldn't happen. */
d0c4e780 18010 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18011 option.section, option.info);
a6e9f9df 18012 break;
2e6be59c 18013
a6e9f9df
AM
18014 case ODK_REGINFO:
18015 printf (" REGINFO ");
dda8d76d 18016 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18017 {
2cf0635d 18018 Elf32_External_RegInfo * ereg;
b34976b6 18019 Elf32_RegInfo reginfo;
a6e9f9df 18020
2e6be59c 18021 /* 32bit form. */
fd17d1e6
AM
18022 if (option.size < (sizeof (Elf_External_Options)
18023 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18024 {
18025 printf (_("<corrupt>\n"));
18026 error (_("Truncated MIPS REGINFO option\n"));
18027 cnt = 0;
18028 break;
18029 }
18030
fd17d1e6 18031 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18032
a6e9f9df
AM
18033 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18034 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18035 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18036 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18037 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18038 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18039
d0c4e780
AM
18040 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18041 reginfo.ri_gprmask, reginfo.ri_gp_value);
18042 printf (" "
18043 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18044 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18045 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18046 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18047 }
18048 else
18049 {
18050 /* 64 bit form. */
2cf0635d 18051 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18052 Elf64_Internal_RegInfo reginfo;
18053
fd17d1e6
AM
18054 if (option.size < (sizeof (Elf_External_Options)
18055 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18056 {
18057 printf (_("<corrupt>\n"));
18058 error (_("Truncated MIPS REGINFO option\n"));
18059 cnt = 0;
18060 break;
18061 }
18062
fd17d1e6 18063 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18064 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18065 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18066 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18067 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18068 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18069 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18070
d0c4e780
AM
18071 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18072 reginfo.ri_gprmask, reginfo.ri_gp_value);
18073 printf (" "
18074 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18075 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18076 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18077 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18078 }
fd17d1e6 18079 offset += option.size;
a6e9f9df 18080 continue;
2e6be59c 18081
a6e9f9df
AM
18082 case ODK_EXCEPTIONS:
18083 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18084 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18085 fputs (") fpe_max(", stdout);
fd17d1e6 18086 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18087 fputs (")", stdout);
18088
fd17d1e6 18089 if (option.info & OEX_PAGE0)
a6e9f9df 18090 fputs (" PAGE0", stdout);
fd17d1e6 18091 if (option.info & OEX_SMM)
a6e9f9df 18092 fputs (" SMM", stdout);
fd17d1e6 18093 if (option.info & OEX_FPDBUG)
a6e9f9df 18094 fputs (" FPDBUG", stdout);
fd17d1e6 18095 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18096 fputs (" DISMISS", stdout);
18097 break;
2e6be59c 18098
a6e9f9df
AM
18099 case ODK_PAD:
18100 fputs (" PAD ", stdout);
fd17d1e6 18101 if (option.info & OPAD_PREFIX)
a6e9f9df 18102 fputs (" PREFIX", stdout);
fd17d1e6 18103 if (option.info & OPAD_POSTFIX)
a6e9f9df 18104 fputs (" POSTFIX", stdout);
fd17d1e6 18105 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18106 fputs (" SYMBOL", stdout);
18107 break;
2e6be59c 18108
a6e9f9df
AM
18109 case ODK_HWPATCH:
18110 fputs (" HWPATCH ", stdout);
fd17d1e6 18111 if (option.info & OHW_R4KEOP)
a6e9f9df 18112 fputs (" R4KEOP", stdout);
fd17d1e6 18113 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18114 fputs (" R8KPFETCH", stdout);
fd17d1e6 18115 if (option.info & OHW_R5KEOP)
a6e9f9df 18116 fputs (" R5KEOP", stdout);
fd17d1e6 18117 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18118 fputs (" R5KCVTL", stdout);
18119 break;
2e6be59c 18120
a6e9f9df
AM
18121 case ODK_FILL:
18122 fputs (" FILL ", stdout);
18123 /* XXX Print content of info word? */
18124 break;
2e6be59c 18125
a6e9f9df
AM
18126 case ODK_TAGS:
18127 fputs (" TAGS ", stdout);
18128 /* XXX Print content of info word? */
18129 break;
2e6be59c 18130
a6e9f9df
AM
18131 case ODK_HWAND:
18132 fputs (" HWAND ", stdout);
fd17d1e6 18133 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18134 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18135 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18136 fputs (" R4KEOP_CLEAN", stdout);
18137 break;
2e6be59c 18138
a6e9f9df
AM
18139 case ODK_HWOR:
18140 fputs (" HWOR ", stdout);
fd17d1e6 18141 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18142 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18143 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18144 fputs (" R4KEOP_CLEAN", stdout);
18145 break;
2e6be59c 18146
a6e9f9df 18147 case ODK_GP_GROUP:
d0c4e780 18148 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18149 option.info & OGP_GROUP,
18150 (option.info & OGP_SELF) >> 16);
a6e9f9df 18151 break;
2e6be59c 18152
a6e9f9df 18153 case ODK_IDENT:
d0c4e780 18154 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18155 option.info & OGP_GROUP,
18156 (option.info & OGP_SELF) >> 16);
a6e9f9df 18157 break;
2e6be59c 18158
a6e9f9df
AM
18159 default:
18160 /* This shouldn't happen. */
d0c4e780 18161 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18162 option.kind, option.section, option.info);
a6e9f9df 18163 break;
252b5132 18164 }
a6e9f9df 18165
2cf0635d 18166 len = sizeof (* eopt);
fd17d1e6 18167 while (len < option.size)
82b1b41b 18168 {
fd17d1e6 18169 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18170
82b1b41b
NC
18171 if (ISPRINT (datum))
18172 printf ("%c", datum);
18173 else
18174 printf ("\\%03o", datum);
18175 len ++;
18176 }
a6e9f9df 18177 fputs ("\n", stdout);
82b1b41b 18178
fd17d1e6 18179 offset += option.size;
252b5132 18180 }
a6e9f9df 18181 free (eopt);
252b5132 18182 }
32ec8896 18183 else
015dc7e1 18184 res = false;
252b5132
RH
18185 }
18186
18187 if (conflicts_offset != 0 && conflictsno != 0)
18188 {
2cf0635d 18189 Elf32_Conflict * iconf;
252b5132
RH
18190 size_t cnt;
18191
978c4450 18192 if (filedata->dynamic_symbols == NULL)
252b5132 18193 {
591a748a 18194 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18195 return false;
252b5132
RH
18196 }
18197
7296a62a
NC
18198 /* PR 21345 - print a slightly more helpful error message
18199 if we are sure that the cmalloc will fail. */
645f43a8 18200 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18201 {
18202 error (_("Overlarge number of conflicts detected: %lx\n"),
18203 (long) conflictsno);
015dc7e1 18204 return false;
7296a62a
NC
18205 }
18206
3f5e193b 18207 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18208 if (iconf == NULL)
18209 {
8b73c356 18210 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18211 return false;
252b5132
RH
18212 }
18213
9ea033b2 18214 if (is_32bit_elf)
252b5132 18215 {
2cf0635d 18216 Elf32_External_Conflict * econf32;
a6e9f9df 18217
3f5e193b 18218 econf32 = (Elf32_External_Conflict *)
95099889
AM
18219 get_data (NULL, filedata, conflicts_offset,
18220 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18221 if (!econf32)
5a814d6d
AM
18222 {
18223 free (iconf);
015dc7e1 18224 return false;
5a814d6d 18225 }
252b5132
RH
18226
18227 for (cnt = 0; cnt < conflictsno; ++cnt)
18228 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18229
18230 free (econf32);
252b5132
RH
18231 }
18232 else
18233 {
2cf0635d 18234 Elf64_External_Conflict * econf64;
a6e9f9df 18235
3f5e193b 18236 econf64 = (Elf64_External_Conflict *)
95099889
AM
18237 get_data (NULL, filedata, conflicts_offset,
18238 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18239 if (!econf64)
5a814d6d
AM
18240 {
18241 free (iconf);
015dc7e1 18242 return false;
5a814d6d 18243 }
252b5132
RH
18244
18245 for (cnt = 0; cnt < conflictsno; ++cnt)
18246 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18247
18248 free (econf64);
252b5132
RH
18249 }
18250
d3a49aa8
AM
18251 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18252 "\nSection '.conflict' contains %lu entries:\n",
18253 (unsigned long) conflictsno),
c7e7ca54 18254 (unsigned long) conflictsno);
252b5132
RH
18255 puts (_(" Num: Index Value Name"));
18256
18257 for (cnt = 0; cnt < conflictsno; ++cnt)
18258 {
b34976b6 18259 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18260
978c4450 18261 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18262 printf (_("<corrupt symbol index>"));
d79b3d50 18263 else
e0a31db1
NC
18264 {
18265 Elf_Internal_Sym * psym;
18266
978c4450 18267 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18268 print_vma (psym->st_value, FULL_HEX);
18269 putchar (' ');
978c4450
AM
18270 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18271 print_symbol (25, GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18272 else
18273 printf (_("<corrupt: %14ld>"), psym->st_name);
18274 }
31104126 18275 putchar ('\n');
252b5132
RH
18276 }
18277
252b5132
RH
18278 free (iconf);
18279 }
18280
ccb4c951
RS
18281 if (pltgot != 0 && local_gotno != 0)
18282 {
91d6fa6a 18283 bfd_vma ent, local_end, global_end;
bbeee7ea 18284 size_t i, offset;
2cf0635d 18285 unsigned char * data;
82b1b41b 18286 unsigned char * data_end;
bbeee7ea 18287 int addr_size;
ccb4c951 18288
91d6fa6a 18289 ent = pltgot;
ccb4c951
RS
18290 addr_size = (is_32bit_elf ? 4 : 8);
18291 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18292
74e1a04b
NC
18293 /* PR binutils/17533 file: 012-111227-0.004 */
18294 if (symtabno < gotsym)
18295 {
18296 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18297 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18298 return false;
74e1a04b 18299 }
82b1b41b 18300
74e1a04b 18301 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18302 /* PR 17531: file: 54c91a34. */
18303 if (global_end < local_end)
18304 {
18305 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18306 return false;
82b1b41b 18307 }
948f632f 18308
dda8d76d
NC
18309 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18310 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18311 global_end - pltgot, 1,
18312 _("Global Offset Table data"));
919383ac 18313 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18314 data_end = data + (global_end - pltgot);
59245841 18315
ccb4c951
RS
18316 printf (_("\nPrimary GOT:\n"));
18317 printf (_(" Canonical gp value: "));
18318 print_vma (pltgot + 0x7ff0, LONG_HEX);
18319 printf ("\n\n");
18320
18321 printf (_(" Reserved entries:\n"));
18322 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18323 addr_size * 2, _("Address"), _("Access"),
18324 addr_size * 2, _("Initial"));
82b1b41b 18325 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18326 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18327 if (ent == (bfd_vma) -1)
18328 goto got_print_fail;
75ec1fdb 18329
c4ab9505
MR
18330 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18331 This entry will be used by some runtime loaders, to store the
18332 module pointer. Otherwise this is an ordinary local entry.
18333 PR 21344: Check for the entry being fully available before
18334 fetching it. */
18335 if (data
18336 && data + ent - pltgot + addr_size <= data_end
18337 && (byte_get (data + ent - pltgot, addr_size)
18338 >> (addr_size * 8 - 1)) != 0)
18339 {
18340 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18341 printf (_(" Module pointer (GNU extension)\n"));
18342 if (ent == (bfd_vma) -1)
18343 goto got_print_fail;
ccb4c951
RS
18344 }
18345 printf ("\n");
18346
f17e9d8a 18347 if (data != NULL && ent < local_end)
ccb4c951
RS
18348 {
18349 printf (_(" Local entries:\n"));
cc5914eb 18350 printf (" %*s %10s %*s\n",
2b692964
NC
18351 addr_size * 2, _("Address"), _("Access"),
18352 addr_size * 2, _("Initial"));
91d6fa6a 18353 while (ent < local_end)
ccb4c951 18354 {
82b1b41b 18355 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18356 printf ("\n");
82b1b41b
NC
18357 if (ent == (bfd_vma) -1)
18358 goto got_print_fail;
ccb4c951
RS
18359 }
18360 printf ("\n");
18361 }
18362
f17e9d8a 18363 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18364 {
18365 int sym_width;
18366
18367 printf (_(" Global entries:\n"));
cc5914eb 18368 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18369 addr_size * 2, _("Address"),
18370 _("Access"),
2b692964 18371 addr_size * 2, _("Initial"),
9cf03b7e
NC
18372 addr_size * 2, _("Sym.Val."),
18373 _("Type"),
18374 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18375 _("Ndx"), _("Name"));
0b4362b0 18376
ccb4c951 18377 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18378
ccb4c951
RS
18379 for (i = gotsym; i < symtabno; i++)
18380 {
82b1b41b 18381 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18382 printf (" ");
e0a31db1 18383
978c4450 18384 if (filedata->dynamic_symbols == NULL)
e0a31db1 18385 printf (_("<no dynamic symbols>"));
978c4450 18386 else if (i < filedata->num_dynamic_syms)
e0a31db1 18387 {
978c4450 18388 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
18389
18390 print_vma (psym->st_value, LONG_HEX);
18391 printf (" %-7s %3s ",
dda8d76d
NC
18392 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18393 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 18394
978c4450
AM
18395 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18396 print_symbol (sym_width,
18397 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18398 else
18399 printf (_("<corrupt: %14ld>"), psym->st_name);
18400 }
ccb4c951 18401 else
7fc5ac57
JBG
18402 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
18403 (unsigned long) i);
e0a31db1 18404
ccb4c951 18405 printf ("\n");
82b1b41b
NC
18406 if (ent == (bfd_vma) -1)
18407 break;
ccb4c951
RS
18408 }
18409 printf ("\n");
18410 }
18411
82b1b41b 18412 got_print_fail:
9db70fc3 18413 free (data);
ccb4c951
RS
18414 }
18415
861fb55a
DJ
18416 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
18417 {
91d6fa6a 18418 bfd_vma ent, end;
861fb55a
DJ
18419 size_t offset, rel_offset;
18420 unsigned long count, i;
2cf0635d 18421 unsigned char * data;
861fb55a 18422 int addr_size, sym_width;
2cf0635d 18423 Elf_Internal_Rela * rels;
861fb55a 18424
dda8d76d 18425 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
18426 if (pltrel == DT_RELA)
18427 {
dda8d76d 18428 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18429 return false;
861fb55a
DJ
18430 }
18431 else
18432 {
dda8d76d 18433 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18434 return false;
861fb55a
DJ
18435 }
18436
91d6fa6a 18437 ent = mips_pltgot;
861fb55a
DJ
18438 addr_size = (is_32bit_elf ? 4 : 8);
18439 end = mips_pltgot + (2 + count) * addr_size;
18440
dda8d76d
NC
18441 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
18442 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 18443 1, _("Procedure Linkage Table data"));
59245841 18444 if (data == NULL)
288f0ba2
AM
18445 {
18446 free (rels);
015dc7e1 18447 return false;
288f0ba2 18448 }
59245841 18449
9cf03b7e 18450 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
18451 printf (_(" Reserved entries:\n"));
18452 printf (_(" %*s %*s Purpose\n"),
2b692964 18453 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 18454 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18455 printf (_(" PLT lazy resolver\n"));
91d6fa6a 18456 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18457 printf (_(" Module pointer\n"));
861fb55a
DJ
18458 printf ("\n");
18459
18460 printf (_(" Entries:\n"));
cc5914eb 18461 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
18462 addr_size * 2, _("Address"),
18463 addr_size * 2, _("Initial"),
18464 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
18465 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
18466 for (i = 0; i < count; i++)
18467 {
df97ab2a 18468 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 18469
91d6fa6a 18470 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 18471 printf (" ");
e0a31db1 18472
978c4450 18473 if (idx >= filedata->num_dynamic_syms)
df97ab2a 18474 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 18475 else
e0a31db1 18476 {
978c4450 18477 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
18478
18479 print_vma (psym->st_value, LONG_HEX);
18480 printf (" %-7s %3s ",
dda8d76d
NC
18481 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18482 get_symbol_index_type (filedata, psym->st_shndx));
978c4450
AM
18483 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18484 print_symbol (sym_width,
18485 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18486 else
18487 printf (_("<corrupt: %14ld>"), psym->st_name);
18488 }
861fb55a
DJ
18489 printf ("\n");
18490 }
18491 printf ("\n");
18492
9db70fc3 18493 free (data);
861fb55a
DJ
18494 free (rels);
18495 }
18496
32ec8896 18497 return res;
252b5132
RH
18498}
18499
015dc7e1 18500static bool
dda8d76d 18501process_nds32_specific (Filedata * filedata)
35c08157
KLC
18502{
18503 Elf_Internal_Shdr *sect = NULL;
18504
dda8d76d 18505 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 18506 if (sect != NULL && sect->sh_size >= 4)
35c08157 18507 {
9c7b8e9b
AM
18508 unsigned char *buf;
18509 unsigned int flag;
35c08157
KLC
18510
18511 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
18512 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
18513 _("NDS32 elf flags section"));
35c08157 18514
9c7b8e9b 18515 if (buf == NULL)
015dc7e1 18516 return false;
32ec8896 18517
9c7b8e9b
AM
18518 flag = byte_get (buf, 4);
18519 free (buf);
18520 switch (flag & 0x3)
35c08157
KLC
18521 {
18522 case 0:
18523 printf ("(VEC_SIZE):\tNo entry.\n");
18524 break;
18525 case 1:
18526 printf ("(VEC_SIZE):\t4 bytes\n");
18527 break;
18528 case 2:
18529 printf ("(VEC_SIZE):\t16 bytes\n");
18530 break;
18531 case 3:
18532 printf ("(VEC_SIZE):\treserved\n");
18533 break;
18534 }
18535 }
18536
015dc7e1 18537 return true;
35c08157
KLC
18538}
18539
015dc7e1 18540static bool
dda8d76d 18541process_gnu_liblist (Filedata * filedata)
047b2264 18542{
2cf0635d
NC
18543 Elf_Internal_Shdr * section;
18544 Elf_Internal_Shdr * string_sec;
18545 Elf32_External_Lib * elib;
18546 char * strtab;
c256ffe7 18547 size_t strtab_size;
047b2264 18548 size_t cnt;
d3a49aa8 18549 unsigned long num_liblist;
047b2264 18550 unsigned i;
015dc7e1 18551 bool res = true;
047b2264
JJ
18552
18553 if (! do_arch)
015dc7e1 18554 return true;
047b2264 18555
dda8d76d
NC
18556 for (i = 0, section = filedata->section_headers;
18557 i < filedata->file_header.e_shnum;
b34976b6 18558 i++, section++)
047b2264
JJ
18559 {
18560 switch (section->sh_type)
18561 {
18562 case SHT_GNU_LIBLIST:
dda8d76d 18563 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
18564 break;
18565
3f5e193b 18566 elib = (Elf32_External_Lib *)
dda8d76d 18567 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 18568 _("liblist section data"));
047b2264
JJ
18569
18570 if (elib == NULL)
32ec8896 18571 {
015dc7e1 18572 res = false;
32ec8896
NC
18573 break;
18574 }
047b2264 18575
dda8d76d
NC
18576 string_sec = filedata->section_headers + section->sh_link;
18577 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
18578 string_sec->sh_size,
18579 _("liblist string table"));
047b2264
JJ
18580 if (strtab == NULL
18581 || section->sh_entsize != sizeof (Elf32_External_Lib))
18582 {
18583 free (elib);
2842702f 18584 free (strtab);
015dc7e1 18585 res = false;
047b2264
JJ
18586 break;
18587 }
59245841 18588 strtab_size = string_sec->sh_size;
047b2264 18589
d3a49aa8
AM
18590 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
18591 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
18592 "\nLibrary list section '%s' contains %lu entries:\n",
18593 num_liblist),
dda8d76d 18594 printable_section_name (filedata, section),
d3a49aa8 18595 num_liblist);
047b2264 18596
2b692964 18597 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
18598
18599 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
18600 ++cnt)
18601 {
18602 Elf32_Lib liblist;
91d6fa6a 18603 time_t atime;
d5b07ef4 18604 char timebuf[128];
2cf0635d 18605 struct tm * tmp;
047b2264
JJ
18606
18607 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18608 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
18609 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18610 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18611 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18612
91d6fa6a 18613 tmp = gmtime (&atime);
e9e44622
JJ
18614 snprintf (timebuf, sizeof (timebuf),
18615 "%04u-%02u-%02uT%02u:%02u:%02u",
18616 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18617 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
18618
18619 printf ("%3lu: ", (unsigned long) cnt);
18620 if (do_wide)
c256ffe7 18621 printf ("%-20s", liblist.l_name < strtab_size
2b692964 18622 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 18623 else
c256ffe7 18624 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 18625 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
18626 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
18627 liblist.l_version, liblist.l_flags);
18628 }
18629
18630 free (elib);
2842702f 18631 free (strtab);
047b2264
JJ
18632 }
18633 }
18634
32ec8896 18635 return res;
047b2264
JJ
18636}
18637
9437c45b 18638static const char *
dda8d76d 18639get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
18640{
18641 static char buff[64];
103f02d3 18642
dda8d76d 18643 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
18644 switch (e_type)
18645 {
57346661 18646 case NT_AUXV:
1ec5cd37 18647 return _("NT_AUXV (auxiliary vector)");
57346661 18648 case NT_PRSTATUS:
1ec5cd37 18649 return _("NT_PRSTATUS (prstatus structure)");
57346661 18650 case NT_FPREGSET:
1ec5cd37 18651 return _("NT_FPREGSET (floating point registers)");
57346661 18652 case NT_PRPSINFO:
1ec5cd37 18653 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 18654 case NT_TASKSTRUCT:
1ec5cd37 18655 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
18656 case NT_GDB_TDESC:
18657 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 18658 case NT_PRXFPREG:
1ec5cd37 18659 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
18660 case NT_PPC_VMX:
18661 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
18662 case NT_PPC_VSX:
18663 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
18664 case NT_PPC_TAR:
18665 return _("NT_PPC_TAR (ppc TAR register)");
18666 case NT_PPC_PPR:
18667 return _("NT_PPC_PPR (ppc PPR register)");
18668 case NT_PPC_DSCR:
18669 return _("NT_PPC_DSCR (ppc DSCR register)");
18670 case NT_PPC_EBB:
18671 return _("NT_PPC_EBB (ppc EBB registers)");
18672 case NT_PPC_PMU:
18673 return _("NT_PPC_PMU (ppc PMU registers)");
18674 case NT_PPC_TM_CGPR:
18675 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
18676 case NT_PPC_TM_CFPR:
18677 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
18678 case NT_PPC_TM_CVMX:
18679 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
18680 case NT_PPC_TM_CVSX:
3fd21718 18681 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
18682 case NT_PPC_TM_SPR:
18683 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
18684 case NT_PPC_TM_CTAR:
18685 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
18686 case NT_PPC_TM_CPPR:
18687 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
18688 case NT_PPC_TM_CDSCR:
18689 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
18690 case NT_386_TLS:
18691 return _("NT_386_TLS (x86 TLS information)");
18692 case NT_386_IOPERM:
18693 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
18694 case NT_X86_XSTATE:
18695 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
18696 case NT_X86_CET:
18697 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
18698 case NT_S390_HIGH_GPRS:
18699 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
18700 case NT_S390_TIMER:
18701 return _("NT_S390_TIMER (s390 timer register)");
18702 case NT_S390_TODCMP:
18703 return _("NT_S390_TODCMP (s390 TOD comparator register)");
18704 case NT_S390_TODPREG:
18705 return _("NT_S390_TODPREG (s390 TOD programmable register)");
18706 case NT_S390_CTRS:
18707 return _("NT_S390_CTRS (s390 control registers)");
18708 case NT_S390_PREFIX:
18709 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
18710 case NT_S390_LAST_BREAK:
18711 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
18712 case NT_S390_SYSTEM_CALL:
18713 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
18714 case NT_S390_TDB:
18715 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
18716 case NT_S390_VXRS_LOW:
18717 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
18718 case NT_S390_VXRS_HIGH:
18719 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
18720 case NT_S390_GS_CB:
18721 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
18722 case NT_S390_GS_BC:
18723 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
18724 case NT_ARM_VFP:
18725 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
18726 case NT_ARM_TLS:
18727 return _("NT_ARM_TLS (AArch TLS registers)");
18728 case NT_ARM_HW_BREAK:
18729 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
18730 case NT_ARM_HW_WATCH:
18731 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
3b2bef8b
LM
18732 case NT_ARM_SVE:
18733 return _("NT_ARM_SVE (AArch SVE registers)");
18734 case NT_ARM_PAC_MASK:
18735 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
18736 case NT_ARM_TAGGED_ADDR_CTRL:
18737 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
27456742
AK
18738 case NT_ARC_V2:
18739 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
18740 case NT_RISCV_CSR:
18741 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 18742 case NT_PSTATUS:
1ec5cd37 18743 return _("NT_PSTATUS (pstatus structure)");
57346661 18744 case NT_FPREGS:
1ec5cd37 18745 return _("NT_FPREGS (floating point registers)");
57346661 18746 case NT_PSINFO:
1ec5cd37 18747 return _("NT_PSINFO (psinfo structure)");
57346661 18748 case NT_LWPSTATUS:
1ec5cd37 18749 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 18750 case NT_LWPSINFO:
1ec5cd37 18751 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 18752 case NT_WIN32PSTATUS:
1ec5cd37 18753 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
18754 case NT_SIGINFO:
18755 return _("NT_SIGINFO (siginfo_t data)");
18756 case NT_FILE:
18757 return _("NT_FILE (mapped files)");
894982bf
LM
18758 case NT_MEMTAG:
18759 return _("NT_MEMTAG (memory tags)");
1ec5cd37
NC
18760 default:
18761 break;
18762 }
18763 else
18764 switch (e_type)
18765 {
18766 case NT_VERSION:
18767 return _("NT_VERSION (version)");
18768 case NT_ARCH:
18769 return _("NT_ARCH (architecture)");
9ef920e9 18770 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 18771 return _("OPEN");
9ef920e9 18772 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 18773 return _("func");
1ec5cd37
NC
18774 default:
18775 break;
18776 }
18777
e9e44622 18778 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 18779 return buff;
779fe533
NC
18780}
18781
015dc7e1 18782static bool
9ece1fa9
TT
18783print_core_note (Elf_Internal_Note *pnote)
18784{
18785 unsigned int addr_size = is_32bit_elf ? 4 : 8;
18786 bfd_vma count, page_size;
18787 unsigned char *descdata, *filenames, *descend;
18788
18789 if (pnote->type != NT_FILE)
04ac15ab
AS
18790 {
18791 if (do_wide)
18792 printf ("\n");
015dc7e1 18793 return true;
04ac15ab 18794 }
9ece1fa9
TT
18795
18796#ifndef BFD64
18797 if (!is_32bit_elf)
18798 {
18799 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
18800 /* Still "successful". */
015dc7e1 18801 return true;
9ece1fa9
TT
18802 }
18803#endif
18804
18805 if (pnote->descsz < 2 * addr_size)
18806 {
32ec8896 18807 error (_(" Malformed note - too short for header\n"));
015dc7e1 18808 return false;
9ece1fa9
TT
18809 }
18810
18811 descdata = (unsigned char *) pnote->descdata;
18812 descend = descdata + pnote->descsz;
18813
18814 if (descdata[pnote->descsz - 1] != '\0')
18815 {
32ec8896 18816 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 18817 return false;
9ece1fa9
TT
18818 }
18819
18820 count = byte_get (descdata, addr_size);
18821 descdata += addr_size;
18822
18823 page_size = byte_get (descdata, addr_size);
18824 descdata += addr_size;
18825
5396a86e
AM
18826 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
18827 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 18828 {
32ec8896 18829 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 18830 return false;
9ece1fa9
TT
18831 }
18832
18833 printf (_(" Page size: "));
18834 print_vma (page_size, DEC);
18835 printf ("\n");
18836
18837 printf (_(" %*s%*s%*s\n"),
18838 (int) (2 + 2 * addr_size), _("Start"),
18839 (int) (4 + 2 * addr_size), _("End"),
18840 (int) (4 + 2 * addr_size), _("Page Offset"));
18841 filenames = descdata + count * 3 * addr_size;
595712bb 18842 while (count-- > 0)
9ece1fa9
TT
18843 {
18844 bfd_vma start, end, file_ofs;
18845
18846 if (filenames == descend)
18847 {
32ec8896 18848 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 18849 return false;
9ece1fa9
TT
18850 }
18851
18852 start = byte_get (descdata, addr_size);
18853 descdata += addr_size;
18854 end = byte_get (descdata, addr_size);
18855 descdata += addr_size;
18856 file_ofs = byte_get (descdata, addr_size);
18857 descdata += addr_size;
18858
18859 printf (" ");
18860 print_vma (start, FULL_HEX);
18861 printf (" ");
18862 print_vma (end, FULL_HEX);
18863 printf (" ");
18864 print_vma (file_ofs, FULL_HEX);
18865 printf ("\n %s\n", filenames);
18866
18867 filenames += 1 + strlen ((char *) filenames);
18868 }
18869
015dc7e1 18870 return true;
9ece1fa9
TT
18871}
18872
1118d252
RM
18873static const char *
18874get_gnu_elf_note_type (unsigned e_type)
18875{
1449284b 18876 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
18877 switch (e_type)
18878 {
18879 case NT_GNU_ABI_TAG:
18880 return _("NT_GNU_ABI_TAG (ABI version tag)");
18881 case NT_GNU_HWCAP:
18882 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
18883 case NT_GNU_BUILD_ID:
18884 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
18885 case NT_GNU_GOLD_VERSION:
18886 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
18887 case NT_GNU_PROPERTY_TYPE_0:
18888 return _("NT_GNU_PROPERTY_TYPE_0");
18889 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
18890 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
18891 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
18892 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 18893 default:
1449284b
NC
18894 {
18895 static char buff[64];
1118d252 18896
1449284b
NC
18897 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18898 return buff;
18899 }
18900 }
1118d252
RM
18901}
18902
a9eafb08
L
18903static void
18904decode_x86_compat_isa (unsigned int bitmask)
18905{
18906 while (bitmask)
18907 {
18908 unsigned int bit = bitmask & (- bitmask);
18909
18910 bitmask &= ~ bit;
18911 switch (bit)
18912 {
18913 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
18914 printf ("i486");
18915 break;
18916 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
18917 printf ("586");
18918 break;
18919 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
18920 printf ("686");
18921 break;
18922 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
18923 printf ("SSE");
18924 break;
18925 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
18926 printf ("SSE2");
18927 break;
18928 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
18929 printf ("SSE3");
18930 break;
18931 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
18932 printf ("SSSE3");
18933 break;
18934 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
18935 printf ("SSE4_1");
18936 break;
18937 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
18938 printf ("SSE4_2");
18939 break;
18940 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
18941 printf ("AVX");
18942 break;
18943 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
18944 printf ("AVX2");
18945 break;
18946 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
18947 printf ("AVX512F");
18948 break;
18949 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
18950 printf ("AVX512CD");
18951 break;
18952 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
18953 printf ("AVX512ER");
18954 break;
18955 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
18956 printf ("AVX512PF");
18957 break;
18958 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
18959 printf ("AVX512VL");
18960 break;
18961 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
18962 printf ("AVX512DQ");
18963 break;
18964 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
18965 printf ("AVX512BW");
18966 break;
65b3d26e
L
18967 default:
18968 printf (_("<unknown: %x>"), bit);
18969 break;
a9eafb08
L
18970 }
18971 if (bitmask)
18972 printf (", ");
18973 }
18974}
18975
9ef920e9 18976static void
32930e4e 18977decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 18978{
0a59decb 18979 if (!bitmask)
90c745dc
L
18980 {
18981 printf (_("<None>"));
18982 return;
18983 }
90c745dc 18984
9ef920e9
NC
18985 while (bitmask)
18986 {
1fc87489 18987 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
18988
18989 bitmask &= ~ bit;
18990 switch (bit)
18991 {
32930e4e 18992 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
18993 printf ("CMOV");
18994 break;
32930e4e 18995 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
18996 printf ("SSE");
18997 break;
32930e4e 18998 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
18999 printf ("SSE2");
19000 break;
32930e4e 19001 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19002 printf ("SSE3");
19003 break;
32930e4e 19004 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19005 printf ("SSSE3");
19006 break;
32930e4e 19007 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19008 printf ("SSE4_1");
19009 break;
32930e4e 19010 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19011 printf ("SSE4_2");
19012 break;
32930e4e 19013 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19014 printf ("AVX");
19015 break;
32930e4e 19016 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19017 printf ("AVX2");
19018 break;
32930e4e 19019 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19020 printf ("FMA");
19021 break;
32930e4e 19022 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19023 printf ("AVX512F");
19024 break;
32930e4e 19025 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19026 printf ("AVX512CD");
19027 break;
32930e4e 19028 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19029 printf ("AVX512ER");
19030 break;
32930e4e 19031 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19032 printf ("AVX512PF");
19033 break;
32930e4e 19034 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19035 printf ("AVX512VL");
19036 break;
32930e4e 19037 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19038 printf ("AVX512DQ");
19039 break;
32930e4e 19040 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19041 printf ("AVX512BW");
19042 break;
32930e4e 19043 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19044 printf ("AVX512_4FMAPS");
19045 break;
32930e4e 19046 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19047 printf ("AVX512_4VNNIW");
19048 break;
32930e4e 19049 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19050 printf ("AVX512_BITALG");
19051 break;
32930e4e 19052 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19053 printf ("AVX512_IFMA");
19054 break;
32930e4e 19055 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19056 printf ("AVX512_VBMI");
19057 break;
32930e4e 19058 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19059 printf ("AVX512_VBMI2");
19060 break;
32930e4e 19061 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19062 printf ("AVX512_VNNI");
19063 break;
32930e4e 19064 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19065 printf ("AVX512_BF16");
19066 break;
65b3d26e
L
19067 default:
19068 printf (_("<unknown: %x>"), bit);
19069 break;
9ef920e9
NC
19070 }
19071 if (bitmask)
19072 printf (", ");
19073 }
19074}
19075
32930e4e
L
19076static void
19077decode_x86_isa (unsigned int bitmask)
19078{
32930e4e
L
19079 while (bitmask)
19080 {
19081 unsigned int bit = bitmask & (- bitmask);
19082
19083 bitmask &= ~ bit;
19084 switch (bit)
19085 {
b0ab0693
L
19086 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19087 printf ("x86-64-baseline");
19088 break;
32930e4e
L
19089 case GNU_PROPERTY_X86_ISA_1_V2:
19090 printf ("x86-64-v2");
19091 break;
19092 case GNU_PROPERTY_X86_ISA_1_V3:
19093 printf ("x86-64-v3");
19094 break;
19095 case GNU_PROPERTY_X86_ISA_1_V4:
19096 printf ("x86-64-v4");
19097 break;
19098 default:
19099 printf (_("<unknown: %x>"), bit);
19100 break;
19101 }
19102 if (bitmask)
19103 printf (", ");
19104 }
19105}
19106
ee2fdd6f 19107static void
a9eafb08 19108decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19109{
0a59decb 19110 if (!bitmask)
90c745dc
L
19111 {
19112 printf (_("<None>"));
19113 return;
19114 }
90c745dc 19115
ee2fdd6f
L
19116 while (bitmask)
19117 {
19118 unsigned int bit = bitmask & (- bitmask);
19119
19120 bitmask &= ~ bit;
19121 switch (bit)
19122 {
19123 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19124 printf ("IBT");
ee2fdd6f 19125 break;
48580982 19126 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19127 printf ("SHSTK");
48580982 19128 break;
279d901e
L
19129 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19130 printf ("LAM_U48");
19131 break;
19132 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19133 printf ("LAM_U57");
19134 break;
ee2fdd6f
L
19135 default:
19136 printf (_("<unknown: %x>"), bit);
19137 break;
19138 }
19139 if (bitmask)
19140 printf (", ");
19141 }
19142}
19143
a9eafb08
L
19144static void
19145decode_x86_feature_2 (unsigned int bitmask)
19146{
0a59decb 19147 if (!bitmask)
90c745dc
L
19148 {
19149 printf (_("<None>"));
19150 return;
19151 }
90c745dc 19152
a9eafb08
L
19153 while (bitmask)
19154 {
19155 unsigned int bit = bitmask & (- bitmask);
19156
19157 bitmask &= ~ bit;
19158 switch (bit)
19159 {
19160 case GNU_PROPERTY_X86_FEATURE_2_X86:
19161 printf ("x86");
19162 break;
19163 case GNU_PROPERTY_X86_FEATURE_2_X87:
19164 printf ("x87");
19165 break;
19166 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19167 printf ("MMX");
19168 break;
19169 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19170 printf ("XMM");
19171 break;
19172 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19173 printf ("YMM");
19174 break;
19175 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19176 printf ("ZMM");
19177 break;
a308b89d
L
19178 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19179 printf ("TMM");
19180 break;
32930e4e
L
19181 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19182 printf ("MASK");
19183 break;
a9eafb08
L
19184 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19185 printf ("FXSR");
19186 break;
19187 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19188 printf ("XSAVE");
19189 break;
19190 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19191 printf ("XSAVEOPT");
19192 break;
19193 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19194 printf ("XSAVEC");
19195 break;
65b3d26e
L
19196 default:
19197 printf (_("<unknown: %x>"), bit);
19198 break;
a9eafb08
L
19199 }
19200 if (bitmask)
19201 printf (", ");
19202 }
19203}
19204
cd702818
SD
19205static void
19206decode_aarch64_feature_1_and (unsigned int bitmask)
19207{
19208 while (bitmask)
19209 {
19210 unsigned int bit = bitmask & (- bitmask);
19211
19212 bitmask &= ~ bit;
19213 switch (bit)
19214 {
19215 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19216 printf ("BTI");
19217 break;
19218
19219 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19220 printf ("PAC");
19221 break;
19222
19223 default:
19224 printf (_("<unknown: %x>"), bit);
19225 break;
19226 }
19227 if (bitmask)
19228 printf (", ");
19229 }
19230}
19231
9ef920e9 19232static void
dda8d76d 19233print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19234{
19235 unsigned char * ptr = (unsigned char *) pnote->descdata;
19236 unsigned char * ptr_end = ptr + pnote->descsz;
19237 unsigned int size = is_32bit_elf ? 4 : 8;
19238
19239 printf (_(" Properties: "));
19240
1fc87489 19241 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19242 {
19243 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19244 return;
19245 }
19246
6ab2c4ed 19247 while (ptr < ptr_end)
9ef920e9 19248 {
1fc87489 19249 unsigned int j;
6ab2c4ed
MC
19250 unsigned int type;
19251 unsigned int datasz;
19252
19253 if ((size_t) (ptr_end - ptr) < 8)
19254 {
19255 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19256 break;
19257 }
19258
19259 type = byte_get (ptr, 4);
19260 datasz = byte_get (ptr + 4, 4);
9ef920e9 19261
1fc87489 19262 ptr += 8;
9ef920e9 19263
6ab2c4ed 19264 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19265 {
1fc87489
L
19266 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19267 type, datasz);
9ef920e9 19268 break;
1fc87489 19269 }
9ef920e9 19270
1fc87489
L
19271 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19272 {
dda8d76d
NC
19273 if (filedata->file_header.e_machine == EM_X86_64
19274 || filedata->file_header.e_machine == EM_IAMCU
19275 || filedata->file_header.e_machine == EM_386)
1fc87489 19276 {
aa7bca9b
L
19277 unsigned int bitmask;
19278
19279 if (datasz == 4)
0a59decb 19280 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19281 else
19282 bitmask = 0;
19283
1fc87489
L
19284 switch (type)
19285 {
19286 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19287 if (datasz != 4)
aa7bca9b
L
19288 printf (_("x86 ISA used: <corrupt length: %#x> "),
19289 datasz);
1fc87489 19290 else
aa7bca9b
L
19291 {
19292 printf ("x86 ISA used: ");
19293 decode_x86_isa (bitmask);
19294 }
1fc87489 19295 goto next;
9ef920e9 19296
1fc87489 19297 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19298 if (datasz != 4)
aa7bca9b
L
19299 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19300 datasz);
1fc87489 19301 else
aa7bca9b
L
19302 {
19303 printf ("x86 ISA needed: ");
19304 decode_x86_isa (bitmask);
19305 }
1fc87489 19306 goto next;
9ef920e9 19307
ee2fdd6f 19308 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19309 if (datasz != 4)
aa7bca9b
L
19310 printf (_("x86 feature: <corrupt length: %#x> "),
19311 datasz);
ee2fdd6f 19312 else
aa7bca9b
L
19313 {
19314 printf ("x86 feature: ");
a9eafb08
L
19315 decode_x86_feature_1 (bitmask);
19316 }
19317 goto next;
19318
19319 case GNU_PROPERTY_X86_FEATURE_2_USED:
19320 if (datasz != 4)
19321 printf (_("x86 feature used: <corrupt length: %#x> "),
19322 datasz);
19323 else
19324 {
19325 printf ("x86 feature used: ");
19326 decode_x86_feature_2 (bitmask);
19327 }
19328 goto next;
19329
19330 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
19331 if (datasz != 4)
19332 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
19333 else
19334 {
19335 printf ("x86 feature needed: ");
19336 decode_x86_feature_2 (bitmask);
19337 }
19338 goto next;
19339
19340 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
19341 if (datasz != 4)
19342 printf (_("x86 ISA used: <corrupt length: %#x> "),
19343 datasz);
19344 else
19345 {
19346 printf ("x86 ISA used: ");
19347 decode_x86_compat_isa (bitmask);
19348 }
19349 goto next;
19350
19351 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
19352 if (datasz != 4)
19353 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19354 datasz);
19355 else
19356 {
19357 printf ("x86 ISA needed: ");
19358 decode_x86_compat_isa (bitmask);
aa7bca9b 19359 }
ee2fdd6f
L
19360 goto next;
19361
32930e4e
L
19362 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
19363 if (datasz != 4)
19364 printf (_("x86 ISA used: <corrupt length: %#x> "),
19365 datasz);
19366 else
19367 {
19368 printf ("x86 ISA used: ");
19369 decode_x86_compat_2_isa (bitmask);
19370 }
19371 goto next;
19372
19373 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
19374 if (datasz != 4)
19375 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19376 datasz);
19377 else
19378 {
19379 printf ("x86 ISA needed: ");
19380 decode_x86_compat_2_isa (bitmask);
19381 }
19382 goto next;
19383
1fc87489
L
19384 default:
19385 break;
19386 }
19387 }
cd702818
SD
19388 else if (filedata->file_header.e_machine == EM_AARCH64)
19389 {
19390 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
19391 {
19392 printf ("AArch64 feature: ");
19393 if (datasz != 4)
19394 printf (_("<corrupt length: %#x> "), datasz);
19395 else
19396 decode_aarch64_feature_1_and (byte_get (ptr, 4));
19397 goto next;
19398 }
19399 }
1fc87489
L
19400 }
19401 else
19402 {
19403 switch (type)
9ef920e9 19404 {
1fc87489
L
19405 case GNU_PROPERTY_STACK_SIZE:
19406 printf (_("stack size: "));
19407 if (datasz != size)
19408 printf (_("<corrupt length: %#x> "), datasz);
19409 else
19410 printf ("%#lx", (unsigned long) byte_get (ptr, size));
19411 goto next;
19412
19413 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
19414 printf ("no copy on protected ");
19415 if (datasz)
19416 printf (_("<corrupt length: %#x> "), datasz);
19417 goto next;
19418
19419 default:
9ef920e9
NC
19420 break;
19421 }
9ef920e9
NC
19422 }
19423
1fc87489
L
19424 if (type < GNU_PROPERTY_LOPROC)
19425 printf (_("<unknown type %#x data: "), type);
19426 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 19427 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
19428 else
19429 printf (_("<application-specific type %#x data: "), type);
19430 for (j = 0; j < datasz; ++j)
19431 printf ("%02x ", ptr[j] & 0xff);
19432 printf (">");
19433
dc1e8a47 19434 next:
9ef920e9 19435 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
19436 if (ptr == ptr_end)
19437 break;
1fc87489 19438
6ab2c4ed
MC
19439 if (do_wide)
19440 printf (", ");
19441 else
19442 printf ("\n\t");
9ef920e9
NC
19443 }
19444
19445 printf ("\n");
19446}
19447
015dc7e1 19448static bool
dda8d76d 19449print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 19450{
1449284b 19451 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
19452 switch (pnote->type)
19453 {
19454 case NT_GNU_BUILD_ID:
19455 {
19456 unsigned long i;
19457
19458 printf (_(" Build ID: "));
19459 for (i = 0; i < pnote->descsz; ++i)
19460 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 19461 printf ("\n");
664f90a3
TT
19462 }
19463 break;
19464
19465 case NT_GNU_ABI_TAG:
19466 {
19467 unsigned long os, major, minor, subminor;
19468 const char *osname;
19469
3102e897
NC
19470 /* PR 17531: file: 030-599401-0.004. */
19471 if (pnote->descsz < 16)
19472 {
19473 printf (_(" <corrupt GNU_ABI_TAG>\n"));
19474 break;
19475 }
19476
664f90a3
TT
19477 os = byte_get ((unsigned char *) pnote->descdata, 4);
19478 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19479 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
19480 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
19481
19482 switch (os)
19483 {
19484 case GNU_ABI_TAG_LINUX:
19485 osname = "Linux";
19486 break;
19487 case GNU_ABI_TAG_HURD:
19488 osname = "Hurd";
19489 break;
19490 case GNU_ABI_TAG_SOLARIS:
19491 osname = "Solaris";
19492 break;
19493 case GNU_ABI_TAG_FREEBSD:
19494 osname = "FreeBSD";
19495 break;
19496 case GNU_ABI_TAG_NETBSD:
19497 osname = "NetBSD";
19498 break;
14ae95f2
RM
19499 case GNU_ABI_TAG_SYLLABLE:
19500 osname = "Syllable";
19501 break;
19502 case GNU_ABI_TAG_NACL:
19503 osname = "NaCl";
19504 break;
664f90a3
TT
19505 default:
19506 osname = "Unknown";
19507 break;
19508 }
19509
19510 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
19511 major, minor, subminor);
19512 }
19513 break;
926c5385
CC
19514
19515 case NT_GNU_GOLD_VERSION:
19516 {
19517 unsigned long i;
19518
19519 printf (_(" Version: "));
19520 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
19521 printf ("%c", pnote->descdata[i]);
19522 printf ("\n");
19523 }
19524 break;
1449284b
NC
19525
19526 case NT_GNU_HWCAP:
19527 {
19528 unsigned long num_entries, mask;
19529
19530 /* Hardware capabilities information. Word 0 is the number of entries.
19531 Word 1 is a bitmask of enabled entries. The rest of the descriptor
19532 is a series of entries, where each entry is a single byte followed
19533 by a nul terminated string. The byte gives the bit number to test
19534 if enabled in the bitmask. */
19535 printf (_(" Hardware Capabilities: "));
19536 if (pnote->descsz < 8)
19537 {
32ec8896 19538 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 19539 return false;
1449284b
NC
19540 }
19541 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
19542 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19543 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
19544 /* FIXME: Add code to display the entries... */
19545 }
19546 break;
19547
9ef920e9 19548 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 19549 print_gnu_property_note (filedata, pnote);
9ef920e9 19550 break;
9abca702 19551
1449284b
NC
19552 default:
19553 /* Handle unrecognised types. An error message should have already been
19554 created by get_gnu_elf_note_type(), so all that we need to do is to
19555 display the data. */
19556 {
19557 unsigned long i;
19558
19559 printf (_(" Description data: "));
19560 for (i = 0; i < pnote->descsz; ++i)
19561 printf ("%02x ", pnote->descdata[i] & 0xff);
19562 printf ("\n");
19563 }
19564 break;
664f90a3
TT
19565 }
19566
015dc7e1 19567 return true;
664f90a3
TT
19568}
19569
685080f2
NC
19570static const char *
19571get_v850_elf_note_type (enum v850_notes n_type)
19572{
19573 static char buff[64];
19574
19575 switch (n_type)
19576 {
19577 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
19578 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
19579 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
19580 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
19581 case V850_NOTE_CACHE_INFO: return _("Use of cache");
19582 case V850_NOTE_MMU_INFO: return _("Use of MMU");
19583 default:
19584 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
19585 return buff;
19586 }
19587}
19588
015dc7e1 19589static bool
685080f2
NC
19590print_v850_note (Elf_Internal_Note * pnote)
19591{
19592 unsigned int val;
19593
19594 if (pnote->descsz != 4)
015dc7e1 19595 return false;
32ec8896 19596
685080f2
NC
19597 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
19598
19599 if (val == 0)
19600 {
19601 printf (_("not set\n"));
015dc7e1 19602 return true;
685080f2
NC
19603 }
19604
19605 switch (pnote->type)
19606 {
19607 case V850_NOTE_ALIGNMENT:
19608 switch (val)
19609 {
015dc7e1
AM
19610 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
19611 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
19612 }
19613 break;
14ae95f2 19614
685080f2
NC
19615 case V850_NOTE_DATA_SIZE:
19616 switch (val)
19617 {
015dc7e1
AM
19618 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
19619 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
19620 }
19621 break;
14ae95f2 19622
685080f2
NC
19623 case V850_NOTE_FPU_INFO:
19624 switch (val)
19625 {
015dc7e1
AM
19626 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
19627 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
19628 }
19629 break;
14ae95f2 19630
685080f2
NC
19631 case V850_NOTE_MMU_INFO:
19632 case V850_NOTE_CACHE_INFO:
19633 case V850_NOTE_SIMD_INFO:
19634 if (val == EF_RH850_SIMD)
19635 {
19636 printf (_("yes\n"));
015dc7e1 19637 return true;
685080f2
NC
19638 }
19639 break;
19640
19641 default:
19642 /* An 'unknown note type' message will already have been displayed. */
19643 break;
19644 }
19645
19646 printf (_("unknown value: %x\n"), val);
015dc7e1 19647 return false;
685080f2
NC
19648}
19649
015dc7e1 19650static bool
c6056a74
SF
19651process_netbsd_elf_note (Elf_Internal_Note * pnote)
19652{
19653 unsigned int version;
19654
19655 switch (pnote->type)
19656 {
19657 case NT_NETBSD_IDENT:
b966f55f
AM
19658 if (pnote->descsz < 1)
19659 break;
c6056a74
SF
19660 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19661 if ((version / 10000) % 100)
b966f55f 19662 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
19663 version, version / 100000000, (version / 1000000) % 100,
19664 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 19665 'A' + (version / 10000) % 26);
c6056a74
SF
19666 else
19667 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 19668 version, version / 100000000, (version / 1000000) % 100,
15f205b1 19669 (version / 100) % 100);
015dc7e1 19670 return true;
c6056a74
SF
19671
19672 case NT_NETBSD_MARCH:
9abca702 19673 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 19674 pnote->descdata);
015dc7e1 19675 return true;
c6056a74 19676
9abca702 19677 case NT_NETBSD_PAX:
b966f55f
AM
19678 if (pnote->descsz < 1)
19679 break;
9abca702
CZ
19680 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19681 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
19682 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
19683 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
19684 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
19685 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
19686 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
19687 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 19688 return true;
c6056a74 19689 }
b966f55f
AM
19690
19691 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
19692 pnote->descsz, pnote->type);
015dc7e1 19693 return false;
c6056a74
SF
19694}
19695
f4ddf30f 19696static const char *
dda8d76d 19697get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 19698{
f4ddf30f
JB
19699 switch (e_type)
19700 {
19701 case NT_FREEBSD_THRMISC:
19702 return _("NT_THRMISC (thrmisc structure)");
19703 case NT_FREEBSD_PROCSTAT_PROC:
19704 return _("NT_PROCSTAT_PROC (proc data)");
19705 case NT_FREEBSD_PROCSTAT_FILES:
19706 return _("NT_PROCSTAT_FILES (files data)");
19707 case NT_FREEBSD_PROCSTAT_VMMAP:
19708 return _("NT_PROCSTAT_VMMAP (vmmap data)");
19709 case NT_FREEBSD_PROCSTAT_GROUPS:
19710 return _("NT_PROCSTAT_GROUPS (groups data)");
19711 case NT_FREEBSD_PROCSTAT_UMASK:
19712 return _("NT_PROCSTAT_UMASK (umask data)");
19713 case NT_FREEBSD_PROCSTAT_RLIMIT:
19714 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
19715 case NT_FREEBSD_PROCSTAT_OSREL:
19716 return _("NT_PROCSTAT_OSREL (osreldate data)");
19717 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
19718 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
19719 case NT_FREEBSD_PROCSTAT_AUXV:
19720 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
19721 case NT_FREEBSD_PTLWPINFO:
19722 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 19723 }
dda8d76d 19724 return get_note_type (filedata, e_type);
f4ddf30f
JB
19725}
19726
9437c45b 19727static const char *
dda8d76d 19728get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
19729{
19730 static char buff[64];
19731
540e6170
CZ
19732 switch (e_type)
19733 {
19734 case NT_NETBSDCORE_PROCINFO:
19735 /* NetBSD core "procinfo" structure. */
19736 return _("NetBSD procinfo structure");
9437c45b 19737
540e6170
CZ
19738 case NT_NETBSDCORE_AUXV:
19739 return _("NetBSD ELF auxiliary vector data");
9437c45b 19740
06d949ec
KR
19741 case NT_NETBSDCORE_LWPSTATUS:
19742 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 19743
540e6170 19744 default:
06d949ec 19745 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
19746 defined for NetBSD core files. If the note type is less
19747 than the start of the machine-dependent note types, we don't
19748 understand it. */
19749
19750 if (e_type < NT_NETBSDCORE_FIRSTMACH)
19751 {
19752 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19753 return buff;
19754 }
19755 break;
9437c45b
JT
19756 }
19757
dda8d76d 19758 switch (filedata->file_header.e_machine)
9437c45b
JT
19759 {
19760 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
19761 and PT_GETFPREGS == mach+2. */
19762
19763 case EM_OLD_ALPHA:
19764 case EM_ALPHA:
19765 case EM_SPARC:
19766 case EM_SPARC32PLUS:
19767 case EM_SPARCV9:
19768 switch (e_type)
19769 {
2b692964 19770 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 19771 return _("PT_GETREGS (reg structure)");
2b692964 19772 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 19773 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19774 default:
19775 break;
19776 }
19777 break;
19778
c0d38b0e
CZ
19779 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
19780 There's also old PT___GETREGS40 == mach + 1 for old reg
19781 structure which lacks GBR. */
19782 case EM_SH:
19783 switch (e_type)
19784 {
19785 case NT_NETBSDCORE_FIRSTMACH + 1:
19786 return _("PT___GETREGS40 (old reg structure)");
19787 case NT_NETBSDCORE_FIRSTMACH + 3:
19788 return _("PT_GETREGS (reg structure)");
19789 case NT_NETBSDCORE_FIRSTMACH + 5:
19790 return _("PT_GETFPREGS (fpreg structure)");
19791 default:
19792 break;
19793 }
19794 break;
19795
9437c45b
JT
19796 /* On all other arch's, PT_GETREGS == mach+1 and
19797 PT_GETFPREGS == mach+3. */
19798 default:
19799 switch (e_type)
19800 {
2b692964 19801 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 19802 return _("PT_GETREGS (reg structure)");
2b692964 19803 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 19804 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19805 default:
19806 break;
19807 }
19808 }
19809
9cf03b7e 19810 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 19811 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
19812 return buff;
19813}
19814
70616151
TT
19815static const char *
19816get_stapsdt_note_type (unsigned e_type)
19817{
19818 static char buff[64];
19819
19820 switch (e_type)
19821 {
19822 case NT_STAPSDT:
19823 return _("NT_STAPSDT (SystemTap probe descriptors)");
19824
19825 default:
19826 break;
19827 }
19828
19829 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19830 return buff;
19831}
19832
015dc7e1 19833static bool
c6a9fc58
TT
19834print_stapsdt_note (Elf_Internal_Note *pnote)
19835{
3ca60c57
NC
19836 size_t len, maxlen;
19837 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
19838 char *data = pnote->descdata;
19839 char *data_end = pnote->descdata + pnote->descsz;
19840 bfd_vma pc, base_addr, semaphore;
19841 char *provider, *probe, *arg_fmt;
19842
3ca60c57
NC
19843 if (pnote->descsz < (addr_size * 3))
19844 goto stapdt_note_too_small;
19845
c6a9fc58
TT
19846 pc = byte_get ((unsigned char *) data, addr_size);
19847 data += addr_size;
3ca60c57 19848
c6a9fc58
TT
19849 base_addr = byte_get ((unsigned char *) data, addr_size);
19850 data += addr_size;
3ca60c57 19851
c6a9fc58
TT
19852 semaphore = byte_get ((unsigned char *) data, addr_size);
19853 data += addr_size;
19854
3ca60c57
NC
19855 if (data >= data_end)
19856 goto stapdt_note_too_small;
19857 maxlen = data_end - data;
19858 len = strnlen (data, maxlen);
19859 if (len < maxlen)
19860 {
19861 provider = data;
19862 data += len + 1;
19863 }
19864 else
19865 goto stapdt_note_too_small;
19866
19867 if (data >= data_end)
19868 goto stapdt_note_too_small;
19869 maxlen = data_end - data;
19870 len = strnlen (data, maxlen);
19871 if (len < maxlen)
19872 {
19873 probe = data;
19874 data += len + 1;
19875 }
19876 else
19877 goto stapdt_note_too_small;
9abca702 19878
3ca60c57
NC
19879 if (data >= data_end)
19880 goto stapdt_note_too_small;
19881 maxlen = data_end - data;
19882 len = strnlen (data, maxlen);
19883 if (len < maxlen)
19884 {
19885 arg_fmt = data;
19886 data += len + 1;
19887 }
19888 else
19889 goto stapdt_note_too_small;
c6a9fc58
TT
19890
19891 printf (_(" Provider: %s\n"), provider);
19892 printf (_(" Name: %s\n"), probe);
19893 printf (_(" Location: "));
19894 print_vma (pc, FULL_HEX);
19895 printf (_(", Base: "));
19896 print_vma (base_addr, FULL_HEX);
19897 printf (_(", Semaphore: "));
19898 print_vma (semaphore, FULL_HEX);
9cf03b7e 19899 printf ("\n");
c6a9fc58
TT
19900 printf (_(" Arguments: %s\n"), arg_fmt);
19901
19902 return data == data_end;
3ca60c57
NC
19903
19904 stapdt_note_too_small:
19905 printf (_(" <corrupt - note is too small>\n"));
19906 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 19907 return false;
c6a9fc58
TT
19908}
19909
00e98fc7
TG
19910static const char *
19911get_ia64_vms_note_type (unsigned e_type)
19912{
19913 static char buff[64];
19914
19915 switch (e_type)
19916 {
19917 case NT_VMS_MHD:
19918 return _("NT_VMS_MHD (module header)");
19919 case NT_VMS_LNM:
19920 return _("NT_VMS_LNM (language name)");
19921 case NT_VMS_SRC:
19922 return _("NT_VMS_SRC (source files)");
19923 case NT_VMS_TITLE:
9cf03b7e 19924 return "NT_VMS_TITLE";
00e98fc7
TG
19925 case NT_VMS_EIDC:
19926 return _("NT_VMS_EIDC (consistency check)");
19927 case NT_VMS_FPMODE:
19928 return _("NT_VMS_FPMODE (FP mode)");
19929 case NT_VMS_LINKTIME:
9cf03b7e 19930 return "NT_VMS_LINKTIME";
00e98fc7
TG
19931 case NT_VMS_IMGNAM:
19932 return _("NT_VMS_IMGNAM (image name)");
19933 case NT_VMS_IMGID:
19934 return _("NT_VMS_IMGID (image id)");
19935 case NT_VMS_LINKID:
19936 return _("NT_VMS_LINKID (link id)");
19937 case NT_VMS_IMGBID:
19938 return _("NT_VMS_IMGBID (build id)");
19939 case NT_VMS_GSTNAM:
19940 return _("NT_VMS_GSTNAM (sym table name)");
19941 case NT_VMS_ORIG_DYN:
9cf03b7e 19942 return "NT_VMS_ORIG_DYN";
00e98fc7 19943 case NT_VMS_PATCHTIME:
9cf03b7e 19944 return "NT_VMS_PATCHTIME";
00e98fc7
TG
19945 default:
19946 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19947 return buff;
19948 }
19949}
19950
015dc7e1 19951static bool
00e98fc7
TG
19952print_ia64_vms_note (Elf_Internal_Note * pnote)
19953{
8d18bf79
NC
19954 int maxlen = pnote->descsz;
19955
19956 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
19957 goto desc_size_fail;
19958
00e98fc7
TG
19959 switch (pnote->type)
19960 {
19961 case NT_VMS_MHD:
8d18bf79
NC
19962 if (maxlen <= 36)
19963 goto desc_size_fail;
19964
19965 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
19966
19967 printf (_(" Creation date : %.17s\n"), pnote->descdata);
19968 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
19969 if (l + 34 < maxlen)
19970 {
19971 printf (_(" Module name : %s\n"), pnote->descdata + 34);
19972 if (l + 35 < maxlen)
19973 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
19974 else
19975 printf (_(" Module version : <missing>\n"));
19976 }
00e98fc7 19977 else
8d18bf79
NC
19978 {
19979 printf (_(" Module name : <missing>\n"));
19980 printf (_(" Module version : <missing>\n"));
19981 }
00e98fc7 19982 break;
8d18bf79 19983
00e98fc7 19984 case NT_VMS_LNM:
8d18bf79 19985 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19986 break;
8d18bf79 19987
00e98fc7
TG
19988#ifdef BFD64
19989 case NT_VMS_FPMODE:
9cf03b7e 19990 printf (_(" Floating Point mode: "));
8d18bf79
NC
19991 if (maxlen < 8)
19992 goto desc_size_fail;
19993 /* FIXME: Generate an error if descsz > 8 ? */
19994
4a5cb34f 19995 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 19996 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 19997 break;
8d18bf79 19998
00e98fc7
TG
19999 case NT_VMS_LINKTIME:
20000 printf (_(" Link time: "));
8d18bf79
NC
20001 if (maxlen < 8)
20002 goto desc_size_fail;
20003 /* FIXME: Generate an error if descsz > 8 ? */
20004
00e98fc7 20005 print_vms_time
8d18bf79 20006 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20007 printf ("\n");
20008 break;
8d18bf79 20009
00e98fc7
TG
20010 case NT_VMS_PATCHTIME:
20011 printf (_(" Patch time: "));
8d18bf79
NC
20012 if (maxlen < 8)
20013 goto desc_size_fail;
20014 /* FIXME: Generate an error if descsz > 8 ? */
20015
00e98fc7 20016 print_vms_time
8d18bf79 20017 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20018 printf ("\n");
20019 break;
8d18bf79 20020
00e98fc7 20021 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20022 if (maxlen < 34)
20023 goto desc_size_fail;
20024
00e98fc7
TG
20025 printf (_(" Major id: %u, minor id: %u\n"),
20026 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
20027 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 20028 printf (_(" Last modified : "));
00e98fc7
TG
20029 print_vms_time
20030 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 20031 printf (_("\n Link flags : "));
4a5cb34f 20032 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 20033 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 20034 printf (_(" Header flags: 0x%08x\n"),
948f632f 20035 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 20036 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
20037 break;
20038#endif
8d18bf79 20039
00e98fc7 20040 case NT_VMS_IMGNAM:
8d18bf79 20041 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20042 break;
8d18bf79 20043
00e98fc7 20044 case NT_VMS_GSTNAM:
8d18bf79 20045 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20046 break;
8d18bf79 20047
00e98fc7 20048 case NT_VMS_IMGID:
8d18bf79 20049 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20050 break;
8d18bf79 20051
00e98fc7 20052 case NT_VMS_LINKID:
8d18bf79 20053 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20054 break;
8d18bf79 20055
00e98fc7 20056 default:
015dc7e1 20057 return false;
00e98fc7 20058 }
8d18bf79 20059
015dc7e1 20060 return true;
8d18bf79
NC
20061
20062 desc_size_fail:
20063 printf (_(" <corrupt - data size is too small>\n"));
20064 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20065 return false;
00e98fc7
TG
20066}
20067
fd486f32
AM
20068struct build_attr_cache {
20069 Filedata *filedata;
20070 char *strtab;
20071 unsigned long strtablen;
20072 Elf_Internal_Sym *symtab;
20073 unsigned long nsyms;
20074} ba_cache;
20075
6f156d7a
NC
20076/* Find the symbol associated with a build attribute that is attached
20077 to address OFFSET. If PNAME is non-NULL then store the name of
20078 the symbol (if found) in the provided pointer, Returns NULL if a
20079 symbol could not be found. */
c799a79d 20080
6f156d7a 20081static Elf_Internal_Sym *
015dc7e1
AM
20082get_symbol_for_build_attribute (Filedata *filedata,
20083 unsigned long offset,
20084 bool is_open_attr,
20085 const char **pname)
9ef920e9 20086{
fd486f32
AM
20087 Elf_Internal_Sym *saved_sym = NULL;
20088 Elf_Internal_Sym *sym;
9ef920e9 20089
dda8d76d 20090 if (filedata->section_headers != NULL
fd486f32 20091 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20092 {
c799a79d 20093 Elf_Internal_Shdr * symsec;
9ef920e9 20094
fd486f32
AM
20095 free (ba_cache.strtab);
20096 ba_cache.strtab = NULL;
20097 free (ba_cache.symtab);
20098 ba_cache.symtab = NULL;
20099
c799a79d 20100 /* Load the symbol and string sections. */
dda8d76d
NC
20101 for (symsec = filedata->section_headers;
20102 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20103 symsec ++)
9ef920e9 20104 {
28d13567
AM
20105 if (symsec->sh_type == SHT_SYMTAB
20106 && get_symtab (filedata, symsec,
20107 &ba_cache.symtab, &ba_cache.nsyms,
20108 &ba_cache.strtab, &ba_cache.strtablen))
20109 break;
9ef920e9 20110 }
fd486f32 20111 ba_cache.filedata = filedata;
9ef920e9
NC
20112 }
20113
fd486f32 20114 if (ba_cache.symtab == NULL)
6f156d7a 20115 return NULL;
9ef920e9 20116
c799a79d 20117 /* Find a symbol whose value matches offset. */
fd486f32 20118 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20119 if (sym->st_value == offset)
20120 {
fd486f32 20121 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20122 /* Huh ? This should not happen. */
20123 continue;
9ef920e9 20124
fd486f32 20125 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20126 continue;
9ef920e9 20127
8fd75781
NC
20128 /* The AArch64 and ARM architectures define mapping symbols
20129 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20130 if (ba_cache.strtab[sym->st_name] == '$'
20131 && ba_cache.strtab[sym->st_name + 1] != 0
20132 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20133 continue;
20134
c799a79d
NC
20135 if (is_open_attr)
20136 {
20137 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20138 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20139 FUNC symbols entirely. */
20140 switch (ELF_ST_TYPE (sym->st_info))
20141 {
c799a79d 20142 case STT_OBJECT:
6f156d7a 20143 case STT_FILE:
c799a79d 20144 saved_sym = sym;
6f156d7a
NC
20145 if (sym->st_size)
20146 {
20147 /* If the symbol has a size associated
20148 with it then we can stop searching. */
fd486f32 20149 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20150 }
c799a79d 20151 continue;
9ef920e9 20152
c799a79d
NC
20153 case STT_FUNC:
20154 /* Ignore function symbols. */
20155 continue;
20156
20157 default:
20158 break;
20159 }
20160
20161 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20162 {
c799a79d
NC
20163 case STB_GLOBAL:
20164 if (saved_sym == NULL
20165 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20166 saved_sym = sym;
20167 break;
c871dade 20168
c799a79d
NC
20169 case STB_LOCAL:
20170 if (saved_sym == NULL)
20171 saved_sym = sym;
20172 break;
20173
20174 default:
9ef920e9
NC
20175 break;
20176 }
20177 }
c799a79d
NC
20178 else
20179 {
20180 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20181 continue;
20182
20183 saved_sym = sym;
20184 break;
20185 }
20186 }
20187
6f156d7a 20188 if (saved_sym && pname)
fd486f32 20189 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20190
20191 return saved_sym;
c799a79d
NC
20192}
20193
d20e98ab
NC
20194/* Returns true iff addr1 and addr2 are in the same section. */
20195
015dc7e1 20196static bool
d20e98ab
NC
20197same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20198{
20199 Elf_Internal_Shdr * a1;
20200 Elf_Internal_Shdr * a2;
20201
20202 a1 = find_section_by_address (filedata, addr1);
20203 a2 = find_section_by_address (filedata, addr2);
9abca702 20204
d20e98ab
NC
20205 return a1 == a2 && a1 != NULL;
20206}
20207
015dc7e1 20208static bool
dda8d76d
NC
20209print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20210 Filedata * filedata)
c799a79d 20211{
015dc7e1
AM
20212 static unsigned long global_offset = 0;
20213 static unsigned long global_end = 0;
20214 static unsigned long func_offset = 0;
20215 static unsigned long func_end = 0;
c871dade 20216
015dc7e1
AM
20217 Elf_Internal_Sym *sym;
20218 const char *name;
20219 unsigned long start;
20220 unsigned long end;
20221 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20222
20223 switch (pnote->descsz)
c799a79d 20224 {
6f156d7a
NC
20225 case 0:
20226 /* A zero-length description means that the range of
20227 the previous note of the same type should be used. */
c799a79d 20228 if (is_open_attr)
c871dade 20229 {
6f156d7a
NC
20230 if (global_end > global_offset)
20231 printf (_(" Applies to region from %#lx to %#lx\n"),
20232 global_offset, global_end);
20233 else
20234 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20235 }
20236 else
20237 {
6f156d7a
NC
20238 if (func_end > func_offset)
20239 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20240 else
20241 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20242 }
015dc7e1 20243 return true;
9ef920e9 20244
6f156d7a
NC
20245 case 4:
20246 start = byte_get ((unsigned char *) pnote->descdata, 4);
20247 end = 0;
20248 break;
20249
20250 case 8:
c74147bb
NC
20251 start = byte_get ((unsigned char *) pnote->descdata, 4);
20252 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20253 break;
20254
20255 case 16:
20256 start = byte_get ((unsigned char *) pnote->descdata, 8);
20257 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20258 break;
9abca702 20259
6f156d7a 20260 default:
c799a79d
NC
20261 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
20262 printf (_(" <invalid descsz>"));
015dc7e1 20263 return false;
c799a79d
NC
20264 }
20265
6f156d7a
NC
20266 name = NULL;
20267 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
20268 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
20269 in order to avoid them being confused with the start address of the
20270 first function in the file... */
20271 if (sym == NULL && is_open_attr)
20272 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
20273 & name);
6f156d7a
NC
20274
20275 if (end == 0 && sym != NULL && sym->st_size > 0)
20276 end = start + sym->st_size;
c799a79d
NC
20277
20278 if (is_open_attr)
20279 {
d20e98ab
NC
20280 /* FIXME: Need to properly allow for section alignment.
20281 16 is just the alignment used on x86_64. */
20282 if (global_end > 0
20283 && start > BFD_ALIGN (global_end, 16)
20284 /* Build notes are not guaranteed to be organised in order of
20285 increasing address, but we should find the all of the notes
20286 for one section in the same place. */
20287 && same_section (filedata, start, global_end))
6f156d7a
NC
20288 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
20289 global_end + 1, start - 1);
20290
20291 printf (_(" Applies to region from %#lx"), start);
20292 global_offset = start;
20293
20294 if (end)
20295 {
20296 printf (_(" to %#lx"), end);
20297 global_end = end;
20298 }
c799a79d
NC
20299 }
20300 else
20301 {
6f156d7a
NC
20302 printf (_(" Applies to region from %#lx"), start);
20303 func_offset = start;
20304
20305 if (end)
20306 {
20307 printf (_(" to %#lx"), end);
20308 func_end = end;
20309 }
c799a79d
NC
20310 }
20311
6f156d7a
NC
20312 if (sym && name)
20313 printf (_(" (%s)"), name);
20314
20315 printf ("\n");
015dc7e1 20316 return true;
9ef920e9
NC
20317}
20318
015dc7e1 20319static bool
9ef920e9
NC
20320print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
20321{
1d15e434
NC
20322 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
20323 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
20324 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
20325 char name_type;
20326 char name_attribute;
1d15e434 20327 const char * expected_types;
9ef920e9
NC
20328 const char * name = pnote->namedata;
20329 const char * text;
88305e1b 20330 signed int left;
9ef920e9
NC
20331
20332 if (name == NULL || pnote->namesz < 2)
20333 {
20334 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 20335 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20336 return false;
9ef920e9
NC
20337 }
20338
6f156d7a
NC
20339 if (do_wide)
20340 left = 28;
20341 else
20342 left = 20;
88305e1b
NC
20343
20344 /* Version 2 of the spec adds a "GA" prefix to the name field. */
20345 if (name[0] == 'G' && name[1] == 'A')
20346 {
6f156d7a
NC
20347 if (pnote->namesz < 4)
20348 {
20349 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
20350 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20351 return false;
6f156d7a
NC
20352 }
20353
88305e1b
NC
20354 printf ("GA");
20355 name += 2;
20356 left -= 2;
20357 }
20358
9ef920e9
NC
20359 switch ((name_type = * name))
20360 {
20361 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20362 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20363 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20364 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20365 printf ("%c", * name);
88305e1b 20366 left --;
9ef920e9
NC
20367 break;
20368 default:
20369 error (_("unrecognised attribute type in name field: %d\n"), name_type);
20370 print_symbol (-20, _("<unknown name type>"));
015dc7e1 20371 return false;
9ef920e9
NC
20372 }
20373
9ef920e9
NC
20374 ++ name;
20375 text = NULL;
20376
20377 switch ((name_attribute = * name))
20378 {
20379 case GNU_BUILD_ATTRIBUTE_VERSION:
20380 text = _("<version>");
1d15e434 20381 expected_types = string_expected;
9ef920e9
NC
20382 ++ name;
20383 break;
20384 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20385 text = _("<stack prot>");
75d7d298 20386 expected_types = "!+*";
9ef920e9
NC
20387 ++ name;
20388 break;
20389 case GNU_BUILD_ATTRIBUTE_RELRO:
20390 text = _("<relro>");
1d15e434 20391 expected_types = bool_expected;
9ef920e9
NC
20392 ++ name;
20393 break;
20394 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
20395 text = _("<stack size>");
1d15e434 20396 expected_types = number_expected;
9ef920e9
NC
20397 ++ name;
20398 break;
20399 case GNU_BUILD_ATTRIBUTE_TOOL:
20400 text = _("<tool>");
1d15e434 20401 expected_types = string_expected;
9ef920e9
NC
20402 ++ name;
20403 break;
20404 case GNU_BUILD_ATTRIBUTE_ABI:
20405 text = _("<ABI>");
20406 expected_types = "$*";
20407 ++ name;
20408 break;
20409 case GNU_BUILD_ATTRIBUTE_PIC:
20410 text = _("<PIC>");
1d15e434 20411 expected_types = number_expected;
9ef920e9
NC
20412 ++ name;
20413 break;
a8be5506
NC
20414 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
20415 text = _("<short enum>");
1d15e434 20416 expected_types = bool_expected;
a8be5506
NC
20417 ++ name;
20418 break;
9ef920e9
NC
20419 default:
20420 if (ISPRINT (* name))
20421 {
20422 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
20423
20424 if (len > left && ! do_wide)
20425 len = left;
75d7d298 20426 printf ("%.*s:", len, name);
9ef920e9 20427 left -= len;
0dd6ae21 20428 name += len;
9ef920e9
NC
20429 }
20430 else
20431 {
3e6b6445 20432 static char tmpbuf [128];
88305e1b 20433
3e6b6445
NC
20434 error (_("unrecognised byte in name field: %d\n"), * name);
20435 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
20436 text = tmpbuf;
20437 name ++;
9ef920e9
NC
20438 }
20439 expected_types = "*$!+";
20440 break;
20441 }
20442
20443 if (text)
88305e1b 20444 left -= printf ("%s", text);
9ef920e9
NC
20445
20446 if (strchr (expected_types, name_type) == NULL)
75d7d298 20447 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
20448
20449 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
20450 {
20451 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
20452 (unsigned long) pnote->namesz,
20453 (long) (name - pnote->namedata));
015dc7e1 20454 return false;
9ef920e9
NC
20455 }
20456
20457 if (left < 1 && ! do_wide)
015dc7e1 20458 return true;
9ef920e9
NC
20459
20460 switch (name_type)
20461 {
20462 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20463 {
b06b2c92 20464 unsigned int bytes;
ddef72cd
NC
20465 unsigned long long val = 0;
20466 unsigned int shift = 0;
20467 char * decoded = NULL;
20468
b06b2c92
NC
20469 bytes = pnote->namesz - (name - pnote->namedata);
20470 if (bytes > 0)
20471 /* The -1 is because the name field is always 0 terminated, and we
20472 want to be able to ensure that the shift in the while loop below
20473 will not overflow. */
20474 -- bytes;
20475
ddef72cd
NC
20476 if (bytes > sizeof (val))
20477 {
3e6b6445
NC
20478 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
20479 bytes);
20480 bytes = sizeof (val);
ddef72cd 20481 }
3e6b6445
NC
20482 /* We do not bother to warn if bytes == 0 as this can
20483 happen with some early versions of the gcc plugin. */
9ef920e9
NC
20484
20485 while (bytes --)
20486 {
54b8331d 20487 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
20488
20489 val |= byte << shift;
9ef920e9
NC
20490 shift += 8;
20491 }
20492
75d7d298 20493 switch (name_attribute)
9ef920e9 20494 {
75d7d298 20495 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
20496 switch (val)
20497 {
75d7d298
NC
20498 case 0: decoded = "static"; break;
20499 case 1: decoded = "pic"; break;
20500 case 2: decoded = "PIC"; break;
20501 case 3: decoded = "pie"; break;
20502 case 4: decoded = "PIE"; break;
20503 default: break;
9ef920e9 20504 }
75d7d298
NC
20505 break;
20506 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20507 switch (val)
9ef920e9 20508 {
75d7d298
NC
20509 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
20510 case 0: decoded = "off"; break;
20511 case 1: decoded = "on"; break;
20512 case 2: decoded = "all"; break;
20513 case 3: decoded = "strong"; break;
20514 case 4: decoded = "explicit"; break;
20515 default: break;
9ef920e9 20516 }
75d7d298
NC
20517 break;
20518 default:
20519 break;
9ef920e9
NC
20520 }
20521
75d7d298 20522 if (decoded != NULL)
3e6b6445
NC
20523 {
20524 print_symbol (-left, decoded);
20525 left = 0;
20526 }
20527 else if (val == 0)
20528 {
20529 printf ("0x0");
20530 left -= 3;
20531 }
9ef920e9 20532 else
75d7d298
NC
20533 {
20534 if (do_wide)
ddef72cd 20535 left -= printf ("0x%llx", val);
75d7d298 20536 else
ddef72cd 20537 left -= printf ("0x%-.*llx", left, val);
75d7d298 20538 }
9ef920e9
NC
20539 }
20540 break;
20541 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20542 left -= print_symbol (- left, name);
20543 break;
20544 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20545 left -= print_symbol (- left, "true");
20546 break;
20547 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20548 left -= print_symbol (- left, "false");
20549 break;
20550 }
20551
20552 if (do_wide && left > 0)
20553 printf ("%-*s", left, " ");
9abca702 20554
015dc7e1 20555 return true;
9ef920e9
NC
20556}
20557
6d118b09
NC
20558/* Note that by the ELF standard, the name field is already null byte
20559 terminated, and namesz includes the terminating null byte.
20560 I.E. the value of namesz for the name "FSF" is 4.
20561
e3c8793a 20562 If the value of namesz is zero, there is no name present. */
9ef920e9 20563
015dc7e1 20564static bool
9ef920e9 20565process_note (Elf_Internal_Note * pnote,
dda8d76d 20566 Filedata * filedata)
779fe533 20567{
2cf0635d
NC
20568 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
20569 const char * nt;
9437c45b
JT
20570
20571 if (pnote->namesz == 0)
1ec5cd37
NC
20572 /* If there is no note name, then use the default set of
20573 note type strings. */
dda8d76d 20574 nt = get_note_type (filedata, pnote->type);
1ec5cd37 20575
24d127aa 20576 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
20577 /* GNU-specific object file notes. */
20578 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 20579
24d127aa 20580 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 20581 /* FreeBSD-specific core file notes. */
dda8d76d 20582 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 20583
24d127aa 20584 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 20585 /* NetBSD-specific core file notes. */
dda8d76d 20586 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 20587
24d127aa 20588 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
20589 /* NetBSD-specific core file notes. */
20590 return process_netbsd_elf_note (pnote);
20591
24d127aa 20592 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
20593 /* NetBSD-specific core file notes. */
20594 return process_netbsd_elf_note (pnote);
20595
e9b095a5 20596 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
20597 {
20598 /* SPU-specific core file notes. */
20599 nt = pnote->namedata + 4;
20600 name = "SPU";
20601 }
20602
24d127aa 20603 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
20604 /* VMS/ia64-specific file notes. */
20605 nt = get_ia64_vms_note_type (pnote->type);
20606
24d127aa 20607 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
20608 nt = get_stapsdt_note_type (pnote->type);
20609
9437c45b 20610 else
1ec5cd37
NC
20611 /* Don't recognize this note name; just use the default set of
20612 note type strings. */
dda8d76d 20613 nt = get_note_type (filedata, pnote->type);
9437c45b 20614
1449284b 20615 printf (" ");
9ef920e9 20616
24d127aa 20617 if (((startswith (pnote->namedata, "GA")
483767a3
AM
20618 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20619 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20620 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20621 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
20622 print_gnu_build_attribute_name (pnote);
20623 else
20624 print_symbol (-20, name);
20625
20626 if (do_wide)
20627 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
20628 else
20629 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 20630
24d127aa 20631 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 20632 return print_ia64_vms_note (pnote);
24d127aa 20633 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 20634 return print_gnu_note (filedata, pnote);
24d127aa 20635 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 20636 return print_stapsdt_note (pnote);
24d127aa 20637 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 20638 return print_core_note (pnote);
24d127aa 20639 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
20640 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20641 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20642 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20643 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 20644 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 20645
9ef920e9 20646 if (pnote->descsz)
1449284b
NC
20647 {
20648 unsigned long i;
20649
20650 printf (_(" description data: "));
20651 for (i = 0; i < pnote->descsz; i++)
178d8719 20652 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
20653 if (!do_wide)
20654 printf ("\n");
1449284b
NC
20655 }
20656
9ef920e9
NC
20657 if (do_wide)
20658 printf ("\n");
20659
015dc7e1 20660 return true;
1449284b 20661}
6d118b09 20662
015dc7e1 20663static bool
dda8d76d
NC
20664process_notes_at (Filedata * filedata,
20665 Elf_Internal_Shdr * section,
20666 bfd_vma offset,
82ed9683
L
20667 bfd_vma length,
20668 bfd_vma align)
779fe533 20669{
015dc7e1
AM
20670 Elf_External_Note *pnotes;
20671 Elf_External_Note *external;
20672 char *end;
20673 bool res = true;
103f02d3 20674
779fe533 20675 if (length <= 0)
015dc7e1 20676 return false;
103f02d3 20677
1449284b
NC
20678 if (section)
20679 {
dda8d76d 20680 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 20681 if (pnotes)
32ec8896 20682 {
dda8d76d 20683 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
20684 {
20685 free (pnotes);
015dc7e1 20686 return false;
f761cb13 20687 }
32ec8896 20688 }
1449284b
NC
20689 }
20690 else
82ed9683 20691 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 20692 _("notes"));
4dff97b2 20693
dd24e3da 20694 if (pnotes == NULL)
015dc7e1 20695 return false;
779fe533 20696
103f02d3 20697 external = pnotes;
103f02d3 20698
ca0e11aa
NC
20699 if (filedata->is_separate)
20700 printf (_("In linked file '%s': "), filedata->file_name);
20701 else
20702 printf ("\n");
1449284b 20703 if (section)
ca0e11aa 20704 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 20705 else
ca0e11aa 20706 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
20707 (unsigned long) offset, (unsigned long) length);
20708
82ed9683
L
20709 /* NB: Some note sections may have alignment value of 0 or 1. gABI
20710 specifies that notes should be aligned to 4 bytes in 32-bit
20711 objects and to 8 bytes in 64-bit objects. As a Linux extension,
20712 we also support 4 byte alignment in 64-bit objects. If section
20713 alignment is less than 4, we treate alignment as 4 bytes. */
20714 if (align < 4)
20715 align = 4;
20716 else if (align != 4 && align != 8)
20717 {
20718 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
20719 (long) align);
a788aedd 20720 free (pnotes);
015dc7e1 20721 return false;
82ed9683
L
20722 }
20723
dbe15e4e 20724 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 20725
c8071705
NC
20726 end = (char *) pnotes + length;
20727 while ((char *) external < end)
779fe533 20728 {
b34976b6 20729 Elf_Internal_Note inote;
15b42fb0 20730 size_t min_notesz;
4dff97b2 20731 char * next;
2cf0635d 20732 char * temp = NULL;
c8071705 20733 size_t data_remaining = end - (char *) external;
6d118b09 20734
dda8d76d 20735 if (!is_ia64_vms (filedata))
15b42fb0 20736 {
9dd3a467
NC
20737 /* PR binutils/15191
20738 Make sure that there is enough data to read. */
15b42fb0
AM
20739 min_notesz = offsetof (Elf_External_Note, name);
20740 if (data_remaining < min_notesz)
9dd3a467 20741 {
d3a49aa8
AM
20742 warn (ngettext ("Corrupt note: only %ld byte remains, "
20743 "not enough for a full note\n",
20744 "Corrupt note: only %ld bytes remain, "
20745 "not enough for a full note\n",
20746 data_remaining),
20747 (long) data_remaining);
9dd3a467
NC
20748 break;
20749 }
5396a86e
AM
20750 data_remaining -= min_notesz;
20751
15b42fb0
AM
20752 inote.type = BYTE_GET (external->type);
20753 inote.namesz = BYTE_GET (external->namesz);
20754 inote.namedata = external->name;
20755 inote.descsz = BYTE_GET (external->descsz);
276da9b3 20756 inote.descdata = ((char *) external
4dff97b2 20757 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 20758 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 20759 next = ((char *) external
4dff97b2 20760 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 20761 }
00e98fc7 20762 else
15b42fb0
AM
20763 {
20764 Elf64_External_VMS_Note *vms_external;
00e98fc7 20765
9dd3a467
NC
20766 /* PR binutils/15191
20767 Make sure that there is enough data to read. */
15b42fb0
AM
20768 min_notesz = offsetof (Elf64_External_VMS_Note, name);
20769 if (data_remaining < min_notesz)
9dd3a467 20770 {
d3a49aa8
AM
20771 warn (ngettext ("Corrupt note: only %ld byte remains, "
20772 "not enough for a full note\n",
20773 "Corrupt note: only %ld bytes remain, "
20774 "not enough for a full note\n",
20775 data_remaining),
20776 (long) data_remaining);
9dd3a467
NC
20777 break;
20778 }
5396a86e 20779 data_remaining -= min_notesz;
3e55a963 20780
15b42fb0
AM
20781 vms_external = (Elf64_External_VMS_Note *) external;
20782 inote.type = BYTE_GET (vms_external->type);
20783 inote.namesz = BYTE_GET (vms_external->namesz);
20784 inote.namedata = vms_external->name;
20785 inote.descsz = BYTE_GET (vms_external->descsz);
20786 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
20787 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20788 next = inote.descdata + align_power (inote.descsz, 3);
20789 }
20790
5396a86e
AM
20791 /* PR 17531: file: 3443835e. */
20792 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
20793 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
20794 || (size_t) (inote.descdata - inote.namedata) > data_remaining
20795 || (size_t) (next - inote.descdata) < inote.descsz
20796 || ((size_t) (next - inote.descdata)
20797 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 20798 {
15b42fb0 20799 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 20800 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
20801 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
20802 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
20803 break;
20804 }
20805
15b42fb0 20806 external = (Elf_External_Note *) next;
dd24e3da 20807
6d118b09
NC
20808 /* Verify that name is null terminated. It appears that at least
20809 one version of Linux (RedHat 6.0) generates corefiles that don't
20810 comply with the ELF spec by failing to include the null byte in
20811 namesz. */
18344509 20812 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 20813 {
5396a86e 20814 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 20815 {
5396a86e
AM
20816 temp = (char *) malloc (inote.namesz + 1);
20817 if (temp == NULL)
20818 {
20819 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 20820 res = false;
5396a86e
AM
20821 break;
20822 }
76da6bbe 20823
5396a86e
AM
20824 memcpy (temp, inote.namedata, inote.namesz);
20825 inote.namedata = temp;
20826 }
20827 inote.namedata[inote.namesz] = 0;
6d118b09
NC
20828 }
20829
dda8d76d 20830 if (! process_note (& inote, filedata))
015dc7e1 20831 res = false;
103f02d3 20832
9db70fc3
AM
20833 free (temp);
20834 temp = NULL;
779fe533
NC
20835 }
20836
20837 free (pnotes);
103f02d3 20838
779fe533
NC
20839 return res;
20840}
20841
015dc7e1 20842static bool
dda8d76d 20843process_corefile_note_segments (Filedata * filedata)
779fe533 20844{
015dc7e1 20845 Elf_Internal_Phdr *segment;
b34976b6 20846 unsigned int i;
015dc7e1 20847 bool res = true;
103f02d3 20848
dda8d76d 20849 if (! get_program_headers (filedata))
015dc7e1 20850 return true;
103f02d3 20851
dda8d76d
NC
20852 for (i = 0, segment = filedata->program_headers;
20853 i < filedata->file_header.e_phnum;
b34976b6 20854 i++, segment++)
779fe533
NC
20855 {
20856 if (segment->p_type == PT_NOTE)
dda8d76d 20857 if (! process_notes_at (filedata, NULL,
32ec8896 20858 (bfd_vma) segment->p_offset,
82ed9683
L
20859 (bfd_vma) segment->p_filesz,
20860 (bfd_vma) segment->p_align))
015dc7e1 20861 res = false;
779fe533 20862 }
103f02d3 20863
779fe533
NC
20864 return res;
20865}
20866
015dc7e1 20867static bool
dda8d76d 20868process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
20869{
20870 Elf_External_Note * pnotes;
20871 Elf_External_Note * external;
c8071705 20872 char * end;
015dc7e1 20873 bool res = true;
685080f2
NC
20874
20875 if (length <= 0)
015dc7e1 20876 return false;
685080f2 20877
dda8d76d 20878 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
20879 _("v850 notes"));
20880 if (pnotes == NULL)
015dc7e1 20881 return false;
685080f2
NC
20882
20883 external = pnotes;
c8071705 20884 end = (char*) pnotes + length;
685080f2
NC
20885
20886 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
20887 (unsigned long) offset, (unsigned long) length);
20888
c8071705 20889 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
20890 {
20891 Elf_External_Note * next;
20892 Elf_Internal_Note inote;
20893
20894 inote.type = BYTE_GET (external->type);
20895 inote.namesz = BYTE_GET (external->namesz);
20896 inote.namedata = external->name;
20897 inote.descsz = BYTE_GET (external->descsz);
20898 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
20899 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20900
c8071705
NC
20901 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
20902 {
20903 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
20904 inote.descdata = inote.namedata;
20905 inote.namesz = 0;
20906 }
20907
685080f2
NC
20908 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
20909
c8071705 20910 if ( ((char *) next > end)
685080f2
NC
20911 || ((char *) next < (char *) pnotes))
20912 {
20913 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
20914 (unsigned long) ((char *) external - (char *) pnotes));
20915 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20916 inote.type, inote.namesz, inote.descsz);
20917 break;
20918 }
20919
20920 external = next;
20921
20922 /* Prevent out-of-bounds indexing. */
c8071705 20923 if ( inote.namedata + inote.namesz > end
685080f2
NC
20924 || inote.namedata + inote.namesz < inote.namedata)
20925 {
20926 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
20927 (unsigned long) ((char *) external - (char *) pnotes));
20928 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20929 inote.type, inote.namesz, inote.descsz);
20930 break;
20931 }
20932
20933 printf (" %s: ", get_v850_elf_note_type (inote.type));
20934
20935 if (! print_v850_note (& inote))
20936 {
015dc7e1 20937 res = false;
685080f2
NC
20938 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
20939 inote.namesz, inote.descsz);
20940 }
20941 }
20942
20943 free (pnotes);
20944
20945 return res;
20946}
20947
015dc7e1 20948static bool
dda8d76d 20949process_note_sections (Filedata * filedata)
1ec5cd37 20950{
015dc7e1 20951 Elf_Internal_Shdr *section;
1ec5cd37 20952 unsigned long i;
32ec8896 20953 unsigned int n = 0;
015dc7e1 20954 bool res = true;
1ec5cd37 20955
dda8d76d
NC
20956 for (i = 0, section = filedata->section_headers;
20957 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 20958 i++, section++)
685080f2
NC
20959 {
20960 if (section->sh_type == SHT_NOTE)
20961 {
dda8d76d 20962 if (! process_notes_at (filedata, section,
32ec8896 20963 (bfd_vma) section->sh_offset,
82ed9683
L
20964 (bfd_vma) section->sh_size,
20965 (bfd_vma) section->sh_addralign))
015dc7e1 20966 res = false;
685080f2
NC
20967 n++;
20968 }
20969
dda8d76d
NC
20970 if (( filedata->file_header.e_machine == EM_V800
20971 || filedata->file_header.e_machine == EM_V850
20972 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
20973 && section->sh_type == SHT_RENESAS_INFO)
20974 {
dda8d76d 20975 if (! process_v850_notes (filedata,
32ec8896
NC
20976 (bfd_vma) section->sh_offset,
20977 (bfd_vma) section->sh_size))
015dc7e1 20978 res = false;
685080f2
NC
20979 n++;
20980 }
20981 }
df565f32
NC
20982
20983 if (n == 0)
20984 /* Try processing NOTE segments instead. */
dda8d76d 20985 return process_corefile_note_segments (filedata);
1ec5cd37
NC
20986
20987 return res;
20988}
20989
015dc7e1 20990static bool
dda8d76d 20991process_notes (Filedata * filedata)
779fe533
NC
20992{
20993 /* If we have not been asked to display the notes then do nothing. */
20994 if (! do_notes)
015dc7e1 20995 return true;
103f02d3 20996
dda8d76d
NC
20997 if (filedata->file_header.e_type != ET_CORE)
20998 return process_note_sections (filedata);
103f02d3 20999
779fe533 21000 /* No program headers means no NOTE segment. */
dda8d76d
NC
21001 if (filedata->file_header.e_phnum > 0)
21002 return process_corefile_note_segments (filedata);
779fe533 21003
ca0e11aa
NC
21004 if (filedata->is_separate)
21005 printf (_("No notes found in linked file '%s'.\n"),
21006 filedata->file_name);
21007 else
21008 printf (_("No notes found file.\n"));
21009
015dc7e1 21010 return true;
779fe533
NC
21011}
21012
60abdbed
NC
21013static unsigned char *
21014display_public_gnu_attributes (unsigned char * start,
21015 const unsigned char * const end)
21016{
21017 printf (_(" Unknown GNU attribute: %s\n"), start);
21018
21019 start += strnlen ((char *) start, end - start);
21020 display_raw_attribute (start, end);
21021
21022 return (unsigned char *) end;
21023}
21024
21025static unsigned char *
21026display_generic_attribute (unsigned char * start,
21027 unsigned int tag,
21028 const unsigned char * const end)
21029{
21030 if (tag == 0)
21031 return (unsigned char *) end;
21032
21033 return display_tag_value (tag, start, end);
21034}
21035
015dc7e1 21036static bool
dda8d76d 21037process_arch_specific (Filedata * filedata)
252b5132 21038{
a952a375 21039 if (! do_arch)
015dc7e1 21040 return true;
a952a375 21041
dda8d76d 21042 switch (filedata->file_header.e_machine)
252b5132 21043 {
53a346d8
CZ
21044 case EM_ARC:
21045 case EM_ARC_COMPACT:
21046 case EM_ARC_COMPACT2:
dda8d76d 21047 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
21048 display_arc_attribute,
21049 display_generic_attribute);
11c1ff18 21050 case EM_ARM:
dda8d76d 21051 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
21052 display_arm_attribute,
21053 display_generic_attribute);
21054
252b5132 21055 case EM_MIPS:
4fe85591 21056 case EM_MIPS_RS3_LE:
dda8d76d 21057 return process_mips_specific (filedata);
60abdbed
NC
21058
21059 case EM_MSP430:
dda8d76d 21060 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21061 display_msp430_attribute,
c0ea7c52 21062 display_msp430_gnu_attribute);
60abdbed 21063
2dc8dd17
JW
21064 case EM_RISCV:
21065 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21066 display_riscv_attribute,
21067 display_generic_attribute);
21068
35c08157 21069 case EM_NDS32:
dda8d76d 21070 return process_nds32_specific (filedata);
60abdbed 21071
85f7484a
PB
21072 case EM_68K:
21073 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21074 display_m68k_gnu_attribute);
21075
34c8bcba 21076 case EM_PPC:
b82317dd 21077 case EM_PPC64:
dda8d76d 21078 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21079 display_power_gnu_attribute);
21080
643f7afb
AK
21081 case EM_S390:
21082 case EM_S390_OLD:
dda8d76d 21083 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21084 display_s390_gnu_attribute);
21085
9e8c70f9
DM
21086 case EM_SPARC:
21087 case EM_SPARC32PLUS:
21088 case EM_SPARCV9:
dda8d76d 21089 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21090 display_sparc_gnu_attribute);
21091
59e6276b 21092 case EM_TI_C6000:
dda8d76d 21093 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
21094 display_tic6x_attribute,
21095 display_generic_attribute);
21096
0861f561
CQ
21097 case EM_CSKY:
21098 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
21099 display_csky_attribute, NULL);
21100
252b5132 21101 default:
dda8d76d 21102 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
21103 display_public_gnu_attributes,
21104 display_generic_attribute);
252b5132 21105 }
252b5132
RH
21106}
21107
015dc7e1 21108static bool
dda8d76d 21109get_file_header (Filedata * filedata)
252b5132 21110{
9ea033b2 21111 /* Read in the identity array. */
dda8d76d 21112 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21113 return false;
252b5132 21114
9ea033b2 21115 /* Determine how to read the rest of the header. */
dda8d76d 21116 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 21117 {
1a0670f3
AM
21118 default:
21119 case ELFDATANONE:
adab8cdc
AO
21120 case ELFDATA2LSB:
21121 byte_get = byte_get_little_endian;
21122 byte_put = byte_put_little_endian;
21123 break;
21124 case ELFDATA2MSB:
21125 byte_get = byte_get_big_endian;
21126 byte_put = byte_put_big_endian;
21127 break;
9ea033b2
NC
21128 }
21129
21130 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 21131 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
21132
21133 /* Read in the rest of the header. */
21134 if (is_32bit_elf)
21135 {
21136 Elf32_External_Ehdr ehdr32;
252b5132 21137
dda8d76d 21138 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21139 return false;
103f02d3 21140
dda8d76d
NC
21141 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
21142 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
21143 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
21144 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
21145 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
21146 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
21147 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
21148 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
21149 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
21150 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
21151 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
21152 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
21153 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 21154 }
252b5132 21155 else
9ea033b2
NC
21156 {
21157 Elf64_External_Ehdr ehdr64;
a952a375
NC
21158
21159 /* If we have been compiled with sizeof (bfd_vma) == 4, then
21160 we will not be able to cope with the 64bit data found in
21161 64 ELF files. Detect this now and abort before we start
50c2245b 21162 overwriting things. */
a952a375
NC
21163 if (sizeof (bfd_vma) < 8)
21164 {
e3c8793a
NC
21165 error (_("This instance of readelf has been built without support for a\n\
2116664 bit data type and so it cannot read 64 bit ELF files.\n"));
015dc7e1 21167 return false;
a952a375 21168 }
103f02d3 21169
dda8d76d 21170 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21171 return false;
103f02d3 21172
dda8d76d
NC
21173 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
21174 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
21175 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
21176 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
21177 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
21178 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
21179 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
21180 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
21181 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
21182 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
21183 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
21184 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
21185 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 21186 }
252b5132 21187
015dc7e1 21188 return true;
252b5132
RH
21189}
21190
13acb58d
AM
21191static void
21192free_filedata (Filedata *filedata)
21193{
21194 free (filedata->program_interpreter);
13acb58d 21195 free (filedata->program_headers);
13acb58d 21196 free (filedata->section_headers);
13acb58d 21197 free (filedata->string_table);
13acb58d 21198 free (filedata->dump.dump_sects);
13acb58d 21199 free (filedata->dynamic_strings);
13acb58d 21200 free (filedata->dynamic_symbols);
13acb58d 21201 free (filedata->dynamic_syminfo);
13acb58d 21202 free (filedata->dynamic_section);
13acb58d
AM
21203
21204 while (filedata->symtab_shndx_list != NULL)
21205 {
21206 elf_section_list *next = filedata->symtab_shndx_list->next;
21207 free (filedata->symtab_shndx_list);
21208 filedata->symtab_shndx_list = next;
21209 }
21210
21211 free (filedata->section_headers_groups);
13acb58d
AM
21212
21213 if (filedata->section_groups)
21214 {
21215 size_t i;
21216 struct group_list * g;
21217 struct group_list * next;
21218
21219 for (i = 0; i < filedata->group_count; i++)
21220 {
21221 for (g = filedata->section_groups [i].root; g != NULL; g = next)
21222 {
21223 next = g->next;
21224 free (g);
21225 }
21226 }
21227
21228 free (filedata->section_groups);
13acb58d 21229 }
066f8fbe
AM
21230 memset (&filedata->section_headers, 0,
21231 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
21232}
21233
dda8d76d
NC
21234static void
21235close_file (Filedata * filedata)
21236{
21237 if (filedata)
21238 {
21239 if (filedata->handle)
21240 fclose (filedata->handle);
21241 free (filedata);
21242 }
21243}
21244
21245void
21246close_debug_file (void * data)
21247{
13acb58d 21248 free_filedata ((Filedata *) data);
dda8d76d
NC
21249 close_file ((Filedata *) data);
21250}
21251
21252static Filedata *
015dc7e1 21253open_file (const char * pathname, bool is_separate)
dda8d76d
NC
21254{
21255 struct stat statbuf;
21256 Filedata * filedata = NULL;
21257
21258 if (stat (pathname, & statbuf) < 0
21259 || ! S_ISREG (statbuf.st_mode))
21260 goto fail;
21261
21262 filedata = calloc (1, sizeof * filedata);
21263 if (filedata == NULL)
21264 goto fail;
21265
21266 filedata->handle = fopen (pathname, "rb");
21267 if (filedata->handle == NULL)
21268 goto fail;
21269
21270 filedata->file_size = (bfd_size_type) statbuf.st_size;
21271 filedata->file_name = pathname;
ca0e11aa 21272 filedata->is_separate = is_separate;
dda8d76d
NC
21273
21274 if (! get_file_header (filedata))
21275 goto fail;
21276
4de91c10
AM
21277 if (!get_section_headers (filedata, false))
21278 goto fail;
dda8d76d
NC
21279
21280 return filedata;
21281
21282 fail:
21283 if (filedata)
21284 {
21285 if (filedata->handle)
21286 fclose (filedata->handle);
21287 free (filedata);
21288 }
21289 return NULL;
21290}
21291
21292void *
21293open_debug_file (const char * pathname)
21294{
015dc7e1 21295 return open_file (pathname, true);
dda8d76d
NC
21296}
21297
835f2fae
NC
21298static void
21299initialise_dump_sects (Filedata * filedata)
21300{
21301 /* Initialise the dump_sects array from the cmdline_dump_sects array.
21302 Note we do this even if cmdline_dump_sects is empty because we
21303 must make sure that the dump_sets array is zeroed out before each
21304 object file is processed. */
21305 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
21306 memset (filedata->dump.dump_sects, 0,
21307 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21308
21309 if (cmdline.num_dump_sects > 0)
21310 {
21311 if (filedata->dump.num_dump_sects == 0)
21312 /* A sneaky way of allocating the dump_sects array. */
21313 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
21314
21315 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
21316 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
21317 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21318 }
21319}
21320
fb52b2f4
NC
21321/* Process one ELF object file according to the command line options.
21322 This file may actually be stored in an archive. The file is
32ec8896
NC
21323 positioned at the start of the ELF object. Returns TRUE if no
21324 problems were encountered, FALSE otherwise. */
fb52b2f4 21325
015dc7e1 21326static bool
dda8d76d 21327process_object (Filedata * filedata)
252b5132 21328{
015dc7e1 21329 bool have_separate_files;
252b5132 21330 unsigned int i;
015dc7e1 21331 bool res;
252b5132 21332
dda8d76d 21333 if (! get_file_header (filedata))
252b5132 21334 {
dda8d76d 21335 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 21336 return false;
252b5132
RH
21337 }
21338
21339 /* Initialise per file variables. */
978c4450
AM
21340 for (i = ARRAY_SIZE (filedata->version_info); i--;)
21341 filedata->version_info[i] = 0;
252b5132 21342
978c4450
AM
21343 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
21344 filedata->dynamic_info[i] = 0;
21345 filedata->dynamic_info_DT_GNU_HASH = 0;
21346 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
21347
21348 /* Process the file. */
21349 if (show_name)
dda8d76d 21350 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 21351
835f2fae 21352 initialise_dump_sects (filedata);
d70c5fc7 21353
4de91c10
AM
21354 /* There may be some extensions in the first section header. Don't
21355 bomb if we can't read it. */
21356 get_section_headers (filedata, true);
21357
dda8d76d 21358 if (! process_file_header (filedata))
4de91c10
AM
21359 {
21360 res = false;
21361 goto out;
21362 }
252b5132 21363
dda8d76d 21364 if (! process_section_headers (filedata))
2f62977e 21365 {
32ec8896 21366 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 21367 do_unwind = do_version = do_dump = do_arch = false;
252b5132 21368
2f62977e 21369 if (! do_using_dynamic)
015dc7e1 21370 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 21371 }
252b5132 21372
dda8d76d 21373 if (! process_section_groups (filedata))
32ec8896 21374 /* Without loaded section groups we cannot process unwind. */
015dc7e1 21375 do_unwind = false;
d1f5c6e3 21376
2482f306
AM
21377 res = process_program_headers (filedata);
21378 if (res)
21379 res = process_dynamic_section (filedata);
252b5132 21380
dda8d76d 21381 if (! process_relocs (filedata))
015dc7e1 21382 res = false;
252b5132 21383
dda8d76d 21384 if (! process_unwind (filedata))
015dc7e1 21385 res = false;
4d6ed7c8 21386
dda8d76d 21387 if (! process_symbol_table (filedata))
015dc7e1 21388 res = false;
252b5132 21389
0f03783c 21390 if (! process_lto_symbol_tables (filedata))
015dc7e1 21391 res = false;
b9e920ec 21392
dda8d76d 21393 if (! process_syminfo (filedata))
015dc7e1 21394 res = false;
252b5132 21395
dda8d76d 21396 if (! process_version_sections (filedata))
015dc7e1 21397 res = false;
252b5132 21398
82ed9683 21399 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 21400 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 21401 else
015dc7e1 21402 have_separate_files = false;
dda8d76d
NC
21403
21404 if (! process_section_contents (filedata))
015dc7e1 21405 res = false;
f5842774 21406
24841daa 21407 if (have_separate_files)
dda8d76d 21408 {
24841daa
NC
21409 separate_info * d;
21410
21411 for (d = first_separate_info; d != NULL; d = d->next)
21412 {
835f2fae
NC
21413 initialise_dump_sects (d->handle);
21414
ca0e11aa 21415 if (process_links && ! process_file_header (d->handle))
015dc7e1 21416 res = false;
ca0e11aa 21417 else if (! process_section_headers (d->handle))
015dc7e1 21418 res = false;
d6bfbc39 21419 else if (! process_section_contents (d->handle))
015dc7e1 21420 res = false;
ca0e11aa
NC
21421 else if (process_links)
21422 {
ca0e11aa 21423 if (! process_section_groups (d->handle))
015dc7e1 21424 res = false;
ca0e11aa 21425 if (! process_program_headers (d->handle))
015dc7e1 21426 res = false;
ca0e11aa 21427 if (! process_dynamic_section (d->handle))
015dc7e1 21428 res = false;
ca0e11aa 21429 if (! process_relocs (d->handle))
015dc7e1 21430 res = false;
ca0e11aa 21431 if (! process_unwind (d->handle))
015dc7e1 21432 res = false;
ca0e11aa 21433 if (! process_symbol_table (d->handle))
015dc7e1 21434 res = false;
ca0e11aa 21435 if (! process_lto_symbol_tables (d->handle))
015dc7e1 21436 res = false;
ca0e11aa 21437 if (! process_syminfo (d->handle))
015dc7e1 21438 res = false;
ca0e11aa 21439 if (! process_version_sections (d->handle))
015dc7e1 21440 res = false;
ca0e11aa 21441 if (! process_notes (d->handle))
015dc7e1 21442 res = false;
ca0e11aa 21443 }
24841daa
NC
21444 }
21445
21446 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
21447 }
21448
21449 if (! process_notes (filedata))
015dc7e1 21450 res = false;
103f02d3 21451
dda8d76d 21452 if (! process_gnu_liblist (filedata))
015dc7e1 21453 res = false;
047b2264 21454
dda8d76d 21455 if (! process_arch_specific (filedata))
015dc7e1 21456 res = false;
252b5132 21457
4de91c10 21458 out:
13acb58d 21459 free_filedata (filedata);
e4b17d5c 21460
19e6b90e 21461 free_debug_memory ();
18bd398b 21462
32ec8896 21463 return res;
252b5132
RH
21464}
21465
2cf0635d 21466/* Process an ELF archive.
32ec8896
NC
21467 On entry the file is positioned just after the ARMAG string.
21468 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 21469
015dc7e1
AM
21470static bool
21471process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
21472{
21473 struct archive_info arch;
21474 struct archive_info nested_arch;
21475 size_t got;
015dc7e1 21476 bool ret = true;
2cf0635d 21477
015dc7e1 21478 show_name = true;
2cf0635d
NC
21479
21480 /* The ARCH structure is used to hold information about this archive. */
21481 arch.file_name = NULL;
21482 arch.file = NULL;
21483 arch.index_array = NULL;
21484 arch.sym_table = NULL;
21485 arch.longnames = NULL;
21486
21487 /* The NESTED_ARCH structure is used as a single-item cache of information
21488 about a nested archive (when members of a thin archive reside within
21489 another regular archive file). */
21490 nested_arch.file_name = NULL;
21491 nested_arch.file = NULL;
21492 nested_arch.index_array = NULL;
21493 nested_arch.sym_table = NULL;
21494 nested_arch.longnames = NULL;
21495
dda8d76d 21496 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
21497 filedata->file_size, is_thin_archive,
21498 do_archive_index) != 0)
2cf0635d 21499 {
015dc7e1 21500 ret = false;
2cf0635d 21501 goto out;
4145f1d5 21502 }
fb52b2f4 21503
4145f1d5
NC
21504 if (do_archive_index)
21505 {
2cf0635d 21506 if (arch.sym_table == NULL)
1cb7d8b1
AM
21507 error (_("%s: unable to dump the index as none was found\n"),
21508 filedata->file_name);
4145f1d5
NC
21509 else
21510 {
591f7597 21511 unsigned long i, l;
4145f1d5
NC
21512 unsigned long current_pos;
21513
1cb7d8b1
AM
21514 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
21515 "in the symbol table)\n"),
21516 filedata->file_name, (unsigned long) arch.index_num,
21517 arch.sym_size);
dda8d76d
NC
21518
21519 current_pos = ftell (filedata->handle);
4145f1d5 21520
2cf0635d 21521 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 21522 {
1cb7d8b1
AM
21523 if (i == 0
21524 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
21525 {
21526 char * member_name
21527 = get_archive_member_name_at (&arch, arch.index_array[i],
21528 &nested_arch);
2cf0635d 21529
1cb7d8b1
AM
21530 if (member_name != NULL)
21531 {
21532 char * qualified_name
21533 = make_qualified_name (&arch, &nested_arch,
21534 member_name);
2cf0635d 21535
1cb7d8b1
AM
21536 if (qualified_name != NULL)
21537 {
21538 printf (_("Contents of binary %s at offset "),
21539 qualified_name);
c2a7d3f5
NC
21540 (void) print_vma (arch.index_array[i], PREFIX_HEX);
21541 putchar ('\n');
1cb7d8b1
AM
21542 free (qualified_name);
21543 }
fd486f32 21544 free (member_name);
4145f1d5
NC
21545 }
21546 }
2cf0635d
NC
21547
21548 if (l >= arch.sym_size)
4145f1d5 21549 {
1cb7d8b1
AM
21550 error (_("%s: end of the symbol table reached "
21551 "before the end of the index\n"),
dda8d76d 21552 filedata->file_name);
015dc7e1 21553 ret = false;
cb8f3167 21554 break;
4145f1d5 21555 }
591f7597 21556 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
21557 printf ("\t%.*s\n",
21558 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 21559 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
21560 }
21561
67ce483b 21562 if (arch.uses_64bit_indices)
c2a7d3f5
NC
21563 l = (l + 7) & ~ 7;
21564 else
21565 l += l & 1;
21566
2cf0635d 21567 if (l < arch.sym_size)
32ec8896 21568 {
d3a49aa8
AM
21569 error (ngettext ("%s: %ld byte remains in the symbol table, "
21570 "but without corresponding entries in "
21571 "the index table\n",
21572 "%s: %ld bytes remain in the symbol table, "
21573 "but without corresponding entries in "
21574 "the index table\n",
21575 arch.sym_size - l),
dda8d76d 21576 filedata->file_name, arch.sym_size - l);
015dc7e1 21577 ret = false;
32ec8896 21578 }
4145f1d5 21579
dda8d76d 21580 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 21581 {
1cb7d8b1
AM
21582 error (_("%s: failed to seek back to start of object files "
21583 "in the archive\n"),
dda8d76d 21584 filedata->file_name);
015dc7e1 21585 ret = false;
2cf0635d 21586 goto out;
4145f1d5 21587 }
fb52b2f4 21588 }
4145f1d5
NC
21589
21590 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
21591 && !do_segments && !do_header && !do_dump && !do_version
21592 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 21593 && !do_section_groups && !do_dyn_syms)
2cf0635d 21594 {
015dc7e1 21595 ret = true; /* Archive index only. */
2cf0635d
NC
21596 goto out;
21597 }
fb52b2f4
NC
21598 }
21599
fb52b2f4
NC
21600 while (1)
21601 {
2cf0635d
NC
21602 char * name;
21603 size_t namelen;
21604 char * qualified_name;
21605
21606 /* Read the next archive header. */
dda8d76d 21607 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
21608 {
21609 error (_("%s: failed to seek to next archive header\n"),
21610 arch.file_name);
015dc7e1 21611 ret = false;
1cb7d8b1
AM
21612 break;
21613 }
dda8d76d 21614 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 21615 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
21616 {
21617 if (got == 0)
2cf0635d 21618 break;
28e817cc
NC
21619 /* PR 24049 - we cannot use filedata->file_name as this will
21620 have already been freed. */
21621 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 21622
015dc7e1 21623 ret = false;
1cb7d8b1
AM
21624 break;
21625 }
2cf0635d 21626 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
21627 {
21628 error (_("%s: did not find a valid archive header\n"),
21629 arch.file_name);
015dc7e1 21630 ret = false;
1cb7d8b1
AM
21631 break;
21632 }
2cf0635d
NC
21633
21634 arch.next_arhdr_offset += sizeof arch.arhdr;
21635
978c4450
AM
21636 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
21637 if (filedata->archive_file_size & 01)
21638 ++filedata->archive_file_size;
2cf0635d
NC
21639
21640 name = get_archive_member_name (&arch, &nested_arch);
21641 if (name == NULL)
fb52b2f4 21642 {
28e817cc 21643 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 21644 ret = false;
d989285c 21645 break;
fb52b2f4 21646 }
2cf0635d 21647 namelen = strlen (name);
fb52b2f4 21648
2cf0635d
NC
21649 qualified_name = make_qualified_name (&arch, &nested_arch, name);
21650 if (qualified_name == NULL)
fb52b2f4 21651 {
28e817cc 21652 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 21653 free (name);
015dc7e1 21654 ret = false;
d989285c 21655 break;
fb52b2f4
NC
21656 }
21657
2cf0635d 21658 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
21659 {
21660 /* This is a proxy for an external member of a thin archive. */
21661 Filedata * member_filedata;
21662 char * member_file_name = adjust_relative_path
dda8d76d 21663 (filedata->file_name, name, namelen);
32ec8896 21664
fd486f32 21665 free (name);
1cb7d8b1
AM
21666 if (member_file_name == NULL)
21667 {
fd486f32 21668 free (qualified_name);
015dc7e1 21669 ret = false;
1cb7d8b1
AM
21670 break;
21671 }
2cf0635d 21672
015dc7e1 21673 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
21674 if (member_filedata == NULL)
21675 {
21676 error (_("Input file '%s' is not readable.\n"), member_file_name);
21677 free (member_file_name);
fd486f32 21678 free (qualified_name);
015dc7e1 21679 ret = false;
1cb7d8b1
AM
21680 break;
21681 }
2cf0635d 21682
978c4450 21683 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 21684 member_filedata->file_name = qualified_name;
2cf0635d 21685
1cb7d8b1 21686 if (! process_object (member_filedata))
015dc7e1 21687 ret = false;
2cf0635d 21688
1cb7d8b1
AM
21689 close_file (member_filedata);
21690 free (member_file_name);
1cb7d8b1 21691 }
2cf0635d 21692 else if (is_thin_archive)
1cb7d8b1
AM
21693 {
21694 Filedata thin_filedata;
eb02c04d 21695
1cb7d8b1 21696 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 21697
a043396b
NC
21698 /* PR 15140: Allow for corrupt thin archives. */
21699 if (nested_arch.file == NULL)
21700 {
21701 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 21702 qualified_name, name);
fd486f32
AM
21703 free (qualified_name);
21704 free (name);
015dc7e1 21705 ret = false;
a043396b
NC
21706 break;
21707 }
fd486f32 21708 free (name);
a043396b 21709
1cb7d8b1 21710 /* This is a proxy for a member of a nested archive. */
978c4450
AM
21711 filedata->archive_file_offset
21712 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 21713
1cb7d8b1
AM
21714 /* The nested archive file will have been opened and setup by
21715 get_archive_member_name. */
978c4450
AM
21716 if (fseek (nested_arch.file, filedata->archive_file_offset,
21717 SEEK_SET) != 0)
1cb7d8b1
AM
21718 {
21719 error (_("%s: failed to seek to archive member.\n"),
21720 nested_arch.file_name);
fd486f32 21721 free (qualified_name);
015dc7e1 21722 ret = false;
1cb7d8b1
AM
21723 break;
21724 }
2cf0635d 21725
dda8d76d
NC
21726 thin_filedata.handle = nested_arch.file;
21727 thin_filedata.file_name = qualified_name;
9abca702 21728
1cb7d8b1 21729 if (! process_object (& thin_filedata))
015dc7e1 21730 ret = false;
1cb7d8b1 21731 }
2cf0635d 21732 else
1cb7d8b1 21733 {
fd486f32 21734 free (name);
978c4450 21735 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 21736 filedata->file_name = qualified_name;
1cb7d8b1 21737 if (! process_object (filedata))
015dc7e1 21738 ret = false;
978c4450 21739 arch.next_arhdr_offset += filedata->archive_file_size;
4c836627 21740 /* Stop looping with "negative" archive_file_size. */
978c4450 21741 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 21742 arch.next_arhdr_offset = -1ul;
1cb7d8b1 21743 }
fb52b2f4 21744
2cf0635d 21745 free (qualified_name);
fb52b2f4
NC
21746 }
21747
4145f1d5 21748 out:
2cf0635d
NC
21749 if (nested_arch.file != NULL)
21750 fclose (nested_arch.file);
21751 release_archive (&nested_arch);
21752 release_archive (&arch);
fb52b2f4 21753
d989285c 21754 return ret;
fb52b2f4
NC
21755}
21756
015dc7e1 21757static bool
2cf0635d 21758process_file (char * file_name)
fb52b2f4 21759{
dda8d76d 21760 Filedata * filedata = NULL;
fb52b2f4
NC
21761 struct stat statbuf;
21762 char armag[SARMAG];
015dc7e1 21763 bool ret = true;
fb52b2f4
NC
21764
21765 if (stat (file_name, &statbuf) < 0)
21766 {
f24ddbdd
NC
21767 if (errno == ENOENT)
21768 error (_("'%s': No such file\n"), file_name);
21769 else
21770 error (_("Could not locate '%s'. System error message: %s\n"),
21771 file_name, strerror (errno));
015dc7e1 21772 return false;
f24ddbdd
NC
21773 }
21774
21775 if (! S_ISREG (statbuf.st_mode))
21776 {
21777 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 21778 return false;
fb52b2f4
NC
21779 }
21780
dda8d76d
NC
21781 filedata = calloc (1, sizeof * filedata);
21782 if (filedata == NULL)
21783 {
21784 error (_("Out of memory allocating file data structure\n"));
015dc7e1 21785 return false;
dda8d76d
NC
21786 }
21787
21788 filedata->file_name = file_name;
21789 filedata->handle = fopen (file_name, "rb");
21790 if (filedata->handle == NULL)
fb52b2f4 21791 {
f24ddbdd 21792 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 21793 free (filedata);
015dc7e1 21794 return false;
fb52b2f4
NC
21795 }
21796
dda8d76d 21797 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 21798 {
4145f1d5 21799 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
21800 fclose (filedata->handle);
21801 free (filedata);
015dc7e1 21802 return false;
fb52b2f4
NC
21803 }
21804
dda8d76d 21805 filedata->file_size = (bfd_size_type) statbuf.st_size;
015dc7e1 21806 filedata->is_separate = false;
f54498b4 21807
fb52b2f4 21808 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 21809 {
015dc7e1
AM
21810 if (! process_archive (filedata, false))
21811 ret = false;
32ec8896 21812 }
2cf0635d 21813 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 21814 {
015dc7e1
AM
21815 if ( ! process_archive (filedata, true))
21816 ret = false;
32ec8896 21817 }
fb52b2f4
NC
21818 else
21819 {
1b513401 21820 if (do_archive_index && !check_all)
4145f1d5
NC
21821 error (_("File %s is not an archive so its index cannot be displayed.\n"),
21822 file_name);
21823
dda8d76d 21824 rewind (filedata->handle);
978c4450 21825 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 21826
dda8d76d 21827 if (! process_object (filedata))
015dc7e1 21828 ret = false;
fb52b2f4
NC
21829 }
21830
dda8d76d 21831 fclose (filedata->handle);
8fb879cd
AM
21832 free (filedata->section_headers);
21833 free (filedata->program_headers);
21834 free (filedata->string_table);
6431e409 21835 free (filedata->dump.dump_sects);
dda8d76d 21836 free (filedata);
32ec8896 21837
fd486f32 21838 free (ba_cache.strtab);
1bd6175a 21839 ba_cache.strtab = NULL;
fd486f32 21840 free (ba_cache.symtab);
1bd6175a 21841 ba_cache.symtab = NULL;
fd486f32
AM
21842 ba_cache.filedata = NULL;
21843
fb52b2f4
NC
21844 return ret;
21845}
21846
252b5132
RH
21847#ifdef SUPPORT_DISASSEMBLY
21848/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 21849 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 21850 symbols. */
252b5132
RH
21851
21852void
2cf0635d 21853print_address (unsigned int addr, FILE * outfile)
252b5132
RH
21854{
21855 fprintf (outfile,"0x%8.8x", addr);
21856}
21857
e3c8793a 21858/* Needed by the i386 disassembler. */
dda8d76d 21859
252b5132
RH
21860void
21861db_task_printsym (unsigned int addr)
21862{
21863 print_address (addr, stderr);
21864}
21865#endif
21866
21867int
2cf0635d 21868main (int argc, char ** argv)
252b5132 21869{
ff78d6d6
L
21870 int err;
21871
87b9f255 21872#ifdef HAVE_LC_MESSAGES
252b5132 21873 setlocale (LC_MESSAGES, "");
3882b010 21874#endif
3882b010 21875 setlocale (LC_CTYPE, "");
252b5132
RH
21876 bindtextdomain (PACKAGE, LOCALEDIR);
21877 textdomain (PACKAGE);
21878
869b9d07
MM
21879 expandargv (&argc, &argv);
21880
dda8d76d 21881 parse_args (& cmdline, argc, argv);
59f14fc0 21882
18bd398b 21883 if (optind < (argc - 1))
1b513401
NC
21884 /* When displaying information for more than one file,
21885 prefix the information with the file name. */
015dc7e1 21886 show_name = true;
5656ba2c
L
21887 else if (optind >= argc)
21888 {
1b513401 21889 /* Ensure that the warning is always displayed. */
015dc7e1 21890 do_checks = true;
1b513401 21891
5656ba2c
L
21892 warn (_("Nothing to do.\n"));
21893 usage (stderr);
21894 }
18bd398b 21895
015dc7e1 21896 err = false;
252b5132 21897 while (optind < argc)
32ec8896 21898 if (! process_file (argv[optind++]))
015dc7e1 21899 err = true;
252b5132 21900
9db70fc3 21901 free (cmdline.dump_sects);
252b5132 21902
7d9813f1
NA
21903 free (dump_ctf_symtab_name);
21904 free (dump_ctf_strtab_name);
21905 free (dump_ctf_parent_name);
21906
32ec8896 21907 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 21908}
This page took 3.817427 seconds and 4 git commands to generate.