Re: readelf section reading
[deliverable/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
250d07de 2 Copyright (C) 1998-2021 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056 46#include <zlib.h>
7bfd842d 47#include <wchar.h>
252b5132 48
a952a375 49#if __GNUC__ >= 2
19936277 50/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 51 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 52 Only do this if we believe that the compiler can support a 64 bit
a952a375 53 data type. For now we only rely on GCC being able to do this. */
19936277 54#define BFD64
a952a375
NC
55#endif
56
3db64b00
AM
57#include "bfd.h"
58#include "bucomm.h"
3284fe0c 59#include "elfcomm.h"
19e6b90e 60#include "dwarf.h"
7d9813f1 61#include "ctf-api.h"
79bc120c 62#include "demangle.h"
252b5132
RH
63
64#include "elf/common.h"
65#include "elf/external.h"
66#include "elf/internal.h"
252b5132 67
4b78141a
NC
68
69/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
70 we can obtain the H8 reloc numbers. We need these for the
71 get_reloc_size() function. We include h8.h again after defining
72 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
73
74#include "elf/h8.h"
75#undef _ELF_H8_H
76
77/* Undo the effects of #including reloc-macros.h. */
78
79#undef START_RELOC_NUMBERS
80#undef RELOC_NUMBER
81#undef FAKE_RELOC
82#undef EMPTY_RELOC
83#undef END_RELOC_NUMBERS
84#undef _RELOC_MACROS_H
85
252b5132
RH
86/* The following headers use the elf/reloc-macros.h file to
87 automatically generate relocation recognition functions
88 such as elf_mips_reloc_type() */
89
90#define RELOC_MACROS_GEN_FUNC
91
a06ea964 92#include "elf/aarch64.h"
252b5132 93#include "elf/alpha.h"
3b16e843 94#include "elf/arc.h"
252b5132 95#include "elf/arm.h"
3b16e843 96#include "elf/avr.h"
1d65ded4 97#include "elf/bfin.h"
60bca95a 98#include "elf/cr16.h"
3b16e843 99#include "elf/cris.h"
1c0d3aa6 100#include "elf/crx.h"
b8891f8d 101#include "elf/csky.h"
252b5132
RH
102#include "elf/d10v.h"
103#include "elf/d30v.h"
d172d4ba 104#include "elf/dlx.h"
aca4efc7 105#include "elf/bpf.h"
cfb8c092 106#include "elf/epiphany.h"
252b5132 107#include "elf/fr30.h"
5c70f934 108#include "elf/frv.h"
3f8107ab 109#include "elf/ft32.h"
3b16e843
NC
110#include "elf/h8.h"
111#include "elf/hppa.h"
112#include "elf/i386.h"
f954747f
AM
113#include "elf/i370.h"
114#include "elf/i860.h"
115#include "elf/i960.h"
3b16e843 116#include "elf/ia64.h"
1e4cf259 117#include "elf/ip2k.h"
84e94c90 118#include "elf/lm32.h"
1c0d3aa6 119#include "elf/iq2000.h"
49f58d10 120#include "elf/m32c.h"
3b16e843
NC
121#include "elf/m32r.h"
122#include "elf/m68k.h"
75751cd9 123#include "elf/m68hc11.h"
7b4ae824 124#include "elf/s12z.h"
252b5132 125#include "elf/mcore.h"
15ab5209 126#include "elf/mep.h"
a3c62988 127#include "elf/metag.h"
7ba29e2a 128#include "elf/microblaze.h"
3b16e843 129#include "elf/mips.h"
3c3bdf30 130#include "elf/mmix.h"
3b16e843
NC
131#include "elf/mn10200.h"
132#include "elf/mn10300.h"
5506d11a 133#include "elf/moxie.h"
4970f871 134#include "elf/mt.h"
2469cfa2 135#include "elf/msp430.h"
35c08157 136#include "elf/nds32.h"
fe944acf 137#include "elf/nfp.h"
13761a11 138#include "elf/nios2.h"
73589c9d 139#include "elf/or1k.h"
7d466069 140#include "elf/pj.h"
3b16e843 141#include "elf/ppc.h"
c833c019 142#include "elf/ppc64.h"
2b100bb5 143#include "elf/pru.h"
03336641 144#include "elf/riscv.h"
99c513f6 145#include "elf/rl78.h"
c7927a3c 146#include "elf/rx.h"
a85d7ed0 147#include "elf/s390.h"
1c0d3aa6 148#include "elf/score.h"
3b16e843
NC
149#include "elf/sh.h"
150#include "elf/sparc.h"
e9f53129 151#include "elf/spu.h"
40b36596 152#include "elf/tic6x.h"
aa137e4d
NC
153#include "elf/tilegx.h"
154#include "elf/tilepro.h"
3b16e843 155#include "elf/v850.h"
179d3252 156#include "elf/vax.h"
619ed720 157#include "elf/visium.h"
f96bd6c2 158#include "elf/wasm32.h"
3b16e843 159#include "elf/x86-64.h"
c29aca4a 160#include "elf/xc16x.h"
f6c1a2d5 161#include "elf/xgate.h"
93fbbb04 162#include "elf/xstormy16.h"
88da6820 163#include "elf/xtensa.h"
6655dba2 164#include "elf/z80.h"
252b5132 165
252b5132 166#include "getopt.h"
566b0d53 167#include "libiberty.h"
09c11c86 168#include "safe-ctype.h"
2cf0635d 169#include "filenames.h"
252b5132 170
15b42fb0
AM
171#ifndef offsetof
172#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
173#endif
174
6a40cf0c
NC
175typedef struct elf_section_list
176{
dda8d76d
NC
177 Elf_Internal_Shdr * hdr;
178 struct elf_section_list * next;
6a40cf0c
NC
179} elf_section_list;
180
dda8d76d
NC
181/* Flag bits indicating particular types of dump. */
182#define HEX_DUMP (1 << 0) /* The -x command line switch. */
183#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
184#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
185#define STRING_DUMP (1 << 3) /* The -p command line switch. */
186#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 187#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
188
189typedef unsigned char dump_type;
190
191/* A linked list of the section names for which dumps were requested. */
192struct dump_list_entry
193{
194 char * name;
195 dump_type type;
196 struct dump_list_entry * next;
197};
198
6431e409
AM
199/* A dynamic array of flags indicating for which sections a dump
200 has been requested via command line switches. */
1b513401
NC
201struct dump_data
202{
6431e409
AM
203 dump_type * dump_sects;
204 unsigned int num_dump_sects;
205};
206
207static struct dump_data cmdline;
208
209static struct dump_list_entry * dump_sects_byname;
210
2cf0635d 211char * program_name = "readelf";
dda8d76d 212
015dc7e1
AM
213static bool show_name = false;
214static bool do_dynamic = false;
215static bool do_syms = false;
216static bool do_dyn_syms = false;
217static bool do_lto_syms = false;
218static bool do_reloc = false;
219static bool do_sections = false;
220static bool do_section_groups = false;
221static bool do_section_details = false;
222static bool do_segments = false;
223static bool do_unwind = false;
224static bool do_using_dynamic = false;
225static bool do_header = false;
226static bool do_dump = false;
227static bool do_version = false;
228static bool do_histogram = false;
229static bool do_debugging = false;
230static bool do_ctf = false;
231static bool do_arch = false;
232static bool do_notes = false;
233static bool do_archive_index = false;
234static bool check_all = false;
235static bool is_32bit_elf = false;
236static bool decompress_dumps = false;
237static bool do_not_show_symbol_truncation = false;
238static bool do_demangle = false; /* Pretty print C++ symbol names. */
239static bool process_links = false;
79bc120c 240static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 241static int sym_base = 0;
252b5132 242
7d9813f1
NA
243static char *dump_ctf_parent_name;
244static char *dump_ctf_symtab_name;
245static char *dump_ctf_strtab_name;
246
e4b17d5c
L
247struct group_list
248{
dda8d76d
NC
249 struct group_list * next;
250 unsigned int section_index;
e4b17d5c
L
251};
252
253struct group
254{
dda8d76d
NC
255 struct group_list * root;
256 unsigned int group_index;
e4b17d5c
L
257};
258
978c4450
AM
259typedef struct filedata
260{
261 const char * file_name;
015dc7e1 262 bool is_separate;
978c4450
AM
263 FILE * handle;
264 bfd_size_type file_size;
265 Elf_Internal_Ehdr file_header;
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
4de91c10
AM
5862 if (is_32bit_elf)
5863 return get_32bit_section_headers (filedata, probe);
5864 else
5865 return get_64bit_section_headers (filedata, probe);
5866}
5867
252b5132 5868static Elf_Internal_Sym *
dda8d76d
NC
5869get_32bit_elf_symbols (Filedata * filedata,
5870 Elf_Internal_Shdr * section,
5871 unsigned long * num_syms_return)
252b5132 5872{
ba5cdace 5873 unsigned long number = 0;
dd24e3da 5874 Elf32_External_Sym * esyms = NULL;
ba5cdace 5875 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5876 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5877 Elf_Internal_Sym * psym;
b34976b6 5878 unsigned int j;
e3d39609 5879 elf_section_list * entry;
252b5132 5880
c9c1d674
EG
5881 if (section->sh_size == 0)
5882 {
5883 if (num_syms_return != NULL)
5884 * num_syms_return = 0;
5885 return NULL;
5886 }
5887
dd24e3da 5888 /* Run some sanity checks first. */
c9c1d674 5889 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5890 {
c9c1d674 5891 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5892 printable_section_name (filedata, section),
5893 (unsigned long) section->sh_entsize);
ba5cdace 5894 goto exit_point;
dd24e3da
NC
5895 }
5896
dda8d76d 5897 if (section->sh_size > filedata->file_size)
f54498b4
NC
5898 {
5899 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5900 printable_section_name (filedata, section),
5901 (unsigned long) section->sh_size);
f54498b4
NC
5902 goto exit_point;
5903 }
5904
dd24e3da
NC
5905 number = section->sh_size / section->sh_entsize;
5906
5907 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5908 {
c9c1d674 5909 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5910 (unsigned long) section->sh_size,
dda8d76d 5911 printable_section_name (filedata, section),
8066deb1 5912 (unsigned long) section->sh_entsize);
ba5cdace 5913 goto exit_point;
dd24e3da
NC
5914 }
5915
dda8d76d 5916 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5917 section->sh_size, _("symbols"));
dd24e3da 5918 if (esyms == NULL)
ba5cdace 5919 goto exit_point;
252b5132 5920
e3d39609 5921 shndx = NULL;
978c4450 5922 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5923 {
5924 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5925 continue;
5926
5927 if (shndx != NULL)
5928 {
5929 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5930 free (shndx);
5931 }
5932
5933 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5934 entry->hdr->sh_offset,
5935 1, entry->hdr->sh_size,
5936 _("symbol table section indices"));
5937 if (shndx == NULL)
5938 goto exit_point;
5939
5940 /* PR17531: file: heap-buffer-overflow */
5941 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5942 {
5943 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5944 printable_section_name (filedata, entry->hdr),
5945 (unsigned long) entry->hdr->sh_size,
5946 (unsigned long) section->sh_size);
5947 goto exit_point;
c9c1d674 5948 }
e3d39609 5949 }
9ad5cbcf 5950
3f5e193b 5951 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5952
5953 if (isyms == NULL)
5954 {
8b73c356
NC
5955 error (_("Out of memory reading %lu symbols\n"),
5956 (unsigned long) number);
dd24e3da 5957 goto exit_point;
252b5132
RH
5958 }
5959
dd24e3da 5960 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5961 {
5962 psym->st_name = BYTE_GET (esyms[j].st_name);
5963 psym->st_value = BYTE_GET (esyms[j].st_value);
5964 psym->st_size = BYTE_GET (esyms[j].st_size);
5965 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5966 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5967 psym->st_shndx
5968 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5969 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5970 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5971 psym->st_info = BYTE_GET (esyms[j].st_info);
5972 psym->st_other = BYTE_GET (esyms[j].st_other);
5973 }
5974
dd24e3da 5975 exit_point:
e3d39609
NC
5976 free (shndx);
5977 free (esyms);
252b5132 5978
ba5cdace
NC
5979 if (num_syms_return != NULL)
5980 * num_syms_return = isyms == NULL ? 0 : number;
5981
252b5132
RH
5982 return isyms;
5983}
5984
9ea033b2 5985static Elf_Internal_Sym *
dda8d76d
NC
5986get_64bit_elf_symbols (Filedata * filedata,
5987 Elf_Internal_Shdr * section,
5988 unsigned long * num_syms_return)
9ea033b2 5989{
ba5cdace
NC
5990 unsigned long number = 0;
5991 Elf64_External_Sym * esyms = NULL;
5992 Elf_External_Sym_Shndx * shndx = NULL;
5993 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5994 Elf_Internal_Sym * psym;
b34976b6 5995 unsigned int j;
e3d39609 5996 elf_section_list * entry;
9ea033b2 5997
c9c1d674
EG
5998 if (section->sh_size == 0)
5999 {
6000 if (num_syms_return != NULL)
6001 * num_syms_return = 0;
6002 return NULL;
6003 }
6004
dd24e3da 6005 /* Run some sanity checks first. */
c9c1d674 6006 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6007 {
c9c1d674 6008 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 6009 printable_section_name (filedata, section),
8066deb1 6010 (unsigned long) section->sh_entsize);
ba5cdace 6011 goto exit_point;
dd24e3da
NC
6012 }
6013
dda8d76d 6014 if (section->sh_size > filedata->file_size)
f54498b4
NC
6015 {
6016 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 6017 printable_section_name (filedata, section),
8066deb1 6018 (unsigned long) section->sh_size);
f54498b4
NC
6019 goto exit_point;
6020 }
6021
dd24e3da
NC
6022 number = section->sh_size / section->sh_entsize;
6023
6024 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6025 {
c9c1d674 6026 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6027 (unsigned long) section->sh_size,
dda8d76d 6028 printable_section_name (filedata, section),
8066deb1 6029 (unsigned long) section->sh_entsize);
ba5cdace 6030 goto exit_point;
dd24e3da
NC
6031 }
6032
dda8d76d 6033 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6034 section->sh_size, _("symbols"));
a6e9f9df 6035 if (!esyms)
ba5cdace 6036 goto exit_point;
9ea033b2 6037
e3d39609 6038 shndx = NULL;
978c4450 6039 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6040 {
6041 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6042 continue;
6043
6044 if (shndx != NULL)
6045 {
6046 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6047 free (shndx);
c9c1d674 6048 }
e3d39609
NC
6049
6050 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6051 entry->hdr->sh_offset,
6052 1, entry->hdr->sh_size,
6053 _("symbol table section indices"));
6054 if (shndx == NULL)
6055 goto exit_point;
6056
6057 /* PR17531: file: heap-buffer-overflow */
6058 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6059 {
6060 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6061 printable_section_name (filedata, entry->hdr),
6062 (unsigned long) entry->hdr->sh_size,
6063 (unsigned long) section->sh_size);
6064 goto exit_point;
6065 }
6066 }
9ad5cbcf 6067
3f5e193b 6068 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6069
6070 if (isyms == NULL)
6071 {
8b73c356
NC
6072 error (_("Out of memory reading %lu symbols\n"),
6073 (unsigned long) number);
ba5cdace 6074 goto exit_point;
9ea033b2
NC
6075 }
6076
ba5cdace 6077 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6078 {
6079 psym->st_name = BYTE_GET (esyms[j].st_name);
6080 psym->st_info = BYTE_GET (esyms[j].st_info);
6081 psym->st_other = BYTE_GET (esyms[j].st_other);
6082 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6083
4fbb74a6 6084 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6085 psym->st_shndx
6086 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6087 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6088 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6089
66543521
AM
6090 psym->st_value = BYTE_GET (esyms[j].st_value);
6091 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6092 }
6093
ba5cdace 6094 exit_point:
e3d39609
NC
6095 free (shndx);
6096 free (esyms);
ba5cdace
NC
6097
6098 if (num_syms_return != NULL)
6099 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6100
6101 return isyms;
6102}
6103
4de91c10
AM
6104static Elf_Internal_Sym *
6105get_elf_symbols (Filedata *filedata,
6106 Elf_Internal_Shdr *section,
6107 unsigned long *num_syms_return)
6108{
6109 if (is_32bit_elf)
6110 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6111 else
6112 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6113}
6114
d1133906 6115static const char *
dda8d76d 6116get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 6117{
5477e8a0 6118 static char buff[1024];
2cf0635d 6119 char * p = buff;
32ec8896
NC
6120 unsigned int field_size = is_32bit_elf ? 8 : 16;
6121 signed int sindex;
6122 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
6123 bfd_vma os_flags = 0;
6124 bfd_vma proc_flags = 0;
6125 bfd_vma unknown_flags = 0;
148b93f2 6126 static const struct
5477e8a0 6127 {
2cf0635d 6128 const char * str;
32ec8896 6129 unsigned int len;
5477e8a0
L
6130 }
6131 flags [] =
6132 {
cfcac11d
NC
6133 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6134 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6135 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6136 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6137 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6138 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6139 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6140 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6141 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6142 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6143 /* IA-64 specific. */
6144 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6145 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6146 /* IA-64 OpenVMS specific. */
6147 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6148 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6149 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6150 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6151 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6152 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6153 /* Generic. */
cfcac11d 6154 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6155 /* SPARC specific. */
77115a4a 6156 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6157 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6158 /* ARM specific. */
6159 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6160 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6161 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6162 /* GNU specific. */
6163 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6164 /* VLE specific. */
6165 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6166 /* GNU specific. */
6167 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6168 };
6169
6170 if (do_section_details)
6171 {
8d5ff12c
L
6172 sprintf (buff, "[%*.*lx]: ",
6173 field_size, field_size, (unsigned long) sh_flags);
6174 p += field_size + 4;
5477e8a0 6175 }
76da6bbe 6176
d1133906
NC
6177 while (sh_flags)
6178 {
6179 bfd_vma flag;
6180
6181 flag = sh_flags & - sh_flags;
6182 sh_flags &= ~ flag;
76da6bbe 6183
5477e8a0 6184 if (do_section_details)
d1133906 6185 {
5477e8a0
L
6186 switch (flag)
6187 {
91d6fa6a
NC
6188 case SHF_WRITE: sindex = 0; break;
6189 case SHF_ALLOC: sindex = 1; break;
6190 case SHF_EXECINSTR: sindex = 2; break;
6191 case SHF_MERGE: sindex = 3; break;
6192 case SHF_STRINGS: sindex = 4; break;
6193 case SHF_INFO_LINK: sindex = 5; break;
6194 case SHF_LINK_ORDER: sindex = 6; break;
6195 case SHF_OS_NONCONFORMING: sindex = 7; break;
6196 case SHF_GROUP: sindex = 8; break;
6197 case SHF_TLS: sindex = 9; break;
18ae9cc1 6198 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6199 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6200
5477e8a0 6201 default:
91d6fa6a 6202 sindex = -1;
dda8d76d 6203 switch (filedata->file_header.e_machine)
148b93f2 6204 {
cfcac11d 6205 case EM_IA_64:
148b93f2 6206 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6207 sindex = 10;
148b93f2 6208 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6209 sindex = 11;
148b93f2 6210#ifdef BFD64
dda8d76d 6211 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6212 switch (flag)
6213 {
91d6fa6a
NC
6214 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6215 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6216 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6217 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6218 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6219 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6220 default: break;
6221 }
6222#endif
cfcac11d
NC
6223 break;
6224
caa83f8b 6225 case EM_386:
22abe556 6226 case EM_IAMCU:
caa83f8b 6227 case EM_X86_64:
7f502d6c 6228 case EM_L1OM:
7a9068fe 6229 case EM_K1OM:
cfcac11d
NC
6230 case EM_OLD_SPARCV9:
6231 case EM_SPARC32PLUS:
6232 case EM_SPARCV9:
6233 case EM_SPARC:
18ae9cc1 6234 if (flag == SHF_ORDERED)
91d6fa6a 6235 sindex = 19;
cfcac11d 6236 break;
ac4c9b04
MG
6237
6238 case EM_ARM:
6239 switch (flag)
6240 {
6241 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6242 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6243 case SHF_COMDEF: sindex = 23; break;
6244 default: break;
6245 }
6246 break;
83eef883
AFB
6247 case EM_PPC:
6248 if (flag == SHF_PPC_VLE)
6249 sindex = 25;
6250 break;
99fabbc9
JL
6251 default:
6252 break;
6253 }
ac4c9b04 6254
99fabbc9
JL
6255 switch (filedata->file_header.e_ident[EI_OSABI])
6256 {
6257 case ELFOSABI_GNU:
6258 case ELFOSABI_FREEBSD:
6259 if (flag == SHF_GNU_RETAIN)
6260 sindex = 26;
6261 /* Fall through */
6262 case ELFOSABI_NONE:
6263 if (flag == SHF_GNU_MBIND)
6264 /* We should not recognize SHF_GNU_MBIND for
6265 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6266 not set the EI_OSABI header byte. */
6267 sindex = 24;
6268 break;
cfcac11d
NC
6269 default:
6270 break;
148b93f2 6271 }
99fabbc9 6272 break;
5477e8a0
L
6273 }
6274
91d6fa6a 6275 if (sindex != -1)
5477e8a0 6276 {
8d5ff12c
L
6277 if (p != buff + field_size + 4)
6278 {
6279 if (size < (10 + 2))
bee0ee85
NC
6280 {
6281 warn (_("Internal error: not enough buffer room for section flag info"));
6282 return _("<unknown>");
6283 }
8d5ff12c
L
6284 size -= 2;
6285 *p++ = ',';
6286 *p++ = ' ';
6287 }
6288
91d6fa6a
NC
6289 size -= flags [sindex].len;
6290 p = stpcpy (p, flags [sindex].str);
5477e8a0 6291 }
3b22753a 6292 else if (flag & SHF_MASKOS)
8d5ff12c 6293 os_flags |= flag;
d1133906 6294 else if (flag & SHF_MASKPROC)
8d5ff12c 6295 proc_flags |= flag;
d1133906 6296 else
8d5ff12c 6297 unknown_flags |= flag;
5477e8a0
L
6298 }
6299 else
6300 {
6301 switch (flag)
6302 {
6303 case SHF_WRITE: *p = 'W'; break;
6304 case SHF_ALLOC: *p = 'A'; break;
6305 case SHF_EXECINSTR: *p = 'X'; break;
6306 case SHF_MERGE: *p = 'M'; break;
6307 case SHF_STRINGS: *p = 'S'; break;
6308 case SHF_INFO_LINK: *p = 'I'; break;
6309 case SHF_LINK_ORDER: *p = 'L'; break;
6310 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6311 case SHF_GROUP: *p = 'G'; break;
6312 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6313 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6314 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6315
6316 default:
dda8d76d
NC
6317 if ((filedata->file_header.e_machine == EM_X86_64
6318 || filedata->file_header.e_machine == EM_L1OM
6319 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6320 && flag == SHF_X86_64_LARGE)
6321 *p = 'l';
dda8d76d 6322 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6323 && flag == SHF_ARM_PURECODE)
99fabbc9 6324 *p = 'y';
dda8d76d 6325 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6326 && flag == SHF_PPC_VLE)
99fabbc9 6327 *p = 'v';
5477e8a0
L
6328 else if (flag & SHF_MASKOS)
6329 {
99fabbc9
JL
6330 switch (filedata->file_header.e_ident[EI_OSABI])
6331 {
6332 case ELFOSABI_GNU:
6333 case ELFOSABI_FREEBSD:
6334 if (flag == SHF_GNU_RETAIN)
6335 {
6336 *p = 'R';
6337 break;
6338 }
6339 /* Fall through */
6340 case ELFOSABI_NONE:
6341 if (flag == SHF_GNU_MBIND)
6342 {
6343 /* We should not recognize SHF_GNU_MBIND for
6344 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6345 not set the EI_OSABI header byte. */
6346 *p = 'D';
6347 break;
6348 }
6349 /* Fall through */
6350 default:
6351 *p = 'o';
6352 sh_flags &= ~SHF_MASKOS;
6353 break;
6354 }
5477e8a0
L
6355 }
6356 else if (flag & SHF_MASKPROC)
6357 {
6358 *p = 'p';
6359 sh_flags &= ~ SHF_MASKPROC;
6360 }
6361 else
6362 *p = 'x';
6363 break;
6364 }
6365 p++;
d1133906
NC
6366 }
6367 }
76da6bbe 6368
8d5ff12c
L
6369 if (do_section_details)
6370 {
6371 if (os_flags)
6372 {
6373 size -= 5 + field_size;
6374 if (p != buff + field_size + 4)
6375 {
6376 if (size < (2 + 1))
bee0ee85
NC
6377 {
6378 warn (_("Internal error: not enough buffer room for section flag info"));
6379 return _("<unknown>");
6380 }
8d5ff12c
L
6381 size -= 2;
6382 *p++ = ',';
6383 *p++ = ' ';
6384 }
6385 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6386 (unsigned long) os_flags);
6387 p += 5 + field_size;
6388 }
6389 if (proc_flags)
6390 {
6391 size -= 7 + field_size;
6392 if (p != buff + field_size + 4)
6393 {
6394 if (size < (2 + 1))
bee0ee85
NC
6395 {
6396 warn (_("Internal error: not enough buffer room for section flag info"));
6397 return _("<unknown>");
6398 }
8d5ff12c
L
6399 size -= 2;
6400 *p++ = ',';
6401 *p++ = ' ';
6402 }
6403 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6404 (unsigned long) proc_flags);
6405 p += 7 + field_size;
6406 }
6407 if (unknown_flags)
6408 {
6409 size -= 10 + field_size;
6410 if (p != buff + field_size + 4)
6411 {
6412 if (size < (2 + 1))
bee0ee85
NC
6413 {
6414 warn (_("Internal error: not enough buffer room for section flag info"));
6415 return _("<unknown>");
6416 }
8d5ff12c
L
6417 size -= 2;
6418 *p++ = ',';
6419 *p++ = ' ';
6420 }
2b692964 6421 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6422 (unsigned long) unknown_flags);
6423 p += 10 + field_size;
6424 }
6425 }
6426
e9e44622 6427 *p = '\0';
d1133906
NC
6428 return buff;
6429}
6430
5844b465 6431static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6432get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6433{
6434 if (is_32bit_elf)
6435 {
6436 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6437
ebdf1ebf
NC
6438 if (size < sizeof (* echdr))
6439 {
6440 error (_("Compressed section is too small even for a compression header\n"));
6441 return 0;
6442 }
6443
77115a4a
L
6444 chdr->ch_type = BYTE_GET (echdr->ch_type);
6445 chdr->ch_size = BYTE_GET (echdr->ch_size);
6446 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6447 return sizeof (*echdr);
6448 }
6449 else
6450 {
6451 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6452
ebdf1ebf
NC
6453 if (size < sizeof (* echdr))
6454 {
6455 error (_("Compressed section is too small even for a compression header\n"));
6456 return 0;
6457 }
6458
77115a4a
L
6459 chdr->ch_type = BYTE_GET (echdr->ch_type);
6460 chdr->ch_size = BYTE_GET (echdr->ch_size);
6461 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6462 return sizeof (*echdr);
6463 }
6464}
6465
015dc7e1 6466static bool
dda8d76d 6467process_section_headers (Filedata * filedata)
252b5132 6468{
2cf0635d 6469 Elf_Internal_Shdr * section;
b34976b6 6470 unsigned int i;
252b5132 6471
dda8d76d 6472 if (filedata->file_header.e_shnum == 0)
252b5132 6473 {
82f2dbf7 6474 /* PR binutils/12467. */
dda8d76d 6475 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6476 {
6477 warn (_("possibly corrupt ELF file header - it has a non-zero"
6478 " section header offset, but no section headers\n"));
015dc7e1 6479 return false;
32ec8896 6480 }
82f2dbf7 6481 else if (do_sections)
252b5132
RH
6482 printf (_("\nThere are no sections in this file.\n"));
6483
015dc7e1 6484 return true;
252b5132
RH
6485 }
6486
6487 if (do_sections && !do_header)
ca0e11aa
NC
6488 {
6489 if (filedata->is_separate && process_links)
6490 printf (_("In linked file '%s': "), filedata->file_name);
6491 if (! filedata->is_separate || process_links)
6492 printf (ngettext ("There is %d section header, "
6493 "starting at offset 0x%lx:\n",
6494 "There are %d section headers, "
6495 "starting at offset 0x%lx:\n",
6496 filedata->file_header.e_shnum),
6497 filedata->file_header.e_shnum,
6498 (unsigned long) filedata->file_header.e_shoff);
6499 }
252b5132 6500
4de91c10
AM
6501 if (!get_section_headers (filedata, false))
6502 return false;
252b5132
RH
6503
6504 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6505 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6506 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6507 {
dda8d76d 6508 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6509
c256ffe7
JJ
6510 if (section->sh_size != 0)
6511 {
dda8d76d
NC
6512 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6513 1, section->sh_size,
6514 _("string table"));
0de14b54 6515
dda8d76d 6516 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6517 }
252b5132
RH
6518 }
6519
6520 /* Scan the sections for the dynamic symbol table
e3c8793a 6521 and dynamic string table and debug sections. */
89fac5e3 6522 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6523 switch (filedata->file_header.e_machine)
89fac5e3
RS
6524 {
6525 case EM_MIPS:
6526 case EM_MIPS_RS3_LE:
6527 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6528 FDE addresses. However, the ABI also has a semi-official ILP32
6529 variant for which the normal FDE address size rules apply.
6530
6531 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6532 section, where XX is the size of longs in bits. Unfortunately,
6533 earlier compilers provided no way of distinguishing ILP32 objects
6534 from LP64 objects, so if there's any doubt, we should assume that
6535 the official LP64 form is being used. */
dda8d76d
NC
6536 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6537 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6538 eh_addr_size = 8;
6539 break;
0f56a26a
DD
6540
6541 case EM_H8_300:
6542 case EM_H8_300H:
dda8d76d 6543 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6544 {
6545 case E_H8_MACH_H8300:
6546 case E_H8_MACH_H8300HN:
6547 case E_H8_MACH_H8300SN:
6548 case E_H8_MACH_H8300SXN:
6549 eh_addr_size = 2;
6550 break;
6551 case E_H8_MACH_H8300H:
6552 case E_H8_MACH_H8300S:
6553 case E_H8_MACH_H8300SX:
6554 eh_addr_size = 4;
6555 break;
6556 }
f4236fe4
DD
6557 break;
6558
ff7eeb89 6559 case EM_M32C_OLD:
f4236fe4 6560 case EM_M32C:
dda8d76d 6561 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6562 {
6563 case EF_M32C_CPU_M16C:
6564 eh_addr_size = 2;
6565 break;
6566 }
6567 break;
89fac5e3
RS
6568 }
6569
76ca31c0
NC
6570#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6571 do \
6572 { \
6573 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6574 if (section->sh_entsize != expected_entsize) \
9dd3a467 6575 { \
76ca31c0
NC
6576 char buf[40]; \
6577 sprintf_vma (buf, section->sh_entsize); \
6578 /* Note: coded this way so that there is a single string for \
6579 translation. */ \
6580 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6581 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6582 (unsigned) expected_entsize); \
9dd3a467 6583 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6584 } \
6585 } \
08d8fa11 6586 while (0)
9dd3a467
NC
6587
6588#define CHECK_ENTSIZE(section, i, type) \
1b513401 6589 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
6590 sizeof (Elf64_External_##type))
6591
dda8d76d
NC
6592 for (i = 0, section = filedata->section_headers;
6593 i < filedata->file_header.e_shnum;
b34976b6 6594 i++, section++)
252b5132 6595 {
b9e920ec 6596 char * name = SECTION_NAME_PRINT (section);
252b5132 6597
1b513401
NC
6598 /* Run some sanity checks on the headers and
6599 possibly fill in some file data as well. */
6600 switch (section->sh_type)
252b5132 6601 {
1b513401 6602 case SHT_DYNSYM:
978c4450 6603 if (filedata->dynamic_symbols != NULL)
252b5132
RH
6604 {
6605 error (_("File contains multiple dynamic symbol tables\n"));
6606 continue;
6607 }
6608
08d8fa11 6609 CHECK_ENTSIZE (section, i, Sym);
978c4450 6610 filedata->dynamic_symbols
4de91c10 6611 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 6612 filedata->dynamic_symtab_section = section;
1b513401
NC
6613 break;
6614
6615 case SHT_STRTAB:
6616 if (streq (name, ".dynstr"))
252b5132 6617 {
1b513401
NC
6618 if (filedata->dynamic_strings != NULL)
6619 {
6620 error (_("File contains multiple dynamic string tables\n"));
6621 continue;
6622 }
6623
6624 filedata->dynamic_strings
6625 = (char *) get_data (NULL, filedata, section->sh_offset,
6626 1, section->sh_size, _("dynamic strings"));
6627 filedata->dynamic_strings_length
6628 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 6629 filedata->dynamic_strtab_section = section;
252b5132 6630 }
1b513401
NC
6631 break;
6632
6633 case SHT_SYMTAB_SHNDX:
6634 {
6635 elf_section_list * entry = xmalloc (sizeof * entry);
6636
6637 entry->hdr = section;
6638 entry->next = filedata->symtab_shndx_list;
6639 filedata->symtab_shndx_list = entry;
6640 }
6641 break;
6642
6643 case SHT_SYMTAB:
6644 CHECK_ENTSIZE (section, i, Sym);
6645 break;
6646
6647 case SHT_GROUP:
6648 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6649 break;
252b5132 6650
1b513401
NC
6651 case SHT_REL:
6652 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 6653 if (do_checks && section->sh_size == 0)
1b513401
NC
6654 warn (_("Section '%s': zero-sized relocation section\n"), name);
6655 break;
6656
6657 case SHT_RELA:
6658 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 6659 if (do_checks && section->sh_size == 0)
1b513401
NC
6660 warn (_("Section '%s': zero-sized relocation section\n"), name);
6661 break;
6662
6663 case SHT_NOTE:
6664 case SHT_PROGBITS:
546cb2d8
NC
6665 /* Having a zero sized section is not illegal according to the
6666 ELF standard, but it might be an indication that something
6667 is wrong. So issue a warning if we are running in lint mode. */
6668 if (do_checks && section->sh_size == 0)
1b513401
NC
6669 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
6670 break;
6671
6672 default:
6673 break;
6674 }
6675
6676 if ((do_debugging || do_debug_info || do_debug_abbrevs
6677 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
6678 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
6679 || do_debug_str || do_debug_str_offsets || do_debug_loc
6680 || do_debug_ranges
1b513401 6681 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
6682 && (startswith (name, ".debug_")
6683 || startswith (name, ".zdebug_")))
252b5132 6684 {
1b315056
CS
6685 if (name[1] == 'z')
6686 name += sizeof (".zdebug_") - 1;
6687 else
6688 name += sizeof (".debug_") - 1;
252b5132
RH
6689
6690 if (do_debugging
24d127aa
ML
6691 || (do_debug_info && startswith (name, "info"))
6692 || (do_debug_info && startswith (name, "types"))
6693 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 6694 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
6695 || (do_debug_lines && startswith (name, "line."))
6696 || (do_debug_pubnames && startswith (name, "pubnames"))
6697 || (do_debug_pubtypes && startswith (name, "pubtypes"))
6698 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
6699 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
6700 || (do_debug_aranges && startswith (name, "aranges"))
6701 || (do_debug_ranges && startswith (name, "ranges"))
6702 || (do_debug_ranges && startswith (name, "rnglists"))
6703 || (do_debug_frames && startswith (name, "frame"))
6704 || (do_debug_macinfo && startswith (name, "macinfo"))
6705 || (do_debug_macinfo && startswith (name, "macro"))
6706 || (do_debug_str && startswith (name, "str"))
6707 || (do_debug_links && startswith (name, "sup"))
6708 || (do_debug_str_offsets && startswith (name, "str_offsets"))
6709 || (do_debug_loc && startswith (name, "loc"))
6710 || (do_debug_loc && startswith (name, "loclists"))
6711 || (do_debug_addr && startswith (name, "addr"))
6712 || (do_debug_cu_index && startswith (name, "cu_index"))
6713 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 6714 )
6431e409 6715 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6716 }
a262ae96 6717 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6718 else if ((do_debugging || do_debug_info)
24d127aa 6719 && startswith (name, ".gnu.linkonce.wi."))
6431e409 6720 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6721 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6722 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6723 else if (do_gdb_index && (streq (name, ".gdb_index")
6724 || streq (name, ".debug_names")))
6431e409 6725 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6726 /* Trace sections for Itanium VMS. */
6727 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6728 || do_trace_aranges)
24d127aa 6729 && startswith (name, ".trace_"))
6f875884
TG
6730 {
6731 name += sizeof (".trace_") - 1;
6732
6733 if (do_debugging
6734 || (do_trace_info && streq (name, "info"))
6735 || (do_trace_abbrevs && streq (name, "abbrev"))
6736 || (do_trace_aranges && streq (name, "aranges"))
6737 )
6431e409 6738 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6739 }
dda8d76d 6740 else if ((do_debugging || do_debug_links)
24d127aa
ML
6741 && (startswith (name, ".gnu_debuglink")
6742 || startswith (name, ".gnu_debugaltlink")))
6431e409 6743 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6744 }
6745
6746 if (! do_sections)
015dc7e1 6747 return true;
252b5132 6748
ca0e11aa 6749 if (filedata->is_separate && ! process_links)
015dc7e1 6750 return true;
ca0e11aa
NC
6751
6752 if (filedata->is_separate)
6753 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
6754 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6755 printf (_("\nSection Headers:\n"));
6756 else
6757 printf (_("\nSection Header:\n"));
76da6bbe 6758
f7a99963 6759 if (is_32bit_elf)
595cf52e 6760 {
5477e8a0 6761 if (do_section_details)
595cf52e
L
6762 {
6763 printf (_(" [Nr] Name\n"));
5477e8a0 6764 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6765 }
6766 else
6767 printf
6768 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6769 }
d974e256 6770 else if (do_wide)
595cf52e 6771 {
5477e8a0 6772 if (do_section_details)
595cf52e
L
6773 {
6774 printf (_(" [Nr] Name\n"));
5477e8a0 6775 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6776 }
6777 else
6778 printf
6779 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6780 }
f7a99963
NC
6781 else
6782 {
5477e8a0 6783 if (do_section_details)
595cf52e
L
6784 {
6785 printf (_(" [Nr] Name\n"));
5477e8a0
L
6786 printf (_(" Type Address Offset Link\n"));
6787 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6788 }
6789 else
6790 {
6791 printf (_(" [Nr] Name Type Address Offset\n"));
6792 printf (_(" Size EntSize Flags Link Info Align\n"));
6793 }
f7a99963 6794 }
252b5132 6795
5477e8a0
L
6796 if (do_section_details)
6797 printf (_(" Flags\n"));
6798
dda8d76d
NC
6799 for (i = 0, section = filedata->section_headers;
6800 i < filedata->file_header.e_shnum;
b34976b6 6801 i++, section++)
252b5132 6802 {
dd905818
NC
6803 /* Run some sanity checks on the section header. */
6804
6805 /* Check the sh_link field. */
6806 switch (section->sh_type)
6807 {
285e3f99
AM
6808 case SHT_REL:
6809 case SHT_RELA:
6810 if (section->sh_link == 0
6811 && (filedata->file_header.e_type == ET_EXEC
6812 || filedata->file_header.e_type == ET_DYN))
6813 /* A dynamic relocation section where all entries use a
6814 zero symbol index need not specify a symtab section. */
6815 break;
6816 /* Fall through. */
dd905818
NC
6817 case SHT_SYMTAB_SHNDX:
6818 case SHT_GROUP:
6819 case SHT_HASH:
6820 case SHT_GNU_HASH:
6821 case SHT_GNU_versym:
285e3f99 6822 if (section->sh_link == 0
dda8d76d
NC
6823 || section->sh_link >= filedata->file_header.e_shnum
6824 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6825 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6826 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6827 i, section->sh_link);
6828 break;
6829
6830 case SHT_DYNAMIC:
6831 case SHT_SYMTAB:
6832 case SHT_DYNSYM:
6833 case SHT_GNU_verneed:
6834 case SHT_GNU_verdef:
6835 case SHT_GNU_LIBLIST:
285e3f99 6836 if (section->sh_link == 0
dda8d76d
NC
6837 || section->sh_link >= filedata->file_header.e_shnum
6838 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6839 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6840 i, section->sh_link);
6841 break;
6842
6843 case SHT_INIT_ARRAY:
6844 case SHT_FINI_ARRAY:
6845 case SHT_PREINIT_ARRAY:
6846 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6847 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6848 i, section->sh_link);
6849 break;
6850
6851 default:
6852 /* FIXME: Add support for target specific section types. */
6853#if 0 /* Currently we do not check other section types as there are too
6854 many special cases. Stab sections for example have a type
6855 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6856 section. */
6857 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6858 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6859 i, section->sh_link);
6860#endif
6861 break;
6862 }
6863
6864 /* Check the sh_info field. */
6865 switch (section->sh_type)
6866 {
6867 case SHT_REL:
6868 case SHT_RELA:
285e3f99
AM
6869 if (section->sh_info == 0
6870 && (filedata->file_header.e_type == ET_EXEC
6871 || filedata->file_header.e_type == ET_DYN))
6872 /* Dynamic relocations apply to segments, so they do not
6873 need to specify the section they relocate. */
6874 break;
6875 if (section->sh_info == 0
dda8d76d
NC
6876 || section->sh_info >= filedata->file_header.e_shnum
6877 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6878 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6879 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6880 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6881 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6882 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6883 /* FIXME: Are other section types valid ? */
dda8d76d 6884 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6885 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6886 i, section->sh_info);
dd905818
NC
6887 break;
6888
6889 case SHT_DYNAMIC:
6890 case SHT_HASH:
6891 case SHT_SYMTAB_SHNDX:
6892 case SHT_INIT_ARRAY:
6893 case SHT_FINI_ARRAY:
6894 case SHT_PREINIT_ARRAY:
6895 if (section->sh_info != 0)
6896 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6897 i, section->sh_info);
6898 break;
6899
6900 case SHT_GROUP:
6901 case SHT_SYMTAB:
6902 case SHT_DYNSYM:
6903 /* A symbol index - we assume that it is valid. */
6904 break;
6905
6906 default:
6907 /* FIXME: Add support for target specific section types. */
6908 if (section->sh_type == SHT_NOBITS)
6909 /* NOBITS section headers with non-zero sh_info fields can be
6910 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6911 information. The stripped sections have their headers
6912 preserved but their types set to SHT_NOBITS. So do not check
6913 this type of section. */
dd905818
NC
6914 ;
6915 else if (section->sh_flags & SHF_INFO_LINK)
6916 {
dda8d76d 6917 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6918 warn (_("[%2u]: Expected link to another section in info field"), i);
6919 }
a91e1603
L
6920 else if (section->sh_type < SHT_LOOS
6921 && (section->sh_flags & SHF_GNU_MBIND) == 0
6922 && section->sh_info != 0)
dd905818
NC
6923 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6924 i, section->sh_info);
6925 break;
6926 }
6927
3e6b6445 6928 /* Check the sh_size field. */
dda8d76d 6929 if (section->sh_size > filedata->file_size
3e6b6445
NC
6930 && section->sh_type != SHT_NOBITS
6931 && section->sh_type != SHT_NULL
6932 && section->sh_type < SHT_LOOS)
6933 warn (_("Size of section %u is larger than the entire file!\n"), i);
6934
7bfd842d 6935 printf (" [%2u] ", i);
5477e8a0 6936 if (do_section_details)
dda8d76d 6937 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6938 else
b9e920ec 6939 print_symbol (-17, SECTION_NAME_PRINT (section));
0b4362b0 6940
ea52a088 6941 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6942 get_section_type_name (filedata, section->sh_type));
0b4362b0 6943
f7a99963
NC
6944 if (is_32bit_elf)
6945 {
cfcac11d
NC
6946 const char * link_too_big = NULL;
6947
f7a99963 6948 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6949
f7a99963
NC
6950 printf ( " %6.6lx %6.6lx %2.2lx",
6951 (unsigned long) section->sh_offset,
6952 (unsigned long) section->sh_size,
6953 (unsigned long) section->sh_entsize);
d1133906 6954
5477e8a0
L
6955 if (do_section_details)
6956 fputs (" ", stdout);
6957 else
dda8d76d 6958 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6959
dda8d76d 6960 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6961 {
6962 link_too_big = "";
6963 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6964 an error but it can have special values in Solaris binaries. */
dda8d76d 6965 switch (filedata->file_header.e_machine)
cfcac11d 6966 {
caa83f8b 6967 case EM_386:
22abe556 6968 case EM_IAMCU:
caa83f8b 6969 case EM_X86_64:
7f502d6c 6970 case EM_L1OM:
7a9068fe 6971 case EM_K1OM:
cfcac11d
NC
6972 case EM_OLD_SPARCV9:
6973 case EM_SPARC32PLUS:
6974 case EM_SPARCV9:
6975 case EM_SPARC:
6976 if (section->sh_link == (SHN_BEFORE & 0xffff))
6977 link_too_big = "BEFORE";
6978 else if (section->sh_link == (SHN_AFTER & 0xffff))
6979 link_too_big = "AFTER";
6980 break;
6981 default:
6982 break;
6983 }
6984 }
6985
6986 if (do_section_details)
6987 {
6988 if (link_too_big != NULL && * link_too_big)
6989 printf ("<%s> ", link_too_big);
6990 else
6991 printf ("%2u ", section->sh_link);
6992 printf ("%3u %2lu\n", section->sh_info,
6993 (unsigned long) section->sh_addralign);
6994 }
6995 else
6996 printf ("%2u %3u %2lu\n",
6997 section->sh_link,
6998 section->sh_info,
6999 (unsigned long) section->sh_addralign);
7000
7001 if (link_too_big && ! * link_too_big)
7002 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7003 i, section->sh_link);
f7a99963 7004 }
d974e256
JJ
7005 else if (do_wide)
7006 {
7007 print_vma (section->sh_addr, LONG_HEX);
7008
7009 if ((long) section->sh_offset == section->sh_offset)
7010 printf (" %6.6lx", (unsigned long) section->sh_offset);
7011 else
7012 {
7013 putchar (' ');
7014 print_vma (section->sh_offset, LONG_HEX);
7015 }
7016
7017 if ((unsigned long) section->sh_size == section->sh_size)
7018 printf (" %6.6lx", (unsigned long) section->sh_size);
7019 else
7020 {
7021 putchar (' ');
7022 print_vma (section->sh_size, LONG_HEX);
7023 }
7024
7025 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7026 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7027 else
7028 {
7029 putchar (' ');
7030 print_vma (section->sh_entsize, LONG_HEX);
7031 }
7032
5477e8a0
L
7033 if (do_section_details)
7034 fputs (" ", stdout);
7035 else
dda8d76d 7036 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7037
72de5009 7038 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7039
7040 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7041 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7042 else
7043 {
7044 print_vma (section->sh_addralign, DEC);
7045 putchar ('\n');
7046 }
7047 }
5477e8a0 7048 else if (do_section_details)
595cf52e 7049 {
55cc53e9 7050 putchar (' ');
595cf52e
L
7051 print_vma (section->sh_addr, LONG_HEX);
7052 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7053 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7054 else
7055 {
7056 printf (" ");
7057 print_vma (section->sh_offset, LONG_HEX);
7058 }
72de5009 7059 printf (" %u\n ", section->sh_link);
595cf52e 7060 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7061 putchar (' ');
595cf52e
L
7062 print_vma (section->sh_entsize, LONG_HEX);
7063
72de5009
AM
7064 printf (" %-16u %lu\n",
7065 section->sh_info,
595cf52e
L
7066 (unsigned long) section->sh_addralign);
7067 }
f7a99963
NC
7068 else
7069 {
7070 putchar (' ');
7071 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7072 if ((long) section->sh_offset == section->sh_offset)
7073 printf (" %8.8lx", (unsigned long) section->sh_offset);
7074 else
7075 {
7076 printf (" ");
7077 print_vma (section->sh_offset, LONG_HEX);
7078 }
f7a99963
NC
7079 printf ("\n ");
7080 print_vma (section->sh_size, LONG_HEX);
7081 printf (" ");
7082 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7083
dda8d76d 7084 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7085
72de5009
AM
7086 printf (" %2u %3u %lu\n",
7087 section->sh_link,
7088 section->sh_info,
f7a99963
NC
7089 (unsigned long) section->sh_addralign);
7090 }
5477e8a0
L
7091
7092 if (do_section_details)
77115a4a 7093 {
dda8d76d 7094 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7095 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7096 {
7097 /* Minimum section size is 12 bytes for 32-bit compression
7098 header + 12 bytes for compressed data header. */
7099 unsigned char buf[24];
d8024a91 7100
77115a4a 7101 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7102 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7103 sizeof (buf), _("compression header")))
7104 {
7105 Elf_Internal_Chdr chdr;
d8024a91 7106
5844b465
NC
7107 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7108 printf (_(" [<corrupt>]\n"));
77115a4a 7109 else
5844b465
NC
7110 {
7111 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7112 printf (" ZLIB, ");
7113 else
7114 printf (_(" [<unknown>: 0x%x], "),
7115 chdr.ch_type);
7116 print_vma (chdr.ch_size, LONG_HEX);
7117 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7118 }
77115a4a
L
7119 }
7120 }
7121 }
252b5132
RH
7122 }
7123
5477e8a0 7124 if (!do_section_details)
3dbcc61d 7125 {
9fb71ee4
NC
7126 /* The ordering of the letters shown here matches the ordering of the
7127 corresponding SHF_xxx values, and hence the order in which these
7128 letters will be displayed to the user. */
7129 printf (_("Key to Flags:\n\
7130 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7131 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7132 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7133 switch (filedata->file_header.e_ident[EI_OSABI])
7134 {
7135 case ELFOSABI_GNU:
7136 case ELFOSABI_FREEBSD:
7137 printf (_("R (retain), "));
7138 /* Fall through */
7139 case ELFOSABI_NONE:
7140 printf (_("D (mbind), "));
7141 break;
7142 default:
7143 break;
7144 }
dda8d76d
NC
7145 if (filedata->file_header.e_machine == EM_X86_64
7146 || filedata->file_header.e_machine == EM_L1OM
7147 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7148 printf (_("l (large), "));
dda8d76d 7149 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7150 printf (_("y (purecode), "));
dda8d76d 7151 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7152 printf (_("v (VLE), "));
9fb71ee4 7153 printf ("p (processor specific)\n");
0b4362b0 7154 }
d1133906 7155
015dc7e1 7156 return true;
252b5132
RH
7157}
7158
015dc7e1 7159static bool
28d13567
AM
7160get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7161 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7162 char **strtab, unsigned long *strtablen)
7163{
7164 *strtab = NULL;
7165 *strtablen = 0;
4de91c10 7166 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7167
7168 if (*symtab == NULL)
015dc7e1 7169 return false;
28d13567
AM
7170
7171 if (symsec->sh_link != 0)
7172 {
7173 Elf_Internal_Shdr *strsec;
7174
7175 if (symsec->sh_link >= filedata->file_header.e_shnum)
7176 {
7177 error (_("Bad sh_link in symbol table section\n"));
7178 free (*symtab);
7179 *symtab = NULL;
7180 *nsyms = 0;
015dc7e1 7181 return false;
28d13567
AM
7182 }
7183
7184 strsec = filedata->section_headers + symsec->sh_link;
7185
7186 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7187 1, strsec->sh_size, _("string table"));
7188 if (*strtab == NULL)
7189 {
7190 free (*symtab);
7191 *symtab = NULL;
7192 *nsyms = 0;
015dc7e1 7193 return false;
28d13567
AM
7194 }
7195 *strtablen = strsec->sh_size;
7196 }
015dc7e1 7197 return true;
28d13567
AM
7198}
7199
f5842774
L
7200static const char *
7201get_group_flags (unsigned int flags)
7202{
1449284b 7203 static char buff[128];
220453ec 7204
6d913794
NC
7205 if (flags == 0)
7206 return "";
7207 else if (flags == GRP_COMDAT)
7208 return "COMDAT ";
f5842774 7209
89246a0e
AM
7210 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7211 flags,
7212 flags & GRP_MASKOS ? _("<OS specific>") : "",
7213 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7214 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7215 ? _("<unknown>") : ""));
6d913794 7216
f5842774
L
7217 return buff;
7218}
7219
015dc7e1 7220static bool
dda8d76d 7221process_section_groups (Filedata * filedata)
f5842774 7222{
2cf0635d 7223 Elf_Internal_Shdr * section;
f5842774 7224 unsigned int i;
2cf0635d
NC
7225 struct group * group;
7226 Elf_Internal_Shdr * symtab_sec;
7227 Elf_Internal_Shdr * strtab_sec;
7228 Elf_Internal_Sym * symtab;
ba5cdace 7229 unsigned long num_syms;
2cf0635d 7230 char * strtab;
c256ffe7 7231 size_t strtab_size;
d1f5c6e3
L
7232
7233 /* Don't process section groups unless needed. */
7234 if (!do_unwind && !do_section_groups)
015dc7e1 7235 return true;
f5842774 7236
dda8d76d 7237 if (filedata->file_header.e_shnum == 0)
f5842774
L
7238 {
7239 if (do_section_groups)
ca0e11aa
NC
7240 {
7241 if (filedata->is_separate)
7242 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7243 filedata->file_name);
7244 else
7245 printf (_("\nThere are no section groups in this file.\n"));
7246 }
015dc7e1 7247 return true;
f5842774
L
7248 }
7249
dda8d76d 7250 if (filedata->section_headers == NULL)
f5842774
L
7251 {
7252 error (_("Section headers are not available!\n"));
fa1908fd 7253 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7254 return false;
f5842774
L
7255 }
7256
978c4450
AM
7257 filedata->section_headers_groups
7258 = (struct group **) calloc (filedata->file_header.e_shnum,
7259 sizeof (struct group *));
e4b17d5c 7260
978c4450 7261 if (filedata->section_headers_groups == NULL)
e4b17d5c 7262 {
8b73c356 7263 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7264 filedata->file_header.e_shnum);
015dc7e1 7265 return false;
e4b17d5c
L
7266 }
7267
f5842774 7268 /* Scan the sections for the group section. */
978c4450 7269 filedata->group_count = 0;
dda8d76d
NC
7270 for (i = 0, section = filedata->section_headers;
7271 i < filedata->file_header.e_shnum;
f5842774 7272 i++, section++)
e4b17d5c 7273 if (section->sh_type == SHT_GROUP)
978c4450 7274 filedata->group_count++;
e4b17d5c 7275
978c4450 7276 if (filedata->group_count == 0)
d1f5c6e3
L
7277 {
7278 if (do_section_groups)
ca0e11aa
NC
7279 {
7280 if (filedata->is_separate)
7281 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7282 filedata->file_name);
7283 else
7284 printf (_("\nThere are no section groups in this file.\n"));
7285 }
d1f5c6e3 7286
015dc7e1 7287 return true;
d1f5c6e3
L
7288 }
7289
978c4450
AM
7290 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7291 sizeof (struct group));
e4b17d5c 7292
978c4450 7293 if (filedata->section_groups == NULL)
e4b17d5c 7294 {
8b73c356 7295 error (_("Out of memory reading %lu groups\n"),
978c4450 7296 (unsigned long) filedata->group_count);
015dc7e1 7297 return false;
e4b17d5c
L
7298 }
7299
d1f5c6e3
L
7300 symtab_sec = NULL;
7301 strtab_sec = NULL;
7302 symtab = NULL;
ba5cdace 7303 num_syms = 0;
d1f5c6e3 7304 strtab = NULL;
c256ffe7 7305 strtab_size = 0;
ca0e11aa
NC
7306
7307 if (filedata->is_separate)
7308 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7309
978c4450 7310 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7311 i < filedata->file_header.e_shnum;
e4b17d5c 7312 i++, section++)
f5842774
L
7313 {
7314 if (section->sh_type == SHT_GROUP)
7315 {
dda8d76d 7316 const char * name = printable_section_name (filedata, section);
74e1a04b 7317 const char * group_name;
2cf0635d
NC
7318 unsigned char * start;
7319 unsigned char * indices;
f5842774 7320 unsigned int entry, j, size;
2cf0635d
NC
7321 Elf_Internal_Shdr * sec;
7322 Elf_Internal_Sym * sym;
f5842774
L
7323
7324 /* Get the symbol table. */
dda8d76d
NC
7325 if (section->sh_link >= filedata->file_header.e_shnum
7326 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7327 != SHT_SYMTAB))
f5842774
L
7328 {
7329 error (_("Bad sh_link in group section `%s'\n"), name);
7330 continue;
7331 }
d1f5c6e3
L
7332
7333 if (symtab_sec != sec)
7334 {
7335 symtab_sec = sec;
9db70fc3 7336 free (symtab);
4de91c10 7337 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 7338 }
f5842774 7339
dd24e3da
NC
7340 if (symtab == NULL)
7341 {
7342 error (_("Corrupt header in group section `%s'\n"), name);
7343 continue;
7344 }
7345
ba5cdace
NC
7346 if (section->sh_info >= num_syms)
7347 {
7348 error (_("Bad sh_info in group section `%s'\n"), name);
7349 continue;
7350 }
7351
f5842774
L
7352 sym = symtab + section->sh_info;
7353
7354 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7355 {
4fbb74a6 7356 if (sym->st_shndx == 0
dda8d76d 7357 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7358 {
7359 error (_("Bad sh_info in group section `%s'\n"), name);
7360 continue;
7361 }
ba2685cc 7362
b9e920ec
AM
7363 group_name = SECTION_NAME_PRINT (filedata->section_headers
7364 + sym->st_shndx);
c256ffe7 7365 strtab_sec = NULL;
9db70fc3 7366 free (strtab);
f5842774 7367 strtab = NULL;
c256ffe7 7368 strtab_size = 0;
f5842774
L
7369 }
7370 else
7371 {
7372 /* Get the string table. */
dda8d76d 7373 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7374 {
7375 strtab_sec = NULL;
9db70fc3 7376 free (strtab);
c256ffe7
JJ
7377 strtab = NULL;
7378 strtab_size = 0;
7379 }
7380 else if (strtab_sec
dda8d76d 7381 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7382 {
7383 strtab_sec = sec;
9db70fc3 7384 free (strtab);
071436c6 7385
dda8d76d 7386 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7387 1, strtab_sec->sh_size,
7388 _("string table"));
c256ffe7 7389 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7390 }
c256ffe7 7391 group_name = sym->st_name < strtab_size
2b692964 7392 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7393 }
7394
c9c1d674
EG
7395 /* PR 17531: file: loop. */
7396 if (section->sh_entsize > section->sh_size)
7397 {
7398 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7399 printable_section_name (filedata, section),
8066deb1
AM
7400 (unsigned long) section->sh_entsize,
7401 (unsigned long) section->sh_size);
61dd8e19 7402 continue;
c9c1d674
EG
7403 }
7404
dda8d76d 7405 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7406 1, section->sh_size,
7407 _("section data"));
59245841
NC
7408 if (start == NULL)
7409 continue;
f5842774
L
7410
7411 indices = start;
7412 size = (section->sh_size / section->sh_entsize) - 1;
7413 entry = byte_get (indices, 4);
7414 indices += 4;
e4b17d5c
L
7415
7416 if (do_section_groups)
7417 {
2b692964 7418 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7419 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7420
e4b17d5c
L
7421 printf (_(" [Index] Name\n"));
7422 }
7423
7424 group->group_index = i;
7425
f5842774
L
7426 for (j = 0; j < size; j++)
7427 {
2cf0635d 7428 struct group_list * g;
e4b17d5c 7429
f5842774
L
7430 entry = byte_get (indices, 4);
7431 indices += 4;
7432
dda8d76d 7433 if (entry >= filedata->file_header.e_shnum)
391cb864 7434 {
57028622
NC
7435 static unsigned num_group_errors = 0;
7436
7437 if (num_group_errors ++ < 10)
7438 {
7439 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7440 entry, i, filedata->file_header.e_shnum - 1);
57028622 7441 if (num_group_errors == 10)
67ce483b 7442 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7443 }
391cb864
L
7444 continue;
7445 }
391cb864 7446
978c4450 7447 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7448 {
d1f5c6e3
L
7449 if (entry)
7450 {
57028622
NC
7451 static unsigned num_errs = 0;
7452
7453 if (num_errs ++ < 10)
7454 {
7455 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7456 entry, i,
978c4450 7457 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7458 if (num_errs == 10)
7459 warn (_("Further error messages about already contained group sections suppressed\n"));
7460 }
d1f5c6e3
L
7461 continue;
7462 }
7463 else
7464 {
7465 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7466 section group. We just warn it the first time
d1f5c6e3 7467 and ignore it afterwards. */
015dc7e1 7468 static bool warned = false;
d1f5c6e3
L
7469 if (!warned)
7470 {
7471 error (_("section 0 in group section [%5u]\n"),
978c4450 7472 filedata->section_headers_groups [entry]->group_index);
015dc7e1 7473 warned = true;
d1f5c6e3
L
7474 }
7475 }
e4b17d5c
L
7476 }
7477
978c4450 7478 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7479
7480 if (do_section_groups)
7481 {
dda8d76d
NC
7482 sec = filedata->section_headers + entry;
7483 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7484 }
7485
3f5e193b 7486 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7487 g->section_index = entry;
7488 g->next = group->root;
7489 group->root = g;
f5842774
L
7490 }
7491
9db70fc3 7492 free (start);
e4b17d5c
L
7493
7494 group++;
f5842774
L
7495 }
7496 }
7497
9db70fc3
AM
7498 free (symtab);
7499 free (strtab);
015dc7e1 7500 return true;
f5842774
L
7501}
7502
28f997cf
TG
7503/* Data used to display dynamic fixups. */
7504
7505struct ia64_vms_dynfixup
7506{
7507 bfd_vma needed_ident; /* Library ident number. */
7508 bfd_vma needed; /* Index in the dstrtab of the library name. */
7509 bfd_vma fixup_needed; /* Index of the library. */
7510 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7511 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7512};
7513
7514/* Data used to display dynamic relocations. */
7515
7516struct ia64_vms_dynimgrela
7517{
7518 bfd_vma img_rela_cnt; /* Number of relocations. */
7519 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7520};
7521
7522/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7523 library). */
7524
015dc7e1 7525static bool
dda8d76d
NC
7526dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7527 struct ia64_vms_dynfixup * fixup,
7528 const char * strtab,
7529 unsigned int strtab_sz)
28f997cf 7530{
32ec8896 7531 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7532 long i;
32ec8896 7533 const char * lib_name;
28f997cf 7534
978c4450
AM
7535 imfs = get_data (NULL, filedata,
7536 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7537 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7538 _("dynamic section image fixups"));
7539 if (!imfs)
015dc7e1 7540 return false;
28f997cf
TG
7541
7542 if (fixup->needed < strtab_sz)
7543 lib_name = strtab + fixup->needed;
7544 else
7545 {
32ec8896 7546 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7547 (unsigned long) fixup->needed);
28f997cf
TG
7548 lib_name = "???";
7549 }
736990c4 7550
28f997cf
TG
7551 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7552 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7553 printf
7554 (_("Seg Offset Type SymVec DataType\n"));
7555
7556 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7557 {
7558 unsigned int type;
7559 const char *rtype;
7560
7561 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7562 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7563 type = BYTE_GET (imfs [i].type);
7564 rtype = elf_ia64_reloc_type (type);
7565 if (rtype == NULL)
7566 printf (" 0x%08x ", type);
7567 else
7568 printf (" %-32s ", rtype);
7569 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7570 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7571 }
7572
7573 free (imfs);
015dc7e1 7574 return true;
28f997cf
TG
7575}
7576
7577/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7578
015dc7e1 7579static bool
dda8d76d 7580dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7581{
7582 Elf64_External_VMS_IMAGE_RELA *imrs;
7583 long i;
7584
978c4450
AM
7585 imrs = get_data (NULL, filedata,
7586 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 7587 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7588 _("dynamic section image relocations"));
28f997cf 7589 if (!imrs)
015dc7e1 7590 return false;
28f997cf
TG
7591
7592 printf (_("\nImage relocs\n"));
7593 printf
7594 (_("Seg Offset Type Addend Seg Sym Off\n"));
7595
7596 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7597 {
7598 unsigned int type;
7599 const char *rtype;
7600
7601 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7602 printf ("%08" BFD_VMA_FMT "x ",
7603 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7604 type = BYTE_GET (imrs [i].type);
7605 rtype = elf_ia64_reloc_type (type);
7606 if (rtype == NULL)
7607 printf ("0x%08x ", type);
7608 else
7609 printf ("%-31s ", rtype);
7610 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7611 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7612 printf ("%08" BFD_VMA_FMT "x\n",
7613 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7614 }
7615
7616 free (imrs);
015dc7e1 7617 return true;
28f997cf
TG
7618}
7619
7620/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7621
015dc7e1 7622static bool
dda8d76d 7623process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7624{
7625 struct ia64_vms_dynfixup fixup;
7626 struct ia64_vms_dynimgrela imgrela;
7627 Elf_Internal_Dyn *entry;
28f997cf
TG
7628 bfd_vma strtab_off = 0;
7629 bfd_vma strtab_sz = 0;
7630 char *strtab = NULL;
015dc7e1 7631 bool res = true;
28f997cf
TG
7632
7633 memset (&fixup, 0, sizeof (fixup));
7634 memset (&imgrela, 0, sizeof (imgrela));
7635
7636 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
7637 for (entry = filedata->dynamic_section;
7638 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
7639 entry++)
7640 {
7641 switch (entry->d_tag)
7642 {
7643 case DT_IA_64_VMS_STRTAB_OFFSET:
7644 strtab_off = entry->d_un.d_val;
7645 break;
7646 case DT_STRSZ:
7647 strtab_sz = entry->d_un.d_val;
7648 if (strtab == NULL)
978c4450
AM
7649 strtab = get_data (NULL, filedata,
7650 filedata->dynamic_addr + strtab_off,
28f997cf 7651 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7652 if (strtab == NULL)
7653 strtab_sz = 0;
28f997cf
TG
7654 break;
7655
7656 case DT_IA_64_VMS_NEEDED_IDENT:
7657 fixup.needed_ident = entry->d_un.d_val;
7658 break;
7659 case DT_NEEDED:
7660 fixup.needed = entry->d_un.d_val;
7661 break;
7662 case DT_IA_64_VMS_FIXUP_NEEDED:
7663 fixup.fixup_needed = entry->d_un.d_val;
7664 break;
7665 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7666 fixup.fixup_rela_cnt = entry->d_un.d_val;
7667 break;
7668 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7669 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7670 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 7671 res = false;
28f997cf 7672 break;
28f997cf
TG
7673 case DT_IA_64_VMS_IMG_RELA_CNT:
7674 imgrela.img_rela_cnt = entry->d_un.d_val;
7675 break;
7676 case DT_IA_64_VMS_IMG_RELA_OFF:
7677 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7678 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 7679 res = false;
28f997cf
TG
7680 break;
7681
7682 default:
7683 break;
7684 }
7685 }
7686
9db70fc3 7687 free (strtab);
28f997cf
TG
7688
7689 return res;
7690}
7691
85b1c36d 7692static struct
566b0d53 7693{
2cf0635d 7694 const char * name;
566b0d53
L
7695 int reloc;
7696 int size;
7697 int rela;
32ec8896
NC
7698}
7699 dynamic_relocations [] =
566b0d53 7700{
015dc7e1
AM
7701 { "REL", DT_REL, DT_RELSZ, false },
7702 { "RELA", DT_RELA, DT_RELASZ, true },
32ec8896 7703 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7704};
7705
252b5132 7706/* Process the reloc section. */
18bd398b 7707
015dc7e1 7708static bool
dda8d76d 7709process_relocs (Filedata * filedata)
252b5132 7710{
b34976b6
AM
7711 unsigned long rel_size;
7712 unsigned long rel_offset;
252b5132 7713
252b5132 7714 if (!do_reloc)
015dc7e1 7715 return true;
252b5132
RH
7716
7717 if (do_using_dynamic)
7718 {
32ec8896 7719 int is_rela;
2cf0635d 7720 const char * name;
015dc7e1 7721 bool has_dynamic_reloc;
566b0d53 7722 unsigned int i;
0de14b54 7723
015dc7e1 7724 has_dynamic_reloc = false;
252b5132 7725
566b0d53 7726 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7727 {
566b0d53
L
7728 is_rela = dynamic_relocations [i].rela;
7729 name = dynamic_relocations [i].name;
978c4450
AM
7730 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
7731 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 7732
32ec8896 7733 if (rel_size)
015dc7e1 7734 has_dynamic_reloc = true;
566b0d53
L
7735
7736 if (is_rela == UNKNOWN)
aa903cfb 7737 {
566b0d53 7738 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 7739 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
7740 {
7741 case DT_REL:
015dc7e1 7742 is_rela = false;
566b0d53
L
7743 break;
7744 case DT_RELA:
015dc7e1 7745 is_rela = true;
566b0d53
L
7746 break;
7747 }
aa903cfb 7748 }
252b5132 7749
566b0d53
L
7750 if (rel_size)
7751 {
ca0e11aa
NC
7752 if (filedata->is_separate)
7753 printf
7754 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
7755 filedata->file_name, name, rel_offset, rel_size);
7756 else
7757 printf
7758 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7759 name, rel_offset, rel_size);
252b5132 7760
dda8d76d
NC
7761 dump_relocations (filedata,
7762 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7763 rel_size,
978c4450
AM
7764 filedata->dynamic_symbols,
7765 filedata->num_dynamic_syms,
7766 filedata->dynamic_strings,
7767 filedata->dynamic_strings_length,
015dc7e1 7768 is_rela, true /* is_dynamic */);
566b0d53 7769 }
252b5132 7770 }
566b0d53 7771
dda8d76d
NC
7772 if (is_ia64_vms (filedata))
7773 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 7774 has_dynamic_reloc = true;
28f997cf 7775
566b0d53 7776 if (! has_dynamic_reloc)
ca0e11aa
NC
7777 {
7778 if (filedata->is_separate)
7779 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
7780 filedata->file_name);
7781 else
7782 printf (_("\nThere are no dynamic relocations in this file.\n"));
7783 }
252b5132
RH
7784 }
7785 else
7786 {
2cf0635d 7787 Elf_Internal_Shdr * section;
b34976b6 7788 unsigned long i;
015dc7e1 7789 bool found = false;
252b5132 7790
dda8d76d
NC
7791 for (i = 0, section = filedata->section_headers;
7792 i < filedata->file_header.e_shnum;
b34976b6 7793 i++, section++)
252b5132
RH
7794 {
7795 if ( section->sh_type != SHT_RELA
7796 && section->sh_type != SHT_REL)
7797 continue;
7798
7799 rel_offset = section->sh_offset;
7800 rel_size = section->sh_size;
7801
7802 if (rel_size)
7803 {
b34976b6 7804 int is_rela;
d3a49aa8 7805 unsigned long num_rela;
103f02d3 7806
ca0e11aa
NC
7807 if (filedata->is_separate)
7808 printf (_("\nIn linked file '%s' relocation section "),
7809 filedata->file_name);
7810 else
7811 printf (_("\nRelocation section "));
252b5132 7812
dda8d76d 7813 if (filedata->string_table == NULL)
19936277 7814 printf ("%d", section->sh_name);
252b5132 7815 else
dda8d76d 7816 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7817
d3a49aa8
AM
7818 num_rela = rel_size / section->sh_entsize;
7819 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7820 " at offset 0x%lx contains %lu entries:\n",
7821 num_rela),
7822 rel_offset, num_rela);
252b5132 7823
d79b3d50
NC
7824 is_rela = section->sh_type == SHT_RELA;
7825
4fbb74a6 7826 if (section->sh_link != 0
dda8d76d 7827 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7828 {
2cf0635d
NC
7829 Elf_Internal_Shdr * symsec;
7830 Elf_Internal_Sym * symtab;
d79b3d50 7831 unsigned long nsyms;
c256ffe7 7832 unsigned long strtablen = 0;
2cf0635d 7833 char * strtab = NULL;
57346661 7834
dda8d76d 7835 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7836 if (symsec->sh_type != SHT_SYMTAB
7837 && symsec->sh_type != SHT_DYNSYM)
7838 continue;
7839
28d13567
AM
7840 if (!get_symtab (filedata, symsec,
7841 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7842 continue;
252b5132 7843
dda8d76d 7844 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7845 symtab, nsyms, strtab, strtablen,
7846 is_rela,
7847 symsec->sh_type == SHT_DYNSYM);
9db70fc3 7848 free (strtab);
d79b3d50
NC
7849 free (symtab);
7850 }
7851 else
dda8d76d 7852 dump_relocations (filedata, rel_offset, rel_size,
32ec8896 7853 NULL, 0, NULL, 0, is_rela,
015dc7e1 7854 false /* is_dynamic */);
252b5132 7855
015dc7e1 7856 found = true;
252b5132
RH
7857 }
7858 }
7859
7860 if (! found)
45ac8f4f
NC
7861 {
7862 /* Users sometimes forget the -D option, so try to be helpful. */
7863 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7864 {
978c4450 7865 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 7866 {
ca0e11aa
NC
7867 if (filedata->is_separate)
7868 printf (_("\nThere are no static relocations in linked file '%s'."),
7869 filedata->file_name);
7870 else
7871 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
7872 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7873
7874 break;
7875 }
7876 }
7877 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
7878 {
7879 if (filedata->is_separate)
7880 printf (_("\nThere are no relocations in linked file '%s'.\n"),
7881 filedata->file_name);
7882 else
7883 printf (_("\nThere are no relocations in this file.\n"));
7884 }
45ac8f4f 7885 }
252b5132
RH
7886 }
7887
015dc7e1 7888 return true;
252b5132
RH
7889}
7890
4d6ed7c8
NC
7891/* An absolute address consists of a section and an offset. If the
7892 section is NULL, the offset itself is the address, otherwise, the
7893 address equals to LOAD_ADDRESS(section) + offset. */
7894
7895struct absaddr
948f632f
DA
7896{
7897 unsigned short section;
7898 bfd_vma offset;
7899};
4d6ed7c8 7900
948f632f
DA
7901/* Find the nearest symbol at or below ADDR. Returns the symbol
7902 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7903
4d6ed7c8 7904static void
dda8d76d
NC
7905find_symbol_for_address (Filedata * filedata,
7906 Elf_Internal_Sym * symtab,
7907 unsigned long nsyms,
7908 const char * strtab,
7909 unsigned long strtab_size,
7910 struct absaddr addr,
7911 const char ** symname,
7912 bfd_vma * offset)
4d6ed7c8 7913{
d3ba0551 7914 bfd_vma dist = 0x100000;
2cf0635d 7915 Elf_Internal_Sym * sym;
948f632f
DA
7916 Elf_Internal_Sym * beg;
7917 Elf_Internal_Sym * end;
2cf0635d 7918 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7919
0b6ae522 7920 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7921 beg = symtab;
7922 end = symtab + nsyms;
0b6ae522 7923
948f632f 7924 while (beg < end)
4d6ed7c8 7925 {
948f632f
DA
7926 bfd_vma value;
7927
7928 sym = beg + (end - beg) / 2;
0b6ae522 7929
948f632f 7930 value = sym->st_value;
0b6ae522
DJ
7931 REMOVE_ARCH_BITS (value);
7932
948f632f 7933 if (sym->st_name != 0
4d6ed7c8 7934 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7935 && addr.offset >= value
7936 && addr.offset - value < dist)
4d6ed7c8
NC
7937 {
7938 best = sym;
0b6ae522 7939 dist = addr.offset - value;
4d6ed7c8
NC
7940 if (!dist)
7941 break;
7942 }
948f632f
DA
7943
7944 if (addr.offset < value)
7945 end = sym;
7946 else
7947 beg = sym + 1;
4d6ed7c8 7948 }
1b31d05e 7949
4d6ed7c8
NC
7950 if (best)
7951 {
57346661 7952 *symname = (best->st_name >= strtab_size
2b692964 7953 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7954 *offset = dist;
7955 return;
7956 }
1b31d05e 7957
4d6ed7c8
NC
7958 *symname = NULL;
7959 *offset = addr.offset;
7960}
7961
32ec8896 7962static /* signed */ int
948f632f
DA
7963symcmp (const void *p, const void *q)
7964{
7965 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7966 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7967
7968 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7969}
7970
7971/* Process the unwind section. */
7972
7973#include "unwind-ia64.h"
7974
7975struct ia64_unw_table_entry
7976{
7977 struct absaddr start;
7978 struct absaddr end;
7979 struct absaddr info;
7980};
7981
7982struct ia64_unw_aux_info
7983{
32ec8896
NC
7984 struct ia64_unw_table_entry * table; /* Unwind table. */
7985 unsigned long table_len; /* Length of unwind table. */
7986 unsigned char * info; /* Unwind info. */
7987 unsigned long info_size; /* Size of unwind info. */
7988 bfd_vma info_addr; /* Starting address of unwind info. */
7989 bfd_vma seg_base; /* Starting address of segment. */
7990 Elf_Internal_Sym * symtab; /* The symbol table. */
7991 unsigned long nsyms; /* Number of symbols. */
7992 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7993 unsigned long nfuns; /* Number of entries in funtab. */
7994 char * strtab; /* The string table. */
7995 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7996};
7997
015dc7e1 7998static bool
dda8d76d 7999dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8000{
2cf0635d 8001 struct ia64_unw_table_entry * tp;
948f632f 8002 unsigned long j, nfuns;
4d6ed7c8 8003 int in_body;
015dc7e1 8004 bool res = true;
7036c0e1 8005
948f632f
DA
8006 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8007 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8008 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8009 aux->funtab[nfuns++] = aux->symtab[j];
8010 aux->nfuns = nfuns;
8011 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8012
4d6ed7c8
NC
8013 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8014 {
8015 bfd_vma stamp;
8016 bfd_vma offset;
2cf0635d
NC
8017 const unsigned char * dp;
8018 const unsigned char * head;
53774b7e 8019 const unsigned char * end;
2cf0635d 8020 const char * procname;
4d6ed7c8 8021
dda8d76d 8022 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8023 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8024
8025 fputs ("\n<", stdout);
8026
8027 if (procname)
8028 {
8029 fputs (procname, stdout);
8030
8031 if (offset)
8032 printf ("+%lx", (unsigned long) offset);
8033 }
8034
8035 fputs (">: [", stdout);
8036 print_vma (tp->start.offset, PREFIX_HEX);
8037 fputc ('-', stdout);
8038 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 8039 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
8040 (unsigned long) (tp->info.offset - aux->seg_base));
8041
53774b7e
NC
8042 /* PR 17531: file: 86232b32. */
8043 if (aux->info == NULL)
8044 continue;
8045
97c0a079
AM
8046 offset = tp->info.offset;
8047 if (tp->info.section)
8048 {
8049 if (tp->info.section >= filedata->file_header.e_shnum)
8050 {
8051 warn (_("Invalid section %u in table entry %ld\n"),
8052 tp->info.section, (long) (tp - aux->table));
015dc7e1 8053 res = false;
97c0a079
AM
8054 continue;
8055 }
8056 offset += filedata->section_headers[tp->info.section].sh_addr;
8057 }
8058 offset -= aux->info_addr;
53774b7e 8059 /* PR 17531: file: 0997b4d1. */
90679903
AM
8060 if (offset >= aux->info_size
8061 || aux->info_size - offset < 8)
53774b7e
NC
8062 {
8063 warn (_("Invalid offset %lx in table entry %ld\n"),
8064 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8065 res = false;
53774b7e
NC
8066 continue;
8067 }
8068
97c0a079 8069 head = aux->info + offset;
a4a00738 8070 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8071
86f55779 8072 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8073 (unsigned) UNW_VER (stamp),
8074 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8075 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8076 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8077 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8078
8079 if (UNW_VER (stamp) != 1)
8080 {
2b692964 8081 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8082 continue;
8083 }
8084
8085 in_body = 0;
53774b7e
NC
8086 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8087 /* PR 17531: file: 16ceda89. */
8088 if (end > aux->info + aux->info_size)
8089 end = aux->info + aux->info_size;
8090 for (dp = head + 8; dp < end;)
b4477bc8 8091 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8092 }
948f632f
DA
8093
8094 free (aux->funtab);
32ec8896
NC
8095
8096 return res;
4d6ed7c8
NC
8097}
8098
015dc7e1 8099static bool
dda8d76d
NC
8100slurp_ia64_unwind_table (Filedata * filedata,
8101 struct ia64_unw_aux_info * aux,
8102 Elf_Internal_Shdr * sec)
4d6ed7c8 8103{
89fac5e3 8104 unsigned long size, nrelas, i;
2cf0635d
NC
8105 Elf_Internal_Phdr * seg;
8106 struct ia64_unw_table_entry * tep;
8107 Elf_Internal_Shdr * relsec;
8108 Elf_Internal_Rela * rela;
8109 Elf_Internal_Rela * rp;
8110 unsigned char * table;
8111 unsigned char * tp;
8112 Elf_Internal_Sym * sym;
8113 const char * relname;
4d6ed7c8 8114
53774b7e
NC
8115 aux->table_len = 0;
8116
4d6ed7c8
NC
8117 /* First, find the starting address of the segment that includes
8118 this section: */
8119
dda8d76d 8120 if (filedata->file_header.e_phnum)
4d6ed7c8 8121 {
dda8d76d 8122 if (! get_program_headers (filedata))
015dc7e1 8123 return false;
4d6ed7c8 8124
dda8d76d
NC
8125 for (seg = filedata->program_headers;
8126 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8127 ++seg)
4d6ed7c8
NC
8128 {
8129 if (seg->p_type != PT_LOAD)
8130 continue;
8131
8132 if (sec->sh_addr >= seg->p_vaddr
8133 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8134 {
8135 aux->seg_base = seg->p_vaddr;
8136 break;
8137 }
8138 }
4d6ed7c8
NC
8139 }
8140
8141 /* Second, build the unwind table from the contents of the unwind section: */
8142 size = sec->sh_size;
dda8d76d 8143 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8144 _("unwind table"));
a6e9f9df 8145 if (!table)
015dc7e1 8146 return false;
4d6ed7c8 8147
53774b7e 8148 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8149 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8150 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8151 tep = aux->table;
53774b7e
NC
8152
8153 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8154 {
8155 tep->start.section = SHN_UNDEF;
8156 tep->end.section = SHN_UNDEF;
8157 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8158 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8159 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8160 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8161 tep->start.offset += aux->seg_base;
8162 tep->end.offset += aux->seg_base;
8163 tep->info.offset += aux->seg_base;
8164 }
8165 free (table);
8166
41e92641 8167 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8168 for (relsec = filedata->section_headers;
8169 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8170 ++relsec)
8171 {
8172 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8173 || relsec->sh_info >= filedata->file_header.e_shnum
8174 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8175 continue;
8176
dda8d76d 8177 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8178 & rela, & nrelas))
53774b7e
NC
8179 {
8180 free (aux->table);
8181 aux->table = NULL;
8182 aux->table_len = 0;
015dc7e1 8183 return false;
53774b7e 8184 }
4d6ed7c8
NC
8185
8186 for (rp = rela; rp < rela + nrelas; ++rp)
8187 {
4770fb94 8188 unsigned int sym_ndx;
726bd37d
AM
8189 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8190 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8191
82b1b41b
NC
8192 /* PR 17531: file: 9fa67536. */
8193 if (relname == NULL)
8194 {
726bd37d 8195 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8196 continue;
8197 }
948f632f 8198
24d127aa 8199 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8200 {
82b1b41b 8201 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8202 continue;
8203 }
8204
89fac5e3 8205 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8206
53774b7e
NC
8207 /* PR 17531: file: 5bc8d9bf. */
8208 if (i >= aux->table_len)
8209 {
8210 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8211 continue;
8212 }
8213
4770fb94
AM
8214 sym_ndx = get_reloc_symindex (rp->r_info);
8215 if (sym_ndx >= aux->nsyms)
8216 {
8217 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8218 sym_ndx);
8219 continue;
8220 }
8221 sym = aux->symtab + sym_ndx;
8222
53774b7e 8223 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8224 {
8225 case 0:
8226 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8227 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8228 break;
8229 case 1:
8230 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8231 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8232 break;
8233 case 2:
8234 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8235 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8236 break;
8237 default:
8238 break;
8239 }
8240 }
8241
8242 free (rela);
8243 }
8244
015dc7e1 8245 return true;
4d6ed7c8
NC
8246}
8247
015dc7e1 8248static bool
dda8d76d 8249ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8250{
2cf0635d
NC
8251 Elf_Internal_Shdr * sec;
8252 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8253 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8254 struct ia64_unw_aux_info aux;
015dc7e1 8255 bool res = true;
f1467e33 8256
4d6ed7c8
NC
8257 memset (& aux, 0, sizeof (aux));
8258
dda8d76d 8259 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8260 {
28d13567 8261 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8262 {
28d13567 8263 if (aux.symtab)
4082ef84 8264 {
28d13567
AM
8265 error (_("Multiple symbol tables encountered\n"));
8266 free (aux.symtab);
8267 aux.symtab = NULL;
4082ef84 8268 free (aux.strtab);
28d13567 8269 aux.strtab = NULL;
4082ef84 8270 }
28d13567
AM
8271 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8272 &aux.strtab, &aux.strtab_size))
015dc7e1 8273 return false;
4d6ed7c8
NC
8274 }
8275 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8276 unwcount++;
8277 }
8278
8279 if (!unwcount)
8280 printf (_("\nThere are no unwind sections in this file.\n"));
8281
8282 while (unwcount-- > 0)
8283 {
2cf0635d 8284 char * suffix;
579f31ac
JJ
8285 size_t len, len2;
8286
dda8d76d
NC
8287 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8288 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8289 if (sec->sh_type == SHT_IA_64_UNWIND)
8290 {
8291 unwsec = sec;
8292 break;
8293 }
4082ef84
NC
8294 /* We have already counted the number of SHT_IA64_UNWIND
8295 sections so the loop above should never fail. */
8296 assert (unwsec != NULL);
579f31ac
JJ
8297
8298 unwstart = i + 1;
8299 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8300
e4b17d5c
L
8301 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8302 {
8303 /* We need to find which section group it is in. */
4082ef84 8304 struct group_list * g;
e4b17d5c 8305
978c4450
AM
8306 if (filedata->section_headers_groups == NULL
8307 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8308 i = filedata->file_header.e_shnum;
4082ef84 8309 else
e4b17d5c 8310 {
978c4450 8311 g = filedata->section_headers_groups[i]->root;
18bd398b 8312
4082ef84
NC
8313 for (; g != NULL; g = g->next)
8314 {
dda8d76d 8315 sec = filedata->section_headers + g->section_index;
e4b17d5c 8316
b9e920ec
AM
8317 if (SECTION_NAME_VALID (sec)
8318 && streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
4082ef84
NC
8319 break;
8320 }
8321
8322 if (g == NULL)
dda8d76d 8323 i = filedata->file_header.e_shnum;
4082ef84 8324 }
e4b17d5c 8325 }
b9e920ec 8326 else if (SECTION_NAME_VALID (unwsec)
e9b095a5
ML
8327 && startswith (SECTION_NAME (unwsec),
8328 ELF_STRING_ia64_unwind_once))
579f31ac 8329 {
18bd398b 8330 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
8331 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
8332 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8333 for (i = 0, sec = filedata->section_headers;
8334 i < filedata->file_header.e_shnum;
579f31ac 8335 ++i, ++sec)
b9e920ec 8336 if (SECTION_NAME_VALID (sec)
e9b095a5
ML
8337 && startswith (SECTION_NAME (sec),
8338 ELF_STRING_ia64_unwind_info_once)
18bd398b 8339 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8340 break;
8341 }
8342 else
8343 {
8344 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8345 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8346 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8347 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8348 suffix = "";
b9e920ec 8349 if (SECTION_NAME_VALID (unwsec)
e9b095a5 8350 && startswith (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind))
579f31ac 8351 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8352 for (i = 0, sec = filedata->section_headers;
8353 i < filedata->file_header.e_shnum;
579f31ac 8354 ++i, ++sec)
b9e920ec 8355 if (SECTION_NAME_VALID (sec)
e9b095a5 8356 && startswith (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info)
18bd398b 8357 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8358 break;
8359 }
8360
dda8d76d 8361 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8362 {
8363 printf (_("\nCould not find unwind info section for "));
8364
dda8d76d 8365 if (filedata->string_table == NULL)
579f31ac
JJ
8366 printf ("%d", unwsec->sh_name);
8367 else
dda8d76d 8368 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8369 }
8370 else
4d6ed7c8 8371 {
4d6ed7c8 8372 aux.info_addr = sec->sh_addr;
dda8d76d 8373 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8374 sec->sh_size,
8375 _("unwind info"));
59245841 8376 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8377
579f31ac 8378 printf (_("\nUnwind section "));
4d6ed7c8 8379
dda8d76d 8380 if (filedata->string_table == NULL)
579f31ac
JJ
8381 printf ("%d", unwsec->sh_name);
8382 else
dda8d76d 8383 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8384
579f31ac 8385 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8386 (unsigned long) unwsec->sh_offset,
89fac5e3 8387 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8388
dda8d76d 8389 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8390 && aux.table_len > 0)
dda8d76d 8391 dump_ia64_unwind (filedata, & aux);
579f31ac 8392
9db70fc3
AM
8393 free ((char *) aux.table);
8394 free ((char *) aux.info);
579f31ac
JJ
8395 aux.table = NULL;
8396 aux.info = NULL;
8397 }
4d6ed7c8 8398 }
4d6ed7c8 8399
9db70fc3
AM
8400 free (aux.symtab);
8401 free ((char *) aux.strtab);
32ec8896
NC
8402
8403 return res;
4d6ed7c8
NC
8404}
8405
3f5e193b 8406struct hppa_unw_table_entry
32ec8896
NC
8407{
8408 struct absaddr start;
8409 struct absaddr end;
8410 unsigned int Cannot_unwind:1; /* 0 */
8411 unsigned int Millicode:1; /* 1 */
8412 unsigned int Millicode_save_sr0:1; /* 2 */
8413 unsigned int Region_description:2; /* 3..4 */
8414 unsigned int reserved1:1; /* 5 */
8415 unsigned int Entry_SR:1; /* 6 */
8416 unsigned int Entry_FR:4; /* Number saved 7..10 */
8417 unsigned int Entry_GR:5; /* Number saved 11..15 */
8418 unsigned int Args_stored:1; /* 16 */
8419 unsigned int Variable_Frame:1; /* 17 */
8420 unsigned int Separate_Package_Body:1; /* 18 */
8421 unsigned int Frame_Extension_Millicode:1; /* 19 */
8422 unsigned int Stack_Overflow_Check:1; /* 20 */
8423 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8424 unsigned int Ada_Region:1; /* 22 */
8425 unsigned int cxx_info:1; /* 23 */
8426 unsigned int cxx_try_catch:1; /* 24 */
8427 unsigned int sched_entry_seq:1; /* 25 */
8428 unsigned int reserved2:1; /* 26 */
8429 unsigned int Save_SP:1; /* 27 */
8430 unsigned int Save_RP:1; /* 28 */
8431 unsigned int Save_MRP_in_frame:1; /* 29 */
8432 unsigned int extn_ptr_defined:1; /* 30 */
8433 unsigned int Cleanup_defined:1; /* 31 */
8434
8435 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8436 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8437 unsigned int Large_frame:1; /* 2 */
8438 unsigned int Pseudo_SP_Set:1; /* 3 */
8439 unsigned int reserved4:1; /* 4 */
8440 unsigned int Total_frame_size:27; /* 5..31 */
8441};
3f5e193b 8442
57346661 8443struct hppa_unw_aux_info
948f632f 8444{
32ec8896
NC
8445 struct hppa_unw_table_entry * table; /* Unwind table. */
8446 unsigned long table_len; /* Length of unwind table. */
8447 bfd_vma seg_base; /* Starting address of segment. */
8448 Elf_Internal_Sym * symtab; /* The symbol table. */
8449 unsigned long nsyms; /* Number of symbols. */
8450 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8451 unsigned long nfuns; /* Number of entries in funtab. */
8452 char * strtab; /* The string table. */
8453 unsigned long strtab_size; /* Size of string table. */
948f632f 8454};
57346661 8455
015dc7e1 8456static bool
dda8d76d 8457dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8458{
2cf0635d 8459 struct hppa_unw_table_entry * tp;
948f632f 8460 unsigned long j, nfuns;
015dc7e1 8461 bool res = true;
948f632f
DA
8462
8463 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8464 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8465 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8466 aux->funtab[nfuns++] = aux->symtab[j];
8467 aux->nfuns = nfuns;
8468 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8469
57346661
AM
8470 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8471 {
8472 bfd_vma offset;
2cf0635d 8473 const char * procname;
57346661 8474
dda8d76d 8475 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8476 aux->strtab_size, tp->start, &procname,
8477 &offset);
8478
8479 fputs ("\n<", stdout);
8480
8481 if (procname)
8482 {
8483 fputs (procname, stdout);
8484
8485 if (offset)
8486 printf ("+%lx", (unsigned long) offset);
8487 }
8488
8489 fputs (">: [", stdout);
8490 print_vma (tp->start.offset, PREFIX_HEX);
8491 fputc ('-', stdout);
8492 print_vma (tp->end.offset, PREFIX_HEX);
8493 printf ("]\n\t");
8494
18bd398b
NC
8495#define PF(_m) if (tp->_m) printf (#_m " ");
8496#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8497 PF(Cannot_unwind);
8498 PF(Millicode);
8499 PF(Millicode_save_sr0);
18bd398b 8500 /* PV(Region_description); */
57346661
AM
8501 PF(Entry_SR);
8502 PV(Entry_FR);
8503 PV(Entry_GR);
8504 PF(Args_stored);
8505 PF(Variable_Frame);
8506 PF(Separate_Package_Body);
8507 PF(Frame_Extension_Millicode);
8508 PF(Stack_Overflow_Check);
8509 PF(Two_Instruction_SP_Increment);
8510 PF(Ada_Region);
8511 PF(cxx_info);
8512 PF(cxx_try_catch);
8513 PF(sched_entry_seq);
8514 PF(Save_SP);
8515 PF(Save_RP);
8516 PF(Save_MRP_in_frame);
8517 PF(extn_ptr_defined);
8518 PF(Cleanup_defined);
8519 PF(MPE_XL_interrupt_marker);
8520 PF(HP_UX_interrupt_marker);
8521 PF(Large_frame);
8522 PF(Pseudo_SP_Set);
8523 PV(Total_frame_size);
8524#undef PF
8525#undef PV
8526 }
8527
18bd398b 8528 printf ("\n");
948f632f
DA
8529
8530 free (aux->funtab);
32ec8896
NC
8531
8532 return res;
57346661
AM
8533}
8534
015dc7e1 8535static bool
dda8d76d
NC
8536slurp_hppa_unwind_table (Filedata * filedata,
8537 struct hppa_unw_aux_info * aux,
8538 Elf_Internal_Shdr * sec)
57346661 8539{
1c0751b2 8540 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8541 Elf_Internal_Phdr * seg;
8542 struct hppa_unw_table_entry * tep;
8543 Elf_Internal_Shdr * relsec;
8544 Elf_Internal_Rela * rela;
8545 Elf_Internal_Rela * rp;
8546 unsigned char * table;
8547 unsigned char * tp;
8548 Elf_Internal_Sym * sym;
8549 const char * relname;
57346661 8550
57346661
AM
8551 /* First, find the starting address of the segment that includes
8552 this section. */
dda8d76d 8553 if (filedata->file_header.e_phnum)
57346661 8554 {
dda8d76d 8555 if (! get_program_headers (filedata))
015dc7e1 8556 return false;
57346661 8557
dda8d76d
NC
8558 for (seg = filedata->program_headers;
8559 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8560 ++seg)
8561 {
8562 if (seg->p_type != PT_LOAD)
8563 continue;
8564
8565 if (sec->sh_addr >= seg->p_vaddr
8566 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8567 {
8568 aux->seg_base = seg->p_vaddr;
8569 break;
8570 }
8571 }
8572 }
8573
8574 /* Second, build the unwind table from the contents of the unwind
8575 section. */
8576 size = sec->sh_size;
dda8d76d 8577 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8578 _("unwind table"));
57346661 8579 if (!table)
015dc7e1 8580 return false;
57346661 8581
1c0751b2
DA
8582 unw_ent_size = 16;
8583 nentries = size / unw_ent_size;
8584 size = unw_ent_size * nentries;
57346661 8585
e3fdc001 8586 aux->table_len = nentries;
3f5e193b
NC
8587 tep = aux->table = (struct hppa_unw_table_entry *)
8588 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8589
1c0751b2 8590 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8591 {
8592 unsigned int tmp1, tmp2;
8593
8594 tep->start.section = SHN_UNDEF;
8595 tep->end.section = SHN_UNDEF;
8596
1c0751b2
DA
8597 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8598 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8599 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8600 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8601
8602 tep->start.offset += aux->seg_base;
8603 tep->end.offset += aux->seg_base;
57346661
AM
8604
8605 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8606 tep->Millicode = (tmp1 >> 30) & 0x1;
8607 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8608 tep->Region_description = (tmp1 >> 27) & 0x3;
8609 tep->reserved1 = (tmp1 >> 26) & 0x1;
8610 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8611 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8612 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8613 tep->Args_stored = (tmp1 >> 15) & 0x1;
8614 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8615 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8616 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8617 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8618 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8619 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8620 tep->cxx_info = (tmp1 >> 8) & 0x1;
8621 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8622 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8623 tep->reserved2 = (tmp1 >> 5) & 0x1;
8624 tep->Save_SP = (tmp1 >> 4) & 0x1;
8625 tep->Save_RP = (tmp1 >> 3) & 0x1;
8626 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8627 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8628 tep->Cleanup_defined = tmp1 & 0x1;
8629
8630 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8631 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8632 tep->Large_frame = (tmp2 >> 29) & 0x1;
8633 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8634 tep->reserved4 = (tmp2 >> 27) & 0x1;
8635 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8636 }
8637 free (table);
8638
8639 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8640 for (relsec = filedata->section_headers;
8641 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8642 ++relsec)
8643 {
8644 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8645 || relsec->sh_info >= filedata->file_header.e_shnum
8646 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8647 continue;
8648
dda8d76d 8649 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8650 & rela, & nrelas))
015dc7e1 8651 return false;
57346661
AM
8652
8653 for (rp = rela; rp < rela + nrelas; ++rp)
8654 {
4770fb94 8655 unsigned int sym_ndx;
726bd37d
AM
8656 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8657 relname = elf_hppa_reloc_type (r_type);
57346661 8658
726bd37d
AM
8659 if (relname == NULL)
8660 {
8661 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8662 continue;
8663 }
8664
57346661 8665 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 8666 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 8667 {
726bd37d 8668 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8669 continue;
8670 }
8671
8672 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8673 if (i >= aux->table_len)
8674 {
8675 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8676 continue;
8677 }
57346661 8678
4770fb94
AM
8679 sym_ndx = get_reloc_symindex (rp->r_info);
8680 if (sym_ndx >= aux->nsyms)
8681 {
8682 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8683 sym_ndx);
8684 continue;
8685 }
8686 sym = aux->symtab + sym_ndx;
8687
43f6cd05 8688 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8689 {
8690 case 0:
8691 aux->table[i].start.section = sym->st_shndx;
1e456d54 8692 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8693 break;
8694 case 1:
8695 aux->table[i].end.section = sym->st_shndx;
1e456d54 8696 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8697 break;
8698 default:
8699 break;
8700 }
8701 }
8702
8703 free (rela);
8704 }
8705
015dc7e1 8706 return true;
57346661
AM
8707}
8708
015dc7e1 8709static bool
dda8d76d 8710hppa_process_unwind (Filedata * filedata)
57346661 8711{
57346661 8712 struct hppa_unw_aux_info aux;
2cf0635d 8713 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8714 Elf_Internal_Shdr * sec;
18bd398b 8715 unsigned long i;
015dc7e1 8716 bool res = true;
57346661 8717
dda8d76d 8718 if (filedata->string_table == NULL)
015dc7e1 8719 return false;
1b31d05e
NC
8720
8721 memset (& aux, 0, sizeof (aux));
57346661 8722
dda8d76d 8723 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8724 {
28d13567 8725 if (sec->sh_type == SHT_SYMTAB)
57346661 8726 {
28d13567 8727 if (aux.symtab)
4082ef84 8728 {
28d13567
AM
8729 error (_("Multiple symbol tables encountered\n"));
8730 free (aux.symtab);
8731 aux.symtab = NULL;
4082ef84 8732 free (aux.strtab);
28d13567 8733 aux.strtab = NULL;
4082ef84 8734 }
28d13567
AM
8735 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8736 &aux.strtab, &aux.strtab_size))
015dc7e1 8737 return false;
57346661 8738 }
b9e920ec
AM
8739 else if (SECTION_NAME_VALID (sec)
8740 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8741 unwsec = sec;
8742 }
8743
8744 if (!unwsec)
8745 printf (_("\nThere are no unwind sections in this file.\n"));
8746
dda8d76d 8747 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8748 {
b9e920ec
AM
8749 if (SECTION_NAME_VALID (sec)
8750 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8751 {
43f6cd05 8752 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8753
d3a49aa8
AM
8754 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8755 "contains %lu entry:\n",
8756 "\nUnwind section '%s' at offset 0x%lx "
8757 "contains %lu entries:\n",
8758 num_unwind),
dda8d76d 8759 printable_section_name (filedata, sec),
57346661 8760 (unsigned long) sec->sh_offset,
d3a49aa8 8761 num_unwind);
57346661 8762
dda8d76d 8763 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 8764 res = false;
66b09c7e
S
8765
8766 if (res && aux.table_len > 0)
32ec8896 8767 {
dda8d76d 8768 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 8769 res = false;
32ec8896 8770 }
57346661 8771
9db70fc3 8772 free ((char *) aux.table);
57346661
AM
8773 aux.table = NULL;
8774 }
8775 }
8776
9db70fc3
AM
8777 free (aux.symtab);
8778 free ((char *) aux.strtab);
32ec8896
NC
8779
8780 return res;
57346661
AM
8781}
8782
0b6ae522
DJ
8783struct arm_section
8784{
a734115a
NC
8785 unsigned char * data; /* The unwind data. */
8786 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8787 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8788 unsigned long nrelas; /* The number of relocations. */
8789 unsigned int rel_type; /* REL or RELA ? */
8790 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8791};
8792
8793struct arm_unw_aux_info
8794{
dda8d76d 8795 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8796 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8797 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8798 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8799 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8800 char * strtab; /* The file's string table. */
8801 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8802};
8803
8804static const char *
dda8d76d
NC
8805arm_print_vma_and_name (Filedata * filedata,
8806 struct arm_unw_aux_info * aux,
8807 bfd_vma fn,
8808 struct absaddr addr)
0b6ae522
DJ
8809{
8810 const char *procname;
8811 bfd_vma sym_offset;
8812
8813 if (addr.section == SHN_UNDEF)
8814 addr.offset = fn;
8815
dda8d76d 8816 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8817 aux->strtab_size, addr, &procname,
8818 &sym_offset);
8819
8820 print_vma (fn, PREFIX_HEX);
8821
8822 if (procname)
8823 {
8824 fputs (" <", stdout);
8825 fputs (procname, stdout);
8826
8827 if (sym_offset)
8828 printf ("+0x%lx", (unsigned long) sym_offset);
8829 fputc ('>', stdout);
8830 }
8831
8832 return procname;
8833}
8834
8835static void
8836arm_free_section (struct arm_section *arm_sec)
8837{
9db70fc3
AM
8838 free (arm_sec->data);
8839 free (arm_sec->rela);
0b6ae522
DJ
8840}
8841
a734115a
NC
8842/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8843 cached section and install SEC instead.
8844 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8845 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8846 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8847 relocation's offset in ADDR.
1b31d05e
NC
8848 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8849 into the string table of the symbol associated with the reloc. If no
8850 reloc was applied store -1 there.
8851 5) Return TRUE upon success, FALSE otherwise. */
a734115a 8852
015dc7e1 8853static bool
dda8d76d
NC
8854get_unwind_section_word (Filedata * filedata,
8855 struct arm_unw_aux_info * aux,
1b31d05e
NC
8856 struct arm_section * arm_sec,
8857 Elf_Internal_Shdr * sec,
8858 bfd_vma word_offset,
8859 unsigned int * wordp,
8860 struct absaddr * addr,
8861 bfd_vma * sym_name)
0b6ae522
DJ
8862{
8863 Elf_Internal_Rela *rp;
8864 Elf_Internal_Sym *sym;
8865 const char * relname;
8866 unsigned int word;
015dc7e1 8867 bool wrapped;
0b6ae522 8868
e0a31db1 8869 if (sec == NULL || arm_sec == NULL)
015dc7e1 8870 return false;
e0a31db1 8871
0b6ae522
DJ
8872 addr->section = SHN_UNDEF;
8873 addr->offset = 0;
8874
1b31d05e
NC
8875 if (sym_name != NULL)
8876 *sym_name = (bfd_vma) -1;
8877
a734115a 8878 /* If necessary, update the section cache. */
0b6ae522
DJ
8879 if (sec != arm_sec->sec)
8880 {
8881 Elf_Internal_Shdr *relsec;
8882
8883 arm_free_section (arm_sec);
8884
8885 arm_sec->sec = sec;
dda8d76d 8886 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8887 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8888 arm_sec->rela = NULL;
8889 arm_sec->nrelas = 0;
8890
dda8d76d
NC
8891 for (relsec = filedata->section_headers;
8892 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8893 ++relsec)
8894 {
dda8d76d
NC
8895 if (relsec->sh_info >= filedata->file_header.e_shnum
8896 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8897 /* PR 15745: Check the section type as well. */
8898 || (relsec->sh_type != SHT_REL
8899 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8900 continue;
8901
a734115a 8902 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8903 if (relsec->sh_type == SHT_REL)
8904 {
dda8d76d 8905 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8906 relsec->sh_size,
8907 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 8908 return false;
0b6ae522 8909 }
1ae40aa4 8910 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8911 {
dda8d76d 8912 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8913 relsec->sh_size,
8914 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 8915 return false;
0b6ae522 8916 }
1ae40aa4 8917 break;
0b6ae522
DJ
8918 }
8919
8920 arm_sec->next_rela = arm_sec->rela;
8921 }
8922
a734115a 8923 /* If there is no unwind data we can do nothing. */
0b6ae522 8924 if (arm_sec->data == NULL)
015dc7e1 8925 return false;
0b6ae522 8926
e0a31db1 8927 /* If the offset is invalid then fail. */
f32ba729
NC
8928 if (/* PR 21343 *//* PR 18879 */
8929 sec->sh_size < 4
8930 || word_offset > (sec->sh_size - 4)
1a915552 8931 || ((bfd_signed_vma) word_offset) < 0)
015dc7e1 8932 return false;
e0a31db1 8933
a734115a 8934 /* Get the word at the required offset. */
0b6ae522
DJ
8935 word = byte_get (arm_sec->data + word_offset, 4);
8936
0eff7165
NC
8937 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8938 if (arm_sec->rela == NULL)
8939 {
8940 * wordp = word;
015dc7e1 8941 return true;
0eff7165
NC
8942 }
8943
a734115a 8944 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 8945 wrapped = false;
0b6ae522
DJ
8946 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8947 {
8948 bfd_vma prelval, offset;
8949
8950 if (rp->r_offset > word_offset && !wrapped)
8951 {
8952 rp = arm_sec->rela;
015dc7e1 8953 wrapped = true;
0b6ae522
DJ
8954 }
8955 if (rp->r_offset > word_offset)
8956 break;
8957
8958 if (rp->r_offset & 3)
8959 {
8960 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8961 (unsigned long) rp->r_offset);
8962 continue;
8963 }
8964
8965 if (rp->r_offset < word_offset)
8966 continue;
8967
74e1a04b
NC
8968 /* PR 17531: file: 027-161405-0.004 */
8969 if (aux->symtab == NULL)
8970 continue;
8971
0b6ae522
DJ
8972 if (arm_sec->rel_type == SHT_REL)
8973 {
8974 offset = word & 0x7fffffff;
8975 if (offset & 0x40000000)
8976 offset |= ~ (bfd_vma) 0x7fffffff;
8977 }
a734115a 8978 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8979 offset = rp->r_addend;
a734115a 8980 else
74e1a04b
NC
8981 {
8982 error (_("Unknown section relocation type %d encountered\n"),
8983 arm_sec->rel_type);
8984 break;
8985 }
0b6ae522 8986
071436c6
NC
8987 /* PR 17531 file: 027-1241568-0.004. */
8988 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8989 {
8990 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8991 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8992 break;
8993 }
8994
8995 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8996 offset += sym->st_value;
8997 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8998
a734115a 8999 /* Check that we are processing the expected reloc type. */
dda8d76d 9000 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9001 {
9002 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9003 if (relname == NULL)
9004 {
9005 warn (_("Skipping unknown ARM relocation type: %d\n"),
9006 (int) ELF32_R_TYPE (rp->r_info));
9007 continue;
9008 }
a734115a
NC
9009
9010 if (streq (relname, "R_ARM_NONE"))
9011 continue;
0b4362b0 9012
a734115a
NC
9013 if (! streq (relname, "R_ARM_PREL31"))
9014 {
071436c6 9015 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9016 continue;
9017 }
9018 }
dda8d76d 9019 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9020 {
9021 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9022 if (relname == NULL)
9023 {
9024 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9025 (int) ELF32_R_TYPE (rp->r_info));
9026 continue;
9027 }
0b4362b0 9028
a734115a
NC
9029 if (streq (relname, "R_C6000_NONE"))
9030 continue;
9031
9032 if (! streq (relname, "R_C6000_PREL31"))
9033 {
071436c6 9034 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9035 continue;
9036 }
9037
9038 prelval >>= 1;
9039 }
9040 else
74e1a04b
NC
9041 {
9042 /* This function currently only supports ARM and TI unwinders. */
9043 warn (_("Only TI and ARM unwinders are currently supported\n"));
9044 break;
9045 }
fa197c1c 9046
0b6ae522
DJ
9047 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
9048 addr->section = sym->st_shndx;
9049 addr->offset = offset;
74e1a04b 9050
1b31d05e
NC
9051 if (sym_name)
9052 * sym_name = sym->st_name;
0b6ae522
DJ
9053 break;
9054 }
9055
9056 *wordp = word;
9057 arm_sec->next_rela = rp;
9058
015dc7e1 9059 return true;
0b6ae522
DJ
9060}
9061
a734115a
NC
9062static const char *tic6x_unwind_regnames[16] =
9063{
0b4362b0
RM
9064 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9065 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9066 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9067};
fa197c1c 9068
0b6ae522 9069static void
fa197c1c 9070decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9071{
fa197c1c
PB
9072 int i;
9073
9074 for (i = 12; mask; mask >>= 1, i--)
9075 {
9076 if (mask & 1)
9077 {
9078 fputs (tic6x_unwind_regnames[i], stdout);
9079 if (mask > 1)
9080 fputs (", ", stdout);
9081 }
9082 }
9083}
0b6ae522
DJ
9084
9085#define ADVANCE \
9086 if (remaining == 0 && more_words) \
9087 { \
9088 data_offset += 4; \
dda8d76d 9089 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9090 data_offset, & word, & addr, NULL)) \
015dc7e1 9091 return false; \
0b6ae522
DJ
9092 remaining = 4; \
9093 more_words--; \
9094 } \
9095
9096#define GET_OP(OP) \
9097 ADVANCE; \
9098 if (remaining) \
9099 { \
9100 remaining--; \
9101 (OP) = word >> 24; \
9102 word <<= 8; \
9103 } \
9104 else \
9105 { \
2b692964 9106 printf (_("[Truncated opcode]\n")); \
015dc7e1 9107 return false; \
0b6ae522 9108 } \
cc5914eb 9109 printf ("0x%02x ", OP)
0b6ae522 9110
015dc7e1 9111static bool
dda8d76d
NC
9112decode_arm_unwind_bytecode (Filedata * filedata,
9113 struct arm_unw_aux_info * aux,
948f632f
DA
9114 unsigned int word,
9115 unsigned int remaining,
9116 unsigned int more_words,
9117 bfd_vma data_offset,
9118 Elf_Internal_Shdr * data_sec,
9119 struct arm_section * data_arm_sec)
fa197c1c
PB
9120{
9121 struct absaddr addr;
015dc7e1 9122 bool res = true;
0b6ae522
DJ
9123
9124 /* Decode the unwinding instructions. */
9125 while (1)
9126 {
9127 unsigned int op, op2;
9128
9129 ADVANCE;
9130 if (remaining == 0)
9131 break;
9132 remaining--;
9133 op = word >> 24;
9134 word <<= 8;
9135
cc5914eb 9136 printf (" 0x%02x ", op);
0b6ae522
DJ
9137
9138 if ((op & 0xc0) == 0x00)
9139 {
9140 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9141
cc5914eb 9142 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9143 }
9144 else if ((op & 0xc0) == 0x40)
9145 {
9146 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9147
cc5914eb 9148 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9149 }
9150 else if ((op & 0xf0) == 0x80)
9151 {
9152 GET_OP (op2);
9153 if (op == 0x80 && op2 == 0)
9154 printf (_("Refuse to unwind"));
9155 else
9156 {
9157 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9158 bool first = true;
0b6ae522 9159 int i;
2b692964 9160
0b6ae522
DJ
9161 printf ("pop {");
9162 for (i = 0; i < 12; i++)
9163 if (mask & (1 << i))
9164 {
9165 if (first)
015dc7e1 9166 first = false;
0b6ae522
DJ
9167 else
9168 printf (", ");
9169 printf ("r%d", 4 + i);
9170 }
9171 printf ("}");
9172 }
9173 }
9174 else if ((op & 0xf0) == 0x90)
9175 {
9176 if (op == 0x9d || op == 0x9f)
9177 printf (_(" [Reserved]"));
9178 else
cc5914eb 9179 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9180 }
9181 else if ((op & 0xf0) == 0xa0)
9182 {
9183 int end = 4 + (op & 0x07);
015dc7e1 9184 bool first = true;
0b6ae522 9185 int i;
61865e30 9186
0b6ae522
DJ
9187 printf (" pop {");
9188 for (i = 4; i <= end; i++)
9189 {
9190 if (first)
015dc7e1 9191 first = false;
0b6ae522
DJ
9192 else
9193 printf (", ");
9194 printf ("r%d", i);
9195 }
9196 if (op & 0x08)
9197 {
1b31d05e 9198 if (!first)
0b6ae522
DJ
9199 printf (", ");
9200 printf ("r14");
9201 }
9202 printf ("}");
9203 }
9204 else if (op == 0xb0)
9205 printf (_(" finish"));
9206 else if (op == 0xb1)
9207 {
9208 GET_OP (op2);
9209 if (op2 == 0 || (op2 & 0xf0) != 0)
9210 printf (_("[Spare]"));
9211 else
9212 {
9213 unsigned int mask = op2 & 0x0f;
015dc7e1 9214 bool first = true;
0b6ae522 9215 int i;
61865e30 9216
0b6ae522
DJ
9217 printf ("pop {");
9218 for (i = 0; i < 12; i++)
9219 if (mask & (1 << i))
9220 {
9221 if (first)
015dc7e1 9222 first = false;
0b6ae522
DJ
9223 else
9224 printf (", ");
9225 printf ("r%d", i);
9226 }
9227 printf ("}");
9228 }
9229 }
9230 else if (op == 0xb2)
9231 {
b115cf96 9232 unsigned char buf[9];
0b6ae522
DJ
9233 unsigned int i, len;
9234 unsigned long offset;
61865e30 9235
b115cf96 9236 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9237 {
9238 GET_OP (buf[i]);
9239 if ((buf[i] & 0x80) == 0)
9240 break;
9241 }
4082ef84 9242 if (i == sizeof (buf))
32ec8896 9243 {
27a45f42 9244 error (_("corrupt change to vsp\n"));
015dc7e1 9245 res = false;
32ec8896 9246 }
4082ef84
NC
9247 else
9248 {
015dc7e1 9249 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9250 assert (len == i + 1);
9251 offset = offset * 4 + 0x204;
9252 printf ("vsp = vsp + %ld", offset);
9253 }
0b6ae522 9254 }
61865e30 9255 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9256 {
61865e30
NC
9257 unsigned int first, last;
9258
9259 GET_OP (op2);
9260 first = op2 >> 4;
9261 last = op2 & 0x0f;
9262 if (op == 0xc8)
9263 first = first + 16;
9264 printf ("pop {D%d", first);
9265 if (last)
9266 printf ("-D%d", first + last);
9267 printf ("}");
9268 }
9269 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9270 {
9271 unsigned int count = op & 0x07;
9272
9273 printf ("pop {D8");
9274 if (count)
9275 printf ("-D%d", 8 + count);
9276 printf ("}");
9277 }
9278 else if (op >= 0xc0 && op <= 0xc5)
9279 {
9280 unsigned int count = op & 0x07;
9281
9282 printf (" pop {wR10");
9283 if (count)
9284 printf ("-wR%d", 10 + count);
9285 printf ("}");
9286 }
9287 else if (op == 0xc6)
9288 {
9289 unsigned int first, last;
9290
9291 GET_OP (op2);
9292 first = op2 >> 4;
9293 last = op2 & 0x0f;
9294 printf ("pop {wR%d", first);
9295 if (last)
9296 printf ("-wR%d", first + last);
9297 printf ("}");
9298 }
9299 else if (op == 0xc7)
9300 {
9301 GET_OP (op2);
9302 if (op2 == 0 || (op2 & 0xf0) != 0)
9303 printf (_("[Spare]"));
0b6ae522
DJ
9304 else
9305 {
61865e30 9306 unsigned int mask = op2 & 0x0f;
015dc7e1 9307 bool first = true;
61865e30
NC
9308 int i;
9309
9310 printf ("pop {");
9311 for (i = 0; i < 4; i++)
9312 if (mask & (1 << i))
9313 {
9314 if (first)
015dc7e1 9315 first = false;
61865e30
NC
9316 else
9317 printf (", ");
9318 printf ("wCGR%d", i);
9319 }
9320 printf ("}");
0b6ae522
DJ
9321 }
9322 }
61865e30 9323 else
32ec8896
NC
9324 {
9325 printf (_(" [unsupported opcode]"));
015dc7e1 9326 res = false;
32ec8896
NC
9327 }
9328
0b6ae522
DJ
9329 printf ("\n");
9330 }
32ec8896
NC
9331
9332 return res;
fa197c1c
PB
9333}
9334
015dc7e1 9335static bool
dda8d76d
NC
9336decode_tic6x_unwind_bytecode (Filedata * filedata,
9337 struct arm_unw_aux_info * aux,
948f632f
DA
9338 unsigned int word,
9339 unsigned int remaining,
9340 unsigned int more_words,
9341 bfd_vma data_offset,
9342 Elf_Internal_Shdr * data_sec,
9343 struct arm_section * data_arm_sec)
fa197c1c
PB
9344{
9345 struct absaddr addr;
9346
9347 /* Decode the unwinding instructions. */
9348 while (1)
9349 {
9350 unsigned int op, op2;
9351
9352 ADVANCE;
9353 if (remaining == 0)
9354 break;
9355 remaining--;
9356 op = word >> 24;
9357 word <<= 8;
9358
9cf03b7e 9359 printf (" 0x%02x ", op);
fa197c1c
PB
9360
9361 if ((op & 0xc0) == 0x00)
9362 {
9363 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9364 printf (" sp = sp + %d", offset);
fa197c1c
PB
9365 }
9366 else if ((op & 0xc0) == 0x80)
9367 {
9368 GET_OP (op2);
9369 if (op == 0x80 && op2 == 0)
9370 printf (_("Refuse to unwind"));
9371 else
9372 {
9373 unsigned int mask = ((op & 0x1f) << 8) | op2;
9374 if (op & 0x20)
9375 printf ("pop compact {");
9376 else
9377 printf ("pop {");
9378
9379 decode_tic6x_unwind_regmask (mask);
9380 printf("}");
9381 }
9382 }
9383 else if ((op & 0xf0) == 0xc0)
9384 {
9385 unsigned int reg;
9386 unsigned int nregs;
9387 unsigned int i;
9388 const char *name;
a734115a
NC
9389 struct
9390 {
32ec8896
NC
9391 unsigned int offset;
9392 unsigned int reg;
fa197c1c
PB
9393 } regpos[16];
9394
9395 /* Scan entire instruction first so that GET_OP output is not
9396 interleaved with disassembly. */
9397 nregs = 0;
9398 for (i = 0; nregs < (op & 0xf); i++)
9399 {
9400 GET_OP (op2);
9401 reg = op2 >> 4;
9402 if (reg != 0xf)
9403 {
9404 regpos[nregs].offset = i * 2;
9405 regpos[nregs].reg = reg;
9406 nregs++;
9407 }
9408
9409 reg = op2 & 0xf;
9410 if (reg != 0xf)
9411 {
9412 regpos[nregs].offset = i * 2 + 1;
9413 regpos[nregs].reg = reg;
9414 nregs++;
9415 }
9416 }
9417
9418 printf (_("pop frame {"));
18344509 9419 if (nregs == 0)
fa197c1c 9420 {
18344509
NC
9421 printf (_("*corrupt* - no registers specified"));
9422 }
9423 else
9424 {
9425 reg = nregs - 1;
9426 for (i = i * 2; i > 0; i--)
fa197c1c 9427 {
18344509
NC
9428 if (regpos[reg].offset == i - 1)
9429 {
9430 name = tic6x_unwind_regnames[regpos[reg].reg];
9431 if (reg > 0)
9432 reg--;
9433 }
9434 else
9435 name = _("[pad]");
fa197c1c 9436
18344509
NC
9437 fputs (name, stdout);
9438 if (i > 1)
9439 printf (", ");
9440 }
fa197c1c
PB
9441 }
9442
9443 printf ("}");
9444 }
9445 else if (op == 0xd0)
9446 printf (" MOV FP, SP");
9447 else if (op == 0xd1)
9448 printf (" __c6xabi_pop_rts");
9449 else if (op == 0xd2)
9450 {
9451 unsigned char buf[9];
9452 unsigned int i, len;
9453 unsigned long offset;
a734115a 9454
fa197c1c
PB
9455 for (i = 0; i < sizeof (buf); i++)
9456 {
9457 GET_OP (buf[i]);
9458 if ((buf[i] & 0x80) == 0)
9459 break;
9460 }
0eff7165
NC
9461 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9462 if (i == sizeof (buf))
9463 {
0eff7165 9464 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 9465 return false;
0eff7165 9466 }
948f632f 9467
015dc7e1 9468 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
9469 assert (len == i + 1);
9470 offset = offset * 8 + 0x408;
9471 printf (_("sp = sp + %ld"), offset);
9472 }
9473 else if ((op & 0xf0) == 0xe0)
9474 {
9475 if ((op & 0x0f) == 7)
9476 printf (" RETURN");
9477 else
9478 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9479 }
9480 else
9481 {
9482 printf (_(" [unsupported opcode]"));
9483 }
9484 putchar ('\n');
9485 }
32ec8896 9486
015dc7e1 9487 return true;
fa197c1c
PB
9488}
9489
9490static bfd_vma
dda8d76d 9491arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9492{
9493 bfd_vma offset;
9494
9495 offset = word & 0x7fffffff;
9496 if (offset & 0x40000000)
9497 offset |= ~ (bfd_vma) 0x7fffffff;
9498
dda8d76d 9499 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9500 offset <<= 1;
9501
9502 return offset + where;
9503}
9504
015dc7e1 9505static bool
dda8d76d
NC
9506decode_arm_unwind (Filedata * filedata,
9507 struct arm_unw_aux_info * aux,
1b31d05e
NC
9508 unsigned int word,
9509 unsigned int remaining,
9510 bfd_vma data_offset,
9511 Elf_Internal_Shdr * data_sec,
9512 struct arm_section * data_arm_sec)
fa197c1c
PB
9513{
9514 int per_index;
9515 unsigned int more_words = 0;
37e14bc3 9516 struct absaddr addr;
1b31d05e 9517 bfd_vma sym_name = (bfd_vma) -1;
015dc7e1 9518 bool res = true;
fa197c1c
PB
9519
9520 if (remaining == 0)
9521 {
1b31d05e
NC
9522 /* Fetch the first word.
9523 Note - when decoding an object file the address extracted
9524 here will always be 0. So we also pass in the sym_name
9525 parameter so that we can find the symbol associated with
9526 the personality routine. */
dda8d76d 9527 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9528 & word, & addr, & sym_name))
015dc7e1 9529 return false;
1b31d05e 9530
fa197c1c
PB
9531 remaining = 4;
9532 }
c93dbb25
CZ
9533 else
9534 {
9535 addr.section = SHN_UNDEF;
9536 addr.offset = 0;
9537 }
fa197c1c
PB
9538
9539 if ((word & 0x80000000) == 0)
9540 {
9541 /* Expand prel31 for personality routine. */
9542 bfd_vma fn;
9543 const char *procname;
9544
dda8d76d 9545 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9546 printf (_(" Personality routine: "));
1b31d05e
NC
9547 if (fn == 0
9548 && addr.section == SHN_UNDEF && addr.offset == 0
9549 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9550 {
9551 procname = aux->strtab + sym_name;
9552 print_vma (fn, PREFIX_HEX);
9553 if (procname)
9554 {
9555 fputs (" <", stdout);
9556 fputs (procname, stdout);
9557 fputc ('>', stdout);
9558 }
9559 }
9560 else
dda8d76d 9561 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9562 fputc ('\n', stdout);
9563
9564 /* The GCC personality routines use the standard compact
9565 encoding, starting with one byte giving the number of
9566 words. */
9567 if (procname != NULL
24d127aa
ML
9568 && (startswith (procname, "__gcc_personality_v0")
9569 || startswith (procname, "__gxx_personality_v0")
9570 || startswith (procname, "__gcj_personality_v0")
9571 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
9572 {
9573 remaining = 0;
9574 more_words = 1;
9575 ADVANCE;
9576 if (!remaining)
9577 {
9578 printf (_(" [Truncated data]\n"));
015dc7e1 9579 return false;
fa197c1c
PB
9580 }
9581 more_words = word >> 24;
9582 word <<= 8;
9583 remaining--;
9584 per_index = -1;
9585 }
9586 else
015dc7e1 9587 return true;
fa197c1c
PB
9588 }
9589 else
9590 {
1b31d05e 9591 /* ARM EHABI Section 6.3:
0b4362b0 9592
1b31d05e 9593 An exception-handling table entry for the compact model looks like:
0b4362b0 9594
1b31d05e
NC
9595 31 30-28 27-24 23-0
9596 -- ----- ----- ----
9597 1 0 index Data for personalityRoutine[index] */
9598
dda8d76d 9599 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9600 && (word & 0x70000000))
32ec8896
NC
9601 {
9602 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 9603 res = false;
32ec8896 9604 }
1b31d05e 9605
fa197c1c 9606 per_index = (word >> 24) & 0x7f;
1b31d05e 9607 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9608 if (per_index == 0)
9609 {
9610 more_words = 0;
9611 word <<= 8;
9612 remaining--;
9613 }
9614 else if (per_index < 3)
9615 {
9616 more_words = (word >> 16) & 0xff;
9617 word <<= 16;
9618 remaining -= 2;
9619 }
9620 }
9621
dda8d76d 9622 switch (filedata->file_header.e_machine)
fa197c1c
PB
9623 {
9624 case EM_ARM:
9625 if (per_index < 3)
9626 {
dda8d76d 9627 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 9628 data_offset, data_sec, data_arm_sec))
015dc7e1 9629 res = false;
fa197c1c
PB
9630 }
9631 else
1b31d05e
NC
9632 {
9633 warn (_("Unknown ARM compact model index encountered\n"));
9634 printf (_(" [reserved]\n"));
015dc7e1 9635 res = false;
1b31d05e 9636 }
fa197c1c
PB
9637 break;
9638
9639 case EM_TI_C6000:
9640 if (per_index < 3)
9641 {
dda8d76d 9642 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 9643 data_offset, data_sec, data_arm_sec))
015dc7e1 9644 res = false;
fa197c1c
PB
9645 }
9646 else if (per_index < 5)
9647 {
9648 if (((word >> 17) & 0x7f) == 0x7f)
9649 printf (_(" Restore stack from frame pointer\n"));
9650 else
9651 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9652 printf (_(" Registers restored: "));
9653 if (per_index == 4)
9654 printf (" (compact) ");
9655 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9656 putchar ('\n');
9657 printf (_(" Return register: %s\n"),
9658 tic6x_unwind_regnames[word & 0xf]);
9659 }
9660 else
1b31d05e 9661 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9662 break;
9663
9664 default:
74e1a04b 9665 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9666 filedata->file_header.e_machine);
015dc7e1 9667 res = false;
fa197c1c 9668 }
0b6ae522
DJ
9669
9670 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9671
9672 return res;
0b6ae522
DJ
9673}
9674
015dc7e1 9675static bool
dda8d76d
NC
9676dump_arm_unwind (Filedata * filedata,
9677 struct arm_unw_aux_info * aux,
9678 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9679{
9680 struct arm_section exidx_arm_sec, extab_arm_sec;
9681 unsigned int i, exidx_len;
948f632f 9682 unsigned long j, nfuns;
015dc7e1 9683 bool res = true;
0b6ae522
DJ
9684
9685 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9686 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9687 exidx_len = exidx_sec->sh_size / 8;
9688
948f632f
DA
9689 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9690 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9691 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9692 aux->funtab[nfuns++] = aux->symtab[j];
9693 aux->nfuns = nfuns;
9694 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9695
0b6ae522
DJ
9696 for (i = 0; i < exidx_len; i++)
9697 {
9698 unsigned int exidx_fn, exidx_entry;
9699 struct absaddr fn_addr, entry_addr;
9700 bfd_vma fn;
9701
9702 fputc ('\n', stdout);
9703
dda8d76d 9704 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9705 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9706 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9707 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9708 {
948f632f 9709 free (aux->funtab);
1b31d05e
NC
9710 arm_free_section (& exidx_arm_sec);
9711 arm_free_section (& extab_arm_sec);
015dc7e1 9712 return false;
0b6ae522
DJ
9713 }
9714
83c257ca
NC
9715 /* ARM EHABI, Section 5:
9716 An index table entry consists of 2 words.
9717 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9718 if (exidx_fn & 0x80000000)
32ec8896
NC
9719 {
9720 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 9721 res = false;
32ec8896 9722 }
83c257ca 9723
dda8d76d 9724 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9725
dda8d76d 9726 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9727 fputs (": ", stdout);
9728
9729 if (exidx_entry == 1)
9730 {
9731 print_vma (exidx_entry, PREFIX_HEX);
9732 fputs (" [cantunwind]\n", stdout);
9733 }
9734 else if (exidx_entry & 0x80000000)
9735 {
9736 print_vma (exidx_entry, PREFIX_HEX);
9737 fputc ('\n', stdout);
dda8d76d 9738 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9739 }
9740 else
9741 {
8f73510c 9742 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9743 Elf_Internal_Shdr *table_sec;
9744
9745 fputs ("@", stdout);
dda8d76d 9746 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9747 print_vma (table, PREFIX_HEX);
9748 printf ("\n");
9749
9750 /* Locate the matching .ARM.extab. */
9751 if (entry_addr.section != SHN_UNDEF
dda8d76d 9752 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9753 {
dda8d76d 9754 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9755 table_offset = entry_addr.offset;
1a915552
NC
9756 /* PR 18879 */
9757 if (table_offset > table_sec->sh_size
9758 || ((bfd_signed_vma) table_offset) < 0)
9759 {
9760 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9761 (unsigned long) table_offset,
dda8d76d 9762 printable_section_name (filedata, table_sec));
015dc7e1 9763 res = false;
1a915552
NC
9764 continue;
9765 }
0b6ae522
DJ
9766 }
9767 else
9768 {
dda8d76d 9769 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9770 if (table_sec != NULL)
9771 table_offset = table - table_sec->sh_addr;
9772 }
32ec8896 9773
0b6ae522
DJ
9774 if (table_sec == NULL)
9775 {
9776 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9777 (unsigned long) table);
015dc7e1 9778 res = false;
0b6ae522
DJ
9779 continue;
9780 }
32ec8896 9781
dda8d76d 9782 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 9783 &extab_arm_sec))
015dc7e1 9784 res = false;
0b6ae522
DJ
9785 }
9786 }
9787
9788 printf ("\n");
9789
948f632f 9790 free (aux->funtab);
0b6ae522
DJ
9791 arm_free_section (&exidx_arm_sec);
9792 arm_free_section (&extab_arm_sec);
32ec8896
NC
9793
9794 return res;
0b6ae522
DJ
9795}
9796
fa197c1c 9797/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9798
015dc7e1 9799static bool
dda8d76d 9800arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9801{
9802 struct arm_unw_aux_info aux;
9803 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9804 Elf_Internal_Shdr *sec;
9805 unsigned long i;
fa197c1c 9806 unsigned int sec_type;
015dc7e1 9807 bool res = true;
0b6ae522 9808
dda8d76d 9809 switch (filedata->file_header.e_machine)
fa197c1c
PB
9810 {
9811 case EM_ARM:
9812 sec_type = SHT_ARM_EXIDX;
9813 break;
9814
9815 case EM_TI_C6000:
9816 sec_type = SHT_C6000_UNWIND;
9817 break;
9818
0b4362b0 9819 default:
74e1a04b 9820 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9821 filedata->file_header.e_machine);
015dc7e1 9822 return false;
fa197c1c
PB
9823 }
9824
dda8d76d 9825 if (filedata->string_table == NULL)
015dc7e1 9826 return false;
1b31d05e
NC
9827
9828 memset (& aux, 0, sizeof (aux));
dda8d76d 9829 aux.filedata = filedata;
0b6ae522 9830
dda8d76d 9831 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9832 {
28d13567 9833 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9834 {
28d13567 9835 if (aux.symtab)
74e1a04b 9836 {
28d13567
AM
9837 error (_("Multiple symbol tables encountered\n"));
9838 free (aux.symtab);
9839 aux.symtab = NULL;
74e1a04b 9840 free (aux.strtab);
28d13567 9841 aux.strtab = NULL;
74e1a04b 9842 }
28d13567
AM
9843 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9844 &aux.strtab, &aux.strtab_size))
015dc7e1 9845 return false;
0b6ae522 9846 }
fa197c1c 9847 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9848 unwsec = sec;
9849 }
9850
1b31d05e 9851 if (unwsec == NULL)
0b6ae522 9852 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9853 else
dda8d76d 9854 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9855 {
9856 if (sec->sh_type == sec_type)
9857 {
d3a49aa8
AM
9858 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9859 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9860 "contains %lu entry:\n",
9861 "\nUnwind section '%s' at offset 0x%lx "
9862 "contains %lu entries:\n",
9863 num_unwind),
dda8d76d 9864 printable_section_name (filedata, sec),
1b31d05e 9865 (unsigned long) sec->sh_offset,
d3a49aa8 9866 num_unwind);
0b6ae522 9867
dda8d76d 9868 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 9869 res = false;
1b31d05e
NC
9870 }
9871 }
0b6ae522 9872
9db70fc3
AM
9873 free (aux.symtab);
9874 free ((char *) aux.strtab);
32ec8896
NC
9875
9876 return res;
0b6ae522
DJ
9877}
9878
3ecc00ec
NC
9879static bool
9880no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
9881{
9882 printf (_("No processor specific unwind information to decode\n"));
9883 return true;
9884}
9885
015dc7e1 9886static bool
dda8d76d 9887process_unwind (Filedata * filedata)
57346661 9888{
2cf0635d
NC
9889 struct unwind_handler
9890 {
32ec8896 9891 unsigned int machtype;
015dc7e1 9892 bool (* handler)(Filedata *);
2cf0635d
NC
9893 } handlers[] =
9894 {
0b6ae522 9895 { EM_ARM, arm_process_unwind },
57346661
AM
9896 { EM_IA_64, ia64_process_unwind },
9897 { EM_PARISC, hppa_process_unwind },
fa197c1c 9898 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
9899 { EM_386, no_processor_specific_unwind },
9900 { EM_X86_64, no_processor_specific_unwind },
32ec8896 9901 { 0, NULL }
57346661
AM
9902 };
9903 int i;
9904
9905 if (!do_unwind)
015dc7e1 9906 return true;
57346661
AM
9907
9908 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9909 if (filedata->file_header.e_machine == handlers[i].machtype)
9910 return handlers[i].handler (filedata);
57346661 9911
1b31d05e 9912 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9913 get_machine_name (filedata->file_header.e_machine));
015dc7e1 9914 return true;
57346661
AM
9915}
9916
37c18eed
SD
9917static void
9918dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
9919{
9920 switch (entry->d_tag)
9921 {
9922 case DT_AARCH64_BTI_PLT:
1dbade74 9923 case DT_AARCH64_PAC_PLT:
37c18eed
SD
9924 break;
9925 default:
9926 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9927 break;
9928 }
9929 putchar ('\n');
9930}
9931
252b5132 9932static void
978c4450 9933dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
9934{
9935 switch (entry->d_tag)
9936 {
9937 case DT_MIPS_FLAGS:
9938 if (entry->d_un.d_val == 0)
4b68bca3 9939 printf (_("NONE"));
252b5132
RH
9940 else
9941 {
9942 static const char * opts[] =
9943 {
9944 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9945 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9946 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9947 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9948 "RLD_ORDER_SAFE"
9949 };
9950 unsigned int cnt;
015dc7e1 9951 bool first = true;
2b692964 9952
60bca95a 9953 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9954 if (entry->d_un.d_val & (1 << cnt))
9955 {
9956 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 9957 first = false;
252b5132 9958 }
252b5132
RH
9959 }
9960 break;
103f02d3 9961
252b5132 9962 case DT_MIPS_IVERSION:
978c4450
AM
9963 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
9964 printf (_("Interface Version: %s"),
9965 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 9966 else
76ca31c0
NC
9967 {
9968 char buf[40];
9969 sprintf_vma (buf, entry->d_un.d_ptr);
9970 /* Note: coded this way so that there is a single string for translation. */
9971 printf (_("<corrupt: %s>"), buf);
9972 }
252b5132 9973 break;
103f02d3 9974
252b5132
RH
9975 case DT_MIPS_TIME_STAMP:
9976 {
d5b07ef4 9977 char timebuf[128];
2cf0635d 9978 struct tm * tmp;
91d6fa6a 9979 time_t atime = entry->d_un.d_val;
82b1b41b 9980
91d6fa6a 9981 tmp = gmtime (&atime);
82b1b41b
NC
9982 /* PR 17531: file: 6accc532. */
9983 if (tmp == NULL)
9984 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9985 else
9986 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9987 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9988 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9989 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9990 }
9991 break;
103f02d3 9992
252b5132
RH
9993 case DT_MIPS_RLD_VERSION:
9994 case DT_MIPS_LOCAL_GOTNO:
9995 case DT_MIPS_CONFLICTNO:
9996 case DT_MIPS_LIBLISTNO:
9997 case DT_MIPS_SYMTABNO:
9998 case DT_MIPS_UNREFEXTNO:
9999 case DT_MIPS_HIPAGENO:
10000 case DT_MIPS_DELTA_CLASS_NO:
10001 case DT_MIPS_DELTA_INSTANCE_NO:
10002 case DT_MIPS_DELTA_RELOC_NO:
10003 case DT_MIPS_DELTA_SYM_NO:
10004 case DT_MIPS_DELTA_CLASSSYM_NO:
10005 case DT_MIPS_COMPACT_SIZE:
c69075ac 10006 print_vma (entry->d_un.d_val, DEC);
252b5132 10007 break;
103f02d3 10008
f16a9783 10009 case DT_MIPS_XHASH:
978c4450
AM
10010 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10011 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10012 /* Falls through. */
10013
103f02d3 10014 default:
4b68bca3 10015 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10016 }
4b68bca3 10017 putchar ('\n');
103f02d3
UD
10018}
10019
103f02d3 10020static void
2cf0635d 10021dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10022{
10023 switch (entry->d_tag)
10024 {
10025 case DT_HP_DLD_FLAGS:
10026 {
10027 static struct
10028 {
10029 long int bit;
2cf0635d 10030 const char * str;
5e220199
NC
10031 }
10032 flags[] =
10033 {
10034 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10035 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10036 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10037 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10038 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10039 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10040 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10041 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10042 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10043 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10044 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10045 { DT_HP_GST, "HP_GST" },
10046 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10047 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10048 { DT_HP_NODELETE, "HP_NODELETE" },
10049 { DT_HP_GROUP, "HP_GROUP" },
10050 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10051 };
015dc7e1 10052 bool first = true;
5e220199 10053 size_t cnt;
f7a99963 10054 bfd_vma val = entry->d_un.d_val;
103f02d3 10055
60bca95a 10056 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10057 if (val & flags[cnt].bit)
30800947
NC
10058 {
10059 if (! first)
10060 putchar (' ');
10061 fputs (flags[cnt].str, stdout);
015dc7e1 10062 first = false;
30800947
NC
10063 val ^= flags[cnt].bit;
10064 }
76da6bbe 10065
103f02d3 10066 if (val != 0 || first)
f7a99963
NC
10067 {
10068 if (! first)
10069 putchar (' ');
10070 print_vma (val, HEX);
10071 }
103f02d3
UD
10072 }
10073 break;
76da6bbe 10074
252b5132 10075 default:
f7a99963
NC
10076 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10077 break;
252b5132 10078 }
35b1837e 10079 putchar ('\n');
252b5132
RH
10080}
10081
28f997cf
TG
10082#ifdef BFD64
10083
10084/* VMS vs Unix time offset and factor. */
10085
10086#define VMS_EPOCH_OFFSET 35067168000000000LL
10087#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10088#ifndef INT64_MIN
10089#define INT64_MIN (-9223372036854775807LL - 1)
10090#endif
28f997cf
TG
10091
10092/* Display a VMS time in a human readable format. */
10093
10094static void
10095print_vms_time (bfd_int64_t vmstime)
10096{
dccc31de 10097 struct tm *tm = NULL;
28f997cf
TG
10098 time_t unxtime;
10099
dccc31de
AM
10100 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10101 {
10102 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10103 unxtime = vmstime;
10104 if (unxtime == vmstime)
10105 tm = gmtime (&unxtime);
10106 }
10107 if (tm != NULL)
10108 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10109 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10110 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
10111}
10112#endif /* BFD64 */
10113
ecc51f48 10114static void
2cf0635d 10115dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10116{
10117 switch (entry->d_tag)
10118 {
0de14b54 10119 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10120 /* First 3 slots reserved. */
ecc51f48
NC
10121 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10122 printf (" -- ");
10123 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10124 break;
10125
28f997cf
TG
10126 case DT_IA_64_VMS_LINKTIME:
10127#ifdef BFD64
10128 print_vms_time (entry->d_un.d_val);
10129#endif
10130 break;
10131
10132 case DT_IA_64_VMS_LNKFLAGS:
10133 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10134 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10135 printf (" CALL_DEBUG");
10136 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10137 printf (" NOP0BUFS");
10138 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10139 printf (" P0IMAGE");
10140 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10141 printf (" MKTHREADS");
10142 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10143 printf (" UPCALLS");
10144 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10145 printf (" IMGSTA");
10146 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10147 printf (" INITIALIZE");
10148 if (entry->d_un.d_val & VMS_LF_MAIN)
10149 printf (" MAIN");
10150 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10151 printf (" EXE_INIT");
10152 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10153 printf (" TBK_IN_IMG");
10154 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10155 printf (" DBG_IN_IMG");
10156 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10157 printf (" TBK_IN_DSF");
10158 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10159 printf (" DBG_IN_DSF");
10160 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10161 printf (" SIGNATURES");
10162 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10163 printf (" REL_SEG_OFF");
10164 break;
10165
bdf4d63a
JJ
10166 default:
10167 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10168 break;
ecc51f48 10169 }
bdf4d63a 10170 putchar ('\n');
ecc51f48
NC
10171}
10172
015dc7e1 10173static bool
dda8d76d 10174get_32bit_dynamic_section (Filedata * filedata)
252b5132 10175{
2cf0635d
NC
10176 Elf32_External_Dyn * edyn;
10177 Elf32_External_Dyn * ext;
10178 Elf_Internal_Dyn * entry;
103f02d3 10179
978c4450
AM
10180 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10181 filedata->dynamic_addr, 1,
10182 filedata->dynamic_size,
10183 _("dynamic section"));
a6e9f9df 10184 if (!edyn)
015dc7e1 10185 return false;
103f02d3 10186
071436c6
NC
10187 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10188 might not have the luxury of section headers. Look for the DT_NULL
10189 terminator to determine the number of entries. */
978c4450
AM
10190 for (ext = edyn, filedata->dynamic_nent = 0;
10191 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10192 ext++)
10193 {
978c4450 10194 filedata->dynamic_nent++;
ba2685cc
AM
10195 if (BYTE_GET (ext->d_tag) == DT_NULL)
10196 break;
10197 }
252b5132 10198
978c4450
AM
10199 filedata->dynamic_section
10200 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10201 if (filedata->dynamic_section == NULL)
252b5132 10202 {
8b73c356 10203 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10204 (unsigned long) filedata->dynamic_nent);
9ea033b2 10205 free (edyn);
015dc7e1 10206 return false;
9ea033b2 10207 }
252b5132 10208
978c4450
AM
10209 for (ext = edyn, entry = filedata->dynamic_section;
10210 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10211 ext++, entry++)
9ea033b2 10212 {
fb514b26
AM
10213 entry->d_tag = BYTE_GET (ext->d_tag);
10214 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10215 }
10216
9ea033b2
NC
10217 free (edyn);
10218
015dc7e1 10219 return true;
9ea033b2
NC
10220}
10221
015dc7e1 10222static bool
dda8d76d 10223get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10224{
2cf0635d
NC
10225 Elf64_External_Dyn * edyn;
10226 Elf64_External_Dyn * ext;
10227 Elf_Internal_Dyn * entry;
103f02d3 10228
071436c6 10229 /* Read in the data. */
978c4450
AM
10230 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10231 filedata->dynamic_addr, 1,
10232 filedata->dynamic_size,
10233 _("dynamic section"));
a6e9f9df 10234 if (!edyn)
015dc7e1 10235 return false;
103f02d3 10236
071436c6
NC
10237 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10238 might not have the luxury of section headers. Look for the DT_NULL
10239 terminator to determine the number of entries. */
978c4450 10240 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10241 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10242 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10243 ext++)
10244 {
978c4450 10245 filedata->dynamic_nent++;
66543521 10246 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10247 break;
10248 }
252b5132 10249
978c4450
AM
10250 filedata->dynamic_section
10251 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10252 if (filedata->dynamic_section == NULL)
252b5132 10253 {
8b73c356 10254 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10255 (unsigned long) filedata->dynamic_nent);
252b5132 10256 free (edyn);
015dc7e1 10257 return false;
252b5132
RH
10258 }
10259
071436c6 10260 /* Convert from external to internal formats. */
978c4450
AM
10261 for (ext = edyn, entry = filedata->dynamic_section;
10262 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10263 ext++, entry++)
252b5132 10264 {
66543521
AM
10265 entry->d_tag = BYTE_GET (ext->d_tag);
10266 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10267 }
10268
10269 free (edyn);
10270
015dc7e1 10271 return true;
9ea033b2
NC
10272}
10273
4de91c10
AM
10274static bool
10275get_dynamic_section (Filedata *filedata)
10276{
10277 if (filedata->dynamic_section)
10278 return true;
10279
10280 if (is_32bit_elf)
10281 return get_32bit_dynamic_section (filedata);
10282 else
10283 return get_64bit_dynamic_section (filedata);
10284}
10285
e9e44622
JJ
10286static void
10287print_dynamic_flags (bfd_vma flags)
d1133906 10288{
015dc7e1 10289 bool first = true;
13ae64f3 10290
d1133906
NC
10291 while (flags)
10292 {
10293 bfd_vma flag;
10294
10295 flag = flags & - flags;
10296 flags &= ~ flag;
10297
e9e44622 10298 if (first)
015dc7e1 10299 first = false;
e9e44622
JJ
10300 else
10301 putc (' ', stdout);
13ae64f3 10302
d1133906
NC
10303 switch (flag)
10304 {
e9e44622
JJ
10305 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10306 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10307 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10308 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10309 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10310 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10311 }
10312 }
e9e44622 10313 puts ("");
d1133906
NC
10314}
10315
10ca4b04
L
10316static bfd_vma *
10317get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10318{
10319 unsigned char * e_data;
10320 bfd_vma * i_data;
10321
10322 /* If the size_t type is smaller than the bfd_size_type, eg because
10323 you are building a 32-bit tool on a 64-bit host, then make sure
10324 that when (number) is cast to (size_t) no information is lost. */
10325 if (sizeof (size_t) < sizeof (bfd_size_type)
10326 && (bfd_size_type) ((size_t) number) != number)
10327 {
10328 error (_("Size truncation prevents reading %s elements of size %u\n"),
10329 bfd_vmatoa ("u", number), ent_size);
10330 return NULL;
10331 }
10332
10333 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10334 attempting to allocate memory when the read is bound to fail. */
10335 if (ent_size * number > filedata->file_size)
10336 {
10337 error (_("Invalid number of dynamic entries: %s\n"),
10338 bfd_vmatoa ("u", number));
10339 return NULL;
10340 }
10341
10342 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10343 if (e_data == NULL)
10344 {
10345 error (_("Out of memory reading %s dynamic entries\n"),
10346 bfd_vmatoa ("u", number));
10347 return NULL;
10348 }
10349
10350 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10351 {
10352 error (_("Unable to read in %s bytes of dynamic data\n"),
10353 bfd_vmatoa ("u", number * ent_size));
10354 free (e_data);
10355 return NULL;
10356 }
10357
10358 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10359 if (i_data == NULL)
10360 {
10361 error (_("Out of memory allocating space for %s dynamic entries\n"),
10362 bfd_vmatoa ("u", number));
10363 free (e_data);
10364 return NULL;
10365 }
10366
10367 while (number--)
10368 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10369
10370 free (e_data);
10371
10372 return i_data;
10373}
10374
10375static unsigned long
10376get_num_dynamic_syms (Filedata * filedata)
10377{
10378 unsigned long num_of_syms = 0;
10379
10380 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10381 return num_of_syms;
10382
978c4450 10383 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10384 {
10385 unsigned char nb[8];
10386 unsigned char nc[8];
10387 unsigned int hash_ent_size = 4;
10388
10389 if ((filedata->file_header.e_machine == EM_ALPHA
10390 || filedata->file_header.e_machine == EM_S390
10391 || filedata->file_header.e_machine == EM_S390_OLD)
10392 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10393 hash_ent_size = 8;
10394
10395 if (fseek (filedata->handle,
978c4450
AM
10396 (filedata->archive_file_offset
10397 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10398 sizeof nb + sizeof nc)),
10399 SEEK_SET))
10400 {
10401 error (_("Unable to seek to start of dynamic information\n"));
10402 goto no_hash;
10403 }
10404
10405 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10406 {
10407 error (_("Failed to read in number of buckets\n"));
10408 goto no_hash;
10409 }
10410
10411 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10412 {
10413 error (_("Failed to read in number of chains\n"));
10414 goto no_hash;
10415 }
10416
978c4450
AM
10417 filedata->nbuckets = byte_get (nb, hash_ent_size);
10418 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10419
2482f306
AM
10420 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10421 {
10422 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10423 hash_ent_size);
10424 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10425 hash_ent_size);
001890e1 10426
2482f306
AM
10427 if (filedata->buckets != NULL && filedata->chains != NULL)
10428 num_of_syms = filedata->nchains;
10429 }
ceb9bf11 10430 no_hash:
10ca4b04
L
10431 if (num_of_syms == 0)
10432 {
9db70fc3
AM
10433 free (filedata->buckets);
10434 filedata->buckets = NULL;
10435 free (filedata->chains);
10436 filedata->chains = NULL;
978c4450 10437 filedata->nbuckets = 0;
10ca4b04
L
10438 }
10439 }
10440
978c4450 10441 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10442 {
10443 unsigned char nb[16];
10444 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10445 bfd_vma buckets_vma;
10446 unsigned long hn;
10ca4b04
L
10447
10448 if (fseek (filedata->handle,
978c4450
AM
10449 (filedata->archive_file_offset
10450 + offset_from_vma (filedata,
10451 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10452 sizeof nb)),
10453 SEEK_SET))
10454 {
10455 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10456 goto no_gnu_hash;
10457 }
10458
10459 if (fread (nb, 16, 1, filedata->handle) != 1)
10460 {
10461 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10462 goto no_gnu_hash;
10463 }
10464
978c4450
AM
10465 filedata->ngnubuckets = byte_get (nb, 4);
10466 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10467 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10468 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10469 if (is_32bit_elf)
10470 buckets_vma += bitmaskwords * 4;
10471 else
10472 buckets_vma += bitmaskwords * 8;
10473
10474 if (fseek (filedata->handle,
978c4450 10475 (filedata->archive_file_offset
10ca4b04
L
10476 + offset_from_vma (filedata, buckets_vma, 4)),
10477 SEEK_SET))
10478 {
10479 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10480 goto no_gnu_hash;
10481 }
10482
978c4450
AM
10483 filedata->gnubuckets
10484 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10485
978c4450 10486 if (filedata->gnubuckets == NULL)
90837ea7 10487 goto no_gnu_hash;
10ca4b04 10488
978c4450
AM
10489 for (i = 0; i < filedata->ngnubuckets; i++)
10490 if (filedata->gnubuckets[i] != 0)
10ca4b04 10491 {
978c4450 10492 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10493 goto no_gnu_hash;
10ca4b04 10494
978c4450
AM
10495 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10496 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10497 }
10498
10499 if (maxchain == 0xffffffff)
90837ea7 10500 goto no_gnu_hash;
10ca4b04 10501
978c4450 10502 maxchain -= filedata->gnusymidx;
10ca4b04
L
10503
10504 if (fseek (filedata->handle,
978c4450
AM
10505 (filedata->archive_file_offset
10506 + offset_from_vma (filedata,
10507 buckets_vma + 4 * (filedata->ngnubuckets
10508 + maxchain),
10509 4)),
10ca4b04
L
10510 SEEK_SET))
10511 {
10512 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10513 goto no_gnu_hash;
10514 }
10515
10516 do
10517 {
10518 if (fread (nb, 4, 1, filedata->handle) != 1)
10519 {
10520 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10521 goto no_gnu_hash;
10522 }
10523
10524 if (maxchain + 1 == 0)
90837ea7 10525 goto no_gnu_hash;
10ca4b04
L
10526
10527 ++maxchain;
10528 }
10529 while ((byte_get (nb, 4) & 1) == 0);
10530
10531 if (fseek (filedata->handle,
978c4450
AM
10532 (filedata->archive_file_offset
10533 + offset_from_vma (filedata, (buckets_vma
10534 + 4 * filedata->ngnubuckets),
10535 4)),
10ca4b04
L
10536 SEEK_SET))
10537 {
10538 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10539 goto no_gnu_hash;
10540 }
10541
978c4450
AM
10542 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10543 filedata->ngnuchains = maxchain;
10ca4b04 10544
978c4450 10545 if (filedata->gnuchains == NULL)
90837ea7 10546 goto no_gnu_hash;
10ca4b04 10547
978c4450 10548 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10549 {
10550 if (fseek (filedata->handle,
978c4450 10551 (filedata->archive_file_offset
10ca4b04 10552 + offset_from_vma (filedata, (buckets_vma
978c4450 10553 + 4 * (filedata->ngnubuckets
10ca4b04
L
10554 + maxchain)), 4)),
10555 SEEK_SET))
10556 {
10557 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10558 goto no_gnu_hash;
10559 }
10560
978c4450 10561 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10562 if (filedata->mipsxlat == NULL)
10563 goto no_gnu_hash;
10ca4b04
L
10564 }
10565
978c4450
AM
10566 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10567 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10568 {
978c4450
AM
10569 bfd_vma si = filedata->gnubuckets[hn];
10570 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10571
10572 do
10573 {
978c4450 10574 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 10575 {
c31ab5a0
AM
10576 if (off < filedata->ngnuchains
10577 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 10578 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
10579 }
10580 else
10581 {
10582 if (si >= num_of_syms)
10583 num_of_syms = si + 1;
10584 }
10585 si++;
10586 }
978c4450
AM
10587 while (off < filedata->ngnuchains
10588 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
10589 }
10590
90837ea7 10591 if (num_of_syms == 0)
10ca4b04 10592 {
90837ea7 10593 no_gnu_hash:
9db70fc3
AM
10594 free (filedata->mipsxlat);
10595 filedata->mipsxlat = NULL;
10596 free (filedata->gnuchains);
10597 filedata->gnuchains = NULL;
10598 free (filedata->gnubuckets);
10599 filedata->gnubuckets = NULL;
978c4450
AM
10600 filedata->ngnubuckets = 0;
10601 filedata->ngnuchains = 0;
10ca4b04
L
10602 }
10603 }
10604
10605 return num_of_syms;
10606}
10607
b2d38a17
NC
10608/* Parse and display the contents of the dynamic section. */
10609
015dc7e1 10610static bool
dda8d76d 10611process_dynamic_section (Filedata * filedata)
9ea033b2 10612{
2cf0635d 10613 Elf_Internal_Dyn * entry;
9ea033b2 10614
978c4450 10615 if (filedata->dynamic_size == 0)
9ea033b2
NC
10616 {
10617 if (do_dynamic)
ca0e11aa
NC
10618 {
10619 if (filedata->is_separate)
10620 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
10621 filedata->file_name);
10622 else
10623 printf (_("\nThere is no dynamic section in this file.\n"));
10624 }
9ea033b2 10625
015dc7e1 10626 return true;
9ea033b2
NC
10627 }
10628
4de91c10
AM
10629 if (!get_dynamic_section (filedata))
10630 return false;
9ea033b2 10631
252b5132 10632 /* Find the appropriate symbol table. */
978c4450 10633 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 10634 {
2482f306
AM
10635 unsigned long num_of_syms;
10636
978c4450
AM
10637 for (entry = filedata->dynamic_section;
10638 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10639 ++entry)
10ca4b04 10640 if (entry->d_tag == DT_SYMTAB)
978c4450 10641 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 10642 else if (entry->d_tag == DT_SYMENT)
978c4450 10643 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 10644 else if (entry->d_tag == DT_HASH)
978c4450 10645 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 10646 else if (entry->d_tag == DT_GNU_HASH)
978c4450 10647 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
10648 else if ((filedata->file_header.e_machine == EM_MIPS
10649 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10650 && entry->d_tag == DT_MIPS_XHASH)
10651 {
978c4450
AM
10652 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10653 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 10654 }
252b5132 10655
2482f306
AM
10656 num_of_syms = get_num_dynamic_syms (filedata);
10657
10658 if (num_of_syms != 0
10659 && filedata->dynamic_symbols == NULL
10660 && filedata->dynamic_info[DT_SYMTAB]
978c4450 10661 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
10662 {
10663 Elf_Internal_Phdr *seg;
2482f306 10664 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 10665
2482f306
AM
10666 if (! get_program_headers (filedata))
10667 {
10668 error (_("Cannot interpret virtual addresses "
10669 "without program headers.\n"));
015dc7e1 10670 return false;
2482f306 10671 }
252b5132 10672
2482f306
AM
10673 for (seg = filedata->program_headers;
10674 seg < filedata->program_headers + filedata->file_header.e_phnum;
10675 ++seg)
10676 {
10677 if (seg->p_type != PT_LOAD)
10678 continue;
252b5132 10679
2482f306
AM
10680 if (seg->p_offset + seg->p_filesz > filedata->file_size)
10681 {
10682 /* See PR 21379 for a reproducer. */
10683 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 10684 return false;
2482f306 10685 }
252b5132 10686
2482f306
AM
10687 if (vma >= (seg->p_vaddr & -seg->p_align)
10688 && vma < seg->p_vaddr + seg->p_filesz)
10689 {
10690 /* Since we do not know how big the symbol table is,
10691 we default to reading in up to the end of PT_LOAD
10692 segment and processing that. This is overkill, I
10693 know, but it should work. */
10694 Elf_Internal_Shdr section;
10695 section.sh_offset = (vma - seg->p_vaddr
10696 + seg->p_offset);
10697 section.sh_size = (num_of_syms
10698 * filedata->dynamic_info[DT_SYMENT]);
10699 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
10700
10701 if (do_checks
10702 && filedata->dynamic_symtab_section != NULL
10703 && ((filedata->dynamic_symtab_section->sh_offset
10704 != section.sh_offset)
10705 || (filedata->dynamic_symtab_section->sh_size
10706 != section.sh_size)
10707 || (filedata->dynamic_symtab_section->sh_entsize
10708 != section.sh_entsize)))
10709 warn (_("\
10710the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
10711
2482f306
AM
10712 section.sh_name = filedata->string_table_length;
10713 filedata->dynamic_symbols
4de91c10 10714 = get_elf_symbols (filedata, &section,
2482f306
AM
10715 &filedata->num_dynamic_syms);
10716 if (filedata->dynamic_symbols == NULL
10717 || filedata->num_dynamic_syms != num_of_syms)
10718 {
10719 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 10720 return false;
2482f306
AM
10721 }
10722 break;
10723 }
10724 }
10725 }
10726 }
252b5132
RH
10727
10728 /* Similarly find a string table. */
978c4450
AM
10729 if (filedata->dynamic_strings == NULL)
10730 for (entry = filedata->dynamic_section;
10731 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
10732 ++entry)
10733 {
10734 if (entry->d_tag == DT_STRTAB)
978c4450 10735 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 10736
10ca4b04 10737 if (entry->d_tag == DT_STRSZ)
978c4450 10738 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10739
978c4450
AM
10740 if (filedata->dynamic_info[DT_STRTAB]
10741 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
10742 {
10743 unsigned long offset;
978c4450 10744 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
10745
10746 offset = offset_from_vma (filedata,
978c4450 10747 filedata->dynamic_info[DT_STRTAB],
10ca4b04 10748 str_tab_len);
8ac10c5b
L
10749 if (do_checks
10750 && filedata->dynamic_strtab_section
10751 && ((filedata->dynamic_strtab_section->sh_offset
10752 != (file_ptr) offset)
10753 || (filedata->dynamic_strtab_section->sh_size
10754 != str_tab_len)))
10755 warn (_("\
10756the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
10757
978c4450
AM
10758 filedata->dynamic_strings
10759 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
10760 _("dynamic string table"));
10761 if (filedata->dynamic_strings == NULL)
10ca4b04
L
10762 {
10763 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10764 break;
10765 }
e3d39609 10766
978c4450 10767 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
10768 break;
10769 }
10770 }
252b5132
RH
10771
10772 /* And find the syminfo section if available. */
978c4450 10773 if (filedata->dynamic_syminfo == NULL)
252b5132 10774 {
3e8bba36 10775 unsigned long syminsz = 0;
252b5132 10776
978c4450
AM
10777 for (entry = filedata->dynamic_section;
10778 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10779 ++entry)
252b5132
RH
10780 {
10781 if (entry->d_tag == DT_SYMINENT)
10782 {
10783 /* Note: these braces are necessary to avoid a syntax
10784 error from the SunOS4 C compiler. */
049b0c3a
NC
10785 /* PR binutils/17531: A corrupt file can trigger this test.
10786 So do not use an assert, instead generate an error message. */
10787 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10788 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10789 (int) entry->d_un.d_val);
252b5132
RH
10790 }
10791 else if (entry->d_tag == DT_SYMINSZ)
10792 syminsz = entry->d_un.d_val;
10793 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
10794 filedata->dynamic_syminfo_offset
10795 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
10796 }
10797
978c4450 10798 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 10799 {
2cf0635d
NC
10800 Elf_External_Syminfo * extsyminfo;
10801 Elf_External_Syminfo * extsym;
10802 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10803
10804 /* There is a syminfo section. Read the data. */
3f5e193b 10805 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
10806 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
10807 1, syminsz, _("symbol information"));
a6e9f9df 10808 if (!extsyminfo)
015dc7e1 10809 return false;
252b5132 10810
978c4450 10811 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
10812 {
10813 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 10814 free (filedata->dynamic_syminfo);
e3d39609 10815 }
978c4450
AM
10816 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
10817 if (filedata->dynamic_syminfo == NULL)
252b5132 10818 {
2482f306
AM
10819 error (_("Out of memory allocating %lu bytes "
10820 "for dynamic symbol info\n"),
8b73c356 10821 (unsigned long) syminsz);
015dc7e1 10822 return false;
252b5132
RH
10823 }
10824
2482f306
AM
10825 filedata->dynamic_syminfo_nent
10826 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 10827 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
10828 syminfo < (filedata->dynamic_syminfo
10829 + filedata->dynamic_syminfo_nent);
86dba8ee 10830 ++syminfo, ++extsym)
252b5132 10831 {
86dba8ee
AM
10832 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10833 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10834 }
10835
10836 free (extsyminfo);
10837 }
10838 }
10839
978c4450 10840 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa
NC
10841 {
10842 if (filedata->dynamic_nent == 1)
10843 {
10844 if (filedata->is_separate)
10845 printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains 1 entry:\n"),
10846 filedata->file_name,
10847 filedata->dynamic_addr);
10848 else
10849 printf (_("\nDynamic section at offset 0x%lx contains 1 entry:\n"),
10850 filedata->dynamic_addr);
10851 }
10852 else
10853 {
10854 if (filedata->is_separate)
10855 printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n"),
10856 filedata->file_name,
10857 filedata->dynamic_addr,
10858 (unsigned long) filedata->dynamic_nent);
10859 else
10860 printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
10861 filedata->dynamic_addr,
10862 (unsigned long) filedata->dynamic_nent);
10863 }
10864 }
252b5132
RH
10865 if (do_dynamic)
10866 printf (_(" Tag Type Name/Value\n"));
10867
978c4450
AM
10868 for (entry = filedata->dynamic_section;
10869 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10870 entry++)
252b5132
RH
10871 {
10872 if (do_dynamic)
f7a99963 10873 {
2cf0635d 10874 const char * dtype;
e699b9ff 10875
f7a99963
NC
10876 putchar (' ');
10877 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10878 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10879 printf (" (%s)%*s", dtype,
32ec8896 10880 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10881 }
252b5132
RH
10882
10883 switch (entry->d_tag)
10884 {
d1133906
NC
10885 case DT_FLAGS:
10886 if (do_dynamic)
e9e44622 10887 print_dynamic_flags (entry->d_un.d_val);
d1133906 10888 break;
76da6bbe 10889
252b5132
RH
10890 case DT_AUXILIARY:
10891 case DT_FILTER:
019148e4
L
10892 case DT_CONFIG:
10893 case DT_DEPAUDIT:
10894 case DT_AUDIT:
252b5132
RH
10895 if (do_dynamic)
10896 {
019148e4 10897 switch (entry->d_tag)
b34976b6 10898 {
019148e4
L
10899 case DT_AUXILIARY:
10900 printf (_("Auxiliary library"));
10901 break;
10902
10903 case DT_FILTER:
10904 printf (_("Filter library"));
10905 break;
10906
b34976b6 10907 case DT_CONFIG:
019148e4
L
10908 printf (_("Configuration file"));
10909 break;
10910
10911 case DT_DEPAUDIT:
10912 printf (_("Dependency audit library"));
10913 break;
10914
10915 case DT_AUDIT:
10916 printf (_("Audit library"));
10917 break;
10918 }
252b5132 10919
978c4450
AM
10920 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10921 printf (": [%s]\n",
10922 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 10923 else
f7a99963
NC
10924 {
10925 printf (": ");
10926 print_vma (entry->d_un.d_val, PREFIX_HEX);
10927 putchar ('\n');
10928 }
252b5132
RH
10929 }
10930 break;
10931
dcefbbbd 10932 case DT_FEATURE:
252b5132
RH
10933 if (do_dynamic)
10934 {
10935 printf (_("Flags:"));
86f55779 10936
252b5132
RH
10937 if (entry->d_un.d_val == 0)
10938 printf (_(" None\n"));
10939 else
10940 {
10941 unsigned long int val = entry->d_un.d_val;
86f55779 10942
252b5132
RH
10943 if (val & DTF_1_PARINIT)
10944 {
10945 printf (" PARINIT");
10946 val ^= DTF_1_PARINIT;
10947 }
dcefbbbd
L
10948 if (val & DTF_1_CONFEXP)
10949 {
10950 printf (" CONFEXP");
10951 val ^= DTF_1_CONFEXP;
10952 }
252b5132
RH
10953 if (val != 0)
10954 printf (" %lx", val);
10955 puts ("");
10956 }
10957 }
10958 break;
10959
10960 case DT_POSFLAG_1:
10961 if (do_dynamic)
10962 {
10963 printf (_("Flags:"));
86f55779 10964
252b5132
RH
10965 if (entry->d_un.d_val == 0)
10966 printf (_(" None\n"));
10967 else
10968 {
10969 unsigned long int val = entry->d_un.d_val;
86f55779 10970
252b5132
RH
10971 if (val & DF_P1_LAZYLOAD)
10972 {
10973 printf (" LAZYLOAD");
10974 val ^= DF_P1_LAZYLOAD;
10975 }
10976 if (val & DF_P1_GROUPPERM)
10977 {
10978 printf (" GROUPPERM");
10979 val ^= DF_P1_GROUPPERM;
10980 }
10981 if (val != 0)
10982 printf (" %lx", val);
10983 puts ("");
10984 }
10985 }
10986 break;
10987
10988 case DT_FLAGS_1:
10989 if (do_dynamic)
10990 {
10991 printf (_("Flags:"));
10992 if (entry->d_un.d_val == 0)
10993 printf (_(" None\n"));
10994 else
10995 {
10996 unsigned long int val = entry->d_un.d_val;
86f55779 10997
252b5132
RH
10998 if (val & DF_1_NOW)
10999 {
11000 printf (" NOW");
11001 val ^= DF_1_NOW;
11002 }
11003 if (val & DF_1_GLOBAL)
11004 {
11005 printf (" GLOBAL");
11006 val ^= DF_1_GLOBAL;
11007 }
11008 if (val & DF_1_GROUP)
11009 {
11010 printf (" GROUP");
11011 val ^= DF_1_GROUP;
11012 }
11013 if (val & DF_1_NODELETE)
11014 {
11015 printf (" NODELETE");
11016 val ^= DF_1_NODELETE;
11017 }
11018 if (val & DF_1_LOADFLTR)
11019 {
11020 printf (" LOADFLTR");
11021 val ^= DF_1_LOADFLTR;
11022 }
11023 if (val & DF_1_INITFIRST)
11024 {
11025 printf (" INITFIRST");
11026 val ^= DF_1_INITFIRST;
11027 }
11028 if (val & DF_1_NOOPEN)
11029 {
11030 printf (" NOOPEN");
11031 val ^= DF_1_NOOPEN;
11032 }
11033 if (val & DF_1_ORIGIN)
11034 {
11035 printf (" ORIGIN");
11036 val ^= DF_1_ORIGIN;
11037 }
11038 if (val & DF_1_DIRECT)
11039 {
11040 printf (" DIRECT");
11041 val ^= DF_1_DIRECT;
11042 }
11043 if (val & DF_1_TRANS)
11044 {
11045 printf (" TRANS");
11046 val ^= DF_1_TRANS;
11047 }
11048 if (val & DF_1_INTERPOSE)
11049 {
11050 printf (" INTERPOSE");
11051 val ^= DF_1_INTERPOSE;
11052 }
f7db6139 11053 if (val & DF_1_NODEFLIB)
dcefbbbd 11054 {
f7db6139
L
11055 printf (" NODEFLIB");
11056 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11057 }
11058 if (val & DF_1_NODUMP)
11059 {
11060 printf (" NODUMP");
11061 val ^= DF_1_NODUMP;
11062 }
34b60028 11063 if (val & DF_1_CONFALT)
dcefbbbd 11064 {
34b60028
L
11065 printf (" CONFALT");
11066 val ^= DF_1_CONFALT;
11067 }
11068 if (val & DF_1_ENDFILTEE)
11069 {
11070 printf (" ENDFILTEE");
11071 val ^= DF_1_ENDFILTEE;
11072 }
11073 if (val & DF_1_DISPRELDNE)
11074 {
11075 printf (" DISPRELDNE");
11076 val ^= DF_1_DISPRELDNE;
11077 }
11078 if (val & DF_1_DISPRELPND)
11079 {
11080 printf (" DISPRELPND");
11081 val ^= DF_1_DISPRELPND;
11082 }
11083 if (val & DF_1_NODIRECT)
11084 {
11085 printf (" NODIRECT");
11086 val ^= DF_1_NODIRECT;
11087 }
11088 if (val & DF_1_IGNMULDEF)
11089 {
11090 printf (" IGNMULDEF");
11091 val ^= DF_1_IGNMULDEF;
11092 }
11093 if (val & DF_1_NOKSYMS)
11094 {
11095 printf (" NOKSYMS");
11096 val ^= DF_1_NOKSYMS;
11097 }
11098 if (val & DF_1_NOHDR)
11099 {
11100 printf (" NOHDR");
11101 val ^= DF_1_NOHDR;
11102 }
11103 if (val & DF_1_EDITED)
11104 {
11105 printf (" EDITED");
11106 val ^= DF_1_EDITED;
11107 }
11108 if (val & DF_1_NORELOC)
11109 {
11110 printf (" NORELOC");
11111 val ^= DF_1_NORELOC;
11112 }
11113 if (val & DF_1_SYMINTPOSE)
11114 {
11115 printf (" SYMINTPOSE");
11116 val ^= DF_1_SYMINTPOSE;
11117 }
11118 if (val & DF_1_GLOBAUDIT)
11119 {
11120 printf (" GLOBAUDIT");
11121 val ^= DF_1_GLOBAUDIT;
11122 }
11123 if (val & DF_1_SINGLETON)
11124 {
11125 printf (" SINGLETON");
11126 val ^= DF_1_SINGLETON;
dcefbbbd 11127 }
5c383f02
RO
11128 if (val & DF_1_STUB)
11129 {
11130 printf (" STUB");
11131 val ^= DF_1_STUB;
11132 }
11133 if (val & DF_1_PIE)
11134 {
11135 printf (" PIE");
11136 val ^= DF_1_PIE;
11137 }
b1202ffa
L
11138 if (val & DF_1_KMOD)
11139 {
11140 printf (" KMOD");
11141 val ^= DF_1_KMOD;
11142 }
11143 if (val & DF_1_WEAKFILTER)
11144 {
11145 printf (" WEAKFILTER");
11146 val ^= DF_1_WEAKFILTER;
11147 }
11148 if (val & DF_1_NOCOMMON)
11149 {
11150 printf (" NOCOMMON");
11151 val ^= DF_1_NOCOMMON;
11152 }
252b5132
RH
11153 if (val != 0)
11154 printf (" %lx", val);
11155 puts ("");
11156 }
11157 }
11158 break;
11159
11160 case DT_PLTREL:
978c4450 11161 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11162 if (do_dynamic)
dda8d76d 11163 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11164 break;
11165
11166 case DT_NULL :
11167 case DT_NEEDED :
11168 case DT_PLTGOT :
11169 case DT_HASH :
11170 case DT_STRTAB :
11171 case DT_SYMTAB :
11172 case DT_RELA :
11173 case DT_INIT :
11174 case DT_FINI :
11175 case DT_SONAME :
11176 case DT_RPATH :
11177 case DT_SYMBOLIC:
11178 case DT_REL :
11179 case DT_DEBUG :
11180 case DT_TEXTREL :
11181 case DT_JMPREL :
019148e4 11182 case DT_RUNPATH :
978c4450 11183 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11184
11185 if (do_dynamic)
11186 {
2cf0635d 11187 char * name;
252b5132 11188
978c4450
AM
11189 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
11190 name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11191 else
d79b3d50 11192 name = NULL;
252b5132
RH
11193
11194 if (name)
11195 {
11196 switch (entry->d_tag)
11197 {
11198 case DT_NEEDED:
11199 printf (_("Shared library: [%s]"), name);
11200
13acb58d
AM
11201 if (filedata->program_interpreter
11202 && streq (name, filedata->program_interpreter))
f7a99963 11203 printf (_(" program interpreter"));
252b5132
RH
11204 break;
11205
11206 case DT_SONAME:
f7a99963 11207 printf (_("Library soname: [%s]"), name);
252b5132
RH
11208 break;
11209
11210 case DT_RPATH:
f7a99963 11211 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11212 break;
11213
019148e4
L
11214 case DT_RUNPATH:
11215 printf (_("Library runpath: [%s]"), name);
11216 break;
11217
252b5132 11218 default:
f7a99963
NC
11219 print_vma (entry->d_un.d_val, PREFIX_HEX);
11220 break;
252b5132
RH
11221 }
11222 }
11223 else
f7a99963
NC
11224 print_vma (entry->d_un.d_val, PREFIX_HEX);
11225
11226 putchar ('\n');
252b5132
RH
11227 }
11228 break;
11229
11230 case DT_PLTRELSZ:
11231 case DT_RELASZ :
11232 case DT_STRSZ :
11233 case DT_RELSZ :
11234 case DT_RELAENT :
11235 case DT_SYMENT :
11236 case DT_RELENT :
978c4450 11237 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11238 /* Fall through. */
252b5132
RH
11239 case DT_PLTPADSZ:
11240 case DT_MOVEENT :
11241 case DT_MOVESZ :
11242 case DT_INIT_ARRAYSZ:
11243 case DT_FINI_ARRAYSZ:
047b2264
JJ
11244 case DT_GNU_CONFLICTSZ:
11245 case DT_GNU_LIBLISTSZ:
252b5132 11246 if (do_dynamic)
f7a99963
NC
11247 {
11248 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11249 printf (_(" (bytes)\n"));
f7a99963 11250 }
252b5132
RH
11251 break;
11252
11253 case DT_VERDEFNUM:
11254 case DT_VERNEEDNUM:
11255 case DT_RELACOUNT:
11256 case DT_RELCOUNT:
11257 if (do_dynamic)
f7a99963
NC
11258 {
11259 print_vma (entry->d_un.d_val, UNSIGNED);
11260 putchar ('\n');
11261 }
252b5132
RH
11262 break;
11263
11264 case DT_SYMINSZ:
11265 case DT_SYMINENT:
11266 case DT_SYMINFO:
11267 case DT_USED:
11268 case DT_INIT_ARRAY:
11269 case DT_FINI_ARRAY:
11270 if (do_dynamic)
11271 {
d79b3d50 11272 if (entry->d_tag == DT_USED
978c4450 11273 && VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
252b5132 11274 {
978c4450 11275 char * name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11276
b34976b6 11277 if (*name)
252b5132
RH
11278 {
11279 printf (_("Not needed object: [%s]\n"), name);
11280 break;
11281 }
11282 }
103f02d3 11283
f7a99963
NC
11284 print_vma (entry->d_un.d_val, PREFIX_HEX);
11285 putchar ('\n');
252b5132
RH
11286 }
11287 break;
11288
11289 case DT_BIND_NOW:
11290 /* The value of this entry is ignored. */
35b1837e
AM
11291 if (do_dynamic)
11292 putchar ('\n');
252b5132 11293 break;
103f02d3 11294
047b2264
JJ
11295 case DT_GNU_PRELINKED:
11296 if (do_dynamic)
11297 {
2cf0635d 11298 struct tm * tmp;
91d6fa6a 11299 time_t atime = entry->d_un.d_val;
047b2264 11300
91d6fa6a 11301 tmp = gmtime (&atime);
071436c6
NC
11302 /* PR 17533 file: 041-1244816-0.004. */
11303 if (tmp == NULL)
5a2cbcf4
L
11304 printf (_("<corrupt time val: %lx"),
11305 (unsigned long) atime);
071436c6
NC
11306 else
11307 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11308 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11309 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11310
11311 }
11312 break;
11313
fdc90cb4 11314 case DT_GNU_HASH:
978c4450 11315 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11316 if (do_dynamic)
11317 {
11318 print_vma (entry->d_un.d_val, PREFIX_HEX);
11319 putchar ('\n');
11320 }
11321 break;
11322
a5da3dee
VDM
11323 case DT_GNU_FLAGS_1:
11324 if (do_dynamic)
11325 {
11326 printf (_("Flags:"));
11327 if (entry->d_un.d_val == 0)
11328 printf (_(" None\n"));
11329 else
11330 {
11331 unsigned long int val = entry->d_un.d_val;
11332
11333 if (val & DF_GNU_1_UNIQUE)
11334 {
11335 printf (" UNIQUE");
11336 val ^= DF_GNU_1_UNIQUE;
11337 }
11338 if (val != 0)
11339 printf (" %lx", val);
11340 puts ("");
11341 }
11342 }
11343 break;
11344
252b5132
RH
11345 default:
11346 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11347 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11348 = entry->d_un.d_val;
252b5132
RH
11349
11350 if (do_dynamic)
11351 {
dda8d76d 11352 switch (filedata->file_header.e_machine)
252b5132 11353 {
37c18eed
SD
11354 case EM_AARCH64:
11355 dynamic_section_aarch64_val (entry);
11356 break;
252b5132 11357 case EM_MIPS:
4fe85591 11358 case EM_MIPS_RS3_LE:
978c4450 11359 dynamic_section_mips_val (filedata, entry);
252b5132 11360 break;
103f02d3 11361 case EM_PARISC:
b2d38a17 11362 dynamic_section_parisc_val (entry);
103f02d3 11363 break;
ecc51f48 11364 case EM_IA_64:
b2d38a17 11365 dynamic_section_ia64_val (entry);
ecc51f48 11366 break;
252b5132 11367 default:
f7a99963
NC
11368 print_vma (entry->d_un.d_val, PREFIX_HEX);
11369 putchar ('\n');
252b5132
RH
11370 }
11371 }
11372 break;
11373 }
11374 }
11375
015dc7e1 11376 return true;
252b5132
RH
11377}
11378
11379static char *
d3ba0551 11380get_ver_flags (unsigned int flags)
252b5132 11381{
6d4f21f6 11382 static char buff[128];
252b5132
RH
11383
11384 buff[0] = 0;
11385
11386 if (flags == 0)
11387 return _("none");
11388
11389 if (flags & VER_FLG_BASE)
7bb1ad17 11390 strcat (buff, "BASE");
252b5132
RH
11391
11392 if (flags & VER_FLG_WEAK)
11393 {
11394 if (flags & VER_FLG_BASE)
7bb1ad17 11395 strcat (buff, " | ");
252b5132 11396
7bb1ad17 11397 strcat (buff, "WEAK");
252b5132
RH
11398 }
11399
44ec90b9
RO
11400 if (flags & VER_FLG_INFO)
11401 {
11402 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11403 strcat (buff, " | ");
44ec90b9 11404
7bb1ad17 11405 strcat (buff, "INFO");
44ec90b9
RO
11406 }
11407
11408 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11409 {
11410 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11411 strcat (buff, " | ");
11412
11413 strcat (buff, _("<unknown>"));
11414 }
252b5132
RH
11415
11416 return buff;
11417}
11418
11419/* Display the contents of the version sections. */
98fb390a 11420
015dc7e1 11421static bool
dda8d76d 11422process_version_sections (Filedata * filedata)
252b5132 11423{
2cf0635d 11424 Elf_Internal_Shdr * section;
b34976b6 11425 unsigned i;
015dc7e1 11426 bool found = false;
252b5132
RH
11427
11428 if (! do_version)
015dc7e1 11429 return true;
252b5132 11430
dda8d76d
NC
11431 for (i = 0, section = filedata->section_headers;
11432 i < filedata->file_header.e_shnum;
b34976b6 11433 i++, section++)
252b5132
RH
11434 {
11435 switch (section->sh_type)
11436 {
11437 case SHT_GNU_verdef:
11438 {
2cf0635d 11439 Elf_External_Verdef * edefs;
452bf675
AM
11440 unsigned long idx;
11441 unsigned long cnt;
2cf0635d 11442 char * endbuf;
252b5132 11443
015dc7e1 11444 found = true;
252b5132 11445
ca0e11aa
NC
11446 if (filedata->is_separate)
11447 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
11448 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
11449 section->sh_info),
11450 filedata->file_name,
11451 printable_section_name (filedata, section),
11452 section->sh_info);
11453 else
11454 printf (ngettext ("\nVersion definition section '%s' "
11455 "contains %u entry:\n",
11456 "\nVersion definition section '%s' "
11457 "contains %u entries:\n",
11458 section->sh_info),
11459 printable_section_name (filedata, section),
11460 section->sh_info);
047c3dbf 11461
ae9ac79e 11462 printf (_(" Addr: 0x"));
252b5132 11463 printf_vma (section->sh_addr);
233f82cf 11464 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11465 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11466 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11467
3f5e193b 11468 edefs = (Elf_External_Verdef *)
dda8d76d 11469 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11470 _("version definition section"));
a6e9f9df
AM
11471 if (!edefs)
11472 break;
59245841 11473 endbuf = (char *) edefs + section->sh_size;
252b5132 11474
1445030f 11475 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11476 {
2cf0635d
NC
11477 char * vstart;
11478 Elf_External_Verdef * edef;
b34976b6 11479 Elf_Internal_Verdef ent;
2cf0635d 11480 Elf_External_Verdaux * eaux;
b34976b6 11481 Elf_Internal_Verdaux aux;
452bf675 11482 unsigned long isum;
b34976b6 11483 int j;
103f02d3 11484
252b5132 11485 vstart = ((char *) edefs) + idx;
54806181
AM
11486 if (vstart + sizeof (*edef) > endbuf)
11487 break;
252b5132
RH
11488
11489 edef = (Elf_External_Verdef *) vstart;
11490
11491 ent.vd_version = BYTE_GET (edef->vd_version);
11492 ent.vd_flags = BYTE_GET (edef->vd_flags);
11493 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11494 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11495 ent.vd_hash = BYTE_GET (edef->vd_hash);
11496 ent.vd_aux = BYTE_GET (edef->vd_aux);
11497 ent.vd_next = BYTE_GET (edef->vd_next);
11498
452bf675 11499 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11500 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11501
11502 printf (_(" Index: %d Cnt: %d "),
11503 ent.vd_ndx, ent.vd_cnt);
11504
452bf675 11505 /* Check for overflow. */
1445030f 11506 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11507 break;
11508
252b5132
RH
11509 vstart += ent.vd_aux;
11510
1445030f
AM
11511 if (vstart + sizeof (*eaux) > endbuf)
11512 break;
252b5132
RH
11513 eaux = (Elf_External_Verdaux *) vstart;
11514
11515 aux.vda_name = BYTE_GET (eaux->vda_name);
11516 aux.vda_next = BYTE_GET (eaux->vda_next);
11517
978c4450
AM
11518 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
11519 printf (_("Name: %s\n"),
11520 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132
RH
11521 else
11522 printf (_("Name index: %ld\n"), aux.vda_name);
11523
11524 isum = idx + ent.vd_aux;
11525
b34976b6 11526 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11527 {
1445030f
AM
11528 if (aux.vda_next < sizeof (*eaux)
11529 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11530 {
11531 warn (_("Invalid vda_next field of %lx\n"),
11532 aux.vda_next);
11533 j = ent.vd_cnt;
11534 break;
11535 }
dd24e3da 11536 /* Check for overflow. */
7e26601c 11537 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11538 break;
11539
252b5132
RH
11540 isum += aux.vda_next;
11541 vstart += aux.vda_next;
11542
54806181
AM
11543 if (vstart + sizeof (*eaux) > endbuf)
11544 break;
1445030f 11545 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11546
11547 aux.vda_name = BYTE_GET (eaux->vda_name);
11548 aux.vda_next = BYTE_GET (eaux->vda_next);
11549
978c4450 11550 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
452bf675 11551 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450
AM
11552 isum, j,
11553 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132 11554 else
452bf675 11555 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11556 isum, j, aux.vda_name);
11557 }
dd24e3da 11558
54806181
AM
11559 if (j < ent.vd_cnt)
11560 printf (_(" Version def aux past end of section\n"));
252b5132 11561
c9f02c3e
MR
11562 /* PR 17531:
11563 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11564 if (ent.vd_next < sizeof (*edef)
11565 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11566 {
11567 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11568 cnt = section->sh_info;
11569 break;
11570 }
452bf675 11571 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11572 break;
11573
252b5132
RH
11574 idx += ent.vd_next;
11575 }
dd24e3da 11576
54806181
AM
11577 if (cnt < section->sh_info)
11578 printf (_(" Version definition past end of section\n"));
252b5132
RH
11579
11580 free (edefs);
11581 }
11582 break;
103f02d3 11583
252b5132
RH
11584 case SHT_GNU_verneed:
11585 {
2cf0635d 11586 Elf_External_Verneed * eneed;
452bf675
AM
11587 unsigned long idx;
11588 unsigned long cnt;
2cf0635d 11589 char * endbuf;
252b5132 11590
015dc7e1 11591 found = true;
252b5132 11592
ca0e11aa
NC
11593 if (filedata->is_separate)
11594 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
11595 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
11596 section->sh_info),
11597 filedata->file_name,
11598 printable_section_name (filedata, section),
11599 section->sh_info);
11600 else
11601 printf (ngettext ("\nVersion needs section '%s' "
11602 "contains %u entry:\n",
11603 "\nVersion needs section '%s' "
11604 "contains %u entries:\n",
11605 section->sh_info),
11606 printable_section_name (filedata, section),
11607 section->sh_info);
047c3dbf 11608
252b5132
RH
11609 printf (_(" Addr: 0x"));
11610 printf_vma (section->sh_addr);
72de5009 11611 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11612 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11613 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11614
dda8d76d 11615 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11616 section->sh_offset, 1,
11617 section->sh_size,
9cf03b7e 11618 _("Version Needs section"));
a6e9f9df
AM
11619 if (!eneed)
11620 break;
59245841 11621 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11622
11623 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11624 {
2cf0635d 11625 Elf_External_Verneed * entry;
b34976b6 11626 Elf_Internal_Verneed ent;
452bf675 11627 unsigned long isum;
b34976b6 11628 int j;
2cf0635d 11629 char * vstart;
252b5132
RH
11630
11631 vstart = ((char *) eneed) + idx;
54806181
AM
11632 if (vstart + sizeof (*entry) > endbuf)
11633 break;
252b5132
RH
11634
11635 entry = (Elf_External_Verneed *) vstart;
11636
11637 ent.vn_version = BYTE_GET (entry->vn_version);
11638 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11639 ent.vn_file = BYTE_GET (entry->vn_file);
11640 ent.vn_aux = BYTE_GET (entry->vn_aux);
11641 ent.vn_next = BYTE_GET (entry->vn_next);
11642
452bf675 11643 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11644
978c4450
AM
11645 if (VALID_DYNAMIC_NAME (filedata, ent.vn_file))
11646 printf (_(" File: %s"),
11647 GET_DYNAMIC_NAME (filedata, ent.vn_file));
252b5132
RH
11648 else
11649 printf (_(" File: %lx"), ent.vn_file);
11650
11651 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11652
dd24e3da 11653 /* Check for overflow. */
7e26601c 11654 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11655 break;
252b5132
RH
11656 vstart += ent.vn_aux;
11657
11658 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11659 {
2cf0635d 11660 Elf_External_Vernaux * eaux;
b34976b6 11661 Elf_Internal_Vernaux aux;
252b5132 11662
54806181
AM
11663 if (vstart + sizeof (*eaux) > endbuf)
11664 break;
252b5132
RH
11665 eaux = (Elf_External_Vernaux *) vstart;
11666
11667 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11668 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11669 aux.vna_other = BYTE_GET (eaux->vna_other);
11670 aux.vna_name = BYTE_GET (eaux->vna_name);
11671 aux.vna_next = BYTE_GET (eaux->vna_next);
11672
978c4450 11673 if (VALID_DYNAMIC_NAME (filedata, aux.vna_name))
452bf675 11674 printf (_(" %#06lx: Name: %s"),
978c4450 11675 isum, GET_DYNAMIC_NAME (filedata, aux.vna_name));
252b5132 11676 else
452bf675 11677 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11678 isum, aux.vna_name);
11679
11680 printf (_(" Flags: %s Version: %d\n"),
11681 get_ver_flags (aux.vna_flags), aux.vna_other);
11682
1445030f
AM
11683 if (aux.vna_next < sizeof (*eaux)
11684 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11685 {
11686 warn (_("Invalid vna_next field of %lx\n"),
11687 aux.vna_next);
11688 j = ent.vn_cnt;
11689 break;
11690 }
1445030f
AM
11691 /* Check for overflow. */
11692 if (aux.vna_next > (size_t) (endbuf - vstart))
11693 break;
252b5132
RH
11694 isum += aux.vna_next;
11695 vstart += aux.vna_next;
11696 }
9cf03b7e 11697
54806181 11698 if (j < ent.vn_cnt)
f9a6a8f0 11699 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 11700
1445030f
AM
11701 if (ent.vn_next < sizeof (*entry)
11702 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11703 {
452bf675 11704 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11705 cnt = section->sh_info;
11706 break;
11707 }
1445030f
AM
11708 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11709 break;
252b5132
RH
11710 idx += ent.vn_next;
11711 }
9cf03b7e 11712
54806181 11713 if (cnt < section->sh_info)
9cf03b7e 11714 warn (_("Missing Version Needs information\n"));
103f02d3 11715
252b5132
RH
11716 free (eneed);
11717 }
11718 break;
11719
11720 case SHT_GNU_versym:
11721 {
2cf0635d 11722 Elf_Internal_Shdr * link_section;
8b73c356
NC
11723 size_t total;
11724 unsigned int cnt;
2cf0635d
NC
11725 unsigned char * edata;
11726 unsigned short * data;
11727 char * strtab;
11728 Elf_Internal_Sym * symbols;
11729 Elf_Internal_Shdr * string_sec;
ba5cdace 11730 unsigned long num_syms;
d3ba0551 11731 long off;
252b5132 11732
dda8d76d 11733 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11734 break;
11735
dda8d76d 11736 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11737 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11738
dda8d76d 11739 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11740 break;
11741
015dc7e1 11742 found = true;
252b5132 11743
4de91c10 11744 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
11745 if (symbols == NULL)
11746 break;
252b5132 11747
dda8d76d 11748 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11749
dda8d76d 11750 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11751 string_sec->sh_size,
11752 _("version string table"));
a6e9f9df 11753 if (!strtab)
0429c154
MS
11754 {
11755 free (symbols);
11756 break;
11757 }
252b5132 11758
ca0e11aa
NC
11759 if (filedata->is_separate)
11760 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
11761 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
11762 total),
11763 filedata->file_name,
11764 printable_section_name (filedata, section),
11765 (unsigned long) total);
11766 else
11767 printf (ngettext ("\nVersion symbols section '%s' "
11768 "contains %lu entry:\n",
11769 "\nVersion symbols section '%s' "
11770 "contains %lu entries:\n",
11771 total),
11772 printable_section_name (filedata, section),
11773 (unsigned long) total);
252b5132 11774
ae9ac79e 11775 printf (_(" Addr: 0x"));
252b5132 11776 printf_vma (section->sh_addr);
72de5009 11777 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11778 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11779 printable_section_name (filedata, link_section));
252b5132 11780
dda8d76d 11781 off = offset_from_vma (filedata,
978c4450 11782 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11783 total * sizeof (short));
95099889
AM
11784 edata = (unsigned char *) get_data (NULL, filedata, off,
11785 sizeof (short), total,
11786 _("version symbol data"));
a6e9f9df
AM
11787 if (!edata)
11788 {
11789 free (strtab);
0429c154 11790 free (symbols);
a6e9f9df
AM
11791 break;
11792 }
252b5132 11793
3f5e193b 11794 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11795
11796 for (cnt = total; cnt --;)
b34976b6
AM
11797 data[cnt] = byte_get (edata + cnt * sizeof (short),
11798 sizeof (short));
252b5132
RH
11799
11800 free (edata);
11801
11802 for (cnt = 0; cnt < total; cnt += 4)
11803 {
11804 int j, nn;
ab273396
AM
11805 char *name;
11806 char *invalid = _("*invalid*");
252b5132
RH
11807
11808 printf (" %03x:", cnt);
11809
11810 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11811 switch (data[cnt + j])
252b5132
RH
11812 {
11813 case 0:
11814 fputs (_(" 0 (*local*) "), stdout);
11815 break;
11816
11817 case 1:
11818 fputs (_(" 1 (*global*) "), stdout);
11819 break;
11820
11821 default:
c244d050
NC
11822 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11823 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11824
dd24e3da 11825 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11826 array, break to avoid an out-of-bounds read. */
11827 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11828 {
11829 warn (_("invalid index into symbol array\n"));
11830 break;
11831 }
11832
ab273396 11833 name = NULL;
978c4450 11834 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11835 {
b34976b6
AM
11836 Elf_Internal_Verneed ivn;
11837 unsigned long offset;
252b5132 11838
d93f0186 11839 offset = offset_from_vma
978c4450
AM
11840 (filedata,
11841 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11842 sizeof (Elf_External_Verneed));
252b5132 11843
b34976b6 11844 do
252b5132 11845 {
b34976b6
AM
11846 Elf_Internal_Vernaux ivna;
11847 Elf_External_Verneed evn;
11848 Elf_External_Vernaux evna;
11849 unsigned long a_off;
252b5132 11850
dda8d76d 11851 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11852 _("version need")) == NULL)
11853 break;
0b4362b0 11854
252b5132
RH
11855 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11856 ivn.vn_next = BYTE_GET (evn.vn_next);
11857
11858 a_off = offset + ivn.vn_aux;
11859
11860 do
11861 {
dda8d76d 11862 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11863 1, _("version need aux (2)")) == NULL)
11864 {
11865 ivna.vna_next = 0;
11866 ivna.vna_other = 0;
11867 }
11868 else
11869 {
11870 ivna.vna_next = BYTE_GET (evna.vna_next);
11871 ivna.vna_other = BYTE_GET (evna.vna_other);
11872 }
252b5132
RH
11873
11874 a_off += ivna.vna_next;
11875 }
b34976b6 11876 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11877 && ivna.vna_next != 0);
11878
b34976b6 11879 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11880 {
11881 ivna.vna_name = BYTE_GET (evna.vna_name);
11882
54806181 11883 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11884 name = invalid;
54806181
AM
11885 else
11886 name = strtab + ivna.vna_name;
252b5132
RH
11887 break;
11888 }
11889
11890 offset += ivn.vn_next;
11891 }
11892 while (ivn.vn_next);
11893 }
00d93f34 11894
ab273396 11895 if (data[cnt + j] != 0x8001
978c4450 11896 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 11897 {
b34976b6
AM
11898 Elf_Internal_Verdef ivd;
11899 Elf_External_Verdef evd;
11900 unsigned long offset;
252b5132 11901
d93f0186 11902 offset = offset_from_vma
978c4450
AM
11903 (filedata,
11904 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 11905 sizeof evd);
252b5132
RH
11906
11907 do
11908 {
dda8d76d 11909 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
11910 _("version def")) == NULL)
11911 {
11912 ivd.vd_next = 0;
948f632f 11913 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
11914 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
11915 break;
59245841
NC
11916 }
11917 else
11918 {
11919 ivd.vd_next = BYTE_GET (evd.vd_next);
11920 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11921 }
252b5132
RH
11922
11923 offset += ivd.vd_next;
11924 }
c244d050 11925 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
11926 && ivd.vd_next != 0);
11927
c244d050 11928 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 11929 {
b34976b6
AM
11930 Elf_External_Verdaux evda;
11931 Elf_Internal_Verdaux ivda;
252b5132
RH
11932
11933 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11934
dda8d76d 11935 if (get_data (&evda, filedata,
59245841
NC
11936 offset - ivd.vd_next + ivd.vd_aux,
11937 sizeof (evda), 1,
11938 _("version def aux")) == NULL)
11939 break;
252b5132
RH
11940
11941 ivda.vda_name = BYTE_GET (evda.vda_name);
11942
54806181 11943 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
11944 name = invalid;
11945 else if (name != NULL && name != invalid)
11946 name = _("*both*");
54806181
AM
11947 else
11948 name = strtab + ivda.vda_name;
252b5132
RH
11949 }
11950 }
ab273396
AM
11951 if (name != NULL)
11952 nn += printf ("(%s%-*s",
11953 name,
11954 12 - (int) strlen (name),
11955 ")");
252b5132
RH
11956
11957 if (nn < 18)
11958 printf ("%*c", 18 - nn, ' ');
11959 }
11960
11961 putchar ('\n');
11962 }
11963
11964 free (data);
11965 free (strtab);
11966 free (symbols);
11967 }
11968 break;
103f02d3 11969
252b5132
RH
11970 default:
11971 break;
11972 }
11973 }
11974
11975 if (! found)
ca0e11aa
NC
11976 {
11977 if (filedata->is_separate)
11978 printf (_("\nNo version information found in linked file '%s'.\n"),
11979 filedata->file_name);
11980 else
11981 printf (_("\nNo version information found in this file.\n"));
11982 }
252b5132 11983
015dc7e1 11984 return true;
252b5132
RH
11985}
11986
d1133906 11987static const char *
dda8d76d 11988get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 11989{
89246a0e 11990 static char buff[64];
252b5132
RH
11991
11992 switch (binding)
11993 {
b34976b6
AM
11994 case STB_LOCAL: return "LOCAL";
11995 case STB_GLOBAL: return "GLOBAL";
11996 case STB_WEAK: return "WEAK";
252b5132
RH
11997 default:
11998 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
11999 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12000 binding);
252b5132 12001 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12002 {
12003 if (binding == STB_GNU_UNIQUE
df3a023b 12004 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12005 return "UNIQUE";
12006 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12007 }
252b5132 12008 else
e9e44622 12009 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12010 return buff;
12011 }
12012}
12013
d1133906 12014static const char *
dda8d76d 12015get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12016{
89246a0e 12017 static char buff[64];
252b5132
RH
12018
12019 switch (type)
12020 {
b34976b6
AM
12021 case STT_NOTYPE: return "NOTYPE";
12022 case STT_OBJECT: return "OBJECT";
12023 case STT_FUNC: return "FUNC";
12024 case STT_SECTION: return "SECTION";
12025 case STT_FILE: return "FILE";
12026 case STT_COMMON: return "COMMON";
12027 case STT_TLS: return "TLS";
15ab5209
DB
12028 case STT_RELC: return "RELC";
12029 case STT_SRELC: return "SRELC";
252b5132
RH
12030 default:
12031 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12032 {
dda8d76d 12033 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12034 return "THUMB_FUNC";
103f02d3 12035
dda8d76d 12036 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12037 return "REGISTER";
12038
dda8d76d 12039 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12040 return "PARISC_MILLI";
12041
e9e44622 12042 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12043 }
252b5132 12044 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12045 {
dda8d76d 12046 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12047 {
12048 if (type == STT_HP_OPAQUE)
12049 return "HP_OPAQUE";
12050 if (type == STT_HP_STUB)
12051 return "HP_STUB";
12052 }
12053
d8045f23 12054 if (type == STT_GNU_IFUNC
dda8d76d 12055 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12056 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12057 return "IFUNC";
12058
e9e44622 12059 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12060 }
252b5132 12061 else
e9e44622 12062 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12063 return buff;
12064 }
12065}
12066
d1133906 12067static const char *
d3ba0551 12068get_symbol_visibility (unsigned int visibility)
d1133906
NC
12069{
12070 switch (visibility)
12071 {
b34976b6
AM
12072 case STV_DEFAULT: return "DEFAULT";
12073 case STV_INTERNAL: return "INTERNAL";
12074 case STV_HIDDEN: return "HIDDEN";
d1133906 12075 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12076 default:
27a45f42 12077 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12078 return _("<unknown>");
d1133906
NC
12079 }
12080}
12081
2057d69d
CZ
12082static const char *
12083get_alpha_symbol_other (unsigned int other)
9abca702 12084{
2057d69d
CZ
12085 switch (other)
12086 {
12087 case STO_ALPHA_NOPV: return "NOPV";
12088 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12089 default:
27a45f42 12090 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12091 return _("<unknown>");
9abca702 12092 }
2057d69d
CZ
12093}
12094
fd85a6a1
NC
12095static const char *
12096get_solaris_symbol_visibility (unsigned int visibility)
12097{
12098 switch (visibility)
12099 {
12100 case 4: return "EXPORTED";
12101 case 5: return "SINGLETON";
12102 case 6: return "ELIMINATE";
12103 default: return get_symbol_visibility (visibility);
12104 }
12105}
12106
2301ed1c
SN
12107static const char *
12108get_aarch64_symbol_other (unsigned int other)
12109{
12110 static char buf[32];
12111
12112 if (other & STO_AARCH64_VARIANT_PCS)
12113 {
12114 other &= ~STO_AARCH64_VARIANT_PCS;
12115 if (other == 0)
12116 return "VARIANT_PCS";
12117 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12118 return buf;
12119 }
12120 return NULL;
12121}
12122
5e2b0d47
NC
12123static const char *
12124get_mips_symbol_other (unsigned int other)
12125{
12126 switch (other)
12127 {
32ec8896
NC
12128 case STO_OPTIONAL: return "OPTIONAL";
12129 case STO_MIPS_PLT: return "MIPS PLT";
12130 case STO_MIPS_PIC: return "MIPS PIC";
12131 case STO_MICROMIPS: return "MICROMIPS";
12132 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12133 case STO_MIPS16: return "MIPS16";
12134 default: return NULL;
5e2b0d47
NC
12135 }
12136}
12137
28f997cf 12138static const char *
dda8d76d 12139get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12140{
dda8d76d 12141 if (is_ia64_vms (filedata))
28f997cf
TG
12142 {
12143 static char res[32];
12144
12145 res[0] = 0;
12146
12147 /* Function types is for images and .STB files only. */
dda8d76d 12148 switch (filedata->file_header.e_type)
28f997cf
TG
12149 {
12150 case ET_DYN:
12151 case ET_EXEC:
12152 switch (VMS_ST_FUNC_TYPE (other))
12153 {
12154 case VMS_SFT_CODE_ADDR:
12155 strcat (res, " CA");
12156 break;
12157 case VMS_SFT_SYMV_IDX:
12158 strcat (res, " VEC");
12159 break;
12160 case VMS_SFT_FD:
12161 strcat (res, " FD");
12162 break;
12163 case VMS_SFT_RESERVE:
12164 strcat (res, " RSV");
12165 break;
12166 default:
bee0ee85
NC
12167 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12168 VMS_ST_FUNC_TYPE (other));
12169 strcat (res, " <unknown>");
12170 break;
28f997cf
TG
12171 }
12172 break;
12173 default:
12174 break;
12175 }
12176 switch (VMS_ST_LINKAGE (other))
12177 {
12178 case VMS_STL_IGNORE:
12179 strcat (res, " IGN");
12180 break;
12181 case VMS_STL_RESERVE:
12182 strcat (res, " RSV");
12183 break;
12184 case VMS_STL_STD:
12185 strcat (res, " STD");
12186 break;
12187 case VMS_STL_LNK:
12188 strcat (res, " LNK");
12189 break;
12190 default:
bee0ee85
NC
12191 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12192 VMS_ST_LINKAGE (other));
12193 strcat (res, " <unknown>");
12194 break;
28f997cf
TG
12195 }
12196
12197 if (res[0] != 0)
12198 return res + 1;
12199 else
12200 return res;
12201 }
12202 return NULL;
12203}
12204
6911b7dc
AM
12205static const char *
12206get_ppc64_symbol_other (unsigned int other)
12207{
14732552
AM
12208 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12209 return NULL;
12210
12211 other >>= STO_PPC64_LOCAL_BIT;
12212 if (other <= 6)
6911b7dc 12213 {
89246a0e 12214 static char buf[64];
14732552
AM
12215 if (other >= 2)
12216 other = ppc64_decode_local_entry (other);
12217 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12218 return buf;
12219 }
12220 return NULL;
12221}
12222
5e2b0d47 12223static const char *
dda8d76d 12224get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12225{
12226 const char * result = NULL;
89246a0e 12227 static char buff [64];
5e2b0d47
NC
12228
12229 if (other == 0)
12230 return "";
12231
dda8d76d 12232 switch (filedata->file_header.e_machine)
5e2b0d47 12233 {
2057d69d
CZ
12234 case EM_ALPHA:
12235 result = get_alpha_symbol_other (other);
12236 break;
2301ed1c
SN
12237 case EM_AARCH64:
12238 result = get_aarch64_symbol_other (other);
12239 break;
5e2b0d47
NC
12240 case EM_MIPS:
12241 result = get_mips_symbol_other (other);
28f997cf
TG
12242 break;
12243 case EM_IA_64:
dda8d76d 12244 result = get_ia64_symbol_other (filedata, other);
28f997cf 12245 break;
6911b7dc
AM
12246 case EM_PPC64:
12247 result = get_ppc64_symbol_other (other);
12248 break;
5e2b0d47 12249 default:
fd85a6a1 12250 result = NULL;
5e2b0d47
NC
12251 break;
12252 }
12253
12254 if (result)
12255 return result;
12256
12257 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12258 return buff;
12259}
12260
d1133906 12261static const char *
dda8d76d 12262get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12263{
b34976b6 12264 static char buff[32];
5cf1065c 12265
252b5132
RH
12266 switch (type)
12267 {
b34976b6
AM
12268 case SHN_UNDEF: return "UND";
12269 case SHN_ABS: return "ABS";
12270 case SHN_COMMON: return "COM";
252b5132 12271 default:
9ce701e2 12272 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12273 && filedata->file_header.e_machine == EM_IA_64
12274 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12275 return "ANSI_COM";
12276 else if ((filedata->file_header.e_machine == EM_X86_64
12277 || filedata->file_header.e_machine == EM_L1OM
12278 || filedata->file_header.e_machine == EM_K1OM)
12279 && type == SHN_X86_64_LCOMMON)
12280 return "LARGE_COM";
12281 else if ((type == SHN_MIPS_SCOMMON
12282 && filedata->file_header.e_machine == EM_MIPS)
12283 || (type == SHN_TIC6X_SCOMMON
12284 && filedata->file_header.e_machine == EM_TI_C6000))
12285 return "SCOM";
12286 else if (type == SHN_MIPS_SUNDEFINED
12287 && filedata->file_header.e_machine == EM_MIPS)
12288 return "SUND";
12289 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12290 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12291 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12292 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12293 else if (type >= SHN_LORESERVE)
12294 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12295 else if (filedata->file_header.e_shnum != 0
12296 && type >= filedata->file_header.e_shnum)
12297 sprintf (buff, _("bad section index[%3d]"), type);
12298 else
12299 sprintf (buff, "%3d", type);
12300 break;
fd85a6a1
NC
12301 }
12302
10ca4b04 12303 return buff;
6bd1a22c
L
12304}
12305
bb4d2ac2 12306static const char *
dda8d76d 12307get_symbol_version_string (Filedata * filedata,
015dc7e1 12308 bool is_dynsym,
1449284b
NC
12309 const char * strtab,
12310 unsigned long int strtab_size,
12311 unsigned int si,
12312 Elf_Internal_Sym * psym,
12313 enum versioned_symbol_info * sym_info,
12314 unsigned short * vna_other)
bb4d2ac2 12315{
ab273396
AM
12316 unsigned char data[2];
12317 unsigned short vers_data;
12318 unsigned long offset;
7a815dd5 12319 unsigned short max_vd_ndx;
bb4d2ac2 12320
ab273396 12321 if (!is_dynsym
978c4450 12322 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12323 return NULL;
bb4d2ac2 12324
978c4450
AM
12325 offset = offset_from_vma (filedata,
12326 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12327 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12328
dda8d76d 12329 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12330 sizeof (data), 1, _("version data")) == NULL)
12331 return NULL;
12332
12333 vers_data = byte_get (data, 2);
bb4d2ac2 12334
1f6f5dba 12335 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12336 return NULL;
bb4d2ac2 12337
0b8b7609 12338 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12339 max_vd_ndx = 0;
12340
ab273396
AM
12341 /* Usually we'd only see verdef for defined symbols, and verneed for
12342 undefined symbols. However, symbols defined by the linker in
12343 .dynbss for variables copied from a shared library in order to
12344 avoid text relocations are defined yet have verneed. We could
12345 use a heuristic to detect the special case, for example, check
12346 for verneed first on symbols defined in SHT_NOBITS sections, but
12347 it is simpler and more reliable to just look for both verdef and
12348 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12349
ab273396
AM
12350 if (psym->st_shndx != SHN_UNDEF
12351 && vers_data != 0x8001
978c4450 12352 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12353 {
12354 Elf_Internal_Verdef ivd;
12355 Elf_Internal_Verdaux ivda;
12356 Elf_External_Verdaux evda;
12357 unsigned long off;
bb4d2ac2 12358
dda8d76d 12359 off = offset_from_vma (filedata,
978c4450 12360 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12361 sizeof (Elf_External_Verdef));
12362
12363 do
bb4d2ac2 12364 {
ab273396
AM
12365 Elf_External_Verdef evd;
12366
dda8d76d 12367 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12368 _("version def")) == NULL)
12369 {
12370 ivd.vd_ndx = 0;
12371 ivd.vd_aux = 0;
12372 ivd.vd_next = 0;
1f6f5dba 12373 ivd.vd_flags = 0;
ab273396
AM
12374 }
12375 else
bb4d2ac2 12376 {
ab273396
AM
12377 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12378 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12379 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12380 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12381 }
bb4d2ac2 12382
7a815dd5
L
12383 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12384 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12385
ab273396
AM
12386 off += ivd.vd_next;
12387 }
12388 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12389
ab273396
AM
12390 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12391 {
9abca702 12392 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12393 return NULL;
12394
ab273396
AM
12395 off -= ivd.vd_next;
12396 off += ivd.vd_aux;
bb4d2ac2 12397
dda8d76d 12398 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12399 _("version def aux")) != NULL)
12400 {
12401 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12402
ab273396 12403 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12404 return (ivda.vda_name < strtab_size
12405 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12406 }
12407 }
12408 }
bb4d2ac2 12409
978c4450 12410 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12411 {
12412 Elf_External_Verneed evn;
12413 Elf_Internal_Verneed ivn;
12414 Elf_Internal_Vernaux ivna;
bb4d2ac2 12415
dda8d76d 12416 offset = offset_from_vma (filedata,
978c4450 12417 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12418 sizeof evn);
12419 do
12420 {
12421 unsigned long vna_off;
bb4d2ac2 12422
dda8d76d 12423 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12424 _("version need")) == NULL)
12425 {
12426 ivna.vna_next = 0;
12427 ivna.vna_other = 0;
12428 ivna.vna_name = 0;
12429 break;
12430 }
bb4d2ac2 12431
ab273396
AM
12432 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12433 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12434
ab273396 12435 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12436
ab273396
AM
12437 do
12438 {
12439 Elf_External_Vernaux evna;
bb4d2ac2 12440
dda8d76d 12441 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12442 _("version need aux (3)")) == NULL)
bb4d2ac2 12443 {
ab273396
AM
12444 ivna.vna_next = 0;
12445 ivna.vna_other = 0;
12446 ivna.vna_name = 0;
bb4d2ac2 12447 }
bb4d2ac2 12448 else
bb4d2ac2 12449 {
ab273396
AM
12450 ivna.vna_other = BYTE_GET (evna.vna_other);
12451 ivna.vna_next = BYTE_GET (evna.vna_next);
12452 ivna.vna_name = BYTE_GET (evna.vna_name);
12453 }
bb4d2ac2 12454
ab273396
AM
12455 vna_off += ivna.vna_next;
12456 }
12457 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12458
ab273396
AM
12459 if (ivna.vna_other == vers_data)
12460 break;
bb4d2ac2 12461
ab273396
AM
12462 offset += ivn.vn_next;
12463 }
12464 while (ivn.vn_next != 0);
bb4d2ac2 12465
ab273396
AM
12466 if (ivna.vna_other == vers_data)
12467 {
12468 *sym_info = symbol_undefined;
12469 *vna_other = ivna.vna_other;
12470 return (ivna.vna_name < strtab_size
12471 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12472 }
7a815dd5
L
12473 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12474 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12475 return _("<corrupt>");
bb4d2ac2 12476 }
ab273396 12477 return NULL;
bb4d2ac2
L
12478}
12479
047c3dbf
NL
12480/* Display a symbol size on stdout. Format is based on --sym-base setting. */
12481
12482static unsigned int
12483print_dynamic_symbol_size (bfd_vma vma, int base)
12484{
12485 switch (base)
12486 {
12487 case 8:
12488 return print_vma (vma, OCTAL_5);
12489
12490 case 10:
12491 return print_vma (vma, UNSIGNED_5);
12492
12493 case 16:
12494 return print_vma (vma, PREFIX_HEX_5);
12495
12496 case 0:
12497 default:
12498 return print_vma (vma, DEC_5);
12499 }
12500}
12501
10ca4b04
L
12502static void
12503print_dynamic_symbol (Filedata *filedata, unsigned long si,
12504 Elf_Internal_Sym *symtab,
12505 Elf_Internal_Shdr *section,
12506 char *strtab, size_t strtab_size)
252b5132 12507{
10ca4b04
L
12508 const char *version_string;
12509 enum versioned_symbol_info sym_info;
12510 unsigned short vna_other;
23356397
NC
12511 bool is_valid;
12512 const char * sstr;
10ca4b04 12513 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 12514
10ca4b04
L
12515 printf ("%6ld: ", si);
12516 print_vma (psym->st_value, LONG_HEX);
12517 putchar (' ');
047c3dbf 12518 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
12519 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12520 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12521 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12522 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12523 else
252b5132 12524 {
10ca4b04 12525 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12526
10ca4b04
L
12527 printf (" %-7s", get_symbol_visibility (vis));
12528 /* Check to see if any other bits in the st_other field are set.
12529 Note - displaying this information disrupts the layout of the
12530 table being generated, but for the moment this case is very rare. */
12531 if (psym->st_other ^ vis)
12532 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12533 }
10ca4b04 12534 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 12535
23356397
NC
12536 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
12537 && psym->st_shndx < filedata->file_header.e_shnum
12538 && psym->st_name == 0)
12539 {
12540 is_valid = SECTION_NAME_VALID (filedata->section_headers + psym->st_shndx);
12541 sstr = is_valid ?
12542 SECTION_NAME_PRINT (filedata->section_headers + psym->st_shndx)
12543 : _("<corrupt>");
12544 }
12545 else
12546 {
12547 is_valid = VALID_SYMBOL_NAME (strtab, strtab_size, psym->st_name);
12548 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
12549 }
10ca4b04
L
12550
12551 version_string
12552 = get_symbol_version_string (filedata,
12553 (section == NULL
12554 || section->sh_type == SHT_DYNSYM),
12555 strtab, strtab_size, si,
12556 psym, &sym_info, &vna_other);
b9e920ec 12557
0942c7ab
NC
12558 int len_avail = 21;
12559 if (! do_wide && version_string != NULL)
12560 {
ddb43bab 12561 char buffer[16];
0942c7ab 12562
ddb43bab 12563 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
12564
12565 if (sym_info == symbol_undefined)
12566 len_avail -= sprintf (buffer," (%d)", vna_other);
12567 else if (sym_info != symbol_hidden)
12568 len_avail -= 1;
12569 }
12570
12571 print_symbol (len_avail, sstr);
b9e920ec 12572
10ca4b04
L
12573 if (version_string)
12574 {
12575 if (sym_info == symbol_undefined)
12576 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12577 else
10ca4b04
L
12578 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12579 version_string);
12580 }
6bd1a22c 12581
10ca4b04 12582 putchar ('\n');
6bd1a22c 12583
10ca4b04
L
12584 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12585 && section != NULL
12586 && si >= section->sh_info
12587 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12588 && filedata->file_header.e_machine != EM_MIPS
12589 /* Solaris binaries have been found to violate this requirement as
12590 well. Not sure if this is a bug or an ABI requirement. */
12591 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12592 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12593 si, printable_section_name (filedata, section), section->sh_info);
12594}
f16a9783 12595
0f03783c
NC
12596static const char *
12597get_lto_kind (unsigned int kind)
12598{
12599 switch (kind)
12600 {
12601 case 0: return "DEF";
12602 case 1: return "WEAKDEF";
12603 case 2: return "UNDEF";
12604 case 3: return "WEAKUNDEF";
12605 case 4: return "COMMON";
12606 default:
12607 break;
12608 }
12609
12610 static char buffer[30];
12611 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
12612 sprintf (buffer, "<unknown: %u>", kind);
12613 return buffer;
12614}
12615
12616static const char *
12617get_lto_visibility (unsigned int visibility)
12618{
12619 switch (visibility)
12620 {
12621 case 0: return "DEFAULT";
12622 case 1: return "PROTECTED";
12623 case 2: return "INTERNAL";
12624 case 3: return "HIDDEN";
12625 default:
12626 break;
12627 }
12628
12629 static char buffer[30];
12630 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
12631 sprintf (buffer, "<unknown: %u>", visibility);
12632 return buffer;
12633}
12634
12635static const char *
12636get_lto_sym_type (unsigned int sym_type)
12637{
12638 switch (sym_type)
12639 {
12640 case 0: return "UNKNOWN";
12641 case 1: return "FUNCTION";
12642 case 2: return "VARIABLE";
12643 default:
12644 break;
12645 }
12646
12647 static char buffer[30];
12648 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
12649 sprintf (buffer, "<unknown: %u>", sym_type);
12650 return buffer;
12651}
12652
12653/* Display an LTO format symbol table.
12654 FIXME: The format of LTO symbol tables is not formalized.
12655 So this code could need changing in the future. */
12656
015dc7e1 12657static bool
0f03783c
NC
12658display_lto_symtab (Filedata * filedata,
12659 Elf_Internal_Shdr * section)
12660{
12661 if (section->sh_size == 0)
12662 {
ca0e11aa
NC
12663 if (filedata->is_separate)
12664 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
12665 printable_section_name (filedata, section),
12666 filedata->file_name);
12667 else
12668 printf (_("\nLTO Symbol table '%s' is empty!\n"),
12669 printable_section_name (filedata, section));
047c3dbf 12670
015dc7e1 12671 return true;
0f03783c
NC
12672 }
12673
12674 if (section->sh_size > filedata->file_size)
12675 {
12676 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
12677 printable_section_name (filedata, section),
12678 (unsigned long) section->sh_size);
015dc7e1 12679 return false;
0f03783c
NC
12680 }
12681
12682 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
12683 section->sh_size, 1, _("LTO symbols"));
12684 if (alloced_data == NULL)
015dc7e1 12685 return false;
0f03783c
NC
12686
12687 /* Look for extended data for the symbol table. */
12688 Elf_Internal_Shdr * ext;
12689 void * ext_data_orig = NULL;
12690 char * ext_data = NULL;
12691 char * ext_data_end = NULL;
12692 char * ext_name = NULL;
12693
12694 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
b9e920ec 12695 SECTION_NAME (section) + sizeof (".gnu.lto_.symtab.") - 1) > 0
0f03783c
NC
12696 && ext_name != NULL /* Paranoia. */
12697 && (ext = find_section (filedata, ext_name)) != NULL)
12698 {
12699 if (ext->sh_size < 3)
12700 error (_("LTO Symbol extension table '%s' is empty!\n"),
12701 printable_section_name (filedata, ext));
12702 else
12703 {
12704 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
12705 ext->sh_size, 1,
12706 _("LTO ext symbol data"));
12707 if (ext_data != NULL)
12708 {
12709 ext_data_end = ext_data + ext->sh_size;
12710 if (* ext_data++ != 1)
12711 error (_("Unexpected version number in symbol extension table\n"));
12712 }
12713 }
12714 }
b9e920ec 12715
0f03783c
NC
12716 const unsigned char * data = (const unsigned char *) alloced_data;
12717 const unsigned char * end = data + section->sh_size;
12718
ca0e11aa
NC
12719 if (filedata->is_separate)
12720 printf (_("\nIn linked file '%s': "), filedata->file_name);
12721 else
12722 printf ("\n");
12723
0f03783c
NC
12724 if (ext_data_orig != NULL)
12725 {
12726 if (do_wide)
ca0e11aa 12727 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
12728 printable_section_name (filedata, section),
12729 printable_section_name (filedata, ext));
12730 else
12731 {
ca0e11aa 12732 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
12733 printable_section_name (filedata, section));
12734 printf (_(" and extension table '%s' contain:\n"),
12735 printable_section_name (filedata, ext));
12736 }
12737 }
12738 else
ca0e11aa 12739 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 12740 printable_section_name (filedata, section));
b9e920ec 12741
0f03783c 12742 /* FIXME: Add a wide version. */
b9e920ec 12743 if (ext_data_orig != NULL)
0f03783c
NC
12744 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
12745 else
12746 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
12747
12748 /* FIXME: We do not handle style prefixes. */
12749
12750 while (data < end)
12751 {
12752 const unsigned char * sym_name = data;
12753 data += strnlen ((const char *) sym_name, end - data) + 1;
12754 if (data >= end)
12755 goto fail;
12756
12757 const unsigned char * comdat_key = data;
12758 data += strnlen ((const char *) comdat_key, end - data) + 1;
12759 if (data >= end)
12760 goto fail;
12761
12762 if (data + 2 + 8 + 4 > end)
12763 goto fail;
12764
12765 unsigned int kind = *data++;
12766 unsigned int visibility = *data++;
12767
12768 elf_vma size = byte_get (data, 8);
12769 data += 8;
12770
12771 elf_vma slot = byte_get (data, 4);
12772 data += 4;
12773
12774 if (ext_data != NULL)
12775 {
12776 if (ext_data < (ext_data_end - 1))
12777 {
12778 unsigned int sym_type = * ext_data ++;
12779 unsigned int sec_kind = * ext_data ++;
12780
12781 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
12782 * comdat_key == 0 ? "-" : (char *) comdat_key,
12783 get_lto_kind (kind),
12784 get_lto_visibility (visibility),
12785 (long) size,
12786 (long) slot,
12787 get_lto_sym_type (sym_type),
12788 (long) sec_kind);
12789 print_symbol (6, (const char *) sym_name);
12790 }
12791 else
12792 {
12793 error (_("Ran out of LTO symbol extension data\n"));
12794 ext_data = NULL;
12795 /* FIXME: return FAIL result ? */
12796 }
12797 }
12798 else
12799 {
12800 printf (" %10s %10s %11s %08lx %08lx _",
12801 * comdat_key == 0 ? "-" : (char *) comdat_key,
12802 get_lto_kind (kind),
12803 get_lto_visibility (visibility),
12804 (long) size,
12805 (long) slot);
12806 print_symbol (21, (const char *) sym_name);
12807 }
12808 putchar ('\n');
12809 }
12810
12811 if (ext_data != NULL && ext_data < ext_data_end)
12812 {
12813 error (_("Data remains in the LTO symbol extension table\n"));
12814 goto fail;
12815 }
12816
12817 free (alloced_data);
12818 free (ext_data_orig);
12819 free (ext_name);
015dc7e1 12820 return true;
b9e920ec 12821
0f03783c
NC
12822 fail:
12823 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
12824 free (alloced_data);
12825 free (ext_data_orig);
12826 free (ext_name);
015dc7e1 12827 return false;
0f03783c
NC
12828}
12829
12830/* Display LTO symbol tables. */
12831
015dc7e1 12832static bool
0f03783c
NC
12833process_lto_symbol_tables (Filedata * filedata)
12834{
12835 Elf_Internal_Shdr * section;
12836 unsigned int i;
015dc7e1 12837 bool res = true;
0f03783c
NC
12838
12839 if (!do_lto_syms)
015dc7e1 12840 return true;
0f03783c
NC
12841
12842 if (filedata->section_headers == NULL)
015dc7e1 12843 return true;
0f03783c
NC
12844
12845 for (i = 0, section = filedata->section_headers;
12846 i < filedata->file_header.e_shnum;
12847 i++, section++)
b9e920ec 12848 if (SECTION_NAME_VALID (section)
08dedd66 12849 && startswith (SECTION_NAME (section), ".gnu.lto_.symtab."))
0f03783c
NC
12850 res &= display_lto_symtab (filedata, section);
12851
b9e920ec 12852 return res;
0f03783c
NC
12853}
12854
10ca4b04 12855/* Dump the symbol table. */
0f03783c 12856
015dc7e1 12857static bool
10ca4b04
L
12858process_symbol_table (Filedata * filedata)
12859{
12860 Elf_Internal_Shdr * section;
f16a9783 12861
10ca4b04 12862 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 12863 return true;
6bd1a22c 12864
978c4450 12865 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
12866 && do_syms
12867 && do_using_dynamic
978c4450
AM
12868 && filedata->dynamic_strings != NULL
12869 && filedata->dynamic_symbols != NULL)
6bd1a22c 12870 {
10ca4b04 12871 unsigned long si;
6bd1a22c 12872
ca0e11aa
NC
12873 if (filedata->is_separate)
12874 {
12875 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
12876 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
12877 filedata->num_dynamic_syms),
12878 filedata->file_name,
12879 filedata->num_dynamic_syms);
12880 }
12881 else
12882 {
12883 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12884 "\nSymbol table for image contains %lu entries:\n",
12885 filedata->num_dynamic_syms),
12886 filedata->num_dynamic_syms);
12887 }
10ca4b04
L
12888 if (is_32bit_elf)
12889 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12890 else
12891 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12892
978c4450
AM
12893 for (si = 0; si < filedata->num_dynamic_syms; si++)
12894 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
12895 filedata->dynamic_strings,
12896 filedata->dynamic_strings_length);
252b5132 12897 }
8b73c356 12898 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 12899 && filedata->section_headers != NULL)
252b5132 12900 {
b34976b6 12901 unsigned int i;
252b5132 12902
dda8d76d
NC
12903 for (i = 0, section = filedata->section_headers;
12904 i < filedata->file_header.e_shnum;
252b5132
RH
12905 i++, section++)
12906 {
2cf0635d 12907 char * strtab = NULL;
c256ffe7 12908 unsigned long int strtab_size = 0;
2cf0635d 12909 Elf_Internal_Sym * symtab;
ef3df110 12910 unsigned long si, num_syms;
252b5132 12911
2c610e4b
L
12912 if ((section->sh_type != SHT_SYMTAB
12913 && section->sh_type != SHT_DYNSYM)
12914 || (!do_syms
12915 && section->sh_type == SHT_SYMTAB))
252b5132
RH
12916 continue;
12917
dd24e3da
NC
12918 if (section->sh_entsize == 0)
12919 {
12920 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 12921 printable_section_name (filedata, section));
dd24e3da
NC
12922 continue;
12923 }
12924
d3a49aa8 12925 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
12926
12927 if (filedata->is_separate)
12928 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
12929 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
12930 num_syms),
12931 filedata->file_name,
12932 printable_section_name (filedata, section),
12933 num_syms);
12934 else
12935 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
12936 "\nSymbol table '%s' contains %lu entries:\n",
12937 num_syms),
12938 printable_section_name (filedata, section),
12939 num_syms);
dd24e3da 12940
f7a99963 12941 if (is_32bit_elf)
ca47b30c 12942 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 12943 else
ca47b30c 12944 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 12945
4de91c10 12946 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
12947 if (symtab == NULL)
12948 continue;
12949
dda8d76d 12950 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 12951 {
dda8d76d
NC
12952 strtab = filedata->string_table;
12953 strtab_size = filedata->string_table_length;
c256ffe7 12954 }
dda8d76d 12955 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 12956 {
2cf0635d 12957 Elf_Internal_Shdr * string_sec;
252b5132 12958
dda8d76d 12959 string_sec = filedata->section_headers + section->sh_link;
252b5132 12960
dda8d76d 12961 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
12962 1, string_sec->sh_size,
12963 _("string table"));
c256ffe7 12964 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
12965 }
12966
10ca4b04
L
12967 for (si = 0; si < num_syms; si++)
12968 print_dynamic_symbol (filedata, si, symtab, section,
12969 strtab, strtab_size);
252b5132
RH
12970
12971 free (symtab);
dda8d76d 12972 if (strtab != filedata->string_table)
252b5132
RH
12973 free (strtab);
12974 }
12975 }
12976 else if (do_syms)
12977 printf
12978 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
12979
978c4450 12980 if (do_histogram && filedata->buckets != NULL)
252b5132 12981 {
2cf0635d
NC
12982 unsigned long * lengths;
12983 unsigned long * counts;
66543521
AM
12984 unsigned long hn;
12985 bfd_vma si;
12986 unsigned long maxlength = 0;
12987 unsigned long nzero_counts = 0;
12988 unsigned long nsyms = 0;
6bd6a03d 12989 char *visited;
252b5132 12990
d3a49aa8
AM
12991 printf (ngettext ("\nHistogram for bucket list length "
12992 "(total of %lu bucket):\n",
12993 "\nHistogram for bucket list length "
12994 "(total of %lu buckets):\n",
978c4450
AM
12995 (unsigned long) filedata->nbuckets),
12996 (unsigned long) filedata->nbuckets);
252b5132 12997
978c4450
AM
12998 lengths = (unsigned long *) calloc (filedata->nbuckets,
12999 sizeof (*lengths));
252b5132
RH
13000 if (lengths == NULL)
13001 {
8b73c356 13002 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13003 goto err_out;
252b5132 13004 }
978c4450
AM
13005 visited = xcmalloc (filedata->nchains, 1);
13006 memset (visited, 0, filedata->nchains);
8b73c356
NC
13007
13008 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13009 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13010 {
978c4450 13011 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13012 {
b34976b6 13013 ++nsyms;
252b5132 13014 if (maxlength < ++lengths[hn])
b34976b6 13015 ++maxlength;
978c4450 13016 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13017 {
13018 error (_("histogram chain is corrupt\n"));
13019 break;
13020 }
13021 visited[si] = 1;
252b5132
RH
13022 }
13023 }
6bd6a03d 13024 free (visited);
252b5132 13025
3f5e193b 13026 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13027 if (counts == NULL)
13028 {
b2e951ec 13029 free (lengths);
8b73c356 13030 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13031 goto err_out;
252b5132
RH
13032 }
13033
978c4450 13034 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13035 ++counts[lengths[hn]];
252b5132 13036
978c4450 13037 if (filedata->nbuckets > 0)
252b5132 13038 {
66543521
AM
13039 unsigned long i;
13040 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13041 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13042 for (i = 1; i <= maxlength; ++i)
103f02d3 13043 {
66543521
AM
13044 nzero_counts += counts[i] * i;
13045 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13046 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13047 (nzero_counts * 100.0) / nsyms);
13048 }
252b5132
RH
13049 }
13050
13051 free (counts);
13052 free (lengths);
13053 }
13054
978c4450
AM
13055 free (filedata->buckets);
13056 filedata->buckets = NULL;
13057 filedata->nbuckets = 0;
13058 free (filedata->chains);
13059 filedata->chains = NULL;
252b5132 13060
978c4450 13061 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13062 {
2cf0635d
NC
13063 unsigned long * lengths;
13064 unsigned long * counts;
fdc90cb4
JJ
13065 unsigned long hn;
13066 unsigned long maxlength = 0;
13067 unsigned long nzero_counts = 0;
13068 unsigned long nsyms = 0;
fdc90cb4 13069
f16a9783 13070 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13071 "(total of %lu bucket):\n",
f16a9783 13072 "\nHistogram for `%s' bucket list length "
d3a49aa8 13073 "(total of %lu buckets):\n",
978c4450
AM
13074 (unsigned long) filedata->ngnubuckets),
13075 GNU_HASH_SECTION_NAME (filedata),
13076 (unsigned long) filedata->ngnubuckets);
8b73c356 13077
978c4450
AM
13078 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13079 sizeof (*lengths));
fdc90cb4
JJ
13080 if (lengths == NULL)
13081 {
8b73c356 13082 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13083 goto err_out;
fdc90cb4
JJ
13084 }
13085
fdc90cb4
JJ
13086 printf (_(" Length Number %% of total Coverage\n"));
13087
978c4450
AM
13088 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13089 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
13090 {
13091 bfd_vma off, length = 1;
13092
978c4450 13093 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13094 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13095 off < filedata->ngnuchains
13096 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13097 ++off)
fdc90cb4
JJ
13098 ++length;
13099 lengths[hn] = length;
13100 if (length > maxlength)
13101 maxlength = length;
13102 nsyms += length;
13103 }
13104
3f5e193b 13105 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13106 if (counts == NULL)
13107 {
b2e951ec 13108 free (lengths);
8b73c356 13109 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13110 goto err_out;
fdc90cb4
JJ
13111 }
13112
978c4450 13113 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13114 ++counts[lengths[hn]];
13115
978c4450 13116 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13117 {
13118 unsigned long j;
13119 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13120 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13121 for (j = 1; j <= maxlength; ++j)
13122 {
13123 nzero_counts += counts[j] * j;
13124 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13125 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13126 (nzero_counts * 100.0) / nsyms);
13127 }
13128 }
13129
13130 free (counts);
13131 free (lengths);
fdc90cb4 13132 }
978c4450
AM
13133 free (filedata->gnubuckets);
13134 filedata->gnubuckets = NULL;
13135 filedata->ngnubuckets = 0;
13136 free (filedata->gnuchains);
13137 filedata->gnuchains = NULL;
13138 filedata->ngnuchains = 0;
13139 free (filedata->mipsxlat);
13140 filedata->mipsxlat = NULL;
015dc7e1 13141 return true;
fd486f32
AM
13142
13143 err_out:
978c4450
AM
13144 free (filedata->gnubuckets);
13145 filedata->gnubuckets = NULL;
13146 filedata->ngnubuckets = 0;
13147 free (filedata->gnuchains);
13148 filedata->gnuchains = NULL;
13149 filedata->ngnuchains = 0;
13150 free (filedata->mipsxlat);
13151 filedata->mipsxlat = NULL;
13152 free (filedata->buckets);
13153 filedata->buckets = NULL;
13154 filedata->nbuckets = 0;
13155 free (filedata->chains);
13156 filedata->chains = NULL;
015dc7e1 13157 return false;
252b5132
RH
13158}
13159
015dc7e1 13160static bool
ca0e11aa 13161process_syminfo (Filedata * filedata)
252b5132 13162{
b4c96d0d 13163 unsigned int i;
252b5132 13164
978c4450 13165 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13166 || !do_dynamic)
13167 /* No syminfo, this is ok. */
015dc7e1 13168 return true;
252b5132
RH
13169
13170 /* There better should be a dynamic symbol section. */
978c4450 13171 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13172 return false;
252b5132 13173
ca0e11aa
NC
13174 if (filedata->is_separate)
13175 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13176 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13177 filedata->dynamic_syminfo_nent),
13178 filedata->file_name,
13179 filedata->dynamic_syminfo_offset,
13180 filedata->dynamic_syminfo_nent);
13181 else
d3a49aa8
AM
13182 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13183 "contains %d entry:\n",
13184 "\nDynamic info segment at offset 0x%lx "
13185 "contains %d entries:\n",
978c4450 13186 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13187 filedata->dynamic_syminfo_offset,
13188 filedata->dynamic_syminfo_nent);
252b5132
RH
13189
13190 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13191 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13192 {
978c4450 13193 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13194
31104126 13195 printf ("%4d: ", i);
978c4450 13196 if (i >= filedata->num_dynamic_syms)
4082ef84 13197 printf (_("<corrupt index>"));
978c4450
AM
13198 else if (VALID_DYNAMIC_NAME (filedata, filedata->dynamic_symbols[i].st_name))
13199 print_symbol (30, GET_DYNAMIC_NAME (filedata,
13200 filedata->dynamic_symbols[i].st_name));
d79b3d50 13201 else
978c4450 13202 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13203 putchar (' ');
252b5132 13204
978c4450 13205 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13206 {
13207 case SYMINFO_BT_SELF:
13208 fputs ("SELF ", stdout);
13209 break;
13210 case SYMINFO_BT_PARENT:
13211 fputs ("PARENT ", stdout);
13212 break;
13213 default:
978c4450
AM
13214 if (filedata->dynamic_syminfo[i].si_boundto > 0
13215 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
13216 && VALID_DYNAMIC_NAME (filedata,
13217 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13218 {
978c4450
AM
13219 print_symbol (10, GET_DYNAMIC_NAME (filedata,
13220 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13221 putchar (' ' );
13222 }
252b5132 13223 else
978c4450 13224 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13225 break;
13226 }
13227
13228 if (flags & SYMINFO_FLG_DIRECT)
13229 printf (" DIRECT");
13230 if (flags & SYMINFO_FLG_PASSTHRU)
13231 printf (" PASSTHRU");
13232 if (flags & SYMINFO_FLG_COPY)
13233 printf (" COPY");
13234 if (flags & SYMINFO_FLG_LAZYLOAD)
13235 printf (" LAZYLOAD");
13236
13237 puts ("");
13238 }
13239
015dc7e1 13240 return true;
252b5132
RH
13241}
13242
75802ccb
CE
13243/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13244 is contained by the region START .. END. The types of ADDR, START
13245 and END should all be the same. Note both ADDR + NELEM and END
13246 point to just beyond the end of the regions that are being tested. */
13247#define IN_RANGE(START,END,ADDR,NELEM) \
13248 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13249
cf13d699
NC
13250/* Check to see if the given reloc needs to be handled in a target specific
13251 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13252 FALSE.
13253
13254 If called with reloc == NULL, then this is a signal that reloc processing
13255 for the current section has finished, and any saved state should be
13256 discarded. */
09c11c86 13257
015dc7e1 13258static bool
dda8d76d
NC
13259target_specific_reloc_handling (Filedata * filedata,
13260 Elf_Internal_Rela * reloc,
13261 unsigned char * start,
13262 unsigned char * end,
13263 Elf_Internal_Sym * symtab,
13264 unsigned long num_syms)
252b5132 13265{
f84ce13b
NC
13266 unsigned int reloc_type = 0;
13267 unsigned long sym_index = 0;
13268
13269 if (reloc)
13270 {
dda8d76d 13271 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13272 sym_index = get_reloc_symindex (reloc->r_info);
13273 }
252b5132 13274
dda8d76d 13275 switch (filedata->file_header.e_machine)
252b5132 13276 {
13761a11
NC
13277 case EM_MSP430:
13278 case EM_MSP430_OLD:
13279 {
13280 static Elf_Internal_Sym * saved_sym = NULL;
13281
f84ce13b
NC
13282 if (reloc == NULL)
13283 {
13284 saved_sym = NULL;
015dc7e1 13285 return true;
f84ce13b
NC
13286 }
13287
13761a11
NC
13288 switch (reloc_type)
13289 {
13290 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13291 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13292 if (uses_msp430x_relocs (filedata))
13761a11 13293 break;
1a0670f3 13294 /* Fall through. */
13761a11 13295 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13296 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13297 /* PR 21139. */
13298 if (sym_index >= num_syms)
13299 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13300 sym_index);
13301 else
13302 saved_sym = symtab + sym_index;
015dc7e1 13303 return true;
13761a11
NC
13304
13305 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13306 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13307 goto handle_sym_diff;
0b4362b0 13308
13761a11
NC
13309 case 5: /* R_MSP430_16_BYTE */
13310 case 9: /* R_MSP430_8 */
7d81bc93 13311 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13312 if (uses_msp430x_relocs (filedata))
13761a11
NC
13313 break;
13314 goto handle_sym_diff;
13315
13316 case 2: /* R_MSP430_ABS16 */
13317 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13318 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13319 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13320 break;
13321 goto handle_sym_diff;
0b4362b0 13322
13761a11
NC
13323 handle_sym_diff:
13324 if (saved_sym != NULL)
13325 {
13326 bfd_vma value;
5a805384 13327 unsigned int reloc_size = 0;
7d81bc93
JL
13328 int leb_ret = 0;
13329 switch (reloc_type)
13330 {
13331 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13332 reloc_size = 4;
13333 break;
13334 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13335 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13336 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13337 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13338 &reloc_size, &leb_ret);
7d81bc93
JL
13339 break;
13340 default:
13341 reloc_size = 2;
13342 break;
13343 }
13761a11 13344
5a805384 13345 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13346 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13347 "ULEB128 value\n"),
13348 (long) reloc->r_offset);
13349 else if (sym_index >= num_syms)
f84ce13b
NC
13350 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13351 sym_index);
03f7786e 13352 else
f84ce13b
NC
13353 {
13354 value = reloc->r_addend + (symtab[sym_index].st_value
13355 - saved_sym->st_value);
13356
b32e566b 13357 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13358 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13359 else
13360 /* PR 21137 */
13361 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13362 (long) reloc->r_offset);
f84ce13b 13363 }
13761a11
NC
13364
13365 saved_sym = NULL;
015dc7e1 13366 return true;
13761a11
NC
13367 }
13368 break;
13369
13370 default:
13371 if (saved_sym != NULL)
071436c6 13372 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
13373 break;
13374 }
13375 break;
13376 }
13377
cf13d699
NC
13378 case EM_MN10300:
13379 case EM_CYGNUS_MN10300:
13380 {
13381 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 13382
f84ce13b
NC
13383 if (reloc == NULL)
13384 {
13385 saved_sym = NULL;
015dc7e1 13386 return true;
f84ce13b
NC
13387 }
13388
cf13d699
NC
13389 switch (reloc_type)
13390 {
13391 case 34: /* R_MN10300_ALIGN */
015dc7e1 13392 return true;
cf13d699 13393 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
13394 if (sym_index >= num_syms)
13395 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
13396 sym_index);
13397 else
13398 saved_sym = symtab + sym_index;
015dc7e1 13399 return true;
f84ce13b 13400
cf13d699
NC
13401 case 1: /* R_MN10300_32 */
13402 case 2: /* R_MN10300_16 */
13403 if (saved_sym != NULL)
13404 {
03f7786e 13405 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 13406 bfd_vma value;
252b5132 13407
f84ce13b
NC
13408 if (sym_index >= num_syms)
13409 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
13410 sym_index);
03f7786e 13411 else
f84ce13b
NC
13412 {
13413 value = reloc->r_addend + (symtab[sym_index].st_value
13414 - saved_sym->st_value);
13415
b32e566b 13416 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13417 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13418 else
13419 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
13420 (long) reloc->r_offset);
f84ce13b 13421 }
252b5132 13422
cf13d699 13423 saved_sym = NULL;
015dc7e1 13424 return true;
cf13d699
NC
13425 }
13426 break;
13427 default:
13428 if (saved_sym != NULL)
071436c6 13429 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
13430 break;
13431 }
13432 break;
13433 }
6ff71e76
NC
13434
13435 case EM_RL78:
13436 {
13437 static bfd_vma saved_sym1 = 0;
13438 static bfd_vma saved_sym2 = 0;
13439 static bfd_vma value;
13440
f84ce13b
NC
13441 if (reloc == NULL)
13442 {
13443 saved_sym1 = saved_sym2 = 0;
015dc7e1 13444 return true;
f84ce13b
NC
13445 }
13446
6ff71e76
NC
13447 switch (reloc_type)
13448 {
13449 case 0x80: /* R_RL78_SYM. */
13450 saved_sym1 = saved_sym2;
f84ce13b
NC
13451 if (sym_index >= num_syms)
13452 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
13453 sym_index);
13454 else
13455 {
13456 saved_sym2 = symtab[sym_index].st_value;
13457 saved_sym2 += reloc->r_addend;
13458 }
015dc7e1 13459 return true;
6ff71e76
NC
13460
13461 case 0x83: /* R_RL78_OPsub. */
13462 value = saved_sym1 - saved_sym2;
13463 saved_sym2 = saved_sym1 = 0;
015dc7e1 13464 return true;
6ff71e76
NC
13465 break;
13466
13467 case 0x41: /* R_RL78_ABS32. */
b32e566b 13468 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 13469 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
13470 else
13471 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13472 (long) reloc->r_offset);
6ff71e76 13473 value = 0;
015dc7e1 13474 return true;
6ff71e76
NC
13475
13476 case 0x43: /* R_RL78_ABS16. */
b32e566b 13477 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 13478 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
13479 else
13480 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13481 (long) reloc->r_offset);
6ff71e76 13482 value = 0;
015dc7e1 13483 return true;
6ff71e76
NC
13484
13485 default:
13486 break;
13487 }
13488 break;
13489 }
252b5132
RH
13490 }
13491
015dc7e1 13492 return false;
252b5132
RH
13493}
13494
aca88567
NC
13495/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
13496 DWARF debug sections. This is a target specific test. Note - we do not
13497 go through the whole including-target-headers-multiple-times route, (as
13498 we have already done with <elf/h8.h>) because this would become very
13499 messy and even then this function would have to contain target specific
13500 information (the names of the relocs instead of their numeric values).
13501 FIXME: This is not the correct way to solve this problem. The proper way
13502 is to have target specific reloc sizing and typing functions created by
13503 the reloc-macros.h header, in the same way that it already creates the
13504 reloc naming functions. */
13505
015dc7e1 13506static bool
dda8d76d 13507is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13508{
d347c9df 13509 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13510 switch (filedata->file_header.e_machine)
aca88567 13511 {
41e92641 13512 case EM_386:
22abe556 13513 case EM_IAMCU:
41e92641 13514 return reloc_type == 1; /* R_386_32. */
aca88567
NC
13515 case EM_68K:
13516 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
13517 case EM_860:
13518 return reloc_type == 1; /* R_860_32. */
13519 case EM_960:
13520 return reloc_type == 2; /* R_960_32. */
a06ea964 13521 case EM_AARCH64:
9282b95a
JW
13522 return (reloc_type == 258
13523 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
13524 case EM_BPF:
13525 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
13526 case EM_ADAPTEVA_EPIPHANY:
13527 return reloc_type == 3;
aca88567 13528 case EM_ALPHA:
137b6b5f 13529 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
13530 case EM_ARC:
13531 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
13532 case EM_ARC_COMPACT:
13533 case EM_ARC_COMPACT2:
13534 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
13535 case EM_ARM:
13536 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 13537 case EM_AVR_OLD:
aca88567
NC
13538 case EM_AVR:
13539 return reloc_type == 1;
13540 case EM_BLACKFIN:
13541 return reloc_type == 0x12; /* R_byte4_data. */
13542 case EM_CRIS:
13543 return reloc_type == 3; /* R_CRIS_32. */
13544 case EM_CR16:
13545 return reloc_type == 3; /* R_CR16_NUM32. */
13546 case EM_CRX:
13547 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
13548 case EM_CSKY:
13549 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
13550 case EM_CYGNUS_FRV:
13551 return reloc_type == 1;
41e92641
NC
13552 case EM_CYGNUS_D10V:
13553 case EM_D10V:
13554 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
13555 case EM_CYGNUS_D30V:
13556 case EM_D30V:
13557 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
13558 case EM_DLX:
13559 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
13560 case EM_CYGNUS_FR30:
13561 case EM_FR30:
13562 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
13563 case EM_FT32:
13564 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
13565 case EM_H8S:
13566 case EM_H8_300:
13567 case EM_H8_300H:
13568 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 13569 case EM_IA_64:
262cdac7
AM
13570 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
13571 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
13572 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
13573 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
13574 case EM_IP2K_OLD:
13575 case EM_IP2K:
13576 return reloc_type == 2; /* R_IP2K_32. */
13577 case EM_IQ2000:
13578 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
13579 case EM_LATTICEMICO32:
13580 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 13581 case EM_M32C_OLD:
aca88567
NC
13582 case EM_M32C:
13583 return reloc_type == 3; /* R_M32C_32. */
13584 case EM_M32R:
13585 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
13586 case EM_68HC11:
13587 case EM_68HC12:
13588 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 13589 case EM_S12Z:
2849d19f
JD
13590 return reloc_type == 7 || /* R_S12Z_EXT32 */
13591 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
13592 case EM_MCORE:
13593 return reloc_type == 1; /* R_MCORE_ADDR32. */
13594 case EM_CYGNUS_MEP:
13595 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
13596 case EM_METAG:
13597 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
13598 case EM_MICROBLAZE:
13599 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
13600 case EM_MIPS:
13601 return reloc_type == 2; /* R_MIPS_32. */
13602 case EM_MMIX:
13603 return reloc_type == 4; /* R_MMIX_32. */
13604 case EM_CYGNUS_MN10200:
13605 case EM_MN10200:
13606 return reloc_type == 1; /* R_MN10200_32. */
13607 case EM_CYGNUS_MN10300:
13608 case EM_MN10300:
13609 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
13610 case EM_MOXIE:
13611 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
13612 case EM_MSP430_OLD:
13613 case EM_MSP430:
13761a11 13614 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
13615 case EM_MT:
13616 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
13617 case EM_NDS32:
13618 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 13619 case EM_ALTERA_NIOS2:
36591ba1 13620 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
13621 case EM_NIOS32:
13622 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
13623 case EM_OR1K:
13624 return reloc_type == 1; /* R_OR1K_32. */
aca88567 13625 case EM_PARISC:
9abca702 13626 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 13627 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 13628 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
13629 case EM_PJ:
13630 case EM_PJ_OLD:
13631 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
13632 case EM_PPC64:
13633 return reloc_type == 1; /* R_PPC64_ADDR32. */
13634 case EM_PPC:
13635 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
13636 case EM_TI_PRU:
13637 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
13638 case EM_RISCV:
13639 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
13640 case EM_RL78:
13641 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
13642 case EM_RX:
13643 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
13644 case EM_S370:
13645 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
13646 case EM_S390_OLD:
13647 case EM_S390:
13648 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
13649 case EM_SCORE:
13650 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
13651 case EM_SH:
13652 return reloc_type == 1; /* R_SH_DIR32. */
13653 case EM_SPARC32PLUS:
13654 case EM_SPARCV9:
13655 case EM_SPARC:
13656 return reloc_type == 3 /* R_SPARC_32. */
13657 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
13658 case EM_SPU:
13659 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
13660 case EM_TI_C6000:
13661 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
13662 case EM_TILEGX:
13663 return reloc_type == 2; /* R_TILEGX_32. */
13664 case EM_TILEPRO:
13665 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
13666 case EM_CYGNUS_V850:
13667 case EM_V850:
13668 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
13669 case EM_V800:
13670 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
13671 case EM_VAX:
13672 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
13673 case EM_VISIUM:
13674 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
13675 case EM_WEBASSEMBLY:
13676 return reloc_type == 1; /* R_WASM32_32. */
aca88567 13677 case EM_X86_64:
8a9036a4 13678 case EM_L1OM:
7a9068fe 13679 case EM_K1OM:
aca88567 13680 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
13681 case EM_XC16X:
13682 case EM_C166:
13683 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
13684 case EM_XGATE:
13685 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
13686 case EM_XSTORMY16:
13687 return reloc_type == 1; /* R_XSTROMY16_32. */
13688 case EM_XTENSA_OLD:
13689 case EM_XTENSA:
13690 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
13691 case EM_Z80:
13692 return reloc_type == 6; /* R_Z80_32. */
aca88567 13693 default:
bee0ee85
NC
13694 {
13695 static unsigned int prev_warn = 0;
13696
13697 /* Avoid repeating the same warning multiple times. */
dda8d76d 13698 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 13699 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
13700 filedata->file_header.e_machine);
13701 prev_warn = filedata->file_header.e_machine;
015dc7e1 13702 return false;
bee0ee85 13703 }
aca88567
NC
13704 }
13705}
13706
13707/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13708 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
13709
015dc7e1 13710static bool
dda8d76d 13711is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13712{
dda8d76d 13713 switch (filedata->file_header.e_machine)
d347c9df 13714 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 13715 {
41e92641 13716 case EM_386:
22abe556 13717 case EM_IAMCU:
3e0873ac 13718 return reloc_type == 2; /* R_386_PC32. */
aca88567 13719 case EM_68K:
3e0873ac 13720 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
13721 case EM_AARCH64:
13722 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
13723 case EM_ADAPTEVA_EPIPHANY:
13724 return reloc_type == 6;
aca88567
NC
13725 case EM_ALPHA:
13726 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
13727 case EM_ARC_COMPACT:
13728 case EM_ARC_COMPACT2:
13729 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 13730 case EM_ARM:
3e0873ac 13731 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
13732 case EM_AVR_OLD:
13733 case EM_AVR:
13734 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
13735 case EM_MICROBLAZE:
13736 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
13737 case EM_OR1K:
13738 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 13739 case EM_PARISC:
85acf597 13740 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
13741 case EM_PPC:
13742 return reloc_type == 26; /* R_PPC_REL32. */
13743 case EM_PPC64:
3e0873ac 13744 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
13745 case EM_RISCV:
13746 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
13747 case EM_S390_OLD:
13748 case EM_S390:
3e0873ac 13749 return reloc_type == 5; /* R_390_PC32. */
aca88567 13750 case EM_SH:
3e0873ac 13751 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
13752 case EM_SPARC32PLUS:
13753 case EM_SPARCV9:
13754 case EM_SPARC:
3e0873ac 13755 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
13756 case EM_SPU:
13757 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
13758 case EM_TILEGX:
13759 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
13760 case EM_TILEPRO:
13761 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
13762 case EM_VISIUM:
13763 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 13764 case EM_X86_64:
8a9036a4 13765 case EM_L1OM:
7a9068fe 13766 case EM_K1OM:
3e0873ac 13767 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
13768 case EM_VAX:
13769 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
13770 case EM_XTENSA_OLD:
13771 case EM_XTENSA:
13772 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
13773 default:
13774 /* Do not abort or issue an error message here. Not all targets use
13775 pc-relative 32-bit relocs in their DWARF debug information and we
13776 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
13777 more helpful warning message will be generated by apply_relocations
13778 anyway, so just return. */
015dc7e1 13779 return false;
aca88567
NC
13780 }
13781}
13782
13783/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13784 a 64-bit absolute RELA relocation used in DWARF debug sections. */
13785
015dc7e1 13786static bool
dda8d76d 13787is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13788{
dda8d76d 13789 switch (filedata->file_header.e_machine)
aca88567 13790 {
a06ea964
NC
13791 case EM_AARCH64:
13792 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
13793 case EM_ALPHA:
13794 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 13795 case EM_IA_64:
262cdac7
AM
13796 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
13797 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
13798 case EM_PARISC:
13799 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
13800 case EM_PPC64:
13801 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
13802 case EM_RISCV:
13803 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
13804 case EM_SPARC32PLUS:
13805 case EM_SPARCV9:
13806 case EM_SPARC:
714da62f
NC
13807 return reloc_type == 32 /* R_SPARC_64. */
13808 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 13809 case EM_X86_64:
8a9036a4 13810 case EM_L1OM:
7a9068fe 13811 case EM_K1OM:
aca88567 13812 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
13813 case EM_S390_OLD:
13814 case EM_S390:
aa137e4d
NC
13815 return reloc_type == 22; /* R_S390_64. */
13816 case EM_TILEGX:
13817 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 13818 case EM_MIPS:
aa137e4d 13819 return reloc_type == 18; /* R_MIPS_64. */
aca88567 13820 default:
015dc7e1 13821 return false;
aca88567
NC
13822 }
13823}
13824
85acf597
RH
13825/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
13826 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
13827
015dc7e1 13828static bool
dda8d76d 13829is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 13830{
dda8d76d 13831 switch (filedata->file_header.e_machine)
85acf597 13832 {
a06ea964
NC
13833 case EM_AARCH64:
13834 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 13835 case EM_ALPHA:
aa137e4d 13836 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 13837 case EM_IA_64:
262cdac7
AM
13838 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
13839 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 13840 case EM_PARISC:
aa137e4d 13841 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 13842 case EM_PPC64:
aa137e4d 13843 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
13844 case EM_SPARC32PLUS:
13845 case EM_SPARCV9:
13846 case EM_SPARC:
aa137e4d 13847 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 13848 case EM_X86_64:
8a9036a4 13849 case EM_L1OM:
7a9068fe 13850 case EM_K1OM:
aa137e4d 13851 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
13852 case EM_S390_OLD:
13853 case EM_S390:
aa137e4d
NC
13854 return reloc_type == 23; /* R_S390_PC64. */
13855 case EM_TILEGX:
13856 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 13857 default:
015dc7e1 13858 return false;
85acf597
RH
13859 }
13860}
13861
4dc3c23d
AM
13862/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13863 a 24-bit absolute RELA relocation used in DWARF debug sections. */
13864
015dc7e1 13865static bool
dda8d76d 13866is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 13867{
dda8d76d 13868 switch (filedata->file_header.e_machine)
4dc3c23d
AM
13869 {
13870 case EM_CYGNUS_MN10200:
13871 case EM_MN10200:
13872 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
13873 case EM_FT32:
13874 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
13875 case EM_Z80:
13876 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 13877 default:
015dc7e1 13878 return false;
4dc3c23d
AM
13879 }
13880}
13881
aca88567
NC
13882/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13883 a 16-bit absolute RELA relocation used in DWARF debug sections. */
13884
015dc7e1 13885static bool
dda8d76d 13886is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 13887{
d347c9df 13888 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13889 switch (filedata->file_header.e_machine)
4b78141a 13890 {
886a2506
NC
13891 case EM_ARC:
13892 case EM_ARC_COMPACT:
13893 case EM_ARC_COMPACT2:
13894 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
13895 case EM_ADAPTEVA_EPIPHANY:
13896 return reloc_type == 5;
aca88567
NC
13897 case EM_AVR_OLD:
13898 case EM_AVR:
13899 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
13900 case EM_CYGNUS_D10V:
13901 case EM_D10V:
13902 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
13903 case EM_FT32:
13904 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
13905 case EM_H8S:
13906 case EM_H8_300:
13907 case EM_H8_300H:
aca88567
NC
13908 return reloc_type == R_H8_DIR16;
13909 case EM_IP2K_OLD:
13910 case EM_IP2K:
13911 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 13912 case EM_M32C_OLD:
f4236fe4
DD
13913 case EM_M32C:
13914 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
13915 case EM_CYGNUS_MN10200:
13916 case EM_MN10200:
13917 return reloc_type == 2; /* R_MN10200_16. */
13918 case EM_CYGNUS_MN10300:
13919 case EM_MN10300:
13920 return reloc_type == 2; /* R_MN10300_16. */
aca88567 13921 case EM_MSP430:
dda8d76d 13922 if (uses_msp430x_relocs (filedata))
13761a11 13923 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 13924 /* Fall through. */
78c8d46c 13925 case EM_MSP430_OLD:
aca88567 13926 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
13927 case EM_NDS32:
13928 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 13929 case EM_ALTERA_NIOS2:
36591ba1 13930 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
13931 case EM_NIOS32:
13932 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
13933 case EM_OR1K:
13934 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
13935 case EM_RISCV:
13936 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
13937 case EM_TI_PRU:
13938 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
13939 case EM_TI_C6000:
13940 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
13941 case EM_VISIUM:
13942 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
13943 case EM_XC16X:
13944 case EM_C166:
13945 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
13946 case EM_XGATE:
13947 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
13948 case EM_Z80:
13949 return reloc_type == 4; /* R_Z80_16. */
4b78141a 13950 default:
015dc7e1 13951 return false;
4b78141a
NC
13952 }
13953}
13954
39e07931
AS
13955/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13956 a 8-bit absolute RELA relocation used in DWARF debug sections. */
13957
015dc7e1 13958static bool
39e07931
AS
13959is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13960{
13961 switch (filedata->file_header.e_machine)
13962 {
13963 case EM_RISCV:
13964 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
13965 case EM_Z80:
13966 return reloc_type == 1; /* R_Z80_8. */
39e07931 13967 default:
015dc7e1 13968 return false;
39e07931
AS
13969 }
13970}
13971
13972/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13973 a 6-bit absolute RELA relocation used in DWARF debug sections. */
13974
015dc7e1 13975static bool
39e07931
AS
13976is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13977{
13978 switch (filedata->file_header.e_machine)
13979 {
13980 case EM_RISCV:
13981 return reloc_type == 53; /* R_RISCV_SET6. */
13982 default:
015dc7e1 13983 return false;
39e07931
AS
13984 }
13985}
13986
03336641
JW
13987/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13988 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
13989
015dc7e1 13990static bool
03336641
JW
13991is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13992{
13993 /* Please keep this table alpha-sorted for ease of visual lookup. */
13994 switch (filedata->file_header.e_machine)
13995 {
13996 case EM_RISCV:
13997 return reloc_type == 35; /* R_RISCV_ADD32. */
13998 default:
015dc7e1 13999 return false;
03336641
JW
14000 }
14001}
14002
14003/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14004 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14005
015dc7e1 14006static bool
03336641
JW
14007is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14008{
14009 /* Please keep this table alpha-sorted for ease of visual lookup. */
14010 switch (filedata->file_header.e_machine)
14011 {
14012 case EM_RISCV:
14013 return reloc_type == 39; /* R_RISCV_SUB32. */
14014 default:
015dc7e1 14015 return false;
03336641
JW
14016 }
14017}
14018
14019/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14020 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14021
015dc7e1 14022static bool
03336641
JW
14023is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14024{
14025 /* Please keep this table alpha-sorted for ease of visual lookup. */
14026 switch (filedata->file_header.e_machine)
14027 {
14028 case EM_RISCV:
14029 return reloc_type == 36; /* R_RISCV_ADD64. */
14030 default:
015dc7e1 14031 return false;
03336641
JW
14032 }
14033}
14034
14035/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14036 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14037
015dc7e1 14038static bool
03336641
JW
14039is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14040{
14041 /* Please keep this table alpha-sorted for ease of visual lookup. */
14042 switch (filedata->file_header.e_machine)
14043 {
14044 case EM_RISCV:
14045 return reloc_type == 40; /* R_RISCV_SUB64. */
14046 default:
015dc7e1 14047 return false;
03336641
JW
14048 }
14049}
14050
14051/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14052 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14053
015dc7e1 14054static bool
03336641
JW
14055is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14056{
14057 /* Please keep this table alpha-sorted for ease of visual lookup. */
14058 switch (filedata->file_header.e_machine)
14059 {
14060 case EM_RISCV:
14061 return reloc_type == 34; /* R_RISCV_ADD16. */
14062 default:
015dc7e1 14063 return false;
03336641
JW
14064 }
14065}
14066
14067/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14068 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14069
015dc7e1 14070static bool
03336641
JW
14071is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14072{
14073 /* Please keep this table alpha-sorted for ease of visual lookup. */
14074 switch (filedata->file_header.e_machine)
14075 {
14076 case EM_RISCV:
14077 return reloc_type == 38; /* R_RISCV_SUB16. */
14078 default:
015dc7e1 14079 return false;
03336641
JW
14080 }
14081}
14082
14083/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14084 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14085
015dc7e1 14086static bool
03336641
JW
14087is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14088{
14089 /* Please keep this table alpha-sorted for ease of visual lookup. */
14090 switch (filedata->file_header.e_machine)
14091 {
14092 case EM_RISCV:
14093 return reloc_type == 33; /* R_RISCV_ADD8. */
14094 default:
015dc7e1 14095 return false;
03336641
JW
14096 }
14097}
14098
14099/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14100 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14101
015dc7e1 14102static bool
03336641
JW
14103is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14104{
14105 /* Please keep this table alpha-sorted for ease of visual lookup. */
14106 switch (filedata->file_header.e_machine)
14107 {
14108 case EM_RISCV:
14109 return reloc_type == 37; /* R_RISCV_SUB8. */
14110 default:
015dc7e1 14111 return false;
03336641
JW
14112 }
14113}
14114
39e07931
AS
14115/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14116 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14117
015dc7e1 14118static bool
39e07931
AS
14119is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14120{
14121 switch (filedata->file_header.e_machine)
14122 {
14123 case EM_RISCV:
14124 return reloc_type == 52; /* R_RISCV_SUB6. */
14125 default:
015dc7e1 14126 return false;
39e07931
AS
14127 }
14128}
14129
2a7b2e88
JK
14130/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14131 relocation entries (possibly formerly used for SHT_GROUP sections). */
14132
015dc7e1 14133static bool
dda8d76d 14134is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14135{
dda8d76d 14136 switch (filedata->file_header.e_machine)
2a7b2e88 14137 {
cb8f3167 14138 case EM_386: /* R_386_NONE. */
d347c9df 14139 case EM_68K: /* R_68K_NONE. */
cfb8c092 14140 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14141 case EM_ALPHA: /* R_ALPHA_NONE. */
14142 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14143 case EM_ARC: /* R_ARC_NONE. */
886a2506 14144 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14145 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14146 case EM_ARM: /* R_ARM_NONE. */
d347c9df 14147 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 14148 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14149 case EM_FT32: /* R_FT32_NONE. */
14150 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14151 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14152 case EM_L1OM: /* R_X86_64_NONE. */
14153 case EM_M32R: /* R_M32R_NONE. */
14154 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14155 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14156 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14157 case EM_NIOS32: /* R_NIOS_NONE. */
14158 case EM_OR1K: /* R_OR1K_NONE. */
14159 case EM_PARISC: /* R_PARISC_NONE. */
14160 case EM_PPC64: /* R_PPC64_NONE. */
14161 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14162 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14163 case EM_S390: /* R_390_NONE. */
14164 case EM_S390_OLD:
14165 case EM_SH: /* R_SH_NONE. */
14166 case EM_SPARC32PLUS:
14167 case EM_SPARC: /* R_SPARC_NONE. */
14168 case EM_SPARCV9:
aa137e4d
NC
14169 case EM_TILEGX: /* R_TILEGX_NONE. */
14170 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14171 case EM_TI_C6000:/* R_C6000_NONE. */
14172 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 14173 case EM_XC16X:
6655dba2 14174 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14175 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14176 return reloc_type == 0;
d347c9df 14177
a06ea964
NC
14178 case EM_AARCH64:
14179 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14180 case EM_AVR_OLD:
14181 case EM_AVR:
14182 return (reloc_type == 0 /* R_AVR_NONE. */
14183 || reloc_type == 30 /* R_AVR_DIFF8. */
14184 || reloc_type == 31 /* R_AVR_DIFF16. */
14185 || reloc_type == 32 /* R_AVR_DIFF32. */);
14186 case EM_METAG:
14187 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
14188 case EM_NDS32:
14189 return (reloc_type == 0 /* R_XTENSA_NONE. */
14190 || reloc_type == 204 /* R_NDS32_DIFF8. */
14191 || reloc_type == 205 /* R_NDS32_DIFF16. */
14192 || reloc_type == 206 /* R_NDS32_DIFF32. */
14193 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
14194 case EM_TI_PRU:
14195 return (reloc_type == 0 /* R_PRU_NONE. */
14196 || reloc_type == 65 /* R_PRU_DIFF8. */
14197 || reloc_type == 66 /* R_PRU_DIFF16. */
14198 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14199 case EM_XTENSA_OLD:
14200 case EM_XTENSA:
4dc3c23d
AM
14201 return (reloc_type == 0 /* R_XTENSA_NONE. */
14202 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14203 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14204 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14205 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14206 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14207 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14208 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14209 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14210 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14211 }
015dc7e1 14212 return false;
2a7b2e88
JK
14213}
14214
d1c4b12b
NC
14215/* Returns TRUE if there is a relocation against
14216 section NAME at OFFSET bytes. */
14217
015dc7e1 14218bool
d1c4b12b
NC
14219reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14220{
14221 Elf_Internal_Rela * relocs;
14222 Elf_Internal_Rela * rp;
14223
14224 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14225 return false;
d1c4b12b
NC
14226
14227 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14228
14229 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14230 if (rp->r_offset == offset)
015dc7e1 14231 return true;
d1c4b12b 14232
015dc7e1 14233 return false;
d1c4b12b
NC
14234}
14235
cf13d699 14236/* Apply relocations to a section.
32ec8896
NC
14237 Returns TRUE upon success, FALSE otherwise.
14238 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14239 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14240 will be set to the number of relocs loaded.
14241
cf13d699 14242 Note: So far support has been added only for those relocations
32ec8896
NC
14243 which can be found in debug sections. FIXME: Add support for
14244 more relocations ? */
1b315056 14245
015dc7e1 14246static bool
dda8d76d 14247apply_relocations (Filedata * filedata,
d1c4b12b
NC
14248 const Elf_Internal_Shdr * section,
14249 unsigned char * start,
14250 bfd_size_type size,
1449284b 14251 void ** relocs_return,
d1c4b12b 14252 unsigned long * num_relocs_return)
1b315056 14253{
cf13d699 14254 Elf_Internal_Shdr * relsec;
0d2a7a93 14255 unsigned char * end = start + size;
cb8f3167 14256
d1c4b12b
NC
14257 if (relocs_return != NULL)
14258 {
14259 * (Elf_Internal_Rela **) relocs_return = NULL;
14260 * num_relocs_return = 0;
14261 }
14262
dda8d76d 14263 if (filedata->file_header.e_type != ET_REL)
32ec8896 14264 /* No relocs to apply. */
015dc7e1 14265 return true;
1b315056 14266
cf13d699 14267 /* Find the reloc section associated with the section. */
dda8d76d
NC
14268 for (relsec = filedata->section_headers;
14269 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14270 ++relsec)
252b5132 14271 {
015dc7e1 14272 bool is_rela;
41e92641 14273 unsigned long num_relocs;
2cf0635d
NC
14274 Elf_Internal_Rela * relocs;
14275 Elf_Internal_Rela * rp;
14276 Elf_Internal_Shdr * symsec;
14277 Elf_Internal_Sym * symtab;
ba5cdace 14278 unsigned long num_syms;
2cf0635d 14279 Elf_Internal_Sym * sym;
252b5132 14280
41e92641 14281 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14282 || relsec->sh_info >= filedata->file_header.e_shnum
14283 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14284 || relsec->sh_size == 0
dda8d76d 14285 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14286 continue;
428409d5 14287
a788aedd
AM
14288 symsec = filedata->section_headers + relsec->sh_link;
14289 if (symsec->sh_type != SHT_SYMTAB
14290 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14291 return false;
a788aedd 14292
41e92641
NC
14293 is_rela = relsec->sh_type == SHT_RELA;
14294
14295 if (is_rela)
14296 {
dda8d76d 14297 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14298 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14299 return false;
41e92641
NC
14300 }
14301 else
14302 {
dda8d76d 14303 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14304 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14305 return false;
41e92641
NC
14306 }
14307
14308 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14309 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14310 is_rela = false;
428409d5 14311
4de91c10 14312 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14313
41e92641 14314 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14315 {
015dc7e1
AM
14316 bfd_vma addend;
14317 unsigned int reloc_type;
14318 unsigned int reloc_size;
14319 bool reloc_inplace = false;
14320 bool reloc_subtract = false;
14321 unsigned char *rloc;
14322 unsigned long sym_index;
4b78141a 14323
dda8d76d 14324 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14325
dda8d76d 14326 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14327 continue;
dda8d76d 14328 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14329 continue;
dda8d76d
NC
14330 else if (is_32bit_abs_reloc (filedata, reloc_type)
14331 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14332 reloc_size = 4;
dda8d76d
NC
14333 else if (is_64bit_abs_reloc (filedata, reloc_type)
14334 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14335 reloc_size = 8;
dda8d76d 14336 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14337 reloc_size = 3;
dda8d76d 14338 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14339 reloc_size = 2;
39e07931
AS
14340 else if (is_8bit_abs_reloc (filedata, reloc_type)
14341 || is_6bit_abs_reloc (filedata, reloc_type))
14342 reloc_size = 1;
03336641
JW
14343 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14344 reloc_type))
14345 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14346 {
14347 reloc_size = 4;
015dc7e1 14348 reloc_inplace = true;
03336641
JW
14349 }
14350 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14351 reloc_type))
14352 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14353 {
14354 reloc_size = 8;
015dc7e1 14355 reloc_inplace = true;
03336641
JW
14356 }
14357 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14358 reloc_type))
14359 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14360 {
14361 reloc_size = 2;
015dc7e1 14362 reloc_inplace = true;
03336641
JW
14363 }
14364 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14365 reloc_type))
14366 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14367 {
14368 reloc_size = 1;
015dc7e1 14369 reloc_inplace = true;
03336641 14370 }
39e07931
AS
14371 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
14372 reloc_type)))
14373 {
14374 reloc_size = 1;
015dc7e1 14375 reloc_inplace = true;
39e07931 14376 }
aca88567 14377 else
4b78141a 14378 {
bee0ee85 14379 static unsigned int prev_reloc = 0;
dda8d76d 14380
bee0ee85
NC
14381 if (reloc_type != prev_reloc)
14382 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 14383 reloc_type, printable_section_name (filedata, section));
bee0ee85 14384 prev_reloc = reloc_type;
4b78141a
NC
14385 continue;
14386 }
103f02d3 14387
91d6fa6a 14388 rloc = start + rp->r_offset;
75802ccb 14389 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
14390 {
14391 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
14392 (unsigned long) rp->r_offset,
dda8d76d 14393 printable_section_name (filedata, section));
700dd8b7
L
14394 continue;
14395 }
103f02d3 14396
ba5cdace
NC
14397 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
14398 if (sym_index >= num_syms)
14399 {
14400 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 14401 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
14402 continue;
14403 }
14404 sym = symtab + sym_index;
41e92641
NC
14405
14406 /* If the reloc has a symbol associated with it,
55f25fc3
L
14407 make sure that it is of an appropriate type.
14408
14409 Relocations against symbols without type can happen.
14410 Gcc -feliminate-dwarf2-dups may generate symbols
14411 without type for debug info.
14412
14413 Icc generates relocations against function symbols
14414 instead of local labels.
14415
14416 Relocations against object symbols can happen, eg when
14417 referencing a global array. For an example of this see
14418 the _clz.o binary in libgcc.a. */
aca88567 14419 if (sym != symtab
b8871f35 14420 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 14421 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 14422 {
d3a49aa8 14423 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
14424 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
14425 printable_section_name (filedata, relsec),
d3a49aa8 14426 (long int)(rp - relocs));
aca88567 14427 continue;
5b18a4bc 14428 }
252b5132 14429
4dc3c23d
AM
14430 addend = 0;
14431 if (is_rela)
14432 addend += rp->r_addend;
c47320c3
AM
14433 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
14434 partial_inplace. */
4dc3c23d 14435 if (!is_rela
dda8d76d 14436 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 14437 && reloc_type == 1)
dda8d76d
NC
14438 || ((filedata->file_header.e_machine == EM_PJ
14439 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 14440 && reloc_type == 1)
dda8d76d
NC
14441 || ((filedata->file_header.e_machine == EM_D30V
14442 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
14443 && reloc_type == 12)
14444 || reloc_inplace)
39e07931
AS
14445 {
14446 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
14447 addend += byte_get (rloc, reloc_size) & 0x3f;
14448 else
14449 addend += byte_get (rloc, reloc_size);
14450 }
cb8f3167 14451
dda8d76d
NC
14452 if (is_32bit_pcrel_reloc (filedata, reloc_type)
14453 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
14454 {
14455 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 14456 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 14457 addend -= 8;
91d6fa6a 14458 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
14459 reloc_size);
14460 }
39e07931
AS
14461 else if (is_6bit_abs_reloc (filedata, reloc_type)
14462 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
14463 {
14464 if (reloc_subtract)
14465 addend -= sym->st_value;
14466 else
14467 addend += sym->st_value;
14468 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
14469 byte_put (rloc, addend, reloc_size);
14470 }
03336641
JW
14471 else if (reloc_subtract)
14472 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 14473 else
91d6fa6a 14474 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 14475 }
252b5132 14476
5b18a4bc 14477 free (symtab);
f84ce13b
NC
14478 /* Let the target specific reloc processing code know that
14479 we have finished with these relocs. */
dda8d76d 14480 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
14481
14482 if (relocs_return)
14483 {
14484 * (Elf_Internal_Rela **) relocs_return = relocs;
14485 * num_relocs_return = num_relocs;
14486 }
14487 else
14488 free (relocs);
14489
5b18a4bc
NC
14490 break;
14491 }
32ec8896 14492
015dc7e1 14493 return true;
5b18a4bc 14494}
103f02d3 14495
cf13d699 14496#ifdef SUPPORT_DISASSEMBLY
015dc7e1 14497static bool
dda8d76d 14498disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14499{
dda8d76d 14500 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 14501
74e1a04b 14502 /* FIXME: XXX -- to be done --- XXX */
cf13d699 14503
015dc7e1 14504 return true;
cf13d699
NC
14505}
14506#endif
14507
14508/* Reads in the contents of SECTION from FILE, returning a pointer
14509 to a malloc'ed buffer or NULL if something went wrong. */
14510
14511static char *
dda8d76d 14512get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14513{
dda8d76d 14514 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
14515
14516 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
14517 {
c6b78c96 14518 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 14519 printable_section_name (filedata, section));
cf13d699
NC
14520 return NULL;
14521 }
14522
dda8d76d 14523 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 14524 _("section contents"));
cf13d699
NC
14525}
14526
0e602686
NC
14527/* Uncompresses a section that was compressed using zlib, in place. */
14528
015dc7e1 14529static bool
dda8d76d
NC
14530uncompress_section_contents (unsigned char ** buffer,
14531 dwarf_size_type uncompressed_size,
14532 dwarf_size_type * size)
0e602686
NC
14533{
14534 dwarf_size_type compressed_size = *size;
14535 unsigned char * compressed_buffer = *buffer;
14536 unsigned char * uncompressed_buffer;
14537 z_stream strm;
14538 int rc;
14539
14540 /* It is possible the section consists of several compressed
14541 buffers concatenated together, so we uncompress in a loop. */
14542 /* PR 18313: The state field in the z_stream structure is supposed
14543 to be invisible to the user (ie us), but some compilers will
14544 still complain about it being used without initialisation. So
14545 we first zero the entire z_stream structure and then set the fields
14546 that we need. */
14547 memset (& strm, 0, sizeof strm);
14548 strm.avail_in = compressed_size;
14549 strm.next_in = (Bytef *) compressed_buffer;
14550 strm.avail_out = uncompressed_size;
14551 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
14552
14553 rc = inflateInit (& strm);
14554 while (strm.avail_in > 0)
14555 {
14556 if (rc != Z_OK)
3624a6c1 14557 break;
0e602686
NC
14558 strm.next_out = ((Bytef *) uncompressed_buffer
14559 + (uncompressed_size - strm.avail_out));
14560 rc = inflate (&strm, Z_FINISH);
14561 if (rc != Z_STREAM_END)
3624a6c1 14562 break;
0e602686
NC
14563 rc = inflateReset (& strm);
14564 }
ad92f33d
AM
14565 if (inflateEnd (& strm) != Z_OK
14566 || rc != Z_OK
0e602686
NC
14567 || strm.avail_out != 0)
14568 goto fail;
14569
14570 *buffer = uncompressed_buffer;
14571 *size = uncompressed_size;
015dc7e1 14572 return true;
0e602686
NC
14573
14574 fail:
14575 free (uncompressed_buffer);
14576 /* Indicate decompression failure. */
14577 *buffer = NULL;
015dc7e1 14578 return false;
0e602686 14579}
dd24e3da 14580
015dc7e1 14581static bool
dda8d76d 14582dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14583{
015dc7e1
AM
14584 Elf_Internal_Shdr *relsec;
14585 bfd_size_type num_bytes;
14586 unsigned char *data;
14587 unsigned char *end;
14588 unsigned char *real_start;
14589 unsigned char *start;
14590 bool some_strings_shown;
cf13d699 14591
dda8d76d 14592 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14593 if (start == NULL)
c6b78c96 14594 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 14595 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 14596
0e602686 14597 num_bytes = section->sh_size;
cf13d699 14598
835f2fae
NC
14599 if (filedata->is_separate)
14600 printf (_("\nString dump of section '%s' in linked file %s:\n"),
14601 printable_section_name (filedata, section),
14602 filedata->file_name);
14603 else
14604 printf (_("\nString dump of section '%s':\n"),
14605 printable_section_name (filedata, section));
cf13d699 14606
0e602686
NC
14607 if (decompress_dumps)
14608 {
14609 dwarf_size_type new_size = num_bytes;
14610 dwarf_size_type uncompressed_size = 0;
14611
14612 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14613 {
14614 Elf_Internal_Chdr chdr;
14615 unsigned int compression_header_size
ebdf1ebf
NC
14616 = get_compression_header (& chdr, (unsigned char *) start,
14617 num_bytes);
5844b465
NC
14618 if (compression_header_size == 0)
14619 /* An error message will have already been generated
14620 by get_compression_header. */
14621 goto error_out;
0e602686 14622
813dabb9 14623 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14624 {
813dabb9 14625 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14626 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14627 goto error_out;
813dabb9 14628 }
813dabb9
L
14629 uncompressed_size = chdr.ch_size;
14630 start += compression_header_size;
14631 new_size -= compression_header_size;
0e602686
NC
14632 }
14633 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14634 {
14635 /* Read the zlib header. In this case, it should be "ZLIB"
14636 followed by the uncompressed section size, 8 bytes in
14637 big-endian order. */
14638 uncompressed_size = start[4]; uncompressed_size <<= 8;
14639 uncompressed_size += start[5]; uncompressed_size <<= 8;
14640 uncompressed_size += start[6]; uncompressed_size <<= 8;
14641 uncompressed_size += start[7]; uncompressed_size <<= 8;
14642 uncompressed_size += start[8]; uncompressed_size <<= 8;
14643 uncompressed_size += start[9]; uncompressed_size <<= 8;
14644 uncompressed_size += start[10]; uncompressed_size <<= 8;
14645 uncompressed_size += start[11];
14646 start += 12;
14647 new_size -= 12;
14648 }
14649
1835f746
NC
14650 if (uncompressed_size)
14651 {
14652 if (uncompress_section_contents (& start,
14653 uncompressed_size, & new_size))
14654 num_bytes = new_size;
14655 else
14656 {
14657 error (_("Unable to decompress section %s\n"),
dda8d76d 14658 printable_section_name (filedata, section));
f761cb13 14659 goto error_out;
1835f746
NC
14660 }
14661 }
bc303e5d
NC
14662 else
14663 start = real_start;
0e602686 14664 }
fd8008d8 14665
cf13d699
NC
14666 /* If the section being dumped has relocations against it the user might
14667 be expecting these relocations to have been applied. Check for this
14668 case and issue a warning message in order to avoid confusion.
14669 FIXME: Maybe we ought to have an option that dumps a section with
14670 relocs applied ? */
dda8d76d
NC
14671 for (relsec = filedata->section_headers;
14672 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14673 ++relsec)
14674 {
14675 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14676 || relsec->sh_info >= filedata->file_header.e_shnum
14677 || filedata->section_headers + relsec->sh_info != section
cf13d699 14678 || relsec->sh_size == 0
dda8d76d 14679 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14680 continue;
14681
14682 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14683 break;
14684 }
14685
cf13d699
NC
14686 data = start;
14687 end = start + num_bytes;
015dc7e1 14688 some_strings_shown = false;
cf13d699 14689
ba3265d0
NC
14690#ifdef HAVE_MBSTATE_T
14691 mbstate_t state;
14692 /* Initialise the multibyte conversion state. */
14693 memset (& state, 0, sizeof (state));
14694#endif
14695
015dc7e1 14696 bool continuing = false;
ba3265d0 14697
cf13d699
NC
14698 while (data < end)
14699 {
14700 while (!ISPRINT (* data))
14701 if (++ data >= end)
14702 break;
14703
14704 if (data < end)
14705 {
071436c6
NC
14706 size_t maxlen = end - data;
14707
ba3265d0
NC
14708 if (continuing)
14709 {
14710 printf (" ");
015dc7e1 14711 continuing = false;
ba3265d0
NC
14712 }
14713 else
14714 {
d1ce973e 14715 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
14716 }
14717
4082ef84
NC
14718 if (maxlen > 0)
14719 {
f3da8a96 14720 char c = 0;
ba3265d0
NC
14721
14722 while (maxlen)
14723 {
14724 c = *data++;
14725
14726 if (c == 0)
14727 break;
14728
14729 /* PR 25543: Treat new-lines as string-ending characters. */
14730 if (c == '\n')
14731 {
14732 printf ("\\n\n");
14733 if (*data != 0)
015dc7e1 14734 continuing = true;
ba3265d0
NC
14735 break;
14736 }
14737
14738 /* Do not print control characters directly as they can affect terminal
14739 settings. Such characters usually appear in the names generated
14740 by the assembler for local labels. */
14741 if (ISCNTRL (c))
14742 {
14743 printf ("^%c", c + 0x40);
14744 }
14745 else if (ISPRINT (c))
14746 {
14747 putchar (c);
14748 }
14749 else
14750 {
14751 size_t n;
14752#ifdef HAVE_MBSTATE_T
14753 wchar_t w;
14754#endif
14755 /* Let printf do the hard work of displaying multibyte characters. */
14756 printf ("%.1s", data - 1);
14757#ifdef HAVE_MBSTATE_T
14758 /* Try to find out how many bytes made up the character that was
14759 just printed. Advance the symbol pointer past the bytes that
14760 were displayed. */
14761 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
14762#else
14763 n = 1;
14764#endif
14765 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
14766 data += (n - 1);
14767 }
14768 }
14769
14770 if (c != '\n')
14771 putchar ('\n');
4082ef84
NC
14772 }
14773 else
14774 {
14775 printf (_("<corrupt>\n"));
14776 data = end;
14777 }
015dc7e1 14778 some_strings_shown = true;
cf13d699
NC
14779 }
14780 }
14781
14782 if (! some_strings_shown)
14783 printf (_(" No strings found in this section."));
14784
0e602686 14785 free (real_start);
cf13d699
NC
14786
14787 putchar ('\n');
015dc7e1 14788 return true;
f761cb13
AM
14789
14790error_out:
14791 free (real_start);
015dc7e1 14792 return false;
cf13d699
NC
14793}
14794
015dc7e1
AM
14795static bool
14796dump_section_as_bytes (Elf_Internal_Shdr *section,
14797 Filedata *filedata,
14798 bool relocate)
cf13d699
NC
14799{
14800 Elf_Internal_Shdr * relsec;
0e602686
NC
14801 bfd_size_type bytes;
14802 bfd_size_type section_size;
14803 bfd_vma addr;
14804 unsigned char * data;
14805 unsigned char * real_start;
14806 unsigned char * start;
14807
dda8d76d 14808 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14809 if (start == NULL)
c6b78c96 14810 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 14811 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 14812
0e602686 14813 section_size = section->sh_size;
cf13d699 14814
835f2fae
NC
14815 if (filedata->is_separate)
14816 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
14817 printable_section_name (filedata, section),
14818 filedata->file_name);
14819 else
14820 printf (_("\nHex dump of section '%s':\n"),
14821 printable_section_name (filedata, section));
cf13d699 14822
0e602686
NC
14823 if (decompress_dumps)
14824 {
14825 dwarf_size_type new_size = section_size;
14826 dwarf_size_type uncompressed_size = 0;
14827
14828 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14829 {
14830 Elf_Internal_Chdr chdr;
14831 unsigned int compression_header_size
ebdf1ebf 14832 = get_compression_header (& chdr, start, section_size);
0e602686 14833
5844b465
NC
14834 if (compression_header_size == 0)
14835 /* An error message will have already been generated
14836 by get_compression_header. */
14837 goto error_out;
14838
813dabb9 14839 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14840 {
813dabb9 14841 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14842 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14843 goto error_out;
0e602686 14844 }
813dabb9
L
14845 uncompressed_size = chdr.ch_size;
14846 start += compression_header_size;
14847 new_size -= compression_header_size;
0e602686
NC
14848 }
14849 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14850 {
14851 /* Read the zlib header. In this case, it should be "ZLIB"
14852 followed by the uncompressed section size, 8 bytes in
14853 big-endian order. */
14854 uncompressed_size = start[4]; uncompressed_size <<= 8;
14855 uncompressed_size += start[5]; uncompressed_size <<= 8;
14856 uncompressed_size += start[6]; uncompressed_size <<= 8;
14857 uncompressed_size += start[7]; uncompressed_size <<= 8;
14858 uncompressed_size += start[8]; uncompressed_size <<= 8;
14859 uncompressed_size += start[9]; uncompressed_size <<= 8;
14860 uncompressed_size += start[10]; uncompressed_size <<= 8;
14861 uncompressed_size += start[11];
14862 start += 12;
14863 new_size -= 12;
14864 }
14865
f055032e
NC
14866 if (uncompressed_size)
14867 {
14868 if (uncompress_section_contents (& start, uncompressed_size,
14869 & new_size))
bc303e5d
NC
14870 {
14871 section_size = new_size;
14872 }
f055032e
NC
14873 else
14874 {
14875 error (_("Unable to decompress section %s\n"),
dda8d76d 14876 printable_section_name (filedata, section));
bc303e5d 14877 /* FIXME: Print the section anyway ? */
f761cb13 14878 goto error_out;
f055032e
NC
14879 }
14880 }
bc303e5d
NC
14881 else
14882 start = real_start;
0e602686 14883 }
14ae95f2 14884
cf13d699
NC
14885 if (relocate)
14886 {
dda8d76d 14887 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 14888 goto error_out;
cf13d699
NC
14889 }
14890 else
14891 {
14892 /* If the section being dumped has relocations against it the user might
14893 be expecting these relocations to have been applied. Check for this
14894 case and issue a warning message in order to avoid confusion.
14895 FIXME: Maybe we ought to have an option that dumps a section with
14896 relocs applied ? */
dda8d76d
NC
14897 for (relsec = filedata->section_headers;
14898 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14899 ++relsec)
14900 {
14901 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14902 || relsec->sh_info >= filedata->file_header.e_shnum
14903 || filedata->section_headers + relsec->sh_info != section
cf13d699 14904 || relsec->sh_size == 0
dda8d76d 14905 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14906 continue;
14907
14908 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14909 break;
14910 }
14911 }
14912
14913 addr = section->sh_addr;
0e602686 14914 bytes = section_size;
cf13d699
NC
14915 data = start;
14916
14917 while (bytes)
14918 {
14919 int j;
14920 int k;
14921 int lbytes;
14922
14923 lbytes = (bytes > 16 ? 16 : bytes);
14924
14925 printf (" 0x%8.8lx ", (unsigned long) addr);
14926
14927 for (j = 0; j < 16; j++)
14928 {
14929 if (j < lbytes)
14930 printf ("%2.2x", data[j]);
14931 else
14932 printf (" ");
14933
14934 if ((j & 3) == 3)
14935 printf (" ");
14936 }
14937
14938 for (j = 0; j < lbytes; j++)
14939 {
14940 k = data[j];
14941 if (k >= ' ' && k < 0x7f)
14942 printf ("%c", k);
14943 else
14944 printf (".");
14945 }
14946
14947 putchar ('\n');
14948
14949 data += lbytes;
14950 addr += lbytes;
14951 bytes -= lbytes;
14952 }
14953
0e602686 14954 free (real_start);
cf13d699
NC
14955
14956 putchar ('\n');
015dc7e1 14957 return true;
f761cb13
AM
14958
14959 error_out:
14960 free (real_start);
015dc7e1 14961 return false;
cf13d699
NC
14962}
14963
094e34f2 14964#ifdef ENABLE_LIBCTF
7d9813f1
NA
14965static ctf_sect_t *
14966shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
14967{
b9e920ec 14968 buf->cts_name = SECTION_NAME_PRINT (shdr);
7d9813f1
NA
14969 buf->cts_size = shdr->sh_size;
14970 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
14971
14972 return buf;
14973}
14974
14975/* Formatting callback function passed to ctf_dump. Returns either the pointer
14976 it is passed, or a pointer to newly-allocated storage, in which case
14977 dump_ctf() will free it when it no longer needs it. */
14978
2f6ecaed
NA
14979static char *
14980dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14981 char *s, void *arg)
7d9813f1 14982{
3e50a591 14983 const char *blanks = arg;
7d9813f1
NA
14984 char *new_s;
14985
3e50a591 14986 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
14987 return s;
14988 return new_s;
14989}
14990
926c9e76
NA
14991/* Dump CTF errors/warnings. */
14992static void
139633c3 14993dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
14994{
14995 ctf_next_t *it = NULL;
14996 char *errtext;
14997 int is_warning;
14998 int err;
14999
15000 /* Dump accumulated errors and warnings. */
15001 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15002 {
5e9b84f7 15003 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15004 errtext);
15005 free (errtext);
15006 }
15007 if (err != ECTF_NEXT_END)
15008 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15009}
15010
2f6ecaed
NA
15011/* Dump one CTF archive member. */
15012
15013static int
139633c3 15014dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
2f6ecaed 15015{
139633c3 15016 ctf_dict_t *parent = (ctf_dict_t *) arg;
2f6ecaed
NA
15017 const char *things[] = {"Header", "Labels", "Data objects",
15018 "Function objects", "Variables", "Types", "Strings",
15019 ""};
15020 const char **thing;
15021 size_t i;
8b37e7b6 15022 int err = 0;
2f6ecaed
NA
15023
15024 /* Only print out the name of non-default-named archive members.
15025 The name .ctf appears everywhere, even for things that aren't
15026 really archives, so printing it out is liable to be confusing.
15027
15028 The parent, if there is one, is the default-owned archive member:
15029 avoid importing it into itself. (This does no harm, but looks
15030 confusing.) */
15031
15032 if (strcmp (name, ".ctf") != 0)
15033 {
15034 printf (_("\nCTF archive member: %s:\n"), name);
15035 ctf_import (ctf, parent);
15036 }
15037
15038 for (i = 0, thing = things; *thing[0]; thing++, i++)
15039 {
15040 ctf_dump_state_t *s = NULL;
15041 char *item;
15042
15043 printf ("\n %s:\n", *thing);
15044 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15045 (void *) " ")) != NULL)
15046 {
15047 printf ("%s\n", item);
15048 free (item);
15049 }
15050
15051 if (ctf_errno (ctf))
15052 {
15053 error (_("Iteration failed: %s, %s\n"), *thing,
15054 ctf_errmsg (ctf_errno (ctf)));
8b37e7b6
NA
15055 err = 1;
15056 goto out;
2f6ecaed
NA
15057 }
15058 }
8b37e7b6
NA
15059
15060 out:
926c9e76 15061 dump_ctf_errs (ctf);
8b37e7b6 15062 return err;
2f6ecaed
NA
15063}
15064
015dc7e1 15065static bool
7d9813f1
NA
15066dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15067{
15068 Elf_Internal_Shdr * parent_sec = NULL;
15069 Elf_Internal_Shdr * symtab_sec = NULL;
15070 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15071 void * data = NULL;
15072 void * symdata = NULL;
15073 void * strdata = NULL;
15074 void * parentdata = NULL;
15075 ctf_sect_t ctfsect, symsect, strsect, parentsect;
15076 ctf_sect_t * symsectp = NULL;
15077 ctf_sect_t * strsectp = NULL;
2f6ecaed
NA
15078 ctf_archive_t * ctfa = NULL;
15079 ctf_archive_t * parenta = NULL, *lookparent;
139633c3 15080 ctf_dict_t * parent = NULL;
7d9813f1 15081
7d9813f1 15082 int err;
015dc7e1 15083 bool ret = false;
7d9813f1
NA
15084
15085 shdr_to_ctf_sect (&ctfsect, section, filedata);
15086 data = get_section_contents (section, filedata);
15087 ctfsect.cts_data = data;
15088
616febde 15089 if (!dump_ctf_symtab_name)
3d16b64e 15090 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15091
15092 if (!dump_ctf_strtab_name)
3d16b64e 15093 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15094
15095 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15096 {
15097 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15098 {
15099 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15100 goto fail;
15101 }
15102 if ((symdata = (void *) get_data (NULL, filedata,
15103 symtab_sec->sh_offset, 1,
15104 symtab_sec->sh_size,
15105 _("symbols"))) == NULL)
15106 goto fail;
15107 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15108 symsect.cts_data = symdata;
15109 }
835f2fae 15110
df16e041 15111 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15112 {
15113 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15114 {
15115 error (_("No string table section named %s\n"),
15116 dump_ctf_strtab_name);
15117 goto fail;
15118 }
15119 if ((strdata = (void *) get_data (NULL, filedata,
15120 strtab_sec->sh_offset, 1,
15121 strtab_sec->sh_size,
15122 _("strings"))) == NULL)
15123 goto fail;
15124 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15125 strsect.cts_data = strdata;
15126 }
835f2fae 15127
7d9813f1
NA
15128 if (dump_ctf_parent_name)
15129 {
15130 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
15131 {
15132 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
15133 goto fail;
15134 }
15135 if ((parentdata = (void *) get_data (NULL, filedata,
15136 parent_sec->sh_offset, 1,
15137 parent_sec->sh_size,
15138 _("CTF parent"))) == NULL)
15139 goto fail;
15140 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
15141 parentsect.cts_data = parentdata;
15142 }
15143
2f6ecaed
NA
15144 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15145 libctf papers over the difference, so we can pretend it is always an
15146 archive. Possibly open the parent as well, if one was specified. */
7d9813f1 15147
2f6ecaed 15148 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15149 {
926c9e76 15150 dump_ctf_errs (NULL);
7d9813f1
NA
15151 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15152 goto fail;
15153 }
15154
96c61be5
NA
15155 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15156 != ELFDATA2MSB);
15157
7d9813f1
NA
15158 if (parentdata)
15159 {
2f6ecaed
NA
15160 if ((parenta = ctf_arc_bufopen (&parentsect, symsectp, strsectp,
15161 &err)) == NULL)
7d9813f1 15162 {
926c9e76 15163 dump_ctf_errs (NULL);
7d9813f1
NA
15164 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15165 goto fail;
15166 }
2f6ecaed
NA
15167 lookparent = parenta;
15168 }
15169 else
15170 lookparent = ctfa;
7d9813f1 15171
2f6ecaed
NA
15172 /* Assume that the applicable parent archive member is the default one.
15173 (This is what all known implementations are expected to do, if they
15174 put CTFs and their parents in archives together.) */
ae41200b 15175 if ((parent = ctf_dict_open (lookparent, NULL, &err)) == NULL)
2f6ecaed 15176 {
926c9e76 15177 dump_ctf_errs (NULL);
2f6ecaed
NA
15178 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15179 goto fail;
7d9813f1
NA
15180 }
15181
015dc7e1 15182 ret = true;
7d9813f1 15183
835f2fae
NC
15184 if (filedata->is_separate)
15185 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15186 printable_section_name (filedata, section),
15187 filedata->file_name);
15188 else
15189 printf (_("\nDump of CTF section '%s':\n"),
15190 printable_section_name (filedata, section));
7d9813f1 15191
83d59285
NA
15192 if ((err = ctf_archive_iter (ctfa, dump_ctf_archive_member, parent)) != 0)
15193 {
15194 dump_ctf_errs (NULL);
15195 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
015dc7e1 15196 ret = false;
83d59285 15197 }
7d9813f1
NA
15198
15199 fail:
139633c3 15200 ctf_dict_close (parent);
2f6ecaed
NA
15201 ctf_close (ctfa);
15202 ctf_close (parenta);
7d9813f1
NA
15203 free (parentdata);
15204 free (data);
15205 free (symdata);
15206 free (strdata);
15207 return ret;
15208}
094e34f2 15209#endif
7d9813f1 15210
015dc7e1 15211static bool
dda8d76d
NC
15212load_specific_debug_section (enum dwarf_section_display_enum debug,
15213 const Elf_Internal_Shdr * sec,
15214 void * data)
1007acb3 15215{
2cf0635d 15216 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15217 char buf [64];
dda8d76d 15218 Filedata * filedata = (Filedata *) data;
9abca702 15219
19e6b90e 15220 if (section->start != NULL)
dda8d76d
NC
15221 {
15222 /* If it is already loaded, do nothing. */
15223 if (streq (section->filename, filedata->file_name))
015dc7e1 15224 return true;
dda8d76d
NC
15225 free (section->start);
15226 }
1007acb3 15227
19e6b90e
L
15228 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15229 section->address = sec->sh_addr;
dda8d76d
NC
15230 section->filename = filedata->file_name;
15231 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15232 sec->sh_offset, 1,
15233 sec->sh_size, buf);
59245841
NC
15234 if (section->start == NULL)
15235 section->size = 0;
15236 else
15237 {
77115a4a
L
15238 unsigned char *start = section->start;
15239 dwarf_size_type size = sec->sh_size;
dab394de 15240 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15241
15242 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15243 {
15244 Elf_Internal_Chdr chdr;
d8024a91
NC
15245 unsigned int compression_header_size;
15246
f53be977
L
15247 if (size < (is_32bit_elf
15248 ? sizeof (Elf32_External_Chdr)
15249 : sizeof (Elf64_External_Chdr)))
d8024a91 15250 {
55be8fd0 15251 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15252 section->name);
015dc7e1 15253 return false;
d8024a91
NC
15254 }
15255
ebdf1ebf 15256 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15257 if (compression_header_size == 0)
15258 /* An error message will have already been generated
15259 by get_compression_header. */
015dc7e1 15260 return false;
d8024a91 15261
813dabb9
L
15262 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15263 {
15264 warn (_("section '%s' has unsupported compress type: %d\n"),
15265 section->name, chdr.ch_type);
015dc7e1 15266 return false;
813dabb9 15267 }
dab394de 15268 uncompressed_size = chdr.ch_size;
77115a4a
L
15269 start += compression_header_size;
15270 size -= compression_header_size;
15271 }
dab394de
L
15272 else if (size > 12 && streq ((char *) start, "ZLIB"))
15273 {
15274 /* Read the zlib header. In this case, it should be "ZLIB"
15275 followed by the uncompressed section size, 8 bytes in
15276 big-endian order. */
15277 uncompressed_size = start[4]; uncompressed_size <<= 8;
15278 uncompressed_size += start[5]; uncompressed_size <<= 8;
15279 uncompressed_size += start[6]; uncompressed_size <<= 8;
15280 uncompressed_size += start[7]; uncompressed_size <<= 8;
15281 uncompressed_size += start[8]; uncompressed_size <<= 8;
15282 uncompressed_size += start[9]; uncompressed_size <<= 8;
15283 uncompressed_size += start[10]; uncompressed_size <<= 8;
15284 uncompressed_size += start[11];
15285 start += 12;
15286 size -= 12;
15287 }
15288
1835f746 15289 if (uncompressed_size)
77115a4a 15290 {
1835f746
NC
15291 if (uncompress_section_contents (&start, uncompressed_size,
15292 &size))
15293 {
15294 /* Free the compressed buffer, update the section buffer
15295 and the section size if uncompress is successful. */
15296 free (section->start);
15297 section->start = start;
15298 }
15299 else
15300 {
15301 error (_("Unable to decompress section %s\n"),
dda8d76d 15302 printable_section_name (filedata, sec));
015dc7e1 15303 return false;
1835f746 15304 }
77115a4a 15305 }
bc303e5d 15306
77115a4a 15307 section->size = size;
59245841 15308 }
4a114e3e 15309
1b315056 15310 if (section->start == NULL)
015dc7e1 15311 return false;
1b315056 15312
19e6b90e 15313 if (debug_displays [debug].relocate)
32ec8896 15314 {
dda8d76d 15315 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15316 & section->reloc_info, & section->num_relocs))
015dc7e1 15317 return false;
32ec8896 15318 }
d1c4b12b
NC
15319 else
15320 {
15321 section->reloc_info = NULL;
15322 section->num_relocs = 0;
15323 }
1007acb3 15324
015dc7e1 15325 return true;
1007acb3
L
15326}
15327
301a9420
AM
15328#if HAVE_LIBDEBUGINFOD
15329/* Return a hex string representation of the build-id. */
15330unsigned char *
15331get_build_id (void * data)
15332{
ca0e11aa 15333 Filedata * filedata = (Filedata *) data;
301a9420
AM
15334 Elf_Internal_Shdr * shdr;
15335 unsigned long i;
15336
55be8fd0
NC
15337 /* Iterate through notes to find note.gnu.build-id.
15338 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15339 for (i = 0, shdr = filedata->section_headers;
15340 i < filedata->file_header.e_shnum && shdr != NULL;
15341 i++, shdr++)
15342 {
15343 if (shdr->sh_type != SHT_NOTE)
15344 continue;
15345
15346 char * next;
15347 char * end;
15348 size_t data_remaining;
15349 size_t min_notesz;
15350 Elf_External_Note * enote;
15351 Elf_Internal_Note inote;
15352
15353 bfd_vma offset = shdr->sh_offset;
15354 bfd_vma align = shdr->sh_addralign;
15355 bfd_vma length = shdr->sh_size;
15356
15357 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15358 if (enote == NULL)
15359 continue;
15360
15361 if (align < 4)
15362 align = 4;
15363 else if (align != 4 && align != 8)
f761cb13
AM
15364 {
15365 free (enote);
15366 continue;
15367 }
301a9420
AM
15368
15369 end = (char *) enote + length;
15370 data_remaining = end - (char *) enote;
15371
15372 if (!is_ia64_vms (filedata))
15373 {
15374 min_notesz = offsetof (Elf_External_Note, name);
15375 if (data_remaining < min_notesz)
15376 {
55be8fd0
NC
15377 warn (_("\
15378malformed note encountered in section %s whilst scanning for build-id note\n"),
15379 printable_section_name (filedata, shdr));
f761cb13 15380 free (enote);
55be8fd0 15381 continue;
301a9420
AM
15382 }
15383 data_remaining -= min_notesz;
15384
15385 inote.type = BYTE_GET (enote->type);
15386 inote.namesz = BYTE_GET (enote->namesz);
15387 inote.namedata = enote->name;
15388 inote.descsz = BYTE_GET (enote->descsz);
15389 inote.descdata = ((char *) enote
15390 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15391 inote.descpos = offset + (inote.descdata - (char *) enote);
15392 next = ((char *) enote
15393 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15394 }
15395 else
15396 {
15397 Elf64_External_VMS_Note *vms_enote;
15398
15399 /* PR binutils/15191
15400 Make sure that there is enough data to read. */
15401 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15402 if (data_remaining < min_notesz)
15403 {
55be8fd0
NC
15404 warn (_("\
15405malformed note encountered in section %s whilst scanning for build-id note\n"),
15406 printable_section_name (filedata, shdr));
f761cb13 15407 free (enote);
55be8fd0 15408 continue;
301a9420
AM
15409 }
15410 data_remaining -= min_notesz;
15411
15412 vms_enote = (Elf64_External_VMS_Note *) enote;
15413 inote.type = BYTE_GET (vms_enote->type);
15414 inote.namesz = BYTE_GET (vms_enote->namesz);
15415 inote.namedata = vms_enote->name;
15416 inote.descsz = BYTE_GET (vms_enote->descsz);
15417 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15418 inote.descpos = offset + (inote.descdata - (char *) enote);
15419 next = inote.descdata + align_power (inote.descsz, 3);
15420 }
15421
15422 /* Skip malformed notes. */
15423 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
15424 || (size_t) (inote.descdata - inote.namedata) > data_remaining
15425 || (size_t) (next - inote.descdata) < inote.descsz
15426 || ((size_t) (next - inote.descdata)
15427 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
15428 {
55be8fd0
NC
15429 warn (_("\
15430malformed note encountered in section %s whilst scanning for build-id note\n"),
15431 printable_section_name (filedata, shdr));
f761cb13 15432 free (enote);
301a9420
AM
15433 continue;
15434 }
15435
15436 /* Check if this is the build-id note. If so then convert the build-id
15437 bytes to a hex string. */
15438 if (inote.namesz > 0
24d127aa 15439 && startswith (inote.namedata, "GNU")
301a9420
AM
15440 && inote.type == NT_GNU_BUILD_ID)
15441 {
15442 unsigned long j;
15443 char * build_id;
15444
15445 build_id = malloc (inote.descsz * 2 + 1);
15446 if (build_id == NULL)
f761cb13
AM
15447 {
15448 free (enote);
15449 return NULL;
15450 }
301a9420
AM
15451
15452 for (j = 0; j < inote.descsz; ++j)
15453 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
15454 build_id[inote.descsz * 2] = '\0';
f761cb13 15455 free (enote);
301a9420 15456
55be8fd0 15457 return (unsigned char *) build_id;
301a9420 15458 }
f761cb13 15459 free (enote);
301a9420
AM
15460 }
15461
15462 return NULL;
15463}
15464#endif /* HAVE_LIBDEBUGINFOD */
15465
657d0d47
CC
15466/* If this is not NULL, load_debug_section will only look for sections
15467 within the list of sections given here. */
32ec8896 15468static unsigned int * section_subset = NULL;
657d0d47 15469
015dc7e1 15470bool
dda8d76d 15471load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 15472{
2cf0635d
NC
15473 struct dwarf_section * section = &debug_displays [debug].section;
15474 Elf_Internal_Shdr * sec;
dda8d76d
NC
15475 Filedata * filedata = (Filedata *) data;
15476
f425ec66
NC
15477 /* Without section headers we cannot find any sections. */
15478 if (filedata->section_headers == NULL)
015dc7e1 15479 return false;
f425ec66 15480
9c1ce108
AM
15481 if (filedata->string_table == NULL
15482 && filedata->file_header.e_shstrndx != SHN_UNDEF
15483 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
15484 {
15485 Elf_Internal_Shdr * strs;
15486
15487 /* Read in the string table, so that we have section names to scan. */
15488 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
15489
4dff97b2 15490 if (strs != NULL && strs->sh_size != 0)
dda8d76d 15491 {
9c1ce108
AM
15492 filedata->string_table
15493 = (char *) get_data (NULL, filedata, strs->sh_offset,
15494 1, strs->sh_size, _("string table"));
dda8d76d 15495
9c1ce108
AM
15496 filedata->string_table_length
15497 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
15498 }
15499 }
d966045b
DJ
15500
15501 /* Locate the debug section. */
dda8d76d 15502 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
15503 if (sec != NULL)
15504 section->name = section->uncompressed_name;
15505 else
15506 {
dda8d76d 15507 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
15508 if (sec != NULL)
15509 section->name = section->compressed_name;
15510 }
15511 if (sec == NULL)
015dc7e1 15512 return false;
d966045b 15513
657d0d47
CC
15514 /* If we're loading from a subset of sections, and we've loaded
15515 a section matching this name before, it's likely that it's a
15516 different one. */
15517 if (section_subset != NULL)
15518 free_debug_section (debug);
15519
dda8d76d 15520 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
15521}
15522
19e6b90e
L
15523void
15524free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 15525{
2cf0635d 15526 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 15527
19e6b90e
L
15528 if (section->start == NULL)
15529 return;
1007acb3 15530
19e6b90e
L
15531 free ((char *) section->start);
15532 section->start = NULL;
15533 section->address = 0;
15534 section->size = 0;
a788aedd 15535
9db70fc3
AM
15536 free (section->reloc_info);
15537 section->reloc_info = NULL;
15538 section->num_relocs = 0;
1007acb3
L
15539}
15540
015dc7e1 15541static bool
dda8d76d 15542display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 15543{
b9e920ec 15544 char * name = SECTION_NAME_VALID (section) ? SECTION_NAME (section) : "";
dda8d76d 15545 const char * print_name = printable_section_name (filedata, section);
19e6b90e 15546 bfd_size_type length;
015dc7e1 15547 bool result = true;
3f5e193b 15548 int i;
1007acb3 15549
19e6b90e
L
15550 length = section->sh_size;
15551 if (length == 0)
1007acb3 15552 {
74e1a04b 15553 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 15554 return true;
1007acb3 15555 }
5dff79d8
NC
15556 if (section->sh_type == SHT_NOBITS)
15557 {
15558 /* There is no point in dumping the contents of a debugging section
15559 which has the NOBITS type - the bits in the file will be random.
15560 This can happen when a file containing a .eh_frame section is
15561 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
15562 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
15563 print_name);
015dc7e1 15564 return false;
5dff79d8 15565 }
1007acb3 15566
24d127aa 15567 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 15568 name = ".debug_info";
1007acb3 15569
19e6b90e
L
15570 /* See if we know how to display the contents of this section. */
15571 for (i = 0; i < max; i++)
d85bf2ba
NC
15572 {
15573 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
15574 struct dwarf_section_display * display = debug_displays + i;
15575 struct dwarf_section * sec = & display->section;
d966045b 15576
d85bf2ba 15577 if (streq (sec->uncompressed_name, name)
24d127aa 15578 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15579 || streq (sec->compressed_name, name))
15580 {
015dc7e1 15581 bool secondary = (section != find_section (filedata, name));
1007acb3 15582
d85bf2ba
NC
15583 if (secondary)
15584 free_debug_section (id);
dda8d76d 15585
24d127aa 15586 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15587 sec->name = name;
15588 else if (streq (sec->uncompressed_name, name))
15589 sec->name = sec->uncompressed_name;
15590 else
15591 sec->name = sec->compressed_name;
657d0d47 15592
d85bf2ba
NC
15593 if (load_specific_debug_section (id, section, filedata))
15594 {
15595 /* If this debug section is part of a CU/TU set in a .dwp file,
15596 restrict load_debug_section to the sections in that set. */
15597 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 15598
d85bf2ba 15599 result &= display->display (sec, filedata);
657d0d47 15600
d85bf2ba 15601 section_subset = NULL;
1007acb3 15602
44266f36 15603 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
15604 free_debug_section (id);
15605 }
15606 break;
15607 }
15608 }
1007acb3 15609
19e6b90e 15610 if (i == max)
1007acb3 15611 {
74e1a04b 15612 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 15613 result = false;
1007acb3
L
15614 }
15615
19e6b90e 15616 return result;
5b18a4bc 15617}
103f02d3 15618
aef1f6d0
DJ
15619/* Set DUMP_SECTS for all sections where dumps were requested
15620 based on section name. */
15621
15622static void
dda8d76d 15623initialise_dumps_byname (Filedata * filedata)
aef1f6d0 15624{
2cf0635d 15625 struct dump_list_entry * cur;
aef1f6d0
DJ
15626
15627 for (cur = dump_sects_byname; cur; cur = cur->next)
15628 {
15629 unsigned int i;
015dc7e1 15630 bool any = false;
aef1f6d0 15631
dda8d76d 15632 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
15633 if (SECTION_NAME_VALID (filedata->section_headers + i)
15634 && streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 15635 {
6431e409 15636 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 15637 any = true;
aef1f6d0
DJ
15638 }
15639
835f2fae
NC
15640 if (!any && !filedata->is_separate)
15641 warn (_("Section '%s' was not dumped because it does not exist\n"),
15642 cur->name);
aef1f6d0
DJ
15643 }
15644}
15645
015dc7e1 15646static bool
dda8d76d 15647process_section_contents (Filedata * filedata)
5b18a4bc 15648{
2cf0635d 15649 Elf_Internal_Shdr * section;
19e6b90e 15650 unsigned int i;
015dc7e1 15651 bool res = true;
103f02d3 15652
19e6b90e 15653 if (! do_dump)
015dc7e1 15654 return true;
103f02d3 15655
dda8d76d 15656 initialise_dumps_byname (filedata);
aef1f6d0 15657
dda8d76d 15658 for (i = 0, section = filedata->section_headers;
6431e409 15659 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
15660 i++, section++)
15661 {
6431e409 15662 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 15663
d6bfbc39
NC
15664 if (filedata->is_separate && ! process_links)
15665 dump &= DEBUG_DUMP;
047c3dbf 15666
19e6b90e 15667#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
15668 if (dump & DISASS_DUMP)
15669 {
15670 if (! disassemble_section (section, filedata))
015dc7e1 15671 res = false;
dda8d76d 15672 }
19e6b90e 15673#endif
dda8d76d 15674 if (dump & HEX_DUMP)
32ec8896 15675 {
015dc7e1
AM
15676 if (! dump_section_as_bytes (section, filedata, false))
15677 res = false;
32ec8896 15678 }
103f02d3 15679
dda8d76d 15680 if (dump & RELOC_DUMP)
32ec8896 15681 {
015dc7e1
AM
15682 if (! dump_section_as_bytes (section, filedata, true))
15683 res = false;
32ec8896 15684 }
09c11c86 15685
dda8d76d 15686 if (dump & STRING_DUMP)
32ec8896 15687 {
dda8d76d 15688 if (! dump_section_as_strings (section, filedata))
015dc7e1 15689 res = false;
32ec8896 15690 }
cf13d699 15691
dda8d76d 15692 if (dump & DEBUG_DUMP)
32ec8896 15693 {
dda8d76d 15694 if (! display_debug_section (i, section, filedata))
015dc7e1 15695 res = false;
32ec8896 15696 }
7d9813f1 15697
094e34f2 15698#ifdef ENABLE_LIBCTF
7d9813f1
NA
15699 if (dump & CTF_DUMP)
15700 {
15701 if (! dump_section_as_ctf (section, filedata))
015dc7e1 15702 res = false;
7d9813f1 15703 }
094e34f2 15704#endif
5b18a4bc 15705 }
103f02d3 15706
835f2fae 15707 if (! filedata->is_separate)
0ee3043f 15708 {
835f2fae
NC
15709 /* Check to see if the user requested a
15710 dump of a section that does not exist. */
15711 for (; i < filedata->dump.num_dump_sects; i++)
15712 if (filedata->dump.dump_sects[i])
15713 {
ca0e11aa 15714 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 15715 res = false;
835f2fae 15716 }
0ee3043f 15717 }
32ec8896
NC
15718
15719 return res;
5b18a4bc 15720}
103f02d3 15721
5b18a4bc 15722static void
19e6b90e 15723process_mips_fpe_exception (int mask)
5b18a4bc 15724{
19e6b90e
L
15725 if (mask)
15726 {
015dc7e1 15727 bool first = true;
32ec8896 15728
19e6b90e 15729 if (mask & OEX_FPU_INEX)
015dc7e1 15730 fputs ("INEX", stdout), first = false;
19e6b90e 15731 if (mask & OEX_FPU_UFLO)
015dc7e1 15732 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 15733 if (mask & OEX_FPU_OFLO)
015dc7e1 15734 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 15735 if (mask & OEX_FPU_DIV0)
015dc7e1 15736 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
15737 if (mask & OEX_FPU_INVAL)
15738 printf ("%sINVAL", first ? "" : "|");
15739 }
5b18a4bc 15740 else
19e6b90e 15741 fputs ("0", stdout);
5b18a4bc 15742}
103f02d3 15743
f6f0e17b
NC
15744/* Display's the value of TAG at location P. If TAG is
15745 greater than 0 it is assumed to be an unknown tag, and
15746 a message is printed to this effect. Otherwise it is
15747 assumed that a message has already been printed.
15748
15749 If the bottom bit of TAG is set it assumed to have a
15750 string value, otherwise it is assumed to have an integer
15751 value.
15752
15753 Returns an updated P pointing to the first unread byte
15754 beyond the end of TAG's value.
15755
15756 Reads at or beyond END will not be made. */
15757
15758static unsigned char *
60abdbed 15759display_tag_value (signed int tag,
f6f0e17b
NC
15760 unsigned char * p,
15761 const unsigned char * const end)
15762{
15763 unsigned long val;
15764
15765 if (tag > 0)
15766 printf (" Tag_unknown_%d: ", tag);
15767
15768 if (p >= end)
15769 {
4082ef84 15770 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
15771 }
15772 else if (tag & 1)
15773 {
071436c6
NC
15774 /* PR 17531 file: 027-19978-0.004. */
15775 size_t maxlen = (end - p) - 1;
15776
15777 putchar ('"');
4082ef84
NC
15778 if (maxlen > 0)
15779 {
15780 print_symbol ((int) maxlen, (const char *) p);
15781 p += strnlen ((char *) p, maxlen) + 1;
15782 }
15783 else
15784 {
15785 printf (_("<corrupt string tag>"));
15786 p = (unsigned char *) end;
15787 }
071436c6 15788 printf ("\"\n");
f6f0e17b
NC
15789 }
15790 else
15791 {
cd30bcef 15792 READ_ULEB (val, p, end);
f6f0e17b
NC
15793 printf ("%ld (0x%lx)\n", val, val);
15794 }
15795
4082ef84 15796 assert (p <= end);
f6f0e17b
NC
15797 return p;
15798}
15799
53a346d8
CZ
15800/* ARC ABI attributes section. */
15801
15802static unsigned char *
15803display_arc_attribute (unsigned char * p,
15804 const unsigned char * const end)
15805{
15806 unsigned int tag;
53a346d8
CZ
15807 unsigned int val;
15808
cd30bcef 15809 READ_ULEB (tag, p, end);
53a346d8
CZ
15810
15811 switch (tag)
15812 {
15813 case Tag_ARC_PCS_config:
cd30bcef 15814 READ_ULEB (val, p, end);
53a346d8
CZ
15815 printf (" Tag_ARC_PCS_config: ");
15816 switch (val)
15817 {
15818 case 0:
15819 printf (_("Absent/Non standard\n"));
15820 break;
15821 case 1:
15822 printf (_("Bare metal/mwdt\n"));
15823 break;
15824 case 2:
15825 printf (_("Bare metal/newlib\n"));
15826 break;
15827 case 3:
15828 printf (_("Linux/uclibc\n"));
15829 break;
15830 case 4:
15831 printf (_("Linux/glibc\n"));
15832 break;
15833 default:
15834 printf (_("Unknown\n"));
15835 break;
15836 }
15837 break;
15838
15839 case Tag_ARC_CPU_base:
cd30bcef 15840 READ_ULEB (val, p, end);
53a346d8
CZ
15841 printf (" Tag_ARC_CPU_base: ");
15842 switch (val)
15843 {
15844 default:
15845 case TAG_CPU_NONE:
15846 printf (_("Absent\n"));
15847 break;
15848 case TAG_CPU_ARC6xx:
15849 printf ("ARC6xx\n");
15850 break;
15851 case TAG_CPU_ARC7xx:
15852 printf ("ARC7xx\n");
15853 break;
15854 case TAG_CPU_ARCEM:
15855 printf ("ARCEM\n");
15856 break;
15857 case TAG_CPU_ARCHS:
15858 printf ("ARCHS\n");
15859 break;
15860 }
15861 break;
15862
15863 case Tag_ARC_CPU_variation:
cd30bcef 15864 READ_ULEB (val, p, end);
53a346d8
CZ
15865 printf (" Tag_ARC_CPU_variation: ");
15866 switch (val)
15867 {
15868 default:
15869 if (val > 0 && val < 16)
53a346d8 15870 printf ("Core%d\n", val);
d8cbc93b
JL
15871 else
15872 printf ("Unknown\n");
15873 break;
15874
53a346d8
CZ
15875 case 0:
15876 printf (_("Absent\n"));
15877 break;
15878 }
15879 break;
15880
15881 case Tag_ARC_CPU_name:
15882 printf (" Tag_ARC_CPU_name: ");
15883 p = display_tag_value (-1, p, end);
15884 break;
15885
15886 case Tag_ARC_ABI_rf16:
cd30bcef 15887 READ_ULEB (val, p, end);
53a346d8
CZ
15888 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
15889 break;
15890
15891 case Tag_ARC_ABI_osver:
cd30bcef 15892 READ_ULEB (val, p, end);
53a346d8
CZ
15893 printf (" Tag_ARC_ABI_osver: v%d\n", val);
15894 break;
15895
15896 case Tag_ARC_ABI_pic:
15897 case Tag_ARC_ABI_sda:
cd30bcef 15898 READ_ULEB (val, p, end);
53a346d8
CZ
15899 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
15900 : " Tag_ARC_ABI_pic: ");
15901 switch (val)
15902 {
15903 case 0:
15904 printf (_("Absent\n"));
15905 break;
15906 case 1:
15907 printf ("MWDT\n");
15908 break;
15909 case 2:
15910 printf ("GNU\n");
15911 break;
15912 default:
15913 printf (_("Unknown\n"));
15914 break;
15915 }
15916 break;
15917
15918 case Tag_ARC_ABI_tls:
cd30bcef 15919 READ_ULEB (val, p, end);
53a346d8
CZ
15920 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
15921 break;
15922
15923 case Tag_ARC_ABI_enumsize:
cd30bcef 15924 READ_ULEB (val, p, end);
53a346d8
CZ
15925 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
15926 _("smallest"));
15927 break;
15928
15929 case Tag_ARC_ABI_exceptions:
cd30bcef 15930 READ_ULEB (val, p, end);
53a346d8
CZ
15931 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
15932 : _("default"));
15933 break;
15934
15935 case Tag_ARC_ABI_double_size:
cd30bcef 15936 READ_ULEB (val, p, end);
53a346d8
CZ
15937 printf (" Tag_ARC_ABI_double_size: %d\n", val);
15938 break;
15939
15940 case Tag_ARC_ISA_config:
15941 printf (" Tag_ARC_ISA_config: ");
15942 p = display_tag_value (-1, p, end);
15943 break;
15944
15945 case Tag_ARC_ISA_apex:
15946 printf (" Tag_ARC_ISA_apex: ");
15947 p = display_tag_value (-1, p, end);
15948 break;
15949
15950 case Tag_ARC_ISA_mpy_option:
cd30bcef 15951 READ_ULEB (val, p, end);
53a346d8
CZ
15952 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
15953 break;
15954
db1e1b45 15955 case Tag_ARC_ATR_version:
cd30bcef 15956 READ_ULEB (val, p, end);
db1e1b45 15957 printf (" Tag_ARC_ATR_version: %d\n", val);
15958 break;
15959
53a346d8
CZ
15960 default:
15961 return display_tag_value (tag & 1, p, end);
15962 }
15963
15964 return p;
15965}
15966
11c1ff18
PB
15967/* ARM EABI attributes section. */
15968typedef struct
15969{
70e99720 15970 unsigned int tag;
2cf0635d 15971 const char * name;
11c1ff18 15972 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 15973 unsigned int type;
288f0ba2 15974 const char *const *table;
11c1ff18
PB
15975} arm_attr_public_tag;
15976
288f0ba2 15977static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 15978 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 15979 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 15980 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
288f0ba2
AM
15981static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
15982static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 15983 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 15984static const char *const arm_attr_tag_FP_arch[] =
bca38921 15985 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 15986 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
15987static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
15988static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
15989 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
15990 "NEON for ARMv8.1"};
288f0ba2 15991static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
15992 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
15993 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 15994static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 15995 {"V6", "SB", "TLS", "Unused"};
288f0ba2 15996static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 15997 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 15998static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 15999 {"Absolute", "PC-relative", "None"};
288f0ba2 16000static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16001 {"None", "direct", "GOT-indirect"};
288f0ba2 16002static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16003 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16004static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16005static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16006 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16007static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16008static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16009static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16010 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16011static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16012 {"Unused", "small", "int", "forced to int"};
288f0ba2 16013static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16014 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16015static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16016 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16017static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16018 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16019static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16020 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16021 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16022static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16023 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16024 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16025static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16026static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16027 {"Not Allowed", "Allowed"};
288f0ba2 16028static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16029 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16030static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16031 {"Follow architecture", "Allowed"};
288f0ba2 16032static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16033 {"Not Allowed", "Allowed"};
288f0ba2 16034static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16035 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16036 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16037static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16038static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16039 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16040 "TrustZone and Virtualization Extensions"};
288f0ba2 16041static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16042 {"Not Allowed", "Allowed"};
11c1ff18 16043
288f0ba2 16044static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16045 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16046
11c1ff18
PB
16047#define LOOKUP(id, name) \
16048 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16049static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16050{
16051 {4, "CPU_raw_name", 1, NULL},
16052 {5, "CPU_name", 1, NULL},
16053 LOOKUP(6, CPU_arch),
16054 {7, "CPU_arch_profile", 0, NULL},
16055 LOOKUP(8, ARM_ISA_use),
16056 LOOKUP(9, THUMB_ISA_use),
75375b3e 16057 LOOKUP(10, FP_arch),
11c1ff18 16058 LOOKUP(11, WMMX_arch),
f5f53991
AS
16059 LOOKUP(12, Advanced_SIMD_arch),
16060 LOOKUP(13, PCS_config),
11c1ff18
PB
16061 LOOKUP(14, ABI_PCS_R9_use),
16062 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16063 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16064 LOOKUP(17, ABI_PCS_GOT_use),
16065 LOOKUP(18, ABI_PCS_wchar_t),
16066 LOOKUP(19, ABI_FP_rounding),
16067 LOOKUP(20, ABI_FP_denormal),
16068 LOOKUP(21, ABI_FP_exceptions),
16069 LOOKUP(22, ABI_FP_user_exceptions),
16070 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16071 {24, "ABI_align_needed", 0, NULL},
16072 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16073 LOOKUP(26, ABI_enum_size),
16074 LOOKUP(27, ABI_HardFP_use),
16075 LOOKUP(28, ABI_VFP_args),
16076 LOOKUP(29, ABI_WMMX_args),
16077 LOOKUP(30, ABI_optimization_goals),
16078 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16079 {32, "compatibility", 0, NULL},
f5f53991 16080 LOOKUP(34, CPU_unaligned_access),
75375b3e 16081 LOOKUP(36, FP_HP_extension),
8e79c3df 16082 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16083 LOOKUP(42, MPextension_use),
16084 LOOKUP(44, DIV_use),
15afaa63 16085 LOOKUP(46, DSP_extension),
a7ad558c 16086 LOOKUP(48, MVE_arch),
f5f53991
AS
16087 {64, "nodefaults", 0, NULL},
16088 {65, "also_compatible_with", 0, NULL},
16089 LOOKUP(66, T2EE_use),
16090 {67, "conformance", 1, NULL},
16091 LOOKUP(68, Virtualization_use),
cd21e546 16092 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16093};
16094#undef LOOKUP
16095
11c1ff18 16096static unsigned char *
f6f0e17b
NC
16097display_arm_attribute (unsigned char * p,
16098 const unsigned char * const end)
11c1ff18 16099{
70e99720 16100 unsigned int tag;
70e99720 16101 unsigned int val;
2cf0635d 16102 arm_attr_public_tag * attr;
11c1ff18 16103 unsigned i;
70e99720 16104 unsigned int type;
11c1ff18 16105
cd30bcef 16106 READ_ULEB (tag, p, end);
11c1ff18 16107 attr = NULL;
2cf0635d 16108 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16109 {
16110 if (arm_attr_public_tags[i].tag == tag)
16111 {
16112 attr = &arm_attr_public_tags[i];
16113 break;
16114 }
16115 }
16116
16117 if (attr)
16118 {
16119 printf (" Tag_%s: ", attr->name);
16120 switch (attr->type)
16121 {
16122 case 0:
16123 switch (tag)
16124 {
16125 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16126 READ_ULEB (val, p, end);
11c1ff18
PB
16127 switch (val)
16128 {
2b692964
NC
16129 case 0: printf (_("None\n")); break;
16130 case 'A': printf (_("Application\n")); break;
16131 case 'R': printf (_("Realtime\n")); break;
16132 case 'M': printf (_("Microcontroller\n")); break;
16133 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16134 default: printf ("??? (%d)\n", val); break;
16135 }
16136 break;
16137
75375b3e 16138 case 24: /* Tag_align_needed. */
cd30bcef 16139 READ_ULEB (val, p, end);
75375b3e
MGD
16140 switch (val)
16141 {
2b692964
NC
16142 case 0: printf (_("None\n")); break;
16143 case 1: printf (_("8-byte\n")); break;
16144 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16145 case 3: printf ("??? 3\n"); break;
16146 default:
16147 if (val <= 12)
dd24e3da 16148 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16149 1 << val);
16150 else
16151 printf ("??? (%d)\n", val);
16152 break;
16153 }
16154 break;
16155
16156 case 25: /* Tag_align_preserved. */
cd30bcef 16157 READ_ULEB (val, p, end);
75375b3e
MGD
16158 switch (val)
16159 {
2b692964
NC
16160 case 0: printf (_("None\n")); break;
16161 case 1: printf (_("8-byte, except leaf SP\n")); break;
16162 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16163 case 3: printf ("??? 3\n"); break;
16164 default:
16165 if (val <= 12)
dd24e3da 16166 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16167 1 << val);
16168 else
16169 printf ("??? (%d)\n", val);
16170 break;
16171 }
16172 break;
16173
11c1ff18 16174 case 32: /* Tag_compatibility. */
071436c6 16175 {
cd30bcef 16176 READ_ULEB (val, p, end);
071436c6 16177 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16178 if (p < end - 1)
16179 {
16180 size_t maxlen = (end - p) - 1;
16181
16182 print_symbol ((int) maxlen, (const char *) p);
16183 p += strnlen ((char *) p, maxlen) + 1;
16184 }
16185 else
16186 {
16187 printf (_("<corrupt>"));
16188 p = (unsigned char *) end;
16189 }
071436c6 16190 putchar ('\n');
071436c6 16191 }
11c1ff18
PB
16192 break;
16193
f5f53991 16194 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16195 /* PR 17531: file: 001-505008-0.01. */
16196 if (p < end)
16197 p++;
2b692964 16198 printf (_("True\n"));
f5f53991
AS
16199 break;
16200
16201 case 65: /* Tag_also_compatible_with. */
cd30bcef 16202 READ_ULEB (val, p, end);
f5f53991
AS
16203 if (val == 6 /* Tag_CPU_arch. */)
16204 {
cd30bcef 16205 READ_ULEB (val, p, end);
071436c6 16206 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16207 printf ("??? (%d)\n", val);
16208 else
16209 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16210 }
16211 else
16212 printf ("???\n");
071436c6
NC
16213 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16214 ;
f5f53991
AS
16215 break;
16216
11c1ff18 16217 default:
bee0ee85
NC
16218 printf (_("<unknown: %d>\n"), tag);
16219 break;
11c1ff18
PB
16220 }
16221 return p;
16222
16223 case 1:
f6f0e17b 16224 return display_tag_value (-1, p, end);
11c1ff18 16225 case 2:
f6f0e17b 16226 return display_tag_value (0, p, end);
11c1ff18
PB
16227
16228 default:
16229 assert (attr->type & 0x80);
cd30bcef 16230 READ_ULEB (val, p, end);
11c1ff18
PB
16231 type = attr->type & 0x7f;
16232 if (val >= type)
16233 printf ("??? (%d)\n", val);
16234 else
16235 printf ("%s\n", attr->table[val]);
16236 return p;
16237 }
16238 }
11c1ff18 16239
f6f0e17b 16240 return display_tag_value (tag, p, end);
11c1ff18
PB
16241}
16242
104d59d1 16243static unsigned char *
60bca95a 16244display_gnu_attribute (unsigned char * p,
60abdbed 16245 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16246 const unsigned char * const end)
104d59d1 16247{
cd30bcef 16248 unsigned int tag;
60abdbed 16249 unsigned int val;
104d59d1 16250
cd30bcef 16251 READ_ULEB (tag, p, end);
104d59d1
JM
16252
16253 /* Tag_compatibility is the only generic GNU attribute defined at
16254 present. */
16255 if (tag == 32)
16256 {
cd30bcef 16257 READ_ULEB (val, p, end);
071436c6
NC
16258
16259 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16260 if (p == end)
16261 {
071436c6 16262 printf (_("<corrupt>\n"));
f6f0e17b
NC
16263 warn (_("corrupt vendor attribute\n"));
16264 }
16265 else
16266 {
4082ef84
NC
16267 if (p < end - 1)
16268 {
16269 size_t maxlen = (end - p) - 1;
071436c6 16270
4082ef84
NC
16271 print_symbol ((int) maxlen, (const char *) p);
16272 p += strnlen ((char *) p, maxlen) + 1;
16273 }
16274 else
16275 {
16276 printf (_("<corrupt>"));
16277 p = (unsigned char *) end;
16278 }
071436c6 16279 putchar ('\n');
f6f0e17b 16280 }
104d59d1
JM
16281 return p;
16282 }
16283
16284 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16285 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16286
f6f0e17b 16287 return display_tag_value (tag, p, end);
104d59d1
JM
16288}
16289
85f7484a
PB
16290static unsigned char *
16291display_m68k_gnu_attribute (unsigned char * p,
16292 unsigned int tag,
16293 const unsigned char * const end)
16294{
16295 unsigned int val;
16296
16297 if (tag == Tag_GNU_M68K_ABI_FP)
16298 {
16299 printf (" Tag_GNU_M68K_ABI_FP: ");
16300 if (p == end)
16301 {
16302 printf (_("<corrupt>\n"));
16303 return p;
16304 }
16305 READ_ULEB (val, p, end);
16306
16307 if (val > 3)
16308 printf ("(%#x), ", val);
16309
16310 switch (val & 3)
16311 {
16312 case 0:
16313 printf (_("unspecified hard/soft float\n"));
16314 break;
16315 case 1:
16316 printf (_("hard float\n"));
16317 break;
16318 case 2:
16319 printf (_("soft float\n"));
16320 break;
16321 }
16322 return p;
16323 }
16324
16325 return display_tag_value (tag & 1, p, end);
16326}
16327
34c8bcba 16328static unsigned char *
f6f0e17b 16329display_power_gnu_attribute (unsigned char * p,
60abdbed 16330 unsigned int tag,
f6f0e17b 16331 const unsigned char * const end)
34c8bcba 16332{
005d79fd 16333 unsigned int val;
34c8bcba
JM
16334
16335 if (tag == Tag_GNU_Power_ABI_FP)
16336 {
34c8bcba 16337 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16338 if (p == end)
005d79fd
AM
16339 {
16340 printf (_("<corrupt>\n"));
16341 return p;
16342 }
cd30bcef 16343 READ_ULEB (val, p, end);
60bca95a 16344
005d79fd
AM
16345 if (val > 15)
16346 printf ("(%#x), ", val);
16347
16348 switch (val & 3)
34c8bcba
JM
16349 {
16350 case 0:
005d79fd 16351 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16352 break;
16353 case 1:
005d79fd 16354 printf (_("hard float, "));
34c8bcba
JM
16355 break;
16356 case 2:
005d79fd 16357 printf (_("soft float, "));
34c8bcba 16358 break;
3c7b9897 16359 case 3:
005d79fd 16360 printf (_("single-precision hard float, "));
3c7b9897 16361 break;
005d79fd
AM
16362 }
16363
16364 switch (val & 0xC)
16365 {
16366 case 0:
16367 printf (_("unspecified long double\n"));
16368 break;
16369 case 4:
16370 printf (_("128-bit IBM long double\n"));
16371 break;
16372 case 8:
16373 printf (_("64-bit long double\n"));
16374 break;
16375 case 12:
16376 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16377 break;
16378 }
16379 return p;
005d79fd 16380 }
34c8bcba 16381
c6e65352
DJ
16382 if (tag == Tag_GNU_Power_ABI_Vector)
16383 {
c6e65352 16384 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 16385 if (p == end)
005d79fd
AM
16386 {
16387 printf (_("<corrupt>\n"));
16388 return p;
16389 }
cd30bcef 16390 READ_ULEB (val, p, end);
005d79fd
AM
16391
16392 if (val > 3)
16393 printf ("(%#x), ", val);
16394
16395 switch (val & 3)
c6e65352
DJ
16396 {
16397 case 0:
005d79fd 16398 printf (_("unspecified\n"));
c6e65352
DJ
16399 break;
16400 case 1:
005d79fd 16401 printf (_("generic\n"));
c6e65352
DJ
16402 break;
16403 case 2:
16404 printf ("AltiVec\n");
16405 break;
16406 case 3:
16407 printf ("SPE\n");
16408 break;
c6e65352
DJ
16409 }
16410 return p;
005d79fd 16411 }
c6e65352 16412
f82e0623
NF
16413 if (tag == Tag_GNU_Power_ABI_Struct_Return)
16414 {
005d79fd 16415 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 16416 if (p == end)
f6f0e17b 16417 {
005d79fd 16418 printf (_("<corrupt>\n"));
f6f0e17b
NC
16419 return p;
16420 }
cd30bcef 16421 READ_ULEB (val, p, end);
0b4362b0 16422
005d79fd
AM
16423 if (val > 2)
16424 printf ("(%#x), ", val);
16425
16426 switch (val & 3)
16427 {
16428 case 0:
16429 printf (_("unspecified\n"));
16430 break;
16431 case 1:
16432 printf ("r3/r4\n");
16433 break;
16434 case 2:
16435 printf (_("memory\n"));
16436 break;
16437 case 3:
16438 printf ("???\n");
16439 break;
16440 }
f82e0623
NF
16441 return p;
16442 }
16443
f6f0e17b 16444 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
16445}
16446
643f7afb
AK
16447static unsigned char *
16448display_s390_gnu_attribute (unsigned char * p,
60abdbed 16449 unsigned int tag,
643f7afb
AK
16450 const unsigned char * const end)
16451{
cd30bcef 16452 unsigned int val;
643f7afb
AK
16453
16454 if (tag == Tag_GNU_S390_ABI_Vector)
16455 {
643f7afb 16456 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 16457 READ_ULEB (val, p, end);
643f7afb
AK
16458
16459 switch (val)
16460 {
16461 case 0:
16462 printf (_("any\n"));
16463 break;
16464 case 1:
16465 printf (_("software\n"));
16466 break;
16467 case 2:
16468 printf (_("hardware\n"));
16469 break;
16470 default:
16471 printf ("??? (%d)\n", val);
16472 break;
16473 }
16474 return p;
16475 }
16476
16477 return display_tag_value (tag & 1, p, end);
16478}
16479
9e8c70f9 16480static void
60abdbed 16481display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
16482{
16483 if (mask)
16484 {
015dc7e1 16485 bool first = true;
071436c6 16486
9e8c70f9 16487 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 16488 fputs ("mul32", stdout), first = false;
9e8c70f9 16489 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 16490 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 16491 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 16492 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 16493 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 16494 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 16495 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 16496 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 16497 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 16498 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 16499 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 16500 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 16501 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 16502 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 16503 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 16504 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 16505 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 16506 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 16507 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 16508 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 16509 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 16510 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 16511 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 16512 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 16513 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 16514 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 16515 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 16516 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 16517 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 16518 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
16519 }
16520 else
071436c6
NC
16521 fputc ('0', stdout);
16522 fputc ('\n', stdout);
9e8c70f9
DM
16523}
16524
3d68f91c 16525static void
60abdbed 16526display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
16527{
16528 if (mask)
16529 {
015dc7e1 16530 bool first = true;
071436c6 16531
3d68f91c 16532 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 16533 fputs ("fjathplus", stdout), first = false;
3d68f91c 16534 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 16535 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 16536 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 16537 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 16538 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 16539 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 16540 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 16541 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 16542 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 16543 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 16544 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 16545 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 16546 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 16547 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 16548 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 16549 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 16550 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 16551 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 16552 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 16553 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
16554 }
16555 else
071436c6
NC
16556 fputc ('0', stdout);
16557 fputc ('\n', stdout);
3d68f91c
JM
16558}
16559
9e8c70f9 16560static unsigned char *
f6f0e17b 16561display_sparc_gnu_attribute (unsigned char * p,
60abdbed 16562 unsigned int tag,
f6f0e17b 16563 const unsigned char * const end)
9e8c70f9 16564{
cd30bcef 16565 unsigned int val;
3d68f91c 16566
9e8c70f9
DM
16567 if (tag == Tag_GNU_Sparc_HWCAPS)
16568 {
cd30bcef 16569 READ_ULEB (val, p, end);
9e8c70f9 16570 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
16571 display_sparc_hwcaps (val);
16572 return p;
3d68f91c
JM
16573 }
16574 if (tag == Tag_GNU_Sparc_HWCAPS2)
16575 {
cd30bcef 16576 READ_ULEB (val, p, end);
3d68f91c
JM
16577 printf (" Tag_GNU_Sparc_HWCAPS2: ");
16578 display_sparc_hwcaps2 (val);
16579 return p;
16580 }
9e8c70f9 16581
f6f0e17b 16582 return display_tag_value (tag, p, end);
9e8c70f9
DM
16583}
16584
351cdf24 16585static void
32ec8896 16586print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
16587{
16588 switch (val)
16589 {
16590 case Val_GNU_MIPS_ABI_FP_ANY:
16591 printf (_("Hard or soft float\n"));
16592 break;
16593 case Val_GNU_MIPS_ABI_FP_DOUBLE:
16594 printf (_("Hard float (double precision)\n"));
16595 break;
16596 case Val_GNU_MIPS_ABI_FP_SINGLE:
16597 printf (_("Hard float (single precision)\n"));
16598 break;
16599 case Val_GNU_MIPS_ABI_FP_SOFT:
16600 printf (_("Soft float\n"));
16601 break;
16602 case Val_GNU_MIPS_ABI_FP_OLD_64:
16603 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
16604 break;
16605 case Val_GNU_MIPS_ABI_FP_XX:
16606 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
16607 break;
16608 case Val_GNU_MIPS_ABI_FP_64:
16609 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
16610 break;
16611 case Val_GNU_MIPS_ABI_FP_64A:
16612 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
16613 break;
3350cc01
CM
16614 case Val_GNU_MIPS_ABI_FP_NAN2008:
16615 printf (_("NaN 2008 compatibility\n"));
16616 break;
351cdf24
MF
16617 default:
16618 printf ("??? (%d)\n", val);
16619 break;
16620 }
16621}
16622
2cf19d5c 16623static unsigned char *
f6f0e17b 16624display_mips_gnu_attribute (unsigned char * p,
60abdbed 16625 unsigned int tag,
f6f0e17b 16626 const unsigned char * const end)
2cf19d5c 16627{
2cf19d5c
JM
16628 if (tag == Tag_GNU_MIPS_ABI_FP)
16629 {
32ec8896 16630 unsigned int val;
f6f0e17b 16631
2cf19d5c 16632 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 16633 READ_ULEB (val, p, end);
351cdf24 16634 print_mips_fp_abi_value (val);
2cf19d5c
JM
16635 return p;
16636 }
16637
a9f58168
CF
16638 if (tag == Tag_GNU_MIPS_ABI_MSA)
16639 {
32ec8896 16640 unsigned int val;
a9f58168 16641
a9f58168 16642 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 16643 READ_ULEB (val, p, end);
a9f58168
CF
16644
16645 switch (val)
16646 {
16647 case Val_GNU_MIPS_ABI_MSA_ANY:
16648 printf (_("Any MSA or not\n"));
16649 break;
16650 case Val_GNU_MIPS_ABI_MSA_128:
16651 printf (_("128-bit MSA\n"));
16652 break;
16653 default:
16654 printf ("??? (%d)\n", val);
16655 break;
16656 }
16657 return p;
16658 }
16659
f6f0e17b 16660 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
16661}
16662
59e6276b 16663static unsigned char *
f6f0e17b
NC
16664display_tic6x_attribute (unsigned char * p,
16665 const unsigned char * const end)
59e6276b 16666{
60abdbed 16667 unsigned int tag;
cd30bcef 16668 unsigned int val;
59e6276b 16669
cd30bcef 16670 READ_ULEB (tag, p, end);
59e6276b
JM
16671
16672 switch (tag)
16673 {
75fa6dc1 16674 case Tag_ISA:
75fa6dc1 16675 printf (" Tag_ISA: ");
cd30bcef 16676 READ_ULEB (val, p, end);
59e6276b
JM
16677
16678 switch (val)
16679 {
75fa6dc1 16680 case C6XABI_Tag_ISA_none:
59e6276b
JM
16681 printf (_("None\n"));
16682 break;
75fa6dc1 16683 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
16684 printf ("C62x\n");
16685 break;
75fa6dc1 16686 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
16687 printf ("C67x\n");
16688 break;
75fa6dc1 16689 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
16690 printf ("C67x+\n");
16691 break;
75fa6dc1 16692 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
16693 printf ("C64x\n");
16694 break;
75fa6dc1 16695 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
16696 printf ("C64x+\n");
16697 break;
75fa6dc1 16698 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
16699 printf ("C674x\n");
16700 break;
16701 default:
16702 printf ("??? (%d)\n", val);
16703 break;
16704 }
16705 return p;
16706
87779176 16707 case Tag_ABI_wchar_t:
87779176 16708 printf (" Tag_ABI_wchar_t: ");
cd30bcef 16709 READ_ULEB (val, p, end);
87779176
JM
16710 switch (val)
16711 {
16712 case 0:
16713 printf (_("Not used\n"));
16714 break;
16715 case 1:
16716 printf (_("2 bytes\n"));
16717 break;
16718 case 2:
16719 printf (_("4 bytes\n"));
16720 break;
16721 default:
16722 printf ("??? (%d)\n", val);
16723 break;
16724 }
16725 return p;
16726
16727 case Tag_ABI_stack_align_needed:
87779176 16728 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 16729 READ_ULEB (val, p, end);
87779176
JM
16730 switch (val)
16731 {
16732 case 0:
16733 printf (_("8-byte\n"));
16734 break;
16735 case 1:
16736 printf (_("16-byte\n"));
16737 break;
16738 default:
16739 printf ("??? (%d)\n", val);
16740 break;
16741 }
16742 return p;
16743
16744 case Tag_ABI_stack_align_preserved:
cd30bcef 16745 READ_ULEB (val, p, end);
87779176
JM
16746 printf (" Tag_ABI_stack_align_preserved: ");
16747 switch (val)
16748 {
16749 case 0:
16750 printf (_("8-byte\n"));
16751 break;
16752 case 1:
16753 printf (_("16-byte\n"));
16754 break;
16755 default:
16756 printf ("??? (%d)\n", val);
16757 break;
16758 }
16759 return p;
16760
b5593623 16761 case Tag_ABI_DSBT:
cd30bcef 16762 READ_ULEB (val, p, end);
b5593623
JM
16763 printf (" Tag_ABI_DSBT: ");
16764 switch (val)
16765 {
16766 case 0:
16767 printf (_("DSBT addressing not used\n"));
16768 break;
16769 case 1:
16770 printf (_("DSBT addressing used\n"));
16771 break;
16772 default:
16773 printf ("??? (%d)\n", val);
16774 break;
16775 }
16776 return p;
16777
87779176 16778 case Tag_ABI_PID:
cd30bcef 16779 READ_ULEB (val, p, end);
87779176
JM
16780 printf (" Tag_ABI_PID: ");
16781 switch (val)
16782 {
16783 case 0:
16784 printf (_("Data addressing position-dependent\n"));
16785 break;
16786 case 1:
16787 printf (_("Data addressing position-independent, GOT near DP\n"));
16788 break;
16789 case 2:
16790 printf (_("Data addressing position-independent, GOT far from DP\n"));
16791 break;
16792 default:
16793 printf ("??? (%d)\n", val);
16794 break;
16795 }
16796 return p;
16797
16798 case Tag_ABI_PIC:
cd30bcef 16799 READ_ULEB (val, p, end);
87779176
JM
16800 printf (" Tag_ABI_PIC: ");
16801 switch (val)
16802 {
16803 case 0:
16804 printf (_("Code addressing position-dependent\n"));
16805 break;
16806 case 1:
16807 printf (_("Code addressing position-independent\n"));
16808 break;
16809 default:
16810 printf ("??? (%d)\n", val);
16811 break;
16812 }
16813 return p;
16814
16815 case Tag_ABI_array_object_alignment:
cd30bcef 16816 READ_ULEB (val, p, end);
87779176
JM
16817 printf (" Tag_ABI_array_object_alignment: ");
16818 switch (val)
16819 {
16820 case 0:
16821 printf (_("8-byte\n"));
16822 break;
16823 case 1:
16824 printf (_("4-byte\n"));
16825 break;
16826 case 2:
16827 printf (_("16-byte\n"));
16828 break;
16829 default:
16830 printf ("??? (%d)\n", val);
16831 break;
16832 }
16833 return p;
16834
16835 case Tag_ABI_array_object_align_expected:
cd30bcef 16836 READ_ULEB (val, p, end);
87779176
JM
16837 printf (" Tag_ABI_array_object_align_expected: ");
16838 switch (val)
16839 {
16840 case 0:
16841 printf (_("8-byte\n"));
16842 break;
16843 case 1:
16844 printf (_("4-byte\n"));
16845 break;
16846 case 2:
16847 printf (_("16-byte\n"));
16848 break;
16849 default:
16850 printf ("??? (%d)\n", val);
16851 break;
16852 }
16853 return p;
16854
3cbd1c06 16855 case Tag_ABI_compatibility:
071436c6 16856 {
cd30bcef 16857 READ_ULEB (val, p, end);
071436c6 16858 printf (" Tag_ABI_compatibility: ");
071436c6 16859 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16860 if (p < end - 1)
16861 {
16862 size_t maxlen = (end - p) - 1;
16863
16864 print_symbol ((int) maxlen, (const char *) p);
16865 p += strnlen ((char *) p, maxlen) + 1;
16866 }
16867 else
16868 {
16869 printf (_("<corrupt>"));
16870 p = (unsigned char *) end;
16871 }
071436c6 16872 putchar ('\n');
071436c6
NC
16873 return p;
16874 }
87779176
JM
16875
16876 case Tag_ABI_conformance:
071436c6 16877 {
4082ef84
NC
16878 printf (" Tag_ABI_conformance: \"");
16879 if (p < end - 1)
16880 {
16881 size_t maxlen = (end - p) - 1;
071436c6 16882
4082ef84
NC
16883 print_symbol ((int) maxlen, (const char *) p);
16884 p += strnlen ((char *) p, maxlen) + 1;
16885 }
16886 else
16887 {
16888 printf (_("<corrupt>"));
16889 p = (unsigned char *) end;
16890 }
071436c6 16891 printf ("\"\n");
071436c6
NC
16892 return p;
16893 }
59e6276b
JM
16894 }
16895
f6f0e17b
NC
16896 return display_tag_value (tag, p, end);
16897}
59e6276b 16898
f6f0e17b 16899static void
60abdbed 16900display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
16901{
16902 unsigned long addr = 0;
16903 size_t bytes = end - p;
16904
feceaa59 16905 assert (end >= p);
f6f0e17b 16906 while (bytes)
87779176 16907 {
f6f0e17b
NC
16908 int j;
16909 int k;
16910 int lbytes = (bytes > 16 ? 16 : bytes);
16911
16912 printf (" 0x%8.8lx ", addr);
16913
16914 for (j = 0; j < 16; j++)
16915 {
16916 if (j < lbytes)
16917 printf ("%2.2x", p[j]);
16918 else
16919 printf (" ");
16920
16921 if ((j & 3) == 3)
16922 printf (" ");
16923 }
16924
16925 for (j = 0; j < lbytes; j++)
16926 {
16927 k = p[j];
16928 if (k >= ' ' && k < 0x7f)
16929 printf ("%c", k);
16930 else
16931 printf (".");
16932 }
16933
16934 putchar ('\n');
16935
16936 p += lbytes;
16937 bytes -= lbytes;
16938 addr += lbytes;
87779176 16939 }
59e6276b 16940
f6f0e17b 16941 putchar ('\n');
59e6276b
JM
16942}
16943
13761a11 16944static unsigned char *
b0191216 16945display_msp430_attribute (unsigned char * p,
13761a11
NC
16946 const unsigned char * const end)
16947{
60abdbed
NC
16948 unsigned int val;
16949 unsigned int tag;
13761a11 16950
cd30bcef 16951 READ_ULEB (tag, p, end);
0b4362b0 16952
13761a11
NC
16953 switch (tag)
16954 {
16955 case OFBA_MSPABI_Tag_ISA:
13761a11 16956 printf (" Tag_ISA: ");
cd30bcef 16957 READ_ULEB (val, p, end);
13761a11
NC
16958 switch (val)
16959 {
16960 case 0: printf (_("None\n")); break;
16961 case 1: printf (_("MSP430\n")); break;
16962 case 2: printf (_("MSP430X\n")); break;
16963 default: printf ("??? (%d)\n", val); break;
16964 }
16965 break;
16966
16967 case OFBA_MSPABI_Tag_Code_Model:
13761a11 16968 printf (" Tag_Code_Model: ");
cd30bcef 16969 READ_ULEB (val, p, end);
13761a11
NC
16970 switch (val)
16971 {
16972 case 0: printf (_("None\n")); break;
16973 case 1: printf (_("Small\n")); break;
16974 case 2: printf (_("Large\n")); break;
16975 default: printf ("??? (%d)\n", val); break;
16976 }
16977 break;
16978
16979 case OFBA_MSPABI_Tag_Data_Model:
13761a11 16980 printf (" Tag_Data_Model: ");
cd30bcef 16981 READ_ULEB (val, p, end);
13761a11
NC
16982 switch (val)
16983 {
16984 case 0: printf (_("None\n")); break;
16985 case 1: printf (_("Small\n")); break;
16986 case 2: printf (_("Large\n")); break;
16987 case 3: printf (_("Restricted Large\n")); break;
16988 default: printf ("??? (%d)\n", val); break;
16989 }
16990 break;
16991
16992 default:
16993 printf (_(" <unknown tag %d>: "), tag);
16994
16995 if (tag & 1)
16996 {
071436c6 16997 putchar ('"');
4082ef84
NC
16998 if (p < end - 1)
16999 {
17000 size_t maxlen = (end - p) - 1;
17001
17002 print_symbol ((int) maxlen, (const char *) p);
17003 p += strnlen ((char *) p, maxlen) + 1;
17004 }
17005 else
17006 {
17007 printf (_("<corrupt>"));
17008 p = (unsigned char *) end;
17009 }
071436c6 17010 printf ("\"\n");
13761a11
NC
17011 }
17012 else
17013 {
cd30bcef 17014 READ_ULEB (val, p, end);
13761a11
NC
17015 printf ("%d (0x%x)\n", val, val);
17016 }
17017 break;
17018 }
17019
4082ef84 17020 assert (p <= end);
13761a11
NC
17021 return p;
17022}
17023
c0ea7c52
JL
17024static unsigned char *
17025display_msp430_gnu_attribute (unsigned char * p,
17026 unsigned int tag,
17027 const unsigned char * const end)
17028{
17029 if (tag == Tag_GNU_MSP430_Data_Region)
17030 {
cd30bcef 17031 unsigned int val;
c0ea7c52 17032
c0ea7c52 17033 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17034 READ_ULEB (val, p, end);
c0ea7c52
JL
17035
17036 switch (val)
17037 {
17038 case Val_GNU_MSP430_Data_Region_Any:
17039 printf (_("Any Region\n"));
17040 break;
17041 case Val_GNU_MSP430_Data_Region_Lower:
17042 printf (_("Lower Region Only\n"));
17043 break;
17044 default:
cd30bcef 17045 printf ("??? (%u)\n", val);
c0ea7c52
JL
17046 }
17047 return p;
17048 }
17049 return display_tag_value (tag & 1, p, end);
17050}
17051
2dc8dd17
JW
17052struct riscv_attr_tag_t {
17053 const char *name;
cd30bcef 17054 unsigned int tag;
2dc8dd17
JW
17055};
17056
17057static struct riscv_attr_tag_t riscv_attr_tag[] =
17058{
17059#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17060 T(arch),
17061 T(priv_spec),
17062 T(priv_spec_minor),
17063 T(priv_spec_revision),
17064 T(unaligned_access),
17065 T(stack_align),
17066#undef T
17067};
17068
17069static unsigned char *
17070display_riscv_attribute (unsigned char *p,
17071 const unsigned char * const end)
17072{
cd30bcef
AM
17073 unsigned int val;
17074 unsigned int tag;
2dc8dd17
JW
17075 struct riscv_attr_tag_t *attr = NULL;
17076 unsigned i;
17077
cd30bcef 17078 READ_ULEB (tag, p, end);
2dc8dd17
JW
17079
17080 /* Find the name of attribute. */
17081 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17082 {
17083 if (riscv_attr_tag[i].tag == tag)
17084 {
17085 attr = &riscv_attr_tag[i];
17086 break;
17087 }
17088 }
17089
17090 if (attr)
17091 printf (" %s: ", attr->name);
17092 else
17093 return display_tag_value (tag, p, end);
17094
17095 switch (tag)
17096 {
17097 case Tag_RISCV_priv_spec:
17098 case Tag_RISCV_priv_spec_minor:
17099 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17100 READ_ULEB (val, p, end);
17101 printf (_("%u\n"), val);
2dc8dd17
JW
17102 break;
17103 case Tag_RISCV_unaligned_access:
cd30bcef 17104 READ_ULEB (val, p, end);
2dc8dd17
JW
17105 switch (val)
17106 {
17107 case 0:
17108 printf (_("No unaligned access\n"));
17109 break;
17110 case 1:
17111 printf (_("Unaligned access\n"));
17112 break;
17113 }
17114 break;
17115 case Tag_RISCV_stack_align:
cd30bcef
AM
17116 READ_ULEB (val, p, end);
17117 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17118 break;
17119 case Tag_RISCV_arch:
17120 p = display_tag_value (-1, p, end);
17121 break;
17122 default:
17123 return display_tag_value (tag, p, end);
17124 }
17125
17126 return p;
17127}
17128
0861f561
CQ
17129static unsigned char *
17130display_csky_attribute (unsigned char * p,
17131 const unsigned char * const end)
17132{
17133 unsigned int tag;
17134 unsigned int val;
17135 READ_ULEB (tag, p, end);
17136
17137 if (tag >= Tag_CSKY_MAX)
17138 {
17139 return display_tag_value (-1, p, end);
17140 }
17141
17142 switch (tag)
17143 {
17144 case Tag_CSKY_ARCH_NAME:
17145 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17146 return display_tag_value (-1, p, end);
17147 case Tag_CSKY_CPU_NAME:
17148 printf (" Tag_CSKY_CPU_NAME:\t\t");
17149 return display_tag_value (-1, p, end);
17150
17151 case Tag_CSKY_ISA_FLAGS:
17152 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17153 return display_tag_value (0, p, end);
17154 case Tag_CSKY_ISA_EXT_FLAGS:
17155 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17156 return display_tag_value (0, p, end);
17157
17158 case Tag_CSKY_DSP_VERSION:
17159 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17160 READ_ULEB (val, p, end);
17161 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17162 printf ("DSP Extension\n");
17163 else if (val == VAL_CSKY_DSP_VERSION_2)
17164 printf ("DSP 2.0\n");
17165 break;
17166
17167 case Tag_CSKY_VDSP_VERSION:
17168 printf (" Tag_CSKY_VDSP_VERSION:\t");
17169 READ_ULEB (val, p, end);
17170 printf ("VDSP Version %d\n", val);
17171 break;
17172
17173 case Tag_CSKY_FPU_VERSION:
17174 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17175 READ_ULEB (val, p, end);
17176 if (val == VAL_CSKY_FPU_VERSION_1)
17177 printf ("ABIV1 FPU Version 1\n");
17178 else if (val == VAL_CSKY_FPU_VERSION_2)
17179 printf ("FPU Version 2\n");
17180 break;
17181
17182 case Tag_CSKY_FPU_ABI:
17183 printf (" Tag_CSKY_FPU_ABI:\t\t");
17184 READ_ULEB (val, p, end);
17185 if (val == VAL_CSKY_FPU_ABI_HARD)
17186 printf ("Hard\n");
17187 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17188 printf ("SoftFP\n");
17189 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17190 printf ("Soft\n");
17191 break;
17192 case Tag_CSKY_FPU_ROUNDING:
17193 READ_ULEB (val, p, end);
17194 if (val == 1) {
17195 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17196 printf ("Needed\n");
17197 }
17198 break;
17199 case Tag_CSKY_FPU_DENORMAL:
17200 READ_ULEB (val, p, end);
17201 if (val == 1) {
17202 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17203 printf ("Needed\n");
17204 }
17205 break;
17206 case Tag_CSKY_FPU_Exception:
17207 READ_ULEB (val, p, end);
17208 if (val == 1) {
17209 printf (" Tag_CSKY_FPU_Exception:\t");
17210 printf ("Needed\n");
17211 }
17212 break;
17213 case Tag_CSKY_FPU_NUMBER_MODULE:
17214 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17215 return display_tag_value (-1, p, end);
17216 case Tag_CSKY_FPU_HARDFP:
17217 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17218 READ_ULEB (val, p, end);
17219 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17220 printf (" Half");
17221 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17222 printf (" Single");
17223 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17224 printf (" Double");
17225 printf ("\n");
17226 break;
17227 default:
17228 return display_tag_value (tag, p, end);
17229 }
17230 return p;
17231}
17232
015dc7e1 17233static bool
dda8d76d 17234process_attributes (Filedata * filedata,
60bca95a 17235 const char * public_name,
104d59d1 17236 unsigned int proc_type,
f6f0e17b 17237 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17238 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17239{
2cf0635d 17240 Elf_Internal_Shdr * sect;
11c1ff18 17241 unsigned i;
015dc7e1 17242 bool res = true;
11c1ff18
PB
17243
17244 /* Find the section header so that we get the size. */
dda8d76d
NC
17245 for (i = 0, sect = filedata->section_headers;
17246 i < filedata->file_header.e_shnum;
11c1ff18
PB
17247 i++, sect++)
17248 {
071436c6
NC
17249 unsigned char * contents;
17250 unsigned char * p;
17251
104d59d1 17252 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17253 continue;
17254
dda8d76d 17255 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17256 sect->sh_size, _("attributes"));
60bca95a 17257 if (contents == NULL)
32ec8896 17258 {
015dc7e1 17259 res = false;
32ec8896
NC
17260 continue;
17261 }
60bca95a 17262
11c1ff18 17263 p = contents;
60abdbed
NC
17264 /* The first character is the version of the attributes.
17265 Currently only version 1, (aka 'A') is recognised here. */
17266 if (*p != 'A')
32ec8896
NC
17267 {
17268 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17269 res = false;
32ec8896 17270 }
60abdbed 17271 else
11c1ff18 17272 {
071436c6
NC
17273 bfd_vma section_len;
17274
17275 section_len = sect->sh_size - 1;
11c1ff18 17276 p++;
60bca95a 17277
071436c6 17278 while (section_len > 0)
11c1ff18 17279 {
071436c6 17280 bfd_vma attr_len;
e9847026 17281 unsigned int namelen;
015dc7e1
AM
17282 bool public_section;
17283 bool gnu_section;
11c1ff18 17284
071436c6 17285 if (section_len <= 4)
e0a31db1
NC
17286 {
17287 error (_("Tag section ends prematurely\n"));
015dc7e1 17288 res = false;
e0a31db1
NC
17289 break;
17290 }
071436c6 17291 attr_len = byte_get (p, 4);
11c1ff18 17292 p += 4;
60bca95a 17293
071436c6 17294 if (attr_len > section_len)
11c1ff18 17295 {
071436c6
NC
17296 error (_("Bad attribute length (%u > %u)\n"),
17297 (unsigned) attr_len, (unsigned) section_len);
17298 attr_len = section_len;
015dc7e1 17299 res = false;
11c1ff18 17300 }
74e1a04b 17301 /* PR 17531: file: 001-101425-0.004 */
071436c6 17302 else if (attr_len < 5)
74e1a04b 17303 {
071436c6 17304 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17305 res = false;
74e1a04b
NC
17306 break;
17307 }
e9847026 17308
071436c6
NC
17309 section_len -= attr_len;
17310 attr_len -= 4;
17311
17312 namelen = strnlen ((char *) p, attr_len) + 1;
17313 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17314 {
17315 error (_("Corrupt attribute section name\n"));
015dc7e1 17316 res = false;
e9847026
NC
17317 break;
17318 }
17319
071436c6
NC
17320 printf (_("Attribute Section: "));
17321 print_symbol (INT_MAX, (const char *) p);
17322 putchar ('\n');
60bca95a
NC
17323
17324 if (public_name && streq ((char *) p, public_name))
015dc7e1 17325 public_section = true;
11c1ff18 17326 else
015dc7e1 17327 public_section = false;
60bca95a
NC
17328
17329 if (streq ((char *) p, "gnu"))
015dc7e1 17330 gnu_section = true;
104d59d1 17331 else
015dc7e1 17332 gnu_section = false;
60bca95a 17333
11c1ff18 17334 p += namelen;
071436c6 17335 attr_len -= namelen;
e0a31db1 17336
071436c6 17337 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17338 {
e0a31db1 17339 int tag;
cd30bcef 17340 unsigned int val;
11c1ff18 17341 bfd_vma size;
071436c6 17342 unsigned char * end;
60bca95a 17343
e0a31db1 17344 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17345 if (attr_len < 6)
e0a31db1
NC
17346 {
17347 error (_("Unused bytes at end of section\n"));
015dc7e1 17348 res = false;
e0a31db1
NC
17349 section_len = 0;
17350 break;
17351 }
17352
17353 tag = *(p++);
11c1ff18 17354 size = byte_get (p, 4);
071436c6 17355 if (size > attr_len)
11c1ff18 17356 {
e9847026 17357 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17358 (unsigned) size, (unsigned) attr_len);
015dc7e1 17359 res = false;
071436c6 17360 size = attr_len;
11c1ff18 17361 }
e0a31db1
NC
17362 /* PR binutils/17531: Safe handling of corrupt files. */
17363 if (size < 6)
17364 {
17365 error (_("Bad subsection length (%u < 6)\n"),
17366 (unsigned) size);
015dc7e1 17367 res = false;
e0a31db1
NC
17368 section_len = 0;
17369 break;
17370 }
60bca95a 17371
071436c6 17372 attr_len -= size;
11c1ff18 17373 end = p + size - 1;
071436c6 17374 assert (end <= contents + sect->sh_size);
11c1ff18 17375 p += 4;
60bca95a 17376
11c1ff18
PB
17377 switch (tag)
17378 {
17379 case 1:
2b692964 17380 printf (_("File Attributes\n"));
11c1ff18
PB
17381 break;
17382 case 2:
2b692964 17383 printf (_("Section Attributes:"));
11c1ff18
PB
17384 goto do_numlist;
17385 case 3:
2b692964 17386 printf (_("Symbol Attributes:"));
1a0670f3 17387 /* Fall through. */
11c1ff18
PB
17388 do_numlist:
17389 for (;;)
17390 {
cd30bcef 17391 READ_ULEB (val, p, end);
11c1ff18
PB
17392 if (val == 0)
17393 break;
17394 printf (" %d", val);
17395 }
17396 printf ("\n");
17397 break;
17398 default:
2b692964 17399 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 17400 public_section = false;
11c1ff18
PB
17401 break;
17402 }
60bca95a 17403
071436c6 17404 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
17405 {
17406 while (p < end)
f6f0e17b 17407 p = display_pub_attribute (p, end);
60abdbed 17408 assert (p == end);
104d59d1 17409 }
071436c6 17410 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
17411 {
17412 while (p < end)
17413 p = display_gnu_attribute (p,
f6f0e17b
NC
17414 display_proc_gnu_attribute,
17415 end);
60abdbed 17416 assert (p == end);
11c1ff18 17417 }
071436c6 17418 else if (p < end)
11c1ff18 17419 {
071436c6 17420 printf (_(" Unknown attribute:\n"));
f6f0e17b 17421 display_raw_attribute (p, end);
11c1ff18
PB
17422 p = end;
17423 }
071436c6
NC
17424 else
17425 attr_len = 0;
11c1ff18
PB
17426 }
17427 }
17428 }
d70c5fc7 17429
60bca95a 17430 free (contents);
11c1ff18 17431 }
32ec8896
NC
17432
17433 return res;
11c1ff18
PB
17434}
17435
ccb4c951
RS
17436/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
17437 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
17438 and return the VMA of the next entry, or -1 if there was a problem.
17439 Does not read from DATA_END or beyond. */
ccb4c951
RS
17440
17441static bfd_vma
82b1b41b
NC
17442print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
17443 unsigned char * data_end)
ccb4c951
RS
17444{
17445 printf (" ");
17446 print_vma (addr, LONG_HEX);
17447 printf (" ");
17448 if (addr < pltgot + 0xfff0)
17449 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
17450 else
17451 printf ("%10s", "");
17452 printf (" ");
17453 if (data == NULL)
2b692964 17454 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
17455 else
17456 {
17457 bfd_vma entry;
82b1b41b 17458 unsigned char * from = data + addr - pltgot;
ccb4c951 17459
82b1b41b
NC
17460 if (from + (is_32bit_elf ? 4 : 8) > data_end)
17461 {
17462 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
17463 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
17464 return (bfd_vma) -1;
17465 }
17466 else
17467 {
17468 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17469 print_vma (entry, LONG_HEX);
17470 }
ccb4c951
RS
17471 }
17472 return addr + (is_32bit_elf ? 4 : 8);
17473}
17474
861fb55a
DJ
17475/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
17476 PLTGOT. Print the Address and Initial fields of an entry at VMA
17477 ADDR and return the VMA of the next entry. */
17478
17479static bfd_vma
2cf0635d 17480print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
17481{
17482 printf (" ");
17483 print_vma (addr, LONG_HEX);
17484 printf (" ");
17485 if (data == NULL)
2b692964 17486 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
17487 else
17488 {
17489 bfd_vma entry;
17490
17491 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17492 print_vma (entry, LONG_HEX);
17493 }
17494 return addr + (is_32bit_elf ? 4 : 8);
17495}
17496
351cdf24
MF
17497static void
17498print_mips_ases (unsigned int mask)
17499{
17500 if (mask & AFL_ASE_DSP)
17501 fputs ("\n\tDSP ASE", stdout);
17502 if (mask & AFL_ASE_DSPR2)
17503 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
17504 if (mask & AFL_ASE_DSPR3)
17505 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
17506 if (mask & AFL_ASE_EVA)
17507 fputs ("\n\tEnhanced VA Scheme", stdout);
17508 if (mask & AFL_ASE_MCU)
17509 fputs ("\n\tMCU (MicroController) ASE", stdout);
17510 if (mask & AFL_ASE_MDMX)
17511 fputs ("\n\tMDMX ASE", stdout);
17512 if (mask & AFL_ASE_MIPS3D)
17513 fputs ("\n\tMIPS-3D ASE", stdout);
17514 if (mask & AFL_ASE_MT)
17515 fputs ("\n\tMT ASE", stdout);
17516 if (mask & AFL_ASE_SMARTMIPS)
17517 fputs ("\n\tSmartMIPS ASE", stdout);
17518 if (mask & AFL_ASE_VIRT)
17519 fputs ("\n\tVZ ASE", stdout);
17520 if (mask & AFL_ASE_MSA)
17521 fputs ("\n\tMSA ASE", stdout);
17522 if (mask & AFL_ASE_MIPS16)
17523 fputs ("\n\tMIPS16 ASE", stdout);
17524 if (mask & AFL_ASE_MICROMIPS)
17525 fputs ("\n\tMICROMIPS ASE", stdout);
17526 if (mask & AFL_ASE_XPA)
17527 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
17528 if (mask & AFL_ASE_MIPS16E2)
17529 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
17530 if (mask & AFL_ASE_CRC)
17531 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
17532 if (mask & AFL_ASE_GINV)
17533 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
17534 if (mask & AFL_ASE_LOONGSON_MMI)
17535 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
17536 if (mask & AFL_ASE_LOONGSON_CAM)
17537 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
17538 if (mask & AFL_ASE_LOONGSON_EXT)
17539 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
17540 if (mask & AFL_ASE_LOONGSON_EXT2)
17541 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
17542 if (mask == 0)
17543 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
17544 else if ((mask & ~AFL_ASE_MASK) != 0)
17545 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
17546}
17547
17548static void
17549print_mips_isa_ext (unsigned int isa_ext)
17550{
17551 switch (isa_ext)
17552 {
17553 case 0:
17554 fputs (_("None"), stdout);
17555 break;
17556 case AFL_EXT_XLR:
17557 fputs ("RMI XLR", stdout);
17558 break;
2c629856
N
17559 case AFL_EXT_OCTEON3:
17560 fputs ("Cavium Networks Octeon3", stdout);
17561 break;
351cdf24
MF
17562 case AFL_EXT_OCTEON2:
17563 fputs ("Cavium Networks Octeon2", stdout);
17564 break;
17565 case AFL_EXT_OCTEONP:
17566 fputs ("Cavium Networks OcteonP", stdout);
17567 break;
351cdf24
MF
17568 case AFL_EXT_OCTEON:
17569 fputs ("Cavium Networks Octeon", stdout);
17570 break;
17571 case AFL_EXT_5900:
17572 fputs ("Toshiba R5900", stdout);
17573 break;
17574 case AFL_EXT_4650:
17575 fputs ("MIPS R4650", stdout);
17576 break;
17577 case AFL_EXT_4010:
17578 fputs ("LSI R4010", stdout);
17579 break;
17580 case AFL_EXT_4100:
17581 fputs ("NEC VR4100", stdout);
17582 break;
17583 case AFL_EXT_3900:
17584 fputs ("Toshiba R3900", stdout);
17585 break;
17586 case AFL_EXT_10000:
17587 fputs ("MIPS R10000", stdout);
17588 break;
17589 case AFL_EXT_SB1:
17590 fputs ("Broadcom SB-1", stdout);
17591 break;
17592 case AFL_EXT_4111:
17593 fputs ("NEC VR4111/VR4181", stdout);
17594 break;
17595 case AFL_EXT_4120:
17596 fputs ("NEC VR4120", stdout);
17597 break;
17598 case AFL_EXT_5400:
17599 fputs ("NEC VR5400", stdout);
17600 break;
17601 case AFL_EXT_5500:
17602 fputs ("NEC VR5500", stdout);
17603 break;
17604 case AFL_EXT_LOONGSON_2E:
17605 fputs ("ST Microelectronics Loongson 2E", stdout);
17606 break;
17607 case AFL_EXT_LOONGSON_2F:
17608 fputs ("ST Microelectronics Loongson 2F", stdout);
17609 break;
38bf472a
MR
17610 case AFL_EXT_INTERAPTIV_MR2:
17611 fputs ("Imagination interAptiv MR2", stdout);
17612 break;
351cdf24 17613 default:
00ac7aa0 17614 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
17615 }
17616}
17617
32ec8896 17618static signed int
351cdf24
MF
17619get_mips_reg_size (int reg_size)
17620{
17621 return (reg_size == AFL_REG_NONE) ? 0
17622 : (reg_size == AFL_REG_32) ? 32
17623 : (reg_size == AFL_REG_64) ? 64
17624 : (reg_size == AFL_REG_128) ? 128
17625 : -1;
17626}
17627
015dc7e1 17628static bool
dda8d76d 17629process_mips_specific (Filedata * filedata)
5b18a4bc 17630{
2cf0635d 17631 Elf_Internal_Dyn * entry;
351cdf24 17632 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
17633 size_t liblist_offset = 0;
17634 size_t liblistno = 0;
17635 size_t conflictsno = 0;
17636 size_t options_offset = 0;
17637 size_t conflicts_offset = 0;
861fb55a
DJ
17638 size_t pltrelsz = 0;
17639 size_t pltrel = 0;
ccb4c951 17640 bfd_vma pltgot = 0;
861fb55a
DJ
17641 bfd_vma mips_pltgot = 0;
17642 bfd_vma jmprel = 0;
ccb4c951
RS
17643 bfd_vma local_gotno = 0;
17644 bfd_vma gotsym = 0;
17645 bfd_vma symtabno = 0;
015dc7e1 17646 bool res = true;
103f02d3 17647
dda8d76d 17648 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 17649 display_mips_gnu_attribute))
015dc7e1 17650 res = false;
2cf19d5c 17651
dda8d76d 17652 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
17653
17654 if (sect != NULL)
17655 {
17656 Elf_External_ABIFlags_v0 *abiflags_ext;
17657 Elf_Internal_ABIFlags_v0 abiflags_in;
17658
17659 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
17660 {
17661 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 17662 res = false;
32ec8896 17663 }
351cdf24
MF
17664 else
17665 {
dda8d76d 17666 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
17667 sect->sh_size, _("MIPS ABI Flags section"));
17668 if (abiflags_ext)
17669 {
17670 abiflags_in.version = BYTE_GET (abiflags_ext->version);
17671 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
17672 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
17673 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
17674 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
17675 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
17676 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
17677 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
17678 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
17679 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
17680 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
17681
17682 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
17683 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
17684 if (abiflags_in.isa_rev > 1)
17685 printf ("r%d", abiflags_in.isa_rev);
17686 printf ("\nGPR size: %d",
17687 get_mips_reg_size (abiflags_in.gpr_size));
17688 printf ("\nCPR1 size: %d",
17689 get_mips_reg_size (abiflags_in.cpr1_size));
17690 printf ("\nCPR2 size: %d",
17691 get_mips_reg_size (abiflags_in.cpr2_size));
17692 fputs ("\nFP ABI: ", stdout);
17693 print_mips_fp_abi_value (abiflags_in.fp_abi);
17694 fputs ("ISA Extension: ", stdout);
17695 print_mips_isa_ext (abiflags_in.isa_ext);
17696 fputs ("\nASEs:", stdout);
17697 print_mips_ases (abiflags_in.ases);
17698 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
17699 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
17700 fputc ('\n', stdout);
17701 free (abiflags_ext);
17702 }
17703 }
17704 }
17705
19e6b90e 17706 /* We have a lot of special sections. Thanks SGI! */
978c4450 17707 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
17708 {
17709 /* No dynamic information available. See if there is static GOT. */
dda8d76d 17710 sect = find_section (filedata, ".got");
bbdd9a68
MR
17711 if (sect != NULL)
17712 {
17713 unsigned char *data_end;
17714 unsigned char *data;
17715 bfd_vma ent, end;
17716 int addr_size;
17717
17718 pltgot = sect->sh_addr;
17719
17720 ent = pltgot;
17721 addr_size = (is_32bit_elf ? 4 : 8);
17722 end = pltgot + sect->sh_size;
17723
dda8d76d 17724 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
17725 end - pltgot, 1,
17726 _("Global Offset Table data"));
17727 /* PR 12855: Null data is handled gracefully throughout. */
17728 data_end = data + (end - pltgot);
17729
17730 printf (_("\nStatic GOT:\n"));
17731 printf (_(" Canonical gp value: "));
17732 print_vma (ent + 0x7ff0, LONG_HEX);
17733 printf ("\n\n");
17734
17735 /* In a dynamic binary GOT[0] is reserved for the dynamic
17736 loader to store the lazy resolver pointer, however in
17737 a static binary it may well have been omitted and GOT
17738 reduced to a table of addresses.
17739 PR 21344: Check for the entry being fully available
17740 before fetching it. */
17741 if (data
17742 && data + ent - pltgot + addr_size <= data_end
17743 && byte_get (data + ent - pltgot, addr_size) == 0)
17744 {
17745 printf (_(" Reserved entries:\n"));
17746 printf (_(" %*s %10s %*s\n"),
17747 addr_size * 2, _("Address"), _("Access"),
17748 addr_size * 2, _("Value"));
17749 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17750 printf ("\n");
17751 if (ent == (bfd_vma) -1)
17752 goto sgot_print_fail;
17753
17754 /* Check for the MSB of GOT[1] being set, identifying a
17755 GNU object. This entry will be used by some runtime
17756 loaders, to store the module pointer. Otherwise this
17757 is an ordinary local entry.
17758 PR 21344: Check for the entry being fully available
17759 before fetching it. */
17760 if (data
17761 && data + ent - pltgot + addr_size <= data_end
17762 && (byte_get (data + ent - pltgot, addr_size)
17763 >> (addr_size * 8 - 1)) != 0)
17764 {
17765 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17766 printf ("\n");
17767 if (ent == (bfd_vma) -1)
17768 goto sgot_print_fail;
17769 }
17770 printf ("\n");
17771 }
17772
f17e9d8a 17773 if (data != NULL && ent < end)
bbdd9a68
MR
17774 {
17775 printf (_(" Local entries:\n"));
17776 printf (" %*s %10s %*s\n",
17777 addr_size * 2, _("Address"), _("Access"),
17778 addr_size * 2, _("Value"));
17779 while (ent < end)
17780 {
17781 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17782 printf ("\n");
17783 if (ent == (bfd_vma) -1)
17784 goto sgot_print_fail;
17785 }
17786 printf ("\n");
17787 }
17788
17789 sgot_print_fail:
9db70fc3 17790 free (data);
bbdd9a68
MR
17791 }
17792 return res;
17793 }
252b5132 17794
978c4450 17795 for (entry = filedata->dynamic_section;
071436c6 17796 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
17797 (entry < filedata->dynamic_section + filedata->dynamic_nent
17798 && entry->d_tag != DT_NULL);
071436c6 17799 ++entry)
252b5132
RH
17800 switch (entry->d_tag)
17801 {
17802 case DT_MIPS_LIBLIST:
d93f0186 17803 liblist_offset
dda8d76d 17804 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17805 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
17806 break;
17807 case DT_MIPS_LIBLISTNO:
17808 liblistno = entry->d_un.d_val;
17809 break;
17810 case DT_MIPS_OPTIONS:
dda8d76d 17811 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
17812 break;
17813 case DT_MIPS_CONFLICT:
d93f0186 17814 conflicts_offset
dda8d76d 17815 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17816 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
17817 break;
17818 case DT_MIPS_CONFLICTNO:
17819 conflictsno = entry->d_un.d_val;
17820 break;
ccb4c951 17821 case DT_PLTGOT:
861fb55a
DJ
17822 pltgot = entry->d_un.d_ptr;
17823 break;
ccb4c951
RS
17824 case DT_MIPS_LOCAL_GOTNO:
17825 local_gotno = entry->d_un.d_val;
17826 break;
17827 case DT_MIPS_GOTSYM:
17828 gotsym = entry->d_un.d_val;
17829 break;
17830 case DT_MIPS_SYMTABNO:
17831 symtabno = entry->d_un.d_val;
17832 break;
861fb55a
DJ
17833 case DT_MIPS_PLTGOT:
17834 mips_pltgot = entry->d_un.d_ptr;
17835 break;
17836 case DT_PLTREL:
17837 pltrel = entry->d_un.d_val;
17838 break;
17839 case DT_PLTRELSZ:
17840 pltrelsz = entry->d_un.d_val;
17841 break;
17842 case DT_JMPREL:
17843 jmprel = entry->d_un.d_ptr;
17844 break;
252b5132
RH
17845 default:
17846 break;
17847 }
17848
17849 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
17850 {
2cf0635d 17851 Elf32_External_Lib * elib;
252b5132
RH
17852 size_t cnt;
17853
dda8d76d 17854 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
17855 sizeof (Elf32_External_Lib),
17856 liblistno,
17857 _("liblist section data"));
a6e9f9df 17858 if (elib)
252b5132 17859 {
d3a49aa8
AM
17860 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
17861 "\nSection '.liblist' contains %lu entries:\n",
17862 (unsigned long) liblistno),
a6e9f9df 17863 (unsigned long) liblistno);
2b692964 17864 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
17865 stdout);
17866
17867 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 17868 {
a6e9f9df 17869 Elf32_Lib liblist;
91d6fa6a 17870 time_t atime;
d5b07ef4 17871 char timebuf[128];
2cf0635d 17872 struct tm * tmp;
a6e9f9df
AM
17873
17874 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17875 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
17876 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17877 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17878 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17879
91d6fa6a 17880 tmp = gmtime (&atime);
e9e44622
JJ
17881 snprintf (timebuf, sizeof (timebuf),
17882 "%04u-%02u-%02uT%02u:%02u:%02u",
17883 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17884 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 17885
31104126 17886 printf ("%3lu: ", (unsigned long) cnt);
978c4450
AM
17887 if (VALID_DYNAMIC_NAME (filedata, liblist.l_name))
17888 print_symbol (20, GET_DYNAMIC_NAME (filedata, liblist.l_name));
d79b3d50 17889 else
2b692964 17890 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
17891 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
17892 liblist.l_version);
a6e9f9df
AM
17893
17894 if (liblist.l_flags == 0)
2b692964 17895 puts (_(" NONE"));
a6e9f9df
AM
17896 else
17897 {
17898 static const struct
252b5132 17899 {
2cf0635d 17900 const char * name;
a6e9f9df 17901 int bit;
252b5132 17902 }
a6e9f9df
AM
17903 l_flags_vals[] =
17904 {
17905 { " EXACT_MATCH", LL_EXACT_MATCH },
17906 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
17907 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
17908 { " EXPORTS", LL_EXPORTS },
17909 { " DELAY_LOAD", LL_DELAY_LOAD },
17910 { " DELTA", LL_DELTA }
17911 };
17912 int flags = liblist.l_flags;
17913 size_t fcnt;
17914
60bca95a 17915 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
17916 if ((flags & l_flags_vals[fcnt].bit) != 0)
17917 {
17918 fputs (l_flags_vals[fcnt].name, stdout);
17919 flags ^= l_flags_vals[fcnt].bit;
17920 }
17921 if (flags != 0)
17922 printf (" %#x", (unsigned int) flags);
252b5132 17923
a6e9f9df
AM
17924 puts ("");
17925 }
252b5132 17926 }
252b5132 17927
a6e9f9df
AM
17928 free (elib);
17929 }
32ec8896 17930 else
015dc7e1 17931 res = false;
252b5132
RH
17932 }
17933
17934 if (options_offset != 0)
17935 {
2cf0635d 17936 Elf_External_Options * eopt;
252b5132
RH
17937 size_t offset;
17938 int cnt;
dda8d76d 17939 sect = filedata->section_headers;
252b5132
RH
17940
17941 /* Find the section header so that we get the size. */
dda8d76d 17942 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 17943 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
17944 if (sect == NULL)
17945 {
17946 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 17947 return false;
071436c6 17948 }
7fc0c668
NC
17949 /* PR 24243 */
17950 if (sect->sh_size < sizeof (* eopt))
17951 {
17952 error (_("The MIPS options section is too small.\n"));
015dc7e1 17953 return false;
7fc0c668 17954 }
252b5132 17955
dda8d76d 17956 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 17957 sect->sh_size, _("options"));
a6e9f9df 17958 if (eopt)
252b5132 17959 {
fd17d1e6 17960 Elf_Internal_Options option;
76da6bbe 17961
a6e9f9df 17962 offset = cnt = 0;
82b1b41b 17963 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 17964 {
2cf0635d 17965 Elf_External_Options * eoption;
fd17d1e6 17966 unsigned int optsize;
252b5132 17967
a6e9f9df 17968 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 17969
fd17d1e6 17970 optsize = BYTE_GET (eoption->size);
76da6bbe 17971
82b1b41b 17972 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
17973 if (optsize < sizeof (* eopt)
17974 || optsize > sect->sh_size - offset)
82b1b41b 17975 {
645f43a8 17976 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 17977 optsize);
645f43a8 17978 free (eopt);
015dc7e1 17979 return false;
82b1b41b 17980 }
fd17d1e6 17981 offset += optsize;
a6e9f9df
AM
17982 ++cnt;
17983 }
252b5132 17984
d3a49aa8
AM
17985 printf (ngettext ("\nSection '%s' contains %d entry:\n",
17986 "\nSection '%s' contains %d entries:\n",
17987 cnt),
dda8d76d 17988 printable_section_name (filedata, sect), cnt);
76da6bbe 17989
82b1b41b 17990 offset = 0;
a6e9f9df 17991 while (cnt-- > 0)
252b5132 17992 {
a6e9f9df 17993 size_t len;
fd17d1e6
AM
17994 Elf_External_Options * eoption;
17995
17996 eoption = (Elf_External_Options *) ((char *) eopt + offset);
17997
17998 option.kind = BYTE_GET (eoption->kind);
17999 option.size = BYTE_GET (eoption->size);
18000 option.section = BYTE_GET (eoption->section);
18001 option.info = BYTE_GET (eoption->info);
a6e9f9df 18002
fd17d1e6 18003 switch (option.kind)
252b5132 18004 {
a6e9f9df
AM
18005 case ODK_NULL:
18006 /* This shouldn't happen. */
d0c4e780 18007 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18008 option.section, option.info);
a6e9f9df 18009 break;
2e6be59c 18010
a6e9f9df
AM
18011 case ODK_REGINFO:
18012 printf (" REGINFO ");
dda8d76d 18013 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18014 {
2cf0635d 18015 Elf32_External_RegInfo * ereg;
b34976b6 18016 Elf32_RegInfo reginfo;
a6e9f9df 18017
2e6be59c 18018 /* 32bit form. */
fd17d1e6
AM
18019 if (option.size < (sizeof (Elf_External_Options)
18020 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18021 {
18022 printf (_("<corrupt>\n"));
18023 error (_("Truncated MIPS REGINFO option\n"));
18024 cnt = 0;
18025 break;
18026 }
18027
fd17d1e6 18028 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18029
a6e9f9df
AM
18030 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18031 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18032 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18033 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18034 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18035 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18036
d0c4e780
AM
18037 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18038 reginfo.ri_gprmask, reginfo.ri_gp_value);
18039 printf (" "
18040 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18041 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18042 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18043 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18044 }
18045 else
18046 {
18047 /* 64 bit form. */
2cf0635d 18048 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18049 Elf64_Internal_RegInfo reginfo;
18050
fd17d1e6
AM
18051 if (option.size < (sizeof (Elf_External_Options)
18052 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18053 {
18054 printf (_("<corrupt>\n"));
18055 error (_("Truncated MIPS REGINFO option\n"));
18056 cnt = 0;
18057 break;
18058 }
18059
fd17d1e6 18060 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18061 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18062 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18063 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18064 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18065 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18066 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18067
d0c4e780
AM
18068 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18069 reginfo.ri_gprmask, reginfo.ri_gp_value);
18070 printf (" "
18071 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18072 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18073 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18074 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18075 }
fd17d1e6 18076 offset += option.size;
a6e9f9df 18077 continue;
2e6be59c 18078
a6e9f9df
AM
18079 case ODK_EXCEPTIONS:
18080 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18081 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18082 fputs (") fpe_max(", stdout);
fd17d1e6 18083 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18084 fputs (")", stdout);
18085
fd17d1e6 18086 if (option.info & OEX_PAGE0)
a6e9f9df 18087 fputs (" PAGE0", stdout);
fd17d1e6 18088 if (option.info & OEX_SMM)
a6e9f9df 18089 fputs (" SMM", stdout);
fd17d1e6 18090 if (option.info & OEX_FPDBUG)
a6e9f9df 18091 fputs (" FPDBUG", stdout);
fd17d1e6 18092 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18093 fputs (" DISMISS", stdout);
18094 break;
2e6be59c 18095
a6e9f9df
AM
18096 case ODK_PAD:
18097 fputs (" PAD ", stdout);
fd17d1e6 18098 if (option.info & OPAD_PREFIX)
a6e9f9df 18099 fputs (" PREFIX", stdout);
fd17d1e6 18100 if (option.info & OPAD_POSTFIX)
a6e9f9df 18101 fputs (" POSTFIX", stdout);
fd17d1e6 18102 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18103 fputs (" SYMBOL", stdout);
18104 break;
2e6be59c 18105
a6e9f9df
AM
18106 case ODK_HWPATCH:
18107 fputs (" HWPATCH ", stdout);
fd17d1e6 18108 if (option.info & OHW_R4KEOP)
a6e9f9df 18109 fputs (" R4KEOP", stdout);
fd17d1e6 18110 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18111 fputs (" R8KPFETCH", stdout);
fd17d1e6 18112 if (option.info & OHW_R5KEOP)
a6e9f9df 18113 fputs (" R5KEOP", stdout);
fd17d1e6 18114 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18115 fputs (" R5KCVTL", stdout);
18116 break;
2e6be59c 18117
a6e9f9df
AM
18118 case ODK_FILL:
18119 fputs (" FILL ", stdout);
18120 /* XXX Print content of info word? */
18121 break;
2e6be59c 18122
a6e9f9df
AM
18123 case ODK_TAGS:
18124 fputs (" TAGS ", stdout);
18125 /* XXX Print content of info word? */
18126 break;
2e6be59c 18127
a6e9f9df
AM
18128 case ODK_HWAND:
18129 fputs (" HWAND ", stdout);
fd17d1e6 18130 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18131 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18132 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18133 fputs (" R4KEOP_CLEAN", stdout);
18134 break;
2e6be59c 18135
a6e9f9df
AM
18136 case ODK_HWOR:
18137 fputs (" HWOR ", stdout);
fd17d1e6 18138 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18139 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18140 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18141 fputs (" R4KEOP_CLEAN", stdout);
18142 break;
2e6be59c 18143
a6e9f9df 18144 case ODK_GP_GROUP:
d0c4e780 18145 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18146 option.info & OGP_GROUP,
18147 (option.info & OGP_SELF) >> 16);
a6e9f9df 18148 break;
2e6be59c 18149
a6e9f9df 18150 case ODK_IDENT:
d0c4e780 18151 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18152 option.info & OGP_GROUP,
18153 (option.info & OGP_SELF) >> 16);
a6e9f9df 18154 break;
2e6be59c 18155
a6e9f9df
AM
18156 default:
18157 /* This shouldn't happen. */
d0c4e780 18158 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18159 option.kind, option.section, option.info);
a6e9f9df 18160 break;
252b5132 18161 }
a6e9f9df 18162
2cf0635d 18163 len = sizeof (* eopt);
fd17d1e6 18164 while (len < option.size)
82b1b41b 18165 {
fd17d1e6 18166 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18167
82b1b41b
NC
18168 if (ISPRINT (datum))
18169 printf ("%c", datum);
18170 else
18171 printf ("\\%03o", datum);
18172 len ++;
18173 }
a6e9f9df 18174 fputs ("\n", stdout);
82b1b41b 18175
fd17d1e6 18176 offset += option.size;
252b5132 18177 }
a6e9f9df 18178 free (eopt);
252b5132 18179 }
32ec8896 18180 else
015dc7e1 18181 res = false;
252b5132
RH
18182 }
18183
18184 if (conflicts_offset != 0 && conflictsno != 0)
18185 {
2cf0635d 18186 Elf32_Conflict * iconf;
252b5132
RH
18187 size_t cnt;
18188
978c4450 18189 if (filedata->dynamic_symbols == NULL)
252b5132 18190 {
591a748a 18191 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18192 return false;
252b5132
RH
18193 }
18194
7296a62a
NC
18195 /* PR 21345 - print a slightly more helpful error message
18196 if we are sure that the cmalloc will fail. */
645f43a8 18197 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18198 {
18199 error (_("Overlarge number of conflicts detected: %lx\n"),
18200 (long) conflictsno);
015dc7e1 18201 return false;
7296a62a
NC
18202 }
18203
3f5e193b 18204 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18205 if (iconf == NULL)
18206 {
8b73c356 18207 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18208 return false;
252b5132
RH
18209 }
18210
9ea033b2 18211 if (is_32bit_elf)
252b5132 18212 {
2cf0635d 18213 Elf32_External_Conflict * econf32;
a6e9f9df 18214
3f5e193b 18215 econf32 = (Elf32_External_Conflict *)
95099889
AM
18216 get_data (NULL, filedata, conflicts_offset,
18217 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18218 if (!econf32)
5a814d6d
AM
18219 {
18220 free (iconf);
015dc7e1 18221 return false;
5a814d6d 18222 }
252b5132
RH
18223
18224 for (cnt = 0; cnt < conflictsno; ++cnt)
18225 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18226
18227 free (econf32);
252b5132
RH
18228 }
18229 else
18230 {
2cf0635d 18231 Elf64_External_Conflict * econf64;
a6e9f9df 18232
3f5e193b 18233 econf64 = (Elf64_External_Conflict *)
95099889
AM
18234 get_data (NULL, filedata, conflicts_offset,
18235 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18236 if (!econf64)
5a814d6d
AM
18237 {
18238 free (iconf);
015dc7e1 18239 return false;
5a814d6d 18240 }
252b5132
RH
18241
18242 for (cnt = 0; cnt < conflictsno; ++cnt)
18243 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18244
18245 free (econf64);
252b5132
RH
18246 }
18247
d3a49aa8
AM
18248 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18249 "\nSection '.conflict' contains %lu entries:\n",
18250 (unsigned long) conflictsno),
c7e7ca54 18251 (unsigned long) conflictsno);
252b5132
RH
18252 puts (_(" Num: Index Value Name"));
18253
18254 for (cnt = 0; cnt < conflictsno; ++cnt)
18255 {
b34976b6 18256 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18257
978c4450 18258 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18259 printf (_("<corrupt symbol index>"));
d79b3d50 18260 else
e0a31db1
NC
18261 {
18262 Elf_Internal_Sym * psym;
18263
978c4450 18264 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18265 print_vma (psym->st_value, FULL_HEX);
18266 putchar (' ');
978c4450
AM
18267 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18268 print_symbol (25, GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18269 else
18270 printf (_("<corrupt: %14ld>"), psym->st_name);
18271 }
31104126 18272 putchar ('\n');
252b5132
RH
18273 }
18274
252b5132
RH
18275 free (iconf);
18276 }
18277
ccb4c951
RS
18278 if (pltgot != 0 && local_gotno != 0)
18279 {
91d6fa6a 18280 bfd_vma ent, local_end, global_end;
bbeee7ea 18281 size_t i, offset;
2cf0635d 18282 unsigned char * data;
82b1b41b 18283 unsigned char * data_end;
bbeee7ea 18284 int addr_size;
ccb4c951 18285
91d6fa6a 18286 ent = pltgot;
ccb4c951
RS
18287 addr_size = (is_32bit_elf ? 4 : 8);
18288 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18289
74e1a04b
NC
18290 /* PR binutils/17533 file: 012-111227-0.004 */
18291 if (symtabno < gotsym)
18292 {
18293 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18294 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18295 return false;
74e1a04b 18296 }
82b1b41b 18297
74e1a04b 18298 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18299 /* PR 17531: file: 54c91a34. */
18300 if (global_end < local_end)
18301 {
18302 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18303 return false;
82b1b41b 18304 }
948f632f 18305
dda8d76d
NC
18306 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18307 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18308 global_end - pltgot, 1,
18309 _("Global Offset Table data"));
919383ac 18310 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18311 data_end = data + (global_end - pltgot);
59245841 18312
ccb4c951
RS
18313 printf (_("\nPrimary GOT:\n"));
18314 printf (_(" Canonical gp value: "));
18315 print_vma (pltgot + 0x7ff0, LONG_HEX);
18316 printf ("\n\n");
18317
18318 printf (_(" Reserved entries:\n"));
18319 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18320 addr_size * 2, _("Address"), _("Access"),
18321 addr_size * 2, _("Initial"));
82b1b41b 18322 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18323 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18324 if (ent == (bfd_vma) -1)
18325 goto got_print_fail;
75ec1fdb 18326
c4ab9505
MR
18327 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18328 This entry will be used by some runtime loaders, to store the
18329 module pointer. Otherwise this is an ordinary local entry.
18330 PR 21344: Check for the entry being fully available before
18331 fetching it. */
18332 if (data
18333 && data + ent - pltgot + addr_size <= data_end
18334 && (byte_get (data + ent - pltgot, addr_size)
18335 >> (addr_size * 8 - 1)) != 0)
18336 {
18337 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18338 printf (_(" Module pointer (GNU extension)\n"));
18339 if (ent == (bfd_vma) -1)
18340 goto got_print_fail;
ccb4c951
RS
18341 }
18342 printf ("\n");
18343
f17e9d8a 18344 if (data != NULL && ent < local_end)
ccb4c951
RS
18345 {
18346 printf (_(" Local entries:\n"));
cc5914eb 18347 printf (" %*s %10s %*s\n",
2b692964
NC
18348 addr_size * 2, _("Address"), _("Access"),
18349 addr_size * 2, _("Initial"));
91d6fa6a 18350 while (ent < local_end)
ccb4c951 18351 {
82b1b41b 18352 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18353 printf ("\n");
82b1b41b
NC
18354 if (ent == (bfd_vma) -1)
18355 goto got_print_fail;
ccb4c951
RS
18356 }
18357 printf ("\n");
18358 }
18359
f17e9d8a 18360 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18361 {
18362 int sym_width;
18363
18364 printf (_(" Global entries:\n"));
cc5914eb 18365 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18366 addr_size * 2, _("Address"),
18367 _("Access"),
2b692964 18368 addr_size * 2, _("Initial"),
9cf03b7e
NC
18369 addr_size * 2, _("Sym.Val."),
18370 _("Type"),
18371 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18372 _("Ndx"), _("Name"));
0b4362b0 18373
ccb4c951 18374 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18375
ccb4c951
RS
18376 for (i = gotsym; i < symtabno; i++)
18377 {
82b1b41b 18378 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18379 printf (" ");
e0a31db1 18380
978c4450 18381 if (filedata->dynamic_symbols == NULL)
e0a31db1 18382 printf (_("<no dynamic symbols>"));
978c4450 18383 else if (i < filedata->num_dynamic_syms)
e0a31db1 18384 {
978c4450 18385 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
18386
18387 print_vma (psym->st_value, LONG_HEX);
18388 printf (" %-7s %3s ",
dda8d76d
NC
18389 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18390 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 18391
978c4450
AM
18392 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18393 print_symbol (sym_width,
18394 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18395 else
18396 printf (_("<corrupt: %14ld>"), psym->st_name);
18397 }
ccb4c951 18398 else
7fc5ac57
JBG
18399 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
18400 (unsigned long) i);
e0a31db1 18401
ccb4c951 18402 printf ("\n");
82b1b41b
NC
18403 if (ent == (bfd_vma) -1)
18404 break;
ccb4c951
RS
18405 }
18406 printf ("\n");
18407 }
18408
82b1b41b 18409 got_print_fail:
9db70fc3 18410 free (data);
ccb4c951
RS
18411 }
18412
861fb55a
DJ
18413 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
18414 {
91d6fa6a 18415 bfd_vma ent, end;
861fb55a
DJ
18416 size_t offset, rel_offset;
18417 unsigned long count, i;
2cf0635d 18418 unsigned char * data;
861fb55a 18419 int addr_size, sym_width;
2cf0635d 18420 Elf_Internal_Rela * rels;
861fb55a 18421
dda8d76d 18422 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
18423 if (pltrel == DT_RELA)
18424 {
dda8d76d 18425 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18426 return false;
861fb55a
DJ
18427 }
18428 else
18429 {
dda8d76d 18430 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18431 return false;
861fb55a
DJ
18432 }
18433
91d6fa6a 18434 ent = mips_pltgot;
861fb55a
DJ
18435 addr_size = (is_32bit_elf ? 4 : 8);
18436 end = mips_pltgot + (2 + count) * addr_size;
18437
dda8d76d
NC
18438 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
18439 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 18440 1, _("Procedure Linkage Table data"));
59245841 18441 if (data == NULL)
288f0ba2
AM
18442 {
18443 free (rels);
015dc7e1 18444 return false;
288f0ba2 18445 }
59245841 18446
9cf03b7e 18447 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
18448 printf (_(" Reserved entries:\n"));
18449 printf (_(" %*s %*s Purpose\n"),
2b692964 18450 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 18451 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18452 printf (_(" PLT lazy resolver\n"));
91d6fa6a 18453 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18454 printf (_(" Module pointer\n"));
861fb55a
DJ
18455 printf ("\n");
18456
18457 printf (_(" Entries:\n"));
cc5914eb 18458 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
18459 addr_size * 2, _("Address"),
18460 addr_size * 2, _("Initial"),
18461 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
18462 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
18463 for (i = 0; i < count; i++)
18464 {
df97ab2a 18465 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 18466
91d6fa6a 18467 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 18468 printf (" ");
e0a31db1 18469
978c4450 18470 if (idx >= filedata->num_dynamic_syms)
df97ab2a 18471 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 18472 else
e0a31db1 18473 {
978c4450 18474 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
18475
18476 print_vma (psym->st_value, LONG_HEX);
18477 printf (" %-7s %3s ",
dda8d76d
NC
18478 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18479 get_symbol_index_type (filedata, psym->st_shndx));
978c4450
AM
18480 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18481 print_symbol (sym_width,
18482 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18483 else
18484 printf (_("<corrupt: %14ld>"), psym->st_name);
18485 }
861fb55a
DJ
18486 printf ("\n");
18487 }
18488 printf ("\n");
18489
9db70fc3 18490 free (data);
861fb55a
DJ
18491 free (rels);
18492 }
18493
32ec8896 18494 return res;
252b5132
RH
18495}
18496
015dc7e1 18497static bool
dda8d76d 18498process_nds32_specific (Filedata * filedata)
35c08157
KLC
18499{
18500 Elf_Internal_Shdr *sect = NULL;
18501
dda8d76d 18502 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 18503 if (sect != NULL && sect->sh_size >= 4)
35c08157 18504 {
9c7b8e9b
AM
18505 unsigned char *buf;
18506 unsigned int flag;
35c08157
KLC
18507
18508 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
18509 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
18510 _("NDS32 elf flags section"));
35c08157 18511
9c7b8e9b 18512 if (buf == NULL)
015dc7e1 18513 return false;
32ec8896 18514
9c7b8e9b
AM
18515 flag = byte_get (buf, 4);
18516 free (buf);
18517 switch (flag & 0x3)
35c08157
KLC
18518 {
18519 case 0:
18520 printf ("(VEC_SIZE):\tNo entry.\n");
18521 break;
18522 case 1:
18523 printf ("(VEC_SIZE):\t4 bytes\n");
18524 break;
18525 case 2:
18526 printf ("(VEC_SIZE):\t16 bytes\n");
18527 break;
18528 case 3:
18529 printf ("(VEC_SIZE):\treserved\n");
18530 break;
18531 }
18532 }
18533
015dc7e1 18534 return true;
35c08157
KLC
18535}
18536
015dc7e1 18537static bool
dda8d76d 18538process_gnu_liblist (Filedata * filedata)
047b2264 18539{
2cf0635d
NC
18540 Elf_Internal_Shdr * section;
18541 Elf_Internal_Shdr * string_sec;
18542 Elf32_External_Lib * elib;
18543 char * strtab;
c256ffe7 18544 size_t strtab_size;
047b2264 18545 size_t cnt;
d3a49aa8 18546 unsigned long num_liblist;
047b2264 18547 unsigned i;
015dc7e1 18548 bool res = true;
047b2264
JJ
18549
18550 if (! do_arch)
015dc7e1 18551 return true;
047b2264 18552
dda8d76d
NC
18553 for (i = 0, section = filedata->section_headers;
18554 i < filedata->file_header.e_shnum;
b34976b6 18555 i++, section++)
047b2264
JJ
18556 {
18557 switch (section->sh_type)
18558 {
18559 case SHT_GNU_LIBLIST:
dda8d76d 18560 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
18561 break;
18562
3f5e193b 18563 elib = (Elf32_External_Lib *)
dda8d76d 18564 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 18565 _("liblist section data"));
047b2264
JJ
18566
18567 if (elib == NULL)
32ec8896 18568 {
015dc7e1 18569 res = false;
32ec8896
NC
18570 break;
18571 }
047b2264 18572
dda8d76d
NC
18573 string_sec = filedata->section_headers + section->sh_link;
18574 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
18575 string_sec->sh_size,
18576 _("liblist string table"));
047b2264
JJ
18577 if (strtab == NULL
18578 || section->sh_entsize != sizeof (Elf32_External_Lib))
18579 {
18580 free (elib);
2842702f 18581 free (strtab);
015dc7e1 18582 res = false;
047b2264
JJ
18583 break;
18584 }
59245841 18585 strtab_size = string_sec->sh_size;
047b2264 18586
d3a49aa8
AM
18587 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
18588 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
18589 "\nLibrary list section '%s' contains %lu entries:\n",
18590 num_liblist),
dda8d76d 18591 printable_section_name (filedata, section),
d3a49aa8 18592 num_liblist);
047b2264 18593
2b692964 18594 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
18595
18596 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
18597 ++cnt)
18598 {
18599 Elf32_Lib liblist;
91d6fa6a 18600 time_t atime;
d5b07ef4 18601 char timebuf[128];
2cf0635d 18602 struct tm * tmp;
047b2264
JJ
18603
18604 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18605 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
18606 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18607 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18608 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18609
91d6fa6a 18610 tmp = gmtime (&atime);
e9e44622
JJ
18611 snprintf (timebuf, sizeof (timebuf),
18612 "%04u-%02u-%02uT%02u:%02u:%02u",
18613 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18614 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
18615
18616 printf ("%3lu: ", (unsigned long) cnt);
18617 if (do_wide)
c256ffe7 18618 printf ("%-20s", liblist.l_name < strtab_size
2b692964 18619 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 18620 else
c256ffe7 18621 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 18622 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
18623 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
18624 liblist.l_version, liblist.l_flags);
18625 }
18626
18627 free (elib);
2842702f 18628 free (strtab);
047b2264
JJ
18629 }
18630 }
18631
32ec8896 18632 return res;
047b2264
JJ
18633}
18634
9437c45b 18635static const char *
dda8d76d 18636get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
18637{
18638 static char buff[64];
103f02d3 18639
dda8d76d 18640 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
18641 switch (e_type)
18642 {
57346661 18643 case NT_AUXV:
1ec5cd37 18644 return _("NT_AUXV (auxiliary vector)");
57346661 18645 case NT_PRSTATUS:
1ec5cd37 18646 return _("NT_PRSTATUS (prstatus structure)");
57346661 18647 case NT_FPREGSET:
1ec5cd37 18648 return _("NT_FPREGSET (floating point registers)");
57346661 18649 case NT_PRPSINFO:
1ec5cd37 18650 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 18651 case NT_TASKSTRUCT:
1ec5cd37 18652 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
18653 case NT_GDB_TDESC:
18654 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 18655 case NT_PRXFPREG:
1ec5cd37 18656 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
18657 case NT_PPC_VMX:
18658 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
18659 case NT_PPC_VSX:
18660 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
18661 case NT_PPC_TAR:
18662 return _("NT_PPC_TAR (ppc TAR register)");
18663 case NT_PPC_PPR:
18664 return _("NT_PPC_PPR (ppc PPR register)");
18665 case NT_PPC_DSCR:
18666 return _("NT_PPC_DSCR (ppc DSCR register)");
18667 case NT_PPC_EBB:
18668 return _("NT_PPC_EBB (ppc EBB registers)");
18669 case NT_PPC_PMU:
18670 return _("NT_PPC_PMU (ppc PMU registers)");
18671 case NT_PPC_TM_CGPR:
18672 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
18673 case NT_PPC_TM_CFPR:
18674 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
18675 case NT_PPC_TM_CVMX:
18676 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
18677 case NT_PPC_TM_CVSX:
3fd21718 18678 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
18679 case NT_PPC_TM_SPR:
18680 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
18681 case NT_PPC_TM_CTAR:
18682 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
18683 case NT_PPC_TM_CPPR:
18684 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
18685 case NT_PPC_TM_CDSCR:
18686 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
18687 case NT_386_TLS:
18688 return _("NT_386_TLS (x86 TLS information)");
18689 case NT_386_IOPERM:
18690 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
18691 case NT_X86_XSTATE:
18692 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
18693 case NT_X86_CET:
18694 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
18695 case NT_S390_HIGH_GPRS:
18696 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
18697 case NT_S390_TIMER:
18698 return _("NT_S390_TIMER (s390 timer register)");
18699 case NT_S390_TODCMP:
18700 return _("NT_S390_TODCMP (s390 TOD comparator register)");
18701 case NT_S390_TODPREG:
18702 return _("NT_S390_TODPREG (s390 TOD programmable register)");
18703 case NT_S390_CTRS:
18704 return _("NT_S390_CTRS (s390 control registers)");
18705 case NT_S390_PREFIX:
18706 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
18707 case NT_S390_LAST_BREAK:
18708 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
18709 case NT_S390_SYSTEM_CALL:
18710 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
18711 case NT_S390_TDB:
18712 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
18713 case NT_S390_VXRS_LOW:
18714 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
18715 case NT_S390_VXRS_HIGH:
18716 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
18717 case NT_S390_GS_CB:
18718 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
18719 case NT_S390_GS_BC:
18720 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
18721 case NT_ARM_VFP:
18722 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
18723 case NT_ARM_TLS:
18724 return _("NT_ARM_TLS (AArch TLS registers)");
18725 case NT_ARM_HW_BREAK:
18726 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
18727 case NT_ARM_HW_WATCH:
18728 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
3b2bef8b
LM
18729 case NT_ARM_SVE:
18730 return _("NT_ARM_SVE (AArch SVE registers)");
18731 case NT_ARM_PAC_MASK:
18732 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
18733 case NT_ARM_TAGGED_ADDR_CTRL:
18734 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
27456742
AK
18735 case NT_ARC_V2:
18736 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
18737 case NT_RISCV_CSR:
18738 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 18739 case NT_PSTATUS:
1ec5cd37 18740 return _("NT_PSTATUS (pstatus structure)");
57346661 18741 case NT_FPREGS:
1ec5cd37 18742 return _("NT_FPREGS (floating point registers)");
57346661 18743 case NT_PSINFO:
1ec5cd37 18744 return _("NT_PSINFO (psinfo structure)");
57346661 18745 case NT_LWPSTATUS:
1ec5cd37 18746 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 18747 case NT_LWPSINFO:
1ec5cd37 18748 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 18749 case NT_WIN32PSTATUS:
1ec5cd37 18750 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
18751 case NT_SIGINFO:
18752 return _("NT_SIGINFO (siginfo_t data)");
18753 case NT_FILE:
18754 return _("NT_FILE (mapped files)");
894982bf
LM
18755 case NT_MEMTAG:
18756 return _("NT_MEMTAG (memory tags)");
1ec5cd37
NC
18757 default:
18758 break;
18759 }
18760 else
18761 switch (e_type)
18762 {
18763 case NT_VERSION:
18764 return _("NT_VERSION (version)");
18765 case NT_ARCH:
18766 return _("NT_ARCH (architecture)");
9ef920e9 18767 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 18768 return _("OPEN");
9ef920e9 18769 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 18770 return _("func");
1ec5cd37
NC
18771 default:
18772 break;
18773 }
18774
e9e44622 18775 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 18776 return buff;
779fe533
NC
18777}
18778
015dc7e1 18779static bool
9ece1fa9
TT
18780print_core_note (Elf_Internal_Note *pnote)
18781{
18782 unsigned int addr_size = is_32bit_elf ? 4 : 8;
18783 bfd_vma count, page_size;
18784 unsigned char *descdata, *filenames, *descend;
18785
18786 if (pnote->type != NT_FILE)
04ac15ab
AS
18787 {
18788 if (do_wide)
18789 printf ("\n");
015dc7e1 18790 return true;
04ac15ab 18791 }
9ece1fa9
TT
18792
18793#ifndef BFD64
18794 if (!is_32bit_elf)
18795 {
18796 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
18797 /* Still "successful". */
015dc7e1 18798 return true;
9ece1fa9
TT
18799 }
18800#endif
18801
18802 if (pnote->descsz < 2 * addr_size)
18803 {
32ec8896 18804 error (_(" Malformed note - too short for header\n"));
015dc7e1 18805 return false;
9ece1fa9
TT
18806 }
18807
18808 descdata = (unsigned char *) pnote->descdata;
18809 descend = descdata + pnote->descsz;
18810
18811 if (descdata[pnote->descsz - 1] != '\0')
18812 {
32ec8896 18813 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 18814 return false;
9ece1fa9
TT
18815 }
18816
18817 count = byte_get (descdata, addr_size);
18818 descdata += addr_size;
18819
18820 page_size = byte_get (descdata, addr_size);
18821 descdata += addr_size;
18822
5396a86e
AM
18823 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
18824 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 18825 {
32ec8896 18826 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 18827 return false;
9ece1fa9
TT
18828 }
18829
18830 printf (_(" Page size: "));
18831 print_vma (page_size, DEC);
18832 printf ("\n");
18833
18834 printf (_(" %*s%*s%*s\n"),
18835 (int) (2 + 2 * addr_size), _("Start"),
18836 (int) (4 + 2 * addr_size), _("End"),
18837 (int) (4 + 2 * addr_size), _("Page Offset"));
18838 filenames = descdata + count * 3 * addr_size;
595712bb 18839 while (count-- > 0)
9ece1fa9
TT
18840 {
18841 bfd_vma start, end, file_ofs;
18842
18843 if (filenames == descend)
18844 {
32ec8896 18845 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 18846 return false;
9ece1fa9
TT
18847 }
18848
18849 start = byte_get (descdata, addr_size);
18850 descdata += addr_size;
18851 end = byte_get (descdata, addr_size);
18852 descdata += addr_size;
18853 file_ofs = byte_get (descdata, addr_size);
18854 descdata += addr_size;
18855
18856 printf (" ");
18857 print_vma (start, FULL_HEX);
18858 printf (" ");
18859 print_vma (end, FULL_HEX);
18860 printf (" ");
18861 print_vma (file_ofs, FULL_HEX);
18862 printf ("\n %s\n", filenames);
18863
18864 filenames += 1 + strlen ((char *) filenames);
18865 }
18866
015dc7e1 18867 return true;
9ece1fa9
TT
18868}
18869
1118d252
RM
18870static const char *
18871get_gnu_elf_note_type (unsigned e_type)
18872{
1449284b 18873 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
18874 switch (e_type)
18875 {
18876 case NT_GNU_ABI_TAG:
18877 return _("NT_GNU_ABI_TAG (ABI version tag)");
18878 case NT_GNU_HWCAP:
18879 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
18880 case NT_GNU_BUILD_ID:
18881 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
18882 case NT_GNU_GOLD_VERSION:
18883 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
18884 case NT_GNU_PROPERTY_TYPE_0:
18885 return _("NT_GNU_PROPERTY_TYPE_0");
18886 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
18887 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
18888 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
18889 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 18890 default:
1449284b
NC
18891 {
18892 static char buff[64];
1118d252 18893
1449284b
NC
18894 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18895 return buff;
18896 }
18897 }
1118d252
RM
18898}
18899
a9eafb08
L
18900static void
18901decode_x86_compat_isa (unsigned int bitmask)
18902{
18903 while (bitmask)
18904 {
18905 unsigned int bit = bitmask & (- bitmask);
18906
18907 bitmask &= ~ bit;
18908 switch (bit)
18909 {
18910 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
18911 printf ("i486");
18912 break;
18913 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
18914 printf ("586");
18915 break;
18916 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
18917 printf ("686");
18918 break;
18919 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
18920 printf ("SSE");
18921 break;
18922 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
18923 printf ("SSE2");
18924 break;
18925 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
18926 printf ("SSE3");
18927 break;
18928 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
18929 printf ("SSSE3");
18930 break;
18931 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
18932 printf ("SSE4_1");
18933 break;
18934 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
18935 printf ("SSE4_2");
18936 break;
18937 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
18938 printf ("AVX");
18939 break;
18940 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
18941 printf ("AVX2");
18942 break;
18943 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
18944 printf ("AVX512F");
18945 break;
18946 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
18947 printf ("AVX512CD");
18948 break;
18949 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
18950 printf ("AVX512ER");
18951 break;
18952 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
18953 printf ("AVX512PF");
18954 break;
18955 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
18956 printf ("AVX512VL");
18957 break;
18958 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
18959 printf ("AVX512DQ");
18960 break;
18961 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
18962 printf ("AVX512BW");
18963 break;
65b3d26e
L
18964 default:
18965 printf (_("<unknown: %x>"), bit);
18966 break;
a9eafb08
L
18967 }
18968 if (bitmask)
18969 printf (", ");
18970 }
18971}
18972
9ef920e9 18973static void
32930e4e 18974decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 18975{
0a59decb 18976 if (!bitmask)
90c745dc
L
18977 {
18978 printf (_("<None>"));
18979 return;
18980 }
90c745dc 18981
9ef920e9
NC
18982 while (bitmask)
18983 {
1fc87489 18984 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
18985
18986 bitmask &= ~ bit;
18987 switch (bit)
18988 {
32930e4e 18989 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
18990 printf ("CMOV");
18991 break;
32930e4e 18992 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
18993 printf ("SSE");
18994 break;
32930e4e 18995 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
18996 printf ("SSE2");
18997 break;
32930e4e 18998 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
18999 printf ("SSE3");
19000 break;
32930e4e 19001 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19002 printf ("SSSE3");
19003 break;
32930e4e 19004 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19005 printf ("SSE4_1");
19006 break;
32930e4e 19007 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19008 printf ("SSE4_2");
19009 break;
32930e4e 19010 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19011 printf ("AVX");
19012 break;
32930e4e 19013 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19014 printf ("AVX2");
19015 break;
32930e4e 19016 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19017 printf ("FMA");
19018 break;
32930e4e 19019 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19020 printf ("AVX512F");
19021 break;
32930e4e 19022 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19023 printf ("AVX512CD");
19024 break;
32930e4e 19025 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19026 printf ("AVX512ER");
19027 break;
32930e4e 19028 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19029 printf ("AVX512PF");
19030 break;
32930e4e 19031 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19032 printf ("AVX512VL");
19033 break;
32930e4e 19034 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19035 printf ("AVX512DQ");
19036 break;
32930e4e 19037 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19038 printf ("AVX512BW");
19039 break;
32930e4e 19040 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19041 printf ("AVX512_4FMAPS");
19042 break;
32930e4e 19043 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19044 printf ("AVX512_4VNNIW");
19045 break;
32930e4e 19046 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19047 printf ("AVX512_BITALG");
19048 break;
32930e4e 19049 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19050 printf ("AVX512_IFMA");
19051 break;
32930e4e 19052 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19053 printf ("AVX512_VBMI");
19054 break;
32930e4e 19055 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19056 printf ("AVX512_VBMI2");
19057 break;
32930e4e 19058 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19059 printf ("AVX512_VNNI");
19060 break;
32930e4e 19061 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19062 printf ("AVX512_BF16");
19063 break;
65b3d26e
L
19064 default:
19065 printf (_("<unknown: %x>"), bit);
19066 break;
9ef920e9
NC
19067 }
19068 if (bitmask)
19069 printf (", ");
19070 }
19071}
19072
32930e4e
L
19073static void
19074decode_x86_isa (unsigned int bitmask)
19075{
32930e4e
L
19076 while (bitmask)
19077 {
19078 unsigned int bit = bitmask & (- bitmask);
19079
19080 bitmask &= ~ bit;
19081 switch (bit)
19082 {
b0ab0693
L
19083 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19084 printf ("x86-64-baseline");
19085 break;
32930e4e
L
19086 case GNU_PROPERTY_X86_ISA_1_V2:
19087 printf ("x86-64-v2");
19088 break;
19089 case GNU_PROPERTY_X86_ISA_1_V3:
19090 printf ("x86-64-v3");
19091 break;
19092 case GNU_PROPERTY_X86_ISA_1_V4:
19093 printf ("x86-64-v4");
19094 break;
19095 default:
19096 printf (_("<unknown: %x>"), bit);
19097 break;
19098 }
19099 if (bitmask)
19100 printf (", ");
19101 }
19102}
19103
ee2fdd6f 19104static void
a9eafb08 19105decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19106{
0a59decb 19107 if (!bitmask)
90c745dc
L
19108 {
19109 printf (_("<None>"));
19110 return;
19111 }
90c745dc 19112
ee2fdd6f
L
19113 while (bitmask)
19114 {
19115 unsigned int bit = bitmask & (- bitmask);
19116
19117 bitmask &= ~ bit;
19118 switch (bit)
19119 {
19120 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19121 printf ("IBT");
ee2fdd6f 19122 break;
48580982 19123 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19124 printf ("SHSTK");
48580982 19125 break;
279d901e
L
19126 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19127 printf ("LAM_U48");
19128 break;
19129 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19130 printf ("LAM_U57");
19131 break;
ee2fdd6f
L
19132 default:
19133 printf (_("<unknown: %x>"), bit);
19134 break;
19135 }
19136 if (bitmask)
19137 printf (", ");
19138 }
19139}
19140
a9eafb08
L
19141static void
19142decode_x86_feature_2 (unsigned int bitmask)
19143{
0a59decb 19144 if (!bitmask)
90c745dc
L
19145 {
19146 printf (_("<None>"));
19147 return;
19148 }
90c745dc 19149
a9eafb08
L
19150 while (bitmask)
19151 {
19152 unsigned int bit = bitmask & (- bitmask);
19153
19154 bitmask &= ~ bit;
19155 switch (bit)
19156 {
19157 case GNU_PROPERTY_X86_FEATURE_2_X86:
19158 printf ("x86");
19159 break;
19160 case GNU_PROPERTY_X86_FEATURE_2_X87:
19161 printf ("x87");
19162 break;
19163 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19164 printf ("MMX");
19165 break;
19166 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19167 printf ("XMM");
19168 break;
19169 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19170 printf ("YMM");
19171 break;
19172 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19173 printf ("ZMM");
19174 break;
a308b89d
L
19175 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19176 printf ("TMM");
19177 break;
32930e4e
L
19178 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19179 printf ("MASK");
19180 break;
a9eafb08
L
19181 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19182 printf ("FXSR");
19183 break;
19184 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19185 printf ("XSAVE");
19186 break;
19187 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19188 printf ("XSAVEOPT");
19189 break;
19190 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19191 printf ("XSAVEC");
19192 break;
65b3d26e
L
19193 default:
19194 printf (_("<unknown: %x>"), bit);
19195 break;
a9eafb08
L
19196 }
19197 if (bitmask)
19198 printf (", ");
19199 }
19200}
19201
cd702818
SD
19202static void
19203decode_aarch64_feature_1_and (unsigned int bitmask)
19204{
19205 while (bitmask)
19206 {
19207 unsigned int bit = bitmask & (- bitmask);
19208
19209 bitmask &= ~ bit;
19210 switch (bit)
19211 {
19212 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19213 printf ("BTI");
19214 break;
19215
19216 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19217 printf ("PAC");
19218 break;
19219
19220 default:
19221 printf (_("<unknown: %x>"), bit);
19222 break;
19223 }
19224 if (bitmask)
19225 printf (", ");
19226 }
19227}
19228
9ef920e9 19229static void
dda8d76d 19230print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19231{
19232 unsigned char * ptr = (unsigned char *) pnote->descdata;
19233 unsigned char * ptr_end = ptr + pnote->descsz;
19234 unsigned int size = is_32bit_elf ? 4 : 8;
19235
19236 printf (_(" Properties: "));
19237
1fc87489 19238 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19239 {
19240 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19241 return;
19242 }
19243
6ab2c4ed 19244 while (ptr < ptr_end)
9ef920e9 19245 {
1fc87489 19246 unsigned int j;
6ab2c4ed
MC
19247 unsigned int type;
19248 unsigned int datasz;
19249
19250 if ((size_t) (ptr_end - ptr) < 8)
19251 {
19252 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19253 break;
19254 }
19255
19256 type = byte_get (ptr, 4);
19257 datasz = byte_get (ptr + 4, 4);
9ef920e9 19258
1fc87489 19259 ptr += 8;
9ef920e9 19260
6ab2c4ed 19261 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19262 {
1fc87489
L
19263 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19264 type, datasz);
9ef920e9 19265 break;
1fc87489 19266 }
9ef920e9 19267
1fc87489
L
19268 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19269 {
dda8d76d
NC
19270 if (filedata->file_header.e_machine == EM_X86_64
19271 || filedata->file_header.e_machine == EM_IAMCU
19272 || filedata->file_header.e_machine == EM_386)
1fc87489 19273 {
aa7bca9b
L
19274 unsigned int bitmask;
19275
19276 if (datasz == 4)
0a59decb 19277 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19278 else
19279 bitmask = 0;
19280
1fc87489
L
19281 switch (type)
19282 {
19283 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19284 if (datasz != 4)
aa7bca9b
L
19285 printf (_("x86 ISA used: <corrupt length: %#x> "),
19286 datasz);
1fc87489 19287 else
aa7bca9b
L
19288 {
19289 printf ("x86 ISA used: ");
19290 decode_x86_isa (bitmask);
19291 }
1fc87489 19292 goto next;
9ef920e9 19293
1fc87489 19294 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19295 if (datasz != 4)
aa7bca9b
L
19296 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19297 datasz);
1fc87489 19298 else
aa7bca9b
L
19299 {
19300 printf ("x86 ISA needed: ");
19301 decode_x86_isa (bitmask);
19302 }
1fc87489 19303 goto next;
9ef920e9 19304
ee2fdd6f 19305 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19306 if (datasz != 4)
aa7bca9b
L
19307 printf (_("x86 feature: <corrupt length: %#x> "),
19308 datasz);
ee2fdd6f 19309 else
aa7bca9b
L
19310 {
19311 printf ("x86 feature: ");
a9eafb08
L
19312 decode_x86_feature_1 (bitmask);
19313 }
19314 goto next;
19315
19316 case GNU_PROPERTY_X86_FEATURE_2_USED:
19317 if (datasz != 4)
19318 printf (_("x86 feature used: <corrupt length: %#x> "),
19319 datasz);
19320 else
19321 {
19322 printf ("x86 feature used: ");
19323 decode_x86_feature_2 (bitmask);
19324 }
19325 goto next;
19326
19327 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
19328 if (datasz != 4)
19329 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
19330 else
19331 {
19332 printf ("x86 feature needed: ");
19333 decode_x86_feature_2 (bitmask);
19334 }
19335 goto next;
19336
19337 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
19338 if (datasz != 4)
19339 printf (_("x86 ISA used: <corrupt length: %#x> "),
19340 datasz);
19341 else
19342 {
19343 printf ("x86 ISA used: ");
19344 decode_x86_compat_isa (bitmask);
19345 }
19346 goto next;
19347
19348 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
19349 if (datasz != 4)
19350 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19351 datasz);
19352 else
19353 {
19354 printf ("x86 ISA needed: ");
19355 decode_x86_compat_isa (bitmask);
aa7bca9b 19356 }
ee2fdd6f
L
19357 goto next;
19358
32930e4e
L
19359 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
19360 if (datasz != 4)
19361 printf (_("x86 ISA used: <corrupt length: %#x> "),
19362 datasz);
19363 else
19364 {
19365 printf ("x86 ISA used: ");
19366 decode_x86_compat_2_isa (bitmask);
19367 }
19368 goto next;
19369
19370 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
19371 if (datasz != 4)
19372 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19373 datasz);
19374 else
19375 {
19376 printf ("x86 ISA needed: ");
19377 decode_x86_compat_2_isa (bitmask);
19378 }
19379 goto next;
19380
1fc87489
L
19381 default:
19382 break;
19383 }
19384 }
cd702818
SD
19385 else if (filedata->file_header.e_machine == EM_AARCH64)
19386 {
19387 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
19388 {
19389 printf ("AArch64 feature: ");
19390 if (datasz != 4)
19391 printf (_("<corrupt length: %#x> "), datasz);
19392 else
19393 decode_aarch64_feature_1_and (byte_get (ptr, 4));
19394 goto next;
19395 }
19396 }
1fc87489
L
19397 }
19398 else
19399 {
19400 switch (type)
9ef920e9 19401 {
1fc87489
L
19402 case GNU_PROPERTY_STACK_SIZE:
19403 printf (_("stack size: "));
19404 if (datasz != size)
19405 printf (_("<corrupt length: %#x> "), datasz);
19406 else
19407 printf ("%#lx", (unsigned long) byte_get (ptr, size));
19408 goto next;
19409
19410 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
19411 printf ("no copy on protected ");
19412 if (datasz)
19413 printf (_("<corrupt length: %#x> "), datasz);
19414 goto next;
19415
19416 default:
9ef920e9
NC
19417 break;
19418 }
9ef920e9
NC
19419 }
19420
1fc87489
L
19421 if (type < GNU_PROPERTY_LOPROC)
19422 printf (_("<unknown type %#x data: "), type);
19423 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 19424 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
19425 else
19426 printf (_("<application-specific type %#x data: "), type);
19427 for (j = 0; j < datasz; ++j)
19428 printf ("%02x ", ptr[j] & 0xff);
19429 printf (">");
19430
dc1e8a47 19431 next:
9ef920e9 19432 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
19433 if (ptr == ptr_end)
19434 break;
1fc87489 19435
6ab2c4ed
MC
19436 if (do_wide)
19437 printf (", ");
19438 else
19439 printf ("\n\t");
9ef920e9
NC
19440 }
19441
19442 printf ("\n");
19443}
19444
015dc7e1 19445static bool
dda8d76d 19446print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 19447{
1449284b 19448 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
19449 switch (pnote->type)
19450 {
19451 case NT_GNU_BUILD_ID:
19452 {
19453 unsigned long i;
19454
19455 printf (_(" Build ID: "));
19456 for (i = 0; i < pnote->descsz; ++i)
19457 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 19458 printf ("\n");
664f90a3
TT
19459 }
19460 break;
19461
19462 case NT_GNU_ABI_TAG:
19463 {
19464 unsigned long os, major, minor, subminor;
19465 const char *osname;
19466
3102e897
NC
19467 /* PR 17531: file: 030-599401-0.004. */
19468 if (pnote->descsz < 16)
19469 {
19470 printf (_(" <corrupt GNU_ABI_TAG>\n"));
19471 break;
19472 }
19473
664f90a3
TT
19474 os = byte_get ((unsigned char *) pnote->descdata, 4);
19475 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19476 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
19477 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
19478
19479 switch (os)
19480 {
19481 case GNU_ABI_TAG_LINUX:
19482 osname = "Linux";
19483 break;
19484 case GNU_ABI_TAG_HURD:
19485 osname = "Hurd";
19486 break;
19487 case GNU_ABI_TAG_SOLARIS:
19488 osname = "Solaris";
19489 break;
19490 case GNU_ABI_TAG_FREEBSD:
19491 osname = "FreeBSD";
19492 break;
19493 case GNU_ABI_TAG_NETBSD:
19494 osname = "NetBSD";
19495 break;
14ae95f2
RM
19496 case GNU_ABI_TAG_SYLLABLE:
19497 osname = "Syllable";
19498 break;
19499 case GNU_ABI_TAG_NACL:
19500 osname = "NaCl";
19501 break;
664f90a3
TT
19502 default:
19503 osname = "Unknown";
19504 break;
19505 }
19506
19507 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
19508 major, minor, subminor);
19509 }
19510 break;
926c5385
CC
19511
19512 case NT_GNU_GOLD_VERSION:
19513 {
19514 unsigned long i;
19515
19516 printf (_(" Version: "));
19517 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
19518 printf ("%c", pnote->descdata[i]);
19519 printf ("\n");
19520 }
19521 break;
1449284b
NC
19522
19523 case NT_GNU_HWCAP:
19524 {
19525 unsigned long num_entries, mask;
19526
19527 /* Hardware capabilities information. Word 0 is the number of entries.
19528 Word 1 is a bitmask of enabled entries. The rest of the descriptor
19529 is a series of entries, where each entry is a single byte followed
19530 by a nul terminated string. The byte gives the bit number to test
19531 if enabled in the bitmask. */
19532 printf (_(" Hardware Capabilities: "));
19533 if (pnote->descsz < 8)
19534 {
32ec8896 19535 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 19536 return false;
1449284b
NC
19537 }
19538 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
19539 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19540 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
19541 /* FIXME: Add code to display the entries... */
19542 }
19543 break;
19544
9ef920e9 19545 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 19546 print_gnu_property_note (filedata, pnote);
9ef920e9 19547 break;
9abca702 19548
1449284b
NC
19549 default:
19550 /* Handle unrecognised types. An error message should have already been
19551 created by get_gnu_elf_note_type(), so all that we need to do is to
19552 display the data. */
19553 {
19554 unsigned long i;
19555
19556 printf (_(" Description data: "));
19557 for (i = 0; i < pnote->descsz; ++i)
19558 printf ("%02x ", pnote->descdata[i] & 0xff);
19559 printf ("\n");
19560 }
19561 break;
664f90a3
TT
19562 }
19563
015dc7e1 19564 return true;
664f90a3
TT
19565}
19566
685080f2
NC
19567static const char *
19568get_v850_elf_note_type (enum v850_notes n_type)
19569{
19570 static char buff[64];
19571
19572 switch (n_type)
19573 {
19574 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
19575 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
19576 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
19577 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
19578 case V850_NOTE_CACHE_INFO: return _("Use of cache");
19579 case V850_NOTE_MMU_INFO: return _("Use of MMU");
19580 default:
19581 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
19582 return buff;
19583 }
19584}
19585
015dc7e1 19586static bool
685080f2
NC
19587print_v850_note (Elf_Internal_Note * pnote)
19588{
19589 unsigned int val;
19590
19591 if (pnote->descsz != 4)
015dc7e1 19592 return false;
32ec8896 19593
685080f2
NC
19594 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
19595
19596 if (val == 0)
19597 {
19598 printf (_("not set\n"));
015dc7e1 19599 return true;
685080f2
NC
19600 }
19601
19602 switch (pnote->type)
19603 {
19604 case V850_NOTE_ALIGNMENT:
19605 switch (val)
19606 {
015dc7e1
AM
19607 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
19608 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
19609 }
19610 break;
14ae95f2 19611
685080f2
NC
19612 case V850_NOTE_DATA_SIZE:
19613 switch (val)
19614 {
015dc7e1
AM
19615 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
19616 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
19617 }
19618 break;
14ae95f2 19619
685080f2
NC
19620 case V850_NOTE_FPU_INFO:
19621 switch (val)
19622 {
015dc7e1
AM
19623 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
19624 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
19625 }
19626 break;
14ae95f2 19627
685080f2
NC
19628 case V850_NOTE_MMU_INFO:
19629 case V850_NOTE_CACHE_INFO:
19630 case V850_NOTE_SIMD_INFO:
19631 if (val == EF_RH850_SIMD)
19632 {
19633 printf (_("yes\n"));
015dc7e1 19634 return true;
685080f2
NC
19635 }
19636 break;
19637
19638 default:
19639 /* An 'unknown note type' message will already have been displayed. */
19640 break;
19641 }
19642
19643 printf (_("unknown value: %x\n"), val);
015dc7e1 19644 return false;
685080f2
NC
19645}
19646
015dc7e1 19647static bool
c6056a74
SF
19648process_netbsd_elf_note (Elf_Internal_Note * pnote)
19649{
19650 unsigned int version;
19651
19652 switch (pnote->type)
19653 {
19654 case NT_NETBSD_IDENT:
b966f55f
AM
19655 if (pnote->descsz < 1)
19656 break;
c6056a74
SF
19657 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19658 if ((version / 10000) % 100)
b966f55f 19659 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
19660 version, version / 100000000, (version / 1000000) % 100,
19661 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 19662 'A' + (version / 10000) % 26);
c6056a74
SF
19663 else
19664 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 19665 version, version / 100000000, (version / 1000000) % 100,
15f205b1 19666 (version / 100) % 100);
015dc7e1 19667 return true;
c6056a74
SF
19668
19669 case NT_NETBSD_MARCH:
9abca702 19670 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 19671 pnote->descdata);
015dc7e1 19672 return true;
c6056a74 19673
9abca702 19674 case NT_NETBSD_PAX:
b966f55f
AM
19675 if (pnote->descsz < 1)
19676 break;
9abca702
CZ
19677 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19678 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
19679 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
19680 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
19681 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
19682 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
19683 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
19684 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 19685 return true;
c6056a74 19686 }
b966f55f
AM
19687
19688 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
19689 pnote->descsz, pnote->type);
015dc7e1 19690 return false;
c6056a74
SF
19691}
19692
f4ddf30f 19693static const char *
dda8d76d 19694get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 19695{
f4ddf30f
JB
19696 switch (e_type)
19697 {
19698 case NT_FREEBSD_THRMISC:
19699 return _("NT_THRMISC (thrmisc structure)");
19700 case NT_FREEBSD_PROCSTAT_PROC:
19701 return _("NT_PROCSTAT_PROC (proc data)");
19702 case NT_FREEBSD_PROCSTAT_FILES:
19703 return _("NT_PROCSTAT_FILES (files data)");
19704 case NT_FREEBSD_PROCSTAT_VMMAP:
19705 return _("NT_PROCSTAT_VMMAP (vmmap data)");
19706 case NT_FREEBSD_PROCSTAT_GROUPS:
19707 return _("NT_PROCSTAT_GROUPS (groups data)");
19708 case NT_FREEBSD_PROCSTAT_UMASK:
19709 return _("NT_PROCSTAT_UMASK (umask data)");
19710 case NT_FREEBSD_PROCSTAT_RLIMIT:
19711 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
19712 case NT_FREEBSD_PROCSTAT_OSREL:
19713 return _("NT_PROCSTAT_OSREL (osreldate data)");
19714 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
19715 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
19716 case NT_FREEBSD_PROCSTAT_AUXV:
19717 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
19718 case NT_FREEBSD_PTLWPINFO:
19719 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 19720 }
dda8d76d 19721 return get_note_type (filedata, e_type);
f4ddf30f
JB
19722}
19723
9437c45b 19724static const char *
dda8d76d 19725get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
19726{
19727 static char buff[64];
19728
540e6170
CZ
19729 switch (e_type)
19730 {
19731 case NT_NETBSDCORE_PROCINFO:
19732 /* NetBSD core "procinfo" structure. */
19733 return _("NetBSD procinfo structure");
9437c45b 19734
540e6170
CZ
19735 case NT_NETBSDCORE_AUXV:
19736 return _("NetBSD ELF auxiliary vector data");
9437c45b 19737
06d949ec
KR
19738 case NT_NETBSDCORE_LWPSTATUS:
19739 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 19740
540e6170 19741 default:
06d949ec 19742 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
19743 defined for NetBSD core files. If the note type is less
19744 than the start of the machine-dependent note types, we don't
19745 understand it. */
19746
19747 if (e_type < NT_NETBSDCORE_FIRSTMACH)
19748 {
19749 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19750 return buff;
19751 }
19752 break;
9437c45b
JT
19753 }
19754
dda8d76d 19755 switch (filedata->file_header.e_machine)
9437c45b
JT
19756 {
19757 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
19758 and PT_GETFPREGS == mach+2. */
19759
19760 case EM_OLD_ALPHA:
19761 case EM_ALPHA:
19762 case EM_SPARC:
19763 case EM_SPARC32PLUS:
19764 case EM_SPARCV9:
19765 switch (e_type)
19766 {
2b692964 19767 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 19768 return _("PT_GETREGS (reg structure)");
2b692964 19769 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 19770 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19771 default:
19772 break;
19773 }
19774 break;
19775
c0d38b0e
CZ
19776 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
19777 There's also old PT___GETREGS40 == mach + 1 for old reg
19778 structure which lacks GBR. */
19779 case EM_SH:
19780 switch (e_type)
19781 {
19782 case NT_NETBSDCORE_FIRSTMACH + 1:
19783 return _("PT___GETREGS40 (old reg structure)");
19784 case NT_NETBSDCORE_FIRSTMACH + 3:
19785 return _("PT_GETREGS (reg structure)");
19786 case NT_NETBSDCORE_FIRSTMACH + 5:
19787 return _("PT_GETFPREGS (fpreg structure)");
19788 default:
19789 break;
19790 }
19791 break;
19792
9437c45b
JT
19793 /* On all other arch's, PT_GETREGS == mach+1 and
19794 PT_GETFPREGS == mach+3. */
19795 default:
19796 switch (e_type)
19797 {
2b692964 19798 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 19799 return _("PT_GETREGS (reg structure)");
2b692964 19800 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 19801 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19802 default:
19803 break;
19804 }
19805 }
19806
9cf03b7e 19807 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 19808 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
19809 return buff;
19810}
19811
70616151
TT
19812static const char *
19813get_stapsdt_note_type (unsigned e_type)
19814{
19815 static char buff[64];
19816
19817 switch (e_type)
19818 {
19819 case NT_STAPSDT:
19820 return _("NT_STAPSDT (SystemTap probe descriptors)");
19821
19822 default:
19823 break;
19824 }
19825
19826 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19827 return buff;
19828}
19829
015dc7e1 19830static bool
c6a9fc58
TT
19831print_stapsdt_note (Elf_Internal_Note *pnote)
19832{
3ca60c57
NC
19833 size_t len, maxlen;
19834 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
19835 char *data = pnote->descdata;
19836 char *data_end = pnote->descdata + pnote->descsz;
19837 bfd_vma pc, base_addr, semaphore;
19838 char *provider, *probe, *arg_fmt;
19839
3ca60c57
NC
19840 if (pnote->descsz < (addr_size * 3))
19841 goto stapdt_note_too_small;
19842
c6a9fc58
TT
19843 pc = byte_get ((unsigned char *) data, addr_size);
19844 data += addr_size;
3ca60c57 19845
c6a9fc58
TT
19846 base_addr = byte_get ((unsigned char *) data, addr_size);
19847 data += addr_size;
3ca60c57 19848
c6a9fc58
TT
19849 semaphore = byte_get ((unsigned char *) data, addr_size);
19850 data += addr_size;
19851
3ca60c57
NC
19852 if (data >= data_end)
19853 goto stapdt_note_too_small;
19854 maxlen = data_end - data;
19855 len = strnlen (data, maxlen);
19856 if (len < maxlen)
19857 {
19858 provider = data;
19859 data += len + 1;
19860 }
19861 else
19862 goto stapdt_note_too_small;
19863
19864 if (data >= data_end)
19865 goto stapdt_note_too_small;
19866 maxlen = data_end - data;
19867 len = strnlen (data, maxlen);
19868 if (len < maxlen)
19869 {
19870 probe = data;
19871 data += len + 1;
19872 }
19873 else
19874 goto stapdt_note_too_small;
9abca702 19875
3ca60c57
NC
19876 if (data >= data_end)
19877 goto stapdt_note_too_small;
19878 maxlen = data_end - data;
19879 len = strnlen (data, maxlen);
19880 if (len < maxlen)
19881 {
19882 arg_fmt = data;
19883 data += len + 1;
19884 }
19885 else
19886 goto stapdt_note_too_small;
c6a9fc58
TT
19887
19888 printf (_(" Provider: %s\n"), provider);
19889 printf (_(" Name: %s\n"), probe);
19890 printf (_(" Location: "));
19891 print_vma (pc, FULL_HEX);
19892 printf (_(", Base: "));
19893 print_vma (base_addr, FULL_HEX);
19894 printf (_(", Semaphore: "));
19895 print_vma (semaphore, FULL_HEX);
9cf03b7e 19896 printf ("\n");
c6a9fc58
TT
19897 printf (_(" Arguments: %s\n"), arg_fmt);
19898
19899 return data == data_end;
3ca60c57
NC
19900
19901 stapdt_note_too_small:
19902 printf (_(" <corrupt - note is too small>\n"));
19903 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 19904 return false;
c6a9fc58
TT
19905}
19906
00e98fc7
TG
19907static const char *
19908get_ia64_vms_note_type (unsigned e_type)
19909{
19910 static char buff[64];
19911
19912 switch (e_type)
19913 {
19914 case NT_VMS_MHD:
19915 return _("NT_VMS_MHD (module header)");
19916 case NT_VMS_LNM:
19917 return _("NT_VMS_LNM (language name)");
19918 case NT_VMS_SRC:
19919 return _("NT_VMS_SRC (source files)");
19920 case NT_VMS_TITLE:
9cf03b7e 19921 return "NT_VMS_TITLE";
00e98fc7
TG
19922 case NT_VMS_EIDC:
19923 return _("NT_VMS_EIDC (consistency check)");
19924 case NT_VMS_FPMODE:
19925 return _("NT_VMS_FPMODE (FP mode)");
19926 case NT_VMS_LINKTIME:
9cf03b7e 19927 return "NT_VMS_LINKTIME";
00e98fc7
TG
19928 case NT_VMS_IMGNAM:
19929 return _("NT_VMS_IMGNAM (image name)");
19930 case NT_VMS_IMGID:
19931 return _("NT_VMS_IMGID (image id)");
19932 case NT_VMS_LINKID:
19933 return _("NT_VMS_LINKID (link id)");
19934 case NT_VMS_IMGBID:
19935 return _("NT_VMS_IMGBID (build id)");
19936 case NT_VMS_GSTNAM:
19937 return _("NT_VMS_GSTNAM (sym table name)");
19938 case NT_VMS_ORIG_DYN:
9cf03b7e 19939 return "NT_VMS_ORIG_DYN";
00e98fc7 19940 case NT_VMS_PATCHTIME:
9cf03b7e 19941 return "NT_VMS_PATCHTIME";
00e98fc7
TG
19942 default:
19943 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19944 return buff;
19945 }
19946}
19947
015dc7e1 19948static bool
00e98fc7
TG
19949print_ia64_vms_note (Elf_Internal_Note * pnote)
19950{
8d18bf79
NC
19951 int maxlen = pnote->descsz;
19952
19953 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
19954 goto desc_size_fail;
19955
00e98fc7
TG
19956 switch (pnote->type)
19957 {
19958 case NT_VMS_MHD:
8d18bf79
NC
19959 if (maxlen <= 36)
19960 goto desc_size_fail;
19961
19962 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
19963
19964 printf (_(" Creation date : %.17s\n"), pnote->descdata);
19965 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
19966 if (l + 34 < maxlen)
19967 {
19968 printf (_(" Module name : %s\n"), pnote->descdata + 34);
19969 if (l + 35 < maxlen)
19970 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
19971 else
19972 printf (_(" Module version : <missing>\n"));
19973 }
00e98fc7 19974 else
8d18bf79
NC
19975 {
19976 printf (_(" Module name : <missing>\n"));
19977 printf (_(" Module version : <missing>\n"));
19978 }
00e98fc7 19979 break;
8d18bf79 19980
00e98fc7 19981 case NT_VMS_LNM:
8d18bf79 19982 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19983 break;
8d18bf79 19984
00e98fc7
TG
19985#ifdef BFD64
19986 case NT_VMS_FPMODE:
9cf03b7e 19987 printf (_(" Floating Point mode: "));
8d18bf79
NC
19988 if (maxlen < 8)
19989 goto desc_size_fail;
19990 /* FIXME: Generate an error if descsz > 8 ? */
19991
4a5cb34f 19992 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 19993 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 19994 break;
8d18bf79 19995
00e98fc7
TG
19996 case NT_VMS_LINKTIME:
19997 printf (_(" Link time: "));
8d18bf79
NC
19998 if (maxlen < 8)
19999 goto desc_size_fail;
20000 /* FIXME: Generate an error if descsz > 8 ? */
20001
00e98fc7 20002 print_vms_time
8d18bf79 20003 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20004 printf ("\n");
20005 break;
8d18bf79 20006
00e98fc7
TG
20007 case NT_VMS_PATCHTIME:
20008 printf (_(" Patch time: "));
8d18bf79
NC
20009 if (maxlen < 8)
20010 goto desc_size_fail;
20011 /* FIXME: Generate an error if descsz > 8 ? */
20012
00e98fc7 20013 print_vms_time
8d18bf79 20014 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20015 printf ("\n");
20016 break;
8d18bf79 20017
00e98fc7 20018 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20019 if (maxlen < 34)
20020 goto desc_size_fail;
20021
00e98fc7
TG
20022 printf (_(" Major id: %u, minor id: %u\n"),
20023 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
20024 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 20025 printf (_(" Last modified : "));
00e98fc7
TG
20026 print_vms_time
20027 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 20028 printf (_("\n Link flags : "));
4a5cb34f 20029 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 20030 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 20031 printf (_(" Header flags: 0x%08x\n"),
948f632f 20032 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 20033 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
20034 break;
20035#endif
8d18bf79 20036
00e98fc7 20037 case NT_VMS_IMGNAM:
8d18bf79 20038 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20039 break;
8d18bf79 20040
00e98fc7 20041 case NT_VMS_GSTNAM:
8d18bf79 20042 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20043 break;
8d18bf79 20044
00e98fc7 20045 case NT_VMS_IMGID:
8d18bf79 20046 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20047 break;
8d18bf79 20048
00e98fc7 20049 case NT_VMS_LINKID:
8d18bf79 20050 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20051 break;
8d18bf79 20052
00e98fc7 20053 default:
015dc7e1 20054 return false;
00e98fc7 20055 }
8d18bf79 20056
015dc7e1 20057 return true;
8d18bf79
NC
20058
20059 desc_size_fail:
20060 printf (_(" <corrupt - data size is too small>\n"));
20061 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20062 return false;
00e98fc7
TG
20063}
20064
fd486f32
AM
20065struct build_attr_cache {
20066 Filedata *filedata;
20067 char *strtab;
20068 unsigned long strtablen;
20069 Elf_Internal_Sym *symtab;
20070 unsigned long nsyms;
20071} ba_cache;
20072
6f156d7a
NC
20073/* Find the symbol associated with a build attribute that is attached
20074 to address OFFSET. If PNAME is non-NULL then store the name of
20075 the symbol (if found) in the provided pointer, Returns NULL if a
20076 symbol could not be found. */
c799a79d 20077
6f156d7a 20078static Elf_Internal_Sym *
015dc7e1
AM
20079get_symbol_for_build_attribute (Filedata *filedata,
20080 unsigned long offset,
20081 bool is_open_attr,
20082 const char **pname)
9ef920e9 20083{
fd486f32
AM
20084 Elf_Internal_Sym *saved_sym = NULL;
20085 Elf_Internal_Sym *sym;
9ef920e9 20086
dda8d76d 20087 if (filedata->section_headers != NULL
fd486f32 20088 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20089 {
c799a79d 20090 Elf_Internal_Shdr * symsec;
9ef920e9 20091
fd486f32
AM
20092 free (ba_cache.strtab);
20093 ba_cache.strtab = NULL;
20094 free (ba_cache.symtab);
20095 ba_cache.symtab = NULL;
20096
c799a79d 20097 /* Load the symbol and string sections. */
dda8d76d
NC
20098 for (symsec = filedata->section_headers;
20099 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20100 symsec ++)
9ef920e9 20101 {
28d13567
AM
20102 if (symsec->sh_type == SHT_SYMTAB
20103 && get_symtab (filedata, symsec,
20104 &ba_cache.symtab, &ba_cache.nsyms,
20105 &ba_cache.strtab, &ba_cache.strtablen))
20106 break;
9ef920e9 20107 }
fd486f32 20108 ba_cache.filedata = filedata;
9ef920e9
NC
20109 }
20110
fd486f32 20111 if (ba_cache.symtab == NULL)
6f156d7a 20112 return NULL;
9ef920e9 20113
c799a79d 20114 /* Find a symbol whose value matches offset. */
fd486f32 20115 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20116 if (sym->st_value == offset)
20117 {
fd486f32 20118 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20119 /* Huh ? This should not happen. */
20120 continue;
9ef920e9 20121
fd486f32 20122 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20123 continue;
9ef920e9 20124
8fd75781
NC
20125 /* The AArch64 and ARM architectures define mapping symbols
20126 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20127 if (ba_cache.strtab[sym->st_name] == '$'
20128 && ba_cache.strtab[sym->st_name + 1] != 0
20129 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20130 continue;
20131
c799a79d
NC
20132 if (is_open_attr)
20133 {
20134 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20135 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20136 FUNC symbols entirely. */
20137 switch (ELF_ST_TYPE (sym->st_info))
20138 {
c799a79d 20139 case STT_OBJECT:
6f156d7a 20140 case STT_FILE:
c799a79d 20141 saved_sym = sym;
6f156d7a
NC
20142 if (sym->st_size)
20143 {
20144 /* If the symbol has a size associated
20145 with it then we can stop searching. */
fd486f32 20146 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20147 }
c799a79d 20148 continue;
9ef920e9 20149
c799a79d
NC
20150 case STT_FUNC:
20151 /* Ignore function symbols. */
20152 continue;
20153
20154 default:
20155 break;
20156 }
20157
20158 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20159 {
c799a79d
NC
20160 case STB_GLOBAL:
20161 if (saved_sym == NULL
20162 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20163 saved_sym = sym;
20164 break;
c871dade 20165
c799a79d
NC
20166 case STB_LOCAL:
20167 if (saved_sym == NULL)
20168 saved_sym = sym;
20169 break;
20170
20171 default:
9ef920e9
NC
20172 break;
20173 }
20174 }
c799a79d
NC
20175 else
20176 {
20177 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20178 continue;
20179
20180 saved_sym = sym;
20181 break;
20182 }
20183 }
20184
6f156d7a 20185 if (saved_sym && pname)
fd486f32 20186 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20187
20188 return saved_sym;
c799a79d
NC
20189}
20190
d20e98ab
NC
20191/* Returns true iff addr1 and addr2 are in the same section. */
20192
015dc7e1 20193static bool
d20e98ab
NC
20194same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20195{
20196 Elf_Internal_Shdr * a1;
20197 Elf_Internal_Shdr * a2;
20198
20199 a1 = find_section_by_address (filedata, addr1);
20200 a2 = find_section_by_address (filedata, addr2);
9abca702 20201
d20e98ab
NC
20202 return a1 == a2 && a1 != NULL;
20203}
20204
015dc7e1 20205static bool
dda8d76d
NC
20206print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20207 Filedata * filedata)
c799a79d 20208{
015dc7e1
AM
20209 static unsigned long global_offset = 0;
20210 static unsigned long global_end = 0;
20211 static unsigned long func_offset = 0;
20212 static unsigned long func_end = 0;
c871dade 20213
015dc7e1
AM
20214 Elf_Internal_Sym *sym;
20215 const char *name;
20216 unsigned long start;
20217 unsigned long end;
20218 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20219
20220 switch (pnote->descsz)
c799a79d 20221 {
6f156d7a
NC
20222 case 0:
20223 /* A zero-length description means that the range of
20224 the previous note of the same type should be used. */
c799a79d 20225 if (is_open_attr)
c871dade 20226 {
6f156d7a
NC
20227 if (global_end > global_offset)
20228 printf (_(" Applies to region from %#lx to %#lx\n"),
20229 global_offset, global_end);
20230 else
20231 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20232 }
20233 else
20234 {
6f156d7a
NC
20235 if (func_end > func_offset)
20236 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20237 else
20238 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20239 }
015dc7e1 20240 return true;
9ef920e9 20241
6f156d7a
NC
20242 case 4:
20243 start = byte_get ((unsigned char *) pnote->descdata, 4);
20244 end = 0;
20245 break;
20246
20247 case 8:
c74147bb
NC
20248 start = byte_get ((unsigned char *) pnote->descdata, 4);
20249 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20250 break;
20251
20252 case 16:
20253 start = byte_get ((unsigned char *) pnote->descdata, 8);
20254 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20255 break;
9abca702 20256
6f156d7a 20257 default:
c799a79d
NC
20258 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
20259 printf (_(" <invalid descsz>"));
015dc7e1 20260 return false;
c799a79d
NC
20261 }
20262
6f156d7a
NC
20263 name = NULL;
20264 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
20265 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
20266 in order to avoid them being confused with the start address of the
20267 first function in the file... */
20268 if (sym == NULL && is_open_attr)
20269 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
20270 & name);
6f156d7a
NC
20271
20272 if (end == 0 && sym != NULL && sym->st_size > 0)
20273 end = start + sym->st_size;
c799a79d
NC
20274
20275 if (is_open_attr)
20276 {
d20e98ab
NC
20277 /* FIXME: Need to properly allow for section alignment.
20278 16 is just the alignment used on x86_64. */
20279 if (global_end > 0
20280 && start > BFD_ALIGN (global_end, 16)
20281 /* Build notes are not guaranteed to be organised in order of
20282 increasing address, but we should find the all of the notes
20283 for one section in the same place. */
20284 && same_section (filedata, start, global_end))
6f156d7a
NC
20285 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
20286 global_end + 1, start - 1);
20287
20288 printf (_(" Applies to region from %#lx"), start);
20289 global_offset = start;
20290
20291 if (end)
20292 {
20293 printf (_(" to %#lx"), end);
20294 global_end = end;
20295 }
c799a79d
NC
20296 }
20297 else
20298 {
6f156d7a
NC
20299 printf (_(" Applies to region from %#lx"), start);
20300 func_offset = start;
20301
20302 if (end)
20303 {
20304 printf (_(" to %#lx"), end);
20305 func_end = end;
20306 }
c799a79d
NC
20307 }
20308
6f156d7a
NC
20309 if (sym && name)
20310 printf (_(" (%s)"), name);
20311
20312 printf ("\n");
015dc7e1 20313 return true;
9ef920e9
NC
20314}
20315
015dc7e1 20316static bool
9ef920e9
NC
20317print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
20318{
1d15e434
NC
20319 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
20320 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
20321 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
20322 char name_type;
20323 char name_attribute;
1d15e434 20324 const char * expected_types;
9ef920e9
NC
20325 const char * name = pnote->namedata;
20326 const char * text;
88305e1b 20327 signed int left;
9ef920e9
NC
20328
20329 if (name == NULL || pnote->namesz < 2)
20330 {
20331 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 20332 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20333 return false;
9ef920e9
NC
20334 }
20335
6f156d7a
NC
20336 if (do_wide)
20337 left = 28;
20338 else
20339 left = 20;
88305e1b
NC
20340
20341 /* Version 2 of the spec adds a "GA" prefix to the name field. */
20342 if (name[0] == 'G' && name[1] == 'A')
20343 {
6f156d7a
NC
20344 if (pnote->namesz < 4)
20345 {
20346 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
20347 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20348 return false;
6f156d7a
NC
20349 }
20350
88305e1b
NC
20351 printf ("GA");
20352 name += 2;
20353 left -= 2;
20354 }
20355
9ef920e9
NC
20356 switch ((name_type = * name))
20357 {
20358 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20359 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20360 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20361 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20362 printf ("%c", * name);
88305e1b 20363 left --;
9ef920e9
NC
20364 break;
20365 default:
20366 error (_("unrecognised attribute type in name field: %d\n"), name_type);
20367 print_symbol (-20, _("<unknown name type>"));
015dc7e1 20368 return false;
9ef920e9
NC
20369 }
20370
9ef920e9
NC
20371 ++ name;
20372 text = NULL;
20373
20374 switch ((name_attribute = * name))
20375 {
20376 case GNU_BUILD_ATTRIBUTE_VERSION:
20377 text = _("<version>");
1d15e434 20378 expected_types = string_expected;
9ef920e9
NC
20379 ++ name;
20380 break;
20381 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20382 text = _("<stack prot>");
75d7d298 20383 expected_types = "!+*";
9ef920e9
NC
20384 ++ name;
20385 break;
20386 case GNU_BUILD_ATTRIBUTE_RELRO:
20387 text = _("<relro>");
1d15e434 20388 expected_types = bool_expected;
9ef920e9
NC
20389 ++ name;
20390 break;
20391 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
20392 text = _("<stack size>");
1d15e434 20393 expected_types = number_expected;
9ef920e9
NC
20394 ++ name;
20395 break;
20396 case GNU_BUILD_ATTRIBUTE_TOOL:
20397 text = _("<tool>");
1d15e434 20398 expected_types = string_expected;
9ef920e9
NC
20399 ++ name;
20400 break;
20401 case GNU_BUILD_ATTRIBUTE_ABI:
20402 text = _("<ABI>");
20403 expected_types = "$*";
20404 ++ name;
20405 break;
20406 case GNU_BUILD_ATTRIBUTE_PIC:
20407 text = _("<PIC>");
1d15e434 20408 expected_types = number_expected;
9ef920e9
NC
20409 ++ name;
20410 break;
a8be5506
NC
20411 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
20412 text = _("<short enum>");
1d15e434 20413 expected_types = bool_expected;
a8be5506
NC
20414 ++ name;
20415 break;
9ef920e9
NC
20416 default:
20417 if (ISPRINT (* name))
20418 {
20419 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
20420
20421 if (len > left && ! do_wide)
20422 len = left;
75d7d298 20423 printf ("%.*s:", len, name);
9ef920e9 20424 left -= len;
0dd6ae21 20425 name += len;
9ef920e9
NC
20426 }
20427 else
20428 {
3e6b6445 20429 static char tmpbuf [128];
88305e1b 20430
3e6b6445
NC
20431 error (_("unrecognised byte in name field: %d\n"), * name);
20432 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
20433 text = tmpbuf;
20434 name ++;
9ef920e9
NC
20435 }
20436 expected_types = "*$!+";
20437 break;
20438 }
20439
20440 if (text)
88305e1b 20441 left -= printf ("%s", text);
9ef920e9
NC
20442
20443 if (strchr (expected_types, name_type) == NULL)
75d7d298 20444 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
20445
20446 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
20447 {
20448 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
20449 (unsigned long) pnote->namesz,
20450 (long) (name - pnote->namedata));
015dc7e1 20451 return false;
9ef920e9
NC
20452 }
20453
20454 if (left < 1 && ! do_wide)
015dc7e1 20455 return true;
9ef920e9
NC
20456
20457 switch (name_type)
20458 {
20459 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20460 {
b06b2c92 20461 unsigned int bytes;
ddef72cd
NC
20462 unsigned long long val = 0;
20463 unsigned int shift = 0;
20464 char * decoded = NULL;
20465
b06b2c92
NC
20466 bytes = pnote->namesz - (name - pnote->namedata);
20467 if (bytes > 0)
20468 /* The -1 is because the name field is always 0 terminated, and we
20469 want to be able to ensure that the shift in the while loop below
20470 will not overflow. */
20471 -- bytes;
20472
ddef72cd
NC
20473 if (bytes > sizeof (val))
20474 {
3e6b6445
NC
20475 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
20476 bytes);
20477 bytes = sizeof (val);
ddef72cd 20478 }
3e6b6445
NC
20479 /* We do not bother to warn if bytes == 0 as this can
20480 happen with some early versions of the gcc plugin. */
9ef920e9
NC
20481
20482 while (bytes --)
20483 {
54b8331d 20484 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
20485
20486 val |= byte << shift;
9ef920e9
NC
20487 shift += 8;
20488 }
20489
75d7d298 20490 switch (name_attribute)
9ef920e9 20491 {
75d7d298 20492 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
20493 switch (val)
20494 {
75d7d298
NC
20495 case 0: decoded = "static"; break;
20496 case 1: decoded = "pic"; break;
20497 case 2: decoded = "PIC"; break;
20498 case 3: decoded = "pie"; break;
20499 case 4: decoded = "PIE"; break;
20500 default: break;
9ef920e9 20501 }
75d7d298
NC
20502 break;
20503 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20504 switch (val)
9ef920e9 20505 {
75d7d298
NC
20506 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
20507 case 0: decoded = "off"; break;
20508 case 1: decoded = "on"; break;
20509 case 2: decoded = "all"; break;
20510 case 3: decoded = "strong"; break;
20511 case 4: decoded = "explicit"; break;
20512 default: break;
9ef920e9 20513 }
75d7d298
NC
20514 break;
20515 default:
20516 break;
9ef920e9
NC
20517 }
20518
75d7d298 20519 if (decoded != NULL)
3e6b6445
NC
20520 {
20521 print_symbol (-left, decoded);
20522 left = 0;
20523 }
20524 else if (val == 0)
20525 {
20526 printf ("0x0");
20527 left -= 3;
20528 }
9ef920e9 20529 else
75d7d298
NC
20530 {
20531 if (do_wide)
ddef72cd 20532 left -= printf ("0x%llx", val);
75d7d298 20533 else
ddef72cd 20534 left -= printf ("0x%-.*llx", left, val);
75d7d298 20535 }
9ef920e9
NC
20536 }
20537 break;
20538 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20539 left -= print_symbol (- left, name);
20540 break;
20541 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20542 left -= print_symbol (- left, "true");
20543 break;
20544 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20545 left -= print_symbol (- left, "false");
20546 break;
20547 }
20548
20549 if (do_wide && left > 0)
20550 printf ("%-*s", left, " ");
9abca702 20551
015dc7e1 20552 return true;
9ef920e9
NC
20553}
20554
6d118b09
NC
20555/* Note that by the ELF standard, the name field is already null byte
20556 terminated, and namesz includes the terminating null byte.
20557 I.E. the value of namesz for the name "FSF" is 4.
20558
e3c8793a 20559 If the value of namesz is zero, there is no name present. */
9ef920e9 20560
015dc7e1 20561static bool
9ef920e9 20562process_note (Elf_Internal_Note * pnote,
dda8d76d 20563 Filedata * filedata)
779fe533 20564{
2cf0635d
NC
20565 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
20566 const char * nt;
9437c45b
JT
20567
20568 if (pnote->namesz == 0)
1ec5cd37
NC
20569 /* If there is no note name, then use the default set of
20570 note type strings. */
dda8d76d 20571 nt = get_note_type (filedata, pnote->type);
1ec5cd37 20572
24d127aa 20573 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
20574 /* GNU-specific object file notes. */
20575 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 20576
24d127aa 20577 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 20578 /* FreeBSD-specific core file notes. */
dda8d76d 20579 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 20580
24d127aa 20581 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 20582 /* NetBSD-specific core file notes. */
dda8d76d 20583 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 20584
24d127aa 20585 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
20586 /* NetBSD-specific core file notes. */
20587 return process_netbsd_elf_note (pnote);
20588
24d127aa 20589 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
20590 /* NetBSD-specific core file notes. */
20591 return process_netbsd_elf_note (pnote);
20592
e9b095a5 20593 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
20594 {
20595 /* SPU-specific core file notes. */
20596 nt = pnote->namedata + 4;
20597 name = "SPU";
20598 }
20599
24d127aa 20600 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
20601 /* VMS/ia64-specific file notes. */
20602 nt = get_ia64_vms_note_type (pnote->type);
20603
24d127aa 20604 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
20605 nt = get_stapsdt_note_type (pnote->type);
20606
9437c45b 20607 else
1ec5cd37
NC
20608 /* Don't recognize this note name; just use the default set of
20609 note type strings. */
dda8d76d 20610 nt = get_note_type (filedata, pnote->type);
9437c45b 20611
1449284b 20612 printf (" ");
9ef920e9 20613
24d127aa 20614 if (((startswith (pnote->namedata, "GA")
483767a3
AM
20615 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20616 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20617 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20618 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
20619 print_gnu_build_attribute_name (pnote);
20620 else
20621 print_symbol (-20, name);
20622
20623 if (do_wide)
20624 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
20625 else
20626 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 20627
24d127aa 20628 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 20629 return print_ia64_vms_note (pnote);
24d127aa 20630 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 20631 return print_gnu_note (filedata, pnote);
24d127aa 20632 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 20633 return print_stapsdt_note (pnote);
24d127aa 20634 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 20635 return print_core_note (pnote);
24d127aa 20636 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
20637 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20638 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20639 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20640 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 20641 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 20642
9ef920e9 20643 if (pnote->descsz)
1449284b
NC
20644 {
20645 unsigned long i;
20646
20647 printf (_(" description data: "));
20648 for (i = 0; i < pnote->descsz; i++)
178d8719 20649 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
20650 if (!do_wide)
20651 printf ("\n");
1449284b
NC
20652 }
20653
9ef920e9
NC
20654 if (do_wide)
20655 printf ("\n");
20656
015dc7e1 20657 return true;
1449284b 20658}
6d118b09 20659
015dc7e1 20660static bool
dda8d76d
NC
20661process_notes_at (Filedata * filedata,
20662 Elf_Internal_Shdr * section,
20663 bfd_vma offset,
82ed9683
L
20664 bfd_vma length,
20665 bfd_vma align)
779fe533 20666{
015dc7e1
AM
20667 Elf_External_Note *pnotes;
20668 Elf_External_Note *external;
20669 char *end;
20670 bool res = true;
103f02d3 20671
779fe533 20672 if (length <= 0)
015dc7e1 20673 return false;
103f02d3 20674
1449284b
NC
20675 if (section)
20676 {
dda8d76d 20677 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 20678 if (pnotes)
32ec8896 20679 {
dda8d76d 20680 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
20681 {
20682 free (pnotes);
015dc7e1 20683 return false;
f761cb13 20684 }
32ec8896 20685 }
1449284b
NC
20686 }
20687 else
82ed9683 20688 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 20689 _("notes"));
4dff97b2 20690
dd24e3da 20691 if (pnotes == NULL)
015dc7e1 20692 return false;
779fe533 20693
103f02d3 20694 external = pnotes;
103f02d3 20695
ca0e11aa
NC
20696 if (filedata->is_separate)
20697 printf (_("In linked file '%s': "), filedata->file_name);
20698 else
20699 printf ("\n");
1449284b 20700 if (section)
ca0e11aa 20701 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 20702 else
ca0e11aa 20703 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
20704 (unsigned long) offset, (unsigned long) length);
20705
82ed9683
L
20706 /* NB: Some note sections may have alignment value of 0 or 1. gABI
20707 specifies that notes should be aligned to 4 bytes in 32-bit
20708 objects and to 8 bytes in 64-bit objects. As a Linux extension,
20709 we also support 4 byte alignment in 64-bit objects. If section
20710 alignment is less than 4, we treate alignment as 4 bytes. */
20711 if (align < 4)
20712 align = 4;
20713 else if (align != 4 && align != 8)
20714 {
20715 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
20716 (long) align);
a788aedd 20717 free (pnotes);
015dc7e1 20718 return false;
82ed9683
L
20719 }
20720
dbe15e4e 20721 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 20722
c8071705
NC
20723 end = (char *) pnotes + length;
20724 while ((char *) external < end)
779fe533 20725 {
b34976b6 20726 Elf_Internal_Note inote;
15b42fb0 20727 size_t min_notesz;
4dff97b2 20728 char * next;
2cf0635d 20729 char * temp = NULL;
c8071705 20730 size_t data_remaining = end - (char *) external;
6d118b09 20731
dda8d76d 20732 if (!is_ia64_vms (filedata))
15b42fb0 20733 {
9dd3a467
NC
20734 /* PR binutils/15191
20735 Make sure that there is enough data to read. */
15b42fb0
AM
20736 min_notesz = offsetof (Elf_External_Note, name);
20737 if (data_remaining < min_notesz)
9dd3a467 20738 {
d3a49aa8
AM
20739 warn (ngettext ("Corrupt note: only %ld byte remains, "
20740 "not enough for a full note\n",
20741 "Corrupt note: only %ld bytes remain, "
20742 "not enough for a full note\n",
20743 data_remaining),
20744 (long) data_remaining);
9dd3a467
NC
20745 break;
20746 }
5396a86e
AM
20747 data_remaining -= min_notesz;
20748
15b42fb0
AM
20749 inote.type = BYTE_GET (external->type);
20750 inote.namesz = BYTE_GET (external->namesz);
20751 inote.namedata = external->name;
20752 inote.descsz = BYTE_GET (external->descsz);
276da9b3 20753 inote.descdata = ((char *) external
4dff97b2 20754 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 20755 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 20756 next = ((char *) external
4dff97b2 20757 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 20758 }
00e98fc7 20759 else
15b42fb0
AM
20760 {
20761 Elf64_External_VMS_Note *vms_external;
00e98fc7 20762
9dd3a467
NC
20763 /* PR binutils/15191
20764 Make sure that there is enough data to read. */
15b42fb0
AM
20765 min_notesz = offsetof (Elf64_External_VMS_Note, name);
20766 if (data_remaining < min_notesz)
9dd3a467 20767 {
d3a49aa8
AM
20768 warn (ngettext ("Corrupt note: only %ld byte remains, "
20769 "not enough for a full note\n",
20770 "Corrupt note: only %ld bytes remain, "
20771 "not enough for a full note\n",
20772 data_remaining),
20773 (long) data_remaining);
9dd3a467
NC
20774 break;
20775 }
5396a86e 20776 data_remaining -= min_notesz;
3e55a963 20777
15b42fb0
AM
20778 vms_external = (Elf64_External_VMS_Note *) external;
20779 inote.type = BYTE_GET (vms_external->type);
20780 inote.namesz = BYTE_GET (vms_external->namesz);
20781 inote.namedata = vms_external->name;
20782 inote.descsz = BYTE_GET (vms_external->descsz);
20783 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
20784 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20785 next = inote.descdata + align_power (inote.descsz, 3);
20786 }
20787
5396a86e
AM
20788 /* PR 17531: file: 3443835e. */
20789 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
20790 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
20791 || (size_t) (inote.descdata - inote.namedata) > data_remaining
20792 || (size_t) (next - inote.descdata) < inote.descsz
20793 || ((size_t) (next - inote.descdata)
20794 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 20795 {
15b42fb0 20796 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 20797 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
20798 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
20799 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
20800 break;
20801 }
20802
15b42fb0 20803 external = (Elf_External_Note *) next;
dd24e3da 20804
6d118b09
NC
20805 /* Verify that name is null terminated. It appears that at least
20806 one version of Linux (RedHat 6.0) generates corefiles that don't
20807 comply with the ELF spec by failing to include the null byte in
20808 namesz. */
18344509 20809 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 20810 {
5396a86e 20811 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 20812 {
5396a86e
AM
20813 temp = (char *) malloc (inote.namesz + 1);
20814 if (temp == NULL)
20815 {
20816 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 20817 res = false;
5396a86e
AM
20818 break;
20819 }
76da6bbe 20820
5396a86e
AM
20821 memcpy (temp, inote.namedata, inote.namesz);
20822 inote.namedata = temp;
20823 }
20824 inote.namedata[inote.namesz] = 0;
6d118b09
NC
20825 }
20826
dda8d76d 20827 if (! process_note (& inote, filedata))
015dc7e1 20828 res = false;
103f02d3 20829
9db70fc3
AM
20830 free (temp);
20831 temp = NULL;
779fe533
NC
20832 }
20833
20834 free (pnotes);
103f02d3 20835
779fe533
NC
20836 return res;
20837}
20838
015dc7e1 20839static bool
dda8d76d 20840process_corefile_note_segments (Filedata * filedata)
779fe533 20841{
015dc7e1 20842 Elf_Internal_Phdr *segment;
b34976b6 20843 unsigned int i;
015dc7e1 20844 bool res = true;
103f02d3 20845
dda8d76d 20846 if (! get_program_headers (filedata))
015dc7e1 20847 return true;
103f02d3 20848
dda8d76d
NC
20849 for (i = 0, segment = filedata->program_headers;
20850 i < filedata->file_header.e_phnum;
b34976b6 20851 i++, segment++)
779fe533
NC
20852 {
20853 if (segment->p_type == PT_NOTE)
dda8d76d 20854 if (! process_notes_at (filedata, NULL,
32ec8896 20855 (bfd_vma) segment->p_offset,
82ed9683
L
20856 (bfd_vma) segment->p_filesz,
20857 (bfd_vma) segment->p_align))
015dc7e1 20858 res = false;
779fe533 20859 }
103f02d3 20860
779fe533
NC
20861 return res;
20862}
20863
015dc7e1 20864static bool
dda8d76d 20865process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
20866{
20867 Elf_External_Note * pnotes;
20868 Elf_External_Note * external;
c8071705 20869 char * end;
015dc7e1 20870 bool res = true;
685080f2
NC
20871
20872 if (length <= 0)
015dc7e1 20873 return false;
685080f2 20874
dda8d76d 20875 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
20876 _("v850 notes"));
20877 if (pnotes == NULL)
015dc7e1 20878 return false;
685080f2
NC
20879
20880 external = pnotes;
c8071705 20881 end = (char*) pnotes + length;
685080f2
NC
20882
20883 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
20884 (unsigned long) offset, (unsigned long) length);
20885
c8071705 20886 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
20887 {
20888 Elf_External_Note * next;
20889 Elf_Internal_Note inote;
20890
20891 inote.type = BYTE_GET (external->type);
20892 inote.namesz = BYTE_GET (external->namesz);
20893 inote.namedata = external->name;
20894 inote.descsz = BYTE_GET (external->descsz);
20895 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
20896 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20897
c8071705
NC
20898 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
20899 {
20900 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
20901 inote.descdata = inote.namedata;
20902 inote.namesz = 0;
20903 }
20904
685080f2
NC
20905 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
20906
c8071705 20907 if ( ((char *) next > end)
685080f2
NC
20908 || ((char *) next < (char *) pnotes))
20909 {
20910 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
20911 (unsigned long) ((char *) external - (char *) pnotes));
20912 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20913 inote.type, inote.namesz, inote.descsz);
20914 break;
20915 }
20916
20917 external = next;
20918
20919 /* Prevent out-of-bounds indexing. */
c8071705 20920 if ( inote.namedata + inote.namesz > end
685080f2
NC
20921 || inote.namedata + inote.namesz < inote.namedata)
20922 {
20923 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
20924 (unsigned long) ((char *) external - (char *) pnotes));
20925 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20926 inote.type, inote.namesz, inote.descsz);
20927 break;
20928 }
20929
20930 printf (" %s: ", get_v850_elf_note_type (inote.type));
20931
20932 if (! print_v850_note (& inote))
20933 {
015dc7e1 20934 res = false;
685080f2
NC
20935 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
20936 inote.namesz, inote.descsz);
20937 }
20938 }
20939
20940 free (pnotes);
20941
20942 return res;
20943}
20944
015dc7e1 20945static bool
dda8d76d 20946process_note_sections (Filedata * filedata)
1ec5cd37 20947{
015dc7e1 20948 Elf_Internal_Shdr *section;
1ec5cd37 20949 unsigned long i;
32ec8896 20950 unsigned int n = 0;
015dc7e1 20951 bool res = true;
1ec5cd37 20952
dda8d76d
NC
20953 for (i = 0, section = filedata->section_headers;
20954 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 20955 i++, section++)
685080f2
NC
20956 {
20957 if (section->sh_type == SHT_NOTE)
20958 {
dda8d76d 20959 if (! process_notes_at (filedata, section,
32ec8896 20960 (bfd_vma) section->sh_offset,
82ed9683
L
20961 (bfd_vma) section->sh_size,
20962 (bfd_vma) section->sh_addralign))
015dc7e1 20963 res = false;
685080f2
NC
20964 n++;
20965 }
20966
dda8d76d
NC
20967 if (( filedata->file_header.e_machine == EM_V800
20968 || filedata->file_header.e_machine == EM_V850
20969 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
20970 && section->sh_type == SHT_RENESAS_INFO)
20971 {
dda8d76d 20972 if (! process_v850_notes (filedata,
32ec8896
NC
20973 (bfd_vma) section->sh_offset,
20974 (bfd_vma) section->sh_size))
015dc7e1 20975 res = false;
685080f2
NC
20976 n++;
20977 }
20978 }
df565f32
NC
20979
20980 if (n == 0)
20981 /* Try processing NOTE segments instead. */
dda8d76d 20982 return process_corefile_note_segments (filedata);
1ec5cd37
NC
20983
20984 return res;
20985}
20986
015dc7e1 20987static bool
dda8d76d 20988process_notes (Filedata * filedata)
779fe533
NC
20989{
20990 /* If we have not been asked to display the notes then do nothing. */
20991 if (! do_notes)
015dc7e1 20992 return true;
103f02d3 20993
dda8d76d
NC
20994 if (filedata->file_header.e_type != ET_CORE)
20995 return process_note_sections (filedata);
103f02d3 20996
779fe533 20997 /* No program headers means no NOTE segment. */
dda8d76d
NC
20998 if (filedata->file_header.e_phnum > 0)
20999 return process_corefile_note_segments (filedata);
779fe533 21000
ca0e11aa
NC
21001 if (filedata->is_separate)
21002 printf (_("No notes found in linked file '%s'.\n"),
21003 filedata->file_name);
21004 else
21005 printf (_("No notes found file.\n"));
21006
015dc7e1 21007 return true;
779fe533
NC
21008}
21009
60abdbed
NC
21010static unsigned char *
21011display_public_gnu_attributes (unsigned char * start,
21012 const unsigned char * const end)
21013{
21014 printf (_(" Unknown GNU attribute: %s\n"), start);
21015
21016 start += strnlen ((char *) start, end - start);
21017 display_raw_attribute (start, end);
21018
21019 return (unsigned char *) end;
21020}
21021
21022static unsigned char *
21023display_generic_attribute (unsigned char * start,
21024 unsigned int tag,
21025 const unsigned char * const end)
21026{
21027 if (tag == 0)
21028 return (unsigned char *) end;
21029
21030 return display_tag_value (tag, start, end);
21031}
21032
015dc7e1 21033static bool
dda8d76d 21034process_arch_specific (Filedata * filedata)
252b5132 21035{
a952a375 21036 if (! do_arch)
015dc7e1 21037 return true;
a952a375 21038
dda8d76d 21039 switch (filedata->file_header.e_machine)
252b5132 21040 {
53a346d8
CZ
21041 case EM_ARC:
21042 case EM_ARC_COMPACT:
21043 case EM_ARC_COMPACT2:
dda8d76d 21044 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
21045 display_arc_attribute,
21046 display_generic_attribute);
11c1ff18 21047 case EM_ARM:
dda8d76d 21048 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
21049 display_arm_attribute,
21050 display_generic_attribute);
21051
252b5132 21052 case EM_MIPS:
4fe85591 21053 case EM_MIPS_RS3_LE:
dda8d76d 21054 return process_mips_specific (filedata);
60abdbed
NC
21055
21056 case EM_MSP430:
dda8d76d 21057 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21058 display_msp430_attribute,
c0ea7c52 21059 display_msp430_gnu_attribute);
60abdbed 21060
2dc8dd17
JW
21061 case EM_RISCV:
21062 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21063 display_riscv_attribute,
21064 display_generic_attribute);
21065
35c08157 21066 case EM_NDS32:
dda8d76d 21067 return process_nds32_specific (filedata);
60abdbed 21068
85f7484a
PB
21069 case EM_68K:
21070 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21071 display_m68k_gnu_attribute);
21072
34c8bcba 21073 case EM_PPC:
b82317dd 21074 case EM_PPC64:
dda8d76d 21075 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21076 display_power_gnu_attribute);
21077
643f7afb
AK
21078 case EM_S390:
21079 case EM_S390_OLD:
dda8d76d 21080 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21081 display_s390_gnu_attribute);
21082
9e8c70f9
DM
21083 case EM_SPARC:
21084 case EM_SPARC32PLUS:
21085 case EM_SPARCV9:
dda8d76d 21086 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21087 display_sparc_gnu_attribute);
21088
59e6276b 21089 case EM_TI_C6000:
dda8d76d 21090 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
21091 display_tic6x_attribute,
21092 display_generic_attribute);
21093
0861f561
CQ
21094 case EM_CSKY:
21095 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
21096 display_csky_attribute, NULL);
21097
252b5132 21098 default:
dda8d76d 21099 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
21100 display_public_gnu_attributes,
21101 display_generic_attribute);
252b5132 21102 }
252b5132
RH
21103}
21104
015dc7e1 21105static bool
dda8d76d 21106get_file_header (Filedata * filedata)
252b5132 21107{
9ea033b2 21108 /* Read in the identity array. */
dda8d76d 21109 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21110 return false;
252b5132 21111
9ea033b2 21112 /* Determine how to read the rest of the header. */
dda8d76d 21113 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 21114 {
1a0670f3
AM
21115 default:
21116 case ELFDATANONE:
adab8cdc
AO
21117 case ELFDATA2LSB:
21118 byte_get = byte_get_little_endian;
21119 byte_put = byte_put_little_endian;
21120 break;
21121 case ELFDATA2MSB:
21122 byte_get = byte_get_big_endian;
21123 byte_put = byte_put_big_endian;
21124 break;
9ea033b2
NC
21125 }
21126
21127 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 21128 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
21129
21130 /* Read in the rest of the header. */
21131 if (is_32bit_elf)
21132 {
21133 Elf32_External_Ehdr ehdr32;
252b5132 21134
dda8d76d 21135 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21136 return false;
103f02d3 21137
dda8d76d
NC
21138 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
21139 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
21140 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
21141 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
21142 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
21143 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
21144 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
21145 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
21146 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
21147 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
21148 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
21149 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
21150 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 21151 }
252b5132 21152 else
9ea033b2
NC
21153 {
21154 Elf64_External_Ehdr ehdr64;
a952a375
NC
21155
21156 /* If we have been compiled with sizeof (bfd_vma) == 4, then
21157 we will not be able to cope with the 64bit data found in
21158 64 ELF files. Detect this now and abort before we start
50c2245b 21159 overwriting things. */
a952a375
NC
21160 if (sizeof (bfd_vma) < 8)
21161 {
e3c8793a
NC
21162 error (_("This instance of readelf has been built without support for a\n\
2116364 bit data type and so it cannot read 64 bit ELF files.\n"));
015dc7e1 21164 return false;
a952a375 21165 }
103f02d3 21166
dda8d76d 21167 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21168 return false;
103f02d3 21169
dda8d76d
NC
21170 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
21171 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
21172 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
21173 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
21174 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
21175 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
21176 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
21177 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
21178 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
21179 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
21180 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
21181 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
21182 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 21183 }
252b5132 21184
015dc7e1 21185 return true;
252b5132
RH
21186}
21187
13acb58d
AM
21188static void
21189free_filedata (Filedata *filedata)
21190{
21191 free (filedata->program_interpreter);
13acb58d 21192 free (filedata->program_headers);
13acb58d 21193 free (filedata->section_headers);
13acb58d 21194 free (filedata->string_table);
13acb58d 21195 free (filedata->dump.dump_sects);
13acb58d 21196 free (filedata->dynamic_strings);
13acb58d 21197 free (filedata->dynamic_symbols);
13acb58d 21198 free (filedata->dynamic_syminfo);
13acb58d 21199 free (filedata->dynamic_section);
13acb58d
AM
21200
21201 while (filedata->symtab_shndx_list != NULL)
21202 {
21203 elf_section_list *next = filedata->symtab_shndx_list->next;
21204 free (filedata->symtab_shndx_list);
21205 filedata->symtab_shndx_list = next;
21206 }
21207
21208 free (filedata->section_headers_groups);
13acb58d
AM
21209
21210 if (filedata->section_groups)
21211 {
21212 size_t i;
21213 struct group_list * g;
21214 struct group_list * next;
21215
21216 for (i = 0; i < filedata->group_count; i++)
21217 {
21218 for (g = filedata->section_groups [i].root; g != NULL; g = next)
21219 {
21220 next = g->next;
21221 free (g);
21222 }
21223 }
21224
21225 free (filedata->section_groups);
13acb58d 21226 }
066f8fbe
AM
21227 memset (&filedata->section_headers, 0,
21228 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
21229}
21230
dda8d76d
NC
21231static void
21232close_file (Filedata * filedata)
21233{
21234 if (filedata)
21235 {
21236 if (filedata->handle)
21237 fclose (filedata->handle);
21238 free (filedata);
21239 }
21240}
21241
21242void
21243close_debug_file (void * data)
21244{
13acb58d 21245 free_filedata ((Filedata *) data);
dda8d76d
NC
21246 close_file ((Filedata *) data);
21247}
21248
21249static Filedata *
015dc7e1 21250open_file (const char * pathname, bool is_separate)
dda8d76d
NC
21251{
21252 struct stat statbuf;
21253 Filedata * filedata = NULL;
21254
21255 if (stat (pathname, & statbuf) < 0
21256 || ! S_ISREG (statbuf.st_mode))
21257 goto fail;
21258
21259 filedata = calloc (1, sizeof * filedata);
21260 if (filedata == NULL)
21261 goto fail;
21262
21263 filedata->handle = fopen (pathname, "rb");
21264 if (filedata->handle == NULL)
21265 goto fail;
21266
21267 filedata->file_size = (bfd_size_type) statbuf.st_size;
21268 filedata->file_name = pathname;
ca0e11aa 21269 filedata->is_separate = is_separate;
dda8d76d
NC
21270
21271 if (! get_file_header (filedata))
21272 goto fail;
21273
4de91c10
AM
21274 if (!get_section_headers (filedata, false))
21275 goto fail;
dda8d76d
NC
21276
21277 return filedata;
21278
21279 fail:
21280 if (filedata)
21281 {
21282 if (filedata->handle)
21283 fclose (filedata->handle);
21284 free (filedata);
21285 }
21286 return NULL;
21287}
21288
21289void *
21290open_debug_file (const char * pathname)
21291{
015dc7e1 21292 return open_file (pathname, true);
dda8d76d
NC
21293}
21294
835f2fae
NC
21295static void
21296initialise_dump_sects (Filedata * filedata)
21297{
21298 /* Initialise the dump_sects array from the cmdline_dump_sects array.
21299 Note we do this even if cmdline_dump_sects is empty because we
21300 must make sure that the dump_sets array is zeroed out before each
21301 object file is processed. */
21302 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
21303 memset (filedata->dump.dump_sects, 0,
21304 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21305
21306 if (cmdline.num_dump_sects > 0)
21307 {
21308 if (filedata->dump.num_dump_sects == 0)
21309 /* A sneaky way of allocating the dump_sects array. */
21310 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
21311
21312 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
21313 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
21314 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21315 }
21316}
21317
fb52b2f4
NC
21318/* Process one ELF object file according to the command line options.
21319 This file may actually be stored in an archive. The file is
32ec8896
NC
21320 positioned at the start of the ELF object. Returns TRUE if no
21321 problems were encountered, FALSE otherwise. */
fb52b2f4 21322
015dc7e1 21323static bool
dda8d76d 21324process_object (Filedata * filedata)
252b5132 21325{
015dc7e1 21326 bool have_separate_files;
252b5132 21327 unsigned int i;
015dc7e1 21328 bool res;
252b5132 21329
dda8d76d 21330 if (! get_file_header (filedata))
252b5132 21331 {
dda8d76d 21332 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 21333 return false;
252b5132
RH
21334 }
21335
21336 /* Initialise per file variables. */
978c4450
AM
21337 for (i = ARRAY_SIZE (filedata->version_info); i--;)
21338 filedata->version_info[i] = 0;
252b5132 21339
978c4450
AM
21340 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
21341 filedata->dynamic_info[i] = 0;
21342 filedata->dynamic_info_DT_GNU_HASH = 0;
21343 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
21344
21345 /* Process the file. */
21346 if (show_name)
dda8d76d 21347 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 21348
835f2fae 21349 initialise_dump_sects (filedata);
d70c5fc7 21350
4de91c10
AM
21351 /* There may be some extensions in the first section header. Don't
21352 bomb if we can't read it. */
21353 get_section_headers (filedata, true);
21354
dda8d76d 21355 if (! process_file_header (filedata))
4de91c10
AM
21356 {
21357 res = false;
21358 goto out;
21359 }
252b5132 21360
e331b18d
AM
21361 /* Throw away the single section header read above, so that we
21362 re-read the entire set. */
21363 free (filedata->section_headers);
21364 filedata->section_headers = NULL;
21365
dda8d76d 21366 if (! process_section_headers (filedata))
2f62977e 21367 {
32ec8896 21368 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 21369 do_unwind = do_version = do_dump = do_arch = false;
252b5132 21370
2f62977e 21371 if (! do_using_dynamic)
015dc7e1 21372 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 21373 }
252b5132 21374
dda8d76d 21375 if (! process_section_groups (filedata))
32ec8896 21376 /* Without loaded section groups we cannot process unwind. */
015dc7e1 21377 do_unwind = false;
d1f5c6e3 21378
2482f306
AM
21379 res = process_program_headers (filedata);
21380 if (res)
21381 res = process_dynamic_section (filedata);
252b5132 21382
dda8d76d 21383 if (! process_relocs (filedata))
015dc7e1 21384 res = false;
252b5132 21385
dda8d76d 21386 if (! process_unwind (filedata))
015dc7e1 21387 res = false;
4d6ed7c8 21388
dda8d76d 21389 if (! process_symbol_table (filedata))
015dc7e1 21390 res = false;
252b5132 21391
0f03783c 21392 if (! process_lto_symbol_tables (filedata))
015dc7e1 21393 res = false;
b9e920ec 21394
dda8d76d 21395 if (! process_syminfo (filedata))
015dc7e1 21396 res = false;
252b5132 21397
dda8d76d 21398 if (! process_version_sections (filedata))
015dc7e1 21399 res = false;
252b5132 21400
82ed9683 21401 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 21402 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 21403 else
015dc7e1 21404 have_separate_files = false;
dda8d76d
NC
21405
21406 if (! process_section_contents (filedata))
015dc7e1 21407 res = false;
f5842774 21408
24841daa 21409 if (have_separate_files)
dda8d76d 21410 {
24841daa
NC
21411 separate_info * d;
21412
21413 for (d = first_separate_info; d != NULL; d = d->next)
21414 {
835f2fae
NC
21415 initialise_dump_sects (d->handle);
21416
ca0e11aa 21417 if (process_links && ! process_file_header (d->handle))
015dc7e1 21418 res = false;
ca0e11aa 21419 else if (! process_section_headers (d->handle))
015dc7e1 21420 res = false;
d6bfbc39 21421 else if (! process_section_contents (d->handle))
015dc7e1 21422 res = false;
ca0e11aa
NC
21423 else if (process_links)
21424 {
ca0e11aa 21425 if (! process_section_groups (d->handle))
015dc7e1 21426 res = false;
ca0e11aa 21427 if (! process_program_headers (d->handle))
015dc7e1 21428 res = false;
ca0e11aa 21429 if (! process_dynamic_section (d->handle))
015dc7e1 21430 res = false;
ca0e11aa 21431 if (! process_relocs (d->handle))
015dc7e1 21432 res = false;
ca0e11aa 21433 if (! process_unwind (d->handle))
015dc7e1 21434 res = false;
ca0e11aa 21435 if (! process_symbol_table (d->handle))
015dc7e1 21436 res = false;
ca0e11aa 21437 if (! process_lto_symbol_tables (d->handle))
015dc7e1 21438 res = false;
ca0e11aa 21439 if (! process_syminfo (d->handle))
015dc7e1 21440 res = false;
ca0e11aa 21441 if (! process_version_sections (d->handle))
015dc7e1 21442 res = false;
ca0e11aa 21443 if (! process_notes (d->handle))
015dc7e1 21444 res = false;
ca0e11aa 21445 }
24841daa
NC
21446 }
21447
21448 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
21449 }
21450
21451 if (! process_notes (filedata))
015dc7e1 21452 res = false;
103f02d3 21453
dda8d76d 21454 if (! process_gnu_liblist (filedata))
015dc7e1 21455 res = false;
047b2264 21456
dda8d76d 21457 if (! process_arch_specific (filedata))
015dc7e1 21458 res = false;
252b5132 21459
4de91c10 21460 out:
13acb58d 21461 free_filedata (filedata);
e4b17d5c 21462
19e6b90e 21463 free_debug_memory ();
18bd398b 21464
32ec8896 21465 return res;
252b5132
RH
21466}
21467
2cf0635d 21468/* Process an ELF archive.
32ec8896
NC
21469 On entry the file is positioned just after the ARMAG string.
21470 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 21471
015dc7e1
AM
21472static bool
21473process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
21474{
21475 struct archive_info arch;
21476 struct archive_info nested_arch;
21477 size_t got;
015dc7e1 21478 bool ret = true;
2cf0635d 21479
015dc7e1 21480 show_name = true;
2cf0635d
NC
21481
21482 /* The ARCH structure is used to hold information about this archive. */
21483 arch.file_name = NULL;
21484 arch.file = NULL;
21485 arch.index_array = NULL;
21486 arch.sym_table = NULL;
21487 arch.longnames = NULL;
21488
21489 /* The NESTED_ARCH structure is used as a single-item cache of information
21490 about a nested archive (when members of a thin archive reside within
21491 another regular archive file). */
21492 nested_arch.file_name = NULL;
21493 nested_arch.file = NULL;
21494 nested_arch.index_array = NULL;
21495 nested_arch.sym_table = NULL;
21496 nested_arch.longnames = NULL;
21497
dda8d76d 21498 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
21499 filedata->file_size, is_thin_archive,
21500 do_archive_index) != 0)
2cf0635d 21501 {
015dc7e1 21502 ret = false;
2cf0635d 21503 goto out;
4145f1d5 21504 }
fb52b2f4 21505
4145f1d5
NC
21506 if (do_archive_index)
21507 {
2cf0635d 21508 if (arch.sym_table == NULL)
1cb7d8b1
AM
21509 error (_("%s: unable to dump the index as none was found\n"),
21510 filedata->file_name);
4145f1d5
NC
21511 else
21512 {
591f7597 21513 unsigned long i, l;
4145f1d5
NC
21514 unsigned long current_pos;
21515
1cb7d8b1
AM
21516 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
21517 "in the symbol table)\n"),
21518 filedata->file_name, (unsigned long) arch.index_num,
21519 arch.sym_size);
dda8d76d
NC
21520
21521 current_pos = ftell (filedata->handle);
4145f1d5 21522
2cf0635d 21523 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 21524 {
1cb7d8b1
AM
21525 if (i == 0
21526 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
21527 {
21528 char * member_name
21529 = get_archive_member_name_at (&arch, arch.index_array[i],
21530 &nested_arch);
2cf0635d 21531
1cb7d8b1
AM
21532 if (member_name != NULL)
21533 {
21534 char * qualified_name
21535 = make_qualified_name (&arch, &nested_arch,
21536 member_name);
2cf0635d 21537
1cb7d8b1
AM
21538 if (qualified_name != NULL)
21539 {
21540 printf (_("Contents of binary %s at offset "),
21541 qualified_name);
c2a7d3f5
NC
21542 (void) print_vma (arch.index_array[i], PREFIX_HEX);
21543 putchar ('\n');
1cb7d8b1
AM
21544 free (qualified_name);
21545 }
fd486f32 21546 free (member_name);
4145f1d5
NC
21547 }
21548 }
2cf0635d
NC
21549
21550 if (l >= arch.sym_size)
4145f1d5 21551 {
1cb7d8b1
AM
21552 error (_("%s: end of the symbol table reached "
21553 "before the end of the index\n"),
dda8d76d 21554 filedata->file_name);
015dc7e1 21555 ret = false;
cb8f3167 21556 break;
4145f1d5 21557 }
591f7597 21558 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
21559 printf ("\t%.*s\n",
21560 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 21561 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
21562 }
21563
67ce483b 21564 if (arch.uses_64bit_indices)
c2a7d3f5
NC
21565 l = (l + 7) & ~ 7;
21566 else
21567 l += l & 1;
21568
2cf0635d 21569 if (l < arch.sym_size)
32ec8896 21570 {
d3a49aa8
AM
21571 error (ngettext ("%s: %ld byte remains in the symbol table, "
21572 "but without corresponding entries in "
21573 "the index table\n",
21574 "%s: %ld bytes remain in the symbol table, "
21575 "but without corresponding entries in "
21576 "the index table\n",
21577 arch.sym_size - l),
dda8d76d 21578 filedata->file_name, arch.sym_size - l);
015dc7e1 21579 ret = false;
32ec8896 21580 }
4145f1d5 21581
dda8d76d 21582 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 21583 {
1cb7d8b1
AM
21584 error (_("%s: failed to seek back to start of object files "
21585 "in the archive\n"),
dda8d76d 21586 filedata->file_name);
015dc7e1 21587 ret = false;
2cf0635d 21588 goto out;
4145f1d5 21589 }
fb52b2f4 21590 }
4145f1d5
NC
21591
21592 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
21593 && !do_segments && !do_header && !do_dump && !do_version
21594 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 21595 && !do_section_groups && !do_dyn_syms)
2cf0635d 21596 {
015dc7e1 21597 ret = true; /* Archive index only. */
2cf0635d
NC
21598 goto out;
21599 }
fb52b2f4
NC
21600 }
21601
fb52b2f4
NC
21602 while (1)
21603 {
2cf0635d
NC
21604 char * name;
21605 size_t namelen;
21606 char * qualified_name;
21607
21608 /* Read the next archive header. */
dda8d76d 21609 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
21610 {
21611 error (_("%s: failed to seek to next archive header\n"),
21612 arch.file_name);
015dc7e1 21613 ret = false;
1cb7d8b1
AM
21614 break;
21615 }
dda8d76d 21616 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 21617 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
21618 {
21619 if (got == 0)
2cf0635d 21620 break;
28e817cc
NC
21621 /* PR 24049 - we cannot use filedata->file_name as this will
21622 have already been freed. */
21623 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 21624
015dc7e1 21625 ret = false;
1cb7d8b1
AM
21626 break;
21627 }
2cf0635d 21628 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
21629 {
21630 error (_("%s: did not find a valid archive header\n"),
21631 arch.file_name);
015dc7e1 21632 ret = false;
1cb7d8b1
AM
21633 break;
21634 }
2cf0635d
NC
21635
21636 arch.next_arhdr_offset += sizeof arch.arhdr;
21637
978c4450
AM
21638 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
21639 if (filedata->archive_file_size & 01)
21640 ++filedata->archive_file_size;
2cf0635d
NC
21641
21642 name = get_archive_member_name (&arch, &nested_arch);
21643 if (name == NULL)
fb52b2f4 21644 {
28e817cc 21645 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 21646 ret = false;
d989285c 21647 break;
fb52b2f4 21648 }
2cf0635d 21649 namelen = strlen (name);
fb52b2f4 21650
2cf0635d
NC
21651 qualified_name = make_qualified_name (&arch, &nested_arch, name);
21652 if (qualified_name == NULL)
fb52b2f4 21653 {
28e817cc 21654 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 21655 free (name);
015dc7e1 21656 ret = false;
d989285c 21657 break;
fb52b2f4
NC
21658 }
21659
2cf0635d 21660 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
21661 {
21662 /* This is a proxy for an external member of a thin archive. */
21663 Filedata * member_filedata;
21664 char * member_file_name = adjust_relative_path
dda8d76d 21665 (filedata->file_name, name, namelen);
32ec8896 21666
fd486f32 21667 free (name);
1cb7d8b1
AM
21668 if (member_file_name == NULL)
21669 {
fd486f32 21670 free (qualified_name);
015dc7e1 21671 ret = false;
1cb7d8b1
AM
21672 break;
21673 }
2cf0635d 21674
015dc7e1 21675 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
21676 if (member_filedata == NULL)
21677 {
21678 error (_("Input file '%s' is not readable.\n"), member_file_name);
21679 free (member_file_name);
fd486f32 21680 free (qualified_name);
015dc7e1 21681 ret = false;
1cb7d8b1
AM
21682 break;
21683 }
2cf0635d 21684
978c4450 21685 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 21686 member_filedata->file_name = qualified_name;
2cf0635d 21687
1cb7d8b1 21688 if (! process_object (member_filedata))
015dc7e1 21689 ret = false;
2cf0635d 21690
1cb7d8b1
AM
21691 close_file (member_filedata);
21692 free (member_file_name);
1cb7d8b1 21693 }
2cf0635d 21694 else if (is_thin_archive)
1cb7d8b1
AM
21695 {
21696 Filedata thin_filedata;
eb02c04d 21697
1cb7d8b1 21698 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 21699
a043396b
NC
21700 /* PR 15140: Allow for corrupt thin archives. */
21701 if (nested_arch.file == NULL)
21702 {
21703 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 21704 qualified_name, name);
fd486f32
AM
21705 free (qualified_name);
21706 free (name);
015dc7e1 21707 ret = false;
a043396b
NC
21708 break;
21709 }
fd486f32 21710 free (name);
a043396b 21711
1cb7d8b1 21712 /* This is a proxy for a member of a nested archive. */
978c4450
AM
21713 filedata->archive_file_offset
21714 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 21715
1cb7d8b1
AM
21716 /* The nested archive file will have been opened and setup by
21717 get_archive_member_name. */
978c4450
AM
21718 if (fseek (nested_arch.file, filedata->archive_file_offset,
21719 SEEK_SET) != 0)
1cb7d8b1
AM
21720 {
21721 error (_("%s: failed to seek to archive member.\n"),
21722 nested_arch.file_name);
fd486f32 21723 free (qualified_name);
015dc7e1 21724 ret = false;
1cb7d8b1
AM
21725 break;
21726 }
2cf0635d 21727
dda8d76d
NC
21728 thin_filedata.handle = nested_arch.file;
21729 thin_filedata.file_name = qualified_name;
9abca702 21730
1cb7d8b1 21731 if (! process_object (& thin_filedata))
015dc7e1 21732 ret = false;
1cb7d8b1 21733 }
2cf0635d 21734 else
1cb7d8b1 21735 {
fd486f32 21736 free (name);
978c4450 21737 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 21738 filedata->file_name = qualified_name;
1cb7d8b1 21739 if (! process_object (filedata))
015dc7e1 21740 ret = false;
978c4450 21741 arch.next_arhdr_offset += filedata->archive_file_size;
4c836627 21742 /* Stop looping with "negative" archive_file_size. */
978c4450 21743 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 21744 arch.next_arhdr_offset = -1ul;
1cb7d8b1 21745 }
fb52b2f4 21746
2cf0635d 21747 free (qualified_name);
fb52b2f4
NC
21748 }
21749
4145f1d5 21750 out:
2cf0635d
NC
21751 if (nested_arch.file != NULL)
21752 fclose (nested_arch.file);
21753 release_archive (&nested_arch);
21754 release_archive (&arch);
fb52b2f4 21755
d989285c 21756 return ret;
fb52b2f4
NC
21757}
21758
015dc7e1 21759static bool
2cf0635d 21760process_file (char * file_name)
fb52b2f4 21761{
dda8d76d 21762 Filedata * filedata = NULL;
fb52b2f4
NC
21763 struct stat statbuf;
21764 char armag[SARMAG];
015dc7e1 21765 bool ret = true;
fb52b2f4
NC
21766
21767 if (stat (file_name, &statbuf) < 0)
21768 {
f24ddbdd
NC
21769 if (errno == ENOENT)
21770 error (_("'%s': No such file\n"), file_name);
21771 else
21772 error (_("Could not locate '%s'. System error message: %s\n"),
21773 file_name, strerror (errno));
015dc7e1 21774 return false;
f24ddbdd
NC
21775 }
21776
21777 if (! S_ISREG (statbuf.st_mode))
21778 {
21779 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 21780 return false;
fb52b2f4
NC
21781 }
21782
dda8d76d
NC
21783 filedata = calloc (1, sizeof * filedata);
21784 if (filedata == NULL)
21785 {
21786 error (_("Out of memory allocating file data structure\n"));
015dc7e1 21787 return false;
dda8d76d
NC
21788 }
21789
21790 filedata->file_name = file_name;
21791 filedata->handle = fopen (file_name, "rb");
21792 if (filedata->handle == NULL)
fb52b2f4 21793 {
f24ddbdd 21794 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 21795 free (filedata);
015dc7e1 21796 return false;
fb52b2f4
NC
21797 }
21798
dda8d76d 21799 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 21800 {
4145f1d5 21801 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
21802 fclose (filedata->handle);
21803 free (filedata);
015dc7e1 21804 return false;
fb52b2f4
NC
21805 }
21806
dda8d76d 21807 filedata->file_size = (bfd_size_type) statbuf.st_size;
015dc7e1 21808 filedata->is_separate = false;
f54498b4 21809
fb52b2f4 21810 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 21811 {
015dc7e1
AM
21812 if (! process_archive (filedata, false))
21813 ret = false;
32ec8896 21814 }
2cf0635d 21815 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 21816 {
015dc7e1
AM
21817 if ( ! process_archive (filedata, true))
21818 ret = false;
32ec8896 21819 }
fb52b2f4
NC
21820 else
21821 {
1b513401 21822 if (do_archive_index && !check_all)
4145f1d5
NC
21823 error (_("File %s is not an archive so its index cannot be displayed.\n"),
21824 file_name);
21825
dda8d76d 21826 rewind (filedata->handle);
978c4450 21827 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 21828
dda8d76d 21829 if (! process_object (filedata))
015dc7e1 21830 ret = false;
fb52b2f4
NC
21831 }
21832
dda8d76d 21833 fclose (filedata->handle);
8fb879cd
AM
21834 free (filedata->section_headers);
21835 free (filedata->program_headers);
21836 free (filedata->string_table);
6431e409 21837 free (filedata->dump.dump_sects);
dda8d76d 21838 free (filedata);
32ec8896 21839
fd486f32 21840 free (ba_cache.strtab);
1bd6175a 21841 ba_cache.strtab = NULL;
fd486f32 21842 free (ba_cache.symtab);
1bd6175a 21843 ba_cache.symtab = NULL;
fd486f32
AM
21844 ba_cache.filedata = NULL;
21845
fb52b2f4
NC
21846 return ret;
21847}
21848
252b5132
RH
21849#ifdef SUPPORT_DISASSEMBLY
21850/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 21851 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 21852 symbols. */
252b5132
RH
21853
21854void
2cf0635d 21855print_address (unsigned int addr, FILE * outfile)
252b5132
RH
21856{
21857 fprintf (outfile,"0x%8.8x", addr);
21858}
21859
e3c8793a 21860/* Needed by the i386 disassembler. */
dda8d76d 21861
252b5132
RH
21862void
21863db_task_printsym (unsigned int addr)
21864{
21865 print_address (addr, stderr);
21866}
21867#endif
21868
21869int
2cf0635d 21870main (int argc, char ** argv)
252b5132 21871{
ff78d6d6
L
21872 int err;
21873
87b9f255 21874#ifdef HAVE_LC_MESSAGES
252b5132 21875 setlocale (LC_MESSAGES, "");
3882b010 21876#endif
3882b010 21877 setlocale (LC_CTYPE, "");
252b5132
RH
21878 bindtextdomain (PACKAGE, LOCALEDIR);
21879 textdomain (PACKAGE);
21880
869b9d07
MM
21881 expandargv (&argc, &argv);
21882
dda8d76d 21883 parse_args (& cmdline, argc, argv);
59f14fc0 21884
18bd398b 21885 if (optind < (argc - 1))
1b513401
NC
21886 /* When displaying information for more than one file,
21887 prefix the information with the file name. */
015dc7e1 21888 show_name = true;
5656ba2c
L
21889 else if (optind >= argc)
21890 {
1b513401 21891 /* Ensure that the warning is always displayed. */
015dc7e1 21892 do_checks = true;
1b513401 21893
5656ba2c
L
21894 warn (_("Nothing to do.\n"));
21895 usage (stderr);
21896 }
18bd398b 21897
015dc7e1 21898 err = false;
252b5132 21899 while (optind < argc)
32ec8896 21900 if (! process_file (argv[optind++]))
015dc7e1 21901 err = true;
252b5132 21902
9db70fc3 21903 free (cmdline.dump_sects);
252b5132 21904
7d9813f1
NA
21905 free (dump_ctf_symtab_name);
21906 free (dump_ctf_strtab_name);
21907 free (dump_ctf_parent_name);
21908
32ec8896 21909 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 21910}
This page took 3.694309 seconds and 4 git commands to generate.