]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
250d07de 2 Copyright (C) 1998-2021 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056 46#include <zlib.h>
7bfd842d 47#include <wchar.h>
252b5132 48
a952a375 49#if __GNUC__ >= 2
19936277 50/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 51 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 52 Only do this if we believe that the compiler can support a 64 bit
a952a375 53 data type. For now we only rely on GCC being able to do this. */
19936277 54#define BFD64
a952a375
NC
55#endif
56
3db64b00
AM
57#include "bfd.h"
58#include "bucomm.h"
3284fe0c 59#include "elfcomm.h"
19e6b90e 60#include "dwarf.h"
7d9813f1 61#include "ctf-api.h"
79bc120c 62#include "demangle.h"
252b5132
RH
63
64#include "elf/common.h"
65#include "elf/external.h"
66#include "elf/internal.h"
252b5132 67
4b78141a
NC
68
69/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
70 we can obtain the H8 reloc numbers. We need these for the
71 get_reloc_size() function. We include h8.h again after defining
72 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
73
74#include "elf/h8.h"
75#undef _ELF_H8_H
76
77/* Undo the effects of #including reloc-macros.h. */
78
79#undef START_RELOC_NUMBERS
80#undef RELOC_NUMBER
81#undef FAKE_RELOC
82#undef EMPTY_RELOC
83#undef END_RELOC_NUMBERS
84#undef _RELOC_MACROS_H
85
252b5132
RH
86/* The following headers use the elf/reloc-macros.h file to
87 automatically generate relocation recognition functions
88 such as elf_mips_reloc_type() */
89
90#define RELOC_MACROS_GEN_FUNC
91
a06ea964 92#include "elf/aarch64.h"
252b5132 93#include "elf/alpha.h"
3b16e843 94#include "elf/arc.h"
252b5132 95#include "elf/arm.h"
3b16e843 96#include "elf/avr.h"
1d65ded4 97#include "elf/bfin.h"
60bca95a 98#include "elf/cr16.h"
3b16e843 99#include "elf/cris.h"
1c0d3aa6 100#include "elf/crx.h"
b8891f8d 101#include "elf/csky.h"
252b5132
RH
102#include "elf/d10v.h"
103#include "elf/d30v.h"
d172d4ba 104#include "elf/dlx.h"
aca4efc7 105#include "elf/bpf.h"
cfb8c092 106#include "elf/epiphany.h"
252b5132 107#include "elf/fr30.h"
5c70f934 108#include "elf/frv.h"
3f8107ab 109#include "elf/ft32.h"
3b16e843
NC
110#include "elf/h8.h"
111#include "elf/hppa.h"
112#include "elf/i386.h"
f954747f
AM
113#include "elf/i370.h"
114#include "elf/i860.h"
115#include "elf/i960.h"
3b16e843 116#include "elf/ia64.h"
1e4cf259 117#include "elf/ip2k.h"
84e94c90 118#include "elf/lm32.h"
1c0d3aa6 119#include "elf/iq2000.h"
49f58d10 120#include "elf/m32c.h"
3b16e843
NC
121#include "elf/m32r.h"
122#include "elf/m68k.h"
75751cd9 123#include "elf/m68hc11.h"
7b4ae824 124#include "elf/s12z.h"
252b5132 125#include "elf/mcore.h"
15ab5209 126#include "elf/mep.h"
a3c62988 127#include "elf/metag.h"
7ba29e2a 128#include "elf/microblaze.h"
3b16e843 129#include "elf/mips.h"
3c3bdf30 130#include "elf/mmix.h"
3b16e843
NC
131#include "elf/mn10200.h"
132#include "elf/mn10300.h"
5506d11a 133#include "elf/moxie.h"
4970f871 134#include "elf/mt.h"
2469cfa2 135#include "elf/msp430.h"
35c08157 136#include "elf/nds32.h"
fe944acf 137#include "elf/nfp.h"
13761a11 138#include "elf/nios2.h"
73589c9d 139#include "elf/or1k.h"
7d466069 140#include "elf/pj.h"
3b16e843 141#include "elf/ppc.h"
c833c019 142#include "elf/ppc64.h"
2b100bb5 143#include "elf/pru.h"
03336641 144#include "elf/riscv.h"
99c513f6 145#include "elf/rl78.h"
c7927a3c 146#include "elf/rx.h"
a85d7ed0 147#include "elf/s390.h"
1c0d3aa6 148#include "elf/score.h"
3b16e843
NC
149#include "elf/sh.h"
150#include "elf/sparc.h"
e9f53129 151#include "elf/spu.h"
40b36596 152#include "elf/tic6x.h"
aa137e4d
NC
153#include "elf/tilegx.h"
154#include "elf/tilepro.h"
3b16e843 155#include "elf/v850.h"
179d3252 156#include "elf/vax.h"
619ed720 157#include "elf/visium.h"
f96bd6c2 158#include "elf/wasm32.h"
3b16e843 159#include "elf/x86-64.h"
c29aca4a 160#include "elf/xc16x.h"
f6c1a2d5 161#include "elf/xgate.h"
93fbbb04 162#include "elf/xstormy16.h"
88da6820 163#include "elf/xtensa.h"
6655dba2 164#include "elf/z80.h"
252b5132 165
252b5132 166#include "getopt.h"
566b0d53 167#include "libiberty.h"
09c11c86 168#include "safe-ctype.h"
2cf0635d 169#include "filenames.h"
252b5132 170
15b42fb0
AM
171#ifndef offsetof
172#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
173#endif
174
6a40cf0c
NC
175typedef struct elf_section_list
176{
dda8d76d
NC
177 Elf_Internal_Shdr * hdr;
178 struct elf_section_list * next;
6a40cf0c
NC
179} elf_section_list;
180
dda8d76d
NC
181/* Flag bits indicating particular types of dump. */
182#define HEX_DUMP (1 << 0) /* The -x command line switch. */
183#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
184#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
185#define STRING_DUMP (1 << 3) /* The -p command line switch. */
186#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 187#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
188
189typedef unsigned char dump_type;
190
191/* A linked list of the section names for which dumps were requested. */
192struct dump_list_entry
193{
194 char * name;
195 dump_type type;
196 struct dump_list_entry * next;
197};
198
6431e409
AM
199/* A dynamic array of flags indicating for which sections a dump
200 has been requested via command line switches. */
1b513401
NC
201struct dump_data
202{
6431e409
AM
203 dump_type * dump_sects;
204 unsigned int num_dump_sects;
205};
206
207static struct dump_data cmdline;
208
209static struct dump_list_entry * dump_sects_byname;
210
2cf0635d 211char * program_name = "readelf";
dda8d76d 212
015dc7e1
AM
213static bool show_name = false;
214static bool do_dynamic = false;
215static bool do_syms = false;
216static bool do_dyn_syms = false;
217static bool do_lto_syms = false;
218static bool do_reloc = false;
219static bool do_sections = false;
220static bool do_section_groups = false;
221static bool do_section_details = false;
222static bool do_segments = false;
223static bool do_unwind = false;
224static bool do_using_dynamic = false;
225static bool do_header = false;
226static bool do_dump = false;
227static bool do_version = false;
228static bool do_histogram = false;
229static bool do_debugging = false;
230static bool do_ctf = false;
231static bool do_arch = false;
232static bool do_notes = false;
233static bool do_archive_index = false;
234static bool check_all = false;
235static bool is_32bit_elf = false;
236static bool decompress_dumps = false;
237static bool do_not_show_symbol_truncation = false;
238static bool do_demangle = false; /* Pretty print C++ symbol names. */
239static bool process_links = false;
79bc120c 240static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 241static int sym_base = 0;
252b5132 242
7d9813f1
NA
243static char *dump_ctf_parent_name;
244static char *dump_ctf_symtab_name;
245static char *dump_ctf_strtab_name;
246
e4b17d5c
L
247struct group_list
248{
dda8d76d
NC
249 struct group_list * next;
250 unsigned int section_index;
e4b17d5c
L
251};
252
253struct group
254{
dda8d76d
NC
255 struct group_list * root;
256 unsigned int group_index;
e4b17d5c
L
257};
258
978c4450
AM
259typedef struct filedata
260{
261 const char * file_name;
015dc7e1 262 bool is_separate;
978c4450
AM
263 FILE * handle;
264 bfd_size_type file_size;
265 Elf_Internal_Ehdr file_header;
266 Elf_Internal_Shdr * section_headers;
267 Elf_Internal_Phdr * program_headers;
268 char * string_table;
269 unsigned long string_table_length;
270 unsigned long archive_file_offset;
271 unsigned long archive_file_size;
272 unsigned long dynamic_addr;
273 bfd_size_type dynamic_size;
274 size_t dynamic_nent;
275 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 276 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450
AM
277 char * dynamic_strings;
278 unsigned long dynamic_strings_length;
8ac10c5b 279 Elf_Internal_Shdr * dynamic_symtab_section;
978c4450
AM
280 unsigned long num_dynamic_syms;
281 Elf_Internal_Sym * dynamic_symbols;
282 bfd_vma version_info[16];
283 unsigned int dynamic_syminfo_nent;
284 Elf_Internal_Syminfo * dynamic_syminfo;
285 unsigned long dynamic_syminfo_offset;
286 bfd_size_type nbuckets;
287 bfd_size_type nchains;
288 bfd_vma * buckets;
289 bfd_vma * chains;
290 bfd_size_type ngnubuckets;
291 bfd_size_type ngnuchains;
292 bfd_vma * gnubuckets;
293 bfd_vma * gnuchains;
294 bfd_vma * mipsxlat;
295 bfd_vma gnusymidx;
13acb58d 296 char * program_interpreter;
978c4450
AM
297 bfd_vma dynamic_info[DT_ENCODING];
298 bfd_vma dynamic_info_DT_GNU_HASH;
299 bfd_vma dynamic_info_DT_MIPS_XHASH;
300 elf_section_list * symtab_shndx_list;
301 size_t group_count;
302 struct group * section_groups;
303 struct group ** section_headers_groups;
304 /* A dynamic array of flags indicating for which sections a dump of
305 some kind has been requested. It is reset on a per-object file
306 basis and then initialised from the cmdline_dump_sects array,
307 the results of interpreting the -w switch, and the
308 dump_sects_byname list. */
309 struct dump_data dump;
310} Filedata;
aef1f6d0 311
c256ffe7 312/* How to print a vma value. */
843dd992
NC
313typedef enum print_mode
314{
315 HEX,
047c3dbf 316 HEX_5,
843dd992
NC
317 DEC,
318 DEC_5,
319 UNSIGNED,
047c3dbf 320 UNSIGNED_5,
843dd992 321 PREFIX_HEX,
047c3dbf 322 PREFIX_HEX_5,
843dd992 323 FULL_HEX,
047c3dbf
NL
324 LONG_HEX,
325 OCTAL,
326 OCTAL_5
843dd992
NC
327}
328print_mode;
329
bb4d2ac2
L
330/* Versioned symbol info. */
331enum versioned_symbol_info
332{
333 symbol_undefined,
334 symbol_hidden,
335 symbol_public
336};
337
32ec8896 338static const char * get_symbol_version_string
015dc7e1 339 (Filedata *, bool, const char *, unsigned long, unsigned,
32ec8896 340 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 341
9c19a809
NC
342#define UNKNOWN -1
343
b9e920ec
AM
344#define SECTION_NAME(X) \
345 (filedata->string_table + (X)->sh_name)
346
347#define SECTION_NAME_VALID(X) \
348 ((X) != NULL \
349 && filedata->string_table != NULL \
350 && (X)->sh_name < filedata->string_table_length)
351
352#define SECTION_NAME_PRINT(X) \
353 ((X) == NULL ? _("<none>") \
354 : filedata->string_table == NULL ? _("<no-strings>") \
355 : (X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
356 : filedata->string_table + (X)->sh_name)
252b5132 357
ee42cf8c 358#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 359
ba5cdace
NC
360#define GET_ELF_SYMBOLS(file, section, sym_count) \
361 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
362 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 363
10ca4b04
L
364#define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
365 (strtab != NULL && offset < strtab_size)
978c4450
AM
366#define VALID_DYNAMIC_NAME(filedata, offset) \
367 VALID_SYMBOL_NAME (filedata->dynamic_strings, \
368 filedata->dynamic_strings_length, offset)
d79b3d50
NC
369/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
370 already been called and verified that the string exists. */
978c4450
AM
371#define GET_DYNAMIC_NAME(filedata, offset) \
372 (filedata->dynamic_strings + offset)
18bd398b 373
61865e30
NC
374#define REMOVE_ARCH_BITS(ADDR) \
375 do \
376 { \
dda8d76d 377 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
378 (ADDR) &= ~1; \
379 } \
380 while (0)
f16a9783
MS
381
382/* Get the correct GNU hash section name. */
978c4450
AM
383#define GNU_HASH_SECTION_NAME(filedata) \
384 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 385\f
66cfc0fd
AM
386/* Print a BFD_VMA to an internal buffer, for use in error messages.
387 BFD_FMA_FMT can't be used in translated strings. */
388
389static const char *
390bfd_vmatoa (char *fmtch, bfd_vma value)
391{
392 /* bfd_vmatoa is used more then once in a printf call for output.
393 Cycle through an array of buffers. */
394 static int buf_pos = 0;
395 static struct bfd_vmatoa_buf
396 {
397 char place[64];
398 } buf[4];
399 char *ret;
400 char fmt[32];
401
402 ret = buf[buf_pos++].place;
403 buf_pos %= ARRAY_SIZE (buf);
404
405 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
406 snprintf (ret, sizeof (buf[0].place), fmt, value);
407 return ret;
408}
409
dda8d76d
NC
410/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
411 OFFSET + the offset of the current archive member, if we are examining an
412 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
413 allocate a buffer using malloc and fill that. In either case return the
414 pointer to the start of the retrieved data or NULL if something went wrong.
415 If something does go wrong and REASON is not NULL then emit an error
416 message using REASON as part of the context. */
59245841 417
c256ffe7 418static void *
dda8d76d
NC
419get_data (void * var,
420 Filedata * filedata,
421 unsigned long offset,
422 bfd_size_type size,
423 bfd_size_type nmemb,
424 const char * reason)
a6e9f9df 425{
2cf0635d 426 void * mvar;
57028622 427 bfd_size_type amt = size * nmemb;
a6e9f9df 428
c256ffe7 429 if (size == 0 || nmemb == 0)
a6e9f9df
AM
430 return NULL;
431
57028622
NC
432 /* If the size_t type is smaller than the bfd_size_type, eg because
433 you are building a 32-bit tool on a 64-bit host, then make sure
434 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
435 if ((size_t) size != size
436 || (size_t) nmemb != nmemb
437 || (size_t) amt != amt)
57028622
NC
438 {
439 if (reason)
66cfc0fd
AM
440 error (_("Size truncation prevents reading %s"
441 " elements of size %s for %s\n"),
442 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
443 return NULL;
444 }
445
446 /* Check for size overflow. */
7c1c1904 447 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
448 {
449 if (reason)
66cfc0fd
AM
450 error (_("Size overflow prevents reading %s"
451 " elements of size %s for %s\n"),
452 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
453 return NULL;
454 }
455
c22b42ce 456 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 457 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
458 if (filedata->archive_file_offset > filedata->file_size
459 || offset > filedata->file_size - filedata->archive_file_offset
460 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 461 {
049b0c3a 462 if (reason)
66cfc0fd
AM
463 error (_("Reading %s bytes extends past end of file for %s\n"),
464 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
465 return NULL;
466 }
467
978c4450
AM
468 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
469 SEEK_SET))
071436c6
NC
470 {
471 if (reason)
c9c1d674 472 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 473 filedata->archive_file_offset + offset, reason);
071436c6
NC
474 return NULL;
475 }
476
a6e9f9df
AM
477 mvar = var;
478 if (mvar == NULL)
479 {
7c1c1904
AM
480 /* + 1 so that we can '\0' terminate invalid string table sections. */
481 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
482
483 if (mvar == NULL)
484 {
049b0c3a 485 if (reason)
66cfc0fd
AM
486 error (_("Out of memory allocating %s bytes for %s\n"),
487 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
488 return NULL;
489 }
c256ffe7 490
c9c1d674 491 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
492 }
493
dda8d76d 494 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 495 {
049b0c3a 496 if (reason)
66cfc0fd
AM
497 error (_("Unable to read in %s bytes of %s\n"),
498 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
499 if (mvar != var)
500 free (mvar);
501 return NULL;
502 }
503
504 return mvar;
505}
506
32ec8896
NC
507/* Print a VMA value in the MODE specified.
508 Returns the number of characters displayed. */
cb8f3167 509
32ec8896 510static unsigned int
14a91970 511print_vma (bfd_vma vma, print_mode mode)
66543521 512{
32ec8896 513 unsigned int nc = 0;
66543521 514
14a91970 515 switch (mode)
66543521 516 {
14a91970
AM
517 case FULL_HEX:
518 nc = printf ("0x");
1a0670f3 519 /* Fall through. */
14a91970 520 case LONG_HEX:
f7a99963 521#ifdef BFD64
14a91970 522 if (is_32bit_elf)
437c2fb7 523 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 524#endif
14a91970
AM
525 printf_vma (vma);
526 return nc + 16;
b19aac67 527
14a91970
AM
528 case DEC_5:
529 if (vma <= 99999)
530 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 531 /* Fall through. */
14a91970
AM
532 case PREFIX_HEX:
533 nc = printf ("0x");
1a0670f3 534 /* Fall through. */
14a91970
AM
535 case HEX:
536 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 537
047c3dbf
NL
538 case PREFIX_HEX_5:
539 nc = printf ("0x");
540 /* Fall through. */
541 case HEX_5:
542 return nc + printf ("%05" BFD_VMA_FMT "x", vma);
543
14a91970
AM
544 case DEC:
545 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 546
14a91970
AM
547 case UNSIGNED:
548 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896 549
047c3dbf
NL
550 case UNSIGNED_5:
551 return printf ("%5" BFD_VMA_FMT "u", vma);
552
553 case OCTAL:
554 return printf ("%" BFD_VMA_FMT "o", vma);
555
556 case OCTAL_5:
557 return printf ("%5" BFD_VMA_FMT "o", vma);
558
32ec8896
NC
559 default:
560 /* FIXME: Report unrecognised mode ? */
561 return 0;
f7a99963 562 }
f7a99963
NC
563}
564
047c3dbf 565
7bfd842d 566/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 567 multibye characters (assuming the host environment supports them).
31104126 568
7bfd842d
NC
569 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
570
0942c7ab
NC
571 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
572 abs(WIDTH) - 5 characters followed by "[...]".
573
7bfd842d
NC
574 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
575 padding as necessary.
171191ba
NC
576
577 Returns the number of emitted characters. */
578
579static unsigned int
0942c7ab 580print_symbol (signed int width, const char * symbol)
31104126 581{
015dc7e1
AM
582 bool extra_padding = false;
583 bool do_dots = false;
32ec8896 584 signed int num_printed = 0;
3bfcb652 585#ifdef HAVE_MBSTATE_T
7bfd842d 586 mbstate_t state;
3bfcb652 587#endif
32ec8896 588 unsigned int width_remaining;
79bc120c 589 const void * alloced_symbol = NULL;
961c521f 590
7bfd842d 591 if (width < 0)
961c521f 592 {
88305e1b 593 /* Keep the width positive. This helps the code below. */
961c521f 594 width = - width;
015dc7e1 595 extra_padding = true;
0b4362b0 596 }
56d8f8a9
NC
597 else if (width == 0)
598 return 0;
961c521f 599
7bfd842d
NC
600 if (do_wide)
601 /* Set the remaining width to a very large value.
602 This simplifies the code below. */
603 width_remaining = INT_MAX;
604 else
0942c7ab
NC
605 {
606 width_remaining = width;
607 if (! do_not_show_symbol_truncation
608 && (int) strlen (symbol) > width)
609 {
610 width_remaining -= 5;
611 if ((int) width_remaining < 0)
612 width_remaining = 0;
015dc7e1 613 do_dots = true;
0942c7ab
NC
614 }
615 }
cb8f3167 616
3bfcb652 617#ifdef HAVE_MBSTATE_T
7bfd842d
NC
618 /* Initialise the multibyte conversion state. */
619 memset (& state, 0, sizeof (state));
3bfcb652 620#endif
961c521f 621
79bc120c
NC
622 if (do_demangle && *symbol)
623 {
624 const char * res = cplus_demangle (symbol, demangle_flags);
625
626 if (res != NULL)
627 alloced_symbol = symbol = res;
628 }
629
7bfd842d
NC
630 while (width_remaining)
631 {
632 size_t n;
7bfd842d 633 const char c = *symbol++;
961c521f 634
7bfd842d 635 if (c == 0)
961c521f
NC
636 break;
637
7bfd842d
NC
638 /* Do not print control characters directly as they can affect terminal
639 settings. Such characters usually appear in the names generated
640 by the assembler for local labels. */
641 if (ISCNTRL (c))
961c521f 642 {
7bfd842d 643 if (width_remaining < 2)
961c521f
NC
644 break;
645
7bfd842d
NC
646 printf ("^%c", c + 0x40);
647 width_remaining -= 2;
171191ba 648 num_printed += 2;
961c521f 649 }
7bfd842d
NC
650 else if (ISPRINT (c))
651 {
652 putchar (c);
653 width_remaining --;
654 num_printed ++;
655 }
961c521f
NC
656 else
657 {
3bfcb652
NC
658#ifdef HAVE_MBSTATE_T
659 wchar_t w;
660#endif
7bfd842d
NC
661 /* Let printf do the hard work of displaying multibyte characters. */
662 printf ("%.1s", symbol - 1);
663 width_remaining --;
664 num_printed ++;
665
3bfcb652 666#ifdef HAVE_MBSTATE_T
7bfd842d
NC
667 /* Try to find out how many bytes made up the character that was
668 just printed. Advance the symbol pointer past the bytes that
669 were displayed. */
670 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
671#else
672 n = 1;
673#endif
7bfd842d
NC
674 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
675 symbol += (n - 1);
961c521f 676 }
961c521f 677 }
171191ba 678
0942c7ab
NC
679 if (do_dots)
680 num_printed += printf ("[...]");
681
7bfd842d 682 if (extra_padding && num_printed < width)
171191ba
NC
683 {
684 /* Fill in the remaining spaces. */
7bfd842d
NC
685 printf ("%-*s", width - num_printed, " ");
686 num_printed = width;
171191ba
NC
687 }
688
79bc120c 689 free ((void *) alloced_symbol);
171191ba 690 return num_printed;
31104126
NC
691}
692
1449284b 693/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
694 the given section's name. Like print_symbol, except that it does not try
695 to print multibyte characters, it just interprets them as hex values. */
696
697static const char *
dda8d76d 698printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 699{
ca0e11aa 700#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 701 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
b9e920ec 702 const char * name = SECTION_NAME_PRINT (sec);
74e1a04b
NC
703 char * buf = sec_name_buf;
704 char c;
705 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
706
707 while ((c = * name ++) != 0)
708 {
709 if (ISCNTRL (c))
710 {
711 if (remaining < 2)
712 break;
948f632f 713
74e1a04b
NC
714 * buf ++ = '^';
715 * buf ++ = c + 0x40;
716 remaining -= 2;
717 }
718 else if (ISPRINT (c))
719 {
720 * buf ++ = c;
721 remaining -= 1;
722 }
723 else
724 {
725 static char hex[17] = "0123456789ABCDEF";
726
727 if (remaining < 4)
728 break;
729 * buf ++ = '<';
730 * buf ++ = hex[(c & 0xf0) >> 4];
731 * buf ++ = hex[c & 0x0f];
732 * buf ++ = '>';
733 remaining -= 4;
734 }
735
736 if (remaining == 0)
737 break;
738 }
739
740 * buf = 0;
741 return sec_name_buf;
742}
743
744static const char *
dda8d76d 745printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 746{
dda8d76d 747 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
748 return _("<corrupt>");
749
dda8d76d 750 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
751}
752
89fac5e3
RS
753/* Return a pointer to section NAME, or NULL if no such section exists. */
754
755static Elf_Internal_Shdr *
dda8d76d 756find_section (Filedata * filedata, const char * name)
89fac5e3
RS
757{
758 unsigned int i;
759
68807c3c
NC
760 if (filedata->section_headers == NULL)
761 return NULL;
dda8d76d
NC
762
763 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
764 if (SECTION_NAME_VALID (filedata->section_headers + i)
765 && streq (SECTION_NAME (filedata->section_headers + i), name))
dda8d76d 766 return filedata->section_headers + i;
89fac5e3
RS
767
768 return NULL;
769}
770
0b6ae522
DJ
771/* Return a pointer to a section containing ADDR, or NULL if no such
772 section exists. */
773
774static Elf_Internal_Shdr *
dda8d76d 775find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
776{
777 unsigned int i;
778
68807c3c
NC
779 if (filedata->section_headers == NULL)
780 return NULL;
781
dda8d76d 782 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 783 {
dda8d76d
NC
784 Elf_Internal_Shdr *sec = filedata->section_headers + i;
785
0b6ae522
DJ
786 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
787 return sec;
788 }
789
790 return NULL;
791}
792
071436c6 793static Elf_Internal_Shdr *
dda8d76d 794find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
795{
796 unsigned int i;
797
68807c3c
NC
798 if (filedata->section_headers == NULL)
799 return NULL;
800
dda8d76d 801 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 802 {
dda8d76d
NC
803 Elf_Internal_Shdr *sec = filedata->section_headers + i;
804
071436c6
NC
805 if (sec->sh_type == type)
806 return sec;
807 }
808
809 return NULL;
810}
811
657d0d47
CC
812/* Return a pointer to section NAME, or NULL if no such section exists,
813 restricted to the list of sections given in SET. */
814
815static Elf_Internal_Shdr *
dda8d76d 816find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
817{
818 unsigned int i;
819
68807c3c
NC
820 if (filedata->section_headers == NULL)
821 return NULL;
822
657d0d47
CC
823 if (set != NULL)
824 {
825 while ((i = *set++) > 0)
b814a36d
NC
826 {
827 /* See PR 21156 for a reproducer. */
dda8d76d 828 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
829 continue; /* FIXME: Should we issue an error message ? */
830
b9e920ec
AM
831 if (SECTION_NAME_VALID (filedata->section_headers + i)
832 && streq (SECTION_NAME (filedata->section_headers + i), name))
dda8d76d 833 return filedata->section_headers + i;
b814a36d 834 }
657d0d47
CC
835 }
836
dda8d76d 837 return find_section (filedata, name);
657d0d47
CC
838}
839
32ec8896 840/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
841 This OS has so many departures from the ELF standard that we test it at
842 many places. */
843
015dc7e1 844static inline bool
dda8d76d 845is_ia64_vms (Filedata * filedata)
28f997cf 846{
dda8d76d
NC
847 return filedata->file_header.e_machine == EM_IA_64
848 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
849}
850
bcedfee6 851/* Guess the relocation size commonly used by the specific machines. */
252b5132 852
015dc7e1 853static bool
2dc4cec1 854guess_is_rela (unsigned int e_machine)
252b5132 855{
9c19a809 856 switch (e_machine)
252b5132
RH
857 {
858 /* Targets that use REL relocations. */
252b5132 859 case EM_386:
22abe556 860 case EM_IAMCU:
f954747f 861 case EM_960:
e9f53129 862 case EM_ARM:
2b0337b0 863 case EM_D10V:
252b5132 864 case EM_CYGNUS_D10V:
e9f53129 865 case EM_DLX:
252b5132 866 case EM_MIPS:
4fe85591 867 case EM_MIPS_RS3_LE:
e9f53129 868 case EM_CYGNUS_M32R:
1c0d3aa6 869 case EM_SCORE:
f6c1a2d5 870 case EM_XGATE:
fe944acf 871 case EM_NFP:
aca4efc7 872 case EM_BPF:
015dc7e1 873 return false;
103f02d3 874
252b5132
RH
875 /* Targets that use RELA relocations. */
876 case EM_68K:
f954747f 877 case EM_860:
a06ea964 878 case EM_AARCH64:
cfb8c092 879 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
880 case EM_ALPHA:
881 case EM_ALTERA_NIOS2:
886a2506
NC
882 case EM_ARC:
883 case EM_ARC_COMPACT:
884 case EM_ARC_COMPACT2:
e9f53129
AM
885 case EM_AVR:
886 case EM_AVR_OLD:
887 case EM_BLACKFIN:
60bca95a 888 case EM_CR16:
e9f53129
AM
889 case EM_CRIS:
890 case EM_CRX:
b8891f8d 891 case EM_CSKY:
2b0337b0 892 case EM_D30V:
252b5132 893 case EM_CYGNUS_D30V:
2b0337b0 894 case EM_FR30:
3f8107ab 895 case EM_FT32:
252b5132 896 case EM_CYGNUS_FR30:
5c70f934 897 case EM_CYGNUS_FRV:
e9f53129
AM
898 case EM_H8S:
899 case EM_H8_300:
900 case EM_H8_300H:
800eeca4 901 case EM_IA_64:
1e4cf259
NC
902 case EM_IP2K:
903 case EM_IP2K_OLD:
3b36097d 904 case EM_IQ2000:
84e94c90 905 case EM_LATTICEMICO32:
ff7eeb89 906 case EM_M32C_OLD:
49f58d10 907 case EM_M32C:
e9f53129
AM
908 case EM_M32R:
909 case EM_MCORE:
15ab5209 910 case EM_CYGNUS_MEP:
a3c62988 911 case EM_METAG:
e9f53129
AM
912 case EM_MMIX:
913 case EM_MN10200:
914 case EM_CYGNUS_MN10200:
915 case EM_MN10300:
916 case EM_CYGNUS_MN10300:
5506d11a 917 case EM_MOXIE:
e9f53129
AM
918 case EM_MSP430:
919 case EM_MSP430_OLD:
d031aafb 920 case EM_MT:
35c08157 921 case EM_NDS32:
64fd6348 922 case EM_NIOS32:
73589c9d 923 case EM_OR1K:
e9f53129
AM
924 case EM_PPC64:
925 case EM_PPC:
2b100bb5 926 case EM_TI_PRU:
e23eba97 927 case EM_RISCV:
99c513f6 928 case EM_RL78:
c7927a3c 929 case EM_RX:
e9f53129
AM
930 case EM_S390:
931 case EM_S390_OLD:
932 case EM_SH:
933 case EM_SPARC:
934 case EM_SPARC32PLUS:
935 case EM_SPARCV9:
936 case EM_SPU:
40b36596 937 case EM_TI_C6000:
aa137e4d
NC
938 case EM_TILEGX:
939 case EM_TILEPRO:
708e2187 940 case EM_V800:
e9f53129
AM
941 case EM_V850:
942 case EM_CYGNUS_V850:
943 case EM_VAX:
619ed720 944 case EM_VISIUM:
e9f53129 945 case EM_X86_64:
8a9036a4 946 case EM_L1OM:
7a9068fe 947 case EM_K1OM:
e9f53129
AM
948 case EM_XSTORMY16:
949 case EM_XTENSA:
950 case EM_XTENSA_OLD:
7ba29e2a
NC
951 case EM_MICROBLAZE:
952 case EM_MICROBLAZE_OLD:
f96bd6c2 953 case EM_WEBASSEMBLY:
015dc7e1 954 return true;
103f02d3 955
e9f53129
AM
956 case EM_68HC05:
957 case EM_68HC08:
958 case EM_68HC11:
959 case EM_68HC16:
960 case EM_FX66:
961 case EM_ME16:
d1133906 962 case EM_MMA:
d1133906
NC
963 case EM_NCPU:
964 case EM_NDR1:
e9f53129 965 case EM_PCP:
d1133906 966 case EM_ST100:
e9f53129 967 case EM_ST19:
d1133906 968 case EM_ST7:
e9f53129
AM
969 case EM_ST9PLUS:
970 case EM_STARCORE:
d1133906 971 case EM_SVX:
e9f53129 972 case EM_TINYJ:
9c19a809
NC
973 default:
974 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 975 return false;
9c19a809
NC
976 }
977}
252b5132 978
dda8d76d 979/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
980 Returns TRUE upon success, FALSE otherwise. If successful then a
981 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
982 and the number of relocs loaded is placed in *NRELASP. It is the caller's
983 responsibility to free the allocated buffer. */
984
015dc7e1 985static bool
dda8d76d
NC
986slurp_rela_relocs (Filedata * filedata,
987 unsigned long rel_offset,
988 unsigned long rel_size,
989 Elf_Internal_Rela ** relasp,
990 unsigned long * nrelasp)
9c19a809 991{
2cf0635d 992 Elf_Internal_Rela * relas;
8b73c356 993 size_t nrelas;
4d6ed7c8 994 unsigned int i;
252b5132 995
4d6ed7c8
NC
996 if (is_32bit_elf)
997 {
2cf0635d 998 Elf32_External_Rela * erelas;
103f02d3 999
dda8d76d 1000 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1001 rel_size, _("32-bit relocation data"));
a6e9f9df 1002 if (!erelas)
015dc7e1 1003 return false;
252b5132 1004
4d6ed7c8 1005 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1006
3f5e193b
NC
1007 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1008 sizeof (Elf_Internal_Rela));
103f02d3 1009
4d6ed7c8
NC
1010 if (relas == NULL)
1011 {
c256ffe7 1012 free (erelas);
591a748a 1013 error (_("out of memory parsing relocs\n"));
015dc7e1 1014 return false;
4d6ed7c8 1015 }
103f02d3 1016
4d6ed7c8
NC
1017 for (i = 0; i < nrelas; i++)
1018 {
1019 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1020 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1021 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1022 }
103f02d3 1023
4d6ed7c8
NC
1024 free (erelas);
1025 }
1026 else
1027 {
2cf0635d 1028 Elf64_External_Rela * erelas;
103f02d3 1029
dda8d76d 1030 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1031 rel_size, _("64-bit relocation data"));
a6e9f9df 1032 if (!erelas)
015dc7e1 1033 return false;
4d6ed7c8
NC
1034
1035 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1036
3f5e193b
NC
1037 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1038 sizeof (Elf_Internal_Rela));
103f02d3 1039
4d6ed7c8
NC
1040 if (relas == NULL)
1041 {
c256ffe7 1042 free (erelas);
591a748a 1043 error (_("out of memory parsing relocs\n"));
015dc7e1 1044 return false;
9c19a809 1045 }
4d6ed7c8
NC
1046
1047 for (i = 0; i < nrelas; i++)
9c19a809 1048 {
66543521
AM
1049 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1050 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1051 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1052
1053 /* The #ifdef BFD64 below is to prevent a compile time
1054 warning. We know that if we do not have a 64 bit data
1055 type that we will never execute this code anyway. */
1056#ifdef BFD64
dda8d76d
NC
1057 if (filedata->file_header.e_machine == EM_MIPS
1058 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1059 {
1060 /* In little-endian objects, r_info isn't really a
1061 64-bit little-endian value: it has a 32-bit
1062 little-endian symbol index followed by four
1063 individual byte fields. Reorder INFO
1064 accordingly. */
91d6fa6a
NC
1065 bfd_vma inf = relas[i].r_info;
1066 inf = (((inf & 0xffffffff) << 32)
1067 | ((inf >> 56) & 0xff)
1068 | ((inf >> 40) & 0xff00)
1069 | ((inf >> 24) & 0xff0000)
1070 | ((inf >> 8) & 0xff000000));
1071 relas[i].r_info = inf;
861fb55a
DJ
1072 }
1073#endif /* BFD64 */
4d6ed7c8 1074 }
103f02d3 1075
4d6ed7c8
NC
1076 free (erelas);
1077 }
32ec8896 1078
4d6ed7c8
NC
1079 *relasp = relas;
1080 *nrelasp = nrelas;
015dc7e1 1081 return true;
4d6ed7c8 1082}
103f02d3 1083
dda8d76d 1084/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1085 Returns TRUE upon success, FALSE otherwise. If successful then a
1086 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1087 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1088 responsibility to free the allocated buffer. */
1089
015dc7e1 1090static bool
dda8d76d
NC
1091slurp_rel_relocs (Filedata * filedata,
1092 unsigned long rel_offset,
1093 unsigned long rel_size,
1094 Elf_Internal_Rela ** relsp,
1095 unsigned long * nrelsp)
4d6ed7c8 1096{
2cf0635d 1097 Elf_Internal_Rela * rels;
8b73c356 1098 size_t nrels;
4d6ed7c8 1099 unsigned int i;
103f02d3 1100
4d6ed7c8
NC
1101 if (is_32bit_elf)
1102 {
2cf0635d 1103 Elf32_External_Rel * erels;
103f02d3 1104
dda8d76d 1105 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1106 rel_size, _("32-bit relocation data"));
a6e9f9df 1107 if (!erels)
015dc7e1 1108 return false;
103f02d3 1109
4d6ed7c8 1110 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1111
3f5e193b 1112 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1113
4d6ed7c8
NC
1114 if (rels == NULL)
1115 {
c256ffe7 1116 free (erels);
591a748a 1117 error (_("out of memory parsing relocs\n"));
015dc7e1 1118 return false;
4d6ed7c8
NC
1119 }
1120
1121 for (i = 0; i < nrels; i++)
1122 {
1123 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1124 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1125 rels[i].r_addend = 0;
9ea033b2 1126 }
4d6ed7c8
NC
1127
1128 free (erels);
9c19a809
NC
1129 }
1130 else
1131 {
2cf0635d 1132 Elf64_External_Rel * erels;
9ea033b2 1133
dda8d76d 1134 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1135 rel_size, _("64-bit relocation data"));
a6e9f9df 1136 if (!erels)
015dc7e1 1137 return false;
103f02d3 1138
4d6ed7c8 1139 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1140
3f5e193b 1141 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1142
4d6ed7c8 1143 if (rels == NULL)
9c19a809 1144 {
c256ffe7 1145 free (erels);
591a748a 1146 error (_("out of memory parsing relocs\n"));
015dc7e1 1147 return false;
4d6ed7c8 1148 }
103f02d3 1149
4d6ed7c8
NC
1150 for (i = 0; i < nrels; i++)
1151 {
66543521
AM
1152 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1153 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1154 rels[i].r_addend = 0;
861fb55a
DJ
1155
1156 /* The #ifdef BFD64 below is to prevent a compile time
1157 warning. We know that if we do not have a 64 bit data
1158 type that we will never execute this code anyway. */
1159#ifdef BFD64
dda8d76d
NC
1160 if (filedata->file_header.e_machine == EM_MIPS
1161 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1162 {
1163 /* In little-endian objects, r_info isn't really a
1164 64-bit little-endian value: it has a 32-bit
1165 little-endian symbol index followed by four
1166 individual byte fields. Reorder INFO
1167 accordingly. */
91d6fa6a
NC
1168 bfd_vma inf = rels[i].r_info;
1169 inf = (((inf & 0xffffffff) << 32)
1170 | ((inf >> 56) & 0xff)
1171 | ((inf >> 40) & 0xff00)
1172 | ((inf >> 24) & 0xff0000)
1173 | ((inf >> 8) & 0xff000000));
1174 rels[i].r_info = inf;
861fb55a
DJ
1175 }
1176#endif /* BFD64 */
4d6ed7c8 1177 }
103f02d3 1178
4d6ed7c8
NC
1179 free (erels);
1180 }
32ec8896 1181
4d6ed7c8
NC
1182 *relsp = rels;
1183 *nrelsp = nrels;
015dc7e1 1184 return true;
4d6ed7c8 1185}
103f02d3 1186
aca88567
NC
1187/* Returns the reloc type extracted from the reloc info field. */
1188
1189static unsigned int
dda8d76d 1190get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1191{
1192 if (is_32bit_elf)
1193 return ELF32_R_TYPE (reloc_info);
1194
dda8d76d 1195 switch (filedata->file_header.e_machine)
aca88567
NC
1196 {
1197 case EM_MIPS:
1198 /* Note: We assume that reloc_info has already been adjusted for us. */
1199 return ELF64_MIPS_R_TYPE (reloc_info);
1200
1201 case EM_SPARCV9:
1202 return ELF64_R_TYPE_ID (reloc_info);
1203
1204 default:
1205 return ELF64_R_TYPE (reloc_info);
1206 }
1207}
1208
1209/* Return the symbol index extracted from the reloc info field. */
1210
1211static bfd_vma
1212get_reloc_symindex (bfd_vma reloc_info)
1213{
1214 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1215}
1216
015dc7e1 1217static inline bool
dda8d76d 1218uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1219{
1220 return
dda8d76d 1221 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1222 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1223 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1224 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1225 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1226}
1227
d3ba0551
AM
1228/* Display the contents of the relocation data found at the specified
1229 offset. */
ee42cf8c 1230
015dc7e1 1231static bool
dda8d76d
NC
1232dump_relocations (Filedata * filedata,
1233 unsigned long rel_offset,
1234 unsigned long rel_size,
1235 Elf_Internal_Sym * symtab,
1236 unsigned long nsyms,
1237 char * strtab,
1238 unsigned long strtablen,
1239 int is_rela,
015dc7e1 1240 bool is_dynsym)
4d6ed7c8 1241{
32ec8896 1242 unsigned long i;
2cf0635d 1243 Elf_Internal_Rela * rels;
015dc7e1 1244 bool res = true;
103f02d3 1245
4d6ed7c8 1246 if (is_rela == UNKNOWN)
dda8d76d 1247 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1248
4d6ed7c8
NC
1249 if (is_rela)
1250 {
dda8d76d 1251 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1252 return false;
4d6ed7c8
NC
1253 }
1254 else
1255 {
dda8d76d 1256 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1257 return false;
252b5132
RH
1258 }
1259
410f7a12
L
1260 if (is_32bit_elf)
1261 {
1262 if (is_rela)
2c71103e
NC
1263 {
1264 if (do_wide)
1265 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1266 else
1267 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1268 }
410f7a12 1269 else
2c71103e
NC
1270 {
1271 if (do_wide)
1272 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1273 else
1274 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1275 }
410f7a12 1276 }
252b5132 1277 else
410f7a12
L
1278 {
1279 if (is_rela)
2c71103e
NC
1280 {
1281 if (do_wide)
8beeaeb7 1282 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1283 else
1284 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1285 }
410f7a12 1286 else
2c71103e
NC
1287 {
1288 if (do_wide)
8beeaeb7 1289 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1290 else
1291 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1292 }
410f7a12 1293 }
252b5132
RH
1294
1295 for (i = 0; i < rel_size; i++)
1296 {
2cf0635d 1297 const char * rtype;
b34976b6 1298 bfd_vma offset;
91d6fa6a 1299 bfd_vma inf;
b34976b6
AM
1300 bfd_vma symtab_index;
1301 bfd_vma type;
103f02d3 1302
b34976b6 1303 offset = rels[i].r_offset;
91d6fa6a 1304 inf = rels[i].r_info;
103f02d3 1305
dda8d76d 1306 type = get_reloc_type (filedata, inf);
91d6fa6a 1307 symtab_index = get_reloc_symindex (inf);
252b5132 1308
410f7a12
L
1309 if (is_32bit_elf)
1310 {
39dbeff8
AM
1311 printf ("%8.8lx %8.8lx ",
1312 (unsigned long) offset & 0xffffffff,
91d6fa6a 1313 (unsigned long) inf & 0xffffffff);
410f7a12
L
1314 }
1315 else
1316 {
39dbeff8 1317 printf (do_wide
d1ce973e
AM
1318 ? "%16.16" BFD_VMA_FMT "x %16.16" BFD_VMA_FMT "x "
1319 : "%12.12" BFD_VMA_FMT "x %12.12" BFD_VMA_FMT "x ",
91d6fa6a 1320 offset, inf);
410f7a12 1321 }
103f02d3 1322
dda8d76d 1323 switch (filedata->file_header.e_machine)
252b5132
RH
1324 {
1325 default:
1326 rtype = NULL;
1327 break;
1328
a06ea964
NC
1329 case EM_AARCH64:
1330 rtype = elf_aarch64_reloc_type (type);
1331 break;
1332
2b0337b0 1333 case EM_M32R:
252b5132 1334 case EM_CYGNUS_M32R:
9ea033b2 1335 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1336 break;
1337
1338 case EM_386:
22abe556 1339 case EM_IAMCU:
9ea033b2 1340 rtype = elf_i386_reloc_type (type);
252b5132
RH
1341 break;
1342
ba2685cc
AM
1343 case EM_68HC11:
1344 case EM_68HC12:
1345 rtype = elf_m68hc11_reloc_type (type);
1346 break;
75751cd9 1347
7b4ae824
JD
1348 case EM_S12Z:
1349 rtype = elf_s12z_reloc_type (type);
1350 break;
1351
252b5132 1352 case EM_68K:
9ea033b2 1353 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1354 break;
1355
f954747f
AM
1356 case EM_960:
1357 rtype = elf_i960_reloc_type (type);
1358 break;
1359
adde6300 1360 case EM_AVR:
2b0337b0 1361 case EM_AVR_OLD:
adde6300
AM
1362 rtype = elf_avr_reloc_type (type);
1363 break;
1364
9ea033b2
NC
1365 case EM_OLD_SPARCV9:
1366 case EM_SPARC32PLUS:
1367 case EM_SPARCV9:
252b5132 1368 case EM_SPARC:
9ea033b2 1369 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1370 break;
1371
e9f53129
AM
1372 case EM_SPU:
1373 rtype = elf_spu_reloc_type (type);
1374 break;
1375
708e2187
NC
1376 case EM_V800:
1377 rtype = v800_reloc_type (type);
1378 break;
2b0337b0 1379 case EM_V850:
252b5132 1380 case EM_CYGNUS_V850:
9ea033b2 1381 rtype = v850_reloc_type (type);
252b5132
RH
1382 break;
1383
2b0337b0 1384 case EM_D10V:
252b5132 1385 case EM_CYGNUS_D10V:
9ea033b2 1386 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1387 break;
1388
2b0337b0 1389 case EM_D30V:
252b5132 1390 case EM_CYGNUS_D30V:
9ea033b2 1391 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1392 break;
1393
d172d4ba
NC
1394 case EM_DLX:
1395 rtype = elf_dlx_reloc_type (type);
1396 break;
1397
252b5132 1398 case EM_SH:
9ea033b2 1399 rtype = elf_sh_reloc_type (type);
252b5132
RH
1400 break;
1401
2b0337b0 1402 case EM_MN10300:
252b5132 1403 case EM_CYGNUS_MN10300:
9ea033b2 1404 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1405 break;
1406
2b0337b0 1407 case EM_MN10200:
252b5132 1408 case EM_CYGNUS_MN10200:
9ea033b2 1409 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1410 break;
1411
2b0337b0 1412 case EM_FR30:
252b5132 1413 case EM_CYGNUS_FR30:
9ea033b2 1414 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1415 break;
1416
ba2685cc
AM
1417 case EM_CYGNUS_FRV:
1418 rtype = elf_frv_reloc_type (type);
1419 break;
5c70f934 1420
b8891f8d
AJ
1421 case EM_CSKY:
1422 rtype = elf_csky_reloc_type (type);
1423 break;
1424
3f8107ab
AM
1425 case EM_FT32:
1426 rtype = elf_ft32_reloc_type (type);
1427 break;
1428
252b5132 1429 case EM_MCORE:
9ea033b2 1430 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1431 break;
1432
3c3bdf30
NC
1433 case EM_MMIX:
1434 rtype = elf_mmix_reloc_type (type);
1435 break;
1436
5506d11a
AM
1437 case EM_MOXIE:
1438 rtype = elf_moxie_reloc_type (type);
1439 break;
1440
2469cfa2 1441 case EM_MSP430:
dda8d76d 1442 if (uses_msp430x_relocs (filedata))
13761a11
NC
1443 {
1444 rtype = elf_msp430x_reloc_type (type);
1445 break;
1446 }
1a0670f3 1447 /* Fall through. */
2469cfa2
NC
1448 case EM_MSP430_OLD:
1449 rtype = elf_msp430_reloc_type (type);
1450 break;
1451
35c08157
KLC
1452 case EM_NDS32:
1453 rtype = elf_nds32_reloc_type (type);
1454 break;
1455
252b5132 1456 case EM_PPC:
9ea033b2 1457 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1458 break;
1459
c833c019
AM
1460 case EM_PPC64:
1461 rtype = elf_ppc64_reloc_type (type);
1462 break;
1463
252b5132 1464 case EM_MIPS:
4fe85591 1465 case EM_MIPS_RS3_LE:
9ea033b2 1466 rtype = elf_mips_reloc_type (type);
252b5132
RH
1467 break;
1468
e23eba97
NC
1469 case EM_RISCV:
1470 rtype = elf_riscv_reloc_type (type);
1471 break;
1472
252b5132 1473 case EM_ALPHA:
9ea033b2 1474 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1475 break;
1476
1477 case EM_ARM:
9ea033b2 1478 rtype = elf_arm_reloc_type (type);
252b5132
RH
1479 break;
1480
584da044 1481 case EM_ARC:
886a2506
NC
1482 case EM_ARC_COMPACT:
1483 case EM_ARC_COMPACT2:
9ea033b2 1484 rtype = elf_arc_reloc_type (type);
252b5132
RH
1485 break;
1486
1487 case EM_PARISC:
69e617ca 1488 rtype = elf_hppa_reloc_type (type);
252b5132 1489 break;
7d466069 1490
b8720f9d
JL
1491 case EM_H8_300:
1492 case EM_H8_300H:
1493 case EM_H8S:
1494 rtype = elf_h8_reloc_type (type);
1495 break;
1496
73589c9d
CS
1497 case EM_OR1K:
1498 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1499 break;
1500
7d466069 1501 case EM_PJ:
2b0337b0 1502 case EM_PJ_OLD:
7d466069
ILT
1503 rtype = elf_pj_reloc_type (type);
1504 break;
800eeca4
JW
1505 case EM_IA_64:
1506 rtype = elf_ia64_reloc_type (type);
1507 break;
1b61cf92
HPN
1508
1509 case EM_CRIS:
1510 rtype = elf_cris_reloc_type (type);
1511 break;
535c37ff 1512
f954747f
AM
1513 case EM_860:
1514 rtype = elf_i860_reloc_type (type);
1515 break;
1516
bcedfee6 1517 case EM_X86_64:
8a9036a4 1518 case EM_L1OM:
7a9068fe 1519 case EM_K1OM:
bcedfee6
NC
1520 rtype = elf_x86_64_reloc_type (type);
1521 break;
a85d7ed0 1522
f954747f
AM
1523 case EM_S370:
1524 rtype = i370_reloc_type (type);
1525 break;
1526
53c7db4b
KH
1527 case EM_S390_OLD:
1528 case EM_S390:
1529 rtype = elf_s390_reloc_type (type);
1530 break;
93fbbb04 1531
1c0d3aa6
NC
1532 case EM_SCORE:
1533 rtype = elf_score_reloc_type (type);
1534 break;
1535
93fbbb04
GK
1536 case EM_XSTORMY16:
1537 rtype = elf_xstormy16_reloc_type (type);
1538 break;
179d3252 1539
1fe1f39c
NC
1540 case EM_CRX:
1541 rtype = elf_crx_reloc_type (type);
1542 break;
1543
179d3252
JT
1544 case EM_VAX:
1545 rtype = elf_vax_reloc_type (type);
1546 break;
1e4cf259 1547
619ed720
EB
1548 case EM_VISIUM:
1549 rtype = elf_visium_reloc_type (type);
1550 break;
1551
aca4efc7
JM
1552 case EM_BPF:
1553 rtype = elf_bpf_reloc_type (type);
1554 break;
1555
cfb8c092
NC
1556 case EM_ADAPTEVA_EPIPHANY:
1557 rtype = elf_epiphany_reloc_type (type);
1558 break;
1559
1e4cf259
NC
1560 case EM_IP2K:
1561 case EM_IP2K_OLD:
1562 rtype = elf_ip2k_reloc_type (type);
1563 break;
3b36097d
SC
1564
1565 case EM_IQ2000:
1566 rtype = elf_iq2000_reloc_type (type);
1567 break;
88da6820
NC
1568
1569 case EM_XTENSA_OLD:
1570 case EM_XTENSA:
1571 rtype = elf_xtensa_reloc_type (type);
1572 break;
a34e3ecb 1573
84e94c90
NC
1574 case EM_LATTICEMICO32:
1575 rtype = elf_lm32_reloc_type (type);
1576 break;
1577
ff7eeb89 1578 case EM_M32C_OLD:
49f58d10
JB
1579 case EM_M32C:
1580 rtype = elf_m32c_reloc_type (type);
1581 break;
1582
d031aafb
NS
1583 case EM_MT:
1584 rtype = elf_mt_reloc_type (type);
a34e3ecb 1585 break;
1d65ded4
CM
1586
1587 case EM_BLACKFIN:
1588 rtype = elf_bfin_reloc_type (type);
1589 break;
15ab5209
DB
1590
1591 case EM_CYGNUS_MEP:
1592 rtype = elf_mep_reloc_type (type);
1593 break;
60bca95a
NC
1594
1595 case EM_CR16:
1596 rtype = elf_cr16_reloc_type (type);
1597 break;
dd24e3da 1598
7ba29e2a
NC
1599 case EM_MICROBLAZE:
1600 case EM_MICROBLAZE_OLD:
1601 rtype = elf_microblaze_reloc_type (type);
1602 break;
c7927a3c 1603
99c513f6
DD
1604 case EM_RL78:
1605 rtype = elf_rl78_reloc_type (type);
1606 break;
1607
c7927a3c
NC
1608 case EM_RX:
1609 rtype = elf_rx_reloc_type (type);
1610 break;
c29aca4a 1611
a3c62988
NC
1612 case EM_METAG:
1613 rtype = elf_metag_reloc_type (type);
1614 break;
1615
c29aca4a
NC
1616 case EM_XC16X:
1617 case EM_C166:
1618 rtype = elf_xc16x_reloc_type (type);
1619 break;
40b36596
JM
1620
1621 case EM_TI_C6000:
1622 rtype = elf_tic6x_reloc_type (type);
1623 break;
aa137e4d
NC
1624
1625 case EM_TILEGX:
1626 rtype = elf_tilegx_reloc_type (type);
1627 break;
1628
1629 case EM_TILEPRO:
1630 rtype = elf_tilepro_reloc_type (type);
1631 break;
f6c1a2d5 1632
f96bd6c2
PC
1633 case EM_WEBASSEMBLY:
1634 rtype = elf_wasm32_reloc_type (type);
1635 break;
1636
f6c1a2d5
NC
1637 case EM_XGATE:
1638 rtype = elf_xgate_reloc_type (type);
1639 break;
36591ba1
SL
1640
1641 case EM_ALTERA_NIOS2:
1642 rtype = elf_nios2_reloc_type (type);
1643 break;
2b100bb5
DD
1644
1645 case EM_TI_PRU:
1646 rtype = elf_pru_reloc_type (type);
1647 break;
fe944acf
FT
1648
1649 case EM_NFP:
1650 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1651 rtype = elf_nfp3200_reloc_type (type);
1652 else
1653 rtype = elf_nfp_reloc_type (type);
1654 break;
6655dba2
SB
1655
1656 case EM_Z80:
1657 rtype = elf_z80_reloc_type (type);
1658 break;
252b5132
RH
1659 }
1660
1661 if (rtype == NULL)
39dbeff8 1662 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1663 else
5c144731 1664 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1665
dda8d76d 1666 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1667 && rtype != NULL
7ace3541
RH
1668 && streq (rtype, "R_ALPHA_LITUSE")
1669 && is_rela)
1670 {
1671 switch (rels[i].r_addend)
1672 {
1673 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1674 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1675 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1676 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1677 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1678 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1679 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1680 default: rtype = NULL;
1681 }
32ec8896 1682
7ace3541
RH
1683 if (rtype)
1684 printf (" (%s)", rtype);
1685 else
1686 {
1687 putchar (' ');
1688 printf (_("<unknown addend: %lx>"),
1689 (unsigned long) rels[i].r_addend);
015dc7e1 1690 res = false;
7ace3541
RH
1691 }
1692 }
1693 else if (symtab_index)
252b5132 1694 {
af3fc3bc 1695 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1696 {
27a45f42
AS
1697 error (_(" bad symbol index: %08lx in reloc\n"),
1698 (unsigned long) symtab_index);
015dc7e1 1699 res = false;
32ec8896 1700 }
af3fc3bc 1701 else
19936277 1702 {
2cf0635d 1703 Elf_Internal_Sym * psym;
bb4d2ac2
L
1704 const char * version_string;
1705 enum versioned_symbol_info sym_info;
1706 unsigned short vna_other;
19936277 1707
af3fc3bc 1708 psym = symtab + symtab_index;
103f02d3 1709
bb4d2ac2 1710 version_string
dda8d76d 1711 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1712 strtab, strtablen,
1713 symtab_index,
1714 psym,
1715 &sym_info,
1716 &vna_other);
1717
af3fc3bc 1718 printf (" ");
171191ba 1719
d8045f23
NC
1720 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1721 {
1722 const char * name;
1723 unsigned int len;
1724 unsigned int width = is_32bit_elf ? 8 : 14;
1725
1726 /* Relocations against GNU_IFUNC symbols do not use the value
1727 of the symbol as the address to relocate against. Instead
1728 they invoke the function named by the symbol and use its
1729 result as the address for relocation.
1730
1731 To indicate this to the user, do not display the value of
1732 the symbol in the "Symbols's Value" field. Instead show
1733 its name followed by () as a hint that the symbol is
1734 invoked. */
1735
1736 if (strtab == NULL
1737 || psym->st_name == 0
1738 || psym->st_name >= strtablen)
1739 name = "??";
1740 else
1741 name = strtab + psym->st_name;
1742
1743 len = print_symbol (width, name);
bb4d2ac2
L
1744 if (version_string)
1745 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1746 version_string);
d8045f23
NC
1747 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1748 }
1749 else
1750 {
1751 print_vma (psym->st_value, LONG_HEX);
171191ba 1752
d8045f23
NC
1753 printf (is_32bit_elf ? " " : " ");
1754 }
103f02d3 1755
af3fc3bc 1756 if (psym->st_name == 0)
f1ef08cb 1757 {
2cf0635d 1758 const char * sec_name = "<null>";
f1ef08cb
AM
1759 char name_buf[40];
1760
1761 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1762 {
dda8d76d 1763 if (psym->st_shndx < filedata->file_header.e_shnum)
b9e920ec
AM
1764 sec_name = SECTION_NAME_PRINT (filedata->section_headers
1765 + psym->st_shndx);
f1ef08cb
AM
1766 else if (psym->st_shndx == SHN_ABS)
1767 sec_name = "ABS";
1768 else if (psym->st_shndx == SHN_COMMON)
1769 sec_name = "COMMON";
dda8d76d 1770 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1771 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1772 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1773 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1774 sec_name = "SCOMMON";
dda8d76d 1775 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1776 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1777 sec_name = "SUNDEF";
dda8d76d
NC
1778 else if ((filedata->file_header.e_machine == EM_X86_64
1779 || filedata->file_header.e_machine == EM_L1OM
1780 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1781 && psym->st_shndx == SHN_X86_64_LCOMMON)
1782 sec_name = "LARGE_COMMON";
dda8d76d
NC
1783 else if (filedata->file_header.e_machine == EM_IA_64
1784 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1785 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1786 sec_name = "ANSI_COM";
dda8d76d 1787 else if (is_ia64_vms (filedata)
148b93f2
NC
1788 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1789 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1790 else
1791 {
1792 sprintf (name_buf, "<section 0x%x>",
1793 (unsigned int) psym->st_shndx);
1794 sec_name = name_buf;
1795 }
1796 }
1797 print_symbol (22, sec_name);
1798 }
af3fc3bc 1799 else if (strtab == NULL)
d79b3d50 1800 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1801 else if (psym->st_name >= strtablen)
32ec8896 1802 {
27a45f42
AS
1803 error (_("<corrupt string table index: %3ld>\n"),
1804 psym->st_name);
015dc7e1 1805 res = false;
32ec8896 1806 }
af3fc3bc 1807 else
bb4d2ac2
L
1808 {
1809 print_symbol (22, strtab + psym->st_name);
1810 if (version_string)
1811 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1812 version_string);
1813 }
103f02d3 1814
af3fc3bc 1815 if (is_rela)
171191ba 1816 {
7360e63f 1817 bfd_vma off = rels[i].r_addend;
171191ba 1818
7360e63f 1819 if ((bfd_signed_vma) off < 0)
598aaa76 1820 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1821 else
598aaa76 1822 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1823 }
19936277 1824 }
252b5132 1825 }
1b228002 1826 else if (is_rela)
f7a99963 1827 {
7360e63f 1828 bfd_vma off = rels[i].r_addend;
e04d7088
L
1829
1830 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1831 if ((bfd_signed_vma) off < 0)
e04d7088
L
1832 printf ("-%" BFD_VMA_FMT "x", - off);
1833 else
1834 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1835 }
252b5132 1836
dda8d76d 1837 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1838 && rtype != NULL
1839 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1840 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1841
252b5132 1842 putchar ('\n');
2c71103e 1843
aca88567 1844#ifdef BFD64
dda8d76d 1845 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1846 {
91d6fa6a
NC
1847 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1848 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1849 const char * rtype2 = elf_mips_reloc_type (type2);
1850 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1851
2c71103e
NC
1852 printf (" Type2: ");
1853
1854 if (rtype2 == NULL)
39dbeff8
AM
1855 printf (_("unrecognized: %-7lx"),
1856 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1857 else
1858 printf ("%-17.17s", rtype2);
1859
18bd398b 1860 printf ("\n Type3: ");
2c71103e
NC
1861
1862 if (rtype3 == NULL)
39dbeff8
AM
1863 printf (_("unrecognized: %-7lx"),
1864 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1865 else
1866 printf ("%-17.17s", rtype3);
1867
53c7db4b 1868 putchar ('\n');
2c71103e 1869 }
aca88567 1870#endif /* BFD64 */
252b5132
RH
1871 }
1872
c8286bd1 1873 free (rels);
32ec8896
NC
1874
1875 return res;
252b5132
RH
1876}
1877
37c18eed
SD
1878static const char *
1879get_aarch64_dynamic_type (unsigned long type)
1880{
1881 switch (type)
1882 {
1883 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 1884 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 1885 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
1886 default:
1887 return NULL;
1888 }
1889}
1890
252b5132 1891static const char *
d3ba0551 1892get_mips_dynamic_type (unsigned long type)
252b5132
RH
1893{
1894 switch (type)
1895 {
1896 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1897 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1898 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1899 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1900 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1901 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1902 case DT_MIPS_MSYM: return "MIPS_MSYM";
1903 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1904 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1905 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1906 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1907 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1908 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1909 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1910 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1911 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1912 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1913 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1914 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1915 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1916 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1917 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1918 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1919 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1920 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1921 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1922 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1923 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1924 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1925 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1926 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1927 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1928 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1929 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1930 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1931 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1932 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1933 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1934 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1935 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1936 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1937 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1938 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1939 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1940 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1941 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 1942 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
1943 default:
1944 return NULL;
1945 }
1946}
1947
9a097730 1948static const char *
d3ba0551 1949get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1950{
1951 switch (type)
1952 {
1953 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1954 default:
1955 return NULL;
1956 }
103f02d3
UD
1957}
1958
7490d522
AM
1959static const char *
1960get_ppc_dynamic_type (unsigned long type)
1961{
1962 switch (type)
1963 {
a7f2871e 1964 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1965 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1966 default:
1967 return NULL;
1968 }
1969}
1970
f1cb7e17 1971static const char *
d3ba0551 1972get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1973{
1974 switch (type)
1975 {
a7f2871e
AM
1976 case DT_PPC64_GLINK: return "PPC64_GLINK";
1977 case DT_PPC64_OPD: return "PPC64_OPD";
1978 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1979 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1980 default:
1981 return NULL;
1982 }
1983}
1984
103f02d3 1985static const char *
d3ba0551 1986get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1987{
1988 switch (type)
1989 {
1990 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1991 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1992 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1993 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1994 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1995 case DT_HP_PREINIT: return "HP_PREINIT";
1996 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1997 case DT_HP_NEEDED: return "HP_NEEDED";
1998 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1999 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2000 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2001 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2002 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2003 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2004 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2005 case DT_HP_FILTERED: return "HP_FILTERED";
2006 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2007 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2008 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2009 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2010 case DT_PLT: return "PLT";
2011 case DT_PLT_SIZE: return "PLT_SIZE";
2012 case DT_DLT: return "DLT";
2013 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2014 default:
2015 return NULL;
2016 }
2017}
9a097730 2018
ecc51f48 2019static const char *
d3ba0551 2020get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2021{
2022 switch (type)
2023 {
148b93f2
NC
2024 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2025 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2026 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2027 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2028 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2029 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2030 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2031 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2032 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2033 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2034 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2035 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2036 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2037 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2038 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2039 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2040 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2041 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2042 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2043 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2044 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2045 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2046 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2047 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2048 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2049 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2050 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2051 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2052 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2053 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2054 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2055 default:
2056 return NULL;
2057 }
2058}
2059
fd85a6a1
NC
2060static const char *
2061get_solaris_section_type (unsigned long type)
2062{
2063 switch (type)
2064 {
2065 case 0x6fffffee: return "SUNW_ancillary";
2066 case 0x6fffffef: return "SUNW_capchain";
2067 case 0x6ffffff0: return "SUNW_capinfo";
2068 case 0x6ffffff1: return "SUNW_symsort";
2069 case 0x6ffffff2: return "SUNW_tlssort";
2070 case 0x6ffffff3: return "SUNW_LDYNSYM";
2071 case 0x6ffffff4: return "SUNW_dof";
2072 case 0x6ffffff5: return "SUNW_cap";
2073 case 0x6ffffff6: return "SUNW_SIGNATURE";
2074 case 0x6ffffff7: return "SUNW_ANNOTATE";
2075 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2076 case 0x6ffffff9: return "SUNW_DEBUG";
2077 case 0x6ffffffa: return "SUNW_move";
2078 case 0x6ffffffb: return "SUNW_COMDAT";
2079 case 0x6ffffffc: return "SUNW_syminfo";
2080 case 0x6ffffffd: return "SUNW_verdef";
2081 case 0x6ffffffe: return "SUNW_verneed";
2082 case 0x6fffffff: return "SUNW_versym";
2083 case 0x70000000: return "SPARC_GOTDATA";
2084 default: return NULL;
2085 }
2086}
2087
fabcb361
RH
2088static const char *
2089get_alpha_dynamic_type (unsigned long type)
2090{
2091 switch (type)
2092 {
2093 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2094 default: return NULL;
fabcb361
RH
2095 }
2096}
2097
1c0d3aa6
NC
2098static const char *
2099get_score_dynamic_type (unsigned long type)
2100{
2101 switch (type)
2102 {
2103 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2104 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2105 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2106 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2107 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2108 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2109 default: return NULL;
1c0d3aa6
NC
2110 }
2111}
2112
40b36596
JM
2113static const char *
2114get_tic6x_dynamic_type (unsigned long type)
2115{
2116 switch (type)
2117 {
2118 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2119 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2120 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2121 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2122 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2123 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2124 default: return NULL;
40b36596
JM
2125 }
2126}
1c0d3aa6 2127
36591ba1
SL
2128static const char *
2129get_nios2_dynamic_type (unsigned long type)
2130{
2131 switch (type)
2132 {
2133 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2134 default: return NULL;
36591ba1
SL
2135 }
2136}
2137
fd85a6a1
NC
2138static const char *
2139get_solaris_dynamic_type (unsigned long type)
2140{
2141 switch (type)
2142 {
2143 case 0x6000000d: return "SUNW_AUXILIARY";
2144 case 0x6000000e: return "SUNW_RTLDINF";
2145 case 0x6000000f: return "SUNW_FILTER";
2146 case 0x60000010: return "SUNW_CAP";
2147 case 0x60000011: return "SUNW_SYMTAB";
2148 case 0x60000012: return "SUNW_SYMSZ";
2149 case 0x60000013: return "SUNW_SORTENT";
2150 case 0x60000014: return "SUNW_SYMSORT";
2151 case 0x60000015: return "SUNW_SYMSORTSZ";
2152 case 0x60000016: return "SUNW_TLSSORT";
2153 case 0x60000017: return "SUNW_TLSSORTSZ";
2154 case 0x60000018: return "SUNW_CAPINFO";
2155 case 0x60000019: return "SUNW_STRPAD";
2156 case 0x6000001a: return "SUNW_CAPCHAIN";
2157 case 0x6000001b: return "SUNW_LDMACH";
2158 case 0x6000001d: return "SUNW_CAPCHAINENT";
2159 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2160 case 0x60000021: return "SUNW_PARENT";
2161 case 0x60000023: return "SUNW_ASLR";
2162 case 0x60000025: return "SUNW_RELAX";
2163 case 0x60000029: return "SUNW_NXHEAP";
2164 case 0x6000002b: return "SUNW_NXSTACK";
2165
2166 case 0x70000001: return "SPARC_REGISTER";
2167 case 0x7ffffffd: return "AUXILIARY";
2168 case 0x7ffffffe: return "USED";
2169 case 0x7fffffff: return "FILTER";
2170
15f205b1 2171 default: return NULL;
fd85a6a1
NC
2172 }
2173}
2174
252b5132 2175static const char *
dda8d76d 2176get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2177{
e9e44622 2178 static char buff[64];
252b5132
RH
2179
2180 switch (type)
2181 {
2182 case DT_NULL: return "NULL";
2183 case DT_NEEDED: return "NEEDED";
2184 case DT_PLTRELSZ: return "PLTRELSZ";
2185 case DT_PLTGOT: return "PLTGOT";
2186 case DT_HASH: return "HASH";
2187 case DT_STRTAB: return "STRTAB";
2188 case DT_SYMTAB: return "SYMTAB";
2189 case DT_RELA: return "RELA";
2190 case DT_RELASZ: return "RELASZ";
2191 case DT_RELAENT: return "RELAENT";
2192 case DT_STRSZ: return "STRSZ";
2193 case DT_SYMENT: return "SYMENT";
2194 case DT_INIT: return "INIT";
2195 case DT_FINI: return "FINI";
2196 case DT_SONAME: return "SONAME";
2197 case DT_RPATH: return "RPATH";
2198 case DT_SYMBOLIC: return "SYMBOLIC";
2199 case DT_REL: return "REL";
2200 case DT_RELSZ: return "RELSZ";
2201 case DT_RELENT: return "RELENT";
2202 case DT_PLTREL: return "PLTREL";
2203 case DT_DEBUG: return "DEBUG";
2204 case DT_TEXTREL: return "TEXTREL";
2205 case DT_JMPREL: return "JMPREL";
2206 case DT_BIND_NOW: return "BIND_NOW";
2207 case DT_INIT_ARRAY: return "INIT_ARRAY";
2208 case DT_FINI_ARRAY: return "FINI_ARRAY";
2209 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2210 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2211 case DT_RUNPATH: return "RUNPATH";
2212 case DT_FLAGS: return "FLAGS";
2d0e6f43 2213
d1133906
NC
2214 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2215 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2216 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2217
05107a46 2218 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2219 case DT_PLTPADSZ: return "PLTPADSZ";
2220 case DT_MOVEENT: return "MOVEENT";
2221 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2222 case DT_FEATURE: return "FEATURE";
252b5132
RH
2223 case DT_POSFLAG_1: return "POSFLAG_1";
2224 case DT_SYMINSZ: return "SYMINSZ";
2225 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2226
252b5132 2227 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2228 case DT_CONFIG: return "CONFIG";
2229 case DT_DEPAUDIT: return "DEPAUDIT";
2230 case DT_AUDIT: return "AUDIT";
2231 case DT_PLTPAD: return "PLTPAD";
2232 case DT_MOVETAB: return "MOVETAB";
252b5132 2233 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2234
252b5132 2235 case DT_VERSYM: return "VERSYM";
103f02d3 2236
67a4f2b7
AO
2237 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2238 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2239 case DT_RELACOUNT: return "RELACOUNT";
2240 case DT_RELCOUNT: return "RELCOUNT";
2241 case DT_FLAGS_1: return "FLAGS_1";
2242 case DT_VERDEF: return "VERDEF";
2243 case DT_VERDEFNUM: return "VERDEFNUM";
2244 case DT_VERNEED: return "VERNEED";
2245 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2246
019148e4 2247 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2248 case DT_USED: return "USED";
2249 case DT_FILTER: return "FILTER";
103f02d3 2250
047b2264
JJ
2251 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2252 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2253 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2254 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2255 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2256 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2257 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2258
252b5132
RH
2259 default:
2260 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2261 {
2cf0635d 2262 const char * result;
103f02d3 2263
dda8d76d 2264 switch (filedata->file_header.e_machine)
252b5132 2265 {
37c18eed
SD
2266 case EM_AARCH64:
2267 result = get_aarch64_dynamic_type (type);
2268 break;
252b5132 2269 case EM_MIPS:
4fe85591 2270 case EM_MIPS_RS3_LE:
252b5132
RH
2271 result = get_mips_dynamic_type (type);
2272 break;
9a097730
RH
2273 case EM_SPARCV9:
2274 result = get_sparc64_dynamic_type (type);
2275 break;
7490d522
AM
2276 case EM_PPC:
2277 result = get_ppc_dynamic_type (type);
2278 break;
f1cb7e17
AM
2279 case EM_PPC64:
2280 result = get_ppc64_dynamic_type (type);
2281 break;
ecc51f48
NC
2282 case EM_IA_64:
2283 result = get_ia64_dynamic_type (type);
2284 break;
fabcb361
RH
2285 case EM_ALPHA:
2286 result = get_alpha_dynamic_type (type);
2287 break;
1c0d3aa6
NC
2288 case EM_SCORE:
2289 result = get_score_dynamic_type (type);
2290 break;
40b36596
JM
2291 case EM_TI_C6000:
2292 result = get_tic6x_dynamic_type (type);
2293 break;
36591ba1
SL
2294 case EM_ALTERA_NIOS2:
2295 result = get_nios2_dynamic_type (type);
2296 break;
252b5132 2297 default:
dda8d76d 2298 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2299 result = get_solaris_dynamic_type (type);
2300 else
2301 result = NULL;
252b5132
RH
2302 break;
2303 }
2304
2305 if (result != NULL)
2306 return result;
2307
e9e44622 2308 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2309 }
eec8f817 2310 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2311 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2312 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2313 {
2cf0635d 2314 const char * result;
103f02d3 2315
dda8d76d 2316 switch (filedata->file_header.e_machine)
103f02d3
UD
2317 {
2318 case EM_PARISC:
2319 result = get_parisc_dynamic_type (type);
2320 break;
148b93f2
NC
2321 case EM_IA_64:
2322 result = get_ia64_dynamic_type (type);
2323 break;
103f02d3 2324 default:
dda8d76d 2325 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2326 result = get_solaris_dynamic_type (type);
2327 else
2328 result = NULL;
103f02d3
UD
2329 break;
2330 }
2331
2332 if (result != NULL)
2333 return result;
2334
e9e44622
JJ
2335 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2336 type);
103f02d3 2337 }
252b5132 2338 else
e9e44622 2339 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2340
252b5132
RH
2341 return buff;
2342 }
2343}
2344
2345static char *
d3ba0551 2346get_file_type (unsigned e_type)
252b5132 2347{
89246a0e 2348 static char buff[64];
252b5132
RH
2349
2350 switch (e_type)
2351 {
32ec8896
NC
2352 case ET_NONE: return _("NONE (None)");
2353 case ET_REL: return _("REL (Relocatable file)");
2354 case ET_EXEC: return _("EXEC (Executable file)");
2355 case ET_DYN: return _("DYN (Shared object file)");
2356 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2357
2358 default:
2359 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2360 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2361 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2362 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2363 else
e9e44622 2364 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2365 return buff;
2366 }
2367}
2368
2369static char *
d3ba0551 2370get_machine_name (unsigned e_machine)
252b5132 2371{
b34976b6 2372 static char buff[64]; /* XXX */
252b5132
RH
2373
2374 switch (e_machine)
2375 {
55e22ca8
NC
2376 /* Please keep this switch table sorted by increasing EM_ value. */
2377 /* 0 */
c45021f2
NC
2378 case EM_NONE: return _("None");
2379 case EM_M32: return "WE32100";
2380 case EM_SPARC: return "Sparc";
2381 case EM_386: return "Intel 80386";
2382 case EM_68K: return "MC68000";
2383 case EM_88K: return "MC88000";
22abe556 2384 case EM_IAMCU: return "Intel MCU";
fb70ec17 2385 case EM_860: return "Intel 80860";
c45021f2
NC
2386 case EM_MIPS: return "MIPS R3000";
2387 case EM_S370: return "IBM System/370";
55e22ca8 2388 /* 10 */
7036c0e1 2389 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2390 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2391 case EM_PARISC: return "HPPA";
55e22ca8 2392 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2393 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2394 case EM_960: return "Intel 80960";
c45021f2 2395 case EM_PPC: return "PowerPC";
55e22ca8 2396 /* 20 */
285d1771 2397 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2398 case EM_S390_OLD:
2399 case EM_S390: return "IBM S/390";
2400 case EM_SPU: return "SPU";
2401 /* 30 */
2402 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2403 case EM_FR20: return "Fujitsu FR20";
2404 case EM_RH32: return "TRW RH32";
b34976b6 2405 case EM_MCORE: return "MCORE";
55e22ca8 2406 /* 40 */
7036c0e1
AJ
2407 case EM_ARM: return "ARM";
2408 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2409 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2410 case EM_SPARCV9: return "Sparc v9";
2411 case EM_TRICORE: return "Siemens Tricore";
584da044 2412 case EM_ARC: return "ARC";
c2dcd04e
NC
2413 case EM_H8_300: return "Renesas H8/300";
2414 case EM_H8_300H: return "Renesas H8/300H";
2415 case EM_H8S: return "Renesas H8S";
2416 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2417 /* 50 */
30800947 2418 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2419 case EM_MIPS_X: return "Stanford MIPS-X";
2420 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2421 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2422 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2423 case EM_PCP: return "Siemens PCP";
2424 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2425 case EM_NDR1: return "Denso NDR1 microprocesspr";
2426 case EM_STARCORE: return "Motorola Star*Core processor";
2427 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2428 /* 60 */
7036c0e1
AJ
2429 case EM_ST100: return "STMicroelectronics ST100 processor";
2430 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2431 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2432 case EM_PDSP: return "Sony DSP processor";
2433 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2434 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2435 case EM_FX66: return "Siemens FX66 microcontroller";
2436 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2437 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2438 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2439 /* 70 */
7036c0e1
AJ
2440 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2441 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2442 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2443 case EM_SVX: return "Silicon Graphics SVx";
2444 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2445 case EM_VAX: return "Digital VAX";
1b61cf92 2446 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2447 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2448 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2449 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2450 /* 80 */
b34976b6 2451 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2452 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2453 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2454 case EM_AVR_OLD:
2455 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2456 case EM_CYGNUS_FR30:
2457 case EM_FR30: return "Fujitsu FR30";
2458 case EM_CYGNUS_D10V:
2459 case EM_D10V: return "d10v";
2460 case EM_CYGNUS_D30V:
2461 case EM_D30V: return "d30v";
2462 case EM_CYGNUS_V850:
2463 case EM_V850: return "Renesas V850";
2464 case EM_CYGNUS_M32R:
2465 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2466 case EM_CYGNUS_MN10300:
2467 case EM_MN10300: return "mn10300";
2468 /* 90 */
2469 case EM_CYGNUS_MN10200:
2470 case EM_MN10200: return "mn10200";
2471 case EM_PJ: return "picoJava";
73589c9d 2472 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2473 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2474 case EM_XTENSA_OLD:
2475 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2476 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2477 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2478 case EM_NS32K: return "National Semiconductor 32000 series";
2479 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2480 case EM_SNP1K: return "Trebia SNP 1000 processor";
2481 /* 100 */
9abca702 2482 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2483 case EM_IP2K_OLD:
2484 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2485 case EM_MAX: return "MAX Processor";
2486 case EM_CR: return "National Semiconductor CompactRISC";
2487 case EM_F2MC16: return "Fujitsu F2MC16";
2488 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2489 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2490 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2491 case EM_SEP: return "Sharp embedded microprocessor";
2492 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2493 /* 110 */
11636f9e
JM
2494 case EM_UNICORE: return "Unicore";
2495 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2496 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2497 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2498 case EM_CRX: return "National Semiconductor CRX microprocessor";
2499 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2500 case EM_C166:
d70c5fc7 2501 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2502 case EM_M16C: return "Renesas M16C series microprocessors";
2503 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2504 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2505 /* 120 */
2506 case EM_M32C: return "Renesas M32c";
2507 /* 130 */
11636f9e
JM
2508 case EM_TSK3000: return "Altium TSK3000 core";
2509 case EM_RS08: return "Freescale RS08 embedded processor";
2510 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2511 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2512 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2513 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2514 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2515 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2516 /* 140 */
11636f9e
JM
2517 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2518 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2519 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2520 case EM_TI_PRU: return "TI PRU I/O processor";
2521 /* 160 */
11636f9e
JM
2522 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2523 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2524 case EM_R32C: return "Renesas R32C series microprocessors";
2525 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2526 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2527 case EM_8051: return "Intel 8051 and variants";
2528 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2529 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2530 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2531 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2532 /* 170 */
11636f9e
JM
2533 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2534 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2535 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2536 case EM_RX: return "Renesas RX";
a3c62988 2537 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2538 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2539 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2540 case EM_CR16:
2541 case EM_MICROBLAZE:
2542 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2543 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2544 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2545 /* 180 */
2546 case EM_L1OM: return "Intel L1OM";
2547 case EM_K1OM: return "Intel K1OM";
2548 case EM_INTEL182: return "Intel (reserved)";
2549 case EM_AARCH64: return "AArch64";
2550 case EM_ARM184: return "ARM (reserved)";
2551 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2552 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2553 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2554 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2555 /* 190 */
11636f9e 2556 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2557 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2558 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2559 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2560 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2561 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2562 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2563 case EM_RL78: return "Renesas RL78";
6d913794 2564 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2565 case EM_78K0R: return "Renesas 78K0R";
2566 /* 200 */
6d913794 2567 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2568 case EM_BA1: return "Beyond BA1 CPU architecture";
2569 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2570 case EM_XCORE: return "XMOS xCORE processor family";
2571 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2572 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2573 /* 210 */
6d913794
NC
2574 case EM_KM32: return "KM211 KM32 32-bit processor";
2575 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2576 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2577 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2578 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2579 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2580 case EM_COGE: return "Cognitive Smart Memory Processor";
2581 case EM_COOL: return "Bluechip Systems CoolEngine";
2582 case EM_NORC: return "Nanoradio Optimized RISC";
2583 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2584 /* 220 */
15f205b1 2585 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2586 case EM_VISIUM: return "CDS VISIUMcore processor";
2587 case EM_FT32: return "FTDI Chip FT32";
2588 case EM_MOXIE: return "Moxie";
2589 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2590 /* 230 (all reserved) */
2591 /* 240 */
55e22ca8
NC
2592 case EM_RISCV: return "RISC-V";
2593 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2594 case EM_CEVA: return "CEVA Processor Architecture Family";
2595 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2596 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2597 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2598 case EM_IMG1: return "Imagination Technologies";
2599 /* 250 */
fe944acf 2600 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2601 case EM_VE: return "NEC Vector Engine";
2602 case EM_CSKY: return "C-SKY";
2603 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2604 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2605 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2606 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2607 case EM_65816: return "WDC 65816/65C816";
2608 case EM_LOONGARCH: return "Loongson Loongarch";
2609 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2610
2611 /* Large numbers... */
2612 case EM_MT: return "Morpho Techologies MT processor";
2613 case EM_ALPHA: return "Alpha";
2614 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2615 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2616 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2617 case EM_IQ2000: return "Vitesse IQ2000";
2618 case EM_M32C_OLD:
2619 case EM_NIOS32: return "Altera Nios";
2620 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2621 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2622 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2623 case EM_S12Z: return "Freescale S12Z";
55e22ca8 2624
252b5132 2625 default:
35d9dd2f 2626 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2627 return buff;
2628 }
2629}
2630
a9522a21
AB
2631static void
2632decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2633{
2634 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 2635 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
2636 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2637 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2638 architectures.
2639
2640 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2641 but also sets a specific architecture type in the e_flags field.
2642
2643 However, when decoding the flags we don't worry if we see an
2644 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2645 ARCEM architecture type. */
2646
2647 switch (e_flags & EF_ARC_MACH_MSK)
2648 {
2649 /* We only expect these to occur for EM_ARC_COMPACT2. */
2650 case EF_ARC_CPU_ARCV2EM:
2651 strcat (buf, ", ARC EM");
2652 break;
2653 case EF_ARC_CPU_ARCV2HS:
2654 strcat (buf, ", ARC HS");
2655 break;
2656
2657 /* We only expect these to occur for EM_ARC_COMPACT. */
2658 case E_ARC_MACH_ARC600:
2659 strcat (buf, ", ARC600");
2660 break;
2661 case E_ARC_MACH_ARC601:
2662 strcat (buf, ", ARC601");
2663 break;
2664 case E_ARC_MACH_ARC700:
2665 strcat (buf, ", ARC700");
2666 break;
2667
2668 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2669 new ELF with new architecture being read by an old version of
2670 readelf, or (c) An ELF built with non-GNU compiler that does not
2671 set the architecture in the e_flags. */
2672 default:
2673 if (e_machine == EM_ARC_COMPACT)
2674 strcat (buf, ", Unknown ARCompact");
2675 else
2676 strcat (buf, ", Unknown ARC");
2677 break;
2678 }
2679
2680 switch (e_flags & EF_ARC_OSABI_MSK)
2681 {
2682 case E_ARC_OSABI_ORIG:
2683 strcat (buf, ", (ABI:legacy)");
2684 break;
2685 case E_ARC_OSABI_V2:
2686 strcat (buf, ", (ABI:v2)");
2687 break;
2688 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2689 case E_ARC_OSABI_V3:
2690 strcat (buf, ", v3 no-legacy-syscalls ABI");
2691 break;
53a346d8
CZ
2692 case E_ARC_OSABI_V4:
2693 strcat (buf, ", v4 ABI");
2694 break;
a9522a21
AB
2695 default:
2696 strcat (buf, ", unrecognised ARC OSABI flag");
2697 break;
2698 }
2699}
2700
f3485b74 2701static void
d3ba0551 2702decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2703{
2704 unsigned eabi;
015dc7e1 2705 bool unknown = false;
f3485b74
NC
2706
2707 eabi = EF_ARM_EABI_VERSION (e_flags);
2708 e_flags &= ~ EF_ARM_EABIMASK;
2709
2710 /* Handle "generic" ARM flags. */
2711 if (e_flags & EF_ARM_RELEXEC)
2712 {
2713 strcat (buf, ", relocatable executable");
2714 e_flags &= ~ EF_ARM_RELEXEC;
2715 }
76da6bbe 2716
18a20338
CL
2717 if (e_flags & EF_ARM_PIC)
2718 {
2719 strcat (buf, ", position independent");
2720 e_flags &= ~ EF_ARM_PIC;
2721 }
2722
f3485b74
NC
2723 /* Now handle EABI specific flags. */
2724 switch (eabi)
2725 {
2726 default:
2c71103e 2727 strcat (buf, ", <unrecognized EABI>");
f3485b74 2728 if (e_flags)
015dc7e1 2729 unknown = true;
f3485b74
NC
2730 break;
2731
2732 case EF_ARM_EABI_VER1:
a5bcd848 2733 strcat (buf, ", Version1 EABI");
f3485b74
NC
2734 while (e_flags)
2735 {
2736 unsigned flag;
76da6bbe 2737
f3485b74
NC
2738 /* Process flags one bit at a time. */
2739 flag = e_flags & - e_flags;
2740 e_flags &= ~ flag;
76da6bbe 2741
f3485b74
NC
2742 switch (flag)
2743 {
a5bcd848 2744 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2745 strcat (buf, ", sorted symbol tables");
2746 break;
76da6bbe 2747
f3485b74 2748 default:
015dc7e1 2749 unknown = true;
f3485b74
NC
2750 break;
2751 }
2752 }
2753 break;
76da6bbe 2754
a5bcd848
PB
2755 case EF_ARM_EABI_VER2:
2756 strcat (buf, ", Version2 EABI");
2757 while (e_flags)
2758 {
2759 unsigned flag;
2760
2761 /* Process flags one bit at a time. */
2762 flag = e_flags & - e_flags;
2763 e_flags &= ~ flag;
2764
2765 switch (flag)
2766 {
2767 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2768 strcat (buf, ", sorted symbol tables");
2769 break;
2770
2771 case EF_ARM_DYNSYMSUSESEGIDX:
2772 strcat (buf, ", dynamic symbols use segment index");
2773 break;
2774
2775 case EF_ARM_MAPSYMSFIRST:
2776 strcat (buf, ", mapping symbols precede others");
2777 break;
2778
2779 default:
015dc7e1 2780 unknown = true;
a5bcd848
PB
2781 break;
2782 }
2783 }
2784 break;
2785
d507cf36
PB
2786 case EF_ARM_EABI_VER3:
2787 strcat (buf, ", Version3 EABI");
8cb51566
PB
2788 break;
2789
2790 case EF_ARM_EABI_VER4:
2791 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2792 while (e_flags)
2793 {
2794 unsigned flag;
2795
2796 /* Process flags one bit at a time. */
2797 flag = e_flags & - e_flags;
2798 e_flags &= ~ flag;
2799
2800 switch (flag)
2801 {
2802 case EF_ARM_BE8:
2803 strcat (buf, ", BE8");
2804 break;
2805
2806 case EF_ARM_LE8:
2807 strcat (buf, ", LE8");
2808 break;
2809
2810 default:
015dc7e1 2811 unknown = true;
3bfcb652
NC
2812 break;
2813 }
3bfcb652
NC
2814 }
2815 break;
3a4a14e9
PB
2816
2817 case EF_ARM_EABI_VER5:
2818 strcat (buf, ", Version5 EABI");
d507cf36
PB
2819 while (e_flags)
2820 {
2821 unsigned flag;
2822
2823 /* Process flags one bit at a time. */
2824 flag = e_flags & - e_flags;
2825 e_flags &= ~ flag;
2826
2827 switch (flag)
2828 {
2829 case EF_ARM_BE8:
2830 strcat (buf, ", BE8");
2831 break;
2832
2833 case EF_ARM_LE8:
2834 strcat (buf, ", LE8");
2835 break;
2836
3bfcb652
NC
2837 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2838 strcat (buf, ", soft-float ABI");
2839 break;
2840
2841 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2842 strcat (buf, ", hard-float ABI");
2843 break;
2844
d507cf36 2845 default:
015dc7e1 2846 unknown = true;
d507cf36
PB
2847 break;
2848 }
2849 }
2850 break;
2851
f3485b74 2852 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2853 strcat (buf, ", GNU EABI");
f3485b74
NC
2854 while (e_flags)
2855 {
2856 unsigned flag;
76da6bbe 2857
f3485b74
NC
2858 /* Process flags one bit at a time. */
2859 flag = e_flags & - e_flags;
2860 e_flags &= ~ flag;
76da6bbe 2861
f3485b74
NC
2862 switch (flag)
2863 {
a5bcd848 2864 case EF_ARM_INTERWORK:
f3485b74
NC
2865 strcat (buf, ", interworking enabled");
2866 break;
76da6bbe 2867
a5bcd848 2868 case EF_ARM_APCS_26:
f3485b74
NC
2869 strcat (buf, ", uses APCS/26");
2870 break;
76da6bbe 2871
a5bcd848 2872 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2873 strcat (buf, ", uses APCS/float");
2874 break;
76da6bbe 2875
a5bcd848 2876 case EF_ARM_PIC:
f3485b74
NC
2877 strcat (buf, ", position independent");
2878 break;
76da6bbe 2879
a5bcd848 2880 case EF_ARM_ALIGN8:
f3485b74
NC
2881 strcat (buf, ", 8 bit structure alignment");
2882 break;
76da6bbe 2883
a5bcd848 2884 case EF_ARM_NEW_ABI:
f3485b74
NC
2885 strcat (buf, ", uses new ABI");
2886 break;
76da6bbe 2887
a5bcd848 2888 case EF_ARM_OLD_ABI:
f3485b74
NC
2889 strcat (buf, ", uses old ABI");
2890 break;
76da6bbe 2891
a5bcd848 2892 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2893 strcat (buf, ", software FP");
2894 break;
76da6bbe 2895
90e01f86
ILT
2896 case EF_ARM_VFP_FLOAT:
2897 strcat (buf, ", VFP");
2898 break;
2899
fde78edd
NC
2900 case EF_ARM_MAVERICK_FLOAT:
2901 strcat (buf, ", Maverick FP");
2902 break;
2903
f3485b74 2904 default:
015dc7e1 2905 unknown = true;
f3485b74
NC
2906 break;
2907 }
2908 }
2909 }
f3485b74
NC
2910
2911 if (unknown)
2b692964 2912 strcat (buf,_(", <unknown>"));
f3485b74
NC
2913}
2914
343433df
AB
2915static void
2916decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2917{
2918 --size; /* Leave space for null terminator. */
2919
2920 switch (e_flags & EF_AVR_MACH)
2921 {
2922 case E_AVR_MACH_AVR1:
2923 strncat (buf, ", avr:1", size);
2924 break;
2925 case E_AVR_MACH_AVR2:
2926 strncat (buf, ", avr:2", size);
2927 break;
2928 case E_AVR_MACH_AVR25:
2929 strncat (buf, ", avr:25", size);
2930 break;
2931 case E_AVR_MACH_AVR3:
2932 strncat (buf, ", avr:3", size);
2933 break;
2934 case E_AVR_MACH_AVR31:
2935 strncat (buf, ", avr:31", size);
2936 break;
2937 case E_AVR_MACH_AVR35:
2938 strncat (buf, ", avr:35", size);
2939 break;
2940 case E_AVR_MACH_AVR4:
2941 strncat (buf, ", avr:4", size);
2942 break;
2943 case E_AVR_MACH_AVR5:
2944 strncat (buf, ", avr:5", size);
2945 break;
2946 case E_AVR_MACH_AVR51:
2947 strncat (buf, ", avr:51", size);
2948 break;
2949 case E_AVR_MACH_AVR6:
2950 strncat (buf, ", avr:6", size);
2951 break;
2952 case E_AVR_MACH_AVRTINY:
2953 strncat (buf, ", avr:100", size);
2954 break;
2955 case E_AVR_MACH_XMEGA1:
2956 strncat (buf, ", avr:101", size);
2957 break;
2958 case E_AVR_MACH_XMEGA2:
2959 strncat (buf, ", avr:102", size);
2960 break;
2961 case E_AVR_MACH_XMEGA3:
2962 strncat (buf, ", avr:103", size);
2963 break;
2964 case E_AVR_MACH_XMEGA4:
2965 strncat (buf, ", avr:104", size);
2966 break;
2967 case E_AVR_MACH_XMEGA5:
2968 strncat (buf, ", avr:105", size);
2969 break;
2970 case E_AVR_MACH_XMEGA6:
2971 strncat (buf, ", avr:106", size);
2972 break;
2973 case E_AVR_MACH_XMEGA7:
2974 strncat (buf, ", avr:107", size);
2975 break;
2976 default:
2977 strncat (buf, ", avr:<unknown>", size);
2978 break;
2979 }
2980
2981 size -= strlen (buf);
2982 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2983 strncat (buf, ", link-relax", size);
2984}
2985
35c08157
KLC
2986static void
2987decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2988{
2989 unsigned abi;
2990 unsigned arch;
2991 unsigned config;
2992 unsigned version;
015dc7e1 2993 bool has_fpu = false;
32ec8896 2994 unsigned int r = 0;
35c08157
KLC
2995
2996 static const char *ABI_STRINGS[] =
2997 {
2998 "ABI v0", /* use r5 as return register; only used in N1213HC */
2999 "ABI v1", /* use r0 as return register */
3000 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3001 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3002 "AABI",
3003 "ABI2 FP+"
35c08157
KLC
3004 };
3005 static const char *VER_STRINGS[] =
3006 {
3007 "Andes ELF V1.3 or older",
3008 "Andes ELF V1.3.1",
3009 "Andes ELF V1.4"
3010 };
3011 static const char *ARCH_STRINGS[] =
3012 {
3013 "",
3014 "Andes Star v1.0",
3015 "Andes Star v2.0",
3016 "Andes Star v3.0",
3017 "Andes Star v3.0m"
3018 };
3019
3020 abi = EF_NDS_ABI & e_flags;
3021 arch = EF_NDS_ARCH & e_flags;
3022 config = EF_NDS_INST & e_flags;
3023 version = EF_NDS32_ELF_VERSION & e_flags;
3024
3025 memset (buf, 0, size);
3026
3027 switch (abi)
3028 {
3029 case E_NDS_ABI_V0:
3030 case E_NDS_ABI_V1:
3031 case E_NDS_ABI_V2:
3032 case E_NDS_ABI_V2FP:
3033 case E_NDS_ABI_AABI:
40c7a7cb 3034 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3035 /* In case there are holes in the array. */
3036 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3037 break;
3038
3039 default:
3040 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3041 break;
3042 }
3043
3044 switch (version)
3045 {
3046 case E_NDS32_ELF_VER_1_2:
3047 case E_NDS32_ELF_VER_1_3:
3048 case E_NDS32_ELF_VER_1_4:
3049 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3050 break;
3051
3052 default:
3053 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3054 break;
3055 }
3056
3057 if (E_NDS_ABI_V0 == abi)
3058 {
3059 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3060 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3061 if (arch == E_NDS_ARCH_STAR_V1_0)
3062 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3063 return;
3064 }
3065
3066 switch (arch)
3067 {
3068 case E_NDS_ARCH_STAR_V1_0:
3069 case E_NDS_ARCH_STAR_V2_0:
3070 case E_NDS_ARCH_STAR_V3_0:
3071 case E_NDS_ARCH_STAR_V3_M:
3072 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3073 break;
3074
3075 default:
3076 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3077 /* ARCH version determines how the e_flags are interpreted.
3078 If it is unknown, we cannot proceed. */
3079 return;
3080 }
3081
3082 /* Newer ABI; Now handle architecture specific flags. */
3083 if (arch == E_NDS_ARCH_STAR_V1_0)
3084 {
3085 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3086 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3087
3088 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3089 r += snprintf (buf + r, size -r, ", MAC");
3090
3091 if (config & E_NDS32_HAS_DIV_INST)
3092 r += snprintf (buf + r, size -r, ", DIV");
3093
3094 if (config & E_NDS32_HAS_16BIT_INST)
3095 r += snprintf (buf + r, size -r, ", 16b");
3096 }
3097 else
3098 {
3099 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3100 {
3101 if (version <= E_NDS32_ELF_VER_1_3)
3102 r += snprintf (buf + r, size -r, ", [B8]");
3103 else
3104 r += snprintf (buf + r, size -r, ", EX9");
3105 }
3106
3107 if (config & E_NDS32_HAS_MAC_DX_INST)
3108 r += snprintf (buf + r, size -r, ", MAC_DX");
3109
3110 if (config & E_NDS32_HAS_DIV_DX_INST)
3111 r += snprintf (buf + r, size -r, ", DIV_DX");
3112
3113 if (config & E_NDS32_HAS_16BIT_INST)
3114 {
3115 if (version <= E_NDS32_ELF_VER_1_3)
3116 r += snprintf (buf + r, size -r, ", 16b");
3117 else
3118 r += snprintf (buf + r, size -r, ", IFC");
3119 }
3120 }
3121
3122 if (config & E_NDS32_HAS_EXT_INST)
3123 r += snprintf (buf + r, size -r, ", PERF1");
3124
3125 if (config & E_NDS32_HAS_EXT2_INST)
3126 r += snprintf (buf + r, size -r, ", PERF2");
3127
3128 if (config & E_NDS32_HAS_FPU_INST)
3129 {
015dc7e1 3130 has_fpu = true;
35c08157
KLC
3131 r += snprintf (buf + r, size -r, ", FPU_SP");
3132 }
3133
3134 if (config & E_NDS32_HAS_FPU_DP_INST)
3135 {
015dc7e1 3136 has_fpu = true;
35c08157
KLC
3137 r += snprintf (buf + r, size -r, ", FPU_DP");
3138 }
3139
3140 if (config & E_NDS32_HAS_FPU_MAC_INST)
3141 {
015dc7e1 3142 has_fpu = true;
35c08157
KLC
3143 r += snprintf (buf + r, size -r, ", FPU_MAC");
3144 }
3145
3146 if (has_fpu)
3147 {
3148 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3149 {
3150 case E_NDS32_FPU_REG_8SP_4DP:
3151 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3152 break;
3153 case E_NDS32_FPU_REG_16SP_8DP:
3154 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3155 break;
3156 case E_NDS32_FPU_REG_32SP_16DP:
3157 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3158 break;
3159 case E_NDS32_FPU_REG_32SP_32DP:
3160 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3161 break;
3162 }
3163 }
3164
3165 if (config & E_NDS32_HAS_AUDIO_INST)
3166 r += snprintf (buf + r, size -r, ", AUDIO");
3167
3168 if (config & E_NDS32_HAS_STRING_INST)
3169 r += snprintf (buf + r, size -r, ", STR");
3170
3171 if (config & E_NDS32_HAS_REDUCED_REGS)
3172 r += snprintf (buf + r, size -r, ", 16REG");
3173
3174 if (config & E_NDS32_HAS_VIDEO_INST)
3175 {
3176 if (version <= E_NDS32_ELF_VER_1_3)
3177 r += snprintf (buf + r, size -r, ", VIDEO");
3178 else
3179 r += snprintf (buf + r, size -r, ", SATURATION");
3180 }
3181
3182 if (config & E_NDS32_HAS_ENCRIPT_INST)
3183 r += snprintf (buf + r, size -r, ", ENCRP");
3184
3185 if (config & E_NDS32_HAS_L2C_INST)
3186 r += snprintf (buf + r, size -r, ", L2C");
3187}
3188
252b5132 3189static char *
dda8d76d 3190get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3191{
b34976b6 3192 static char buf[1024];
252b5132
RH
3193
3194 buf[0] = '\0';
76da6bbe 3195
252b5132
RH
3196 if (e_flags)
3197 {
3198 switch (e_machine)
3199 {
3200 default:
3201 break;
3202
886a2506 3203 case EM_ARC_COMPACT2:
886a2506 3204 case EM_ARC_COMPACT:
a9522a21
AB
3205 decode_ARC_machine_flags (e_flags, e_machine, buf);
3206 break;
886a2506 3207
f3485b74
NC
3208 case EM_ARM:
3209 decode_ARM_machine_flags (e_flags, buf);
3210 break;
76da6bbe 3211
343433df
AB
3212 case EM_AVR:
3213 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3214 break;
3215
781303ce
MF
3216 case EM_BLACKFIN:
3217 if (e_flags & EF_BFIN_PIC)
3218 strcat (buf, ", PIC");
3219
3220 if (e_flags & EF_BFIN_FDPIC)
3221 strcat (buf, ", FDPIC");
3222
3223 if (e_flags & EF_BFIN_CODE_IN_L1)
3224 strcat (buf, ", code in L1");
3225
3226 if (e_flags & EF_BFIN_DATA_IN_L1)
3227 strcat (buf, ", data in L1");
3228
3229 break;
3230
ec2dfb42
AO
3231 case EM_CYGNUS_FRV:
3232 switch (e_flags & EF_FRV_CPU_MASK)
3233 {
3234 case EF_FRV_CPU_GENERIC:
3235 break;
3236
3237 default:
3238 strcat (buf, ", fr???");
3239 break;
57346661 3240
ec2dfb42
AO
3241 case EF_FRV_CPU_FR300:
3242 strcat (buf, ", fr300");
3243 break;
3244
3245 case EF_FRV_CPU_FR400:
3246 strcat (buf, ", fr400");
3247 break;
3248 case EF_FRV_CPU_FR405:
3249 strcat (buf, ", fr405");
3250 break;
3251
3252 case EF_FRV_CPU_FR450:
3253 strcat (buf, ", fr450");
3254 break;
3255
3256 case EF_FRV_CPU_FR500:
3257 strcat (buf, ", fr500");
3258 break;
3259 case EF_FRV_CPU_FR550:
3260 strcat (buf, ", fr550");
3261 break;
3262
3263 case EF_FRV_CPU_SIMPLE:
3264 strcat (buf, ", simple");
3265 break;
3266 case EF_FRV_CPU_TOMCAT:
3267 strcat (buf, ", tomcat");
3268 break;
3269 }
1c877e87 3270 break;
ec2dfb42 3271
53c7db4b 3272 case EM_68K:
425c6cb0 3273 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3274 strcat (buf, ", m68000");
425c6cb0 3275 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3276 strcat (buf, ", cpu32");
3277 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3278 strcat (buf, ", fido_a");
425c6cb0 3279 else
266abb8f 3280 {
2cf0635d
NC
3281 char const * isa = _("unknown");
3282 char const * mac = _("unknown mac");
3283 char const * additional = NULL;
0112cd26 3284
c694fd50 3285 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3286 {
c694fd50 3287 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3288 isa = "A";
3289 additional = ", nodiv";
3290 break;
c694fd50 3291 case EF_M68K_CF_ISA_A:
266abb8f
NS
3292 isa = "A";
3293 break;
c694fd50 3294 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3295 isa = "A+";
3296 break;
c694fd50 3297 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3298 isa = "B";
3299 additional = ", nousp";
3300 break;
c694fd50 3301 case EF_M68K_CF_ISA_B:
266abb8f
NS
3302 isa = "B";
3303 break;
f608cd77
NS
3304 case EF_M68K_CF_ISA_C:
3305 isa = "C";
3306 break;
3307 case EF_M68K_CF_ISA_C_NODIV:
3308 isa = "C";
3309 additional = ", nodiv";
3310 break;
266abb8f
NS
3311 }
3312 strcat (buf, ", cf, isa ");
3313 strcat (buf, isa);
0b2e31dc
NS
3314 if (additional)
3315 strcat (buf, additional);
c694fd50 3316 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3317 strcat (buf, ", float");
c694fd50 3318 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3319 {
3320 case 0:
3321 mac = NULL;
3322 break;
c694fd50 3323 case EF_M68K_CF_MAC:
266abb8f
NS
3324 mac = "mac";
3325 break;
c694fd50 3326 case EF_M68K_CF_EMAC:
266abb8f
NS
3327 mac = "emac";
3328 break;
f608cd77
NS
3329 case EF_M68K_CF_EMAC_B:
3330 mac = "emac_b";
3331 break;
266abb8f
NS
3332 }
3333 if (mac)
3334 {
3335 strcat (buf, ", ");
3336 strcat (buf, mac);
3337 }
266abb8f 3338 }
53c7db4b 3339 break;
33c63f9d 3340
153a2776
NC
3341 case EM_CYGNUS_MEP:
3342 switch (e_flags & EF_MEP_CPU_MASK)
3343 {
3344 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3345 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3346 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3347 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3348 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3349 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3350 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3351 }
3352
3353 switch (e_flags & EF_MEP_COP_MASK)
3354 {
3355 case EF_MEP_COP_NONE: break;
3356 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3357 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3358 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3359 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3360 default: strcat (buf, _("<unknown MeP copro type>")); break;
3361 }
3362
3363 if (e_flags & EF_MEP_LIBRARY)
3364 strcat (buf, ", Built for Library");
3365
3366 if (e_flags & EF_MEP_INDEX_MASK)
3367 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3368 e_flags & EF_MEP_INDEX_MASK);
3369
3370 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3371 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3372 e_flags & ~ EF_MEP_ALL_FLAGS);
3373 break;
3374
252b5132
RH
3375 case EM_PPC:
3376 if (e_flags & EF_PPC_EMB)
3377 strcat (buf, ", emb");
3378
3379 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3380 strcat (buf, _(", relocatable"));
252b5132
RH
3381
3382 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3383 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3384 break;
3385
ee67d69a
AM
3386 case EM_PPC64:
3387 if (e_flags & EF_PPC64_ABI)
3388 {
3389 char abi[] = ", abiv0";
3390
3391 abi[6] += e_flags & EF_PPC64_ABI;
3392 strcat (buf, abi);
3393 }
3394 break;
3395
708e2187
NC
3396 case EM_V800:
3397 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3398 strcat (buf, ", RH850 ABI");
0b4362b0 3399
708e2187
NC
3400 if (e_flags & EF_V800_850E3)
3401 strcat (buf, ", V3 architecture");
3402
3403 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3404 strcat (buf, ", FPU not used");
3405
3406 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3407 strcat (buf, ", regmode: COMMON");
3408
3409 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3410 strcat (buf, ", r4 not used");
3411
3412 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3413 strcat (buf, ", r30 not used");
3414
3415 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3416 strcat (buf, ", r5 not used");
3417
3418 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3419 strcat (buf, ", r2 not used");
3420
3421 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3422 {
3423 switch (e_flags & - e_flags)
3424 {
3425 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3426 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3427 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3428 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3429 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3430 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3431 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3432 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3433 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3434 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3435 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3436 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3437 default: break;
3438 }
3439 }
3440 break;
3441
2b0337b0 3442 case EM_V850:
252b5132
RH
3443 case EM_CYGNUS_V850:
3444 switch (e_flags & EF_V850_ARCH)
3445 {
78c8d46c
NC
3446 case E_V850E3V5_ARCH:
3447 strcat (buf, ", v850e3v5");
3448 break;
1cd986c5
NC
3449 case E_V850E2V3_ARCH:
3450 strcat (buf, ", v850e2v3");
3451 break;
3452 case E_V850E2_ARCH:
3453 strcat (buf, ", v850e2");
3454 break;
3455 case E_V850E1_ARCH:
3456 strcat (buf, ", v850e1");
8ad30312 3457 break;
252b5132
RH
3458 case E_V850E_ARCH:
3459 strcat (buf, ", v850e");
3460 break;
252b5132
RH
3461 case E_V850_ARCH:
3462 strcat (buf, ", v850");
3463 break;
3464 default:
2b692964 3465 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3466 break;
3467 }
3468 break;
3469
2b0337b0 3470 case EM_M32R:
252b5132
RH
3471 case EM_CYGNUS_M32R:
3472 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3473 strcat (buf, ", m32r");
252b5132
RH
3474 break;
3475
3476 case EM_MIPS:
4fe85591 3477 case EM_MIPS_RS3_LE:
252b5132
RH
3478 if (e_flags & EF_MIPS_NOREORDER)
3479 strcat (buf, ", noreorder");
3480
3481 if (e_flags & EF_MIPS_PIC)
3482 strcat (buf, ", pic");
3483
3484 if (e_flags & EF_MIPS_CPIC)
3485 strcat (buf, ", cpic");
3486
d1bdd336
TS
3487 if (e_flags & EF_MIPS_UCODE)
3488 strcat (buf, ", ugen_reserved");
3489
252b5132
RH
3490 if (e_flags & EF_MIPS_ABI2)
3491 strcat (buf, ", abi2");
3492
43521d43
TS
3493 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3494 strcat (buf, ", odk first");
3495
a5d22d2a
TS
3496 if (e_flags & EF_MIPS_32BITMODE)
3497 strcat (buf, ", 32bitmode");
3498
ba92f887
MR
3499 if (e_flags & EF_MIPS_NAN2008)
3500 strcat (buf, ", nan2008");
3501
fef1b0b3
SE
3502 if (e_flags & EF_MIPS_FP64)
3503 strcat (buf, ", fp64");
3504
156c2f8b
NC
3505 switch ((e_flags & EF_MIPS_MACH))
3506 {
3507 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3508 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3509 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3510 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3511 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3512 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3513 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3514 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3515 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3516 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3517 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3518 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3519 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3520 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3521 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3522 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3523 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3524 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3525 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3526 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3527 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3528 case 0:
3529 /* We simply ignore the field in this case to avoid confusion:
3530 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3531 extension. */
3532 break;
2b692964 3533 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3534 }
43521d43
TS
3535
3536 switch ((e_flags & EF_MIPS_ABI))
3537 {
3538 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3539 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3540 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3541 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3542 case 0:
3543 /* We simply ignore the field in this case to avoid confusion:
3544 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3545 This means it is likely to be an o32 file, but not for
3546 sure. */
3547 break;
2b692964 3548 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3549 }
3550
3551 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3552 strcat (buf, ", mdmx");
3553
3554 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3555 strcat (buf, ", mips16");
3556
df58fc94
RS
3557 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3558 strcat (buf, ", micromips");
3559
43521d43
TS
3560 switch ((e_flags & EF_MIPS_ARCH))
3561 {
3562 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3563 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3564 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3565 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3566 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3567 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3568 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3569 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3570 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3571 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3572 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3573 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3574 }
252b5132 3575 break;
351b4b40 3576
35c08157
KLC
3577 case EM_NDS32:
3578 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3579 break;
3580
fe944acf
FT
3581 case EM_NFP:
3582 switch (EF_NFP_MACH (e_flags))
3583 {
3584 case E_NFP_MACH_3200:
3585 strcat (buf, ", NFP-32xx");
3586 break;
3587 case E_NFP_MACH_6000:
3588 strcat (buf, ", NFP-6xxx");
3589 break;
3590 }
3591 break;
3592
e23eba97
NC
3593 case EM_RISCV:
3594 if (e_flags & EF_RISCV_RVC)
3595 strcat (buf, ", RVC");
2922d21d 3596
7f999549
JW
3597 if (e_flags & EF_RISCV_RVE)
3598 strcat (buf, ", RVE");
3599
2922d21d
AW
3600 switch (e_flags & EF_RISCV_FLOAT_ABI)
3601 {
3602 case EF_RISCV_FLOAT_ABI_SOFT:
3603 strcat (buf, ", soft-float ABI");
3604 break;
3605
3606 case EF_RISCV_FLOAT_ABI_SINGLE:
3607 strcat (buf, ", single-float ABI");
3608 break;
3609
3610 case EF_RISCV_FLOAT_ABI_DOUBLE:
3611 strcat (buf, ", double-float ABI");
3612 break;
3613
3614 case EF_RISCV_FLOAT_ABI_QUAD:
3615 strcat (buf, ", quad-float ABI");
3616 break;
3617 }
e23eba97
NC
3618 break;
3619
ccde1100
AO
3620 case EM_SH:
3621 switch ((e_flags & EF_SH_MACH_MASK))
3622 {
3623 case EF_SH1: strcat (buf, ", sh1"); break;
3624 case EF_SH2: strcat (buf, ", sh2"); break;
3625 case EF_SH3: strcat (buf, ", sh3"); break;
3626 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3627 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3628 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3629 case EF_SH3E: strcat (buf, ", sh3e"); break;
3630 case EF_SH4: strcat (buf, ", sh4"); break;
3631 case EF_SH5: strcat (buf, ", sh5"); break;
3632 case EF_SH2E: strcat (buf, ", sh2e"); break;
3633 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3634 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3635 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3636 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3637 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3638 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3639 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3640 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3641 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3642 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3643 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3644 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3645 }
3646
cec6a5b8
MR
3647 if (e_flags & EF_SH_PIC)
3648 strcat (buf, ", pic");
3649
3650 if (e_flags & EF_SH_FDPIC)
3651 strcat (buf, ", fdpic");
ccde1100 3652 break;
948f632f 3653
73589c9d
CS
3654 case EM_OR1K:
3655 if (e_flags & EF_OR1K_NODELAY)
3656 strcat (buf, ", no delay");
3657 break;
57346661 3658
351b4b40
RH
3659 case EM_SPARCV9:
3660 if (e_flags & EF_SPARC_32PLUS)
3661 strcat (buf, ", v8+");
3662
3663 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3664 strcat (buf, ", ultrasparcI");
3665
3666 if (e_flags & EF_SPARC_SUN_US3)
3667 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3668
3669 if (e_flags & EF_SPARC_HAL_R1)
3670 strcat (buf, ", halr1");
3671
3672 if (e_flags & EF_SPARC_LEDATA)
3673 strcat (buf, ", ledata");
3674
3675 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3676 strcat (buf, ", tso");
3677
3678 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3679 strcat (buf, ", pso");
3680
3681 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3682 strcat (buf, ", rmo");
3683 break;
7d466069 3684
103f02d3
UD
3685 case EM_PARISC:
3686 switch (e_flags & EF_PARISC_ARCH)
3687 {
3688 case EFA_PARISC_1_0:
3689 strcpy (buf, ", PA-RISC 1.0");
3690 break;
3691 case EFA_PARISC_1_1:
3692 strcpy (buf, ", PA-RISC 1.1");
3693 break;
3694 case EFA_PARISC_2_0:
3695 strcpy (buf, ", PA-RISC 2.0");
3696 break;
3697 default:
3698 break;
3699 }
3700 if (e_flags & EF_PARISC_TRAPNIL)
3701 strcat (buf, ", trapnil");
3702 if (e_flags & EF_PARISC_EXT)
3703 strcat (buf, ", ext");
3704 if (e_flags & EF_PARISC_LSB)
3705 strcat (buf, ", lsb");
3706 if (e_flags & EF_PARISC_WIDE)
3707 strcat (buf, ", wide");
3708 if (e_flags & EF_PARISC_NO_KABP)
3709 strcat (buf, ", no kabp");
3710 if (e_flags & EF_PARISC_LAZYSWAP)
3711 strcat (buf, ", lazyswap");
30800947 3712 break;
76da6bbe 3713
7d466069 3714 case EM_PJ:
2b0337b0 3715 case EM_PJ_OLD:
7d466069
ILT
3716 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3717 strcat (buf, ", new calling convention");
3718
3719 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3720 strcat (buf, ", gnu calling convention");
3721 break;
4d6ed7c8
NC
3722
3723 case EM_IA_64:
3724 if ((e_flags & EF_IA_64_ABI64))
3725 strcat (buf, ", 64-bit");
3726 else
3727 strcat (buf, ", 32-bit");
3728 if ((e_flags & EF_IA_64_REDUCEDFP))
3729 strcat (buf, ", reduced fp model");
3730 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3731 strcat (buf, ", no function descriptors, constant gp");
3732 else if ((e_flags & EF_IA_64_CONS_GP))
3733 strcat (buf, ", constant gp");
3734 if ((e_flags & EF_IA_64_ABSOLUTE))
3735 strcat (buf, ", absolute");
dda8d76d 3736 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3737 {
3738 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3739 strcat (buf, ", vms_linkages");
3740 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3741 {
3742 case EF_IA_64_VMS_COMCOD_SUCCESS:
3743 break;
3744 case EF_IA_64_VMS_COMCOD_WARNING:
3745 strcat (buf, ", warning");
3746 break;
3747 case EF_IA_64_VMS_COMCOD_ERROR:
3748 strcat (buf, ", error");
3749 break;
3750 case EF_IA_64_VMS_COMCOD_ABORT:
3751 strcat (buf, ", abort");
3752 break;
3753 default:
bee0ee85
NC
3754 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3755 e_flags & EF_IA_64_VMS_COMCOD);
3756 strcat (buf, ", <unknown>");
28f997cf
TG
3757 }
3758 }
4d6ed7c8 3759 break;
179d3252
JT
3760
3761 case EM_VAX:
3762 if ((e_flags & EF_VAX_NONPIC))
3763 strcat (buf, ", non-PIC");
3764 if ((e_flags & EF_VAX_DFLOAT))
3765 strcat (buf, ", D-Float");
3766 if ((e_flags & EF_VAX_GFLOAT))
3767 strcat (buf, ", G-Float");
3768 break;
c7927a3c 3769
619ed720
EB
3770 case EM_VISIUM:
3771 if (e_flags & EF_VISIUM_ARCH_MCM)
3772 strcat (buf, ", mcm");
3773 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3774 strcat (buf, ", mcm24");
3775 if (e_flags & EF_VISIUM_ARCH_GR6)
3776 strcat (buf, ", gr6");
3777 break;
3778
4046d87a 3779 case EM_RL78:
1740ba0c
NC
3780 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3781 {
3782 case E_FLAG_RL78_ANY_CPU: break;
3783 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3784 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3785 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3786 }
856ea05c
KP
3787 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3788 strcat (buf, ", 64-bit doubles");
4046d87a 3789 break;
0b4362b0 3790
c7927a3c
NC
3791 case EM_RX:
3792 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3793 strcat (buf, ", 64-bit doubles");
3794 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3795 strcat (buf, ", dsp");
d4cb0ea0 3796 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3797 strcat (buf, ", pid");
708e2187
NC
3798 if (e_flags & E_FLAG_RX_ABI)
3799 strcat (buf, ", RX ABI");
3525236c
NC
3800 if (e_flags & E_FLAG_RX_SINSNS_SET)
3801 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3802 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3803 if (e_flags & E_FLAG_RX_V2)
3804 strcat (buf, ", V2");
f87673e0
YS
3805 if (e_flags & E_FLAG_RX_V3)
3806 strcat (buf, ", V3");
d4cb0ea0 3807 break;
55786da2
AK
3808
3809 case EM_S390:
3810 if (e_flags & EF_S390_HIGH_GPRS)
3811 strcat (buf, ", highgprs");
d4cb0ea0 3812 break;
40b36596
JM
3813
3814 case EM_TI_C6000:
3815 if ((e_flags & EF_C6000_REL))
3816 strcat (buf, ", relocatable module");
d4cb0ea0 3817 break;
13761a11
NC
3818
3819 case EM_MSP430:
3820 strcat (buf, _(": architecture variant: "));
3821 switch (e_flags & EF_MSP430_MACH)
3822 {
3823 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3824 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3825 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3826 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3827 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3828 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3829 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3830 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3831 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3832 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3833 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3834 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3835 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3836 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3837 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3838 default:
3839 strcat (buf, _(": unknown")); break;
3840 }
3841
3842 if (e_flags & ~ EF_MSP430_MACH)
3843 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
3844 break;
3845
3846 case EM_Z80:
3847 switch (e_flags & EF_Z80_MACH_MSK)
3848 {
3849 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
3850 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
3851 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
3852 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
3853 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
3854 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 3855 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
3856 default:
3857 strcat (buf, _(", unknown")); break;
3858 }
3859 break;
252b5132
RH
3860 }
3861 }
3862
3863 return buf;
3864}
3865
252b5132 3866static const char *
dda8d76d 3867get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3868{
3869 static char buff[32];
3870
3871 switch (osabi)
3872 {
3873 case ELFOSABI_NONE: return "UNIX - System V";
3874 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3875 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3876 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3877 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3878 case ELFOSABI_AIX: return "UNIX - AIX";
3879 case ELFOSABI_IRIX: return "UNIX - IRIX";
3880 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3881 case ELFOSABI_TRU64: return "UNIX - TRU64";
3882 case ELFOSABI_MODESTO: return "Novell - Modesto";
3883 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3884 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3885 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3886 case ELFOSABI_AROS: return "AROS";
11636f9e 3887 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3888 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3889 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3890 default:
40b36596 3891 if (osabi >= 64)
dda8d76d 3892 switch (filedata->file_header.e_machine)
40b36596
JM
3893 {
3894 case EM_ARM:
3895 switch (osabi)
3896 {
3897 case ELFOSABI_ARM: return "ARM";
18a20338 3898 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3899 default:
3900 break;
3901 }
3902 break;
3903
3904 case EM_MSP430:
3905 case EM_MSP430_OLD:
619ed720 3906 case EM_VISIUM:
40b36596
JM
3907 switch (osabi)
3908 {
3909 case ELFOSABI_STANDALONE: return _("Standalone App");
3910 default:
3911 break;
3912 }
3913 break;
3914
3915 case EM_TI_C6000:
3916 switch (osabi)
3917 {
3918 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3919 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3920 default:
3921 break;
3922 }
3923 break;
3924
3925 default:
3926 break;
3927 }
e9e44622 3928 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3929 return buff;
3930 }
3931}
3932
a06ea964
NC
3933static const char *
3934get_aarch64_segment_type (unsigned long type)
3935{
3936 switch (type)
3937 {
32ec8896
NC
3938 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3939 default: return NULL;
a06ea964 3940 }
a06ea964
NC
3941}
3942
b294bdf8
MM
3943static const char *
3944get_arm_segment_type (unsigned long type)
3945{
3946 switch (type)
3947 {
32ec8896
NC
3948 case PT_ARM_EXIDX: return "EXIDX";
3949 default: return NULL;
b294bdf8 3950 }
b294bdf8
MM
3951}
3952
b4cbbe8f
AK
3953static const char *
3954get_s390_segment_type (unsigned long type)
3955{
3956 switch (type)
3957 {
3958 case PT_S390_PGSTE: return "S390_PGSTE";
3959 default: return NULL;
3960 }
3961}
3962
d3ba0551
AM
3963static const char *
3964get_mips_segment_type (unsigned long type)
252b5132
RH
3965{
3966 switch (type)
3967 {
32ec8896
NC
3968 case PT_MIPS_REGINFO: return "REGINFO";
3969 case PT_MIPS_RTPROC: return "RTPROC";
3970 case PT_MIPS_OPTIONS: return "OPTIONS";
3971 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3972 default: return NULL;
252b5132 3973 }
252b5132
RH
3974}
3975
103f02d3 3976static const char *
d3ba0551 3977get_parisc_segment_type (unsigned long type)
103f02d3
UD
3978{
3979 switch (type)
3980 {
103f02d3
UD
3981 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3982 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3983 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3984 default: return NULL;
103f02d3 3985 }
103f02d3
UD
3986}
3987
4d6ed7c8 3988static const char *
d3ba0551 3989get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3990{
3991 switch (type)
3992 {
3993 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3994 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 3995 default: return NULL;
4d6ed7c8 3996 }
4d6ed7c8
NC
3997}
3998
40b36596
JM
3999static const char *
4000get_tic6x_segment_type (unsigned long type)
4001{
4002 switch (type)
4003 {
32ec8896
NC
4004 case PT_C6000_PHATTR: return "C6000_PHATTR";
4005 default: return NULL;
40b36596 4006 }
40b36596
JM
4007}
4008
df3a023b
AM
4009static const char *
4010get_hpux_segment_type (unsigned long type, unsigned e_machine)
4011{
4012 if (e_machine == EM_PARISC)
4013 switch (type)
4014 {
4015 case PT_HP_TLS: return "HP_TLS";
4016 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4017 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4018 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4019 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4020 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4021 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4022 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4023 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4024 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4025 case PT_HP_PARALLEL: return "HP_PARALLEL";
4026 case PT_HP_FASTBIND: return "HP_FASTBIND";
4027 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4028 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4029 case PT_HP_STACK: return "HP_STACK";
4030 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4031 default: return NULL;
4032 }
4033
4034 if (e_machine == EM_IA_64)
4035 switch (type)
4036 {
4037 case PT_HP_TLS: return "HP_TLS";
4038 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4039 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4040 case PT_IA_64_HP_STACK: return "HP_STACK";
4041 default: return NULL;
4042 }
4043
4044 return NULL;
4045}
4046
5522f910
NC
4047static const char *
4048get_solaris_segment_type (unsigned long type)
4049{
4050 switch (type)
4051 {
4052 case 0x6464e550: return "PT_SUNW_UNWIND";
4053 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4054 case 0x6ffffff7: return "PT_LOSUNW";
4055 case 0x6ffffffa: return "PT_SUNWBSS";
4056 case 0x6ffffffb: return "PT_SUNWSTACK";
4057 case 0x6ffffffc: return "PT_SUNWDTRACE";
4058 case 0x6ffffffd: return "PT_SUNWCAP";
4059 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4060 default: return NULL;
5522f910
NC
4061 }
4062}
4063
252b5132 4064static const char *
dda8d76d 4065get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4066{
b34976b6 4067 static char buff[32];
252b5132
RH
4068
4069 switch (p_type)
4070 {
b34976b6
AM
4071 case PT_NULL: return "NULL";
4072 case PT_LOAD: return "LOAD";
252b5132 4073 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4074 case PT_INTERP: return "INTERP";
4075 case PT_NOTE: return "NOTE";
4076 case PT_SHLIB: return "SHLIB";
4077 case PT_PHDR: return "PHDR";
13ae64f3 4078 case PT_TLS: return "TLS";
32ec8896 4079 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4080 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4081 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4082 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4083
3eba3ef3
NC
4084 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4085 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4086 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4087
252b5132 4088 default:
df3a023b 4089 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4090 {
2cf0635d 4091 const char * result;
103f02d3 4092
dda8d76d 4093 switch (filedata->file_header.e_machine)
252b5132 4094 {
a06ea964
NC
4095 case EM_AARCH64:
4096 result = get_aarch64_segment_type (p_type);
4097 break;
b294bdf8
MM
4098 case EM_ARM:
4099 result = get_arm_segment_type (p_type);
4100 break;
252b5132 4101 case EM_MIPS:
4fe85591 4102 case EM_MIPS_RS3_LE:
252b5132
RH
4103 result = get_mips_segment_type (p_type);
4104 break;
103f02d3
UD
4105 case EM_PARISC:
4106 result = get_parisc_segment_type (p_type);
4107 break;
4d6ed7c8
NC
4108 case EM_IA_64:
4109 result = get_ia64_segment_type (p_type);
4110 break;
40b36596
JM
4111 case EM_TI_C6000:
4112 result = get_tic6x_segment_type (p_type);
4113 break;
b4cbbe8f
AK
4114 case EM_S390:
4115 case EM_S390_OLD:
4116 result = get_s390_segment_type (p_type);
4117 break;
252b5132
RH
4118 default:
4119 result = NULL;
4120 break;
4121 }
103f02d3 4122
252b5132
RH
4123 if (result != NULL)
4124 return result;
103f02d3 4125
1a9ccd70 4126 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4127 }
4128 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4129 {
df3a023b 4130 const char * result = NULL;
103f02d3 4131
df3a023b 4132 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4133 {
df3a023b
AM
4134 case ELFOSABI_GNU:
4135 case ELFOSABI_FREEBSD:
4136 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4137 {
4138 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4139 result = buff;
4140 }
103f02d3 4141 break;
df3a023b
AM
4142 case ELFOSABI_HPUX:
4143 result = get_hpux_segment_type (p_type,
4144 filedata->file_header.e_machine);
4145 break;
4146 case ELFOSABI_SOLARIS:
4147 result = get_solaris_segment_type (p_type);
00428cca 4148 break;
103f02d3 4149 default:
103f02d3
UD
4150 break;
4151 }
103f02d3
UD
4152 if (result != NULL)
4153 return result;
4154
1a9ccd70 4155 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4156 }
252b5132 4157 else
e9e44622 4158 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4159
4160 return buff;
4161 }
4162}
4163
53a346d8
CZ
4164static const char *
4165get_arc_section_type_name (unsigned int sh_type)
4166{
4167 switch (sh_type)
4168 {
4169 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4170 default:
4171 break;
4172 }
4173 return NULL;
4174}
4175
252b5132 4176static const char *
d3ba0551 4177get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4178{
4179 switch (sh_type)
4180 {
b34976b6
AM
4181 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4182 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4183 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4184 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4185 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4186 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4187 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4188 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4189 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4190 case SHT_MIPS_RELD: return "MIPS_RELD";
4191 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4192 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4193 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4194 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4195 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4196 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4197 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4198 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4199 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4200 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4201 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4202 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4203 case SHT_MIPS_LINE: return "MIPS_LINE";
4204 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4205 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4206 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4207 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4208 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4209 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4210 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4211 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4212 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4213 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4214 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4215 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4216 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4217 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4218 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4219 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4220 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4221 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4222 default:
4223 break;
4224 }
4225 return NULL;
4226}
4227
103f02d3 4228static const char *
d3ba0551 4229get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4230{
4231 switch (sh_type)
4232 {
4233 case SHT_PARISC_EXT: return "PARISC_EXT";
4234 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4235 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4236 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4237 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4238 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4239 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4240 default: return NULL;
103f02d3 4241 }
103f02d3
UD
4242}
4243
4d6ed7c8 4244static const char *
dda8d76d 4245get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4246{
18bd398b 4247 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4248 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4249 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4250
4d6ed7c8
NC
4251 switch (sh_type)
4252 {
148b93f2
NC
4253 case SHT_IA_64_EXT: return "IA_64_EXT";
4254 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4255 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4256 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4257 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4258 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4259 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4260 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4261 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4262 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4263 default:
4264 break;
4265 }
4266 return NULL;
4267}
4268
d2b2c203
DJ
4269static const char *
4270get_x86_64_section_type_name (unsigned int sh_type)
4271{
4272 switch (sh_type)
4273 {
4274 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4275 default: return NULL;
d2b2c203 4276 }
d2b2c203
DJ
4277}
4278
a06ea964
NC
4279static const char *
4280get_aarch64_section_type_name (unsigned int sh_type)
4281{
4282 switch (sh_type)
4283 {
32ec8896
NC
4284 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4285 default: return NULL;
a06ea964 4286 }
a06ea964
NC
4287}
4288
40a18ebd
NC
4289static const char *
4290get_arm_section_type_name (unsigned int sh_type)
4291{
4292 switch (sh_type)
4293 {
7f6fed87
NC
4294 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4295 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4296 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4297 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4298 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4299 default: return NULL;
40a18ebd 4300 }
40a18ebd
NC
4301}
4302
40b36596
JM
4303static const char *
4304get_tic6x_section_type_name (unsigned int sh_type)
4305{
4306 switch (sh_type)
4307 {
32ec8896
NC
4308 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4309 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4310 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4311 case SHT_TI_ICODE: return "TI_ICODE";
4312 case SHT_TI_XREF: return "TI_XREF";
4313 case SHT_TI_HANDLER: return "TI_HANDLER";
4314 case SHT_TI_INITINFO: return "TI_INITINFO";
4315 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4316 default: return NULL;
40b36596 4317 }
40b36596
JM
4318}
4319
13761a11 4320static const char *
b0191216 4321get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4322{
4323 switch (sh_type)
4324 {
32ec8896
NC
4325 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4326 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4327 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4328 default: return NULL;
13761a11
NC
4329 }
4330}
4331
fe944acf
FT
4332static const char *
4333get_nfp_section_type_name (unsigned int sh_type)
4334{
4335 switch (sh_type)
4336 {
4337 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4338 case SHT_NFP_INITREG: return "NFP_INITREG";
4339 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4340 default: return NULL;
4341 }
4342}
4343
685080f2
NC
4344static const char *
4345get_v850_section_type_name (unsigned int sh_type)
4346{
4347 switch (sh_type)
4348 {
32ec8896
NC
4349 case SHT_V850_SCOMMON: return "V850 Small Common";
4350 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4351 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4352 case SHT_RENESAS_IOP: return "RENESAS IOP";
4353 case SHT_RENESAS_INFO: return "RENESAS INFO";
4354 default: return NULL;
685080f2
NC
4355 }
4356}
4357
2dc8dd17
JW
4358static const char *
4359get_riscv_section_type_name (unsigned int sh_type)
4360{
4361 switch (sh_type)
4362 {
4363 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4364 default: return NULL;
4365 }
4366}
4367
0861f561
CQ
4368static const char *
4369get_csky_section_type_name (unsigned int sh_type)
4370{
4371 switch (sh_type)
4372 {
4373 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4374 default: return NULL;
4375 }
4376}
4377
252b5132 4378static const char *
dda8d76d 4379get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4380{
b34976b6 4381 static char buff[32];
9fb71ee4 4382 const char * result;
252b5132
RH
4383
4384 switch (sh_type)
4385 {
4386 case SHT_NULL: return "NULL";
4387 case SHT_PROGBITS: return "PROGBITS";
4388 case SHT_SYMTAB: return "SYMTAB";
4389 case SHT_STRTAB: return "STRTAB";
4390 case SHT_RELA: return "RELA";
4391 case SHT_HASH: return "HASH";
4392 case SHT_DYNAMIC: return "DYNAMIC";
4393 case SHT_NOTE: return "NOTE";
4394 case SHT_NOBITS: return "NOBITS";
4395 case SHT_REL: return "REL";
4396 case SHT_SHLIB: return "SHLIB";
4397 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4398 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4399 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4400 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4401 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4402 case SHT_GROUP: return "GROUP";
67ce483b 4403 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4404 case SHT_GNU_verdef: return "VERDEF";
4405 case SHT_GNU_verneed: return "VERNEED";
4406 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4407 case 0x6ffffff0: return "VERSYM";
4408 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4409 case 0x7ffffffd: return "AUXILIARY";
4410 case 0x7fffffff: return "FILTER";
047b2264 4411 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4412
4413 default:
4414 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4415 {
dda8d76d 4416 switch (filedata->file_header.e_machine)
252b5132 4417 {
53a346d8
CZ
4418 case EM_ARC:
4419 case EM_ARC_COMPACT:
4420 case EM_ARC_COMPACT2:
4421 result = get_arc_section_type_name (sh_type);
4422 break;
252b5132 4423 case EM_MIPS:
4fe85591 4424 case EM_MIPS_RS3_LE:
252b5132
RH
4425 result = get_mips_section_type_name (sh_type);
4426 break;
103f02d3
UD
4427 case EM_PARISC:
4428 result = get_parisc_section_type_name (sh_type);
4429 break;
4d6ed7c8 4430 case EM_IA_64:
dda8d76d 4431 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4432 break;
d2b2c203 4433 case EM_X86_64:
8a9036a4 4434 case EM_L1OM:
7a9068fe 4435 case EM_K1OM:
d2b2c203
DJ
4436 result = get_x86_64_section_type_name (sh_type);
4437 break;
a06ea964
NC
4438 case EM_AARCH64:
4439 result = get_aarch64_section_type_name (sh_type);
4440 break;
40a18ebd
NC
4441 case EM_ARM:
4442 result = get_arm_section_type_name (sh_type);
4443 break;
40b36596
JM
4444 case EM_TI_C6000:
4445 result = get_tic6x_section_type_name (sh_type);
4446 break;
13761a11 4447 case EM_MSP430:
b0191216 4448 result = get_msp430_section_type_name (sh_type);
13761a11 4449 break;
fe944acf
FT
4450 case EM_NFP:
4451 result = get_nfp_section_type_name (sh_type);
4452 break;
685080f2
NC
4453 case EM_V800:
4454 case EM_V850:
4455 case EM_CYGNUS_V850:
4456 result = get_v850_section_type_name (sh_type);
4457 break;
2dc8dd17
JW
4458 case EM_RISCV:
4459 result = get_riscv_section_type_name (sh_type);
4460 break;
0861f561
CQ
4461 case EM_CSKY:
4462 result = get_csky_section_type_name (sh_type);
4463 break;
252b5132
RH
4464 default:
4465 result = NULL;
4466 break;
4467 }
4468
4469 if (result != NULL)
4470 return result;
4471
9fb71ee4 4472 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4473 }
4474 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4475 {
dda8d76d 4476 switch (filedata->file_header.e_machine)
148b93f2
NC
4477 {
4478 case EM_IA_64:
dda8d76d 4479 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4480 break;
4481 default:
dda8d76d 4482 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4483 result = get_solaris_section_type (sh_type);
4484 else
1b4b80bf
NC
4485 {
4486 switch (sh_type)
4487 {
4488 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4489 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4490 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4491 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4492 default:
4493 result = NULL;
4494 break;
4495 }
4496 }
148b93f2
NC
4497 break;
4498 }
4499
4500 if (result != NULL)
4501 return result;
4502
9fb71ee4 4503 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4504 }
252b5132 4505 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4506 {
dda8d76d 4507 switch (filedata->file_header.e_machine)
685080f2
NC
4508 {
4509 case EM_V800:
4510 case EM_V850:
4511 case EM_CYGNUS_V850:
9fb71ee4 4512 result = get_v850_section_type_name (sh_type);
a9fb83be 4513 break;
685080f2 4514 default:
9fb71ee4 4515 result = NULL;
685080f2
NC
4516 break;
4517 }
4518
9fb71ee4
NC
4519 if (result != NULL)
4520 return result;
4521
4522 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4523 }
252b5132 4524 else
a7dbfd1c
NC
4525 /* This message is probably going to be displayed in a 15
4526 character wide field, so put the hex value first. */
4527 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4528
252b5132
RH
4529 return buff;
4530 }
4531}
4532
79bc120c
NC
4533enum long_option_values
4534{
4535 OPTION_DEBUG_DUMP = 512,
4536 OPTION_DYN_SYMS,
0f03783c 4537 OPTION_LTO_SYMS,
79bc120c
NC
4538 OPTION_DWARF_DEPTH,
4539 OPTION_DWARF_START,
4540 OPTION_DWARF_CHECK,
4541 OPTION_CTF_DUMP,
4542 OPTION_CTF_PARENT,
4543 OPTION_CTF_SYMBOLS,
4544 OPTION_CTF_STRINGS,
4545 OPTION_WITH_SYMBOL_VERSIONS,
4546 OPTION_RECURSE_LIMIT,
4547 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
4548 OPTION_NO_DEMANGLING,
4549 OPTION_SYM_BASE
79bc120c 4550};
2979dc34 4551
85b1c36d 4552static struct option options[] =
252b5132 4553{
79bc120c
NC
4554 /* Note - This table is alpha-sorted on the 'val'
4555 field in order to make adding new options easier. */
4556 {"arch-specific", no_argument, 0, 'A'},
b34976b6 4557 {"all", no_argument, 0, 'a'},
79bc120c
NC
4558 {"demangle", optional_argument, 0, 'C'},
4559 {"archive-index", no_argument, 0, 'c'},
4560 {"use-dynamic", no_argument, 0, 'D'},
4561 {"dynamic", no_argument, 0, 'd'},
b34976b6 4562 {"headers", no_argument, 0, 'e'},
79bc120c
NC
4563 {"section-groups", no_argument, 0, 'g'},
4564 {"help", no_argument, 0, 'H'},
4565 {"file-header", no_argument, 0, 'h'},
b34976b6 4566 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
4567 {"lint", no_argument, 0, 'L'},
4568 {"enable-checks", no_argument, 0, 'L'},
4569 {"program-headers", no_argument, 0, 'l'},
b34976b6 4570 {"segments", no_argument, 0, 'l'},
595cf52e 4571 {"full-section-name",no_argument, 0, 'N'},
79bc120c 4572 {"notes", no_argument, 0, 'n'},
ca0e11aa 4573 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
4574 {"string-dump", required_argument, 0, 'p'},
4575 {"relocated-dump", required_argument, 0, 'R'},
4576 {"relocs", no_argument, 0, 'r'},
4577 {"section-headers", no_argument, 0, 'S'},
4578 {"sections", no_argument, 0, 'S'},
b34976b6
AM
4579 {"symbols", no_argument, 0, 's'},
4580 {"syms", no_argument, 0, 's'},
79bc120c
NC
4581 {"silent-truncation",no_argument, 0, 'T'},
4582 {"section-details", no_argument, 0, 't'},
09c11c86 4583 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
4584 {"version-info", no_argument, 0, 'V'},
4585 {"version", no_argument, 0, 'v'},
4586 {"wide", no_argument, 0, 'W'},
b34976b6 4587 {"hex-dump", required_argument, 0, 'x'},
0e602686 4588 {"decompress", no_argument, 0, 'z'},
252b5132 4589
79bc120c
NC
4590 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
4591 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
4592 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4593 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4594 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 4595 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 4596 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
4597 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4598 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4599 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 4600#ifdef ENABLE_LIBCTF
d344b407 4601 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
4602 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
4603 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
4604 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 4605#endif
047c3dbf 4606 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 4607
b34976b6 4608 {0, no_argument, 0, 0}
252b5132
RH
4609};
4610
4611static void
2cf0635d 4612usage (FILE * stream)
252b5132 4613{
92f01d61
JM
4614 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4615 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4616 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4617 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4618 -h --file-header Display the ELF file header\n\
4619 -l --program-headers Display the program headers\n\
4620 --segments An alias for --program-headers\n\
4621 -S --section-headers Display the sections' header\n\
4622 --sections An alias for --section-headers\n\
f5842774 4623 -g --section-groups Display the section groups\n\
5477e8a0 4624 -t --section-details Display the section details\n\
8b53311e
NC
4625 -e --headers Equivalent to: -h -l -S\n\
4626 -s --syms Display the symbol table\n\
3f08eb35 4627 --symbols An alias for --syms\n\
1b513401 4628 --dyn-syms Display the dynamic symbol table\n\
0f03783c 4629 --lto-syms Display LTO symbol tables\n\
047c3dbf
NL
4630 --sym-base=[0|8|10|16] \n\
4631 Force base for symbol sizes. The options are \n\
4632 mixed (the default), octal, decimal, hexadecimal.\n\
79bc120c
NC
4633 -C --demangle[=STYLE] Decode low-level symbol names into user-level names\n\
4634 The STYLE, if specified, can be `auto' (the default),\n\
4635 `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
4636 or `gnat'\n\
4637 --no-demangle Do not demangle low-level symbol names. (This is the default)\n\
4638 --recurse-limit Enable a demangling recursion limit. (This is the default)\n\
4639 --no-recurse-limit Disable a demangling recursion limit\n\
8b53311e
NC
4640 -n --notes Display the core notes (if present)\n\
4641 -r --relocs Display the relocations (if present)\n\
4642 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4643 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4644 -V --version-info Display the version sections (if present)\n\
1b31d05e 4645 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4646 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4647 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
1b513401 4648 -L --lint|--enable-checks Display warning messages for possible problems\n\
09c11c86
NC
4649 -x --hex-dump=<number|name>\n\
4650 Dump the contents of section <number|name> as bytes\n\
4651 -p --string-dump=<number|name>\n\
4652 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4653 -R --relocated-dump=<number|name>\n\
4654 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4655 -z --decompress Decompress section before dumping it\n\
ca0e11aa 4656 -w[lLiaprmfFsoORtUuTgAc] or\n\
1ed06042 4657 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
e4b7104b 4658 =frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,\n\
657d0d47 4659 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
ca0e11aa
NC
4660 =addr,=cu_index]\n\
4661 Display the contents of DWARF debug sections\n\
4662 -wk,--debug-dump=links Display the contents of sections that link to separate debuginfo files\n\
4663 -P,--process-links Display the contents of non-debug sections in separate debuginfo files. (Implies -wK)\n"));
c46b7066
NC
4664#if DEFAULT_FOR_FOLLOW_LINKS
4665 fprintf (stream, _("\
4666 -wK,--debug-dump=follow-links Follow links to separate debug info files (default)\n\
4667 -wN,--debug-dump=no-follow-links Do not follow links to separate debug info files\n\
4668"));
4669#else
4670 fprintf (stream, _("\
4671 -wK,--debug-dump=follow-links Follow links to separate debug info files\n\
4672 -wN,--debug-dump=no-follow-links Do not follow links to separate debug info files (default)\n\
4673"));
4674#endif
fd2f0033
TT
4675 fprintf (stream, _("\
4676 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4677 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4678 or deeper\n"));
094e34f2 4679#ifdef ENABLE_LIBCTF
7d9813f1
NA
4680 fprintf (stream, _("\
4681 --ctf=<number|name> Display CTF info from section <number|name>\n\
4682 --ctf-parent=<number|name>\n\
4683 Use section <number|name> as the CTF parent\n\n\
4684 --ctf-symbols=<number|name>\n\
4685 Use section <number|name> as the CTF external symtab\n\n\
4686 --ctf-strings=<number|name>\n\
4687 Use section <number|name> as the CTF external strtab\n\n"));
094e34f2 4688#endif
7d9813f1 4689
252b5132 4690#ifdef SUPPORT_DISASSEMBLY
92f01d61 4691 fprintf (stream, _("\
09c11c86
NC
4692 -i --instruction-dump=<number|name>\n\
4693 Disassemble the contents of section <number|name>\n"));
252b5132 4694#endif
92f01d61 4695 fprintf (stream, _("\
8b53311e
NC
4696 -I --histogram Display histogram of bucket list lengths\n\
4697 -W --wide Allow output width to exceed 80 characters\n\
0942c7ab 4698 -T --silent-truncation If a symbol name is truncated, do not add a suffix [...]\n\
07012eee 4699 @<file> Read options from <file>\n\
8b53311e
NC
4700 -H --help Display this information\n\
4701 -v --version Display the version number of readelf\n"));
1118d252 4702
92f01d61
JM
4703 if (REPORT_BUGS_TO[0] && stream == stdout)
4704 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4705
92f01d61 4706 exit (stream == stdout ? 0 : 1);
252b5132
RH
4707}
4708
18bd398b
NC
4709/* Record the fact that the user wants the contents of section number
4710 SECTION to be displayed using the method(s) encoded as flags bits
4711 in TYPE. Note, TYPE can be zero if we are creating the array for
4712 the first time. */
4713
252b5132 4714static void
6431e409
AM
4715request_dump_bynumber (struct dump_data *dumpdata,
4716 unsigned int section, dump_type type)
252b5132 4717{
6431e409 4718 if (section >= dumpdata->num_dump_sects)
252b5132 4719 {
2cf0635d 4720 dump_type * new_dump_sects;
252b5132 4721
3f5e193b 4722 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4723 sizeof (* new_dump_sects));
252b5132
RH
4724
4725 if (new_dump_sects == NULL)
591a748a 4726 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4727 else
4728 {
6431e409 4729 if (dumpdata->dump_sects)
21b65bac
NC
4730 {
4731 /* Copy current flag settings. */
6431e409
AM
4732 memcpy (new_dump_sects, dumpdata->dump_sects,
4733 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4734
6431e409 4735 free (dumpdata->dump_sects);
21b65bac 4736 }
252b5132 4737
6431e409
AM
4738 dumpdata->dump_sects = new_dump_sects;
4739 dumpdata->num_dump_sects = section + 1;
252b5132
RH
4740 }
4741 }
4742
6431e409
AM
4743 if (dumpdata->dump_sects)
4744 dumpdata->dump_sects[section] |= type;
252b5132
RH
4745}
4746
aef1f6d0
DJ
4747/* Request a dump by section name. */
4748
4749static void
2cf0635d 4750request_dump_byname (const char * section, dump_type type)
aef1f6d0 4751{
2cf0635d 4752 struct dump_list_entry * new_request;
aef1f6d0 4753
3f5e193b
NC
4754 new_request = (struct dump_list_entry *)
4755 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4756 if (!new_request)
591a748a 4757 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4758
4759 new_request->name = strdup (section);
4760 if (!new_request->name)
591a748a 4761 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4762
4763 new_request->type = type;
4764
4765 new_request->next = dump_sects_byname;
4766 dump_sects_byname = new_request;
4767}
4768
cf13d699 4769static inline void
6431e409 4770request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
4771{
4772 int section;
4773 char * cp;
4774
015dc7e1 4775 do_dump = true;
cf13d699
NC
4776 section = strtoul (optarg, & cp, 0);
4777
4778 if (! *cp && section >= 0)
6431e409 4779 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
4780 else
4781 request_dump_byname (optarg, type);
4782}
4783
252b5132 4784static void
6431e409 4785parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
4786{
4787 int c;
4788
4789 if (argc < 2)
92f01d61 4790 usage (stderr);
252b5132
RH
4791
4792 while ((c = getopt_long
ca0e11aa 4793 (argc, argv, "ACDHILNPR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4794 {
252b5132
RH
4795 switch (c)
4796 {
4797 case 0:
4798 /* Long options. */
4799 break;
4800 case 'H':
92f01d61 4801 usage (stdout);
252b5132
RH
4802 break;
4803
4804 case 'a':
015dc7e1
AM
4805 do_syms = true;
4806 do_reloc = true;
4807 do_unwind = true;
4808 do_dynamic = true;
4809 do_header = true;
4810 do_sections = true;
4811 do_section_groups = true;
4812 do_segments = true;
4813 do_version = true;
4814 do_histogram = true;
4815 do_arch = true;
4816 do_notes = true;
252b5132 4817 break;
79bc120c 4818
f5842774 4819 case 'g':
015dc7e1 4820 do_section_groups = true;
f5842774 4821 break;
5477e8a0 4822 case 't':
595cf52e 4823 case 'N':
015dc7e1
AM
4824 do_sections = true;
4825 do_section_details = true;
595cf52e 4826 break;
252b5132 4827 case 'e':
015dc7e1
AM
4828 do_header = true;
4829 do_sections = true;
4830 do_segments = true;
252b5132 4831 break;
a952a375 4832 case 'A':
015dc7e1 4833 do_arch = true;
a952a375 4834 break;
252b5132 4835 case 'D':
015dc7e1 4836 do_using_dynamic = true;
252b5132
RH
4837 break;
4838 case 'r':
015dc7e1 4839 do_reloc = true;
252b5132 4840 break;
4d6ed7c8 4841 case 'u':
015dc7e1 4842 do_unwind = true;
4d6ed7c8 4843 break;
252b5132 4844 case 'h':
015dc7e1 4845 do_header = true;
252b5132
RH
4846 break;
4847 case 'l':
015dc7e1 4848 do_segments = true;
252b5132
RH
4849 break;
4850 case 's':
015dc7e1 4851 do_syms = true;
252b5132
RH
4852 break;
4853 case 'S':
015dc7e1 4854 do_sections = true;
252b5132
RH
4855 break;
4856 case 'd':
015dc7e1 4857 do_dynamic = true;
252b5132 4858 break;
a952a375 4859 case 'I':
015dc7e1 4860 do_histogram = true;
a952a375 4861 break;
779fe533 4862 case 'n':
015dc7e1 4863 do_notes = true;
779fe533 4864 break;
4145f1d5 4865 case 'c':
015dc7e1 4866 do_archive_index = true;
4145f1d5 4867 break;
1b513401 4868 case 'L':
015dc7e1 4869 do_checks = true;
1b513401 4870 break;
ca0e11aa 4871 case 'P':
015dc7e1
AM
4872 process_links = true;
4873 do_follow_links = true;
ca0e11aa 4874 break;
252b5132 4875 case 'x':
6431e409 4876 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 4877 break;
09c11c86 4878 case 'p':
6431e409 4879 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
4880 break;
4881 case 'R':
6431e409 4882 request_dump (dumpdata, RELOC_DUMP);
09c11c86 4883 break;
0e602686 4884 case 'z':
015dc7e1 4885 decompress_dumps = true;
0e602686 4886 break;
252b5132 4887 case 'w':
015dc7e1 4888 do_dump = true;
0f03783c 4889 if (optarg == NULL)
613ff48b 4890 {
015dc7e1 4891 do_debugging = true;
613ff48b
CC
4892 dwarf_select_sections_all ();
4893 }
252b5132
RH
4894 else
4895 {
015dc7e1 4896 do_debugging = false;
4cb93e3b 4897 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4898 }
4899 break;
2979dc34 4900 case OPTION_DEBUG_DUMP:
015dc7e1 4901 do_dump = true;
0f03783c 4902 if (optarg == NULL)
015dc7e1 4903 do_debugging = true;
2979dc34
JJ
4904 else
4905 {
015dc7e1 4906 do_debugging = false;
4cb93e3b 4907 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4908 }
4909 break;
fd2f0033
TT
4910 case OPTION_DWARF_DEPTH:
4911 {
4912 char *cp;
4913
4914 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4915 }
4916 break;
4917 case OPTION_DWARF_START:
4918 {
4919 char *cp;
4920
4921 dwarf_start_die = strtoul (optarg, & cp, 0);
4922 }
4923 break;
4723351a 4924 case OPTION_DWARF_CHECK:
015dc7e1 4925 dwarf_check = true;
4723351a 4926 break;
7d9813f1 4927 case OPTION_CTF_DUMP:
015dc7e1 4928 do_ctf = true;
6431e409 4929 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
4930 break;
4931 case OPTION_CTF_SYMBOLS:
df16e041 4932 free (dump_ctf_symtab_name);
7d9813f1
NA
4933 dump_ctf_symtab_name = strdup (optarg);
4934 break;
4935 case OPTION_CTF_STRINGS:
df16e041 4936 free (dump_ctf_strtab_name);
7d9813f1
NA
4937 dump_ctf_strtab_name = strdup (optarg);
4938 break;
4939 case OPTION_CTF_PARENT:
df16e041 4940 free (dump_ctf_parent_name);
7d9813f1
NA
4941 dump_ctf_parent_name = strdup (optarg);
4942 break;
2c610e4b 4943 case OPTION_DYN_SYMS:
015dc7e1 4944 do_dyn_syms = true;
2c610e4b 4945 break;
0f03783c 4946 case OPTION_LTO_SYMS:
015dc7e1 4947 do_lto_syms = true;
0f03783c 4948 break;
252b5132
RH
4949#ifdef SUPPORT_DISASSEMBLY
4950 case 'i':
6431e409 4951 request_dump (dumpdata, DISASS_DUMP);
cf13d699 4952 break;
252b5132
RH
4953#endif
4954 case 'v':
4955 print_version (program_name);
4956 break;
4957 case 'V':
015dc7e1 4958 do_version = true;
252b5132 4959 break;
d974e256 4960 case 'W':
015dc7e1 4961 do_wide = true;
d974e256 4962 break;
0942c7ab 4963 case 'T':
015dc7e1 4964 do_not_show_symbol_truncation = true;
0942c7ab 4965 break;
79bc120c 4966 case 'C':
015dc7e1 4967 do_demangle = true;
79bc120c
NC
4968 if (optarg != NULL)
4969 {
4970 enum demangling_styles style;
4971
4972 style = cplus_demangle_name_to_style (optarg);
4973 if (style == unknown_demangling)
4974 error (_("unknown demangling style `%s'"), optarg);
4975
4976 cplus_demangle_set_style (style);
4977 }
4978 break;
4979 case OPTION_NO_DEMANGLING:
015dc7e1 4980 do_demangle = false;
79bc120c
NC
4981 break;
4982 case OPTION_RECURSE_LIMIT:
4983 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
4984 break;
4985 case OPTION_NO_RECURSE_LIMIT:
4986 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
4987 break;
4988 case OPTION_WITH_SYMBOL_VERSIONS:
4989 /* Ignored for backward compatibility. */
4990 break;
b9e920ec 4991
047c3dbf
NL
4992 case OPTION_SYM_BASE:
4993 sym_base = 0;
4994 if (optarg != NULL)
4995 {
4996 sym_base = strtoul (optarg, NULL, 0);
4997 switch (sym_base)
4998 {
4999 case 0:
5000 case 8:
5001 case 10:
5002 case 16:
5003 break;
5004
5005 default:
5006 sym_base = 0;
5007 break;
5008 }
5009 }
5010 break;
5011
252b5132 5012 default:
252b5132
RH
5013 /* xgettext:c-format */
5014 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5015 /* Fall through. */
252b5132 5016 case '?':
92f01d61 5017 usage (stderr);
252b5132
RH
5018 }
5019 }
5020
4d6ed7c8 5021 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5022 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5023 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5024 && !do_section_groups && !do_archive_index
0f03783c 5025 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5026 {
5027 if (do_checks)
5028 {
015dc7e1
AM
5029 check_all = true;
5030 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5031 do_segments = do_header = do_dump = do_version = true;
5032 do_histogram = do_debugging = do_arch = do_notes = true;
5033 do_section_groups = do_archive_index = do_dyn_syms = true;
5034 do_lto_syms = true;
1b513401
NC
5035 }
5036 else
5037 usage (stderr);
5038 }
252b5132
RH
5039}
5040
5041static const char *
d3ba0551 5042get_elf_class (unsigned int elf_class)
252b5132 5043{
b34976b6 5044 static char buff[32];
103f02d3 5045
252b5132
RH
5046 switch (elf_class)
5047 {
5048 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5049 case ELFCLASS32: return "ELF32";
5050 case ELFCLASS64: return "ELF64";
ab5e7794 5051 default:
e9e44622 5052 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5053 return buff;
252b5132
RH
5054 }
5055}
5056
5057static const char *
d3ba0551 5058get_data_encoding (unsigned int encoding)
252b5132 5059{
b34976b6 5060 static char buff[32];
103f02d3 5061
252b5132
RH
5062 switch (encoding)
5063 {
5064 case ELFDATANONE: return _("none");
33c63f9d
CM
5065 case ELFDATA2LSB: return _("2's complement, little endian");
5066 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5067 default:
e9e44622 5068 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5069 return buff;
252b5132
RH
5070 }
5071}
5072
dda8d76d 5073/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5074
015dc7e1 5075static bool
dda8d76d 5076process_file_header (Filedata * filedata)
252b5132 5077{
dda8d76d
NC
5078 Elf_Internal_Ehdr * header = & filedata->file_header;
5079
5080 if ( header->e_ident[EI_MAG0] != ELFMAG0
5081 || header->e_ident[EI_MAG1] != ELFMAG1
5082 || header->e_ident[EI_MAG2] != ELFMAG2
5083 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5084 {
5085 error
5086 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
015dc7e1 5087 return false;
252b5132
RH
5088 }
5089
ca0e11aa
NC
5090 if (! filedata->is_separate)
5091 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5092
252b5132
RH
5093 if (do_header)
5094 {
32ec8896 5095 unsigned i;
252b5132 5096
ca0e11aa
NC
5097 if (filedata->is_separate)
5098 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5099 else
5100 printf (_("ELF Header:\n"));
252b5132 5101 printf (_(" Magic: "));
b34976b6 5102 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5103 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5104 printf ("\n");
5105 printf (_(" Class: %s\n"),
dda8d76d 5106 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5107 printf (_(" Data: %s\n"),
dda8d76d 5108 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5109 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5110 header->e_ident[EI_VERSION],
5111 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5112 ? _(" (current)")
dda8d76d 5113 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5114 ? _(" <unknown>")
789be9f7 5115 : "")));
252b5132 5116 printf (_(" OS/ABI: %s\n"),
dda8d76d 5117 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5118 printf (_(" ABI Version: %d\n"),
dda8d76d 5119 header->e_ident[EI_ABIVERSION]);
252b5132 5120 printf (_(" Type: %s\n"),
dda8d76d 5121 get_file_type (header->e_type));
252b5132 5122 printf (_(" Machine: %s\n"),
dda8d76d 5123 get_machine_name (header->e_machine));
252b5132 5124 printf (_(" Version: 0x%lx\n"),
e8a64888 5125 header->e_version);
76da6bbe 5126
f7a99963 5127 printf (_(" Entry point address: "));
e8a64888 5128 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5129 printf (_("\n Start of program headers: "));
e8a64888 5130 print_vma (header->e_phoff, DEC);
f7a99963 5131 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5132 print_vma (header->e_shoff, DEC);
f7a99963 5133 printf (_(" (bytes into file)\n"));
76da6bbe 5134
252b5132 5135 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5136 header->e_flags,
dda8d76d 5137 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5138 printf (_(" Size of this header: %u (bytes)\n"),
5139 header->e_ehsize);
5140 printf (_(" Size of program headers: %u (bytes)\n"),
5141 header->e_phentsize);
5142 printf (_(" Number of program headers: %u"),
5143 header->e_phnum);
dda8d76d
NC
5144 if (filedata->section_headers != NULL
5145 && header->e_phnum == PN_XNUM
5146 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
5147 {
5148 header->e_phnum = filedata->section_headers[0].sh_info;
5149 printf (" (%u)", header->e_phnum);
5150 }
2046a35d 5151 putc ('\n', stdout);
e8a64888
AM
5152 printf (_(" Size of section headers: %u (bytes)\n"),
5153 header->e_shentsize);
5154 printf (_(" Number of section headers: %u"),
5155 header->e_shnum);
dda8d76d 5156 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5157 {
5158 header->e_shnum = filedata->section_headers[0].sh_size;
5159 printf (" (%u)", header->e_shnum);
5160 }
560f3c1c 5161 putc ('\n', stdout);
e8a64888
AM
5162 printf (_(" Section header string table index: %u"),
5163 header->e_shstrndx);
dda8d76d
NC
5164 if (filedata->section_headers != NULL
5165 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5166 {
5167 header->e_shstrndx = filedata->section_headers[0].sh_link;
5168 printf (" (%u)", header->e_shstrndx);
5169 }
5170 if (header->e_shstrndx != SHN_UNDEF
5171 && header->e_shstrndx >= header->e_shnum)
5172 {
5173 header->e_shstrndx = SHN_UNDEF;
5174 printf (_(" <corrupt: out of range>"));
5175 }
560f3c1c
AM
5176 putc ('\n', stdout);
5177 }
5178
dda8d76d 5179 if (filedata->section_headers != NULL)
560f3c1c 5180 {
dda8d76d
NC
5181 if (header->e_phnum == PN_XNUM
5182 && filedata->section_headers[0].sh_info != 0)
5183 header->e_phnum = filedata->section_headers[0].sh_info;
5184 if (header->e_shnum == SHN_UNDEF)
5185 header->e_shnum = filedata->section_headers[0].sh_size;
5186 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5187 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5188 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
5189 header->e_shstrndx = SHN_UNDEF;
5190 free (filedata->section_headers);
5191 filedata->section_headers = NULL;
252b5132 5192 }
103f02d3 5193
015dc7e1 5194 return true;
9ea033b2
NC
5195}
5196
dda8d76d
NC
5197/* Read in the program headers from FILEDATA and store them in PHEADERS.
5198 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5199
015dc7e1 5200static bool
dda8d76d 5201get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5202{
2cf0635d
NC
5203 Elf32_External_Phdr * phdrs;
5204 Elf32_External_Phdr * external;
5205 Elf_Internal_Phdr * internal;
b34976b6 5206 unsigned int i;
dda8d76d
NC
5207 unsigned int size = filedata->file_header.e_phentsize;
5208 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5209
5210 /* PR binutils/17531: Cope with unexpected section header sizes. */
5211 if (size == 0 || num == 0)
015dc7e1 5212 return false;
e0a31db1
NC
5213 if (size < sizeof * phdrs)
5214 {
5215 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5216 return false;
e0a31db1
NC
5217 }
5218 if (size > sizeof * phdrs)
5219 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5220
dda8d76d 5221 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5222 size, num, _("program headers"));
5223 if (phdrs == NULL)
015dc7e1 5224 return false;
9ea033b2 5225
91d6fa6a 5226 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5227 i < filedata->file_header.e_phnum;
b34976b6 5228 i++, internal++, external++)
252b5132 5229 {
9ea033b2
NC
5230 internal->p_type = BYTE_GET (external->p_type);
5231 internal->p_offset = BYTE_GET (external->p_offset);
5232 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5233 internal->p_paddr = BYTE_GET (external->p_paddr);
5234 internal->p_filesz = BYTE_GET (external->p_filesz);
5235 internal->p_memsz = BYTE_GET (external->p_memsz);
5236 internal->p_flags = BYTE_GET (external->p_flags);
5237 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5238 }
5239
9ea033b2 5240 free (phdrs);
015dc7e1 5241 return true;
252b5132
RH
5242}
5243
dda8d76d
NC
5244/* Read in the program headers from FILEDATA and store them in PHEADERS.
5245 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5246
015dc7e1 5247static bool
dda8d76d 5248get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5249{
2cf0635d
NC
5250 Elf64_External_Phdr * phdrs;
5251 Elf64_External_Phdr * external;
5252 Elf_Internal_Phdr * internal;
b34976b6 5253 unsigned int i;
dda8d76d
NC
5254 unsigned int size = filedata->file_header.e_phentsize;
5255 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5256
5257 /* PR binutils/17531: Cope with unexpected section header sizes. */
5258 if (size == 0 || num == 0)
015dc7e1 5259 return false;
e0a31db1
NC
5260 if (size < sizeof * phdrs)
5261 {
5262 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5263 return false;
e0a31db1
NC
5264 }
5265 if (size > sizeof * phdrs)
5266 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5267
dda8d76d 5268 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5269 size, num, _("program headers"));
a6e9f9df 5270 if (!phdrs)
015dc7e1 5271 return false;
9ea033b2 5272
91d6fa6a 5273 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5274 i < filedata->file_header.e_phnum;
b34976b6 5275 i++, internal++, external++)
9ea033b2
NC
5276 {
5277 internal->p_type = BYTE_GET (external->p_type);
5278 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5279 internal->p_offset = BYTE_GET (external->p_offset);
5280 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5281 internal->p_paddr = BYTE_GET (external->p_paddr);
5282 internal->p_filesz = BYTE_GET (external->p_filesz);
5283 internal->p_memsz = BYTE_GET (external->p_memsz);
5284 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5285 }
5286
5287 free (phdrs);
015dc7e1 5288 return true;
9ea033b2 5289}
252b5132 5290
32ec8896 5291/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5292
015dc7e1 5293static bool
dda8d76d 5294get_program_headers (Filedata * filedata)
d93f0186 5295{
2cf0635d 5296 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5297
5298 /* Check cache of prior read. */
dda8d76d 5299 if (filedata->program_headers != NULL)
015dc7e1 5300 return true;
d93f0186 5301
82156ab7
NC
5302 /* Be kind to memory checkers by looking for
5303 e_phnum values which we know must be invalid. */
dda8d76d 5304 if (filedata->file_header.e_phnum
82156ab7 5305 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5306 >= filedata->file_size)
82156ab7
NC
5307 {
5308 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5309 filedata->file_header.e_phnum);
015dc7e1 5310 return false;
82156ab7 5311 }
d93f0186 5312
dda8d76d 5313 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5314 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5315 if (phdrs == NULL)
5316 {
8b73c356 5317 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5318 filedata->file_header.e_phnum);
015dc7e1 5319 return false;
d93f0186
NC
5320 }
5321
5322 if (is_32bit_elf
dda8d76d
NC
5323 ? get_32bit_program_headers (filedata, phdrs)
5324 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5325 {
dda8d76d 5326 filedata->program_headers = phdrs;
015dc7e1 5327 return true;
d93f0186
NC
5328 }
5329
5330 free (phdrs);
015dc7e1 5331 return false;
d93f0186
NC
5332}
5333
32ec8896 5334/* Returns TRUE if the program headers were loaded. */
2f62977e 5335
015dc7e1 5336static bool
dda8d76d 5337process_program_headers (Filedata * filedata)
252b5132 5338{
2cf0635d 5339 Elf_Internal_Phdr * segment;
b34976b6 5340 unsigned int i;
1a9ccd70 5341 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5342
978c4450
AM
5343 filedata->dynamic_addr = 0;
5344 filedata->dynamic_size = 0;
663f67df 5345
dda8d76d 5346 if (filedata->file_header.e_phnum == 0)
252b5132 5347 {
82f2dbf7 5348 /* PR binutils/12467. */
dda8d76d 5349 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5350 {
5351 warn (_("possibly corrupt ELF header - it has a non-zero program"
5352 " header offset, but no program headers\n"));
015dc7e1 5353 return false;
32ec8896 5354 }
82f2dbf7 5355 else if (do_segments)
ca0e11aa
NC
5356 {
5357 if (filedata->is_separate)
5358 printf (_("\nThere are no program headers in linked file '%s'.\n"),
5359 filedata->file_name);
5360 else
5361 printf (_("\nThere are no program headers in this file.\n"));
5362 }
015dc7e1 5363 return true;
252b5132
RH
5364 }
5365
5366 if (do_segments && !do_header)
5367 {
ca0e11aa
NC
5368 if (filedata->is_separate)
5369 printf ("\nIn linked file '%s' the ELF file type is %s\n",
5370 filedata->file_name,
5371 get_file_type (filedata->file_header.e_type));
5372 else
5373 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
dda8d76d 5374 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5375 printf (ngettext ("There is %d program header, starting at offset %s\n",
5376 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5377 filedata->file_header.e_phnum),
5378 filedata->file_header.e_phnum,
5379 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5380 }
5381
dda8d76d 5382 if (! get_program_headers (filedata))
015dc7e1 5383 return true;
103f02d3 5384
252b5132
RH
5385 if (do_segments)
5386 {
dda8d76d 5387 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5388 printf (_("\nProgram Headers:\n"));
5389 else
5390 printf (_("\nProgram Headers:\n"));
76da6bbe 5391
f7a99963
NC
5392 if (is_32bit_elf)
5393 printf
5394 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5395 else if (do_wide)
5396 printf
5397 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5398 else
5399 {
5400 printf
5401 (_(" Type Offset VirtAddr PhysAddr\n"));
5402 printf
5403 (_(" FileSiz MemSiz Flags Align\n"));
5404 }
252b5132
RH
5405 }
5406
dda8d76d
NC
5407 for (i = 0, segment = filedata->program_headers;
5408 i < filedata->file_header.e_phnum;
b34976b6 5409 i++, segment++)
252b5132
RH
5410 {
5411 if (do_segments)
5412 {
dda8d76d 5413 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5414
5415 if (is_32bit_elf)
5416 {
5417 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5418 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5419 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5420 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5421 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5422 printf ("%c%c%c ",
5423 (segment->p_flags & PF_R ? 'R' : ' '),
5424 (segment->p_flags & PF_W ? 'W' : ' '),
5425 (segment->p_flags & PF_X ? 'E' : ' '));
5426 printf ("%#lx", (unsigned long) segment->p_align);
5427 }
d974e256
JJ
5428 else if (do_wide)
5429 {
5430 if ((unsigned long) segment->p_offset == segment->p_offset)
5431 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5432 else
5433 {
5434 print_vma (segment->p_offset, FULL_HEX);
5435 putchar (' ');
5436 }
5437
5438 print_vma (segment->p_vaddr, FULL_HEX);
5439 putchar (' ');
5440 print_vma (segment->p_paddr, FULL_HEX);
5441 putchar (' ');
5442
5443 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5444 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5445 else
5446 {
5447 print_vma (segment->p_filesz, FULL_HEX);
5448 putchar (' ');
5449 }
5450
5451 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5452 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5453 else
5454 {
f48e6c45 5455 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5456 }
5457
5458 printf (" %c%c%c ",
5459 (segment->p_flags & PF_R ? 'R' : ' '),
5460 (segment->p_flags & PF_W ? 'W' : ' '),
5461 (segment->p_flags & PF_X ? 'E' : ' '));
5462
5463 if ((unsigned long) segment->p_align == segment->p_align)
5464 printf ("%#lx", (unsigned long) segment->p_align);
5465 else
5466 {
5467 print_vma (segment->p_align, PREFIX_HEX);
5468 }
5469 }
f7a99963
NC
5470 else
5471 {
5472 print_vma (segment->p_offset, FULL_HEX);
5473 putchar (' ');
5474 print_vma (segment->p_vaddr, FULL_HEX);
5475 putchar (' ');
5476 print_vma (segment->p_paddr, FULL_HEX);
5477 printf ("\n ");
5478 print_vma (segment->p_filesz, FULL_HEX);
5479 putchar (' ');
5480 print_vma (segment->p_memsz, FULL_HEX);
5481 printf (" %c%c%c ",
5482 (segment->p_flags & PF_R ? 'R' : ' '),
5483 (segment->p_flags & PF_W ? 'W' : ' '),
5484 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5485 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5486 }
252b5132 5487
1a9ccd70
NC
5488 putc ('\n', stdout);
5489 }
f54498b4 5490
252b5132
RH
5491 switch (segment->p_type)
5492 {
1a9ccd70 5493 case PT_LOAD:
502d895c
NC
5494#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5495 required by the ELF standard, several programs, including the Linux
5496 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5497 if (previous_load
5498 && previous_load->p_vaddr > segment->p_vaddr)
5499 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5500#endif
1a9ccd70
NC
5501 if (segment->p_memsz < segment->p_filesz)
5502 error (_("the segment's file size is larger than its memory size\n"));
5503 previous_load = segment;
5504 break;
5505
5506 case PT_PHDR:
5507 /* PR 20815 - Verify that the program header is loaded into memory. */
5508 if (i > 0 && previous_load != NULL)
5509 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5510 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5511 {
5512 unsigned int j;
5513
dda8d76d 5514 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5515 {
5516 Elf_Internal_Phdr *load = filedata->program_headers + j;
5517 if (load->p_type == PT_LOAD
5518 && load->p_offset <= segment->p_offset
5519 && (load->p_offset + load->p_filesz
5520 >= segment->p_offset + segment->p_filesz)
5521 && load->p_vaddr <= segment->p_vaddr
5522 && (load->p_vaddr + load->p_filesz
5523 >= segment->p_vaddr + segment->p_filesz))
5524 break;
5525 }
dda8d76d 5526 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5527 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5528 }
5529 break;
5530
252b5132 5531 case PT_DYNAMIC:
978c4450 5532 if (filedata->dynamic_addr)
252b5132
RH
5533 error (_("more than one dynamic segment\n"));
5534
20737c13
AM
5535 /* By default, assume that the .dynamic section is the first
5536 section in the DYNAMIC segment. */
978c4450
AM
5537 filedata->dynamic_addr = segment->p_offset;
5538 filedata->dynamic_size = segment->p_filesz;
20737c13 5539
b2d38a17
NC
5540 /* Try to locate the .dynamic section. If there is
5541 a section header table, we can easily locate it. */
dda8d76d 5542 if (filedata->section_headers != NULL)
b2d38a17 5543 {
2cf0635d 5544 Elf_Internal_Shdr * sec;
b2d38a17 5545
dda8d76d 5546 sec = find_section (filedata, ".dynamic");
89fac5e3 5547 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5548 {
28f997cf
TG
5549 /* A corresponding .dynamic section is expected, but on
5550 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5551 if (!is_ia64_vms (filedata))
28f997cf 5552 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5553 break;
5554 }
5555
42bb2e33 5556 if (sec->sh_type == SHT_NOBITS)
20737c13 5557 {
978c4450 5558 filedata->dynamic_size = 0;
20737c13
AM
5559 break;
5560 }
42bb2e33 5561
978c4450
AM
5562 filedata->dynamic_addr = sec->sh_offset;
5563 filedata->dynamic_size = sec->sh_size;
b2d38a17 5564
8ac10c5b
L
5565 /* The PT_DYNAMIC segment, which is used by the run-time
5566 loader, should exactly match the .dynamic section. */
5567 if (do_checks
5568 && (filedata->dynamic_addr != segment->p_offset
5569 || filedata->dynamic_size != segment->p_filesz))
5570 warn (_("\
5571the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 5572 }
39e224f6
MW
5573
5574 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5575 segment. Check this after matching against the section headers
5576 so we don't warn on debuginfo file (which have NOBITS .dynamic
5577 sections). */
978c4450
AM
5578 if (filedata->dynamic_addr > filedata->file_size
5579 || (filedata->dynamic_size
5580 > filedata->file_size - filedata->dynamic_addr))
39e224f6
MW
5581 {
5582 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
978c4450 5583 filedata->dynamic_addr = filedata->dynamic_size = 0;
39e224f6 5584 }
252b5132
RH
5585 break;
5586
5587 case PT_INTERP:
13acb58d
AM
5588 if (segment->p_offset >= filedata->file_size
5589 || segment->p_filesz > filedata->file_size - segment->p_offset
5590 || segment->p_filesz - 1 >= (size_t) -2
5591 || fseek (filedata->handle,
5592 filedata->archive_file_offset + (long) segment->p_offset,
5593 SEEK_SET))
252b5132
RH
5594 error (_("Unable to find program interpreter name\n"));
5595 else
5596 {
13acb58d
AM
5597 size_t len = segment->p_filesz;
5598 free (filedata->program_interpreter);
5599 filedata->program_interpreter = xmalloc (len + 1);
5600 len = fread (filedata->program_interpreter, 1, len,
5601 filedata->handle);
5602 filedata->program_interpreter[len] = 0;
252b5132
RH
5603
5604 if (do_segments)
f54498b4 5605 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 5606 filedata->program_interpreter);
252b5132
RH
5607 }
5608 break;
5609 }
252b5132
RH
5610 }
5611
dda8d76d
NC
5612 if (do_segments
5613 && filedata->section_headers != NULL
5614 && filedata->string_table != NULL)
252b5132
RH
5615 {
5616 printf (_("\n Section to Segment mapping:\n"));
5617 printf (_(" Segment Sections...\n"));
5618
dda8d76d 5619 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5620 {
9ad5cbcf 5621 unsigned int j;
2cf0635d 5622 Elf_Internal_Shdr * section;
252b5132 5623
dda8d76d
NC
5624 segment = filedata->program_headers + i;
5625 section = filedata->section_headers + 1;
252b5132
RH
5626
5627 printf (" %2.2d ", i);
5628
dda8d76d 5629 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5630 {
f4638467
AM
5631 if (!ELF_TBSS_SPECIAL (section, segment)
5632 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5633 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5634 }
5635
5636 putc ('\n',stdout);
5637 }
5638 }
5639
015dc7e1 5640 return true;
252b5132
RH
5641}
5642
5643
d93f0186
NC
5644/* Find the file offset corresponding to VMA by using the program headers. */
5645
5646static long
dda8d76d 5647offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5648{
2cf0635d 5649 Elf_Internal_Phdr * seg;
d93f0186 5650
dda8d76d 5651 if (! get_program_headers (filedata))
d93f0186
NC
5652 {
5653 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5654 return (long) vma;
5655 }
5656
dda8d76d
NC
5657 for (seg = filedata->program_headers;
5658 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5659 ++seg)
5660 {
5661 if (seg->p_type != PT_LOAD)
5662 continue;
5663
5664 if (vma >= (seg->p_vaddr & -seg->p_align)
5665 && vma + size <= seg->p_vaddr + seg->p_filesz)
5666 return vma - seg->p_vaddr + seg->p_offset;
5667 }
5668
5669 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5670 (unsigned long) vma);
d93f0186
NC
5671 return (long) vma;
5672}
5673
5674
dda8d76d
NC
5675/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5676 If PROBE is true, this is just a probe and we do not generate any error
5677 messages if the load fails. */
049b0c3a 5678
015dc7e1
AM
5679static bool
5680get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 5681{
2cf0635d
NC
5682 Elf32_External_Shdr * shdrs;
5683 Elf_Internal_Shdr * internal;
dda8d76d
NC
5684 unsigned int i;
5685 unsigned int size = filedata->file_header.e_shentsize;
5686 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5687
5688 /* PR binutils/17531: Cope with unexpected section header sizes. */
5689 if (size == 0 || num == 0)
015dc7e1 5690 return false;
049b0c3a
NC
5691 if (size < sizeof * shdrs)
5692 {
5693 if (! probe)
5694 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 5695 return false;
049b0c3a
NC
5696 }
5697 if (!probe && size > sizeof * shdrs)
5698 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5699
dda8d76d 5700 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5701 size, num,
5702 probe ? NULL : _("section headers"));
5703 if (shdrs == NULL)
015dc7e1 5704 return false;
252b5132 5705
dda8d76d
NC
5706 free (filedata->section_headers);
5707 filedata->section_headers = (Elf_Internal_Shdr *)
5708 cmalloc (num, sizeof (Elf_Internal_Shdr));
5709 if (filedata->section_headers == NULL)
252b5132 5710 {
049b0c3a 5711 if (!probe)
8b73c356 5712 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5713 free (shdrs);
015dc7e1 5714 return false;
252b5132
RH
5715 }
5716
dda8d76d 5717 for (i = 0, internal = filedata->section_headers;
560f3c1c 5718 i < num;
b34976b6 5719 i++, internal++)
252b5132
RH
5720 {
5721 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5722 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5723 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5724 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5725 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5726 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5727 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5728 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5729 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5730 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5731 if (!probe && internal->sh_link > num)
5732 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5733 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5734 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5735 }
5736
5737 free (shdrs);
015dc7e1 5738 return true;
252b5132
RH
5739}
5740
dda8d76d
NC
5741/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5742
015dc7e1
AM
5743static bool
5744get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 5745{
dda8d76d
NC
5746 Elf64_External_Shdr * shdrs;
5747 Elf_Internal_Shdr * internal;
5748 unsigned int i;
5749 unsigned int size = filedata->file_header.e_shentsize;
5750 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5751
5752 /* PR binutils/17531: Cope with unexpected section header sizes. */
5753 if (size == 0 || num == 0)
015dc7e1 5754 return false;
dda8d76d 5755
049b0c3a
NC
5756 if (size < sizeof * shdrs)
5757 {
5758 if (! probe)
5759 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 5760 return false;
049b0c3a 5761 }
dda8d76d 5762
049b0c3a
NC
5763 if (! probe && size > sizeof * shdrs)
5764 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5765
dda8d76d
NC
5766 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5767 filedata->file_header.e_shoff,
049b0c3a
NC
5768 size, num,
5769 probe ? NULL : _("section headers"));
5770 if (shdrs == NULL)
015dc7e1 5771 return false;
9ea033b2 5772
dda8d76d
NC
5773 free (filedata->section_headers);
5774 filedata->section_headers = (Elf_Internal_Shdr *)
5775 cmalloc (num, sizeof (Elf_Internal_Shdr));
5776 if (filedata->section_headers == NULL)
9ea033b2 5777 {
049b0c3a 5778 if (! probe)
8b73c356 5779 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5780 free (shdrs);
015dc7e1 5781 return false;
9ea033b2
NC
5782 }
5783
dda8d76d 5784 for (i = 0, internal = filedata->section_headers;
560f3c1c 5785 i < num;
b34976b6 5786 i++, internal++)
9ea033b2
NC
5787 {
5788 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5789 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5790 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5791 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5792 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5793 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5794 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5795 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5796 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5797 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5798 if (!probe && internal->sh_link > num)
5799 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5800 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5801 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5802 }
5803
5804 free (shdrs);
015dc7e1 5805 return true;
9ea033b2
NC
5806}
5807
252b5132 5808static Elf_Internal_Sym *
dda8d76d
NC
5809get_32bit_elf_symbols (Filedata * filedata,
5810 Elf_Internal_Shdr * section,
5811 unsigned long * num_syms_return)
252b5132 5812{
ba5cdace 5813 unsigned long number = 0;
dd24e3da 5814 Elf32_External_Sym * esyms = NULL;
ba5cdace 5815 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5816 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5817 Elf_Internal_Sym * psym;
b34976b6 5818 unsigned int j;
e3d39609 5819 elf_section_list * entry;
252b5132 5820
c9c1d674
EG
5821 if (section->sh_size == 0)
5822 {
5823 if (num_syms_return != NULL)
5824 * num_syms_return = 0;
5825 return NULL;
5826 }
5827
dd24e3da 5828 /* Run some sanity checks first. */
c9c1d674 5829 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5830 {
c9c1d674 5831 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5832 printable_section_name (filedata, section),
5833 (unsigned long) section->sh_entsize);
ba5cdace 5834 goto exit_point;
dd24e3da
NC
5835 }
5836
dda8d76d 5837 if (section->sh_size > filedata->file_size)
f54498b4
NC
5838 {
5839 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5840 printable_section_name (filedata, section),
5841 (unsigned long) section->sh_size);
f54498b4
NC
5842 goto exit_point;
5843 }
5844
dd24e3da
NC
5845 number = section->sh_size / section->sh_entsize;
5846
5847 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5848 {
c9c1d674 5849 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5850 (unsigned long) section->sh_size,
dda8d76d 5851 printable_section_name (filedata, section),
8066deb1 5852 (unsigned long) section->sh_entsize);
ba5cdace 5853 goto exit_point;
dd24e3da
NC
5854 }
5855
dda8d76d 5856 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5857 section->sh_size, _("symbols"));
dd24e3da 5858 if (esyms == NULL)
ba5cdace 5859 goto exit_point;
252b5132 5860
e3d39609 5861 shndx = NULL;
978c4450 5862 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5863 {
5864 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5865 continue;
5866
5867 if (shndx != NULL)
5868 {
5869 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5870 free (shndx);
5871 }
5872
5873 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5874 entry->hdr->sh_offset,
5875 1, entry->hdr->sh_size,
5876 _("symbol table section indices"));
5877 if (shndx == NULL)
5878 goto exit_point;
5879
5880 /* PR17531: file: heap-buffer-overflow */
5881 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5882 {
5883 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5884 printable_section_name (filedata, entry->hdr),
5885 (unsigned long) entry->hdr->sh_size,
5886 (unsigned long) section->sh_size);
5887 goto exit_point;
c9c1d674 5888 }
e3d39609 5889 }
9ad5cbcf 5890
3f5e193b 5891 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5892
5893 if (isyms == NULL)
5894 {
8b73c356
NC
5895 error (_("Out of memory reading %lu symbols\n"),
5896 (unsigned long) number);
dd24e3da 5897 goto exit_point;
252b5132
RH
5898 }
5899
dd24e3da 5900 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5901 {
5902 psym->st_name = BYTE_GET (esyms[j].st_name);
5903 psym->st_value = BYTE_GET (esyms[j].st_value);
5904 psym->st_size = BYTE_GET (esyms[j].st_size);
5905 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5906 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5907 psym->st_shndx
5908 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5909 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5910 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5911 psym->st_info = BYTE_GET (esyms[j].st_info);
5912 psym->st_other = BYTE_GET (esyms[j].st_other);
5913 }
5914
dd24e3da 5915 exit_point:
e3d39609
NC
5916 free (shndx);
5917 free (esyms);
252b5132 5918
ba5cdace
NC
5919 if (num_syms_return != NULL)
5920 * num_syms_return = isyms == NULL ? 0 : number;
5921
252b5132
RH
5922 return isyms;
5923}
5924
9ea033b2 5925static Elf_Internal_Sym *
dda8d76d
NC
5926get_64bit_elf_symbols (Filedata * filedata,
5927 Elf_Internal_Shdr * section,
5928 unsigned long * num_syms_return)
9ea033b2 5929{
ba5cdace
NC
5930 unsigned long number = 0;
5931 Elf64_External_Sym * esyms = NULL;
5932 Elf_External_Sym_Shndx * shndx = NULL;
5933 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5934 Elf_Internal_Sym * psym;
b34976b6 5935 unsigned int j;
e3d39609 5936 elf_section_list * entry;
9ea033b2 5937
c9c1d674
EG
5938 if (section->sh_size == 0)
5939 {
5940 if (num_syms_return != NULL)
5941 * num_syms_return = 0;
5942 return NULL;
5943 }
5944
dd24e3da 5945 /* Run some sanity checks first. */
c9c1d674 5946 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5947 {
c9c1d674 5948 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5949 printable_section_name (filedata, section),
8066deb1 5950 (unsigned long) section->sh_entsize);
ba5cdace 5951 goto exit_point;
dd24e3da
NC
5952 }
5953
dda8d76d 5954 if (section->sh_size > filedata->file_size)
f54498b4
NC
5955 {
5956 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5957 printable_section_name (filedata, section),
8066deb1 5958 (unsigned long) section->sh_size);
f54498b4
NC
5959 goto exit_point;
5960 }
5961
dd24e3da
NC
5962 number = section->sh_size / section->sh_entsize;
5963
5964 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5965 {
c9c1d674 5966 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5967 (unsigned long) section->sh_size,
dda8d76d 5968 printable_section_name (filedata, section),
8066deb1 5969 (unsigned long) section->sh_entsize);
ba5cdace 5970 goto exit_point;
dd24e3da
NC
5971 }
5972
dda8d76d 5973 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5974 section->sh_size, _("symbols"));
a6e9f9df 5975 if (!esyms)
ba5cdace 5976 goto exit_point;
9ea033b2 5977
e3d39609 5978 shndx = NULL;
978c4450 5979 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5980 {
5981 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5982 continue;
5983
5984 if (shndx != NULL)
5985 {
5986 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5987 free (shndx);
c9c1d674 5988 }
e3d39609
NC
5989
5990 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5991 entry->hdr->sh_offset,
5992 1, entry->hdr->sh_size,
5993 _("symbol table section indices"));
5994 if (shndx == NULL)
5995 goto exit_point;
5996
5997 /* PR17531: file: heap-buffer-overflow */
5998 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5999 {
6000 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6001 printable_section_name (filedata, entry->hdr),
6002 (unsigned long) entry->hdr->sh_size,
6003 (unsigned long) section->sh_size);
6004 goto exit_point;
6005 }
6006 }
9ad5cbcf 6007
3f5e193b 6008 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6009
6010 if (isyms == NULL)
6011 {
8b73c356
NC
6012 error (_("Out of memory reading %lu symbols\n"),
6013 (unsigned long) number);
ba5cdace 6014 goto exit_point;
9ea033b2
NC
6015 }
6016
ba5cdace 6017 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6018 {
6019 psym->st_name = BYTE_GET (esyms[j].st_name);
6020 psym->st_info = BYTE_GET (esyms[j].st_info);
6021 psym->st_other = BYTE_GET (esyms[j].st_other);
6022 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6023
4fbb74a6 6024 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6025 psym->st_shndx
6026 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6027 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6028 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6029
66543521
AM
6030 psym->st_value = BYTE_GET (esyms[j].st_value);
6031 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6032 }
6033
ba5cdace 6034 exit_point:
e3d39609
NC
6035 free (shndx);
6036 free (esyms);
ba5cdace
NC
6037
6038 if (num_syms_return != NULL)
6039 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6040
6041 return isyms;
6042}
6043
d1133906 6044static const char *
dda8d76d 6045get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 6046{
5477e8a0 6047 static char buff[1024];
2cf0635d 6048 char * p = buff;
32ec8896
NC
6049 unsigned int field_size = is_32bit_elf ? 8 : 16;
6050 signed int sindex;
6051 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
6052 bfd_vma os_flags = 0;
6053 bfd_vma proc_flags = 0;
6054 bfd_vma unknown_flags = 0;
148b93f2 6055 static const struct
5477e8a0 6056 {
2cf0635d 6057 const char * str;
32ec8896 6058 unsigned int len;
5477e8a0
L
6059 }
6060 flags [] =
6061 {
cfcac11d
NC
6062 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6063 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6064 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6065 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6066 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6067 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6068 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6069 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6070 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6071 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6072 /* IA-64 specific. */
6073 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6074 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6075 /* IA-64 OpenVMS specific. */
6076 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6077 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6078 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6079 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6080 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6081 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6082 /* Generic. */
cfcac11d 6083 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6084 /* SPARC specific. */
77115a4a 6085 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6086 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6087 /* ARM specific. */
6088 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6089 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6090 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6091 /* GNU specific. */
6092 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6093 /* VLE specific. */
6094 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6095 /* GNU specific. */
6096 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6097 };
6098
6099 if (do_section_details)
6100 {
8d5ff12c
L
6101 sprintf (buff, "[%*.*lx]: ",
6102 field_size, field_size, (unsigned long) sh_flags);
6103 p += field_size + 4;
5477e8a0 6104 }
76da6bbe 6105
d1133906
NC
6106 while (sh_flags)
6107 {
6108 bfd_vma flag;
6109
6110 flag = sh_flags & - sh_flags;
6111 sh_flags &= ~ flag;
76da6bbe 6112
5477e8a0 6113 if (do_section_details)
d1133906 6114 {
5477e8a0
L
6115 switch (flag)
6116 {
91d6fa6a
NC
6117 case SHF_WRITE: sindex = 0; break;
6118 case SHF_ALLOC: sindex = 1; break;
6119 case SHF_EXECINSTR: sindex = 2; break;
6120 case SHF_MERGE: sindex = 3; break;
6121 case SHF_STRINGS: sindex = 4; break;
6122 case SHF_INFO_LINK: sindex = 5; break;
6123 case SHF_LINK_ORDER: sindex = 6; break;
6124 case SHF_OS_NONCONFORMING: sindex = 7; break;
6125 case SHF_GROUP: sindex = 8; break;
6126 case SHF_TLS: sindex = 9; break;
18ae9cc1 6127 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6128 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6129
5477e8a0 6130 default:
91d6fa6a 6131 sindex = -1;
dda8d76d 6132 switch (filedata->file_header.e_machine)
148b93f2 6133 {
cfcac11d 6134 case EM_IA_64:
148b93f2 6135 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6136 sindex = 10;
148b93f2 6137 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6138 sindex = 11;
148b93f2 6139#ifdef BFD64
dda8d76d 6140 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6141 switch (flag)
6142 {
91d6fa6a
NC
6143 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6144 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6145 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6146 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6147 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6148 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6149 default: break;
6150 }
6151#endif
cfcac11d
NC
6152 break;
6153
caa83f8b 6154 case EM_386:
22abe556 6155 case EM_IAMCU:
caa83f8b 6156 case EM_X86_64:
7f502d6c 6157 case EM_L1OM:
7a9068fe 6158 case EM_K1OM:
cfcac11d
NC
6159 case EM_OLD_SPARCV9:
6160 case EM_SPARC32PLUS:
6161 case EM_SPARCV9:
6162 case EM_SPARC:
18ae9cc1 6163 if (flag == SHF_ORDERED)
91d6fa6a 6164 sindex = 19;
cfcac11d 6165 break;
ac4c9b04
MG
6166
6167 case EM_ARM:
6168 switch (flag)
6169 {
6170 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6171 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6172 case SHF_COMDEF: sindex = 23; break;
6173 default: break;
6174 }
6175 break;
83eef883
AFB
6176 case EM_PPC:
6177 if (flag == SHF_PPC_VLE)
6178 sindex = 25;
6179 break;
99fabbc9
JL
6180 default:
6181 break;
6182 }
ac4c9b04 6183
99fabbc9
JL
6184 switch (filedata->file_header.e_ident[EI_OSABI])
6185 {
6186 case ELFOSABI_GNU:
6187 case ELFOSABI_FREEBSD:
6188 if (flag == SHF_GNU_RETAIN)
6189 sindex = 26;
6190 /* Fall through */
6191 case ELFOSABI_NONE:
6192 if (flag == SHF_GNU_MBIND)
6193 /* We should not recognize SHF_GNU_MBIND for
6194 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6195 not set the EI_OSABI header byte. */
6196 sindex = 24;
6197 break;
cfcac11d
NC
6198 default:
6199 break;
148b93f2 6200 }
99fabbc9 6201 break;
5477e8a0
L
6202 }
6203
91d6fa6a 6204 if (sindex != -1)
5477e8a0 6205 {
8d5ff12c
L
6206 if (p != buff + field_size + 4)
6207 {
6208 if (size < (10 + 2))
bee0ee85
NC
6209 {
6210 warn (_("Internal error: not enough buffer room for section flag info"));
6211 return _("<unknown>");
6212 }
8d5ff12c
L
6213 size -= 2;
6214 *p++ = ',';
6215 *p++ = ' ';
6216 }
6217
91d6fa6a
NC
6218 size -= flags [sindex].len;
6219 p = stpcpy (p, flags [sindex].str);
5477e8a0 6220 }
3b22753a 6221 else if (flag & SHF_MASKOS)
8d5ff12c 6222 os_flags |= flag;
d1133906 6223 else if (flag & SHF_MASKPROC)
8d5ff12c 6224 proc_flags |= flag;
d1133906 6225 else
8d5ff12c 6226 unknown_flags |= flag;
5477e8a0
L
6227 }
6228 else
6229 {
6230 switch (flag)
6231 {
6232 case SHF_WRITE: *p = 'W'; break;
6233 case SHF_ALLOC: *p = 'A'; break;
6234 case SHF_EXECINSTR: *p = 'X'; break;
6235 case SHF_MERGE: *p = 'M'; break;
6236 case SHF_STRINGS: *p = 'S'; break;
6237 case SHF_INFO_LINK: *p = 'I'; break;
6238 case SHF_LINK_ORDER: *p = 'L'; break;
6239 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6240 case SHF_GROUP: *p = 'G'; break;
6241 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6242 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6243 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6244
6245 default:
dda8d76d
NC
6246 if ((filedata->file_header.e_machine == EM_X86_64
6247 || filedata->file_header.e_machine == EM_L1OM
6248 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6249 && flag == SHF_X86_64_LARGE)
6250 *p = 'l';
dda8d76d 6251 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6252 && flag == SHF_ARM_PURECODE)
99fabbc9 6253 *p = 'y';
dda8d76d 6254 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6255 && flag == SHF_PPC_VLE)
99fabbc9 6256 *p = 'v';
5477e8a0
L
6257 else if (flag & SHF_MASKOS)
6258 {
99fabbc9
JL
6259 switch (filedata->file_header.e_ident[EI_OSABI])
6260 {
6261 case ELFOSABI_GNU:
6262 case ELFOSABI_FREEBSD:
6263 if (flag == SHF_GNU_RETAIN)
6264 {
6265 *p = 'R';
6266 break;
6267 }
6268 /* Fall through */
6269 case ELFOSABI_NONE:
6270 if (flag == SHF_GNU_MBIND)
6271 {
6272 /* We should not recognize SHF_GNU_MBIND for
6273 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6274 not set the EI_OSABI header byte. */
6275 *p = 'D';
6276 break;
6277 }
6278 /* Fall through */
6279 default:
6280 *p = 'o';
6281 sh_flags &= ~SHF_MASKOS;
6282 break;
6283 }
5477e8a0
L
6284 }
6285 else if (flag & SHF_MASKPROC)
6286 {
6287 *p = 'p';
6288 sh_flags &= ~ SHF_MASKPROC;
6289 }
6290 else
6291 *p = 'x';
6292 break;
6293 }
6294 p++;
d1133906
NC
6295 }
6296 }
76da6bbe 6297
8d5ff12c
L
6298 if (do_section_details)
6299 {
6300 if (os_flags)
6301 {
6302 size -= 5 + field_size;
6303 if (p != buff + field_size + 4)
6304 {
6305 if (size < (2 + 1))
bee0ee85
NC
6306 {
6307 warn (_("Internal error: not enough buffer room for section flag info"));
6308 return _("<unknown>");
6309 }
8d5ff12c
L
6310 size -= 2;
6311 *p++ = ',';
6312 *p++ = ' ';
6313 }
6314 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6315 (unsigned long) os_flags);
6316 p += 5 + field_size;
6317 }
6318 if (proc_flags)
6319 {
6320 size -= 7 + field_size;
6321 if (p != buff + field_size + 4)
6322 {
6323 if (size < (2 + 1))
bee0ee85
NC
6324 {
6325 warn (_("Internal error: not enough buffer room for section flag info"));
6326 return _("<unknown>");
6327 }
8d5ff12c
L
6328 size -= 2;
6329 *p++ = ',';
6330 *p++ = ' ';
6331 }
6332 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6333 (unsigned long) proc_flags);
6334 p += 7 + field_size;
6335 }
6336 if (unknown_flags)
6337 {
6338 size -= 10 + field_size;
6339 if (p != buff + field_size + 4)
6340 {
6341 if (size < (2 + 1))
bee0ee85
NC
6342 {
6343 warn (_("Internal error: not enough buffer room for section flag info"));
6344 return _("<unknown>");
6345 }
8d5ff12c
L
6346 size -= 2;
6347 *p++ = ',';
6348 *p++ = ' ';
6349 }
2b692964 6350 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6351 (unsigned long) unknown_flags);
6352 p += 10 + field_size;
6353 }
6354 }
6355
e9e44622 6356 *p = '\0';
d1133906
NC
6357 return buff;
6358}
6359
5844b465 6360static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6361get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6362{
6363 if (is_32bit_elf)
6364 {
6365 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6366
ebdf1ebf
NC
6367 if (size < sizeof (* echdr))
6368 {
6369 error (_("Compressed section is too small even for a compression header\n"));
6370 return 0;
6371 }
6372
77115a4a
L
6373 chdr->ch_type = BYTE_GET (echdr->ch_type);
6374 chdr->ch_size = BYTE_GET (echdr->ch_size);
6375 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6376 return sizeof (*echdr);
6377 }
6378 else
6379 {
6380 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6381
ebdf1ebf
NC
6382 if (size < sizeof (* echdr))
6383 {
6384 error (_("Compressed section is too small even for a compression header\n"));
6385 return 0;
6386 }
6387
77115a4a
L
6388 chdr->ch_type = BYTE_GET (echdr->ch_type);
6389 chdr->ch_size = BYTE_GET (echdr->ch_size);
6390 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6391 return sizeof (*echdr);
6392 }
6393}
6394
015dc7e1 6395static bool
dda8d76d 6396process_section_headers (Filedata * filedata)
252b5132 6397{
2cf0635d 6398 Elf_Internal_Shdr * section;
b34976b6 6399 unsigned int i;
252b5132 6400
8fb879cd 6401 free (filedata->section_headers);
dda8d76d 6402 filedata->section_headers = NULL;
978c4450
AM
6403 free (filedata->dynamic_symbols);
6404 filedata->dynamic_symbols = NULL;
6405 filedata->num_dynamic_syms = 0;
6406 free (filedata->dynamic_strings);
6407 filedata->dynamic_strings = NULL;
6408 filedata->dynamic_strings_length = 0;
6409 free (filedata->dynamic_syminfo);
6410 filedata->dynamic_syminfo = NULL;
6411 while (filedata->symtab_shndx_list != NULL)
8ff66993 6412 {
978c4450
AM
6413 elf_section_list *next = filedata->symtab_shndx_list->next;
6414 free (filedata->symtab_shndx_list);
6415 filedata->symtab_shndx_list = next;
8ff66993 6416 }
252b5132 6417
dda8d76d 6418 if (filedata->file_header.e_shnum == 0)
252b5132 6419 {
82f2dbf7 6420 /* PR binutils/12467. */
dda8d76d 6421 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6422 {
6423 warn (_("possibly corrupt ELF file header - it has a non-zero"
6424 " section header offset, but no section headers\n"));
015dc7e1 6425 return false;
32ec8896 6426 }
82f2dbf7 6427 else if (do_sections)
252b5132
RH
6428 printf (_("\nThere are no sections in this file.\n"));
6429
015dc7e1 6430 return true;
252b5132
RH
6431 }
6432
6433 if (do_sections && !do_header)
ca0e11aa
NC
6434 {
6435 if (filedata->is_separate && process_links)
6436 printf (_("In linked file '%s': "), filedata->file_name);
6437 if (! filedata->is_separate || process_links)
6438 printf (ngettext ("There is %d section header, "
6439 "starting at offset 0x%lx:\n",
6440 "There are %d section headers, "
6441 "starting at offset 0x%lx:\n",
6442 filedata->file_header.e_shnum),
6443 filedata->file_header.e_shnum,
6444 (unsigned long) filedata->file_header.e_shoff);
6445 }
252b5132 6446
9ea033b2
NC
6447 if (is_32bit_elf)
6448 {
015dc7e1
AM
6449 if (! get_32bit_section_headers (filedata, false))
6450 return false;
32ec8896
NC
6451 }
6452 else
6453 {
015dc7e1
AM
6454 if (! get_64bit_section_headers (filedata, false))
6455 return false;
9ea033b2 6456 }
252b5132
RH
6457
6458 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6459 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6460 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6461 {
dda8d76d 6462 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6463
c256ffe7
JJ
6464 if (section->sh_size != 0)
6465 {
dda8d76d
NC
6466 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6467 1, section->sh_size,
6468 _("string table"));
0de14b54 6469
dda8d76d 6470 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6471 }
252b5132
RH
6472 }
6473
6474 /* Scan the sections for the dynamic symbol table
e3c8793a 6475 and dynamic string table and debug sections. */
89fac5e3 6476 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6477 switch (filedata->file_header.e_machine)
89fac5e3
RS
6478 {
6479 case EM_MIPS:
6480 case EM_MIPS_RS3_LE:
6481 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6482 FDE addresses. However, the ABI also has a semi-official ILP32
6483 variant for which the normal FDE address size rules apply.
6484
6485 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6486 section, where XX is the size of longs in bits. Unfortunately,
6487 earlier compilers provided no way of distinguishing ILP32 objects
6488 from LP64 objects, so if there's any doubt, we should assume that
6489 the official LP64 form is being used. */
dda8d76d
NC
6490 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6491 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6492 eh_addr_size = 8;
6493 break;
0f56a26a
DD
6494
6495 case EM_H8_300:
6496 case EM_H8_300H:
dda8d76d 6497 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6498 {
6499 case E_H8_MACH_H8300:
6500 case E_H8_MACH_H8300HN:
6501 case E_H8_MACH_H8300SN:
6502 case E_H8_MACH_H8300SXN:
6503 eh_addr_size = 2;
6504 break;
6505 case E_H8_MACH_H8300H:
6506 case E_H8_MACH_H8300S:
6507 case E_H8_MACH_H8300SX:
6508 eh_addr_size = 4;
6509 break;
6510 }
f4236fe4
DD
6511 break;
6512
ff7eeb89 6513 case EM_M32C_OLD:
f4236fe4 6514 case EM_M32C:
dda8d76d 6515 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6516 {
6517 case EF_M32C_CPU_M16C:
6518 eh_addr_size = 2;
6519 break;
6520 }
6521 break;
89fac5e3
RS
6522 }
6523
76ca31c0
NC
6524#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6525 do \
6526 { \
6527 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6528 if (section->sh_entsize != expected_entsize) \
9dd3a467 6529 { \
76ca31c0
NC
6530 char buf[40]; \
6531 sprintf_vma (buf, section->sh_entsize); \
6532 /* Note: coded this way so that there is a single string for \
6533 translation. */ \
6534 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6535 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6536 (unsigned) expected_entsize); \
9dd3a467 6537 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6538 } \
6539 } \
08d8fa11 6540 while (0)
9dd3a467
NC
6541
6542#define CHECK_ENTSIZE(section, i, type) \
1b513401 6543 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
6544 sizeof (Elf64_External_##type))
6545
dda8d76d
NC
6546 for (i = 0, section = filedata->section_headers;
6547 i < filedata->file_header.e_shnum;
b34976b6 6548 i++, section++)
252b5132 6549 {
b9e920ec 6550 char * name = SECTION_NAME_PRINT (section);
252b5132 6551
1b513401
NC
6552 /* Run some sanity checks on the headers and
6553 possibly fill in some file data as well. */
6554 switch (section->sh_type)
252b5132 6555 {
1b513401 6556 case SHT_DYNSYM:
978c4450 6557 if (filedata->dynamic_symbols != NULL)
252b5132
RH
6558 {
6559 error (_("File contains multiple dynamic symbol tables\n"));
6560 continue;
6561 }
6562
08d8fa11 6563 CHECK_ENTSIZE (section, i, Sym);
978c4450
AM
6564 filedata->dynamic_symbols
6565 = GET_ELF_SYMBOLS (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 6566 filedata->dynamic_symtab_section = section;
1b513401
NC
6567 break;
6568
6569 case SHT_STRTAB:
6570 if (streq (name, ".dynstr"))
252b5132 6571 {
1b513401
NC
6572 if (filedata->dynamic_strings != NULL)
6573 {
6574 error (_("File contains multiple dynamic string tables\n"));
6575 continue;
6576 }
6577
6578 filedata->dynamic_strings
6579 = (char *) get_data (NULL, filedata, section->sh_offset,
6580 1, section->sh_size, _("dynamic strings"));
6581 filedata->dynamic_strings_length
6582 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 6583 filedata->dynamic_strtab_section = section;
252b5132 6584 }
1b513401
NC
6585 break;
6586
6587 case SHT_SYMTAB_SHNDX:
6588 {
6589 elf_section_list * entry = xmalloc (sizeof * entry);
6590
6591 entry->hdr = section;
6592 entry->next = filedata->symtab_shndx_list;
6593 filedata->symtab_shndx_list = entry;
6594 }
6595 break;
6596
6597 case SHT_SYMTAB:
6598 CHECK_ENTSIZE (section, i, Sym);
6599 break;
6600
6601 case SHT_GROUP:
6602 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6603 break;
252b5132 6604
1b513401
NC
6605 case SHT_REL:
6606 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 6607 if (do_checks && section->sh_size == 0)
1b513401
NC
6608 warn (_("Section '%s': zero-sized relocation section\n"), name);
6609 break;
6610
6611 case SHT_RELA:
6612 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 6613 if (do_checks && section->sh_size == 0)
1b513401
NC
6614 warn (_("Section '%s': zero-sized relocation section\n"), name);
6615 break;
6616
6617 case SHT_NOTE:
6618 case SHT_PROGBITS:
546cb2d8
NC
6619 /* Having a zero sized section is not illegal according to the
6620 ELF standard, but it might be an indication that something
6621 is wrong. So issue a warning if we are running in lint mode. */
6622 if (do_checks && section->sh_size == 0)
1b513401
NC
6623 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
6624 break;
6625
6626 default:
6627 break;
6628 }
6629
6630 if ((do_debugging || do_debug_info || do_debug_abbrevs
6631 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
6632 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
6633 || do_debug_str || do_debug_str_offsets || do_debug_loc
6634 || do_debug_ranges
1b513401 6635 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
6636 && (startswith (name, ".debug_")
6637 || startswith (name, ".zdebug_")))
252b5132 6638 {
1b315056
CS
6639 if (name[1] == 'z')
6640 name += sizeof (".zdebug_") - 1;
6641 else
6642 name += sizeof (".debug_") - 1;
252b5132
RH
6643
6644 if (do_debugging
24d127aa
ML
6645 || (do_debug_info && startswith (name, "info"))
6646 || (do_debug_info && startswith (name, "types"))
6647 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 6648 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
6649 || (do_debug_lines && startswith (name, "line."))
6650 || (do_debug_pubnames && startswith (name, "pubnames"))
6651 || (do_debug_pubtypes && startswith (name, "pubtypes"))
6652 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
6653 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
6654 || (do_debug_aranges && startswith (name, "aranges"))
6655 || (do_debug_ranges && startswith (name, "ranges"))
6656 || (do_debug_ranges && startswith (name, "rnglists"))
6657 || (do_debug_frames && startswith (name, "frame"))
6658 || (do_debug_macinfo && startswith (name, "macinfo"))
6659 || (do_debug_macinfo && startswith (name, "macro"))
6660 || (do_debug_str && startswith (name, "str"))
6661 || (do_debug_links && startswith (name, "sup"))
6662 || (do_debug_str_offsets && startswith (name, "str_offsets"))
6663 || (do_debug_loc && startswith (name, "loc"))
6664 || (do_debug_loc && startswith (name, "loclists"))
6665 || (do_debug_addr && startswith (name, "addr"))
6666 || (do_debug_cu_index && startswith (name, "cu_index"))
6667 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 6668 )
6431e409 6669 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6670 }
a262ae96 6671 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6672 else if ((do_debugging || do_debug_info)
24d127aa 6673 && startswith (name, ".gnu.linkonce.wi."))
6431e409 6674 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6675 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6676 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6677 else if (do_gdb_index && (streq (name, ".gdb_index")
6678 || streq (name, ".debug_names")))
6431e409 6679 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6680 /* Trace sections for Itanium VMS. */
6681 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6682 || do_trace_aranges)
24d127aa 6683 && startswith (name, ".trace_"))
6f875884
TG
6684 {
6685 name += sizeof (".trace_") - 1;
6686
6687 if (do_debugging
6688 || (do_trace_info && streq (name, "info"))
6689 || (do_trace_abbrevs && streq (name, "abbrev"))
6690 || (do_trace_aranges && streq (name, "aranges"))
6691 )
6431e409 6692 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6693 }
dda8d76d 6694 else if ((do_debugging || do_debug_links)
24d127aa
ML
6695 && (startswith (name, ".gnu_debuglink")
6696 || startswith (name, ".gnu_debugaltlink")))
6431e409 6697 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6698 }
6699
6700 if (! do_sections)
015dc7e1 6701 return true;
252b5132 6702
ca0e11aa 6703 if (filedata->is_separate && ! process_links)
015dc7e1 6704 return true;
ca0e11aa
NC
6705
6706 if (filedata->is_separate)
6707 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
6708 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6709 printf (_("\nSection Headers:\n"));
6710 else
6711 printf (_("\nSection Header:\n"));
76da6bbe 6712
f7a99963 6713 if (is_32bit_elf)
595cf52e 6714 {
5477e8a0 6715 if (do_section_details)
595cf52e
L
6716 {
6717 printf (_(" [Nr] Name\n"));
5477e8a0 6718 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6719 }
6720 else
6721 printf
6722 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6723 }
d974e256 6724 else if (do_wide)
595cf52e 6725 {
5477e8a0 6726 if (do_section_details)
595cf52e
L
6727 {
6728 printf (_(" [Nr] Name\n"));
5477e8a0 6729 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6730 }
6731 else
6732 printf
6733 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6734 }
f7a99963
NC
6735 else
6736 {
5477e8a0 6737 if (do_section_details)
595cf52e
L
6738 {
6739 printf (_(" [Nr] Name\n"));
5477e8a0
L
6740 printf (_(" Type Address Offset Link\n"));
6741 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6742 }
6743 else
6744 {
6745 printf (_(" [Nr] Name Type Address Offset\n"));
6746 printf (_(" Size EntSize Flags Link Info Align\n"));
6747 }
f7a99963 6748 }
252b5132 6749
5477e8a0
L
6750 if (do_section_details)
6751 printf (_(" Flags\n"));
6752
dda8d76d
NC
6753 for (i = 0, section = filedata->section_headers;
6754 i < filedata->file_header.e_shnum;
b34976b6 6755 i++, section++)
252b5132 6756 {
dd905818
NC
6757 /* Run some sanity checks on the section header. */
6758
6759 /* Check the sh_link field. */
6760 switch (section->sh_type)
6761 {
285e3f99
AM
6762 case SHT_REL:
6763 case SHT_RELA:
6764 if (section->sh_link == 0
6765 && (filedata->file_header.e_type == ET_EXEC
6766 || filedata->file_header.e_type == ET_DYN))
6767 /* A dynamic relocation section where all entries use a
6768 zero symbol index need not specify a symtab section. */
6769 break;
6770 /* Fall through. */
dd905818
NC
6771 case SHT_SYMTAB_SHNDX:
6772 case SHT_GROUP:
6773 case SHT_HASH:
6774 case SHT_GNU_HASH:
6775 case SHT_GNU_versym:
285e3f99 6776 if (section->sh_link == 0
dda8d76d
NC
6777 || section->sh_link >= filedata->file_header.e_shnum
6778 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6779 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6780 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6781 i, section->sh_link);
6782 break;
6783
6784 case SHT_DYNAMIC:
6785 case SHT_SYMTAB:
6786 case SHT_DYNSYM:
6787 case SHT_GNU_verneed:
6788 case SHT_GNU_verdef:
6789 case SHT_GNU_LIBLIST:
285e3f99 6790 if (section->sh_link == 0
dda8d76d
NC
6791 || section->sh_link >= filedata->file_header.e_shnum
6792 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6793 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6794 i, section->sh_link);
6795 break;
6796
6797 case SHT_INIT_ARRAY:
6798 case SHT_FINI_ARRAY:
6799 case SHT_PREINIT_ARRAY:
6800 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6801 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6802 i, section->sh_link);
6803 break;
6804
6805 default:
6806 /* FIXME: Add support for target specific section types. */
6807#if 0 /* Currently we do not check other section types as there are too
6808 many special cases. Stab sections for example have a type
6809 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6810 section. */
6811 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6812 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6813 i, section->sh_link);
6814#endif
6815 break;
6816 }
6817
6818 /* Check the sh_info field. */
6819 switch (section->sh_type)
6820 {
6821 case SHT_REL:
6822 case SHT_RELA:
285e3f99
AM
6823 if (section->sh_info == 0
6824 && (filedata->file_header.e_type == ET_EXEC
6825 || filedata->file_header.e_type == ET_DYN))
6826 /* Dynamic relocations apply to segments, so they do not
6827 need to specify the section they relocate. */
6828 break;
6829 if (section->sh_info == 0
dda8d76d
NC
6830 || section->sh_info >= filedata->file_header.e_shnum
6831 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6832 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6833 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6834 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6835 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6836 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6837 /* FIXME: Are other section types valid ? */
dda8d76d 6838 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6839 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6840 i, section->sh_info);
dd905818
NC
6841 break;
6842
6843 case SHT_DYNAMIC:
6844 case SHT_HASH:
6845 case SHT_SYMTAB_SHNDX:
6846 case SHT_INIT_ARRAY:
6847 case SHT_FINI_ARRAY:
6848 case SHT_PREINIT_ARRAY:
6849 if (section->sh_info != 0)
6850 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6851 i, section->sh_info);
6852 break;
6853
6854 case SHT_GROUP:
6855 case SHT_SYMTAB:
6856 case SHT_DYNSYM:
6857 /* A symbol index - we assume that it is valid. */
6858 break;
6859
6860 default:
6861 /* FIXME: Add support for target specific section types. */
6862 if (section->sh_type == SHT_NOBITS)
6863 /* NOBITS section headers with non-zero sh_info fields can be
6864 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6865 information. The stripped sections have their headers
6866 preserved but their types set to SHT_NOBITS. So do not check
6867 this type of section. */
dd905818
NC
6868 ;
6869 else if (section->sh_flags & SHF_INFO_LINK)
6870 {
dda8d76d 6871 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6872 warn (_("[%2u]: Expected link to another section in info field"), i);
6873 }
a91e1603
L
6874 else if (section->sh_type < SHT_LOOS
6875 && (section->sh_flags & SHF_GNU_MBIND) == 0
6876 && section->sh_info != 0)
dd905818
NC
6877 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6878 i, section->sh_info);
6879 break;
6880 }
6881
3e6b6445 6882 /* Check the sh_size field. */
dda8d76d 6883 if (section->sh_size > filedata->file_size
3e6b6445
NC
6884 && section->sh_type != SHT_NOBITS
6885 && section->sh_type != SHT_NULL
6886 && section->sh_type < SHT_LOOS)
6887 warn (_("Size of section %u is larger than the entire file!\n"), i);
6888
7bfd842d 6889 printf (" [%2u] ", i);
5477e8a0 6890 if (do_section_details)
dda8d76d 6891 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6892 else
b9e920ec 6893 print_symbol (-17, SECTION_NAME_PRINT (section));
0b4362b0 6894
ea52a088 6895 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6896 get_section_type_name (filedata, section->sh_type));
0b4362b0 6897
f7a99963
NC
6898 if (is_32bit_elf)
6899 {
cfcac11d
NC
6900 const char * link_too_big = NULL;
6901
f7a99963 6902 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6903
f7a99963
NC
6904 printf ( " %6.6lx %6.6lx %2.2lx",
6905 (unsigned long) section->sh_offset,
6906 (unsigned long) section->sh_size,
6907 (unsigned long) section->sh_entsize);
d1133906 6908
5477e8a0
L
6909 if (do_section_details)
6910 fputs (" ", stdout);
6911 else
dda8d76d 6912 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6913
dda8d76d 6914 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6915 {
6916 link_too_big = "";
6917 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6918 an error but it can have special values in Solaris binaries. */
dda8d76d 6919 switch (filedata->file_header.e_machine)
cfcac11d 6920 {
caa83f8b 6921 case EM_386:
22abe556 6922 case EM_IAMCU:
caa83f8b 6923 case EM_X86_64:
7f502d6c 6924 case EM_L1OM:
7a9068fe 6925 case EM_K1OM:
cfcac11d
NC
6926 case EM_OLD_SPARCV9:
6927 case EM_SPARC32PLUS:
6928 case EM_SPARCV9:
6929 case EM_SPARC:
6930 if (section->sh_link == (SHN_BEFORE & 0xffff))
6931 link_too_big = "BEFORE";
6932 else if (section->sh_link == (SHN_AFTER & 0xffff))
6933 link_too_big = "AFTER";
6934 break;
6935 default:
6936 break;
6937 }
6938 }
6939
6940 if (do_section_details)
6941 {
6942 if (link_too_big != NULL && * link_too_big)
6943 printf ("<%s> ", link_too_big);
6944 else
6945 printf ("%2u ", section->sh_link);
6946 printf ("%3u %2lu\n", section->sh_info,
6947 (unsigned long) section->sh_addralign);
6948 }
6949 else
6950 printf ("%2u %3u %2lu\n",
6951 section->sh_link,
6952 section->sh_info,
6953 (unsigned long) section->sh_addralign);
6954
6955 if (link_too_big && ! * link_too_big)
6956 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6957 i, section->sh_link);
f7a99963 6958 }
d974e256
JJ
6959 else if (do_wide)
6960 {
6961 print_vma (section->sh_addr, LONG_HEX);
6962
6963 if ((long) section->sh_offset == section->sh_offset)
6964 printf (" %6.6lx", (unsigned long) section->sh_offset);
6965 else
6966 {
6967 putchar (' ');
6968 print_vma (section->sh_offset, LONG_HEX);
6969 }
6970
6971 if ((unsigned long) section->sh_size == section->sh_size)
6972 printf (" %6.6lx", (unsigned long) section->sh_size);
6973 else
6974 {
6975 putchar (' ');
6976 print_vma (section->sh_size, LONG_HEX);
6977 }
6978
6979 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6980 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6981 else
6982 {
6983 putchar (' ');
6984 print_vma (section->sh_entsize, LONG_HEX);
6985 }
6986
5477e8a0
L
6987 if (do_section_details)
6988 fputs (" ", stdout);
6989 else
dda8d76d 6990 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6991
72de5009 6992 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6993
6994 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6995 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6996 else
6997 {
6998 print_vma (section->sh_addralign, DEC);
6999 putchar ('\n');
7000 }
7001 }
5477e8a0 7002 else if (do_section_details)
595cf52e 7003 {
55cc53e9 7004 putchar (' ');
595cf52e
L
7005 print_vma (section->sh_addr, LONG_HEX);
7006 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7007 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7008 else
7009 {
7010 printf (" ");
7011 print_vma (section->sh_offset, LONG_HEX);
7012 }
72de5009 7013 printf (" %u\n ", section->sh_link);
595cf52e 7014 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7015 putchar (' ');
595cf52e
L
7016 print_vma (section->sh_entsize, LONG_HEX);
7017
72de5009
AM
7018 printf (" %-16u %lu\n",
7019 section->sh_info,
595cf52e
L
7020 (unsigned long) section->sh_addralign);
7021 }
f7a99963
NC
7022 else
7023 {
7024 putchar (' ');
7025 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7026 if ((long) section->sh_offset == section->sh_offset)
7027 printf (" %8.8lx", (unsigned long) section->sh_offset);
7028 else
7029 {
7030 printf (" ");
7031 print_vma (section->sh_offset, LONG_HEX);
7032 }
f7a99963
NC
7033 printf ("\n ");
7034 print_vma (section->sh_size, LONG_HEX);
7035 printf (" ");
7036 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7037
dda8d76d 7038 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7039
72de5009
AM
7040 printf (" %2u %3u %lu\n",
7041 section->sh_link,
7042 section->sh_info,
f7a99963
NC
7043 (unsigned long) section->sh_addralign);
7044 }
5477e8a0
L
7045
7046 if (do_section_details)
77115a4a 7047 {
dda8d76d 7048 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7049 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7050 {
7051 /* Minimum section size is 12 bytes for 32-bit compression
7052 header + 12 bytes for compressed data header. */
7053 unsigned char buf[24];
d8024a91 7054
77115a4a 7055 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7056 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7057 sizeof (buf), _("compression header")))
7058 {
7059 Elf_Internal_Chdr chdr;
d8024a91 7060
5844b465
NC
7061 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7062 printf (_(" [<corrupt>]\n"));
77115a4a 7063 else
5844b465
NC
7064 {
7065 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7066 printf (" ZLIB, ");
7067 else
7068 printf (_(" [<unknown>: 0x%x], "),
7069 chdr.ch_type);
7070 print_vma (chdr.ch_size, LONG_HEX);
7071 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7072 }
77115a4a
L
7073 }
7074 }
7075 }
252b5132
RH
7076 }
7077
5477e8a0 7078 if (!do_section_details)
3dbcc61d 7079 {
9fb71ee4
NC
7080 /* The ordering of the letters shown here matches the ordering of the
7081 corresponding SHF_xxx values, and hence the order in which these
7082 letters will be displayed to the user. */
7083 printf (_("Key to Flags:\n\
7084 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7085 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7086 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7087 switch (filedata->file_header.e_ident[EI_OSABI])
7088 {
7089 case ELFOSABI_GNU:
7090 case ELFOSABI_FREEBSD:
7091 printf (_("R (retain), "));
7092 /* Fall through */
7093 case ELFOSABI_NONE:
7094 printf (_("D (mbind), "));
7095 break;
7096 default:
7097 break;
7098 }
dda8d76d
NC
7099 if (filedata->file_header.e_machine == EM_X86_64
7100 || filedata->file_header.e_machine == EM_L1OM
7101 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7102 printf (_("l (large), "));
dda8d76d 7103 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7104 printf (_("y (purecode), "));
dda8d76d 7105 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7106 printf (_("v (VLE), "));
9fb71ee4 7107 printf ("p (processor specific)\n");
0b4362b0 7108 }
d1133906 7109
015dc7e1 7110 return true;
252b5132
RH
7111}
7112
015dc7e1 7113static bool
28d13567
AM
7114get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7115 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7116 char **strtab, unsigned long *strtablen)
7117{
7118 *strtab = NULL;
7119 *strtablen = 0;
7120 *symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms);
7121
7122 if (*symtab == NULL)
015dc7e1 7123 return false;
28d13567
AM
7124
7125 if (symsec->sh_link != 0)
7126 {
7127 Elf_Internal_Shdr *strsec;
7128
7129 if (symsec->sh_link >= filedata->file_header.e_shnum)
7130 {
7131 error (_("Bad sh_link in symbol table section\n"));
7132 free (*symtab);
7133 *symtab = NULL;
7134 *nsyms = 0;
015dc7e1 7135 return false;
28d13567
AM
7136 }
7137
7138 strsec = filedata->section_headers + symsec->sh_link;
7139
7140 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7141 1, strsec->sh_size, _("string table"));
7142 if (*strtab == NULL)
7143 {
7144 free (*symtab);
7145 *symtab = NULL;
7146 *nsyms = 0;
015dc7e1 7147 return false;
28d13567
AM
7148 }
7149 *strtablen = strsec->sh_size;
7150 }
015dc7e1 7151 return true;
28d13567
AM
7152}
7153
f5842774
L
7154static const char *
7155get_group_flags (unsigned int flags)
7156{
1449284b 7157 static char buff[128];
220453ec 7158
6d913794
NC
7159 if (flags == 0)
7160 return "";
7161 else if (flags == GRP_COMDAT)
7162 return "COMDAT ";
f5842774 7163
89246a0e
AM
7164 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7165 flags,
7166 flags & GRP_MASKOS ? _("<OS specific>") : "",
7167 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7168 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7169 ? _("<unknown>") : ""));
6d913794 7170
f5842774
L
7171 return buff;
7172}
7173
015dc7e1 7174static bool
dda8d76d 7175process_section_groups (Filedata * filedata)
f5842774 7176{
2cf0635d 7177 Elf_Internal_Shdr * section;
f5842774 7178 unsigned int i;
2cf0635d
NC
7179 struct group * group;
7180 Elf_Internal_Shdr * symtab_sec;
7181 Elf_Internal_Shdr * strtab_sec;
7182 Elf_Internal_Sym * symtab;
ba5cdace 7183 unsigned long num_syms;
2cf0635d 7184 char * strtab;
c256ffe7 7185 size_t strtab_size;
d1f5c6e3
L
7186
7187 /* Don't process section groups unless needed. */
7188 if (!do_unwind && !do_section_groups)
015dc7e1 7189 return true;
f5842774 7190
dda8d76d 7191 if (filedata->file_header.e_shnum == 0)
f5842774
L
7192 {
7193 if (do_section_groups)
ca0e11aa
NC
7194 {
7195 if (filedata->is_separate)
7196 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7197 filedata->file_name);
7198 else
7199 printf (_("\nThere are no section groups in this file.\n"));
7200 }
015dc7e1 7201 return true;
f5842774
L
7202 }
7203
dda8d76d 7204 if (filedata->section_headers == NULL)
f5842774
L
7205 {
7206 error (_("Section headers are not available!\n"));
fa1908fd 7207 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7208 return false;
f5842774
L
7209 }
7210
978c4450
AM
7211 filedata->section_headers_groups
7212 = (struct group **) calloc (filedata->file_header.e_shnum,
7213 sizeof (struct group *));
e4b17d5c 7214
978c4450 7215 if (filedata->section_headers_groups == NULL)
e4b17d5c 7216 {
8b73c356 7217 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7218 filedata->file_header.e_shnum);
015dc7e1 7219 return false;
e4b17d5c
L
7220 }
7221
f5842774 7222 /* Scan the sections for the group section. */
978c4450 7223 filedata->group_count = 0;
dda8d76d
NC
7224 for (i = 0, section = filedata->section_headers;
7225 i < filedata->file_header.e_shnum;
f5842774 7226 i++, section++)
e4b17d5c 7227 if (section->sh_type == SHT_GROUP)
978c4450 7228 filedata->group_count++;
e4b17d5c 7229
978c4450 7230 if (filedata->group_count == 0)
d1f5c6e3
L
7231 {
7232 if (do_section_groups)
ca0e11aa
NC
7233 {
7234 if (filedata->is_separate)
7235 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7236 filedata->file_name);
7237 else
7238 printf (_("\nThere are no section groups in this file.\n"));
7239 }
d1f5c6e3 7240
015dc7e1 7241 return true;
d1f5c6e3
L
7242 }
7243
978c4450
AM
7244 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7245 sizeof (struct group));
e4b17d5c 7246
978c4450 7247 if (filedata->section_groups == NULL)
e4b17d5c 7248 {
8b73c356 7249 error (_("Out of memory reading %lu groups\n"),
978c4450 7250 (unsigned long) filedata->group_count);
015dc7e1 7251 return false;
e4b17d5c
L
7252 }
7253
d1f5c6e3
L
7254 symtab_sec = NULL;
7255 strtab_sec = NULL;
7256 symtab = NULL;
ba5cdace 7257 num_syms = 0;
d1f5c6e3 7258 strtab = NULL;
c256ffe7 7259 strtab_size = 0;
ca0e11aa
NC
7260
7261 if (filedata->is_separate)
7262 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7263
978c4450 7264 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7265 i < filedata->file_header.e_shnum;
e4b17d5c 7266 i++, section++)
f5842774
L
7267 {
7268 if (section->sh_type == SHT_GROUP)
7269 {
dda8d76d 7270 const char * name = printable_section_name (filedata, section);
74e1a04b 7271 const char * group_name;
2cf0635d
NC
7272 unsigned char * start;
7273 unsigned char * indices;
f5842774 7274 unsigned int entry, j, size;
2cf0635d
NC
7275 Elf_Internal_Shdr * sec;
7276 Elf_Internal_Sym * sym;
f5842774
L
7277
7278 /* Get the symbol table. */
dda8d76d
NC
7279 if (section->sh_link >= filedata->file_header.e_shnum
7280 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7281 != SHT_SYMTAB))
f5842774
L
7282 {
7283 error (_("Bad sh_link in group section `%s'\n"), name);
7284 continue;
7285 }
d1f5c6e3
L
7286
7287 if (symtab_sec != sec)
7288 {
7289 symtab_sec = sec;
9db70fc3 7290 free (symtab);
dda8d76d 7291 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 7292 }
f5842774 7293
dd24e3da
NC
7294 if (symtab == NULL)
7295 {
7296 error (_("Corrupt header in group section `%s'\n"), name);
7297 continue;
7298 }
7299
ba5cdace
NC
7300 if (section->sh_info >= num_syms)
7301 {
7302 error (_("Bad sh_info in group section `%s'\n"), name);
7303 continue;
7304 }
7305
f5842774
L
7306 sym = symtab + section->sh_info;
7307
7308 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7309 {
4fbb74a6 7310 if (sym->st_shndx == 0
dda8d76d 7311 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7312 {
7313 error (_("Bad sh_info in group section `%s'\n"), name);
7314 continue;
7315 }
ba2685cc 7316
b9e920ec
AM
7317 group_name = SECTION_NAME_PRINT (filedata->section_headers
7318 + sym->st_shndx);
c256ffe7 7319 strtab_sec = NULL;
9db70fc3 7320 free (strtab);
f5842774 7321 strtab = NULL;
c256ffe7 7322 strtab_size = 0;
f5842774
L
7323 }
7324 else
7325 {
7326 /* Get the string table. */
dda8d76d 7327 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7328 {
7329 strtab_sec = NULL;
9db70fc3 7330 free (strtab);
c256ffe7
JJ
7331 strtab = NULL;
7332 strtab_size = 0;
7333 }
7334 else if (strtab_sec
dda8d76d 7335 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7336 {
7337 strtab_sec = sec;
9db70fc3 7338 free (strtab);
071436c6 7339
dda8d76d 7340 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7341 1, strtab_sec->sh_size,
7342 _("string table"));
c256ffe7 7343 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7344 }
c256ffe7 7345 group_name = sym->st_name < strtab_size
2b692964 7346 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7347 }
7348
c9c1d674
EG
7349 /* PR 17531: file: loop. */
7350 if (section->sh_entsize > section->sh_size)
7351 {
7352 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7353 printable_section_name (filedata, section),
8066deb1
AM
7354 (unsigned long) section->sh_entsize,
7355 (unsigned long) section->sh_size);
61dd8e19 7356 continue;
c9c1d674
EG
7357 }
7358
dda8d76d 7359 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7360 1, section->sh_size,
7361 _("section data"));
59245841
NC
7362 if (start == NULL)
7363 continue;
f5842774
L
7364
7365 indices = start;
7366 size = (section->sh_size / section->sh_entsize) - 1;
7367 entry = byte_get (indices, 4);
7368 indices += 4;
e4b17d5c
L
7369
7370 if (do_section_groups)
7371 {
2b692964 7372 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7373 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7374
e4b17d5c
L
7375 printf (_(" [Index] Name\n"));
7376 }
7377
7378 group->group_index = i;
7379
f5842774
L
7380 for (j = 0; j < size; j++)
7381 {
2cf0635d 7382 struct group_list * g;
e4b17d5c 7383
f5842774
L
7384 entry = byte_get (indices, 4);
7385 indices += 4;
7386
dda8d76d 7387 if (entry >= filedata->file_header.e_shnum)
391cb864 7388 {
57028622
NC
7389 static unsigned num_group_errors = 0;
7390
7391 if (num_group_errors ++ < 10)
7392 {
7393 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7394 entry, i, filedata->file_header.e_shnum - 1);
57028622 7395 if (num_group_errors == 10)
67ce483b 7396 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7397 }
391cb864
L
7398 continue;
7399 }
391cb864 7400
978c4450 7401 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7402 {
d1f5c6e3
L
7403 if (entry)
7404 {
57028622
NC
7405 static unsigned num_errs = 0;
7406
7407 if (num_errs ++ < 10)
7408 {
7409 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7410 entry, i,
978c4450 7411 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7412 if (num_errs == 10)
7413 warn (_("Further error messages about already contained group sections suppressed\n"));
7414 }
d1f5c6e3
L
7415 continue;
7416 }
7417 else
7418 {
7419 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7420 section group. We just warn it the first time
d1f5c6e3 7421 and ignore it afterwards. */
015dc7e1 7422 static bool warned = false;
d1f5c6e3
L
7423 if (!warned)
7424 {
7425 error (_("section 0 in group section [%5u]\n"),
978c4450 7426 filedata->section_headers_groups [entry]->group_index);
015dc7e1 7427 warned = true;
d1f5c6e3
L
7428 }
7429 }
e4b17d5c
L
7430 }
7431
978c4450 7432 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7433
7434 if (do_section_groups)
7435 {
dda8d76d
NC
7436 sec = filedata->section_headers + entry;
7437 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7438 }
7439
3f5e193b 7440 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7441 g->section_index = entry;
7442 g->next = group->root;
7443 group->root = g;
f5842774
L
7444 }
7445
9db70fc3 7446 free (start);
e4b17d5c
L
7447
7448 group++;
f5842774
L
7449 }
7450 }
7451
9db70fc3
AM
7452 free (symtab);
7453 free (strtab);
015dc7e1 7454 return true;
f5842774
L
7455}
7456
28f997cf
TG
7457/* Data used to display dynamic fixups. */
7458
7459struct ia64_vms_dynfixup
7460{
7461 bfd_vma needed_ident; /* Library ident number. */
7462 bfd_vma needed; /* Index in the dstrtab of the library name. */
7463 bfd_vma fixup_needed; /* Index of the library. */
7464 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7465 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7466};
7467
7468/* Data used to display dynamic relocations. */
7469
7470struct ia64_vms_dynimgrela
7471{
7472 bfd_vma img_rela_cnt; /* Number of relocations. */
7473 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7474};
7475
7476/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7477 library). */
7478
015dc7e1 7479static bool
dda8d76d
NC
7480dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7481 struct ia64_vms_dynfixup * fixup,
7482 const char * strtab,
7483 unsigned int strtab_sz)
28f997cf 7484{
32ec8896 7485 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7486 long i;
32ec8896 7487 const char * lib_name;
28f997cf 7488
978c4450
AM
7489 imfs = get_data (NULL, filedata,
7490 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7491 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7492 _("dynamic section image fixups"));
7493 if (!imfs)
015dc7e1 7494 return false;
28f997cf
TG
7495
7496 if (fixup->needed < strtab_sz)
7497 lib_name = strtab + fixup->needed;
7498 else
7499 {
32ec8896 7500 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7501 (unsigned long) fixup->needed);
28f997cf
TG
7502 lib_name = "???";
7503 }
736990c4 7504
28f997cf
TG
7505 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7506 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7507 printf
7508 (_("Seg Offset Type SymVec DataType\n"));
7509
7510 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7511 {
7512 unsigned int type;
7513 const char *rtype;
7514
7515 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7516 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7517 type = BYTE_GET (imfs [i].type);
7518 rtype = elf_ia64_reloc_type (type);
7519 if (rtype == NULL)
7520 printf (" 0x%08x ", type);
7521 else
7522 printf (" %-32s ", rtype);
7523 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7524 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7525 }
7526
7527 free (imfs);
015dc7e1 7528 return true;
28f997cf
TG
7529}
7530
7531/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7532
015dc7e1 7533static bool
dda8d76d 7534dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7535{
7536 Elf64_External_VMS_IMAGE_RELA *imrs;
7537 long i;
7538
978c4450
AM
7539 imrs = get_data (NULL, filedata,
7540 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 7541 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7542 _("dynamic section image relocations"));
28f997cf 7543 if (!imrs)
015dc7e1 7544 return false;
28f997cf
TG
7545
7546 printf (_("\nImage relocs\n"));
7547 printf
7548 (_("Seg Offset Type Addend Seg Sym Off\n"));
7549
7550 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7551 {
7552 unsigned int type;
7553 const char *rtype;
7554
7555 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7556 printf ("%08" BFD_VMA_FMT "x ",
7557 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7558 type = BYTE_GET (imrs [i].type);
7559 rtype = elf_ia64_reloc_type (type);
7560 if (rtype == NULL)
7561 printf ("0x%08x ", type);
7562 else
7563 printf ("%-31s ", rtype);
7564 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7565 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7566 printf ("%08" BFD_VMA_FMT "x\n",
7567 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7568 }
7569
7570 free (imrs);
015dc7e1 7571 return true;
28f997cf
TG
7572}
7573
7574/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7575
015dc7e1 7576static bool
dda8d76d 7577process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7578{
7579 struct ia64_vms_dynfixup fixup;
7580 struct ia64_vms_dynimgrela imgrela;
7581 Elf_Internal_Dyn *entry;
28f997cf
TG
7582 bfd_vma strtab_off = 0;
7583 bfd_vma strtab_sz = 0;
7584 char *strtab = NULL;
015dc7e1 7585 bool res = true;
28f997cf
TG
7586
7587 memset (&fixup, 0, sizeof (fixup));
7588 memset (&imgrela, 0, sizeof (imgrela));
7589
7590 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
7591 for (entry = filedata->dynamic_section;
7592 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
7593 entry++)
7594 {
7595 switch (entry->d_tag)
7596 {
7597 case DT_IA_64_VMS_STRTAB_OFFSET:
7598 strtab_off = entry->d_un.d_val;
7599 break;
7600 case DT_STRSZ:
7601 strtab_sz = entry->d_un.d_val;
7602 if (strtab == NULL)
978c4450
AM
7603 strtab = get_data (NULL, filedata,
7604 filedata->dynamic_addr + strtab_off,
28f997cf 7605 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7606 if (strtab == NULL)
7607 strtab_sz = 0;
28f997cf
TG
7608 break;
7609
7610 case DT_IA_64_VMS_NEEDED_IDENT:
7611 fixup.needed_ident = entry->d_un.d_val;
7612 break;
7613 case DT_NEEDED:
7614 fixup.needed = entry->d_un.d_val;
7615 break;
7616 case DT_IA_64_VMS_FIXUP_NEEDED:
7617 fixup.fixup_needed = entry->d_un.d_val;
7618 break;
7619 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7620 fixup.fixup_rela_cnt = entry->d_un.d_val;
7621 break;
7622 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7623 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7624 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 7625 res = false;
28f997cf 7626 break;
28f997cf
TG
7627 case DT_IA_64_VMS_IMG_RELA_CNT:
7628 imgrela.img_rela_cnt = entry->d_un.d_val;
7629 break;
7630 case DT_IA_64_VMS_IMG_RELA_OFF:
7631 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7632 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 7633 res = false;
28f997cf
TG
7634 break;
7635
7636 default:
7637 break;
7638 }
7639 }
7640
9db70fc3 7641 free (strtab);
28f997cf
TG
7642
7643 return res;
7644}
7645
85b1c36d 7646static struct
566b0d53 7647{
2cf0635d 7648 const char * name;
566b0d53
L
7649 int reloc;
7650 int size;
7651 int rela;
32ec8896
NC
7652}
7653 dynamic_relocations [] =
566b0d53 7654{
015dc7e1
AM
7655 { "REL", DT_REL, DT_RELSZ, false },
7656 { "RELA", DT_RELA, DT_RELASZ, true },
32ec8896 7657 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7658};
7659
252b5132 7660/* Process the reloc section. */
18bd398b 7661
015dc7e1 7662static bool
dda8d76d 7663process_relocs (Filedata * filedata)
252b5132 7664{
b34976b6
AM
7665 unsigned long rel_size;
7666 unsigned long rel_offset;
252b5132 7667
252b5132 7668 if (!do_reloc)
015dc7e1 7669 return true;
252b5132
RH
7670
7671 if (do_using_dynamic)
7672 {
32ec8896 7673 int is_rela;
2cf0635d 7674 const char * name;
015dc7e1 7675 bool has_dynamic_reloc;
566b0d53 7676 unsigned int i;
0de14b54 7677
015dc7e1 7678 has_dynamic_reloc = false;
252b5132 7679
566b0d53 7680 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7681 {
566b0d53
L
7682 is_rela = dynamic_relocations [i].rela;
7683 name = dynamic_relocations [i].name;
978c4450
AM
7684 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
7685 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 7686
32ec8896 7687 if (rel_size)
015dc7e1 7688 has_dynamic_reloc = true;
566b0d53
L
7689
7690 if (is_rela == UNKNOWN)
aa903cfb 7691 {
566b0d53 7692 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 7693 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
7694 {
7695 case DT_REL:
015dc7e1 7696 is_rela = false;
566b0d53
L
7697 break;
7698 case DT_RELA:
015dc7e1 7699 is_rela = true;
566b0d53
L
7700 break;
7701 }
aa903cfb 7702 }
252b5132 7703
566b0d53
L
7704 if (rel_size)
7705 {
ca0e11aa
NC
7706 if (filedata->is_separate)
7707 printf
7708 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
7709 filedata->file_name, name, rel_offset, rel_size);
7710 else
7711 printf
7712 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7713 name, rel_offset, rel_size);
252b5132 7714
dda8d76d
NC
7715 dump_relocations (filedata,
7716 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7717 rel_size,
978c4450
AM
7718 filedata->dynamic_symbols,
7719 filedata->num_dynamic_syms,
7720 filedata->dynamic_strings,
7721 filedata->dynamic_strings_length,
015dc7e1 7722 is_rela, true /* is_dynamic */);
566b0d53 7723 }
252b5132 7724 }
566b0d53 7725
dda8d76d
NC
7726 if (is_ia64_vms (filedata))
7727 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 7728 has_dynamic_reloc = true;
28f997cf 7729
566b0d53 7730 if (! has_dynamic_reloc)
ca0e11aa
NC
7731 {
7732 if (filedata->is_separate)
7733 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
7734 filedata->file_name);
7735 else
7736 printf (_("\nThere are no dynamic relocations in this file.\n"));
7737 }
252b5132
RH
7738 }
7739 else
7740 {
2cf0635d 7741 Elf_Internal_Shdr * section;
b34976b6 7742 unsigned long i;
015dc7e1 7743 bool found = false;
252b5132 7744
dda8d76d
NC
7745 for (i = 0, section = filedata->section_headers;
7746 i < filedata->file_header.e_shnum;
b34976b6 7747 i++, section++)
252b5132
RH
7748 {
7749 if ( section->sh_type != SHT_RELA
7750 && section->sh_type != SHT_REL)
7751 continue;
7752
7753 rel_offset = section->sh_offset;
7754 rel_size = section->sh_size;
7755
7756 if (rel_size)
7757 {
b34976b6 7758 int is_rela;
d3a49aa8 7759 unsigned long num_rela;
103f02d3 7760
ca0e11aa
NC
7761 if (filedata->is_separate)
7762 printf (_("\nIn linked file '%s' relocation section "),
7763 filedata->file_name);
7764 else
7765 printf (_("\nRelocation section "));
252b5132 7766
dda8d76d 7767 if (filedata->string_table == NULL)
19936277 7768 printf ("%d", section->sh_name);
252b5132 7769 else
dda8d76d 7770 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7771
d3a49aa8
AM
7772 num_rela = rel_size / section->sh_entsize;
7773 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7774 " at offset 0x%lx contains %lu entries:\n",
7775 num_rela),
7776 rel_offset, num_rela);
252b5132 7777
d79b3d50
NC
7778 is_rela = section->sh_type == SHT_RELA;
7779
4fbb74a6 7780 if (section->sh_link != 0
dda8d76d 7781 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7782 {
2cf0635d
NC
7783 Elf_Internal_Shdr * symsec;
7784 Elf_Internal_Sym * symtab;
d79b3d50 7785 unsigned long nsyms;
c256ffe7 7786 unsigned long strtablen = 0;
2cf0635d 7787 char * strtab = NULL;
57346661 7788
dda8d76d 7789 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7790 if (symsec->sh_type != SHT_SYMTAB
7791 && symsec->sh_type != SHT_DYNSYM)
7792 continue;
7793
28d13567
AM
7794 if (!get_symtab (filedata, symsec,
7795 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7796 continue;
252b5132 7797
dda8d76d 7798 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7799 symtab, nsyms, strtab, strtablen,
7800 is_rela,
7801 symsec->sh_type == SHT_DYNSYM);
9db70fc3 7802 free (strtab);
d79b3d50
NC
7803 free (symtab);
7804 }
7805 else
dda8d76d 7806 dump_relocations (filedata, rel_offset, rel_size,
32ec8896 7807 NULL, 0, NULL, 0, is_rela,
015dc7e1 7808 false /* is_dynamic */);
252b5132 7809
015dc7e1 7810 found = true;
252b5132
RH
7811 }
7812 }
7813
7814 if (! found)
45ac8f4f
NC
7815 {
7816 /* Users sometimes forget the -D option, so try to be helpful. */
7817 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7818 {
978c4450 7819 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 7820 {
ca0e11aa
NC
7821 if (filedata->is_separate)
7822 printf (_("\nThere are no static relocations in linked file '%s'."),
7823 filedata->file_name);
7824 else
7825 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
7826 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7827
7828 break;
7829 }
7830 }
7831 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
7832 {
7833 if (filedata->is_separate)
7834 printf (_("\nThere are no relocations in linked file '%s'.\n"),
7835 filedata->file_name);
7836 else
7837 printf (_("\nThere are no relocations in this file.\n"));
7838 }
45ac8f4f 7839 }
252b5132
RH
7840 }
7841
015dc7e1 7842 return true;
252b5132
RH
7843}
7844
4d6ed7c8
NC
7845/* An absolute address consists of a section and an offset. If the
7846 section is NULL, the offset itself is the address, otherwise, the
7847 address equals to LOAD_ADDRESS(section) + offset. */
7848
7849struct absaddr
948f632f
DA
7850{
7851 unsigned short section;
7852 bfd_vma offset;
7853};
4d6ed7c8 7854
948f632f
DA
7855/* Find the nearest symbol at or below ADDR. Returns the symbol
7856 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7857
4d6ed7c8 7858static void
dda8d76d
NC
7859find_symbol_for_address (Filedata * filedata,
7860 Elf_Internal_Sym * symtab,
7861 unsigned long nsyms,
7862 const char * strtab,
7863 unsigned long strtab_size,
7864 struct absaddr addr,
7865 const char ** symname,
7866 bfd_vma * offset)
4d6ed7c8 7867{
d3ba0551 7868 bfd_vma dist = 0x100000;
2cf0635d 7869 Elf_Internal_Sym * sym;
948f632f
DA
7870 Elf_Internal_Sym * beg;
7871 Elf_Internal_Sym * end;
2cf0635d 7872 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7873
0b6ae522 7874 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7875 beg = symtab;
7876 end = symtab + nsyms;
0b6ae522 7877
948f632f 7878 while (beg < end)
4d6ed7c8 7879 {
948f632f
DA
7880 bfd_vma value;
7881
7882 sym = beg + (end - beg) / 2;
0b6ae522 7883
948f632f 7884 value = sym->st_value;
0b6ae522
DJ
7885 REMOVE_ARCH_BITS (value);
7886
948f632f 7887 if (sym->st_name != 0
4d6ed7c8 7888 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7889 && addr.offset >= value
7890 && addr.offset - value < dist)
4d6ed7c8
NC
7891 {
7892 best = sym;
0b6ae522 7893 dist = addr.offset - value;
4d6ed7c8
NC
7894 if (!dist)
7895 break;
7896 }
948f632f
DA
7897
7898 if (addr.offset < value)
7899 end = sym;
7900 else
7901 beg = sym + 1;
4d6ed7c8 7902 }
1b31d05e 7903
4d6ed7c8
NC
7904 if (best)
7905 {
57346661 7906 *symname = (best->st_name >= strtab_size
2b692964 7907 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7908 *offset = dist;
7909 return;
7910 }
1b31d05e 7911
4d6ed7c8
NC
7912 *symname = NULL;
7913 *offset = addr.offset;
7914}
7915
32ec8896 7916static /* signed */ int
948f632f
DA
7917symcmp (const void *p, const void *q)
7918{
7919 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7920 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7921
7922 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7923}
7924
7925/* Process the unwind section. */
7926
7927#include "unwind-ia64.h"
7928
7929struct ia64_unw_table_entry
7930{
7931 struct absaddr start;
7932 struct absaddr end;
7933 struct absaddr info;
7934};
7935
7936struct ia64_unw_aux_info
7937{
32ec8896
NC
7938 struct ia64_unw_table_entry * table; /* Unwind table. */
7939 unsigned long table_len; /* Length of unwind table. */
7940 unsigned char * info; /* Unwind info. */
7941 unsigned long info_size; /* Size of unwind info. */
7942 bfd_vma info_addr; /* Starting address of unwind info. */
7943 bfd_vma seg_base; /* Starting address of segment. */
7944 Elf_Internal_Sym * symtab; /* The symbol table. */
7945 unsigned long nsyms; /* Number of symbols. */
7946 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7947 unsigned long nfuns; /* Number of entries in funtab. */
7948 char * strtab; /* The string table. */
7949 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7950};
7951
015dc7e1 7952static bool
dda8d76d 7953dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7954{
2cf0635d 7955 struct ia64_unw_table_entry * tp;
948f632f 7956 unsigned long j, nfuns;
4d6ed7c8 7957 int in_body;
015dc7e1 7958 bool res = true;
7036c0e1 7959
948f632f
DA
7960 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7961 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7962 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7963 aux->funtab[nfuns++] = aux->symtab[j];
7964 aux->nfuns = nfuns;
7965 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7966
4d6ed7c8
NC
7967 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7968 {
7969 bfd_vma stamp;
7970 bfd_vma offset;
2cf0635d
NC
7971 const unsigned char * dp;
7972 const unsigned char * head;
53774b7e 7973 const unsigned char * end;
2cf0635d 7974 const char * procname;
4d6ed7c8 7975
dda8d76d 7976 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7977 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7978
7979 fputs ("\n<", stdout);
7980
7981 if (procname)
7982 {
7983 fputs (procname, stdout);
7984
7985 if (offset)
7986 printf ("+%lx", (unsigned long) offset);
7987 }
7988
7989 fputs (">: [", stdout);
7990 print_vma (tp->start.offset, PREFIX_HEX);
7991 fputc ('-', stdout);
7992 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7993 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7994 (unsigned long) (tp->info.offset - aux->seg_base));
7995
53774b7e
NC
7996 /* PR 17531: file: 86232b32. */
7997 if (aux->info == NULL)
7998 continue;
7999
97c0a079
AM
8000 offset = tp->info.offset;
8001 if (tp->info.section)
8002 {
8003 if (tp->info.section >= filedata->file_header.e_shnum)
8004 {
8005 warn (_("Invalid section %u in table entry %ld\n"),
8006 tp->info.section, (long) (tp - aux->table));
015dc7e1 8007 res = false;
97c0a079
AM
8008 continue;
8009 }
8010 offset += filedata->section_headers[tp->info.section].sh_addr;
8011 }
8012 offset -= aux->info_addr;
53774b7e 8013 /* PR 17531: file: 0997b4d1. */
90679903
AM
8014 if (offset >= aux->info_size
8015 || aux->info_size - offset < 8)
53774b7e
NC
8016 {
8017 warn (_("Invalid offset %lx in table entry %ld\n"),
8018 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8019 res = false;
53774b7e
NC
8020 continue;
8021 }
8022
97c0a079 8023 head = aux->info + offset;
a4a00738 8024 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8025
86f55779 8026 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8027 (unsigned) UNW_VER (stamp),
8028 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8029 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8030 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8031 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8032
8033 if (UNW_VER (stamp) != 1)
8034 {
2b692964 8035 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8036 continue;
8037 }
8038
8039 in_body = 0;
53774b7e
NC
8040 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8041 /* PR 17531: file: 16ceda89. */
8042 if (end > aux->info + aux->info_size)
8043 end = aux->info + aux->info_size;
8044 for (dp = head + 8; dp < end;)
b4477bc8 8045 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8046 }
948f632f
DA
8047
8048 free (aux->funtab);
32ec8896
NC
8049
8050 return res;
4d6ed7c8
NC
8051}
8052
015dc7e1 8053static bool
dda8d76d
NC
8054slurp_ia64_unwind_table (Filedata * filedata,
8055 struct ia64_unw_aux_info * aux,
8056 Elf_Internal_Shdr * sec)
4d6ed7c8 8057{
89fac5e3 8058 unsigned long size, nrelas, i;
2cf0635d
NC
8059 Elf_Internal_Phdr * seg;
8060 struct ia64_unw_table_entry * tep;
8061 Elf_Internal_Shdr * relsec;
8062 Elf_Internal_Rela * rela;
8063 Elf_Internal_Rela * rp;
8064 unsigned char * table;
8065 unsigned char * tp;
8066 Elf_Internal_Sym * sym;
8067 const char * relname;
4d6ed7c8 8068
53774b7e
NC
8069 aux->table_len = 0;
8070
4d6ed7c8
NC
8071 /* First, find the starting address of the segment that includes
8072 this section: */
8073
dda8d76d 8074 if (filedata->file_header.e_phnum)
4d6ed7c8 8075 {
dda8d76d 8076 if (! get_program_headers (filedata))
015dc7e1 8077 return false;
4d6ed7c8 8078
dda8d76d
NC
8079 for (seg = filedata->program_headers;
8080 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8081 ++seg)
4d6ed7c8
NC
8082 {
8083 if (seg->p_type != PT_LOAD)
8084 continue;
8085
8086 if (sec->sh_addr >= seg->p_vaddr
8087 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8088 {
8089 aux->seg_base = seg->p_vaddr;
8090 break;
8091 }
8092 }
4d6ed7c8
NC
8093 }
8094
8095 /* Second, build the unwind table from the contents of the unwind section: */
8096 size = sec->sh_size;
dda8d76d 8097 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8098 _("unwind table"));
a6e9f9df 8099 if (!table)
015dc7e1 8100 return false;
4d6ed7c8 8101
53774b7e 8102 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8103 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8104 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8105 tep = aux->table;
53774b7e
NC
8106
8107 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8108 {
8109 tep->start.section = SHN_UNDEF;
8110 tep->end.section = SHN_UNDEF;
8111 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8112 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8113 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8114 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8115 tep->start.offset += aux->seg_base;
8116 tep->end.offset += aux->seg_base;
8117 tep->info.offset += aux->seg_base;
8118 }
8119 free (table);
8120
41e92641 8121 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8122 for (relsec = filedata->section_headers;
8123 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8124 ++relsec)
8125 {
8126 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8127 || relsec->sh_info >= filedata->file_header.e_shnum
8128 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8129 continue;
8130
dda8d76d 8131 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8132 & rela, & nrelas))
53774b7e
NC
8133 {
8134 free (aux->table);
8135 aux->table = NULL;
8136 aux->table_len = 0;
015dc7e1 8137 return false;
53774b7e 8138 }
4d6ed7c8
NC
8139
8140 for (rp = rela; rp < rela + nrelas; ++rp)
8141 {
4770fb94 8142 unsigned int sym_ndx;
726bd37d
AM
8143 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8144 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8145
82b1b41b
NC
8146 /* PR 17531: file: 9fa67536. */
8147 if (relname == NULL)
8148 {
726bd37d 8149 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8150 continue;
8151 }
948f632f 8152
24d127aa 8153 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8154 {
82b1b41b 8155 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8156 continue;
8157 }
8158
89fac5e3 8159 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8160
53774b7e
NC
8161 /* PR 17531: file: 5bc8d9bf. */
8162 if (i >= aux->table_len)
8163 {
8164 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8165 continue;
8166 }
8167
4770fb94
AM
8168 sym_ndx = get_reloc_symindex (rp->r_info);
8169 if (sym_ndx >= aux->nsyms)
8170 {
8171 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8172 sym_ndx);
8173 continue;
8174 }
8175 sym = aux->symtab + sym_ndx;
8176
53774b7e 8177 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8178 {
8179 case 0:
8180 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8181 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8182 break;
8183 case 1:
8184 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8185 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8186 break;
8187 case 2:
8188 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8189 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8190 break;
8191 default:
8192 break;
8193 }
8194 }
8195
8196 free (rela);
8197 }
8198
015dc7e1 8199 return true;
4d6ed7c8
NC
8200}
8201
015dc7e1 8202static bool
dda8d76d 8203ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8204{
2cf0635d
NC
8205 Elf_Internal_Shdr * sec;
8206 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8207 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8208 struct ia64_unw_aux_info aux;
015dc7e1 8209 bool res = true;
f1467e33 8210
4d6ed7c8
NC
8211 memset (& aux, 0, sizeof (aux));
8212
dda8d76d 8213 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8214 {
28d13567 8215 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8216 {
28d13567 8217 if (aux.symtab)
4082ef84 8218 {
28d13567
AM
8219 error (_("Multiple symbol tables encountered\n"));
8220 free (aux.symtab);
8221 aux.symtab = NULL;
4082ef84 8222 free (aux.strtab);
28d13567 8223 aux.strtab = NULL;
4082ef84 8224 }
28d13567
AM
8225 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8226 &aux.strtab, &aux.strtab_size))
015dc7e1 8227 return false;
4d6ed7c8
NC
8228 }
8229 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8230 unwcount++;
8231 }
8232
8233 if (!unwcount)
8234 printf (_("\nThere are no unwind sections in this file.\n"));
8235
8236 while (unwcount-- > 0)
8237 {
2cf0635d 8238 char * suffix;
579f31ac
JJ
8239 size_t len, len2;
8240
dda8d76d
NC
8241 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8242 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8243 if (sec->sh_type == SHT_IA_64_UNWIND)
8244 {
8245 unwsec = sec;
8246 break;
8247 }
4082ef84
NC
8248 /* We have already counted the number of SHT_IA64_UNWIND
8249 sections so the loop above should never fail. */
8250 assert (unwsec != NULL);
579f31ac
JJ
8251
8252 unwstart = i + 1;
8253 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8254
e4b17d5c
L
8255 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8256 {
8257 /* We need to find which section group it is in. */
4082ef84 8258 struct group_list * g;
e4b17d5c 8259
978c4450
AM
8260 if (filedata->section_headers_groups == NULL
8261 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8262 i = filedata->file_header.e_shnum;
4082ef84 8263 else
e4b17d5c 8264 {
978c4450 8265 g = filedata->section_headers_groups[i]->root;
18bd398b 8266
4082ef84
NC
8267 for (; g != NULL; g = g->next)
8268 {
dda8d76d 8269 sec = filedata->section_headers + g->section_index;
e4b17d5c 8270
b9e920ec
AM
8271 if (SECTION_NAME_VALID (sec)
8272 && streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
4082ef84
NC
8273 break;
8274 }
8275
8276 if (g == NULL)
dda8d76d 8277 i = filedata->file_header.e_shnum;
4082ef84 8278 }
e4b17d5c 8279 }
b9e920ec 8280 else if (SECTION_NAME_VALID (unwsec)
e9b095a5
ML
8281 && startswith (SECTION_NAME (unwsec),
8282 ELF_STRING_ia64_unwind_once))
579f31ac 8283 {
18bd398b 8284 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
8285 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
8286 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8287 for (i = 0, sec = filedata->section_headers;
8288 i < filedata->file_header.e_shnum;
579f31ac 8289 ++i, ++sec)
b9e920ec 8290 if (SECTION_NAME_VALID (sec)
e9b095a5
ML
8291 && startswith (SECTION_NAME (sec),
8292 ELF_STRING_ia64_unwind_info_once)
18bd398b 8293 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8294 break;
8295 }
8296 else
8297 {
8298 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8299 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8300 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8301 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8302 suffix = "";
b9e920ec 8303 if (SECTION_NAME_VALID (unwsec)
e9b095a5 8304 && startswith (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind))
579f31ac 8305 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8306 for (i = 0, sec = filedata->section_headers;
8307 i < filedata->file_header.e_shnum;
579f31ac 8308 ++i, ++sec)
b9e920ec 8309 if (SECTION_NAME_VALID (sec)
e9b095a5 8310 && startswith (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info)
18bd398b 8311 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8312 break;
8313 }
8314
dda8d76d 8315 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8316 {
8317 printf (_("\nCould not find unwind info section for "));
8318
dda8d76d 8319 if (filedata->string_table == NULL)
579f31ac
JJ
8320 printf ("%d", unwsec->sh_name);
8321 else
dda8d76d 8322 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8323 }
8324 else
4d6ed7c8 8325 {
4d6ed7c8 8326 aux.info_addr = sec->sh_addr;
dda8d76d 8327 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8328 sec->sh_size,
8329 _("unwind info"));
59245841 8330 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8331
579f31ac 8332 printf (_("\nUnwind section "));
4d6ed7c8 8333
dda8d76d 8334 if (filedata->string_table == NULL)
579f31ac
JJ
8335 printf ("%d", unwsec->sh_name);
8336 else
dda8d76d 8337 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8338
579f31ac 8339 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8340 (unsigned long) unwsec->sh_offset,
89fac5e3 8341 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8342
dda8d76d 8343 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8344 && aux.table_len > 0)
dda8d76d 8345 dump_ia64_unwind (filedata, & aux);
579f31ac 8346
9db70fc3
AM
8347 free ((char *) aux.table);
8348 free ((char *) aux.info);
579f31ac
JJ
8349 aux.table = NULL;
8350 aux.info = NULL;
8351 }
4d6ed7c8 8352 }
4d6ed7c8 8353
9db70fc3
AM
8354 free (aux.symtab);
8355 free ((char *) aux.strtab);
32ec8896
NC
8356
8357 return res;
4d6ed7c8
NC
8358}
8359
3f5e193b 8360struct hppa_unw_table_entry
32ec8896
NC
8361{
8362 struct absaddr start;
8363 struct absaddr end;
8364 unsigned int Cannot_unwind:1; /* 0 */
8365 unsigned int Millicode:1; /* 1 */
8366 unsigned int Millicode_save_sr0:1; /* 2 */
8367 unsigned int Region_description:2; /* 3..4 */
8368 unsigned int reserved1:1; /* 5 */
8369 unsigned int Entry_SR:1; /* 6 */
8370 unsigned int Entry_FR:4; /* Number saved 7..10 */
8371 unsigned int Entry_GR:5; /* Number saved 11..15 */
8372 unsigned int Args_stored:1; /* 16 */
8373 unsigned int Variable_Frame:1; /* 17 */
8374 unsigned int Separate_Package_Body:1; /* 18 */
8375 unsigned int Frame_Extension_Millicode:1; /* 19 */
8376 unsigned int Stack_Overflow_Check:1; /* 20 */
8377 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8378 unsigned int Ada_Region:1; /* 22 */
8379 unsigned int cxx_info:1; /* 23 */
8380 unsigned int cxx_try_catch:1; /* 24 */
8381 unsigned int sched_entry_seq:1; /* 25 */
8382 unsigned int reserved2:1; /* 26 */
8383 unsigned int Save_SP:1; /* 27 */
8384 unsigned int Save_RP:1; /* 28 */
8385 unsigned int Save_MRP_in_frame:1; /* 29 */
8386 unsigned int extn_ptr_defined:1; /* 30 */
8387 unsigned int Cleanup_defined:1; /* 31 */
8388
8389 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8390 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8391 unsigned int Large_frame:1; /* 2 */
8392 unsigned int Pseudo_SP_Set:1; /* 3 */
8393 unsigned int reserved4:1; /* 4 */
8394 unsigned int Total_frame_size:27; /* 5..31 */
8395};
3f5e193b 8396
57346661 8397struct hppa_unw_aux_info
948f632f 8398{
32ec8896
NC
8399 struct hppa_unw_table_entry * table; /* Unwind table. */
8400 unsigned long table_len; /* Length of unwind table. */
8401 bfd_vma seg_base; /* Starting address of segment. */
8402 Elf_Internal_Sym * symtab; /* The symbol table. */
8403 unsigned long nsyms; /* Number of symbols. */
8404 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8405 unsigned long nfuns; /* Number of entries in funtab. */
8406 char * strtab; /* The string table. */
8407 unsigned long strtab_size; /* Size of string table. */
948f632f 8408};
57346661 8409
015dc7e1 8410static bool
dda8d76d 8411dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8412{
2cf0635d 8413 struct hppa_unw_table_entry * tp;
948f632f 8414 unsigned long j, nfuns;
015dc7e1 8415 bool res = true;
948f632f
DA
8416
8417 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8418 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8419 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8420 aux->funtab[nfuns++] = aux->symtab[j];
8421 aux->nfuns = nfuns;
8422 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8423
57346661
AM
8424 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8425 {
8426 bfd_vma offset;
2cf0635d 8427 const char * procname;
57346661 8428
dda8d76d 8429 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8430 aux->strtab_size, tp->start, &procname,
8431 &offset);
8432
8433 fputs ("\n<", stdout);
8434
8435 if (procname)
8436 {
8437 fputs (procname, stdout);
8438
8439 if (offset)
8440 printf ("+%lx", (unsigned long) offset);
8441 }
8442
8443 fputs (">: [", stdout);
8444 print_vma (tp->start.offset, PREFIX_HEX);
8445 fputc ('-', stdout);
8446 print_vma (tp->end.offset, PREFIX_HEX);
8447 printf ("]\n\t");
8448
18bd398b
NC
8449#define PF(_m) if (tp->_m) printf (#_m " ");
8450#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8451 PF(Cannot_unwind);
8452 PF(Millicode);
8453 PF(Millicode_save_sr0);
18bd398b 8454 /* PV(Region_description); */
57346661
AM
8455 PF(Entry_SR);
8456 PV(Entry_FR);
8457 PV(Entry_GR);
8458 PF(Args_stored);
8459 PF(Variable_Frame);
8460 PF(Separate_Package_Body);
8461 PF(Frame_Extension_Millicode);
8462 PF(Stack_Overflow_Check);
8463 PF(Two_Instruction_SP_Increment);
8464 PF(Ada_Region);
8465 PF(cxx_info);
8466 PF(cxx_try_catch);
8467 PF(sched_entry_seq);
8468 PF(Save_SP);
8469 PF(Save_RP);
8470 PF(Save_MRP_in_frame);
8471 PF(extn_ptr_defined);
8472 PF(Cleanup_defined);
8473 PF(MPE_XL_interrupt_marker);
8474 PF(HP_UX_interrupt_marker);
8475 PF(Large_frame);
8476 PF(Pseudo_SP_Set);
8477 PV(Total_frame_size);
8478#undef PF
8479#undef PV
8480 }
8481
18bd398b 8482 printf ("\n");
948f632f
DA
8483
8484 free (aux->funtab);
32ec8896
NC
8485
8486 return res;
57346661
AM
8487}
8488
015dc7e1 8489static bool
dda8d76d
NC
8490slurp_hppa_unwind_table (Filedata * filedata,
8491 struct hppa_unw_aux_info * aux,
8492 Elf_Internal_Shdr * sec)
57346661 8493{
1c0751b2 8494 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8495 Elf_Internal_Phdr * seg;
8496 struct hppa_unw_table_entry * tep;
8497 Elf_Internal_Shdr * relsec;
8498 Elf_Internal_Rela * rela;
8499 Elf_Internal_Rela * rp;
8500 unsigned char * table;
8501 unsigned char * tp;
8502 Elf_Internal_Sym * sym;
8503 const char * relname;
57346661 8504
57346661
AM
8505 /* First, find the starting address of the segment that includes
8506 this section. */
dda8d76d 8507 if (filedata->file_header.e_phnum)
57346661 8508 {
dda8d76d 8509 if (! get_program_headers (filedata))
015dc7e1 8510 return false;
57346661 8511
dda8d76d
NC
8512 for (seg = filedata->program_headers;
8513 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8514 ++seg)
8515 {
8516 if (seg->p_type != PT_LOAD)
8517 continue;
8518
8519 if (sec->sh_addr >= seg->p_vaddr
8520 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8521 {
8522 aux->seg_base = seg->p_vaddr;
8523 break;
8524 }
8525 }
8526 }
8527
8528 /* Second, build the unwind table from the contents of the unwind
8529 section. */
8530 size = sec->sh_size;
dda8d76d 8531 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8532 _("unwind table"));
57346661 8533 if (!table)
015dc7e1 8534 return false;
57346661 8535
1c0751b2
DA
8536 unw_ent_size = 16;
8537 nentries = size / unw_ent_size;
8538 size = unw_ent_size * nentries;
57346661 8539
e3fdc001 8540 aux->table_len = nentries;
3f5e193b
NC
8541 tep = aux->table = (struct hppa_unw_table_entry *)
8542 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8543
1c0751b2 8544 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8545 {
8546 unsigned int tmp1, tmp2;
8547
8548 tep->start.section = SHN_UNDEF;
8549 tep->end.section = SHN_UNDEF;
8550
1c0751b2
DA
8551 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8552 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8553 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8554 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8555
8556 tep->start.offset += aux->seg_base;
8557 tep->end.offset += aux->seg_base;
57346661
AM
8558
8559 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8560 tep->Millicode = (tmp1 >> 30) & 0x1;
8561 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8562 tep->Region_description = (tmp1 >> 27) & 0x3;
8563 tep->reserved1 = (tmp1 >> 26) & 0x1;
8564 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8565 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8566 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8567 tep->Args_stored = (tmp1 >> 15) & 0x1;
8568 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8569 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8570 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8571 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8572 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8573 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8574 tep->cxx_info = (tmp1 >> 8) & 0x1;
8575 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8576 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8577 tep->reserved2 = (tmp1 >> 5) & 0x1;
8578 tep->Save_SP = (tmp1 >> 4) & 0x1;
8579 tep->Save_RP = (tmp1 >> 3) & 0x1;
8580 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8581 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8582 tep->Cleanup_defined = tmp1 & 0x1;
8583
8584 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8585 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8586 tep->Large_frame = (tmp2 >> 29) & 0x1;
8587 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8588 tep->reserved4 = (tmp2 >> 27) & 0x1;
8589 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8590 }
8591 free (table);
8592
8593 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8594 for (relsec = filedata->section_headers;
8595 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8596 ++relsec)
8597 {
8598 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8599 || relsec->sh_info >= filedata->file_header.e_shnum
8600 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8601 continue;
8602
dda8d76d 8603 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8604 & rela, & nrelas))
015dc7e1 8605 return false;
57346661
AM
8606
8607 for (rp = rela; rp < rela + nrelas; ++rp)
8608 {
4770fb94 8609 unsigned int sym_ndx;
726bd37d
AM
8610 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8611 relname = elf_hppa_reloc_type (r_type);
57346661 8612
726bd37d
AM
8613 if (relname == NULL)
8614 {
8615 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8616 continue;
8617 }
8618
57346661 8619 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 8620 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 8621 {
726bd37d 8622 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8623 continue;
8624 }
8625
8626 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8627 if (i >= aux->table_len)
8628 {
8629 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8630 continue;
8631 }
57346661 8632
4770fb94
AM
8633 sym_ndx = get_reloc_symindex (rp->r_info);
8634 if (sym_ndx >= aux->nsyms)
8635 {
8636 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8637 sym_ndx);
8638 continue;
8639 }
8640 sym = aux->symtab + sym_ndx;
8641
43f6cd05 8642 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8643 {
8644 case 0:
8645 aux->table[i].start.section = sym->st_shndx;
1e456d54 8646 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8647 break;
8648 case 1:
8649 aux->table[i].end.section = sym->st_shndx;
1e456d54 8650 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8651 break;
8652 default:
8653 break;
8654 }
8655 }
8656
8657 free (rela);
8658 }
8659
015dc7e1 8660 return true;
57346661
AM
8661}
8662
015dc7e1 8663static bool
dda8d76d 8664hppa_process_unwind (Filedata * filedata)
57346661 8665{
57346661 8666 struct hppa_unw_aux_info aux;
2cf0635d 8667 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8668 Elf_Internal_Shdr * sec;
18bd398b 8669 unsigned long i;
015dc7e1 8670 bool res = true;
57346661 8671
dda8d76d 8672 if (filedata->string_table == NULL)
015dc7e1 8673 return false;
1b31d05e
NC
8674
8675 memset (& aux, 0, sizeof (aux));
57346661 8676
dda8d76d 8677 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8678 {
28d13567 8679 if (sec->sh_type == SHT_SYMTAB)
57346661 8680 {
28d13567 8681 if (aux.symtab)
4082ef84 8682 {
28d13567
AM
8683 error (_("Multiple symbol tables encountered\n"));
8684 free (aux.symtab);
8685 aux.symtab = NULL;
4082ef84 8686 free (aux.strtab);
28d13567 8687 aux.strtab = NULL;
4082ef84 8688 }
28d13567
AM
8689 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8690 &aux.strtab, &aux.strtab_size))
015dc7e1 8691 return false;
57346661 8692 }
b9e920ec
AM
8693 else if (SECTION_NAME_VALID (sec)
8694 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8695 unwsec = sec;
8696 }
8697
8698 if (!unwsec)
8699 printf (_("\nThere are no unwind sections in this file.\n"));
8700
dda8d76d 8701 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8702 {
b9e920ec
AM
8703 if (SECTION_NAME_VALID (sec)
8704 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8705 {
43f6cd05 8706 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8707
d3a49aa8
AM
8708 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8709 "contains %lu entry:\n",
8710 "\nUnwind section '%s' at offset 0x%lx "
8711 "contains %lu entries:\n",
8712 num_unwind),
dda8d76d 8713 printable_section_name (filedata, sec),
57346661 8714 (unsigned long) sec->sh_offset,
d3a49aa8 8715 num_unwind);
57346661 8716
dda8d76d 8717 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 8718 res = false;
66b09c7e
S
8719
8720 if (res && aux.table_len > 0)
32ec8896 8721 {
dda8d76d 8722 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 8723 res = false;
32ec8896 8724 }
57346661 8725
9db70fc3 8726 free ((char *) aux.table);
57346661
AM
8727 aux.table = NULL;
8728 }
8729 }
8730
9db70fc3
AM
8731 free (aux.symtab);
8732 free ((char *) aux.strtab);
32ec8896
NC
8733
8734 return res;
57346661
AM
8735}
8736
0b6ae522
DJ
8737struct arm_section
8738{
a734115a
NC
8739 unsigned char * data; /* The unwind data. */
8740 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8741 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8742 unsigned long nrelas; /* The number of relocations. */
8743 unsigned int rel_type; /* REL or RELA ? */
8744 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8745};
8746
8747struct arm_unw_aux_info
8748{
dda8d76d 8749 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8750 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8751 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8752 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8753 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8754 char * strtab; /* The file's string table. */
8755 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8756};
8757
8758static const char *
dda8d76d
NC
8759arm_print_vma_and_name (Filedata * filedata,
8760 struct arm_unw_aux_info * aux,
8761 bfd_vma fn,
8762 struct absaddr addr)
0b6ae522
DJ
8763{
8764 const char *procname;
8765 bfd_vma sym_offset;
8766
8767 if (addr.section == SHN_UNDEF)
8768 addr.offset = fn;
8769
dda8d76d 8770 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8771 aux->strtab_size, addr, &procname,
8772 &sym_offset);
8773
8774 print_vma (fn, PREFIX_HEX);
8775
8776 if (procname)
8777 {
8778 fputs (" <", stdout);
8779 fputs (procname, stdout);
8780
8781 if (sym_offset)
8782 printf ("+0x%lx", (unsigned long) sym_offset);
8783 fputc ('>', stdout);
8784 }
8785
8786 return procname;
8787}
8788
8789static void
8790arm_free_section (struct arm_section *arm_sec)
8791{
9db70fc3
AM
8792 free (arm_sec->data);
8793 free (arm_sec->rela);
0b6ae522
DJ
8794}
8795
a734115a
NC
8796/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8797 cached section and install SEC instead.
8798 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8799 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8800 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8801 relocation's offset in ADDR.
1b31d05e
NC
8802 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8803 into the string table of the symbol associated with the reloc. If no
8804 reloc was applied store -1 there.
8805 5) Return TRUE upon success, FALSE otherwise. */
a734115a 8806
015dc7e1 8807static bool
dda8d76d
NC
8808get_unwind_section_word (Filedata * filedata,
8809 struct arm_unw_aux_info * aux,
1b31d05e
NC
8810 struct arm_section * arm_sec,
8811 Elf_Internal_Shdr * sec,
8812 bfd_vma word_offset,
8813 unsigned int * wordp,
8814 struct absaddr * addr,
8815 bfd_vma * sym_name)
0b6ae522
DJ
8816{
8817 Elf_Internal_Rela *rp;
8818 Elf_Internal_Sym *sym;
8819 const char * relname;
8820 unsigned int word;
015dc7e1 8821 bool wrapped;
0b6ae522 8822
e0a31db1 8823 if (sec == NULL || arm_sec == NULL)
015dc7e1 8824 return false;
e0a31db1 8825
0b6ae522
DJ
8826 addr->section = SHN_UNDEF;
8827 addr->offset = 0;
8828
1b31d05e
NC
8829 if (sym_name != NULL)
8830 *sym_name = (bfd_vma) -1;
8831
a734115a 8832 /* If necessary, update the section cache. */
0b6ae522
DJ
8833 if (sec != arm_sec->sec)
8834 {
8835 Elf_Internal_Shdr *relsec;
8836
8837 arm_free_section (arm_sec);
8838
8839 arm_sec->sec = sec;
dda8d76d 8840 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8841 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8842 arm_sec->rela = NULL;
8843 arm_sec->nrelas = 0;
8844
dda8d76d
NC
8845 for (relsec = filedata->section_headers;
8846 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8847 ++relsec)
8848 {
dda8d76d
NC
8849 if (relsec->sh_info >= filedata->file_header.e_shnum
8850 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8851 /* PR 15745: Check the section type as well. */
8852 || (relsec->sh_type != SHT_REL
8853 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8854 continue;
8855
a734115a 8856 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8857 if (relsec->sh_type == SHT_REL)
8858 {
dda8d76d 8859 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8860 relsec->sh_size,
8861 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 8862 return false;
0b6ae522 8863 }
1ae40aa4 8864 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8865 {
dda8d76d 8866 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8867 relsec->sh_size,
8868 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 8869 return false;
0b6ae522 8870 }
1ae40aa4 8871 break;
0b6ae522
DJ
8872 }
8873
8874 arm_sec->next_rela = arm_sec->rela;
8875 }
8876
a734115a 8877 /* If there is no unwind data we can do nothing. */
0b6ae522 8878 if (arm_sec->data == NULL)
015dc7e1 8879 return false;
0b6ae522 8880
e0a31db1 8881 /* If the offset is invalid then fail. */
f32ba729
NC
8882 if (/* PR 21343 *//* PR 18879 */
8883 sec->sh_size < 4
8884 || word_offset > (sec->sh_size - 4)
1a915552 8885 || ((bfd_signed_vma) word_offset) < 0)
015dc7e1 8886 return false;
e0a31db1 8887
a734115a 8888 /* Get the word at the required offset. */
0b6ae522
DJ
8889 word = byte_get (arm_sec->data + word_offset, 4);
8890
0eff7165
NC
8891 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8892 if (arm_sec->rela == NULL)
8893 {
8894 * wordp = word;
015dc7e1 8895 return true;
0eff7165
NC
8896 }
8897
a734115a 8898 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 8899 wrapped = false;
0b6ae522
DJ
8900 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8901 {
8902 bfd_vma prelval, offset;
8903
8904 if (rp->r_offset > word_offset && !wrapped)
8905 {
8906 rp = arm_sec->rela;
015dc7e1 8907 wrapped = true;
0b6ae522
DJ
8908 }
8909 if (rp->r_offset > word_offset)
8910 break;
8911
8912 if (rp->r_offset & 3)
8913 {
8914 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8915 (unsigned long) rp->r_offset);
8916 continue;
8917 }
8918
8919 if (rp->r_offset < word_offset)
8920 continue;
8921
74e1a04b
NC
8922 /* PR 17531: file: 027-161405-0.004 */
8923 if (aux->symtab == NULL)
8924 continue;
8925
0b6ae522
DJ
8926 if (arm_sec->rel_type == SHT_REL)
8927 {
8928 offset = word & 0x7fffffff;
8929 if (offset & 0x40000000)
8930 offset |= ~ (bfd_vma) 0x7fffffff;
8931 }
a734115a 8932 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8933 offset = rp->r_addend;
a734115a 8934 else
74e1a04b
NC
8935 {
8936 error (_("Unknown section relocation type %d encountered\n"),
8937 arm_sec->rel_type);
8938 break;
8939 }
0b6ae522 8940
071436c6
NC
8941 /* PR 17531 file: 027-1241568-0.004. */
8942 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8943 {
8944 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8945 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8946 break;
8947 }
8948
8949 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8950 offset += sym->st_value;
8951 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8952
a734115a 8953 /* Check that we are processing the expected reloc type. */
dda8d76d 8954 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8955 {
8956 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8957 if (relname == NULL)
8958 {
8959 warn (_("Skipping unknown ARM relocation type: %d\n"),
8960 (int) ELF32_R_TYPE (rp->r_info));
8961 continue;
8962 }
a734115a
NC
8963
8964 if (streq (relname, "R_ARM_NONE"))
8965 continue;
0b4362b0 8966
a734115a
NC
8967 if (! streq (relname, "R_ARM_PREL31"))
8968 {
071436c6 8969 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8970 continue;
8971 }
8972 }
dda8d76d 8973 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8974 {
8975 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8976 if (relname == NULL)
8977 {
8978 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8979 (int) ELF32_R_TYPE (rp->r_info));
8980 continue;
8981 }
0b4362b0 8982
a734115a
NC
8983 if (streq (relname, "R_C6000_NONE"))
8984 continue;
8985
8986 if (! streq (relname, "R_C6000_PREL31"))
8987 {
071436c6 8988 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8989 continue;
8990 }
8991
8992 prelval >>= 1;
8993 }
8994 else
74e1a04b
NC
8995 {
8996 /* This function currently only supports ARM and TI unwinders. */
8997 warn (_("Only TI and ARM unwinders are currently supported\n"));
8998 break;
8999 }
fa197c1c 9000
0b6ae522
DJ
9001 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
9002 addr->section = sym->st_shndx;
9003 addr->offset = offset;
74e1a04b 9004
1b31d05e
NC
9005 if (sym_name)
9006 * sym_name = sym->st_name;
0b6ae522
DJ
9007 break;
9008 }
9009
9010 *wordp = word;
9011 arm_sec->next_rela = rp;
9012
015dc7e1 9013 return true;
0b6ae522
DJ
9014}
9015
a734115a
NC
9016static const char *tic6x_unwind_regnames[16] =
9017{
0b4362b0
RM
9018 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9019 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9020 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9021};
fa197c1c 9022
0b6ae522 9023static void
fa197c1c 9024decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9025{
fa197c1c
PB
9026 int i;
9027
9028 for (i = 12; mask; mask >>= 1, i--)
9029 {
9030 if (mask & 1)
9031 {
9032 fputs (tic6x_unwind_regnames[i], stdout);
9033 if (mask > 1)
9034 fputs (", ", stdout);
9035 }
9036 }
9037}
0b6ae522
DJ
9038
9039#define ADVANCE \
9040 if (remaining == 0 && more_words) \
9041 { \
9042 data_offset += 4; \
dda8d76d 9043 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9044 data_offset, & word, & addr, NULL)) \
015dc7e1 9045 return false; \
0b6ae522
DJ
9046 remaining = 4; \
9047 more_words--; \
9048 } \
9049
9050#define GET_OP(OP) \
9051 ADVANCE; \
9052 if (remaining) \
9053 { \
9054 remaining--; \
9055 (OP) = word >> 24; \
9056 word <<= 8; \
9057 } \
9058 else \
9059 { \
2b692964 9060 printf (_("[Truncated opcode]\n")); \
015dc7e1 9061 return false; \
0b6ae522 9062 } \
cc5914eb 9063 printf ("0x%02x ", OP)
0b6ae522 9064
015dc7e1 9065static bool
dda8d76d
NC
9066decode_arm_unwind_bytecode (Filedata * filedata,
9067 struct arm_unw_aux_info * aux,
948f632f
DA
9068 unsigned int word,
9069 unsigned int remaining,
9070 unsigned int more_words,
9071 bfd_vma data_offset,
9072 Elf_Internal_Shdr * data_sec,
9073 struct arm_section * data_arm_sec)
fa197c1c
PB
9074{
9075 struct absaddr addr;
015dc7e1 9076 bool res = true;
0b6ae522
DJ
9077
9078 /* Decode the unwinding instructions. */
9079 while (1)
9080 {
9081 unsigned int op, op2;
9082
9083 ADVANCE;
9084 if (remaining == 0)
9085 break;
9086 remaining--;
9087 op = word >> 24;
9088 word <<= 8;
9089
cc5914eb 9090 printf (" 0x%02x ", op);
0b6ae522
DJ
9091
9092 if ((op & 0xc0) == 0x00)
9093 {
9094 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9095
cc5914eb 9096 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9097 }
9098 else if ((op & 0xc0) == 0x40)
9099 {
9100 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9101
cc5914eb 9102 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9103 }
9104 else if ((op & 0xf0) == 0x80)
9105 {
9106 GET_OP (op2);
9107 if (op == 0x80 && op2 == 0)
9108 printf (_("Refuse to unwind"));
9109 else
9110 {
9111 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9112 bool first = true;
0b6ae522 9113 int i;
2b692964 9114
0b6ae522
DJ
9115 printf ("pop {");
9116 for (i = 0; i < 12; i++)
9117 if (mask & (1 << i))
9118 {
9119 if (first)
015dc7e1 9120 first = false;
0b6ae522
DJ
9121 else
9122 printf (", ");
9123 printf ("r%d", 4 + i);
9124 }
9125 printf ("}");
9126 }
9127 }
9128 else if ((op & 0xf0) == 0x90)
9129 {
9130 if (op == 0x9d || op == 0x9f)
9131 printf (_(" [Reserved]"));
9132 else
cc5914eb 9133 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9134 }
9135 else if ((op & 0xf0) == 0xa0)
9136 {
9137 int end = 4 + (op & 0x07);
015dc7e1 9138 bool first = true;
0b6ae522 9139 int i;
61865e30 9140
0b6ae522
DJ
9141 printf (" pop {");
9142 for (i = 4; i <= end; i++)
9143 {
9144 if (first)
015dc7e1 9145 first = false;
0b6ae522
DJ
9146 else
9147 printf (", ");
9148 printf ("r%d", i);
9149 }
9150 if (op & 0x08)
9151 {
1b31d05e 9152 if (!first)
0b6ae522
DJ
9153 printf (", ");
9154 printf ("r14");
9155 }
9156 printf ("}");
9157 }
9158 else if (op == 0xb0)
9159 printf (_(" finish"));
9160 else if (op == 0xb1)
9161 {
9162 GET_OP (op2);
9163 if (op2 == 0 || (op2 & 0xf0) != 0)
9164 printf (_("[Spare]"));
9165 else
9166 {
9167 unsigned int mask = op2 & 0x0f;
015dc7e1 9168 bool first = true;
0b6ae522 9169 int i;
61865e30 9170
0b6ae522
DJ
9171 printf ("pop {");
9172 for (i = 0; i < 12; i++)
9173 if (mask & (1 << i))
9174 {
9175 if (first)
015dc7e1 9176 first = false;
0b6ae522
DJ
9177 else
9178 printf (", ");
9179 printf ("r%d", i);
9180 }
9181 printf ("}");
9182 }
9183 }
9184 else if (op == 0xb2)
9185 {
b115cf96 9186 unsigned char buf[9];
0b6ae522
DJ
9187 unsigned int i, len;
9188 unsigned long offset;
61865e30 9189
b115cf96 9190 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9191 {
9192 GET_OP (buf[i]);
9193 if ((buf[i] & 0x80) == 0)
9194 break;
9195 }
4082ef84 9196 if (i == sizeof (buf))
32ec8896 9197 {
27a45f42 9198 error (_("corrupt change to vsp\n"));
015dc7e1 9199 res = false;
32ec8896 9200 }
4082ef84
NC
9201 else
9202 {
015dc7e1 9203 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9204 assert (len == i + 1);
9205 offset = offset * 4 + 0x204;
9206 printf ("vsp = vsp + %ld", offset);
9207 }
0b6ae522 9208 }
61865e30 9209 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9210 {
61865e30
NC
9211 unsigned int first, last;
9212
9213 GET_OP (op2);
9214 first = op2 >> 4;
9215 last = op2 & 0x0f;
9216 if (op == 0xc8)
9217 first = first + 16;
9218 printf ("pop {D%d", first);
9219 if (last)
9220 printf ("-D%d", first + last);
9221 printf ("}");
9222 }
9223 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9224 {
9225 unsigned int count = op & 0x07;
9226
9227 printf ("pop {D8");
9228 if (count)
9229 printf ("-D%d", 8 + count);
9230 printf ("}");
9231 }
9232 else if (op >= 0xc0 && op <= 0xc5)
9233 {
9234 unsigned int count = op & 0x07;
9235
9236 printf (" pop {wR10");
9237 if (count)
9238 printf ("-wR%d", 10 + count);
9239 printf ("}");
9240 }
9241 else if (op == 0xc6)
9242 {
9243 unsigned int first, last;
9244
9245 GET_OP (op2);
9246 first = op2 >> 4;
9247 last = op2 & 0x0f;
9248 printf ("pop {wR%d", first);
9249 if (last)
9250 printf ("-wR%d", first + last);
9251 printf ("}");
9252 }
9253 else if (op == 0xc7)
9254 {
9255 GET_OP (op2);
9256 if (op2 == 0 || (op2 & 0xf0) != 0)
9257 printf (_("[Spare]"));
0b6ae522
DJ
9258 else
9259 {
61865e30 9260 unsigned int mask = op2 & 0x0f;
015dc7e1 9261 bool first = true;
61865e30
NC
9262 int i;
9263
9264 printf ("pop {");
9265 for (i = 0; i < 4; i++)
9266 if (mask & (1 << i))
9267 {
9268 if (first)
015dc7e1 9269 first = false;
61865e30
NC
9270 else
9271 printf (", ");
9272 printf ("wCGR%d", i);
9273 }
9274 printf ("}");
0b6ae522
DJ
9275 }
9276 }
61865e30 9277 else
32ec8896
NC
9278 {
9279 printf (_(" [unsupported opcode]"));
015dc7e1 9280 res = false;
32ec8896
NC
9281 }
9282
0b6ae522
DJ
9283 printf ("\n");
9284 }
32ec8896
NC
9285
9286 return res;
fa197c1c
PB
9287}
9288
015dc7e1 9289static bool
dda8d76d
NC
9290decode_tic6x_unwind_bytecode (Filedata * filedata,
9291 struct arm_unw_aux_info * aux,
948f632f
DA
9292 unsigned int word,
9293 unsigned int remaining,
9294 unsigned int more_words,
9295 bfd_vma data_offset,
9296 Elf_Internal_Shdr * data_sec,
9297 struct arm_section * data_arm_sec)
fa197c1c
PB
9298{
9299 struct absaddr addr;
9300
9301 /* Decode the unwinding instructions. */
9302 while (1)
9303 {
9304 unsigned int op, op2;
9305
9306 ADVANCE;
9307 if (remaining == 0)
9308 break;
9309 remaining--;
9310 op = word >> 24;
9311 word <<= 8;
9312
9cf03b7e 9313 printf (" 0x%02x ", op);
fa197c1c
PB
9314
9315 if ((op & 0xc0) == 0x00)
9316 {
9317 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9318 printf (" sp = sp + %d", offset);
fa197c1c
PB
9319 }
9320 else if ((op & 0xc0) == 0x80)
9321 {
9322 GET_OP (op2);
9323 if (op == 0x80 && op2 == 0)
9324 printf (_("Refuse to unwind"));
9325 else
9326 {
9327 unsigned int mask = ((op & 0x1f) << 8) | op2;
9328 if (op & 0x20)
9329 printf ("pop compact {");
9330 else
9331 printf ("pop {");
9332
9333 decode_tic6x_unwind_regmask (mask);
9334 printf("}");
9335 }
9336 }
9337 else if ((op & 0xf0) == 0xc0)
9338 {
9339 unsigned int reg;
9340 unsigned int nregs;
9341 unsigned int i;
9342 const char *name;
a734115a
NC
9343 struct
9344 {
32ec8896
NC
9345 unsigned int offset;
9346 unsigned int reg;
fa197c1c
PB
9347 } regpos[16];
9348
9349 /* Scan entire instruction first so that GET_OP output is not
9350 interleaved with disassembly. */
9351 nregs = 0;
9352 for (i = 0; nregs < (op & 0xf); i++)
9353 {
9354 GET_OP (op2);
9355 reg = op2 >> 4;
9356 if (reg != 0xf)
9357 {
9358 regpos[nregs].offset = i * 2;
9359 regpos[nregs].reg = reg;
9360 nregs++;
9361 }
9362
9363 reg = op2 & 0xf;
9364 if (reg != 0xf)
9365 {
9366 regpos[nregs].offset = i * 2 + 1;
9367 regpos[nregs].reg = reg;
9368 nregs++;
9369 }
9370 }
9371
9372 printf (_("pop frame {"));
18344509 9373 if (nregs == 0)
fa197c1c 9374 {
18344509
NC
9375 printf (_("*corrupt* - no registers specified"));
9376 }
9377 else
9378 {
9379 reg = nregs - 1;
9380 for (i = i * 2; i > 0; i--)
fa197c1c 9381 {
18344509
NC
9382 if (regpos[reg].offset == i - 1)
9383 {
9384 name = tic6x_unwind_regnames[regpos[reg].reg];
9385 if (reg > 0)
9386 reg--;
9387 }
9388 else
9389 name = _("[pad]");
fa197c1c 9390
18344509
NC
9391 fputs (name, stdout);
9392 if (i > 1)
9393 printf (", ");
9394 }
fa197c1c
PB
9395 }
9396
9397 printf ("}");
9398 }
9399 else if (op == 0xd0)
9400 printf (" MOV FP, SP");
9401 else if (op == 0xd1)
9402 printf (" __c6xabi_pop_rts");
9403 else if (op == 0xd2)
9404 {
9405 unsigned char buf[9];
9406 unsigned int i, len;
9407 unsigned long offset;
a734115a 9408
fa197c1c
PB
9409 for (i = 0; i < sizeof (buf); i++)
9410 {
9411 GET_OP (buf[i]);
9412 if ((buf[i] & 0x80) == 0)
9413 break;
9414 }
0eff7165
NC
9415 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9416 if (i == sizeof (buf))
9417 {
0eff7165 9418 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 9419 return false;
0eff7165 9420 }
948f632f 9421
015dc7e1 9422 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
9423 assert (len == i + 1);
9424 offset = offset * 8 + 0x408;
9425 printf (_("sp = sp + %ld"), offset);
9426 }
9427 else if ((op & 0xf0) == 0xe0)
9428 {
9429 if ((op & 0x0f) == 7)
9430 printf (" RETURN");
9431 else
9432 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9433 }
9434 else
9435 {
9436 printf (_(" [unsupported opcode]"));
9437 }
9438 putchar ('\n');
9439 }
32ec8896 9440
015dc7e1 9441 return true;
fa197c1c
PB
9442}
9443
9444static bfd_vma
dda8d76d 9445arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9446{
9447 bfd_vma offset;
9448
9449 offset = word & 0x7fffffff;
9450 if (offset & 0x40000000)
9451 offset |= ~ (bfd_vma) 0x7fffffff;
9452
dda8d76d 9453 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9454 offset <<= 1;
9455
9456 return offset + where;
9457}
9458
015dc7e1 9459static bool
dda8d76d
NC
9460decode_arm_unwind (Filedata * filedata,
9461 struct arm_unw_aux_info * aux,
1b31d05e
NC
9462 unsigned int word,
9463 unsigned int remaining,
9464 bfd_vma data_offset,
9465 Elf_Internal_Shdr * data_sec,
9466 struct arm_section * data_arm_sec)
fa197c1c
PB
9467{
9468 int per_index;
9469 unsigned int more_words = 0;
37e14bc3 9470 struct absaddr addr;
1b31d05e 9471 bfd_vma sym_name = (bfd_vma) -1;
015dc7e1 9472 bool res = true;
fa197c1c
PB
9473
9474 if (remaining == 0)
9475 {
1b31d05e
NC
9476 /* Fetch the first word.
9477 Note - when decoding an object file the address extracted
9478 here will always be 0. So we also pass in the sym_name
9479 parameter so that we can find the symbol associated with
9480 the personality routine. */
dda8d76d 9481 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9482 & word, & addr, & sym_name))
015dc7e1 9483 return false;
1b31d05e 9484
fa197c1c
PB
9485 remaining = 4;
9486 }
c93dbb25
CZ
9487 else
9488 {
9489 addr.section = SHN_UNDEF;
9490 addr.offset = 0;
9491 }
fa197c1c
PB
9492
9493 if ((word & 0x80000000) == 0)
9494 {
9495 /* Expand prel31 for personality routine. */
9496 bfd_vma fn;
9497 const char *procname;
9498
dda8d76d 9499 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9500 printf (_(" Personality routine: "));
1b31d05e
NC
9501 if (fn == 0
9502 && addr.section == SHN_UNDEF && addr.offset == 0
9503 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9504 {
9505 procname = aux->strtab + sym_name;
9506 print_vma (fn, PREFIX_HEX);
9507 if (procname)
9508 {
9509 fputs (" <", stdout);
9510 fputs (procname, stdout);
9511 fputc ('>', stdout);
9512 }
9513 }
9514 else
dda8d76d 9515 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9516 fputc ('\n', stdout);
9517
9518 /* The GCC personality routines use the standard compact
9519 encoding, starting with one byte giving the number of
9520 words. */
9521 if (procname != NULL
24d127aa
ML
9522 && (startswith (procname, "__gcc_personality_v0")
9523 || startswith (procname, "__gxx_personality_v0")
9524 || startswith (procname, "__gcj_personality_v0")
9525 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
9526 {
9527 remaining = 0;
9528 more_words = 1;
9529 ADVANCE;
9530 if (!remaining)
9531 {
9532 printf (_(" [Truncated data]\n"));
015dc7e1 9533 return false;
fa197c1c
PB
9534 }
9535 more_words = word >> 24;
9536 word <<= 8;
9537 remaining--;
9538 per_index = -1;
9539 }
9540 else
015dc7e1 9541 return true;
fa197c1c
PB
9542 }
9543 else
9544 {
1b31d05e 9545 /* ARM EHABI Section 6.3:
0b4362b0 9546
1b31d05e 9547 An exception-handling table entry for the compact model looks like:
0b4362b0 9548
1b31d05e
NC
9549 31 30-28 27-24 23-0
9550 -- ----- ----- ----
9551 1 0 index Data for personalityRoutine[index] */
9552
dda8d76d 9553 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9554 && (word & 0x70000000))
32ec8896
NC
9555 {
9556 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 9557 res = false;
32ec8896 9558 }
1b31d05e 9559
fa197c1c 9560 per_index = (word >> 24) & 0x7f;
1b31d05e 9561 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9562 if (per_index == 0)
9563 {
9564 more_words = 0;
9565 word <<= 8;
9566 remaining--;
9567 }
9568 else if (per_index < 3)
9569 {
9570 more_words = (word >> 16) & 0xff;
9571 word <<= 16;
9572 remaining -= 2;
9573 }
9574 }
9575
dda8d76d 9576 switch (filedata->file_header.e_machine)
fa197c1c
PB
9577 {
9578 case EM_ARM:
9579 if (per_index < 3)
9580 {
dda8d76d 9581 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 9582 data_offset, data_sec, data_arm_sec))
015dc7e1 9583 res = false;
fa197c1c
PB
9584 }
9585 else
1b31d05e
NC
9586 {
9587 warn (_("Unknown ARM compact model index encountered\n"));
9588 printf (_(" [reserved]\n"));
015dc7e1 9589 res = false;
1b31d05e 9590 }
fa197c1c
PB
9591 break;
9592
9593 case EM_TI_C6000:
9594 if (per_index < 3)
9595 {
dda8d76d 9596 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 9597 data_offset, data_sec, data_arm_sec))
015dc7e1 9598 res = false;
fa197c1c
PB
9599 }
9600 else if (per_index < 5)
9601 {
9602 if (((word >> 17) & 0x7f) == 0x7f)
9603 printf (_(" Restore stack from frame pointer\n"));
9604 else
9605 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9606 printf (_(" Registers restored: "));
9607 if (per_index == 4)
9608 printf (" (compact) ");
9609 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9610 putchar ('\n');
9611 printf (_(" Return register: %s\n"),
9612 tic6x_unwind_regnames[word & 0xf]);
9613 }
9614 else
1b31d05e 9615 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9616 break;
9617
9618 default:
74e1a04b 9619 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9620 filedata->file_header.e_machine);
015dc7e1 9621 res = false;
fa197c1c 9622 }
0b6ae522
DJ
9623
9624 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9625
9626 return res;
0b6ae522
DJ
9627}
9628
015dc7e1 9629static bool
dda8d76d
NC
9630dump_arm_unwind (Filedata * filedata,
9631 struct arm_unw_aux_info * aux,
9632 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9633{
9634 struct arm_section exidx_arm_sec, extab_arm_sec;
9635 unsigned int i, exidx_len;
948f632f 9636 unsigned long j, nfuns;
015dc7e1 9637 bool res = true;
0b6ae522
DJ
9638
9639 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9640 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9641 exidx_len = exidx_sec->sh_size / 8;
9642
948f632f
DA
9643 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9644 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9645 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9646 aux->funtab[nfuns++] = aux->symtab[j];
9647 aux->nfuns = nfuns;
9648 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9649
0b6ae522
DJ
9650 for (i = 0; i < exidx_len; i++)
9651 {
9652 unsigned int exidx_fn, exidx_entry;
9653 struct absaddr fn_addr, entry_addr;
9654 bfd_vma fn;
9655
9656 fputc ('\n', stdout);
9657
dda8d76d 9658 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9659 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9660 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9661 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9662 {
948f632f 9663 free (aux->funtab);
1b31d05e
NC
9664 arm_free_section (& exidx_arm_sec);
9665 arm_free_section (& extab_arm_sec);
015dc7e1 9666 return false;
0b6ae522
DJ
9667 }
9668
83c257ca
NC
9669 /* ARM EHABI, Section 5:
9670 An index table entry consists of 2 words.
9671 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9672 if (exidx_fn & 0x80000000)
32ec8896
NC
9673 {
9674 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 9675 res = false;
32ec8896 9676 }
83c257ca 9677
dda8d76d 9678 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9679
dda8d76d 9680 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9681 fputs (": ", stdout);
9682
9683 if (exidx_entry == 1)
9684 {
9685 print_vma (exidx_entry, PREFIX_HEX);
9686 fputs (" [cantunwind]\n", stdout);
9687 }
9688 else if (exidx_entry & 0x80000000)
9689 {
9690 print_vma (exidx_entry, PREFIX_HEX);
9691 fputc ('\n', stdout);
dda8d76d 9692 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9693 }
9694 else
9695 {
8f73510c 9696 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9697 Elf_Internal_Shdr *table_sec;
9698
9699 fputs ("@", stdout);
dda8d76d 9700 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9701 print_vma (table, PREFIX_HEX);
9702 printf ("\n");
9703
9704 /* Locate the matching .ARM.extab. */
9705 if (entry_addr.section != SHN_UNDEF
dda8d76d 9706 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9707 {
dda8d76d 9708 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9709 table_offset = entry_addr.offset;
1a915552
NC
9710 /* PR 18879 */
9711 if (table_offset > table_sec->sh_size
9712 || ((bfd_signed_vma) table_offset) < 0)
9713 {
9714 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9715 (unsigned long) table_offset,
dda8d76d 9716 printable_section_name (filedata, table_sec));
015dc7e1 9717 res = false;
1a915552
NC
9718 continue;
9719 }
0b6ae522
DJ
9720 }
9721 else
9722 {
dda8d76d 9723 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9724 if (table_sec != NULL)
9725 table_offset = table - table_sec->sh_addr;
9726 }
32ec8896 9727
0b6ae522
DJ
9728 if (table_sec == NULL)
9729 {
9730 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9731 (unsigned long) table);
015dc7e1 9732 res = false;
0b6ae522
DJ
9733 continue;
9734 }
32ec8896 9735
dda8d76d 9736 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 9737 &extab_arm_sec))
015dc7e1 9738 res = false;
0b6ae522
DJ
9739 }
9740 }
9741
9742 printf ("\n");
9743
948f632f 9744 free (aux->funtab);
0b6ae522
DJ
9745 arm_free_section (&exidx_arm_sec);
9746 arm_free_section (&extab_arm_sec);
32ec8896
NC
9747
9748 return res;
0b6ae522
DJ
9749}
9750
fa197c1c 9751/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9752
015dc7e1 9753static bool
dda8d76d 9754arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9755{
9756 struct arm_unw_aux_info aux;
9757 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9758 Elf_Internal_Shdr *sec;
9759 unsigned long i;
fa197c1c 9760 unsigned int sec_type;
015dc7e1 9761 bool res = true;
0b6ae522 9762
dda8d76d 9763 switch (filedata->file_header.e_machine)
fa197c1c
PB
9764 {
9765 case EM_ARM:
9766 sec_type = SHT_ARM_EXIDX;
9767 break;
9768
9769 case EM_TI_C6000:
9770 sec_type = SHT_C6000_UNWIND;
9771 break;
9772
0b4362b0 9773 default:
74e1a04b 9774 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9775 filedata->file_header.e_machine);
015dc7e1 9776 return false;
fa197c1c
PB
9777 }
9778
dda8d76d 9779 if (filedata->string_table == NULL)
015dc7e1 9780 return false;
1b31d05e
NC
9781
9782 memset (& aux, 0, sizeof (aux));
dda8d76d 9783 aux.filedata = filedata;
0b6ae522 9784
dda8d76d 9785 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9786 {
28d13567 9787 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9788 {
28d13567 9789 if (aux.symtab)
74e1a04b 9790 {
28d13567
AM
9791 error (_("Multiple symbol tables encountered\n"));
9792 free (aux.symtab);
9793 aux.symtab = NULL;
74e1a04b 9794 free (aux.strtab);
28d13567 9795 aux.strtab = NULL;
74e1a04b 9796 }
28d13567
AM
9797 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9798 &aux.strtab, &aux.strtab_size))
015dc7e1 9799 return false;
0b6ae522 9800 }
fa197c1c 9801 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9802 unwsec = sec;
9803 }
9804
1b31d05e 9805 if (unwsec == NULL)
0b6ae522 9806 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9807 else
dda8d76d 9808 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9809 {
9810 if (sec->sh_type == sec_type)
9811 {
d3a49aa8
AM
9812 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9813 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9814 "contains %lu entry:\n",
9815 "\nUnwind section '%s' at offset 0x%lx "
9816 "contains %lu entries:\n",
9817 num_unwind),
dda8d76d 9818 printable_section_name (filedata, sec),
1b31d05e 9819 (unsigned long) sec->sh_offset,
d3a49aa8 9820 num_unwind);
0b6ae522 9821
dda8d76d 9822 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 9823 res = false;
1b31d05e
NC
9824 }
9825 }
0b6ae522 9826
9db70fc3
AM
9827 free (aux.symtab);
9828 free ((char *) aux.strtab);
32ec8896
NC
9829
9830 return res;
0b6ae522
DJ
9831}
9832
3ecc00ec
NC
9833static bool
9834no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
9835{
9836 printf (_("No processor specific unwind information to decode\n"));
9837 return true;
9838}
9839
015dc7e1 9840static bool
dda8d76d 9841process_unwind (Filedata * filedata)
57346661 9842{
2cf0635d
NC
9843 struct unwind_handler
9844 {
32ec8896 9845 unsigned int machtype;
015dc7e1 9846 bool (* handler)(Filedata *);
2cf0635d
NC
9847 } handlers[] =
9848 {
0b6ae522 9849 { EM_ARM, arm_process_unwind },
57346661
AM
9850 { EM_IA_64, ia64_process_unwind },
9851 { EM_PARISC, hppa_process_unwind },
fa197c1c 9852 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
9853 { EM_386, no_processor_specific_unwind },
9854 { EM_X86_64, no_processor_specific_unwind },
32ec8896 9855 { 0, NULL }
57346661
AM
9856 };
9857 int i;
9858
9859 if (!do_unwind)
015dc7e1 9860 return true;
57346661
AM
9861
9862 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9863 if (filedata->file_header.e_machine == handlers[i].machtype)
9864 return handlers[i].handler (filedata);
57346661 9865
1b31d05e 9866 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9867 get_machine_name (filedata->file_header.e_machine));
015dc7e1 9868 return true;
57346661
AM
9869}
9870
37c18eed
SD
9871static void
9872dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
9873{
9874 switch (entry->d_tag)
9875 {
9876 case DT_AARCH64_BTI_PLT:
1dbade74 9877 case DT_AARCH64_PAC_PLT:
37c18eed
SD
9878 break;
9879 default:
9880 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9881 break;
9882 }
9883 putchar ('\n');
9884}
9885
252b5132 9886static void
978c4450 9887dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
9888{
9889 switch (entry->d_tag)
9890 {
9891 case DT_MIPS_FLAGS:
9892 if (entry->d_un.d_val == 0)
4b68bca3 9893 printf (_("NONE"));
252b5132
RH
9894 else
9895 {
9896 static const char * opts[] =
9897 {
9898 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9899 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9900 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9901 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9902 "RLD_ORDER_SAFE"
9903 };
9904 unsigned int cnt;
015dc7e1 9905 bool first = true;
2b692964 9906
60bca95a 9907 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9908 if (entry->d_un.d_val & (1 << cnt))
9909 {
9910 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 9911 first = false;
252b5132 9912 }
252b5132
RH
9913 }
9914 break;
103f02d3 9915
252b5132 9916 case DT_MIPS_IVERSION:
978c4450
AM
9917 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
9918 printf (_("Interface Version: %s"),
9919 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 9920 else
76ca31c0
NC
9921 {
9922 char buf[40];
9923 sprintf_vma (buf, entry->d_un.d_ptr);
9924 /* Note: coded this way so that there is a single string for translation. */
9925 printf (_("<corrupt: %s>"), buf);
9926 }
252b5132 9927 break;
103f02d3 9928
252b5132
RH
9929 case DT_MIPS_TIME_STAMP:
9930 {
d5b07ef4 9931 char timebuf[128];
2cf0635d 9932 struct tm * tmp;
91d6fa6a 9933 time_t atime = entry->d_un.d_val;
82b1b41b 9934
91d6fa6a 9935 tmp = gmtime (&atime);
82b1b41b
NC
9936 /* PR 17531: file: 6accc532. */
9937 if (tmp == NULL)
9938 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9939 else
9940 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9941 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9942 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9943 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9944 }
9945 break;
103f02d3 9946
252b5132
RH
9947 case DT_MIPS_RLD_VERSION:
9948 case DT_MIPS_LOCAL_GOTNO:
9949 case DT_MIPS_CONFLICTNO:
9950 case DT_MIPS_LIBLISTNO:
9951 case DT_MIPS_SYMTABNO:
9952 case DT_MIPS_UNREFEXTNO:
9953 case DT_MIPS_HIPAGENO:
9954 case DT_MIPS_DELTA_CLASS_NO:
9955 case DT_MIPS_DELTA_INSTANCE_NO:
9956 case DT_MIPS_DELTA_RELOC_NO:
9957 case DT_MIPS_DELTA_SYM_NO:
9958 case DT_MIPS_DELTA_CLASSSYM_NO:
9959 case DT_MIPS_COMPACT_SIZE:
c69075ac 9960 print_vma (entry->d_un.d_val, DEC);
252b5132 9961 break;
103f02d3 9962
f16a9783 9963 case DT_MIPS_XHASH:
978c4450
AM
9964 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
9965 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
9966 /* Falls through. */
9967
103f02d3 9968 default:
4b68bca3 9969 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9970 }
4b68bca3 9971 putchar ('\n');
103f02d3
UD
9972}
9973
103f02d3 9974static void
2cf0635d 9975dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9976{
9977 switch (entry->d_tag)
9978 {
9979 case DT_HP_DLD_FLAGS:
9980 {
9981 static struct
9982 {
9983 long int bit;
2cf0635d 9984 const char * str;
5e220199
NC
9985 }
9986 flags[] =
9987 {
9988 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9989 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9990 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9991 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9992 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9993 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9994 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9995 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9996 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9997 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9998 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9999 { DT_HP_GST, "HP_GST" },
10000 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10001 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10002 { DT_HP_NODELETE, "HP_NODELETE" },
10003 { DT_HP_GROUP, "HP_GROUP" },
10004 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10005 };
015dc7e1 10006 bool first = true;
5e220199 10007 size_t cnt;
f7a99963 10008 bfd_vma val = entry->d_un.d_val;
103f02d3 10009
60bca95a 10010 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10011 if (val & flags[cnt].bit)
30800947
NC
10012 {
10013 if (! first)
10014 putchar (' ');
10015 fputs (flags[cnt].str, stdout);
015dc7e1 10016 first = false;
30800947
NC
10017 val ^= flags[cnt].bit;
10018 }
76da6bbe 10019
103f02d3 10020 if (val != 0 || first)
f7a99963
NC
10021 {
10022 if (! first)
10023 putchar (' ');
10024 print_vma (val, HEX);
10025 }
103f02d3
UD
10026 }
10027 break;
76da6bbe 10028
252b5132 10029 default:
f7a99963
NC
10030 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10031 break;
252b5132 10032 }
35b1837e 10033 putchar ('\n');
252b5132
RH
10034}
10035
28f997cf
TG
10036#ifdef BFD64
10037
10038/* VMS vs Unix time offset and factor. */
10039
10040#define VMS_EPOCH_OFFSET 35067168000000000LL
10041#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10042#ifndef INT64_MIN
10043#define INT64_MIN (-9223372036854775807LL - 1)
10044#endif
28f997cf
TG
10045
10046/* Display a VMS time in a human readable format. */
10047
10048static void
10049print_vms_time (bfd_int64_t vmstime)
10050{
dccc31de 10051 struct tm *tm = NULL;
28f997cf
TG
10052 time_t unxtime;
10053
dccc31de
AM
10054 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10055 {
10056 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10057 unxtime = vmstime;
10058 if (unxtime == vmstime)
10059 tm = gmtime (&unxtime);
10060 }
10061 if (tm != NULL)
10062 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10063 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10064 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
10065}
10066#endif /* BFD64 */
10067
ecc51f48 10068static void
2cf0635d 10069dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10070{
10071 switch (entry->d_tag)
10072 {
0de14b54 10073 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10074 /* First 3 slots reserved. */
ecc51f48
NC
10075 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10076 printf (" -- ");
10077 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10078 break;
10079
28f997cf
TG
10080 case DT_IA_64_VMS_LINKTIME:
10081#ifdef BFD64
10082 print_vms_time (entry->d_un.d_val);
10083#endif
10084 break;
10085
10086 case DT_IA_64_VMS_LNKFLAGS:
10087 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10088 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10089 printf (" CALL_DEBUG");
10090 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10091 printf (" NOP0BUFS");
10092 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10093 printf (" P0IMAGE");
10094 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10095 printf (" MKTHREADS");
10096 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10097 printf (" UPCALLS");
10098 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10099 printf (" IMGSTA");
10100 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10101 printf (" INITIALIZE");
10102 if (entry->d_un.d_val & VMS_LF_MAIN)
10103 printf (" MAIN");
10104 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10105 printf (" EXE_INIT");
10106 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10107 printf (" TBK_IN_IMG");
10108 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10109 printf (" DBG_IN_IMG");
10110 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10111 printf (" TBK_IN_DSF");
10112 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10113 printf (" DBG_IN_DSF");
10114 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10115 printf (" SIGNATURES");
10116 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10117 printf (" REL_SEG_OFF");
10118 break;
10119
bdf4d63a
JJ
10120 default:
10121 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10122 break;
ecc51f48 10123 }
bdf4d63a 10124 putchar ('\n');
ecc51f48
NC
10125}
10126
015dc7e1 10127static bool
dda8d76d 10128get_32bit_dynamic_section (Filedata * filedata)
252b5132 10129{
2cf0635d
NC
10130 Elf32_External_Dyn * edyn;
10131 Elf32_External_Dyn * ext;
10132 Elf_Internal_Dyn * entry;
103f02d3 10133
978c4450
AM
10134 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10135 filedata->dynamic_addr, 1,
10136 filedata->dynamic_size,
10137 _("dynamic section"));
a6e9f9df 10138 if (!edyn)
015dc7e1 10139 return false;
103f02d3 10140
071436c6
NC
10141 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10142 might not have the luxury of section headers. Look for the DT_NULL
10143 terminator to determine the number of entries. */
978c4450
AM
10144 for (ext = edyn, filedata->dynamic_nent = 0;
10145 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10146 ext++)
10147 {
978c4450 10148 filedata->dynamic_nent++;
ba2685cc
AM
10149 if (BYTE_GET (ext->d_tag) == DT_NULL)
10150 break;
10151 }
252b5132 10152
978c4450
AM
10153 filedata->dynamic_section
10154 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10155 if (filedata->dynamic_section == NULL)
252b5132 10156 {
8b73c356 10157 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10158 (unsigned long) filedata->dynamic_nent);
9ea033b2 10159 free (edyn);
015dc7e1 10160 return false;
9ea033b2 10161 }
252b5132 10162
978c4450
AM
10163 for (ext = edyn, entry = filedata->dynamic_section;
10164 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10165 ext++, entry++)
9ea033b2 10166 {
fb514b26
AM
10167 entry->d_tag = BYTE_GET (ext->d_tag);
10168 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10169 }
10170
9ea033b2
NC
10171 free (edyn);
10172
015dc7e1 10173 return true;
9ea033b2
NC
10174}
10175
015dc7e1 10176static bool
dda8d76d 10177get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10178{
2cf0635d
NC
10179 Elf64_External_Dyn * edyn;
10180 Elf64_External_Dyn * ext;
10181 Elf_Internal_Dyn * entry;
103f02d3 10182
071436c6 10183 /* Read in the data. */
978c4450
AM
10184 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10185 filedata->dynamic_addr, 1,
10186 filedata->dynamic_size,
10187 _("dynamic section"));
a6e9f9df 10188 if (!edyn)
015dc7e1 10189 return false;
103f02d3 10190
071436c6
NC
10191 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10192 might not have the luxury of section headers. Look for the DT_NULL
10193 terminator to determine the number of entries. */
978c4450 10194 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10195 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10196 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10197 ext++)
10198 {
978c4450 10199 filedata->dynamic_nent++;
66543521 10200 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10201 break;
10202 }
252b5132 10203
978c4450
AM
10204 filedata->dynamic_section
10205 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10206 if (filedata->dynamic_section == NULL)
252b5132 10207 {
8b73c356 10208 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10209 (unsigned long) filedata->dynamic_nent);
252b5132 10210 free (edyn);
015dc7e1 10211 return false;
252b5132
RH
10212 }
10213
071436c6 10214 /* Convert from external to internal formats. */
978c4450
AM
10215 for (ext = edyn, entry = filedata->dynamic_section;
10216 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10217 ext++, entry++)
252b5132 10218 {
66543521
AM
10219 entry->d_tag = BYTE_GET (ext->d_tag);
10220 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10221 }
10222
10223 free (edyn);
10224
015dc7e1 10225 return true;
9ea033b2
NC
10226}
10227
e9e44622
JJ
10228static void
10229print_dynamic_flags (bfd_vma flags)
d1133906 10230{
015dc7e1 10231 bool first = true;
13ae64f3 10232
d1133906
NC
10233 while (flags)
10234 {
10235 bfd_vma flag;
10236
10237 flag = flags & - flags;
10238 flags &= ~ flag;
10239
e9e44622 10240 if (first)
015dc7e1 10241 first = false;
e9e44622
JJ
10242 else
10243 putc (' ', stdout);
13ae64f3 10244
d1133906
NC
10245 switch (flag)
10246 {
e9e44622
JJ
10247 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10248 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10249 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10250 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10251 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10252 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10253 }
10254 }
e9e44622 10255 puts ("");
d1133906
NC
10256}
10257
10ca4b04
L
10258static bfd_vma *
10259get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10260{
10261 unsigned char * e_data;
10262 bfd_vma * i_data;
10263
10264 /* If the size_t type is smaller than the bfd_size_type, eg because
10265 you are building a 32-bit tool on a 64-bit host, then make sure
10266 that when (number) is cast to (size_t) no information is lost. */
10267 if (sizeof (size_t) < sizeof (bfd_size_type)
10268 && (bfd_size_type) ((size_t) number) != number)
10269 {
10270 error (_("Size truncation prevents reading %s elements of size %u\n"),
10271 bfd_vmatoa ("u", number), ent_size);
10272 return NULL;
10273 }
10274
10275 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10276 attempting to allocate memory when the read is bound to fail. */
10277 if (ent_size * number > filedata->file_size)
10278 {
10279 error (_("Invalid number of dynamic entries: %s\n"),
10280 bfd_vmatoa ("u", number));
10281 return NULL;
10282 }
10283
10284 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10285 if (e_data == NULL)
10286 {
10287 error (_("Out of memory reading %s dynamic entries\n"),
10288 bfd_vmatoa ("u", number));
10289 return NULL;
10290 }
10291
10292 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10293 {
10294 error (_("Unable to read in %s bytes of dynamic data\n"),
10295 bfd_vmatoa ("u", number * ent_size));
10296 free (e_data);
10297 return NULL;
10298 }
10299
10300 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10301 if (i_data == NULL)
10302 {
10303 error (_("Out of memory allocating space for %s dynamic entries\n"),
10304 bfd_vmatoa ("u", number));
10305 free (e_data);
10306 return NULL;
10307 }
10308
10309 while (number--)
10310 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10311
10312 free (e_data);
10313
10314 return i_data;
10315}
10316
10317static unsigned long
10318get_num_dynamic_syms (Filedata * filedata)
10319{
10320 unsigned long num_of_syms = 0;
10321
10322 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10323 return num_of_syms;
10324
978c4450 10325 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10326 {
10327 unsigned char nb[8];
10328 unsigned char nc[8];
10329 unsigned int hash_ent_size = 4;
10330
10331 if ((filedata->file_header.e_machine == EM_ALPHA
10332 || filedata->file_header.e_machine == EM_S390
10333 || filedata->file_header.e_machine == EM_S390_OLD)
10334 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10335 hash_ent_size = 8;
10336
10337 if (fseek (filedata->handle,
978c4450
AM
10338 (filedata->archive_file_offset
10339 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10340 sizeof nb + sizeof nc)),
10341 SEEK_SET))
10342 {
10343 error (_("Unable to seek to start of dynamic information\n"));
10344 goto no_hash;
10345 }
10346
10347 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10348 {
10349 error (_("Failed to read in number of buckets\n"));
10350 goto no_hash;
10351 }
10352
10353 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10354 {
10355 error (_("Failed to read in number of chains\n"));
10356 goto no_hash;
10357 }
10358
978c4450
AM
10359 filedata->nbuckets = byte_get (nb, hash_ent_size);
10360 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10361
2482f306
AM
10362 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10363 {
10364 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10365 hash_ent_size);
10366 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10367 hash_ent_size);
001890e1 10368
2482f306
AM
10369 if (filedata->buckets != NULL && filedata->chains != NULL)
10370 num_of_syms = filedata->nchains;
10371 }
ceb9bf11 10372 no_hash:
10ca4b04
L
10373 if (num_of_syms == 0)
10374 {
9db70fc3
AM
10375 free (filedata->buckets);
10376 filedata->buckets = NULL;
10377 free (filedata->chains);
10378 filedata->chains = NULL;
978c4450 10379 filedata->nbuckets = 0;
10ca4b04
L
10380 }
10381 }
10382
978c4450 10383 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10384 {
10385 unsigned char nb[16];
10386 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10387 bfd_vma buckets_vma;
10388 unsigned long hn;
10ca4b04
L
10389
10390 if (fseek (filedata->handle,
978c4450
AM
10391 (filedata->archive_file_offset
10392 + offset_from_vma (filedata,
10393 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10394 sizeof nb)),
10395 SEEK_SET))
10396 {
10397 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10398 goto no_gnu_hash;
10399 }
10400
10401 if (fread (nb, 16, 1, filedata->handle) != 1)
10402 {
10403 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10404 goto no_gnu_hash;
10405 }
10406
978c4450
AM
10407 filedata->ngnubuckets = byte_get (nb, 4);
10408 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10409 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10410 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10411 if (is_32bit_elf)
10412 buckets_vma += bitmaskwords * 4;
10413 else
10414 buckets_vma += bitmaskwords * 8;
10415
10416 if (fseek (filedata->handle,
978c4450 10417 (filedata->archive_file_offset
10ca4b04
L
10418 + offset_from_vma (filedata, buckets_vma, 4)),
10419 SEEK_SET))
10420 {
10421 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10422 goto no_gnu_hash;
10423 }
10424
978c4450
AM
10425 filedata->gnubuckets
10426 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10427
978c4450 10428 if (filedata->gnubuckets == NULL)
90837ea7 10429 goto no_gnu_hash;
10ca4b04 10430
978c4450
AM
10431 for (i = 0; i < filedata->ngnubuckets; i++)
10432 if (filedata->gnubuckets[i] != 0)
10ca4b04 10433 {
978c4450 10434 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10435 goto no_gnu_hash;
10ca4b04 10436
978c4450
AM
10437 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10438 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10439 }
10440
10441 if (maxchain == 0xffffffff)
90837ea7 10442 goto no_gnu_hash;
10ca4b04 10443
978c4450 10444 maxchain -= filedata->gnusymidx;
10ca4b04
L
10445
10446 if (fseek (filedata->handle,
978c4450
AM
10447 (filedata->archive_file_offset
10448 + offset_from_vma (filedata,
10449 buckets_vma + 4 * (filedata->ngnubuckets
10450 + maxchain),
10451 4)),
10ca4b04
L
10452 SEEK_SET))
10453 {
10454 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10455 goto no_gnu_hash;
10456 }
10457
10458 do
10459 {
10460 if (fread (nb, 4, 1, filedata->handle) != 1)
10461 {
10462 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10463 goto no_gnu_hash;
10464 }
10465
10466 if (maxchain + 1 == 0)
90837ea7 10467 goto no_gnu_hash;
10ca4b04
L
10468
10469 ++maxchain;
10470 }
10471 while ((byte_get (nb, 4) & 1) == 0);
10472
10473 if (fseek (filedata->handle,
978c4450
AM
10474 (filedata->archive_file_offset
10475 + offset_from_vma (filedata, (buckets_vma
10476 + 4 * filedata->ngnubuckets),
10477 4)),
10ca4b04
L
10478 SEEK_SET))
10479 {
10480 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10481 goto no_gnu_hash;
10482 }
10483
978c4450
AM
10484 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10485 filedata->ngnuchains = maxchain;
10ca4b04 10486
978c4450 10487 if (filedata->gnuchains == NULL)
90837ea7 10488 goto no_gnu_hash;
10ca4b04 10489
978c4450 10490 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10491 {
10492 if (fseek (filedata->handle,
978c4450 10493 (filedata->archive_file_offset
10ca4b04 10494 + offset_from_vma (filedata, (buckets_vma
978c4450 10495 + 4 * (filedata->ngnubuckets
10ca4b04
L
10496 + maxchain)), 4)),
10497 SEEK_SET))
10498 {
10499 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10500 goto no_gnu_hash;
10501 }
10502
978c4450 10503 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10504 if (filedata->mipsxlat == NULL)
10505 goto no_gnu_hash;
10ca4b04
L
10506 }
10507
978c4450
AM
10508 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10509 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10510 {
978c4450
AM
10511 bfd_vma si = filedata->gnubuckets[hn];
10512 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10513
10514 do
10515 {
978c4450 10516 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 10517 {
c31ab5a0
AM
10518 if (off < filedata->ngnuchains
10519 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 10520 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
10521 }
10522 else
10523 {
10524 if (si >= num_of_syms)
10525 num_of_syms = si + 1;
10526 }
10527 si++;
10528 }
978c4450
AM
10529 while (off < filedata->ngnuchains
10530 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
10531 }
10532
90837ea7 10533 if (num_of_syms == 0)
10ca4b04 10534 {
90837ea7 10535 no_gnu_hash:
9db70fc3
AM
10536 free (filedata->mipsxlat);
10537 filedata->mipsxlat = NULL;
10538 free (filedata->gnuchains);
10539 filedata->gnuchains = NULL;
10540 free (filedata->gnubuckets);
10541 filedata->gnubuckets = NULL;
978c4450
AM
10542 filedata->ngnubuckets = 0;
10543 filedata->ngnuchains = 0;
10ca4b04
L
10544 }
10545 }
10546
10547 return num_of_syms;
10548}
10549
b2d38a17
NC
10550/* Parse and display the contents of the dynamic section. */
10551
015dc7e1 10552static bool
dda8d76d 10553process_dynamic_section (Filedata * filedata)
9ea033b2 10554{
2cf0635d 10555 Elf_Internal_Dyn * entry;
9ea033b2 10556
978c4450 10557 if (filedata->dynamic_size == 0)
9ea033b2
NC
10558 {
10559 if (do_dynamic)
ca0e11aa
NC
10560 {
10561 if (filedata->is_separate)
10562 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
10563 filedata->file_name);
10564 else
10565 printf (_("\nThere is no dynamic section in this file.\n"));
10566 }
9ea033b2 10567
015dc7e1 10568 return true;
9ea033b2
NC
10569 }
10570
10571 if (is_32bit_elf)
10572 {
dda8d76d 10573 if (! get_32bit_dynamic_section (filedata))
015dc7e1 10574 return false;
32ec8896
NC
10575 }
10576 else
10577 {
dda8d76d 10578 if (! get_64bit_dynamic_section (filedata))
015dc7e1 10579 return false;
9ea033b2 10580 }
9ea033b2 10581
252b5132 10582 /* Find the appropriate symbol table. */
978c4450 10583 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 10584 {
2482f306
AM
10585 unsigned long num_of_syms;
10586
978c4450
AM
10587 for (entry = filedata->dynamic_section;
10588 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10589 ++entry)
10ca4b04 10590 if (entry->d_tag == DT_SYMTAB)
978c4450 10591 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 10592 else if (entry->d_tag == DT_SYMENT)
978c4450 10593 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 10594 else if (entry->d_tag == DT_HASH)
978c4450 10595 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 10596 else if (entry->d_tag == DT_GNU_HASH)
978c4450 10597 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
10598 else if ((filedata->file_header.e_machine == EM_MIPS
10599 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10600 && entry->d_tag == DT_MIPS_XHASH)
10601 {
978c4450
AM
10602 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10603 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 10604 }
252b5132 10605
2482f306
AM
10606 num_of_syms = get_num_dynamic_syms (filedata);
10607
10608 if (num_of_syms != 0
10609 && filedata->dynamic_symbols == NULL
10610 && filedata->dynamic_info[DT_SYMTAB]
978c4450 10611 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
10612 {
10613 Elf_Internal_Phdr *seg;
2482f306 10614 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 10615
2482f306
AM
10616 if (! get_program_headers (filedata))
10617 {
10618 error (_("Cannot interpret virtual addresses "
10619 "without program headers.\n"));
015dc7e1 10620 return false;
2482f306 10621 }
252b5132 10622
2482f306
AM
10623 for (seg = filedata->program_headers;
10624 seg < filedata->program_headers + filedata->file_header.e_phnum;
10625 ++seg)
10626 {
10627 if (seg->p_type != PT_LOAD)
10628 continue;
252b5132 10629
2482f306
AM
10630 if (seg->p_offset + seg->p_filesz > filedata->file_size)
10631 {
10632 /* See PR 21379 for a reproducer. */
10633 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 10634 return false;
2482f306 10635 }
252b5132 10636
2482f306
AM
10637 if (vma >= (seg->p_vaddr & -seg->p_align)
10638 && vma < seg->p_vaddr + seg->p_filesz)
10639 {
10640 /* Since we do not know how big the symbol table is,
10641 we default to reading in up to the end of PT_LOAD
10642 segment and processing that. This is overkill, I
10643 know, but it should work. */
10644 Elf_Internal_Shdr section;
10645 section.sh_offset = (vma - seg->p_vaddr
10646 + seg->p_offset);
10647 section.sh_size = (num_of_syms
10648 * filedata->dynamic_info[DT_SYMENT]);
10649 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
10650
10651 if (do_checks
10652 && filedata->dynamic_symtab_section != NULL
10653 && ((filedata->dynamic_symtab_section->sh_offset
10654 != section.sh_offset)
10655 || (filedata->dynamic_symtab_section->sh_size
10656 != section.sh_size)
10657 || (filedata->dynamic_symtab_section->sh_entsize
10658 != section.sh_entsize)))
10659 warn (_("\
10660the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
10661
2482f306
AM
10662 section.sh_name = filedata->string_table_length;
10663 filedata->dynamic_symbols
10664 = GET_ELF_SYMBOLS (filedata, &section,
10665 &filedata->num_dynamic_syms);
10666 if (filedata->dynamic_symbols == NULL
10667 || filedata->num_dynamic_syms != num_of_syms)
10668 {
10669 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 10670 return false;
2482f306
AM
10671 }
10672 break;
10673 }
10674 }
10675 }
10676 }
252b5132
RH
10677
10678 /* Similarly find a string table. */
978c4450
AM
10679 if (filedata->dynamic_strings == NULL)
10680 for (entry = filedata->dynamic_section;
10681 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
10682 ++entry)
10683 {
10684 if (entry->d_tag == DT_STRTAB)
978c4450 10685 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 10686
10ca4b04 10687 if (entry->d_tag == DT_STRSZ)
978c4450 10688 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10689
978c4450
AM
10690 if (filedata->dynamic_info[DT_STRTAB]
10691 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
10692 {
10693 unsigned long offset;
978c4450 10694 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
10695
10696 offset = offset_from_vma (filedata,
978c4450 10697 filedata->dynamic_info[DT_STRTAB],
10ca4b04 10698 str_tab_len);
8ac10c5b
L
10699 if (do_checks
10700 && filedata->dynamic_strtab_section
10701 && ((filedata->dynamic_strtab_section->sh_offset
10702 != (file_ptr) offset)
10703 || (filedata->dynamic_strtab_section->sh_size
10704 != str_tab_len)))
10705 warn (_("\
10706the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
10707
978c4450
AM
10708 filedata->dynamic_strings
10709 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
10710 _("dynamic string table"));
10711 if (filedata->dynamic_strings == NULL)
10ca4b04
L
10712 {
10713 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10714 break;
10715 }
e3d39609 10716
978c4450 10717 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
10718 break;
10719 }
10720 }
252b5132
RH
10721
10722 /* And find the syminfo section if available. */
978c4450 10723 if (filedata->dynamic_syminfo == NULL)
252b5132 10724 {
3e8bba36 10725 unsigned long syminsz = 0;
252b5132 10726
978c4450
AM
10727 for (entry = filedata->dynamic_section;
10728 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10729 ++entry)
252b5132
RH
10730 {
10731 if (entry->d_tag == DT_SYMINENT)
10732 {
10733 /* Note: these braces are necessary to avoid a syntax
10734 error from the SunOS4 C compiler. */
049b0c3a
NC
10735 /* PR binutils/17531: A corrupt file can trigger this test.
10736 So do not use an assert, instead generate an error message. */
10737 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10738 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10739 (int) entry->d_un.d_val);
252b5132
RH
10740 }
10741 else if (entry->d_tag == DT_SYMINSZ)
10742 syminsz = entry->d_un.d_val;
10743 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
10744 filedata->dynamic_syminfo_offset
10745 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
10746 }
10747
978c4450 10748 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 10749 {
2cf0635d
NC
10750 Elf_External_Syminfo * extsyminfo;
10751 Elf_External_Syminfo * extsym;
10752 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10753
10754 /* There is a syminfo section. Read the data. */
3f5e193b 10755 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
10756 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
10757 1, syminsz, _("symbol information"));
a6e9f9df 10758 if (!extsyminfo)
015dc7e1 10759 return false;
252b5132 10760
978c4450 10761 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
10762 {
10763 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 10764 free (filedata->dynamic_syminfo);
e3d39609 10765 }
978c4450
AM
10766 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
10767 if (filedata->dynamic_syminfo == NULL)
252b5132 10768 {
2482f306
AM
10769 error (_("Out of memory allocating %lu bytes "
10770 "for dynamic symbol info\n"),
8b73c356 10771 (unsigned long) syminsz);
015dc7e1 10772 return false;
252b5132
RH
10773 }
10774
2482f306
AM
10775 filedata->dynamic_syminfo_nent
10776 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 10777 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
10778 syminfo < (filedata->dynamic_syminfo
10779 + filedata->dynamic_syminfo_nent);
86dba8ee 10780 ++syminfo, ++extsym)
252b5132 10781 {
86dba8ee
AM
10782 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10783 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10784 }
10785
10786 free (extsyminfo);
10787 }
10788 }
10789
978c4450 10790 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa
NC
10791 {
10792 if (filedata->dynamic_nent == 1)
10793 {
10794 if (filedata->is_separate)
10795 printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains 1 entry:\n"),
10796 filedata->file_name,
10797 filedata->dynamic_addr);
10798 else
10799 printf (_("\nDynamic section at offset 0x%lx contains 1 entry:\n"),
10800 filedata->dynamic_addr);
10801 }
10802 else
10803 {
10804 if (filedata->is_separate)
10805 printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n"),
10806 filedata->file_name,
10807 filedata->dynamic_addr,
10808 (unsigned long) filedata->dynamic_nent);
10809 else
10810 printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
10811 filedata->dynamic_addr,
10812 (unsigned long) filedata->dynamic_nent);
10813 }
10814 }
252b5132
RH
10815 if (do_dynamic)
10816 printf (_(" Tag Type Name/Value\n"));
10817
978c4450
AM
10818 for (entry = filedata->dynamic_section;
10819 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10820 entry++)
252b5132
RH
10821 {
10822 if (do_dynamic)
f7a99963 10823 {
2cf0635d 10824 const char * dtype;
e699b9ff 10825
f7a99963
NC
10826 putchar (' ');
10827 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10828 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10829 printf (" (%s)%*s", dtype,
32ec8896 10830 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10831 }
252b5132
RH
10832
10833 switch (entry->d_tag)
10834 {
d1133906
NC
10835 case DT_FLAGS:
10836 if (do_dynamic)
e9e44622 10837 print_dynamic_flags (entry->d_un.d_val);
d1133906 10838 break;
76da6bbe 10839
252b5132
RH
10840 case DT_AUXILIARY:
10841 case DT_FILTER:
019148e4
L
10842 case DT_CONFIG:
10843 case DT_DEPAUDIT:
10844 case DT_AUDIT:
252b5132
RH
10845 if (do_dynamic)
10846 {
019148e4 10847 switch (entry->d_tag)
b34976b6 10848 {
019148e4
L
10849 case DT_AUXILIARY:
10850 printf (_("Auxiliary library"));
10851 break;
10852
10853 case DT_FILTER:
10854 printf (_("Filter library"));
10855 break;
10856
b34976b6 10857 case DT_CONFIG:
019148e4
L
10858 printf (_("Configuration file"));
10859 break;
10860
10861 case DT_DEPAUDIT:
10862 printf (_("Dependency audit library"));
10863 break;
10864
10865 case DT_AUDIT:
10866 printf (_("Audit library"));
10867 break;
10868 }
252b5132 10869
978c4450
AM
10870 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10871 printf (": [%s]\n",
10872 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 10873 else
f7a99963
NC
10874 {
10875 printf (": ");
10876 print_vma (entry->d_un.d_val, PREFIX_HEX);
10877 putchar ('\n');
10878 }
252b5132
RH
10879 }
10880 break;
10881
dcefbbbd 10882 case DT_FEATURE:
252b5132
RH
10883 if (do_dynamic)
10884 {
10885 printf (_("Flags:"));
86f55779 10886
252b5132
RH
10887 if (entry->d_un.d_val == 0)
10888 printf (_(" None\n"));
10889 else
10890 {
10891 unsigned long int val = entry->d_un.d_val;
86f55779 10892
252b5132
RH
10893 if (val & DTF_1_PARINIT)
10894 {
10895 printf (" PARINIT");
10896 val ^= DTF_1_PARINIT;
10897 }
dcefbbbd
L
10898 if (val & DTF_1_CONFEXP)
10899 {
10900 printf (" CONFEXP");
10901 val ^= DTF_1_CONFEXP;
10902 }
252b5132
RH
10903 if (val != 0)
10904 printf (" %lx", val);
10905 puts ("");
10906 }
10907 }
10908 break;
10909
10910 case DT_POSFLAG_1:
10911 if (do_dynamic)
10912 {
10913 printf (_("Flags:"));
86f55779 10914
252b5132
RH
10915 if (entry->d_un.d_val == 0)
10916 printf (_(" None\n"));
10917 else
10918 {
10919 unsigned long int val = entry->d_un.d_val;
86f55779 10920
252b5132
RH
10921 if (val & DF_P1_LAZYLOAD)
10922 {
10923 printf (" LAZYLOAD");
10924 val ^= DF_P1_LAZYLOAD;
10925 }
10926 if (val & DF_P1_GROUPPERM)
10927 {
10928 printf (" GROUPPERM");
10929 val ^= DF_P1_GROUPPERM;
10930 }
10931 if (val != 0)
10932 printf (" %lx", val);
10933 puts ("");
10934 }
10935 }
10936 break;
10937
10938 case DT_FLAGS_1:
10939 if (do_dynamic)
10940 {
10941 printf (_("Flags:"));
10942 if (entry->d_un.d_val == 0)
10943 printf (_(" None\n"));
10944 else
10945 {
10946 unsigned long int val = entry->d_un.d_val;
86f55779 10947
252b5132
RH
10948 if (val & DF_1_NOW)
10949 {
10950 printf (" NOW");
10951 val ^= DF_1_NOW;
10952 }
10953 if (val & DF_1_GLOBAL)
10954 {
10955 printf (" GLOBAL");
10956 val ^= DF_1_GLOBAL;
10957 }
10958 if (val & DF_1_GROUP)
10959 {
10960 printf (" GROUP");
10961 val ^= DF_1_GROUP;
10962 }
10963 if (val & DF_1_NODELETE)
10964 {
10965 printf (" NODELETE");
10966 val ^= DF_1_NODELETE;
10967 }
10968 if (val & DF_1_LOADFLTR)
10969 {
10970 printf (" LOADFLTR");
10971 val ^= DF_1_LOADFLTR;
10972 }
10973 if (val & DF_1_INITFIRST)
10974 {
10975 printf (" INITFIRST");
10976 val ^= DF_1_INITFIRST;
10977 }
10978 if (val & DF_1_NOOPEN)
10979 {
10980 printf (" NOOPEN");
10981 val ^= DF_1_NOOPEN;
10982 }
10983 if (val & DF_1_ORIGIN)
10984 {
10985 printf (" ORIGIN");
10986 val ^= DF_1_ORIGIN;
10987 }
10988 if (val & DF_1_DIRECT)
10989 {
10990 printf (" DIRECT");
10991 val ^= DF_1_DIRECT;
10992 }
10993 if (val & DF_1_TRANS)
10994 {
10995 printf (" TRANS");
10996 val ^= DF_1_TRANS;
10997 }
10998 if (val & DF_1_INTERPOSE)
10999 {
11000 printf (" INTERPOSE");
11001 val ^= DF_1_INTERPOSE;
11002 }
f7db6139 11003 if (val & DF_1_NODEFLIB)
dcefbbbd 11004 {
f7db6139
L
11005 printf (" NODEFLIB");
11006 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11007 }
11008 if (val & DF_1_NODUMP)
11009 {
11010 printf (" NODUMP");
11011 val ^= DF_1_NODUMP;
11012 }
34b60028 11013 if (val & DF_1_CONFALT)
dcefbbbd 11014 {
34b60028
L
11015 printf (" CONFALT");
11016 val ^= DF_1_CONFALT;
11017 }
11018 if (val & DF_1_ENDFILTEE)
11019 {
11020 printf (" ENDFILTEE");
11021 val ^= DF_1_ENDFILTEE;
11022 }
11023 if (val & DF_1_DISPRELDNE)
11024 {
11025 printf (" DISPRELDNE");
11026 val ^= DF_1_DISPRELDNE;
11027 }
11028 if (val & DF_1_DISPRELPND)
11029 {
11030 printf (" DISPRELPND");
11031 val ^= DF_1_DISPRELPND;
11032 }
11033 if (val & DF_1_NODIRECT)
11034 {
11035 printf (" NODIRECT");
11036 val ^= DF_1_NODIRECT;
11037 }
11038 if (val & DF_1_IGNMULDEF)
11039 {
11040 printf (" IGNMULDEF");
11041 val ^= DF_1_IGNMULDEF;
11042 }
11043 if (val & DF_1_NOKSYMS)
11044 {
11045 printf (" NOKSYMS");
11046 val ^= DF_1_NOKSYMS;
11047 }
11048 if (val & DF_1_NOHDR)
11049 {
11050 printf (" NOHDR");
11051 val ^= DF_1_NOHDR;
11052 }
11053 if (val & DF_1_EDITED)
11054 {
11055 printf (" EDITED");
11056 val ^= DF_1_EDITED;
11057 }
11058 if (val & DF_1_NORELOC)
11059 {
11060 printf (" NORELOC");
11061 val ^= DF_1_NORELOC;
11062 }
11063 if (val & DF_1_SYMINTPOSE)
11064 {
11065 printf (" SYMINTPOSE");
11066 val ^= DF_1_SYMINTPOSE;
11067 }
11068 if (val & DF_1_GLOBAUDIT)
11069 {
11070 printf (" GLOBAUDIT");
11071 val ^= DF_1_GLOBAUDIT;
11072 }
11073 if (val & DF_1_SINGLETON)
11074 {
11075 printf (" SINGLETON");
11076 val ^= DF_1_SINGLETON;
dcefbbbd 11077 }
5c383f02
RO
11078 if (val & DF_1_STUB)
11079 {
11080 printf (" STUB");
11081 val ^= DF_1_STUB;
11082 }
11083 if (val & DF_1_PIE)
11084 {
11085 printf (" PIE");
11086 val ^= DF_1_PIE;
11087 }
b1202ffa
L
11088 if (val & DF_1_KMOD)
11089 {
11090 printf (" KMOD");
11091 val ^= DF_1_KMOD;
11092 }
11093 if (val & DF_1_WEAKFILTER)
11094 {
11095 printf (" WEAKFILTER");
11096 val ^= DF_1_WEAKFILTER;
11097 }
11098 if (val & DF_1_NOCOMMON)
11099 {
11100 printf (" NOCOMMON");
11101 val ^= DF_1_NOCOMMON;
11102 }
252b5132
RH
11103 if (val != 0)
11104 printf (" %lx", val);
11105 puts ("");
11106 }
11107 }
11108 break;
11109
11110 case DT_PLTREL:
978c4450 11111 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11112 if (do_dynamic)
dda8d76d 11113 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11114 break;
11115
11116 case DT_NULL :
11117 case DT_NEEDED :
11118 case DT_PLTGOT :
11119 case DT_HASH :
11120 case DT_STRTAB :
11121 case DT_SYMTAB :
11122 case DT_RELA :
11123 case DT_INIT :
11124 case DT_FINI :
11125 case DT_SONAME :
11126 case DT_RPATH :
11127 case DT_SYMBOLIC:
11128 case DT_REL :
11129 case DT_DEBUG :
11130 case DT_TEXTREL :
11131 case DT_JMPREL :
019148e4 11132 case DT_RUNPATH :
978c4450 11133 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11134
11135 if (do_dynamic)
11136 {
2cf0635d 11137 char * name;
252b5132 11138
978c4450
AM
11139 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
11140 name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11141 else
d79b3d50 11142 name = NULL;
252b5132
RH
11143
11144 if (name)
11145 {
11146 switch (entry->d_tag)
11147 {
11148 case DT_NEEDED:
11149 printf (_("Shared library: [%s]"), name);
11150
13acb58d
AM
11151 if (filedata->program_interpreter
11152 && streq (name, filedata->program_interpreter))
f7a99963 11153 printf (_(" program interpreter"));
252b5132
RH
11154 break;
11155
11156 case DT_SONAME:
f7a99963 11157 printf (_("Library soname: [%s]"), name);
252b5132
RH
11158 break;
11159
11160 case DT_RPATH:
f7a99963 11161 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11162 break;
11163
019148e4
L
11164 case DT_RUNPATH:
11165 printf (_("Library runpath: [%s]"), name);
11166 break;
11167
252b5132 11168 default:
f7a99963
NC
11169 print_vma (entry->d_un.d_val, PREFIX_HEX);
11170 break;
252b5132
RH
11171 }
11172 }
11173 else
f7a99963
NC
11174 print_vma (entry->d_un.d_val, PREFIX_HEX);
11175
11176 putchar ('\n');
252b5132
RH
11177 }
11178 break;
11179
11180 case DT_PLTRELSZ:
11181 case DT_RELASZ :
11182 case DT_STRSZ :
11183 case DT_RELSZ :
11184 case DT_RELAENT :
11185 case DT_SYMENT :
11186 case DT_RELENT :
978c4450 11187 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11188 /* Fall through. */
252b5132
RH
11189 case DT_PLTPADSZ:
11190 case DT_MOVEENT :
11191 case DT_MOVESZ :
11192 case DT_INIT_ARRAYSZ:
11193 case DT_FINI_ARRAYSZ:
047b2264
JJ
11194 case DT_GNU_CONFLICTSZ:
11195 case DT_GNU_LIBLISTSZ:
252b5132 11196 if (do_dynamic)
f7a99963
NC
11197 {
11198 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11199 printf (_(" (bytes)\n"));
f7a99963 11200 }
252b5132
RH
11201 break;
11202
11203 case DT_VERDEFNUM:
11204 case DT_VERNEEDNUM:
11205 case DT_RELACOUNT:
11206 case DT_RELCOUNT:
11207 if (do_dynamic)
f7a99963
NC
11208 {
11209 print_vma (entry->d_un.d_val, UNSIGNED);
11210 putchar ('\n');
11211 }
252b5132
RH
11212 break;
11213
11214 case DT_SYMINSZ:
11215 case DT_SYMINENT:
11216 case DT_SYMINFO:
11217 case DT_USED:
11218 case DT_INIT_ARRAY:
11219 case DT_FINI_ARRAY:
11220 if (do_dynamic)
11221 {
d79b3d50 11222 if (entry->d_tag == DT_USED
978c4450 11223 && VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
252b5132 11224 {
978c4450 11225 char * name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11226
b34976b6 11227 if (*name)
252b5132
RH
11228 {
11229 printf (_("Not needed object: [%s]\n"), name);
11230 break;
11231 }
11232 }
103f02d3 11233
f7a99963
NC
11234 print_vma (entry->d_un.d_val, PREFIX_HEX);
11235 putchar ('\n');
252b5132
RH
11236 }
11237 break;
11238
11239 case DT_BIND_NOW:
11240 /* The value of this entry is ignored. */
35b1837e
AM
11241 if (do_dynamic)
11242 putchar ('\n');
252b5132 11243 break;
103f02d3 11244
047b2264
JJ
11245 case DT_GNU_PRELINKED:
11246 if (do_dynamic)
11247 {
2cf0635d 11248 struct tm * tmp;
91d6fa6a 11249 time_t atime = entry->d_un.d_val;
047b2264 11250
91d6fa6a 11251 tmp = gmtime (&atime);
071436c6
NC
11252 /* PR 17533 file: 041-1244816-0.004. */
11253 if (tmp == NULL)
5a2cbcf4
L
11254 printf (_("<corrupt time val: %lx"),
11255 (unsigned long) atime);
071436c6
NC
11256 else
11257 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11258 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11259 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11260
11261 }
11262 break;
11263
fdc90cb4 11264 case DT_GNU_HASH:
978c4450 11265 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11266 if (do_dynamic)
11267 {
11268 print_vma (entry->d_un.d_val, PREFIX_HEX);
11269 putchar ('\n');
11270 }
11271 break;
11272
a5da3dee
VDM
11273 case DT_GNU_FLAGS_1:
11274 if (do_dynamic)
11275 {
11276 printf (_("Flags:"));
11277 if (entry->d_un.d_val == 0)
11278 printf (_(" None\n"));
11279 else
11280 {
11281 unsigned long int val = entry->d_un.d_val;
11282
11283 if (val & DF_GNU_1_UNIQUE)
11284 {
11285 printf (" UNIQUE");
11286 val ^= DF_GNU_1_UNIQUE;
11287 }
11288 if (val != 0)
11289 printf (" %lx", val);
11290 puts ("");
11291 }
11292 }
11293 break;
11294
252b5132
RH
11295 default:
11296 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11297 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11298 = entry->d_un.d_val;
252b5132
RH
11299
11300 if (do_dynamic)
11301 {
dda8d76d 11302 switch (filedata->file_header.e_machine)
252b5132 11303 {
37c18eed
SD
11304 case EM_AARCH64:
11305 dynamic_section_aarch64_val (entry);
11306 break;
252b5132 11307 case EM_MIPS:
4fe85591 11308 case EM_MIPS_RS3_LE:
978c4450 11309 dynamic_section_mips_val (filedata, entry);
252b5132 11310 break;
103f02d3 11311 case EM_PARISC:
b2d38a17 11312 dynamic_section_parisc_val (entry);
103f02d3 11313 break;
ecc51f48 11314 case EM_IA_64:
b2d38a17 11315 dynamic_section_ia64_val (entry);
ecc51f48 11316 break;
252b5132 11317 default:
f7a99963
NC
11318 print_vma (entry->d_un.d_val, PREFIX_HEX);
11319 putchar ('\n');
252b5132
RH
11320 }
11321 }
11322 break;
11323 }
11324 }
11325
015dc7e1 11326 return true;
252b5132
RH
11327}
11328
11329static char *
d3ba0551 11330get_ver_flags (unsigned int flags)
252b5132 11331{
6d4f21f6 11332 static char buff[128];
252b5132
RH
11333
11334 buff[0] = 0;
11335
11336 if (flags == 0)
11337 return _("none");
11338
11339 if (flags & VER_FLG_BASE)
7bb1ad17 11340 strcat (buff, "BASE");
252b5132
RH
11341
11342 if (flags & VER_FLG_WEAK)
11343 {
11344 if (flags & VER_FLG_BASE)
7bb1ad17 11345 strcat (buff, " | ");
252b5132 11346
7bb1ad17 11347 strcat (buff, "WEAK");
252b5132
RH
11348 }
11349
44ec90b9
RO
11350 if (flags & VER_FLG_INFO)
11351 {
11352 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11353 strcat (buff, " | ");
44ec90b9 11354
7bb1ad17 11355 strcat (buff, "INFO");
44ec90b9
RO
11356 }
11357
11358 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11359 {
11360 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11361 strcat (buff, " | ");
11362
11363 strcat (buff, _("<unknown>"));
11364 }
252b5132
RH
11365
11366 return buff;
11367}
11368
11369/* Display the contents of the version sections. */
98fb390a 11370
015dc7e1 11371static bool
dda8d76d 11372process_version_sections (Filedata * filedata)
252b5132 11373{
2cf0635d 11374 Elf_Internal_Shdr * section;
b34976b6 11375 unsigned i;
015dc7e1 11376 bool found = false;
252b5132
RH
11377
11378 if (! do_version)
015dc7e1 11379 return true;
252b5132 11380
dda8d76d
NC
11381 for (i = 0, section = filedata->section_headers;
11382 i < filedata->file_header.e_shnum;
b34976b6 11383 i++, section++)
252b5132
RH
11384 {
11385 switch (section->sh_type)
11386 {
11387 case SHT_GNU_verdef:
11388 {
2cf0635d 11389 Elf_External_Verdef * edefs;
452bf675
AM
11390 unsigned long idx;
11391 unsigned long cnt;
2cf0635d 11392 char * endbuf;
252b5132 11393
015dc7e1 11394 found = true;
252b5132 11395
ca0e11aa
NC
11396 if (filedata->is_separate)
11397 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
11398 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
11399 section->sh_info),
11400 filedata->file_name,
11401 printable_section_name (filedata, section),
11402 section->sh_info);
11403 else
11404 printf (ngettext ("\nVersion definition section '%s' "
11405 "contains %u entry:\n",
11406 "\nVersion definition section '%s' "
11407 "contains %u entries:\n",
11408 section->sh_info),
11409 printable_section_name (filedata, section),
11410 section->sh_info);
047c3dbf 11411
ae9ac79e 11412 printf (_(" Addr: 0x"));
252b5132 11413 printf_vma (section->sh_addr);
233f82cf 11414 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11415 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11416 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11417
3f5e193b 11418 edefs = (Elf_External_Verdef *)
dda8d76d 11419 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11420 _("version definition section"));
a6e9f9df
AM
11421 if (!edefs)
11422 break;
59245841 11423 endbuf = (char *) edefs + section->sh_size;
252b5132 11424
1445030f 11425 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11426 {
2cf0635d
NC
11427 char * vstart;
11428 Elf_External_Verdef * edef;
b34976b6 11429 Elf_Internal_Verdef ent;
2cf0635d 11430 Elf_External_Verdaux * eaux;
b34976b6 11431 Elf_Internal_Verdaux aux;
452bf675 11432 unsigned long isum;
b34976b6 11433 int j;
103f02d3 11434
252b5132 11435 vstart = ((char *) edefs) + idx;
54806181
AM
11436 if (vstart + sizeof (*edef) > endbuf)
11437 break;
252b5132
RH
11438
11439 edef = (Elf_External_Verdef *) vstart;
11440
11441 ent.vd_version = BYTE_GET (edef->vd_version);
11442 ent.vd_flags = BYTE_GET (edef->vd_flags);
11443 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11444 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11445 ent.vd_hash = BYTE_GET (edef->vd_hash);
11446 ent.vd_aux = BYTE_GET (edef->vd_aux);
11447 ent.vd_next = BYTE_GET (edef->vd_next);
11448
452bf675 11449 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11450 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11451
11452 printf (_(" Index: %d Cnt: %d "),
11453 ent.vd_ndx, ent.vd_cnt);
11454
452bf675 11455 /* Check for overflow. */
1445030f 11456 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11457 break;
11458
252b5132
RH
11459 vstart += ent.vd_aux;
11460
1445030f
AM
11461 if (vstart + sizeof (*eaux) > endbuf)
11462 break;
252b5132
RH
11463 eaux = (Elf_External_Verdaux *) vstart;
11464
11465 aux.vda_name = BYTE_GET (eaux->vda_name);
11466 aux.vda_next = BYTE_GET (eaux->vda_next);
11467
978c4450
AM
11468 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
11469 printf (_("Name: %s\n"),
11470 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132
RH
11471 else
11472 printf (_("Name index: %ld\n"), aux.vda_name);
11473
11474 isum = idx + ent.vd_aux;
11475
b34976b6 11476 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11477 {
1445030f
AM
11478 if (aux.vda_next < sizeof (*eaux)
11479 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11480 {
11481 warn (_("Invalid vda_next field of %lx\n"),
11482 aux.vda_next);
11483 j = ent.vd_cnt;
11484 break;
11485 }
dd24e3da 11486 /* Check for overflow. */
7e26601c 11487 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11488 break;
11489
252b5132
RH
11490 isum += aux.vda_next;
11491 vstart += aux.vda_next;
11492
54806181
AM
11493 if (vstart + sizeof (*eaux) > endbuf)
11494 break;
1445030f 11495 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11496
11497 aux.vda_name = BYTE_GET (eaux->vda_name);
11498 aux.vda_next = BYTE_GET (eaux->vda_next);
11499
978c4450 11500 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
452bf675 11501 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450
AM
11502 isum, j,
11503 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132 11504 else
452bf675 11505 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11506 isum, j, aux.vda_name);
11507 }
dd24e3da 11508
54806181
AM
11509 if (j < ent.vd_cnt)
11510 printf (_(" Version def aux past end of section\n"));
252b5132 11511
c9f02c3e
MR
11512 /* PR 17531:
11513 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11514 if (ent.vd_next < sizeof (*edef)
11515 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11516 {
11517 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11518 cnt = section->sh_info;
11519 break;
11520 }
452bf675 11521 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11522 break;
11523
252b5132
RH
11524 idx += ent.vd_next;
11525 }
dd24e3da 11526
54806181
AM
11527 if (cnt < section->sh_info)
11528 printf (_(" Version definition past end of section\n"));
252b5132
RH
11529
11530 free (edefs);
11531 }
11532 break;
103f02d3 11533
252b5132
RH
11534 case SHT_GNU_verneed:
11535 {
2cf0635d 11536 Elf_External_Verneed * eneed;
452bf675
AM
11537 unsigned long idx;
11538 unsigned long cnt;
2cf0635d 11539 char * endbuf;
252b5132 11540
015dc7e1 11541 found = true;
252b5132 11542
ca0e11aa
NC
11543 if (filedata->is_separate)
11544 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
11545 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
11546 section->sh_info),
11547 filedata->file_name,
11548 printable_section_name (filedata, section),
11549 section->sh_info);
11550 else
11551 printf (ngettext ("\nVersion needs section '%s' "
11552 "contains %u entry:\n",
11553 "\nVersion needs section '%s' "
11554 "contains %u entries:\n",
11555 section->sh_info),
11556 printable_section_name (filedata, section),
11557 section->sh_info);
047c3dbf 11558
252b5132
RH
11559 printf (_(" Addr: 0x"));
11560 printf_vma (section->sh_addr);
72de5009 11561 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11562 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11563 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11564
dda8d76d 11565 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11566 section->sh_offset, 1,
11567 section->sh_size,
9cf03b7e 11568 _("Version Needs section"));
a6e9f9df
AM
11569 if (!eneed)
11570 break;
59245841 11571 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11572
11573 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11574 {
2cf0635d 11575 Elf_External_Verneed * entry;
b34976b6 11576 Elf_Internal_Verneed ent;
452bf675 11577 unsigned long isum;
b34976b6 11578 int j;
2cf0635d 11579 char * vstart;
252b5132
RH
11580
11581 vstart = ((char *) eneed) + idx;
54806181
AM
11582 if (vstart + sizeof (*entry) > endbuf)
11583 break;
252b5132
RH
11584
11585 entry = (Elf_External_Verneed *) vstart;
11586
11587 ent.vn_version = BYTE_GET (entry->vn_version);
11588 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11589 ent.vn_file = BYTE_GET (entry->vn_file);
11590 ent.vn_aux = BYTE_GET (entry->vn_aux);
11591 ent.vn_next = BYTE_GET (entry->vn_next);
11592
452bf675 11593 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11594
978c4450
AM
11595 if (VALID_DYNAMIC_NAME (filedata, ent.vn_file))
11596 printf (_(" File: %s"),
11597 GET_DYNAMIC_NAME (filedata, ent.vn_file));
252b5132
RH
11598 else
11599 printf (_(" File: %lx"), ent.vn_file);
11600
11601 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11602
dd24e3da 11603 /* Check for overflow. */
7e26601c 11604 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11605 break;
252b5132
RH
11606 vstart += ent.vn_aux;
11607
11608 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11609 {
2cf0635d 11610 Elf_External_Vernaux * eaux;
b34976b6 11611 Elf_Internal_Vernaux aux;
252b5132 11612
54806181
AM
11613 if (vstart + sizeof (*eaux) > endbuf)
11614 break;
252b5132
RH
11615 eaux = (Elf_External_Vernaux *) vstart;
11616
11617 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11618 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11619 aux.vna_other = BYTE_GET (eaux->vna_other);
11620 aux.vna_name = BYTE_GET (eaux->vna_name);
11621 aux.vna_next = BYTE_GET (eaux->vna_next);
11622
978c4450 11623 if (VALID_DYNAMIC_NAME (filedata, aux.vna_name))
452bf675 11624 printf (_(" %#06lx: Name: %s"),
978c4450 11625 isum, GET_DYNAMIC_NAME (filedata, aux.vna_name));
252b5132 11626 else
452bf675 11627 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11628 isum, aux.vna_name);
11629
11630 printf (_(" Flags: %s Version: %d\n"),
11631 get_ver_flags (aux.vna_flags), aux.vna_other);
11632
1445030f
AM
11633 if (aux.vna_next < sizeof (*eaux)
11634 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11635 {
11636 warn (_("Invalid vna_next field of %lx\n"),
11637 aux.vna_next);
11638 j = ent.vn_cnt;
11639 break;
11640 }
1445030f
AM
11641 /* Check for overflow. */
11642 if (aux.vna_next > (size_t) (endbuf - vstart))
11643 break;
252b5132
RH
11644 isum += aux.vna_next;
11645 vstart += aux.vna_next;
11646 }
9cf03b7e 11647
54806181 11648 if (j < ent.vn_cnt)
f9a6a8f0 11649 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 11650
1445030f
AM
11651 if (ent.vn_next < sizeof (*entry)
11652 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11653 {
452bf675 11654 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11655 cnt = section->sh_info;
11656 break;
11657 }
1445030f
AM
11658 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11659 break;
252b5132
RH
11660 idx += ent.vn_next;
11661 }
9cf03b7e 11662
54806181 11663 if (cnt < section->sh_info)
9cf03b7e 11664 warn (_("Missing Version Needs information\n"));
103f02d3 11665
252b5132
RH
11666 free (eneed);
11667 }
11668 break;
11669
11670 case SHT_GNU_versym:
11671 {
2cf0635d 11672 Elf_Internal_Shdr * link_section;
8b73c356
NC
11673 size_t total;
11674 unsigned int cnt;
2cf0635d
NC
11675 unsigned char * edata;
11676 unsigned short * data;
11677 char * strtab;
11678 Elf_Internal_Sym * symbols;
11679 Elf_Internal_Shdr * string_sec;
ba5cdace 11680 unsigned long num_syms;
d3ba0551 11681 long off;
252b5132 11682
dda8d76d 11683 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11684 break;
11685
dda8d76d 11686 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11687 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11688
dda8d76d 11689 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11690 break;
11691
015dc7e1 11692 found = true;
252b5132 11693
dda8d76d 11694 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
11695 if (symbols == NULL)
11696 break;
252b5132 11697
dda8d76d 11698 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11699
dda8d76d 11700 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11701 string_sec->sh_size,
11702 _("version string table"));
a6e9f9df 11703 if (!strtab)
0429c154
MS
11704 {
11705 free (symbols);
11706 break;
11707 }
252b5132 11708
ca0e11aa
NC
11709 if (filedata->is_separate)
11710 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
11711 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
11712 total),
11713 filedata->file_name,
11714 printable_section_name (filedata, section),
11715 (unsigned long) total);
11716 else
11717 printf (ngettext ("\nVersion symbols section '%s' "
11718 "contains %lu entry:\n",
11719 "\nVersion symbols section '%s' "
11720 "contains %lu entries:\n",
11721 total),
11722 printable_section_name (filedata, section),
11723 (unsigned long) total);
252b5132 11724
ae9ac79e 11725 printf (_(" Addr: 0x"));
252b5132 11726 printf_vma (section->sh_addr);
72de5009 11727 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11728 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11729 printable_section_name (filedata, link_section));
252b5132 11730
dda8d76d 11731 off = offset_from_vma (filedata,
978c4450 11732 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11733 total * sizeof (short));
95099889
AM
11734 edata = (unsigned char *) get_data (NULL, filedata, off,
11735 sizeof (short), total,
11736 _("version symbol data"));
a6e9f9df
AM
11737 if (!edata)
11738 {
11739 free (strtab);
0429c154 11740 free (symbols);
a6e9f9df
AM
11741 break;
11742 }
252b5132 11743
3f5e193b 11744 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11745
11746 for (cnt = total; cnt --;)
b34976b6
AM
11747 data[cnt] = byte_get (edata + cnt * sizeof (short),
11748 sizeof (short));
252b5132
RH
11749
11750 free (edata);
11751
11752 for (cnt = 0; cnt < total; cnt += 4)
11753 {
11754 int j, nn;
ab273396
AM
11755 char *name;
11756 char *invalid = _("*invalid*");
252b5132
RH
11757
11758 printf (" %03x:", cnt);
11759
11760 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11761 switch (data[cnt + j])
252b5132
RH
11762 {
11763 case 0:
11764 fputs (_(" 0 (*local*) "), stdout);
11765 break;
11766
11767 case 1:
11768 fputs (_(" 1 (*global*) "), stdout);
11769 break;
11770
11771 default:
c244d050
NC
11772 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11773 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11774
dd24e3da 11775 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11776 array, break to avoid an out-of-bounds read. */
11777 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11778 {
11779 warn (_("invalid index into symbol array\n"));
11780 break;
11781 }
11782
ab273396 11783 name = NULL;
978c4450 11784 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11785 {
b34976b6
AM
11786 Elf_Internal_Verneed ivn;
11787 unsigned long offset;
252b5132 11788
d93f0186 11789 offset = offset_from_vma
978c4450
AM
11790 (filedata,
11791 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11792 sizeof (Elf_External_Verneed));
252b5132 11793
b34976b6 11794 do
252b5132 11795 {
b34976b6
AM
11796 Elf_Internal_Vernaux ivna;
11797 Elf_External_Verneed evn;
11798 Elf_External_Vernaux evna;
11799 unsigned long a_off;
252b5132 11800
dda8d76d 11801 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11802 _("version need")) == NULL)
11803 break;
0b4362b0 11804
252b5132
RH
11805 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11806 ivn.vn_next = BYTE_GET (evn.vn_next);
11807
11808 a_off = offset + ivn.vn_aux;
11809
11810 do
11811 {
dda8d76d 11812 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11813 1, _("version need aux (2)")) == NULL)
11814 {
11815 ivna.vna_next = 0;
11816 ivna.vna_other = 0;
11817 }
11818 else
11819 {
11820 ivna.vna_next = BYTE_GET (evna.vna_next);
11821 ivna.vna_other = BYTE_GET (evna.vna_other);
11822 }
252b5132
RH
11823
11824 a_off += ivna.vna_next;
11825 }
b34976b6 11826 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11827 && ivna.vna_next != 0);
11828
b34976b6 11829 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11830 {
11831 ivna.vna_name = BYTE_GET (evna.vna_name);
11832
54806181 11833 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11834 name = invalid;
54806181
AM
11835 else
11836 name = strtab + ivna.vna_name;
252b5132
RH
11837 break;
11838 }
11839
11840 offset += ivn.vn_next;
11841 }
11842 while (ivn.vn_next);
11843 }
00d93f34 11844
ab273396 11845 if (data[cnt + j] != 0x8001
978c4450 11846 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 11847 {
b34976b6
AM
11848 Elf_Internal_Verdef ivd;
11849 Elf_External_Verdef evd;
11850 unsigned long offset;
252b5132 11851
d93f0186 11852 offset = offset_from_vma
978c4450
AM
11853 (filedata,
11854 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 11855 sizeof evd);
252b5132
RH
11856
11857 do
11858 {
dda8d76d 11859 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
11860 _("version def")) == NULL)
11861 {
11862 ivd.vd_next = 0;
948f632f 11863 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
11864 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
11865 break;
59245841
NC
11866 }
11867 else
11868 {
11869 ivd.vd_next = BYTE_GET (evd.vd_next);
11870 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11871 }
252b5132
RH
11872
11873 offset += ivd.vd_next;
11874 }
c244d050 11875 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
11876 && ivd.vd_next != 0);
11877
c244d050 11878 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 11879 {
b34976b6
AM
11880 Elf_External_Verdaux evda;
11881 Elf_Internal_Verdaux ivda;
252b5132
RH
11882
11883 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11884
dda8d76d 11885 if (get_data (&evda, filedata,
59245841
NC
11886 offset - ivd.vd_next + ivd.vd_aux,
11887 sizeof (evda), 1,
11888 _("version def aux")) == NULL)
11889 break;
252b5132
RH
11890
11891 ivda.vda_name = BYTE_GET (evda.vda_name);
11892
54806181 11893 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
11894 name = invalid;
11895 else if (name != NULL && name != invalid)
11896 name = _("*both*");
54806181
AM
11897 else
11898 name = strtab + ivda.vda_name;
252b5132
RH
11899 }
11900 }
ab273396
AM
11901 if (name != NULL)
11902 nn += printf ("(%s%-*s",
11903 name,
11904 12 - (int) strlen (name),
11905 ")");
252b5132
RH
11906
11907 if (nn < 18)
11908 printf ("%*c", 18 - nn, ' ');
11909 }
11910
11911 putchar ('\n');
11912 }
11913
11914 free (data);
11915 free (strtab);
11916 free (symbols);
11917 }
11918 break;
103f02d3 11919
252b5132
RH
11920 default:
11921 break;
11922 }
11923 }
11924
11925 if (! found)
ca0e11aa
NC
11926 {
11927 if (filedata->is_separate)
11928 printf (_("\nNo version information found in linked file '%s'.\n"),
11929 filedata->file_name);
11930 else
11931 printf (_("\nNo version information found in this file.\n"));
11932 }
252b5132 11933
015dc7e1 11934 return true;
252b5132
RH
11935}
11936
d1133906 11937static const char *
dda8d76d 11938get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 11939{
89246a0e 11940 static char buff[64];
252b5132
RH
11941
11942 switch (binding)
11943 {
b34976b6
AM
11944 case STB_LOCAL: return "LOCAL";
11945 case STB_GLOBAL: return "GLOBAL";
11946 case STB_WEAK: return "WEAK";
252b5132
RH
11947 default:
11948 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
11949 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
11950 binding);
252b5132 11951 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
11952 {
11953 if (binding == STB_GNU_UNIQUE
df3a023b 11954 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
11955 return "UNIQUE";
11956 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
11957 }
252b5132 11958 else
e9e44622 11959 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
11960 return buff;
11961 }
11962}
11963
d1133906 11964static const char *
dda8d76d 11965get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 11966{
89246a0e 11967 static char buff[64];
252b5132
RH
11968
11969 switch (type)
11970 {
b34976b6
AM
11971 case STT_NOTYPE: return "NOTYPE";
11972 case STT_OBJECT: return "OBJECT";
11973 case STT_FUNC: return "FUNC";
11974 case STT_SECTION: return "SECTION";
11975 case STT_FILE: return "FILE";
11976 case STT_COMMON: return "COMMON";
11977 case STT_TLS: return "TLS";
15ab5209
DB
11978 case STT_RELC: return "RELC";
11979 case STT_SRELC: return "SRELC";
252b5132
RH
11980 default:
11981 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 11982 {
dda8d76d 11983 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 11984 return "THUMB_FUNC";
103f02d3 11985
dda8d76d 11986 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
11987 return "REGISTER";
11988
dda8d76d 11989 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
11990 return "PARISC_MILLI";
11991
e9e44622 11992 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 11993 }
252b5132 11994 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 11995 {
dda8d76d 11996 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
11997 {
11998 if (type == STT_HP_OPAQUE)
11999 return "HP_OPAQUE";
12000 if (type == STT_HP_STUB)
12001 return "HP_STUB";
12002 }
12003
d8045f23 12004 if (type == STT_GNU_IFUNC
dda8d76d 12005 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12006 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12007 return "IFUNC";
12008
e9e44622 12009 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12010 }
252b5132 12011 else
e9e44622 12012 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12013 return buff;
12014 }
12015}
12016
d1133906 12017static const char *
d3ba0551 12018get_symbol_visibility (unsigned int visibility)
d1133906
NC
12019{
12020 switch (visibility)
12021 {
b34976b6
AM
12022 case STV_DEFAULT: return "DEFAULT";
12023 case STV_INTERNAL: return "INTERNAL";
12024 case STV_HIDDEN: return "HIDDEN";
d1133906 12025 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12026 default:
27a45f42 12027 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12028 return _("<unknown>");
d1133906
NC
12029 }
12030}
12031
2057d69d
CZ
12032static const char *
12033get_alpha_symbol_other (unsigned int other)
9abca702 12034{
2057d69d
CZ
12035 switch (other)
12036 {
12037 case STO_ALPHA_NOPV: return "NOPV";
12038 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12039 default:
27a45f42 12040 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12041 return _("<unknown>");
9abca702 12042 }
2057d69d
CZ
12043}
12044
fd85a6a1
NC
12045static const char *
12046get_solaris_symbol_visibility (unsigned int visibility)
12047{
12048 switch (visibility)
12049 {
12050 case 4: return "EXPORTED";
12051 case 5: return "SINGLETON";
12052 case 6: return "ELIMINATE";
12053 default: return get_symbol_visibility (visibility);
12054 }
12055}
12056
2301ed1c
SN
12057static const char *
12058get_aarch64_symbol_other (unsigned int other)
12059{
12060 static char buf[32];
12061
12062 if (other & STO_AARCH64_VARIANT_PCS)
12063 {
12064 other &= ~STO_AARCH64_VARIANT_PCS;
12065 if (other == 0)
12066 return "VARIANT_PCS";
12067 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12068 return buf;
12069 }
12070 return NULL;
12071}
12072
5e2b0d47
NC
12073static const char *
12074get_mips_symbol_other (unsigned int other)
12075{
12076 switch (other)
12077 {
32ec8896
NC
12078 case STO_OPTIONAL: return "OPTIONAL";
12079 case STO_MIPS_PLT: return "MIPS PLT";
12080 case STO_MIPS_PIC: return "MIPS PIC";
12081 case STO_MICROMIPS: return "MICROMIPS";
12082 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12083 case STO_MIPS16: return "MIPS16";
12084 default: return NULL;
5e2b0d47
NC
12085 }
12086}
12087
28f997cf 12088static const char *
dda8d76d 12089get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12090{
dda8d76d 12091 if (is_ia64_vms (filedata))
28f997cf
TG
12092 {
12093 static char res[32];
12094
12095 res[0] = 0;
12096
12097 /* Function types is for images and .STB files only. */
dda8d76d 12098 switch (filedata->file_header.e_type)
28f997cf
TG
12099 {
12100 case ET_DYN:
12101 case ET_EXEC:
12102 switch (VMS_ST_FUNC_TYPE (other))
12103 {
12104 case VMS_SFT_CODE_ADDR:
12105 strcat (res, " CA");
12106 break;
12107 case VMS_SFT_SYMV_IDX:
12108 strcat (res, " VEC");
12109 break;
12110 case VMS_SFT_FD:
12111 strcat (res, " FD");
12112 break;
12113 case VMS_SFT_RESERVE:
12114 strcat (res, " RSV");
12115 break;
12116 default:
bee0ee85
NC
12117 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12118 VMS_ST_FUNC_TYPE (other));
12119 strcat (res, " <unknown>");
12120 break;
28f997cf
TG
12121 }
12122 break;
12123 default:
12124 break;
12125 }
12126 switch (VMS_ST_LINKAGE (other))
12127 {
12128 case VMS_STL_IGNORE:
12129 strcat (res, " IGN");
12130 break;
12131 case VMS_STL_RESERVE:
12132 strcat (res, " RSV");
12133 break;
12134 case VMS_STL_STD:
12135 strcat (res, " STD");
12136 break;
12137 case VMS_STL_LNK:
12138 strcat (res, " LNK");
12139 break;
12140 default:
bee0ee85
NC
12141 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12142 VMS_ST_LINKAGE (other));
12143 strcat (res, " <unknown>");
12144 break;
28f997cf
TG
12145 }
12146
12147 if (res[0] != 0)
12148 return res + 1;
12149 else
12150 return res;
12151 }
12152 return NULL;
12153}
12154
6911b7dc
AM
12155static const char *
12156get_ppc64_symbol_other (unsigned int other)
12157{
14732552
AM
12158 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12159 return NULL;
12160
12161 other >>= STO_PPC64_LOCAL_BIT;
12162 if (other <= 6)
6911b7dc 12163 {
89246a0e 12164 static char buf[64];
14732552
AM
12165 if (other >= 2)
12166 other = ppc64_decode_local_entry (other);
12167 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12168 return buf;
12169 }
12170 return NULL;
12171}
12172
5e2b0d47 12173static const char *
dda8d76d 12174get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12175{
12176 const char * result = NULL;
89246a0e 12177 static char buff [64];
5e2b0d47
NC
12178
12179 if (other == 0)
12180 return "";
12181
dda8d76d 12182 switch (filedata->file_header.e_machine)
5e2b0d47 12183 {
2057d69d
CZ
12184 case EM_ALPHA:
12185 result = get_alpha_symbol_other (other);
12186 break;
2301ed1c
SN
12187 case EM_AARCH64:
12188 result = get_aarch64_symbol_other (other);
12189 break;
5e2b0d47
NC
12190 case EM_MIPS:
12191 result = get_mips_symbol_other (other);
28f997cf
TG
12192 break;
12193 case EM_IA_64:
dda8d76d 12194 result = get_ia64_symbol_other (filedata, other);
28f997cf 12195 break;
6911b7dc
AM
12196 case EM_PPC64:
12197 result = get_ppc64_symbol_other (other);
12198 break;
5e2b0d47 12199 default:
fd85a6a1 12200 result = NULL;
5e2b0d47
NC
12201 break;
12202 }
12203
12204 if (result)
12205 return result;
12206
12207 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12208 return buff;
12209}
12210
d1133906 12211static const char *
dda8d76d 12212get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12213{
b34976b6 12214 static char buff[32];
5cf1065c 12215
252b5132
RH
12216 switch (type)
12217 {
b34976b6
AM
12218 case SHN_UNDEF: return "UND";
12219 case SHN_ABS: return "ABS";
12220 case SHN_COMMON: return "COM";
252b5132 12221 default:
9ce701e2 12222 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12223 && filedata->file_header.e_machine == EM_IA_64
12224 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12225 return "ANSI_COM";
12226 else if ((filedata->file_header.e_machine == EM_X86_64
12227 || filedata->file_header.e_machine == EM_L1OM
12228 || filedata->file_header.e_machine == EM_K1OM)
12229 && type == SHN_X86_64_LCOMMON)
12230 return "LARGE_COM";
12231 else if ((type == SHN_MIPS_SCOMMON
12232 && filedata->file_header.e_machine == EM_MIPS)
12233 || (type == SHN_TIC6X_SCOMMON
12234 && filedata->file_header.e_machine == EM_TI_C6000))
12235 return "SCOM";
12236 else if (type == SHN_MIPS_SUNDEFINED
12237 && filedata->file_header.e_machine == EM_MIPS)
12238 return "SUND";
12239 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12240 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12241 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12242 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12243 else if (type >= SHN_LORESERVE)
12244 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12245 else if (filedata->file_header.e_shnum != 0
12246 && type >= filedata->file_header.e_shnum)
12247 sprintf (buff, _("bad section index[%3d]"), type);
12248 else
12249 sprintf (buff, "%3d", type);
12250 break;
fd85a6a1
NC
12251 }
12252
10ca4b04 12253 return buff;
6bd1a22c
L
12254}
12255
bb4d2ac2 12256static const char *
dda8d76d 12257get_symbol_version_string (Filedata * filedata,
015dc7e1 12258 bool is_dynsym,
1449284b
NC
12259 const char * strtab,
12260 unsigned long int strtab_size,
12261 unsigned int si,
12262 Elf_Internal_Sym * psym,
12263 enum versioned_symbol_info * sym_info,
12264 unsigned short * vna_other)
bb4d2ac2 12265{
ab273396
AM
12266 unsigned char data[2];
12267 unsigned short vers_data;
12268 unsigned long offset;
7a815dd5 12269 unsigned short max_vd_ndx;
bb4d2ac2 12270
ab273396 12271 if (!is_dynsym
978c4450 12272 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12273 return NULL;
bb4d2ac2 12274
978c4450
AM
12275 offset = offset_from_vma (filedata,
12276 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12277 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12278
dda8d76d 12279 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12280 sizeof (data), 1, _("version data")) == NULL)
12281 return NULL;
12282
12283 vers_data = byte_get (data, 2);
bb4d2ac2 12284
1f6f5dba 12285 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12286 return NULL;
bb4d2ac2 12287
0b8b7609 12288 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12289 max_vd_ndx = 0;
12290
ab273396
AM
12291 /* Usually we'd only see verdef for defined symbols, and verneed for
12292 undefined symbols. However, symbols defined by the linker in
12293 .dynbss for variables copied from a shared library in order to
12294 avoid text relocations are defined yet have verneed. We could
12295 use a heuristic to detect the special case, for example, check
12296 for verneed first on symbols defined in SHT_NOBITS sections, but
12297 it is simpler and more reliable to just look for both verdef and
12298 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12299
ab273396
AM
12300 if (psym->st_shndx != SHN_UNDEF
12301 && vers_data != 0x8001
978c4450 12302 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12303 {
12304 Elf_Internal_Verdef ivd;
12305 Elf_Internal_Verdaux ivda;
12306 Elf_External_Verdaux evda;
12307 unsigned long off;
bb4d2ac2 12308
dda8d76d 12309 off = offset_from_vma (filedata,
978c4450 12310 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12311 sizeof (Elf_External_Verdef));
12312
12313 do
bb4d2ac2 12314 {
ab273396
AM
12315 Elf_External_Verdef evd;
12316
dda8d76d 12317 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12318 _("version def")) == NULL)
12319 {
12320 ivd.vd_ndx = 0;
12321 ivd.vd_aux = 0;
12322 ivd.vd_next = 0;
1f6f5dba 12323 ivd.vd_flags = 0;
ab273396
AM
12324 }
12325 else
bb4d2ac2 12326 {
ab273396
AM
12327 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12328 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12329 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12330 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12331 }
bb4d2ac2 12332
7a815dd5
L
12333 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12334 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12335
ab273396
AM
12336 off += ivd.vd_next;
12337 }
12338 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12339
ab273396
AM
12340 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12341 {
9abca702 12342 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12343 return NULL;
12344
ab273396
AM
12345 off -= ivd.vd_next;
12346 off += ivd.vd_aux;
bb4d2ac2 12347
dda8d76d 12348 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12349 _("version def aux")) != NULL)
12350 {
12351 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12352
ab273396 12353 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12354 return (ivda.vda_name < strtab_size
12355 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12356 }
12357 }
12358 }
bb4d2ac2 12359
978c4450 12360 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12361 {
12362 Elf_External_Verneed evn;
12363 Elf_Internal_Verneed ivn;
12364 Elf_Internal_Vernaux ivna;
bb4d2ac2 12365
dda8d76d 12366 offset = offset_from_vma (filedata,
978c4450 12367 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12368 sizeof evn);
12369 do
12370 {
12371 unsigned long vna_off;
bb4d2ac2 12372
dda8d76d 12373 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12374 _("version need")) == NULL)
12375 {
12376 ivna.vna_next = 0;
12377 ivna.vna_other = 0;
12378 ivna.vna_name = 0;
12379 break;
12380 }
bb4d2ac2 12381
ab273396
AM
12382 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12383 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12384
ab273396 12385 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12386
ab273396
AM
12387 do
12388 {
12389 Elf_External_Vernaux evna;
bb4d2ac2 12390
dda8d76d 12391 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12392 _("version need aux (3)")) == NULL)
bb4d2ac2 12393 {
ab273396
AM
12394 ivna.vna_next = 0;
12395 ivna.vna_other = 0;
12396 ivna.vna_name = 0;
bb4d2ac2 12397 }
bb4d2ac2 12398 else
bb4d2ac2 12399 {
ab273396
AM
12400 ivna.vna_other = BYTE_GET (evna.vna_other);
12401 ivna.vna_next = BYTE_GET (evna.vna_next);
12402 ivna.vna_name = BYTE_GET (evna.vna_name);
12403 }
bb4d2ac2 12404
ab273396
AM
12405 vna_off += ivna.vna_next;
12406 }
12407 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12408
ab273396
AM
12409 if (ivna.vna_other == vers_data)
12410 break;
bb4d2ac2 12411
ab273396
AM
12412 offset += ivn.vn_next;
12413 }
12414 while (ivn.vn_next != 0);
bb4d2ac2 12415
ab273396
AM
12416 if (ivna.vna_other == vers_data)
12417 {
12418 *sym_info = symbol_undefined;
12419 *vna_other = ivna.vna_other;
12420 return (ivna.vna_name < strtab_size
12421 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12422 }
7a815dd5
L
12423 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12424 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12425 return _("<corrupt>");
bb4d2ac2 12426 }
ab273396 12427 return NULL;
bb4d2ac2
L
12428}
12429
047c3dbf
NL
12430/* Display a symbol size on stdout. Format is based on --sym-base setting. */
12431
12432static unsigned int
12433print_dynamic_symbol_size (bfd_vma vma, int base)
12434{
12435 switch (base)
12436 {
12437 case 8:
12438 return print_vma (vma, OCTAL_5);
12439
12440 case 10:
12441 return print_vma (vma, UNSIGNED_5);
12442
12443 case 16:
12444 return print_vma (vma, PREFIX_HEX_5);
12445
12446 case 0:
12447 default:
12448 return print_vma (vma, DEC_5);
12449 }
12450}
12451
10ca4b04
L
12452static void
12453print_dynamic_symbol (Filedata *filedata, unsigned long si,
12454 Elf_Internal_Sym *symtab,
12455 Elf_Internal_Shdr *section,
12456 char *strtab, size_t strtab_size)
252b5132 12457{
10ca4b04
L
12458 const char *version_string;
12459 enum versioned_symbol_info sym_info;
12460 unsigned short vna_other;
23356397
NC
12461 bool is_valid;
12462 const char * sstr;
10ca4b04 12463 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 12464
10ca4b04
L
12465 printf ("%6ld: ", si);
12466 print_vma (psym->st_value, LONG_HEX);
12467 putchar (' ');
047c3dbf 12468 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
12469 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12470 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12471 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12472 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12473 else
252b5132 12474 {
10ca4b04 12475 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12476
10ca4b04
L
12477 printf (" %-7s", get_symbol_visibility (vis));
12478 /* Check to see if any other bits in the st_other field are set.
12479 Note - displaying this information disrupts the layout of the
12480 table being generated, but for the moment this case is very rare. */
12481 if (psym->st_other ^ vis)
12482 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12483 }
10ca4b04 12484 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 12485
23356397
NC
12486 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
12487 && psym->st_shndx < filedata->file_header.e_shnum
12488 && psym->st_name == 0)
12489 {
12490 is_valid = SECTION_NAME_VALID (filedata->section_headers + psym->st_shndx);
12491 sstr = is_valid ?
12492 SECTION_NAME_PRINT (filedata->section_headers + psym->st_shndx)
12493 : _("<corrupt>");
12494 }
12495 else
12496 {
12497 is_valid = VALID_SYMBOL_NAME (strtab, strtab_size, psym->st_name);
12498 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
12499 }
10ca4b04
L
12500
12501 version_string
12502 = get_symbol_version_string (filedata,
12503 (section == NULL
12504 || section->sh_type == SHT_DYNSYM),
12505 strtab, strtab_size, si,
12506 psym, &sym_info, &vna_other);
b9e920ec 12507
0942c7ab
NC
12508 int len_avail = 21;
12509 if (! do_wide && version_string != NULL)
12510 {
ddb43bab 12511 char buffer[16];
0942c7ab 12512
ddb43bab 12513 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
12514
12515 if (sym_info == symbol_undefined)
12516 len_avail -= sprintf (buffer," (%d)", vna_other);
12517 else if (sym_info != symbol_hidden)
12518 len_avail -= 1;
12519 }
12520
12521 print_symbol (len_avail, sstr);
b9e920ec 12522
10ca4b04
L
12523 if (version_string)
12524 {
12525 if (sym_info == symbol_undefined)
12526 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12527 else
10ca4b04
L
12528 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12529 version_string);
12530 }
6bd1a22c 12531
10ca4b04 12532 putchar ('\n');
6bd1a22c 12533
10ca4b04
L
12534 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12535 && section != NULL
12536 && si >= section->sh_info
12537 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12538 && filedata->file_header.e_machine != EM_MIPS
12539 /* Solaris binaries have been found to violate this requirement as
12540 well. Not sure if this is a bug or an ABI requirement. */
12541 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12542 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12543 si, printable_section_name (filedata, section), section->sh_info);
12544}
f16a9783 12545
0f03783c
NC
12546static const char *
12547get_lto_kind (unsigned int kind)
12548{
12549 switch (kind)
12550 {
12551 case 0: return "DEF";
12552 case 1: return "WEAKDEF";
12553 case 2: return "UNDEF";
12554 case 3: return "WEAKUNDEF";
12555 case 4: return "COMMON";
12556 default:
12557 break;
12558 }
12559
12560 static char buffer[30];
12561 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
12562 sprintf (buffer, "<unknown: %u>", kind);
12563 return buffer;
12564}
12565
12566static const char *
12567get_lto_visibility (unsigned int visibility)
12568{
12569 switch (visibility)
12570 {
12571 case 0: return "DEFAULT";
12572 case 1: return "PROTECTED";
12573 case 2: return "INTERNAL";
12574 case 3: return "HIDDEN";
12575 default:
12576 break;
12577 }
12578
12579 static char buffer[30];
12580 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
12581 sprintf (buffer, "<unknown: %u>", visibility);
12582 return buffer;
12583}
12584
12585static const char *
12586get_lto_sym_type (unsigned int sym_type)
12587{
12588 switch (sym_type)
12589 {
12590 case 0: return "UNKNOWN";
12591 case 1: return "FUNCTION";
12592 case 2: return "VARIABLE";
12593 default:
12594 break;
12595 }
12596
12597 static char buffer[30];
12598 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
12599 sprintf (buffer, "<unknown: %u>", sym_type);
12600 return buffer;
12601}
12602
12603/* Display an LTO format symbol table.
12604 FIXME: The format of LTO symbol tables is not formalized.
12605 So this code could need changing in the future. */
12606
015dc7e1 12607static bool
0f03783c
NC
12608display_lto_symtab (Filedata * filedata,
12609 Elf_Internal_Shdr * section)
12610{
12611 if (section->sh_size == 0)
12612 {
ca0e11aa
NC
12613 if (filedata->is_separate)
12614 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
12615 printable_section_name (filedata, section),
12616 filedata->file_name);
12617 else
12618 printf (_("\nLTO Symbol table '%s' is empty!\n"),
12619 printable_section_name (filedata, section));
047c3dbf 12620
015dc7e1 12621 return true;
0f03783c
NC
12622 }
12623
12624 if (section->sh_size > filedata->file_size)
12625 {
12626 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
12627 printable_section_name (filedata, section),
12628 (unsigned long) section->sh_size);
015dc7e1 12629 return false;
0f03783c
NC
12630 }
12631
12632 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
12633 section->sh_size, 1, _("LTO symbols"));
12634 if (alloced_data == NULL)
015dc7e1 12635 return false;
0f03783c
NC
12636
12637 /* Look for extended data for the symbol table. */
12638 Elf_Internal_Shdr * ext;
12639 void * ext_data_orig = NULL;
12640 char * ext_data = NULL;
12641 char * ext_data_end = NULL;
12642 char * ext_name = NULL;
12643
12644 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
b9e920ec 12645 SECTION_NAME (section) + sizeof (".gnu.lto_.symtab.") - 1) > 0
0f03783c
NC
12646 && ext_name != NULL /* Paranoia. */
12647 && (ext = find_section (filedata, ext_name)) != NULL)
12648 {
12649 if (ext->sh_size < 3)
12650 error (_("LTO Symbol extension table '%s' is empty!\n"),
12651 printable_section_name (filedata, ext));
12652 else
12653 {
12654 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
12655 ext->sh_size, 1,
12656 _("LTO ext symbol data"));
12657 if (ext_data != NULL)
12658 {
12659 ext_data_end = ext_data + ext->sh_size;
12660 if (* ext_data++ != 1)
12661 error (_("Unexpected version number in symbol extension table\n"));
12662 }
12663 }
12664 }
b9e920ec 12665
0f03783c
NC
12666 const unsigned char * data = (const unsigned char *) alloced_data;
12667 const unsigned char * end = data + section->sh_size;
12668
ca0e11aa
NC
12669 if (filedata->is_separate)
12670 printf (_("\nIn linked file '%s': "), filedata->file_name);
12671 else
12672 printf ("\n");
12673
0f03783c
NC
12674 if (ext_data_orig != NULL)
12675 {
12676 if (do_wide)
ca0e11aa 12677 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
12678 printable_section_name (filedata, section),
12679 printable_section_name (filedata, ext));
12680 else
12681 {
ca0e11aa 12682 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
12683 printable_section_name (filedata, section));
12684 printf (_(" and extension table '%s' contain:\n"),
12685 printable_section_name (filedata, ext));
12686 }
12687 }
12688 else
ca0e11aa 12689 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 12690 printable_section_name (filedata, section));
b9e920ec 12691
0f03783c 12692 /* FIXME: Add a wide version. */
b9e920ec 12693 if (ext_data_orig != NULL)
0f03783c
NC
12694 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
12695 else
12696 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
12697
12698 /* FIXME: We do not handle style prefixes. */
12699
12700 while (data < end)
12701 {
12702 const unsigned char * sym_name = data;
12703 data += strnlen ((const char *) sym_name, end - data) + 1;
12704 if (data >= end)
12705 goto fail;
12706
12707 const unsigned char * comdat_key = data;
12708 data += strnlen ((const char *) comdat_key, end - data) + 1;
12709 if (data >= end)
12710 goto fail;
12711
12712 if (data + 2 + 8 + 4 > end)
12713 goto fail;
12714
12715 unsigned int kind = *data++;
12716 unsigned int visibility = *data++;
12717
12718 elf_vma size = byte_get (data, 8);
12719 data += 8;
12720
12721 elf_vma slot = byte_get (data, 4);
12722 data += 4;
12723
12724 if (ext_data != NULL)
12725 {
12726 if (ext_data < (ext_data_end - 1))
12727 {
12728 unsigned int sym_type = * ext_data ++;
12729 unsigned int sec_kind = * ext_data ++;
12730
12731 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
12732 * comdat_key == 0 ? "-" : (char *) comdat_key,
12733 get_lto_kind (kind),
12734 get_lto_visibility (visibility),
12735 (long) size,
12736 (long) slot,
12737 get_lto_sym_type (sym_type),
12738 (long) sec_kind);
12739 print_symbol (6, (const char *) sym_name);
12740 }
12741 else
12742 {
12743 error (_("Ran out of LTO symbol extension data\n"));
12744 ext_data = NULL;
12745 /* FIXME: return FAIL result ? */
12746 }
12747 }
12748 else
12749 {
12750 printf (" %10s %10s %11s %08lx %08lx _",
12751 * comdat_key == 0 ? "-" : (char *) comdat_key,
12752 get_lto_kind (kind),
12753 get_lto_visibility (visibility),
12754 (long) size,
12755 (long) slot);
12756 print_symbol (21, (const char *) sym_name);
12757 }
12758 putchar ('\n');
12759 }
12760
12761 if (ext_data != NULL && ext_data < ext_data_end)
12762 {
12763 error (_("Data remains in the LTO symbol extension table\n"));
12764 goto fail;
12765 }
12766
12767 free (alloced_data);
12768 free (ext_data_orig);
12769 free (ext_name);
015dc7e1 12770 return true;
b9e920ec 12771
0f03783c
NC
12772 fail:
12773 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
12774 free (alloced_data);
12775 free (ext_data_orig);
12776 free (ext_name);
015dc7e1 12777 return false;
0f03783c
NC
12778}
12779
12780/* Display LTO symbol tables. */
12781
015dc7e1 12782static bool
0f03783c
NC
12783process_lto_symbol_tables (Filedata * filedata)
12784{
12785 Elf_Internal_Shdr * section;
12786 unsigned int i;
015dc7e1 12787 bool res = true;
0f03783c
NC
12788
12789 if (!do_lto_syms)
015dc7e1 12790 return true;
0f03783c
NC
12791
12792 if (filedata->section_headers == NULL)
015dc7e1 12793 return true;
0f03783c
NC
12794
12795 for (i = 0, section = filedata->section_headers;
12796 i < filedata->file_header.e_shnum;
12797 i++, section++)
b9e920ec 12798 if (SECTION_NAME_VALID (section)
08dedd66 12799 && startswith (SECTION_NAME (section), ".gnu.lto_.symtab."))
0f03783c
NC
12800 res &= display_lto_symtab (filedata, section);
12801
b9e920ec 12802 return res;
0f03783c
NC
12803}
12804
10ca4b04 12805/* Dump the symbol table. */
0f03783c 12806
015dc7e1 12807static bool
10ca4b04
L
12808process_symbol_table (Filedata * filedata)
12809{
12810 Elf_Internal_Shdr * section;
f16a9783 12811
10ca4b04 12812 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 12813 return true;
6bd1a22c 12814
978c4450 12815 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
12816 && do_syms
12817 && do_using_dynamic
978c4450
AM
12818 && filedata->dynamic_strings != NULL
12819 && filedata->dynamic_symbols != NULL)
6bd1a22c 12820 {
10ca4b04 12821 unsigned long si;
6bd1a22c 12822
ca0e11aa
NC
12823 if (filedata->is_separate)
12824 {
12825 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
12826 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
12827 filedata->num_dynamic_syms),
12828 filedata->file_name,
12829 filedata->num_dynamic_syms);
12830 }
12831 else
12832 {
12833 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12834 "\nSymbol table for image contains %lu entries:\n",
12835 filedata->num_dynamic_syms),
12836 filedata->num_dynamic_syms);
12837 }
10ca4b04
L
12838 if (is_32bit_elf)
12839 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12840 else
12841 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12842
978c4450
AM
12843 for (si = 0; si < filedata->num_dynamic_syms; si++)
12844 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
12845 filedata->dynamic_strings,
12846 filedata->dynamic_strings_length);
252b5132 12847 }
8b73c356 12848 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 12849 && filedata->section_headers != NULL)
252b5132 12850 {
b34976b6 12851 unsigned int i;
252b5132 12852
dda8d76d
NC
12853 for (i = 0, section = filedata->section_headers;
12854 i < filedata->file_header.e_shnum;
252b5132
RH
12855 i++, section++)
12856 {
2cf0635d 12857 char * strtab = NULL;
c256ffe7 12858 unsigned long int strtab_size = 0;
2cf0635d 12859 Elf_Internal_Sym * symtab;
ef3df110 12860 unsigned long si, num_syms;
252b5132 12861
2c610e4b
L
12862 if ((section->sh_type != SHT_SYMTAB
12863 && section->sh_type != SHT_DYNSYM)
12864 || (!do_syms
12865 && section->sh_type == SHT_SYMTAB))
252b5132
RH
12866 continue;
12867
dd24e3da
NC
12868 if (section->sh_entsize == 0)
12869 {
12870 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 12871 printable_section_name (filedata, section));
dd24e3da
NC
12872 continue;
12873 }
12874
d3a49aa8 12875 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
12876
12877 if (filedata->is_separate)
12878 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
12879 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
12880 num_syms),
12881 filedata->file_name,
12882 printable_section_name (filedata, section),
12883 num_syms);
12884 else
12885 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
12886 "\nSymbol table '%s' contains %lu entries:\n",
12887 num_syms),
12888 printable_section_name (filedata, section),
12889 num_syms);
dd24e3da 12890
f7a99963 12891 if (is_32bit_elf)
ca47b30c 12892 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 12893 else
ca47b30c 12894 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 12895
dda8d76d 12896 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
12897 if (symtab == NULL)
12898 continue;
12899
dda8d76d 12900 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 12901 {
dda8d76d
NC
12902 strtab = filedata->string_table;
12903 strtab_size = filedata->string_table_length;
c256ffe7 12904 }
dda8d76d 12905 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 12906 {
2cf0635d 12907 Elf_Internal_Shdr * string_sec;
252b5132 12908
dda8d76d 12909 string_sec = filedata->section_headers + section->sh_link;
252b5132 12910
dda8d76d 12911 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
12912 1, string_sec->sh_size,
12913 _("string table"));
c256ffe7 12914 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
12915 }
12916
10ca4b04
L
12917 for (si = 0; si < num_syms; si++)
12918 print_dynamic_symbol (filedata, si, symtab, section,
12919 strtab, strtab_size);
252b5132
RH
12920
12921 free (symtab);
dda8d76d 12922 if (strtab != filedata->string_table)
252b5132
RH
12923 free (strtab);
12924 }
12925 }
12926 else if (do_syms)
12927 printf
12928 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
12929
978c4450 12930 if (do_histogram && filedata->buckets != NULL)
252b5132 12931 {
2cf0635d
NC
12932 unsigned long * lengths;
12933 unsigned long * counts;
66543521
AM
12934 unsigned long hn;
12935 bfd_vma si;
12936 unsigned long maxlength = 0;
12937 unsigned long nzero_counts = 0;
12938 unsigned long nsyms = 0;
6bd6a03d 12939 char *visited;
252b5132 12940
d3a49aa8
AM
12941 printf (ngettext ("\nHistogram for bucket list length "
12942 "(total of %lu bucket):\n",
12943 "\nHistogram for bucket list length "
12944 "(total of %lu buckets):\n",
978c4450
AM
12945 (unsigned long) filedata->nbuckets),
12946 (unsigned long) filedata->nbuckets);
252b5132 12947
978c4450
AM
12948 lengths = (unsigned long *) calloc (filedata->nbuckets,
12949 sizeof (*lengths));
252b5132
RH
12950 if (lengths == NULL)
12951 {
8b73c356 12952 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 12953 goto err_out;
252b5132 12954 }
978c4450
AM
12955 visited = xcmalloc (filedata->nchains, 1);
12956 memset (visited, 0, filedata->nchains);
8b73c356
NC
12957
12958 printf (_(" Length Number %% of total Coverage\n"));
978c4450 12959 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 12960 {
978c4450 12961 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 12962 {
b34976b6 12963 ++nsyms;
252b5132 12964 if (maxlength < ++lengths[hn])
b34976b6 12965 ++maxlength;
978c4450 12966 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
12967 {
12968 error (_("histogram chain is corrupt\n"));
12969 break;
12970 }
12971 visited[si] = 1;
252b5132
RH
12972 }
12973 }
6bd6a03d 12974 free (visited);
252b5132 12975
3f5e193b 12976 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
12977 if (counts == NULL)
12978 {
b2e951ec 12979 free (lengths);
8b73c356 12980 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 12981 goto err_out;
252b5132
RH
12982 }
12983
978c4450 12984 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 12985 ++counts[lengths[hn]];
252b5132 12986
978c4450 12987 if (filedata->nbuckets > 0)
252b5132 12988 {
66543521
AM
12989 unsigned long i;
12990 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12991 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 12992 for (i = 1; i <= maxlength; ++i)
103f02d3 12993 {
66543521
AM
12994 nzero_counts += counts[i] * i;
12995 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12996 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
12997 (nzero_counts * 100.0) / nsyms);
12998 }
252b5132
RH
12999 }
13000
13001 free (counts);
13002 free (lengths);
13003 }
13004
978c4450
AM
13005 free (filedata->buckets);
13006 filedata->buckets = NULL;
13007 filedata->nbuckets = 0;
13008 free (filedata->chains);
13009 filedata->chains = NULL;
252b5132 13010
978c4450 13011 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13012 {
2cf0635d
NC
13013 unsigned long * lengths;
13014 unsigned long * counts;
fdc90cb4
JJ
13015 unsigned long hn;
13016 unsigned long maxlength = 0;
13017 unsigned long nzero_counts = 0;
13018 unsigned long nsyms = 0;
fdc90cb4 13019
f16a9783 13020 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13021 "(total of %lu bucket):\n",
f16a9783 13022 "\nHistogram for `%s' bucket list length "
d3a49aa8 13023 "(total of %lu buckets):\n",
978c4450
AM
13024 (unsigned long) filedata->ngnubuckets),
13025 GNU_HASH_SECTION_NAME (filedata),
13026 (unsigned long) filedata->ngnubuckets);
8b73c356 13027
978c4450
AM
13028 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13029 sizeof (*lengths));
fdc90cb4
JJ
13030 if (lengths == NULL)
13031 {
8b73c356 13032 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13033 goto err_out;
fdc90cb4
JJ
13034 }
13035
fdc90cb4
JJ
13036 printf (_(" Length Number %% of total Coverage\n"));
13037
978c4450
AM
13038 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13039 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
13040 {
13041 bfd_vma off, length = 1;
13042
978c4450 13043 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13044 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13045 off < filedata->ngnuchains
13046 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13047 ++off)
fdc90cb4
JJ
13048 ++length;
13049 lengths[hn] = length;
13050 if (length > maxlength)
13051 maxlength = length;
13052 nsyms += length;
13053 }
13054
3f5e193b 13055 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13056 if (counts == NULL)
13057 {
b2e951ec 13058 free (lengths);
8b73c356 13059 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13060 goto err_out;
fdc90cb4
JJ
13061 }
13062
978c4450 13063 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13064 ++counts[lengths[hn]];
13065
978c4450 13066 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13067 {
13068 unsigned long j;
13069 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13070 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13071 for (j = 1; j <= maxlength; ++j)
13072 {
13073 nzero_counts += counts[j] * j;
13074 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13075 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13076 (nzero_counts * 100.0) / nsyms);
13077 }
13078 }
13079
13080 free (counts);
13081 free (lengths);
fdc90cb4 13082 }
978c4450
AM
13083 free (filedata->gnubuckets);
13084 filedata->gnubuckets = NULL;
13085 filedata->ngnubuckets = 0;
13086 free (filedata->gnuchains);
13087 filedata->gnuchains = NULL;
13088 filedata->ngnuchains = 0;
13089 free (filedata->mipsxlat);
13090 filedata->mipsxlat = NULL;
015dc7e1 13091 return true;
fd486f32
AM
13092
13093 err_out:
978c4450
AM
13094 free (filedata->gnubuckets);
13095 filedata->gnubuckets = NULL;
13096 filedata->ngnubuckets = 0;
13097 free (filedata->gnuchains);
13098 filedata->gnuchains = NULL;
13099 filedata->ngnuchains = 0;
13100 free (filedata->mipsxlat);
13101 filedata->mipsxlat = NULL;
13102 free (filedata->buckets);
13103 filedata->buckets = NULL;
13104 filedata->nbuckets = 0;
13105 free (filedata->chains);
13106 filedata->chains = NULL;
015dc7e1 13107 return false;
252b5132
RH
13108}
13109
015dc7e1 13110static bool
ca0e11aa 13111process_syminfo (Filedata * filedata)
252b5132 13112{
b4c96d0d 13113 unsigned int i;
252b5132 13114
978c4450 13115 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13116 || !do_dynamic)
13117 /* No syminfo, this is ok. */
015dc7e1 13118 return true;
252b5132
RH
13119
13120 /* There better should be a dynamic symbol section. */
978c4450 13121 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13122 return false;
252b5132 13123
ca0e11aa
NC
13124 if (filedata->is_separate)
13125 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13126 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13127 filedata->dynamic_syminfo_nent),
13128 filedata->file_name,
13129 filedata->dynamic_syminfo_offset,
13130 filedata->dynamic_syminfo_nent);
13131 else
d3a49aa8
AM
13132 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13133 "contains %d entry:\n",
13134 "\nDynamic info segment at offset 0x%lx "
13135 "contains %d entries:\n",
978c4450 13136 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13137 filedata->dynamic_syminfo_offset,
13138 filedata->dynamic_syminfo_nent);
252b5132
RH
13139
13140 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13141 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13142 {
978c4450 13143 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13144
31104126 13145 printf ("%4d: ", i);
978c4450 13146 if (i >= filedata->num_dynamic_syms)
4082ef84 13147 printf (_("<corrupt index>"));
978c4450
AM
13148 else if (VALID_DYNAMIC_NAME (filedata, filedata->dynamic_symbols[i].st_name))
13149 print_symbol (30, GET_DYNAMIC_NAME (filedata,
13150 filedata->dynamic_symbols[i].st_name));
d79b3d50 13151 else
978c4450 13152 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13153 putchar (' ');
252b5132 13154
978c4450 13155 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13156 {
13157 case SYMINFO_BT_SELF:
13158 fputs ("SELF ", stdout);
13159 break;
13160 case SYMINFO_BT_PARENT:
13161 fputs ("PARENT ", stdout);
13162 break;
13163 default:
978c4450
AM
13164 if (filedata->dynamic_syminfo[i].si_boundto > 0
13165 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
13166 && VALID_DYNAMIC_NAME (filedata,
13167 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13168 {
978c4450
AM
13169 print_symbol (10, GET_DYNAMIC_NAME (filedata,
13170 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13171 putchar (' ' );
13172 }
252b5132 13173 else
978c4450 13174 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13175 break;
13176 }
13177
13178 if (flags & SYMINFO_FLG_DIRECT)
13179 printf (" DIRECT");
13180 if (flags & SYMINFO_FLG_PASSTHRU)
13181 printf (" PASSTHRU");
13182 if (flags & SYMINFO_FLG_COPY)
13183 printf (" COPY");
13184 if (flags & SYMINFO_FLG_LAZYLOAD)
13185 printf (" LAZYLOAD");
13186
13187 puts ("");
13188 }
13189
015dc7e1 13190 return true;
252b5132
RH
13191}
13192
75802ccb
CE
13193/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13194 is contained by the region START .. END. The types of ADDR, START
13195 and END should all be the same. Note both ADDR + NELEM and END
13196 point to just beyond the end of the regions that are being tested. */
13197#define IN_RANGE(START,END,ADDR,NELEM) \
13198 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13199
cf13d699
NC
13200/* Check to see if the given reloc needs to be handled in a target specific
13201 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13202 FALSE.
13203
13204 If called with reloc == NULL, then this is a signal that reloc processing
13205 for the current section has finished, and any saved state should be
13206 discarded. */
09c11c86 13207
015dc7e1 13208static bool
dda8d76d
NC
13209target_specific_reloc_handling (Filedata * filedata,
13210 Elf_Internal_Rela * reloc,
13211 unsigned char * start,
13212 unsigned char * end,
13213 Elf_Internal_Sym * symtab,
13214 unsigned long num_syms)
252b5132 13215{
f84ce13b
NC
13216 unsigned int reloc_type = 0;
13217 unsigned long sym_index = 0;
13218
13219 if (reloc)
13220 {
dda8d76d 13221 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13222 sym_index = get_reloc_symindex (reloc->r_info);
13223 }
252b5132 13224
dda8d76d 13225 switch (filedata->file_header.e_machine)
252b5132 13226 {
13761a11
NC
13227 case EM_MSP430:
13228 case EM_MSP430_OLD:
13229 {
13230 static Elf_Internal_Sym * saved_sym = NULL;
13231
f84ce13b
NC
13232 if (reloc == NULL)
13233 {
13234 saved_sym = NULL;
015dc7e1 13235 return true;
f84ce13b
NC
13236 }
13237
13761a11
NC
13238 switch (reloc_type)
13239 {
13240 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13241 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13242 if (uses_msp430x_relocs (filedata))
13761a11 13243 break;
1a0670f3 13244 /* Fall through. */
13761a11 13245 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13246 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13247 /* PR 21139. */
13248 if (sym_index >= num_syms)
13249 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13250 sym_index);
13251 else
13252 saved_sym = symtab + sym_index;
015dc7e1 13253 return true;
13761a11
NC
13254
13255 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13256 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13257 goto handle_sym_diff;
0b4362b0 13258
13761a11
NC
13259 case 5: /* R_MSP430_16_BYTE */
13260 case 9: /* R_MSP430_8 */
7d81bc93 13261 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13262 if (uses_msp430x_relocs (filedata))
13761a11
NC
13263 break;
13264 goto handle_sym_diff;
13265
13266 case 2: /* R_MSP430_ABS16 */
13267 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13268 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13269 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13270 break;
13271 goto handle_sym_diff;
0b4362b0 13272
13761a11
NC
13273 handle_sym_diff:
13274 if (saved_sym != NULL)
13275 {
13276 bfd_vma value;
5a805384 13277 unsigned int reloc_size = 0;
7d81bc93
JL
13278 int leb_ret = 0;
13279 switch (reloc_type)
13280 {
13281 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13282 reloc_size = 4;
13283 break;
13284 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13285 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13286 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13287 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13288 &reloc_size, &leb_ret);
7d81bc93
JL
13289 break;
13290 default:
13291 reloc_size = 2;
13292 break;
13293 }
13761a11 13294
5a805384 13295 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13296 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13297 "ULEB128 value\n"),
13298 (long) reloc->r_offset);
13299 else if (sym_index >= num_syms)
f84ce13b
NC
13300 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13301 sym_index);
03f7786e 13302 else
f84ce13b
NC
13303 {
13304 value = reloc->r_addend + (symtab[sym_index].st_value
13305 - saved_sym->st_value);
13306
b32e566b 13307 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13308 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13309 else
13310 /* PR 21137 */
13311 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13312 (long) reloc->r_offset);
f84ce13b 13313 }
13761a11
NC
13314
13315 saved_sym = NULL;
015dc7e1 13316 return true;
13761a11
NC
13317 }
13318 break;
13319
13320 default:
13321 if (saved_sym != NULL)
071436c6 13322 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
13323 break;
13324 }
13325 break;
13326 }
13327
cf13d699
NC
13328 case EM_MN10300:
13329 case EM_CYGNUS_MN10300:
13330 {
13331 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 13332
f84ce13b
NC
13333 if (reloc == NULL)
13334 {
13335 saved_sym = NULL;
015dc7e1 13336 return true;
f84ce13b
NC
13337 }
13338
cf13d699
NC
13339 switch (reloc_type)
13340 {
13341 case 34: /* R_MN10300_ALIGN */
015dc7e1 13342 return true;
cf13d699 13343 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
13344 if (sym_index >= num_syms)
13345 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
13346 sym_index);
13347 else
13348 saved_sym = symtab + sym_index;
015dc7e1 13349 return true;
f84ce13b 13350
cf13d699
NC
13351 case 1: /* R_MN10300_32 */
13352 case 2: /* R_MN10300_16 */
13353 if (saved_sym != NULL)
13354 {
03f7786e 13355 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 13356 bfd_vma value;
252b5132 13357
f84ce13b
NC
13358 if (sym_index >= num_syms)
13359 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
13360 sym_index);
03f7786e 13361 else
f84ce13b
NC
13362 {
13363 value = reloc->r_addend + (symtab[sym_index].st_value
13364 - saved_sym->st_value);
13365
b32e566b 13366 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13367 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13368 else
13369 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
13370 (long) reloc->r_offset);
f84ce13b 13371 }
252b5132 13372
cf13d699 13373 saved_sym = NULL;
015dc7e1 13374 return true;
cf13d699
NC
13375 }
13376 break;
13377 default:
13378 if (saved_sym != NULL)
071436c6 13379 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
13380 break;
13381 }
13382 break;
13383 }
6ff71e76
NC
13384
13385 case EM_RL78:
13386 {
13387 static bfd_vma saved_sym1 = 0;
13388 static bfd_vma saved_sym2 = 0;
13389 static bfd_vma value;
13390
f84ce13b
NC
13391 if (reloc == NULL)
13392 {
13393 saved_sym1 = saved_sym2 = 0;
015dc7e1 13394 return true;
f84ce13b
NC
13395 }
13396
6ff71e76
NC
13397 switch (reloc_type)
13398 {
13399 case 0x80: /* R_RL78_SYM. */
13400 saved_sym1 = saved_sym2;
f84ce13b
NC
13401 if (sym_index >= num_syms)
13402 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
13403 sym_index);
13404 else
13405 {
13406 saved_sym2 = symtab[sym_index].st_value;
13407 saved_sym2 += reloc->r_addend;
13408 }
015dc7e1 13409 return true;
6ff71e76
NC
13410
13411 case 0x83: /* R_RL78_OPsub. */
13412 value = saved_sym1 - saved_sym2;
13413 saved_sym2 = saved_sym1 = 0;
015dc7e1 13414 return true;
6ff71e76
NC
13415 break;
13416
13417 case 0x41: /* R_RL78_ABS32. */
b32e566b 13418 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 13419 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
13420 else
13421 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13422 (long) reloc->r_offset);
6ff71e76 13423 value = 0;
015dc7e1 13424 return true;
6ff71e76
NC
13425
13426 case 0x43: /* R_RL78_ABS16. */
b32e566b 13427 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 13428 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
13429 else
13430 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13431 (long) reloc->r_offset);
6ff71e76 13432 value = 0;
015dc7e1 13433 return true;
6ff71e76
NC
13434
13435 default:
13436 break;
13437 }
13438 break;
13439 }
252b5132
RH
13440 }
13441
015dc7e1 13442 return false;
252b5132
RH
13443}
13444
aca88567
NC
13445/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
13446 DWARF debug sections. This is a target specific test. Note - we do not
13447 go through the whole including-target-headers-multiple-times route, (as
13448 we have already done with <elf/h8.h>) because this would become very
13449 messy and even then this function would have to contain target specific
13450 information (the names of the relocs instead of their numeric values).
13451 FIXME: This is not the correct way to solve this problem. The proper way
13452 is to have target specific reloc sizing and typing functions created by
13453 the reloc-macros.h header, in the same way that it already creates the
13454 reloc naming functions. */
13455
015dc7e1 13456static bool
dda8d76d 13457is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13458{
d347c9df 13459 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13460 switch (filedata->file_header.e_machine)
aca88567 13461 {
41e92641 13462 case EM_386:
22abe556 13463 case EM_IAMCU:
41e92641 13464 return reloc_type == 1; /* R_386_32. */
aca88567
NC
13465 case EM_68K:
13466 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
13467 case EM_860:
13468 return reloc_type == 1; /* R_860_32. */
13469 case EM_960:
13470 return reloc_type == 2; /* R_960_32. */
a06ea964 13471 case EM_AARCH64:
9282b95a
JW
13472 return (reloc_type == 258
13473 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
13474 case EM_BPF:
13475 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
13476 case EM_ADAPTEVA_EPIPHANY:
13477 return reloc_type == 3;
aca88567 13478 case EM_ALPHA:
137b6b5f 13479 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
13480 case EM_ARC:
13481 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
13482 case EM_ARC_COMPACT:
13483 case EM_ARC_COMPACT2:
13484 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
13485 case EM_ARM:
13486 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 13487 case EM_AVR_OLD:
aca88567
NC
13488 case EM_AVR:
13489 return reloc_type == 1;
13490 case EM_BLACKFIN:
13491 return reloc_type == 0x12; /* R_byte4_data. */
13492 case EM_CRIS:
13493 return reloc_type == 3; /* R_CRIS_32. */
13494 case EM_CR16:
13495 return reloc_type == 3; /* R_CR16_NUM32. */
13496 case EM_CRX:
13497 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
13498 case EM_CSKY:
13499 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
13500 case EM_CYGNUS_FRV:
13501 return reloc_type == 1;
41e92641
NC
13502 case EM_CYGNUS_D10V:
13503 case EM_D10V:
13504 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
13505 case EM_CYGNUS_D30V:
13506 case EM_D30V:
13507 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
13508 case EM_DLX:
13509 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
13510 case EM_CYGNUS_FR30:
13511 case EM_FR30:
13512 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
13513 case EM_FT32:
13514 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
13515 case EM_H8S:
13516 case EM_H8_300:
13517 case EM_H8_300H:
13518 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 13519 case EM_IA_64:
262cdac7
AM
13520 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
13521 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
13522 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
13523 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
13524 case EM_IP2K_OLD:
13525 case EM_IP2K:
13526 return reloc_type == 2; /* R_IP2K_32. */
13527 case EM_IQ2000:
13528 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
13529 case EM_LATTICEMICO32:
13530 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 13531 case EM_M32C_OLD:
aca88567
NC
13532 case EM_M32C:
13533 return reloc_type == 3; /* R_M32C_32. */
13534 case EM_M32R:
13535 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
13536 case EM_68HC11:
13537 case EM_68HC12:
13538 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 13539 case EM_S12Z:
2849d19f
JD
13540 return reloc_type == 7 || /* R_S12Z_EXT32 */
13541 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
13542 case EM_MCORE:
13543 return reloc_type == 1; /* R_MCORE_ADDR32. */
13544 case EM_CYGNUS_MEP:
13545 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
13546 case EM_METAG:
13547 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
13548 case EM_MICROBLAZE:
13549 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
13550 case EM_MIPS:
13551 return reloc_type == 2; /* R_MIPS_32. */
13552 case EM_MMIX:
13553 return reloc_type == 4; /* R_MMIX_32. */
13554 case EM_CYGNUS_MN10200:
13555 case EM_MN10200:
13556 return reloc_type == 1; /* R_MN10200_32. */
13557 case EM_CYGNUS_MN10300:
13558 case EM_MN10300:
13559 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
13560 case EM_MOXIE:
13561 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
13562 case EM_MSP430_OLD:
13563 case EM_MSP430:
13761a11 13564 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
13565 case EM_MT:
13566 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
13567 case EM_NDS32:
13568 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 13569 case EM_ALTERA_NIOS2:
36591ba1 13570 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
13571 case EM_NIOS32:
13572 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
13573 case EM_OR1K:
13574 return reloc_type == 1; /* R_OR1K_32. */
aca88567 13575 case EM_PARISC:
9abca702 13576 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 13577 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 13578 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
13579 case EM_PJ:
13580 case EM_PJ_OLD:
13581 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
13582 case EM_PPC64:
13583 return reloc_type == 1; /* R_PPC64_ADDR32. */
13584 case EM_PPC:
13585 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
13586 case EM_TI_PRU:
13587 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
13588 case EM_RISCV:
13589 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
13590 case EM_RL78:
13591 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
13592 case EM_RX:
13593 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
13594 case EM_S370:
13595 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
13596 case EM_S390_OLD:
13597 case EM_S390:
13598 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
13599 case EM_SCORE:
13600 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
13601 case EM_SH:
13602 return reloc_type == 1; /* R_SH_DIR32. */
13603 case EM_SPARC32PLUS:
13604 case EM_SPARCV9:
13605 case EM_SPARC:
13606 return reloc_type == 3 /* R_SPARC_32. */
13607 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
13608 case EM_SPU:
13609 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
13610 case EM_TI_C6000:
13611 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
13612 case EM_TILEGX:
13613 return reloc_type == 2; /* R_TILEGX_32. */
13614 case EM_TILEPRO:
13615 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
13616 case EM_CYGNUS_V850:
13617 case EM_V850:
13618 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
13619 case EM_V800:
13620 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
13621 case EM_VAX:
13622 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
13623 case EM_VISIUM:
13624 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
13625 case EM_WEBASSEMBLY:
13626 return reloc_type == 1; /* R_WASM32_32. */
aca88567 13627 case EM_X86_64:
8a9036a4 13628 case EM_L1OM:
7a9068fe 13629 case EM_K1OM:
aca88567 13630 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
13631 case EM_XC16X:
13632 case EM_C166:
13633 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
13634 case EM_XGATE:
13635 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
13636 case EM_XSTORMY16:
13637 return reloc_type == 1; /* R_XSTROMY16_32. */
13638 case EM_XTENSA_OLD:
13639 case EM_XTENSA:
13640 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
13641 case EM_Z80:
13642 return reloc_type == 6; /* R_Z80_32. */
aca88567 13643 default:
bee0ee85
NC
13644 {
13645 static unsigned int prev_warn = 0;
13646
13647 /* Avoid repeating the same warning multiple times. */
dda8d76d 13648 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 13649 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
13650 filedata->file_header.e_machine);
13651 prev_warn = filedata->file_header.e_machine;
015dc7e1 13652 return false;
bee0ee85 13653 }
aca88567
NC
13654 }
13655}
13656
13657/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13658 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
13659
015dc7e1 13660static bool
dda8d76d 13661is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13662{
dda8d76d 13663 switch (filedata->file_header.e_machine)
d347c9df 13664 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 13665 {
41e92641 13666 case EM_386:
22abe556 13667 case EM_IAMCU:
3e0873ac 13668 return reloc_type == 2; /* R_386_PC32. */
aca88567 13669 case EM_68K:
3e0873ac 13670 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
13671 case EM_AARCH64:
13672 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
13673 case EM_ADAPTEVA_EPIPHANY:
13674 return reloc_type == 6;
aca88567
NC
13675 case EM_ALPHA:
13676 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
13677 case EM_ARC_COMPACT:
13678 case EM_ARC_COMPACT2:
13679 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 13680 case EM_ARM:
3e0873ac 13681 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
13682 case EM_AVR_OLD:
13683 case EM_AVR:
13684 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
13685 case EM_MICROBLAZE:
13686 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
13687 case EM_OR1K:
13688 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 13689 case EM_PARISC:
85acf597 13690 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
13691 case EM_PPC:
13692 return reloc_type == 26; /* R_PPC_REL32. */
13693 case EM_PPC64:
3e0873ac 13694 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
13695 case EM_RISCV:
13696 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
13697 case EM_S390_OLD:
13698 case EM_S390:
3e0873ac 13699 return reloc_type == 5; /* R_390_PC32. */
aca88567 13700 case EM_SH:
3e0873ac 13701 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
13702 case EM_SPARC32PLUS:
13703 case EM_SPARCV9:
13704 case EM_SPARC:
3e0873ac 13705 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
13706 case EM_SPU:
13707 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
13708 case EM_TILEGX:
13709 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
13710 case EM_TILEPRO:
13711 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
13712 case EM_VISIUM:
13713 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 13714 case EM_X86_64:
8a9036a4 13715 case EM_L1OM:
7a9068fe 13716 case EM_K1OM:
3e0873ac 13717 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
13718 case EM_VAX:
13719 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
13720 case EM_XTENSA_OLD:
13721 case EM_XTENSA:
13722 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
13723 default:
13724 /* Do not abort or issue an error message here. Not all targets use
13725 pc-relative 32-bit relocs in their DWARF debug information and we
13726 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
13727 more helpful warning message will be generated by apply_relocations
13728 anyway, so just return. */
015dc7e1 13729 return false;
aca88567
NC
13730 }
13731}
13732
13733/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13734 a 64-bit absolute RELA relocation used in DWARF debug sections. */
13735
015dc7e1 13736static bool
dda8d76d 13737is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13738{
dda8d76d 13739 switch (filedata->file_header.e_machine)
aca88567 13740 {
a06ea964
NC
13741 case EM_AARCH64:
13742 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
13743 case EM_ALPHA:
13744 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 13745 case EM_IA_64:
262cdac7
AM
13746 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
13747 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
13748 case EM_PARISC:
13749 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
13750 case EM_PPC64:
13751 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
13752 case EM_RISCV:
13753 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
13754 case EM_SPARC32PLUS:
13755 case EM_SPARCV9:
13756 case EM_SPARC:
714da62f
NC
13757 return reloc_type == 32 /* R_SPARC_64. */
13758 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 13759 case EM_X86_64:
8a9036a4 13760 case EM_L1OM:
7a9068fe 13761 case EM_K1OM:
aca88567 13762 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
13763 case EM_S390_OLD:
13764 case EM_S390:
aa137e4d
NC
13765 return reloc_type == 22; /* R_S390_64. */
13766 case EM_TILEGX:
13767 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 13768 case EM_MIPS:
aa137e4d 13769 return reloc_type == 18; /* R_MIPS_64. */
aca88567 13770 default:
015dc7e1 13771 return false;
aca88567
NC
13772 }
13773}
13774
85acf597
RH
13775/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
13776 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
13777
015dc7e1 13778static bool
dda8d76d 13779is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 13780{
dda8d76d 13781 switch (filedata->file_header.e_machine)
85acf597 13782 {
a06ea964
NC
13783 case EM_AARCH64:
13784 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 13785 case EM_ALPHA:
aa137e4d 13786 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 13787 case EM_IA_64:
262cdac7
AM
13788 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
13789 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 13790 case EM_PARISC:
aa137e4d 13791 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 13792 case EM_PPC64:
aa137e4d 13793 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
13794 case EM_SPARC32PLUS:
13795 case EM_SPARCV9:
13796 case EM_SPARC:
aa137e4d 13797 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 13798 case EM_X86_64:
8a9036a4 13799 case EM_L1OM:
7a9068fe 13800 case EM_K1OM:
aa137e4d 13801 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
13802 case EM_S390_OLD:
13803 case EM_S390:
aa137e4d
NC
13804 return reloc_type == 23; /* R_S390_PC64. */
13805 case EM_TILEGX:
13806 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 13807 default:
015dc7e1 13808 return false;
85acf597
RH
13809 }
13810}
13811
4dc3c23d
AM
13812/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13813 a 24-bit absolute RELA relocation used in DWARF debug sections. */
13814
015dc7e1 13815static bool
dda8d76d 13816is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 13817{
dda8d76d 13818 switch (filedata->file_header.e_machine)
4dc3c23d
AM
13819 {
13820 case EM_CYGNUS_MN10200:
13821 case EM_MN10200:
13822 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
13823 case EM_FT32:
13824 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
13825 case EM_Z80:
13826 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 13827 default:
015dc7e1 13828 return false;
4dc3c23d
AM
13829 }
13830}
13831
aca88567
NC
13832/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13833 a 16-bit absolute RELA relocation used in DWARF debug sections. */
13834
015dc7e1 13835static bool
dda8d76d 13836is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 13837{
d347c9df 13838 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13839 switch (filedata->file_header.e_machine)
4b78141a 13840 {
886a2506
NC
13841 case EM_ARC:
13842 case EM_ARC_COMPACT:
13843 case EM_ARC_COMPACT2:
13844 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
13845 case EM_ADAPTEVA_EPIPHANY:
13846 return reloc_type == 5;
aca88567
NC
13847 case EM_AVR_OLD:
13848 case EM_AVR:
13849 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
13850 case EM_CYGNUS_D10V:
13851 case EM_D10V:
13852 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
13853 case EM_FT32:
13854 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
13855 case EM_H8S:
13856 case EM_H8_300:
13857 case EM_H8_300H:
aca88567
NC
13858 return reloc_type == R_H8_DIR16;
13859 case EM_IP2K_OLD:
13860 case EM_IP2K:
13861 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 13862 case EM_M32C_OLD:
f4236fe4
DD
13863 case EM_M32C:
13864 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
13865 case EM_CYGNUS_MN10200:
13866 case EM_MN10200:
13867 return reloc_type == 2; /* R_MN10200_16. */
13868 case EM_CYGNUS_MN10300:
13869 case EM_MN10300:
13870 return reloc_type == 2; /* R_MN10300_16. */
aca88567 13871 case EM_MSP430:
dda8d76d 13872 if (uses_msp430x_relocs (filedata))
13761a11 13873 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 13874 /* Fall through. */
78c8d46c 13875 case EM_MSP430_OLD:
aca88567 13876 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
13877 case EM_NDS32:
13878 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 13879 case EM_ALTERA_NIOS2:
36591ba1 13880 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
13881 case EM_NIOS32:
13882 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
13883 case EM_OR1K:
13884 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
13885 case EM_RISCV:
13886 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
13887 case EM_TI_PRU:
13888 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
13889 case EM_TI_C6000:
13890 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
13891 case EM_VISIUM:
13892 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
13893 case EM_XC16X:
13894 case EM_C166:
13895 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
13896 case EM_XGATE:
13897 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
13898 case EM_Z80:
13899 return reloc_type == 4; /* R_Z80_16. */
4b78141a 13900 default:
015dc7e1 13901 return false;
4b78141a
NC
13902 }
13903}
13904
39e07931
AS
13905/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13906 a 8-bit absolute RELA relocation used in DWARF debug sections. */
13907
015dc7e1 13908static bool
39e07931
AS
13909is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13910{
13911 switch (filedata->file_header.e_machine)
13912 {
13913 case EM_RISCV:
13914 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
13915 case EM_Z80:
13916 return reloc_type == 1; /* R_Z80_8. */
39e07931 13917 default:
015dc7e1 13918 return false;
39e07931
AS
13919 }
13920}
13921
13922/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13923 a 6-bit absolute RELA relocation used in DWARF debug sections. */
13924
015dc7e1 13925static bool
39e07931
AS
13926is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13927{
13928 switch (filedata->file_header.e_machine)
13929 {
13930 case EM_RISCV:
13931 return reloc_type == 53; /* R_RISCV_SET6. */
13932 default:
015dc7e1 13933 return false;
39e07931
AS
13934 }
13935}
13936
03336641
JW
13937/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13938 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
13939
015dc7e1 13940static bool
03336641
JW
13941is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13942{
13943 /* Please keep this table alpha-sorted for ease of visual lookup. */
13944 switch (filedata->file_header.e_machine)
13945 {
13946 case EM_RISCV:
13947 return reloc_type == 35; /* R_RISCV_ADD32. */
13948 default:
015dc7e1 13949 return false;
03336641
JW
13950 }
13951}
13952
13953/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13954 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
13955
015dc7e1 13956static bool
03336641
JW
13957is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13958{
13959 /* Please keep this table alpha-sorted for ease of visual lookup. */
13960 switch (filedata->file_header.e_machine)
13961 {
13962 case EM_RISCV:
13963 return reloc_type == 39; /* R_RISCV_SUB32. */
13964 default:
015dc7e1 13965 return false;
03336641
JW
13966 }
13967}
13968
13969/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13970 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
13971
015dc7e1 13972static bool
03336641
JW
13973is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13974{
13975 /* Please keep this table alpha-sorted for ease of visual lookup. */
13976 switch (filedata->file_header.e_machine)
13977 {
13978 case EM_RISCV:
13979 return reloc_type == 36; /* R_RISCV_ADD64. */
13980 default:
015dc7e1 13981 return false;
03336641
JW
13982 }
13983}
13984
13985/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13986 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
13987
015dc7e1 13988static bool
03336641
JW
13989is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13990{
13991 /* Please keep this table alpha-sorted for ease of visual lookup. */
13992 switch (filedata->file_header.e_machine)
13993 {
13994 case EM_RISCV:
13995 return reloc_type == 40; /* R_RISCV_SUB64. */
13996 default:
015dc7e1 13997 return false;
03336641
JW
13998 }
13999}
14000
14001/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14002 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14003
015dc7e1 14004static bool
03336641
JW
14005is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14006{
14007 /* Please keep this table alpha-sorted for ease of visual lookup. */
14008 switch (filedata->file_header.e_machine)
14009 {
14010 case EM_RISCV:
14011 return reloc_type == 34; /* R_RISCV_ADD16. */
14012 default:
015dc7e1 14013 return false;
03336641
JW
14014 }
14015}
14016
14017/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14018 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14019
015dc7e1 14020static bool
03336641
JW
14021is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14022{
14023 /* Please keep this table alpha-sorted for ease of visual lookup. */
14024 switch (filedata->file_header.e_machine)
14025 {
14026 case EM_RISCV:
14027 return reloc_type == 38; /* R_RISCV_SUB16. */
14028 default:
015dc7e1 14029 return false;
03336641
JW
14030 }
14031}
14032
14033/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14034 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14035
015dc7e1 14036static bool
03336641
JW
14037is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14038{
14039 /* Please keep this table alpha-sorted for ease of visual lookup. */
14040 switch (filedata->file_header.e_machine)
14041 {
14042 case EM_RISCV:
14043 return reloc_type == 33; /* R_RISCV_ADD8. */
14044 default:
015dc7e1 14045 return false;
03336641
JW
14046 }
14047}
14048
14049/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14050 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14051
015dc7e1 14052static bool
03336641
JW
14053is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14054{
14055 /* Please keep this table alpha-sorted for ease of visual lookup. */
14056 switch (filedata->file_header.e_machine)
14057 {
14058 case EM_RISCV:
14059 return reloc_type == 37; /* R_RISCV_SUB8. */
14060 default:
015dc7e1 14061 return false;
03336641
JW
14062 }
14063}
14064
39e07931
AS
14065/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14066 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14067
015dc7e1 14068static bool
39e07931
AS
14069is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14070{
14071 switch (filedata->file_header.e_machine)
14072 {
14073 case EM_RISCV:
14074 return reloc_type == 52; /* R_RISCV_SUB6. */
14075 default:
015dc7e1 14076 return false;
39e07931
AS
14077 }
14078}
14079
2a7b2e88
JK
14080/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14081 relocation entries (possibly formerly used for SHT_GROUP sections). */
14082
015dc7e1 14083static bool
dda8d76d 14084is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14085{
dda8d76d 14086 switch (filedata->file_header.e_machine)
2a7b2e88 14087 {
cb8f3167 14088 case EM_386: /* R_386_NONE. */
d347c9df 14089 case EM_68K: /* R_68K_NONE. */
cfb8c092 14090 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14091 case EM_ALPHA: /* R_ALPHA_NONE. */
14092 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14093 case EM_ARC: /* R_ARC_NONE. */
886a2506 14094 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14095 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14096 case EM_ARM: /* R_ARM_NONE. */
d347c9df 14097 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 14098 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14099 case EM_FT32: /* R_FT32_NONE. */
14100 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14101 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14102 case EM_L1OM: /* R_X86_64_NONE. */
14103 case EM_M32R: /* R_M32R_NONE. */
14104 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14105 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14106 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14107 case EM_NIOS32: /* R_NIOS_NONE. */
14108 case EM_OR1K: /* R_OR1K_NONE. */
14109 case EM_PARISC: /* R_PARISC_NONE. */
14110 case EM_PPC64: /* R_PPC64_NONE. */
14111 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14112 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14113 case EM_S390: /* R_390_NONE. */
14114 case EM_S390_OLD:
14115 case EM_SH: /* R_SH_NONE. */
14116 case EM_SPARC32PLUS:
14117 case EM_SPARC: /* R_SPARC_NONE. */
14118 case EM_SPARCV9:
aa137e4d
NC
14119 case EM_TILEGX: /* R_TILEGX_NONE. */
14120 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14121 case EM_TI_C6000:/* R_C6000_NONE. */
14122 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 14123 case EM_XC16X:
6655dba2 14124 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14125 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14126 return reloc_type == 0;
d347c9df 14127
a06ea964
NC
14128 case EM_AARCH64:
14129 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14130 case EM_AVR_OLD:
14131 case EM_AVR:
14132 return (reloc_type == 0 /* R_AVR_NONE. */
14133 || reloc_type == 30 /* R_AVR_DIFF8. */
14134 || reloc_type == 31 /* R_AVR_DIFF16. */
14135 || reloc_type == 32 /* R_AVR_DIFF32. */);
14136 case EM_METAG:
14137 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
14138 case EM_NDS32:
14139 return (reloc_type == 0 /* R_XTENSA_NONE. */
14140 || reloc_type == 204 /* R_NDS32_DIFF8. */
14141 || reloc_type == 205 /* R_NDS32_DIFF16. */
14142 || reloc_type == 206 /* R_NDS32_DIFF32. */
14143 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
14144 case EM_TI_PRU:
14145 return (reloc_type == 0 /* R_PRU_NONE. */
14146 || reloc_type == 65 /* R_PRU_DIFF8. */
14147 || reloc_type == 66 /* R_PRU_DIFF16. */
14148 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14149 case EM_XTENSA_OLD:
14150 case EM_XTENSA:
4dc3c23d
AM
14151 return (reloc_type == 0 /* R_XTENSA_NONE. */
14152 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14153 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14154 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14155 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14156 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14157 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14158 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14159 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14160 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14161 }
015dc7e1 14162 return false;
2a7b2e88
JK
14163}
14164
d1c4b12b
NC
14165/* Returns TRUE if there is a relocation against
14166 section NAME at OFFSET bytes. */
14167
015dc7e1 14168bool
d1c4b12b
NC
14169reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14170{
14171 Elf_Internal_Rela * relocs;
14172 Elf_Internal_Rela * rp;
14173
14174 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14175 return false;
d1c4b12b
NC
14176
14177 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14178
14179 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14180 if (rp->r_offset == offset)
015dc7e1 14181 return true;
d1c4b12b 14182
015dc7e1 14183 return false;
d1c4b12b
NC
14184}
14185
cf13d699 14186/* Apply relocations to a section.
32ec8896
NC
14187 Returns TRUE upon success, FALSE otherwise.
14188 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14189 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14190 will be set to the number of relocs loaded.
14191
cf13d699 14192 Note: So far support has been added only for those relocations
32ec8896
NC
14193 which can be found in debug sections. FIXME: Add support for
14194 more relocations ? */
1b315056 14195
015dc7e1 14196static bool
dda8d76d 14197apply_relocations (Filedata * filedata,
d1c4b12b
NC
14198 const Elf_Internal_Shdr * section,
14199 unsigned char * start,
14200 bfd_size_type size,
1449284b 14201 void ** relocs_return,
d1c4b12b 14202 unsigned long * num_relocs_return)
1b315056 14203{
cf13d699 14204 Elf_Internal_Shdr * relsec;
0d2a7a93 14205 unsigned char * end = start + size;
cb8f3167 14206
d1c4b12b
NC
14207 if (relocs_return != NULL)
14208 {
14209 * (Elf_Internal_Rela **) relocs_return = NULL;
14210 * num_relocs_return = 0;
14211 }
14212
dda8d76d 14213 if (filedata->file_header.e_type != ET_REL)
32ec8896 14214 /* No relocs to apply. */
015dc7e1 14215 return true;
1b315056 14216
cf13d699 14217 /* Find the reloc section associated with the section. */
dda8d76d
NC
14218 for (relsec = filedata->section_headers;
14219 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14220 ++relsec)
252b5132 14221 {
015dc7e1 14222 bool is_rela;
41e92641 14223 unsigned long num_relocs;
2cf0635d
NC
14224 Elf_Internal_Rela * relocs;
14225 Elf_Internal_Rela * rp;
14226 Elf_Internal_Shdr * symsec;
14227 Elf_Internal_Sym * symtab;
ba5cdace 14228 unsigned long num_syms;
2cf0635d 14229 Elf_Internal_Sym * sym;
252b5132 14230
41e92641 14231 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14232 || relsec->sh_info >= filedata->file_header.e_shnum
14233 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14234 || relsec->sh_size == 0
dda8d76d 14235 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14236 continue;
428409d5 14237
a788aedd
AM
14238 symsec = filedata->section_headers + relsec->sh_link;
14239 if (symsec->sh_type != SHT_SYMTAB
14240 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14241 return false;
a788aedd 14242
41e92641
NC
14243 is_rela = relsec->sh_type == SHT_RELA;
14244
14245 if (is_rela)
14246 {
dda8d76d 14247 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14248 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14249 return false;
41e92641
NC
14250 }
14251 else
14252 {
dda8d76d 14253 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14254 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14255 return false;
41e92641
NC
14256 }
14257
14258 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14259 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14260 is_rela = false;
428409d5 14261
dda8d76d 14262 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 14263
41e92641 14264 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14265 {
015dc7e1
AM
14266 bfd_vma addend;
14267 unsigned int reloc_type;
14268 unsigned int reloc_size;
14269 bool reloc_inplace = false;
14270 bool reloc_subtract = false;
14271 unsigned char *rloc;
14272 unsigned long sym_index;
4b78141a 14273
dda8d76d 14274 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14275
dda8d76d 14276 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14277 continue;
dda8d76d 14278 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14279 continue;
dda8d76d
NC
14280 else if (is_32bit_abs_reloc (filedata, reloc_type)
14281 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14282 reloc_size = 4;
dda8d76d
NC
14283 else if (is_64bit_abs_reloc (filedata, reloc_type)
14284 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14285 reloc_size = 8;
dda8d76d 14286 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14287 reloc_size = 3;
dda8d76d 14288 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14289 reloc_size = 2;
39e07931
AS
14290 else if (is_8bit_abs_reloc (filedata, reloc_type)
14291 || is_6bit_abs_reloc (filedata, reloc_type))
14292 reloc_size = 1;
03336641
JW
14293 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14294 reloc_type))
14295 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14296 {
14297 reloc_size = 4;
015dc7e1 14298 reloc_inplace = true;
03336641
JW
14299 }
14300 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14301 reloc_type))
14302 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14303 {
14304 reloc_size = 8;
015dc7e1 14305 reloc_inplace = true;
03336641
JW
14306 }
14307 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14308 reloc_type))
14309 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14310 {
14311 reloc_size = 2;
015dc7e1 14312 reloc_inplace = true;
03336641
JW
14313 }
14314 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14315 reloc_type))
14316 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14317 {
14318 reloc_size = 1;
015dc7e1 14319 reloc_inplace = true;
03336641 14320 }
39e07931
AS
14321 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
14322 reloc_type)))
14323 {
14324 reloc_size = 1;
015dc7e1 14325 reloc_inplace = true;
39e07931 14326 }
aca88567 14327 else
4b78141a 14328 {
bee0ee85 14329 static unsigned int prev_reloc = 0;
dda8d76d 14330
bee0ee85
NC
14331 if (reloc_type != prev_reloc)
14332 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 14333 reloc_type, printable_section_name (filedata, section));
bee0ee85 14334 prev_reloc = reloc_type;
4b78141a
NC
14335 continue;
14336 }
103f02d3 14337
91d6fa6a 14338 rloc = start + rp->r_offset;
75802ccb 14339 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
14340 {
14341 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
14342 (unsigned long) rp->r_offset,
dda8d76d 14343 printable_section_name (filedata, section));
700dd8b7
L
14344 continue;
14345 }
103f02d3 14346
ba5cdace
NC
14347 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
14348 if (sym_index >= num_syms)
14349 {
14350 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 14351 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
14352 continue;
14353 }
14354 sym = symtab + sym_index;
41e92641
NC
14355
14356 /* If the reloc has a symbol associated with it,
55f25fc3
L
14357 make sure that it is of an appropriate type.
14358
14359 Relocations against symbols without type can happen.
14360 Gcc -feliminate-dwarf2-dups may generate symbols
14361 without type for debug info.
14362
14363 Icc generates relocations against function symbols
14364 instead of local labels.
14365
14366 Relocations against object symbols can happen, eg when
14367 referencing a global array. For an example of this see
14368 the _clz.o binary in libgcc.a. */
aca88567 14369 if (sym != symtab
b8871f35 14370 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 14371 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 14372 {
d3a49aa8 14373 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
14374 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
14375 printable_section_name (filedata, relsec),
d3a49aa8 14376 (long int)(rp - relocs));
aca88567 14377 continue;
5b18a4bc 14378 }
252b5132 14379
4dc3c23d
AM
14380 addend = 0;
14381 if (is_rela)
14382 addend += rp->r_addend;
c47320c3
AM
14383 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
14384 partial_inplace. */
4dc3c23d 14385 if (!is_rela
dda8d76d 14386 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 14387 && reloc_type == 1)
dda8d76d
NC
14388 || ((filedata->file_header.e_machine == EM_PJ
14389 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 14390 && reloc_type == 1)
dda8d76d
NC
14391 || ((filedata->file_header.e_machine == EM_D30V
14392 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
14393 && reloc_type == 12)
14394 || reloc_inplace)
39e07931
AS
14395 {
14396 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
14397 addend += byte_get (rloc, reloc_size) & 0x3f;
14398 else
14399 addend += byte_get (rloc, reloc_size);
14400 }
cb8f3167 14401
dda8d76d
NC
14402 if (is_32bit_pcrel_reloc (filedata, reloc_type)
14403 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
14404 {
14405 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 14406 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 14407 addend -= 8;
91d6fa6a 14408 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
14409 reloc_size);
14410 }
39e07931
AS
14411 else if (is_6bit_abs_reloc (filedata, reloc_type)
14412 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
14413 {
14414 if (reloc_subtract)
14415 addend -= sym->st_value;
14416 else
14417 addend += sym->st_value;
14418 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
14419 byte_put (rloc, addend, reloc_size);
14420 }
03336641
JW
14421 else if (reloc_subtract)
14422 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 14423 else
91d6fa6a 14424 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 14425 }
252b5132 14426
5b18a4bc 14427 free (symtab);
f84ce13b
NC
14428 /* Let the target specific reloc processing code know that
14429 we have finished with these relocs. */
dda8d76d 14430 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
14431
14432 if (relocs_return)
14433 {
14434 * (Elf_Internal_Rela **) relocs_return = relocs;
14435 * num_relocs_return = num_relocs;
14436 }
14437 else
14438 free (relocs);
14439
5b18a4bc
NC
14440 break;
14441 }
32ec8896 14442
015dc7e1 14443 return true;
5b18a4bc 14444}
103f02d3 14445
cf13d699 14446#ifdef SUPPORT_DISASSEMBLY
015dc7e1 14447static bool
dda8d76d 14448disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14449{
dda8d76d 14450 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 14451
74e1a04b 14452 /* FIXME: XXX -- to be done --- XXX */
cf13d699 14453
015dc7e1 14454 return true;
cf13d699
NC
14455}
14456#endif
14457
14458/* Reads in the contents of SECTION from FILE, returning a pointer
14459 to a malloc'ed buffer or NULL if something went wrong. */
14460
14461static char *
dda8d76d 14462get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14463{
dda8d76d 14464 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
14465
14466 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
14467 {
c6b78c96 14468 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 14469 printable_section_name (filedata, section));
cf13d699
NC
14470 return NULL;
14471 }
14472
dda8d76d 14473 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 14474 _("section contents"));
cf13d699
NC
14475}
14476
0e602686
NC
14477/* Uncompresses a section that was compressed using zlib, in place. */
14478
015dc7e1 14479static bool
dda8d76d
NC
14480uncompress_section_contents (unsigned char ** buffer,
14481 dwarf_size_type uncompressed_size,
14482 dwarf_size_type * size)
0e602686
NC
14483{
14484 dwarf_size_type compressed_size = *size;
14485 unsigned char * compressed_buffer = *buffer;
14486 unsigned char * uncompressed_buffer;
14487 z_stream strm;
14488 int rc;
14489
14490 /* It is possible the section consists of several compressed
14491 buffers concatenated together, so we uncompress in a loop. */
14492 /* PR 18313: The state field in the z_stream structure is supposed
14493 to be invisible to the user (ie us), but some compilers will
14494 still complain about it being used without initialisation. So
14495 we first zero the entire z_stream structure and then set the fields
14496 that we need. */
14497 memset (& strm, 0, sizeof strm);
14498 strm.avail_in = compressed_size;
14499 strm.next_in = (Bytef *) compressed_buffer;
14500 strm.avail_out = uncompressed_size;
14501 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
14502
14503 rc = inflateInit (& strm);
14504 while (strm.avail_in > 0)
14505 {
14506 if (rc != Z_OK)
3624a6c1 14507 break;
0e602686
NC
14508 strm.next_out = ((Bytef *) uncompressed_buffer
14509 + (uncompressed_size - strm.avail_out));
14510 rc = inflate (&strm, Z_FINISH);
14511 if (rc != Z_STREAM_END)
3624a6c1 14512 break;
0e602686
NC
14513 rc = inflateReset (& strm);
14514 }
ad92f33d
AM
14515 if (inflateEnd (& strm) != Z_OK
14516 || rc != Z_OK
0e602686
NC
14517 || strm.avail_out != 0)
14518 goto fail;
14519
14520 *buffer = uncompressed_buffer;
14521 *size = uncompressed_size;
015dc7e1 14522 return true;
0e602686
NC
14523
14524 fail:
14525 free (uncompressed_buffer);
14526 /* Indicate decompression failure. */
14527 *buffer = NULL;
015dc7e1 14528 return false;
0e602686 14529}
dd24e3da 14530
015dc7e1 14531static bool
dda8d76d 14532dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14533{
015dc7e1
AM
14534 Elf_Internal_Shdr *relsec;
14535 bfd_size_type num_bytes;
14536 unsigned char *data;
14537 unsigned char *end;
14538 unsigned char *real_start;
14539 unsigned char *start;
14540 bool some_strings_shown;
cf13d699 14541
dda8d76d 14542 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14543 if (start == NULL)
c6b78c96 14544 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 14545 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 14546
0e602686 14547 num_bytes = section->sh_size;
cf13d699 14548
835f2fae
NC
14549 if (filedata->is_separate)
14550 printf (_("\nString dump of section '%s' in linked file %s:\n"),
14551 printable_section_name (filedata, section),
14552 filedata->file_name);
14553 else
14554 printf (_("\nString dump of section '%s':\n"),
14555 printable_section_name (filedata, section));
cf13d699 14556
0e602686
NC
14557 if (decompress_dumps)
14558 {
14559 dwarf_size_type new_size = num_bytes;
14560 dwarf_size_type uncompressed_size = 0;
14561
14562 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14563 {
14564 Elf_Internal_Chdr chdr;
14565 unsigned int compression_header_size
ebdf1ebf
NC
14566 = get_compression_header (& chdr, (unsigned char *) start,
14567 num_bytes);
5844b465
NC
14568 if (compression_header_size == 0)
14569 /* An error message will have already been generated
14570 by get_compression_header. */
14571 goto error_out;
0e602686 14572
813dabb9 14573 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14574 {
813dabb9 14575 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14576 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14577 goto error_out;
813dabb9 14578 }
813dabb9
L
14579 uncompressed_size = chdr.ch_size;
14580 start += compression_header_size;
14581 new_size -= compression_header_size;
0e602686
NC
14582 }
14583 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14584 {
14585 /* Read the zlib header. In this case, it should be "ZLIB"
14586 followed by the uncompressed section size, 8 bytes in
14587 big-endian order. */
14588 uncompressed_size = start[4]; uncompressed_size <<= 8;
14589 uncompressed_size += start[5]; uncompressed_size <<= 8;
14590 uncompressed_size += start[6]; uncompressed_size <<= 8;
14591 uncompressed_size += start[7]; uncompressed_size <<= 8;
14592 uncompressed_size += start[8]; uncompressed_size <<= 8;
14593 uncompressed_size += start[9]; uncompressed_size <<= 8;
14594 uncompressed_size += start[10]; uncompressed_size <<= 8;
14595 uncompressed_size += start[11];
14596 start += 12;
14597 new_size -= 12;
14598 }
14599
1835f746
NC
14600 if (uncompressed_size)
14601 {
14602 if (uncompress_section_contents (& start,
14603 uncompressed_size, & new_size))
14604 num_bytes = new_size;
14605 else
14606 {
14607 error (_("Unable to decompress section %s\n"),
dda8d76d 14608 printable_section_name (filedata, section));
f761cb13 14609 goto error_out;
1835f746
NC
14610 }
14611 }
bc303e5d
NC
14612 else
14613 start = real_start;
0e602686 14614 }
fd8008d8 14615
cf13d699
NC
14616 /* If the section being dumped has relocations against it the user might
14617 be expecting these relocations to have been applied. Check for this
14618 case and issue a warning message in order to avoid confusion.
14619 FIXME: Maybe we ought to have an option that dumps a section with
14620 relocs applied ? */
dda8d76d
NC
14621 for (relsec = filedata->section_headers;
14622 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14623 ++relsec)
14624 {
14625 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14626 || relsec->sh_info >= filedata->file_header.e_shnum
14627 || filedata->section_headers + relsec->sh_info != section
cf13d699 14628 || relsec->sh_size == 0
dda8d76d 14629 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14630 continue;
14631
14632 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14633 break;
14634 }
14635
cf13d699
NC
14636 data = start;
14637 end = start + num_bytes;
015dc7e1 14638 some_strings_shown = false;
cf13d699 14639
ba3265d0
NC
14640#ifdef HAVE_MBSTATE_T
14641 mbstate_t state;
14642 /* Initialise the multibyte conversion state. */
14643 memset (& state, 0, sizeof (state));
14644#endif
14645
015dc7e1 14646 bool continuing = false;
ba3265d0 14647
cf13d699
NC
14648 while (data < end)
14649 {
14650 while (!ISPRINT (* data))
14651 if (++ data >= end)
14652 break;
14653
14654 if (data < end)
14655 {
071436c6
NC
14656 size_t maxlen = end - data;
14657
ba3265d0
NC
14658 if (continuing)
14659 {
14660 printf (" ");
015dc7e1 14661 continuing = false;
ba3265d0
NC
14662 }
14663 else
14664 {
d1ce973e 14665 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
14666 }
14667
4082ef84
NC
14668 if (maxlen > 0)
14669 {
f3da8a96 14670 char c = 0;
ba3265d0
NC
14671
14672 while (maxlen)
14673 {
14674 c = *data++;
14675
14676 if (c == 0)
14677 break;
14678
14679 /* PR 25543: Treat new-lines as string-ending characters. */
14680 if (c == '\n')
14681 {
14682 printf ("\\n\n");
14683 if (*data != 0)
015dc7e1 14684 continuing = true;
ba3265d0
NC
14685 break;
14686 }
14687
14688 /* Do not print control characters directly as they can affect terminal
14689 settings. Such characters usually appear in the names generated
14690 by the assembler for local labels. */
14691 if (ISCNTRL (c))
14692 {
14693 printf ("^%c", c + 0x40);
14694 }
14695 else if (ISPRINT (c))
14696 {
14697 putchar (c);
14698 }
14699 else
14700 {
14701 size_t n;
14702#ifdef HAVE_MBSTATE_T
14703 wchar_t w;
14704#endif
14705 /* Let printf do the hard work of displaying multibyte characters. */
14706 printf ("%.1s", data - 1);
14707#ifdef HAVE_MBSTATE_T
14708 /* Try to find out how many bytes made up the character that was
14709 just printed. Advance the symbol pointer past the bytes that
14710 were displayed. */
14711 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
14712#else
14713 n = 1;
14714#endif
14715 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
14716 data += (n - 1);
14717 }
14718 }
14719
14720 if (c != '\n')
14721 putchar ('\n');
4082ef84
NC
14722 }
14723 else
14724 {
14725 printf (_("<corrupt>\n"));
14726 data = end;
14727 }
015dc7e1 14728 some_strings_shown = true;
cf13d699
NC
14729 }
14730 }
14731
14732 if (! some_strings_shown)
14733 printf (_(" No strings found in this section."));
14734
0e602686 14735 free (real_start);
cf13d699
NC
14736
14737 putchar ('\n');
015dc7e1 14738 return true;
f761cb13
AM
14739
14740error_out:
14741 free (real_start);
015dc7e1 14742 return false;
cf13d699
NC
14743}
14744
015dc7e1
AM
14745static bool
14746dump_section_as_bytes (Elf_Internal_Shdr *section,
14747 Filedata *filedata,
14748 bool relocate)
cf13d699
NC
14749{
14750 Elf_Internal_Shdr * relsec;
0e602686
NC
14751 bfd_size_type bytes;
14752 bfd_size_type section_size;
14753 bfd_vma addr;
14754 unsigned char * data;
14755 unsigned char * real_start;
14756 unsigned char * start;
14757
dda8d76d 14758 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14759 if (start == NULL)
c6b78c96 14760 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 14761 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 14762
0e602686 14763 section_size = section->sh_size;
cf13d699 14764
835f2fae
NC
14765 if (filedata->is_separate)
14766 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
14767 printable_section_name (filedata, section),
14768 filedata->file_name);
14769 else
14770 printf (_("\nHex dump of section '%s':\n"),
14771 printable_section_name (filedata, section));
cf13d699 14772
0e602686
NC
14773 if (decompress_dumps)
14774 {
14775 dwarf_size_type new_size = section_size;
14776 dwarf_size_type uncompressed_size = 0;
14777
14778 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14779 {
14780 Elf_Internal_Chdr chdr;
14781 unsigned int compression_header_size
ebdf1ebf 14782 = get_compression_header (& chdr, start, section_size);
0e602686 14783
5844b465
NC
14784 if (compression_header_size == 0)
14785 /* An error message will have already been generated
14786 by get_compression_header. */
14787 goto error_out;
14788
813dabb9 14789 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14790 {
813dabb9 14791 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14792 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14793 goto error_out;
0e602686 14794 }
813dabb9
L
14795 uncompressed_size = chdr.ch_size;
14796 start += compression_header_size;
14797 new_size -= compression_header_size;
0e602686
NC
14798 }
14799 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14800 {
14801 /* Read the zlib header. In this case, it should be "ZLIB"
14802 followed by the uncompressed section size, 8 bytes in
14803 big-endian order. */
14804 uncompressed_size = start[4]; uncompressed_size <<= 8;
14805 uncompressed_size += start[5]; uncompressed_size <<= 8;
14806 uncompressed_size += start[6]; uncompressed_size <<= 8;
14807 uncompressed_size += start[7]; uncompressed_size <<= 8;
14808 uncompressed_size += start[8]; uncompressed_size <<= 8;
14809 uncompressed_size += start[9]; uncompressed_size <<= 8;
14810 uncompressed_size += start[10]; uncompressed_size <<= 8;
14811 uncompressed_size += start[11];
14812 start += 12;
14813 new_size -= 12;
14814 }
14815
f055032e
NC
14816 if (uncompressed_size)
14817 {
14818 if (uncompress_section_contents (& start, uncompressed_size,
14819 & new_size))
bc303e5d
NC
14820 {
14821 section_size = new_size;
14822 }
f055032e
NC
14823 else
14824 {
14825 error (_("Unable to decompress section %s\n"),
dda8d76d 14826 printable_section_name (filedata, section));
bc303e5d 14827 /* FIXME: Print the section anyway ? */
f761cb13 14828 goto error_out;
f055032e
NC
14829 }
14830 }
bc303e5d
NC
14831 else
14832 start = real_start;
0e602686 14833 }
14ae95f2 14834
cf13d699
NC
14835 if (relocate)
14836 {
dda8d76d 14837 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 14838 goto error_out;
cf13d699
NC
14839 }
14840 else
14841 {
14842 /* If the section being dumped has relocations against it the user might
14843 be expecting these relocations to have been applied. Check for this
14844 case and issue a warning message in order to avoid confusion.
14845 FIXME: Maybe we ought to have an option that dumps a section with
14846 relocs applied ? */
dda8d76d
NC
14847 for (relsec = filedata->section_headers;
14848 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14849 ++relsec)
14850 {
14851 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14852 || relsec->sh_info >= filedata->file_header.e_shnum
14853 || filedata->section_headers + relsec->sh_info != section
cf13d699 14854 || relsec->sh_size == 0
dda8d76d 14855 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14856 continue;
14857
14858 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14859 break;
14860 }
14861 }
14862
14863 addr = section->sh_addr;
0e602686 14864 bytes = section_size;
cf13d699
NC
14865 data = start;
14866
14867 while (bytes)
14868 {
14869 int j;
14870 int k;
14871 int lbytes;
14872
14873 lbytes = (bytes > 16 ? 16 : bytes);
14874
14875 printf (" 0x%8.8lx ", (unsigned long) addr);
14876
14877 for (j = 0; j < 16; j++)
14878 {
14879 if (j < lbytes)
14880 printf ("%2.2x", data[j]);
14881 else
14882 printf (" ");
14883
14884 if ((j & 3) == 3)
14885 printf (" ");
14886 }
14887
14888 for (j = 0; j < lbytes; j++)
14889 {
14890 k = data[j];
14891 if (k >= ' ' && k < 0x7f)
14892 printf ("%c", k);
14893 else
14894 printf (".");
14895 }
14896
14897 putchar ('\n');
14898
14899 data += lbytes;
14900 addr += lbytes;
14901 bytes -= lbytes;
14902 }
14903
0e602686 14904 free (real_start);
cf13d699
NC
14905
14906 putchar ('\n');
015dc7e1 14907 return true;
f761cb13
AM
14908
14909 error_out:
14910 free (real_start);
015dc7e1 14911 return false;
cf13d699
NC
14912}
14913
094e34f2 14914#ifdef ENABLE_LIBCTF
7d9813f1
NA
14915static ctf_sect_t *
14916shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
14917{
b9e920ec 14918 buf->cts_name = SECTION_NAME_PRINT (shdr);
7d9813f1
NA
14919 buf->cts_size = shdr->sh_size;
14920 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
14921
14922 return buf;
14923}
14924
14925/* Formatting callback function passed to ctf_dump. Returns either the pointer
14926 it is passed, or a pointer to newly-allocated storage, in which case
14927 dump_ctf() will free it when it no longer needs it. */
14928
2f6ecaed
NA
14929static char *
14930dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14931 char *s, void *arg)
7d9813f1 14932{
3e50a591 14933 const char *blanks = arg;
7d9813f1
NA
14934 char *new_s;
14935
3e50a591 14936 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
14937 return s;
14938 return new_s;
14939}
14940
926c9e76
NA
14941/* Dump CTF errors/warnings. */
14942static void
139633c3 14943dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
14944{
14945 ctf_next_t *it = NULL;
14946 char *errtext;
14947 int is_warning;
14948 int err;
14949
14950 /* Dump accumulated errors and warnings. */
14951 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
14952 {
5e9b84f7 14953 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
14954 errtext);
14955 free (errtext);
14956 }
14957 if (err != ECTF_NEXT_END)
14958 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
14959}
14960
2f6ecaed
NA
14961/* Dump one CTF archive member. */
14962
14963static int
139633c3 14964dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
2f6ecaed 14965{
139633c3 14966 ctf_dict_t *parent = (ctf_dict_t *) arg;
2f6ecaed
NA
14967 const char *things[] = {"Header", "Labels", "Data objects",
14968 "Function objects", "Variables", "Types", "Strings",
14969 ""};
14970 const char **thing;
14971 size_t i;
8b37e7b6 14972 int err = 0;
2f6ecaed
NA
14973
14974 /* Only print out the name of non-default-named archive members.
14975 The name .ctf appears everywhere, even for things that aren't
14976 really archives, so printing it out is liable to be confusing.
14977
14978 The parent, if there is one, is the default-owned archive member:
14979 avoid importing it into itself. (This does no harm, but looks
14980 confusing.) */
14981
14982 if (strcmp (name, ".ctf") != 0)
14983 {
14984 printf (_("\nCTF archive member: %s:\n"), name);
14985 ctf_import (ctf, parent);
14986 }
14987
14988 for (i = 0, thing = things; *thing[0]; thing++, i++)
14989 {
14990 ctf_dump_state_t *s = NULL;
14991 char *item;
14992
14993 printf ("\n %s:\n", *thing);
14994 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
14995 (void *) " ")) != NULL)
14996 {
14997 printf ("%s\n", item);
14998 free (item);
14999 }
15000
15001 if (ctf_errno (ctf))
15002 {
15003 error (_("Iteration failed: %s, %s\n"), *thing,
15004 ctf_errmsg (ctf_errno (ctf)));
8b37e7b6
NA
15005 err = 1;
15006 goto out;
2f6ecaed
NA
15007 }
15008 }
8b37e7b6
NA
15009
15010 out:
926c9e76 15011 dump_ctf_errs (ctf);
8b37e7b6 15012 return err;
2f6ecaed
NA
15013}
15014
015dc7e1 15015static bool
7d9813f1
NA
15016dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15017{
15018 Elf_Internal_Shdr * parent_sec = NULL;
15019 Elf_Internal_Shdr * symtab_sec = NULL;
15020 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15021 void * data = NULL;
15022 void * symdata = NULL;
15023 void * strdata = NULL;
15024 void * parentdata = NULL;
15025 ctf_sect_t ctfsect, symsect, strsect, parentsect;
15026 ctf_sect_t * symsectp = NULL;
15027 ctf_sect_t * strsectp = NULL;
2f6ecaed
NA
15028 ctf_archive_t * ctfa = NULL;
15029 ctf_archive_t * parenta = NULL, *lookparent;
139633c3 15030 ctf_dict_t * parent = NULL;
7d9813f1 15031
7d9813f1 15032 int err;
015dc7e1 15033 bool ret = false;
7d9813f1
NA
15034
15035 shdr_to_ctf_sect (&ctfsect, section, filedata);
15036 data = get_section_contents (section, filedata);
15037 ctfsect.cts_data = data;
15038
616febde 15039 if (!dump_ctf_symtab_name)
3d16b64e 15040 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15041
15042 if (!dump_ctf_strtab_name)
3d16b64e 15043 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15044
15045 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15046 {
15047 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15048 {
15049 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15050 goto fail;
15051 }
15052 if ((symdata = (void *) get_data (NULL, filedata,
15053 symtab_sec->sh_offset, 1,
15054 symtab_sec->sh_size,
15055 _("symbols"))) == NULL)
15056 goto fail;
15057 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15058 symsect.cts_data = symdata;
15059 }
835f2fae 15060
df16e041 15061 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15062 {
15063 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15064 {
15065 error (_("No string table section named %s\n"),
15066 dump_ctf_strtab_name);
15067 goto fail;
15068 }
15069 if ((strdata = (void *) get_data (NULL, filedata,
15070 strtab_sec->sh_offset, 1,
15071 strtab_sec->sh_size,
15072 _("strings"))) == NULL)
15073 goto fail;
15074 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15075 strsect.cts_data = strdata;
15076 }
835f2fae 15077
7d9813f1
NA
15078 if (dump_ctf_parent_name)
15079 {
15080 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
15081 {
15082 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
15083 goto fail;
15084 }
15085 if ((parentdata = (void *) get_data (NULL, filedata,
15086 parent_sec->sh_offset, 1,
15087 parent_sec->sh_size,
15088 _("CTF parent"))) == NULL)
15089 goto fail;
15090 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
15091 parentsect.cts_data = parentdata;
15092 }
15093
2f6ecaed
NA
15094 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15095 libctf papers over the difference, so we can pretend it is always an
15096 archive. Possibly open the parent as well, if one was specified. */
7d9813f1 15097
2f6ecaed 15098 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15099 {
926c9e76 15100 dump_ctf_errs (NULL);
7d9813f1
NA
15101 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15102 goto fail;
15103 }
15104
96c61be5
NA
15105 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15106 != ELFDATA2MSB);
15107
7d9813f1
NA
15108 if (parentdata)
15109 {
2f6ecaed
NA
15110 if ((parenta = ctf_arc_bufopen (&parentsect, symsectp, strsectp,
15111 &err)) == NULL)
7d9813f1 15112 {
926c9e76 15113 dump_ctf_errs (NULL);
7d9813f1
NA
15114 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15115 goto fail;
15116 }
2f6ecaed
NA
15117 lookparent = parenta;
15118 }
15119 else
15120 lookparent = ctfa;
7d9813f1 15121
2f6ecaed
NA
15122 /* Assume that the applicable parent archive member is the default one.
15123 (This is what all known implementations are expected to do, if they
15124 put CTFs and their parents in archives together.) */
ae41200b 15125 if ((parent = ctf_dict_open (lookparent, NULL, &err)) == NULL)
2f6ecaed 15126 {
926c9e76 15127 dump_ctf_errs (NULL);
2f6ecaed
NA
15128 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15129 goto fail;
7d9813f1
NA
15130 }
15131
015dc7e1 15132 ret = true;
7d9813f1 15133
835f2fae
NC
15134 if (filedata->is_separate)
15135 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15136 printable_section_name (filedata, section),
15137 filedata->file_name);
15138 else
15139 printf (_("\nDump of CTF section '%s':\n"),
15140 printable_section_name (filedata, section));
7d9813f1 15141
83d59285
NA
15142 if ((err = ctf_archive_iter (ctfa, dump_ctf_archive_member, parent)) != 0)
15143 {
15144 dump_ctf_errs (NULL);
15145 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
015dc7e1 15146 ret = false;
83d59285 15147 }
7d9813f1
NA
15148
15149 fail:
139633c3 15150 ctf_dict_close (parent);
2f6ecaed
NA
15151 ctf_close (ctfa);
15152 ctf_close (parenta);
7d9813f1
NA
15153 free (parentdata);
15154 free (data);
15155 free (symdata);
15156 free (strdata);
15157 return ret;
15158}
094e34f2 15159#endif
7d9813f1 15160
015dc7e1 15161static bool
dda8d76d
NC
15162load_specific_debug_section (enum dwarf_section_display_enum debug,
15163 const Elf_Internal_Shdr * sec,
15164 void * data)
1007acb3 15165{
2cf0635d 15166 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15167 char buf [64];
dda8d76d 15168 Filedata * filedata = (Filedata *) data;
9abca702 15169
19e6b90e 15170 if (section->start != NULL)
dda8d76d
NC
15171 {
15172 /* If it is already loaded, do nothing. */
15173 if (streq (section->filename, filedata->file_name))
015dc7e1 15174 return true;
dda8d76d
NC
15175 free (section->start);
15176 }
1007acb3 15177
19e6b90e
L
15178 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15179 section->address = sec->sh_addr;
dda8d76d
NC
15180 section->filename = filedata->file_name;
15181 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15182 sec->sh_offset, 1,
15183 sec->sh_size, buf);
59245841
NC
15184 if (section->start == NULL)
15185 section->size = 0;
15186 else
15187 {
77115a4a
L
15188 unsigned char *start = section->start;
15189 dwarf_size_type size = sec->sh_size;
dab394de 15190 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15191
15192 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15193 {
15194 Elf_Internal_Chdr chdr;
d8024a91
NC
15195 unsigned int compression_header_size;
15196
f53be977
L
15197 if (size < (is_32bit_elf
15198 ? sizeof (Elf32_External_Chdr)
15199 : sizeof (Elf64_External_Chdr)))
d8024a91 15200 {
55be8fd0 15201 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15202 section->name);
015dc7e1 15203 return false;
d8024a91
NC
15204 }
15205
ebdf1ebf 15206 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15207 if (compression_header_size == 0)
15208 /* An error message will have already been generated
15209 by get_compression_header. */
015dc7e1 15210 return false;
d8024a91 15211
813dabb9
L
15212 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15213 {
15214 warn (_("section '%s' has unsupported compress type: %d\n"),
15215 section->name, chdr.ch_type);
015dc7e1 15216 return false;
813dabb9 15217 }
dab394de 15218 uncompressed_size = chdr.ch_size;
77115a4a
L
15219 start += compression_header_size;
15220 size -= compression_header_size;
15221 }
dab394de
L
15222 else if (size > 12 && streq ((char *) start, "ZLIB"))
15223 {
15224 /* Read the zlib header. In this case, it should be "ZLIB"
15225 followed by the uncompressed section size, 8 bytes in
15226 big-endian order. */
15227 uncompressed_size = start[4]; uncompressed_size <<= 8;
15228 uncompressed_size += start[5]; uncompressed_size <<= 8;
15229 uncompressed_size += start[6]; uncompressed_size <<= 8;
15230 uncompressed_size += start[7]; uncompressed_size <<= 8;
15231 uncompressed_size += start[8]; uncompressed_size <<= 8;
15232 uncompressed_size += start[9]; uncompressed_size <<= 8;
15233 uncompressed_size += start[10]; uncompressed_size <<= 8;
15234 uncompressed_size += start[11];
15235 start += 12;
15236 size -= 12;
15237 }
15238
1835f746 15239 if (uncompressed_size)
77115a4a 15240 {
1835f746
NC
15241 if (uncompress_section_contents (&start, uncompressed_size,
15242 &size))
15243 {
15244 /* Free the compressed buffer, update the section buffer
15245 and the section size if uncompress is successful. */
15246 free (section->start);
15247 section->start = start;
15248 }
15249 else
15250 {
15251 error (_("Unable to decompress section %s\n"),
dda8d76d 15252 printable_section_name (filedata, sec));
015dc7e1 15253 return false;
1835f746 15254 }
77115a4a 15255 }
bc303e5d 15256
77115a4a 15257 section->size = size;
59245841 15258 }
4a114e3e 15259
1b315056 15260 if (section->start == NULL)
015dc7e1 15261 return false;
1b315056 15262
19e6b90e 15263 if (debug_displays [debug].relocate)
32ec8896 15264 {
dda8d76d 15265 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15266 & section->reloc_info, & section->num_relocs))
015dc7e1 15267 return false;
32ec8896 15268 }
d1c4b12b
NC
15269 else
15270 {
15271 section->reloc_info = NULL;
15272 section->num_relocs = 0;
15273 }
1007acb3 15274
015dc7e1 15275 return true;
1007acb3
L
15276}
15277
301a9420
AM
15278#if HAVE_LIBDEBUGINFOD
15279/* Return a hex string representation of the build-id. */
15280unsigned char *
15281get_build_id (void * data)
15282{
ca0e11aa 15283 Filedata * filedata = (Filedata *) data;
301a9420
AM
15284 Elf_Internal_Shdr * shdr;
15285 unsigned long i;
15286
55be8fd0
NC
15287 /* Iterate through notes to find note.gnu.build-id.
15288 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15289 for (i = 0, shdr = filedata->section_headers;
15290 i < filedata->file_header.e_shnum && shdr != NULL;
15291 i++, shdr++)
15292 {
15293 if (shdr->sh_type != SHT_NOTE)
15294 continue;
15295
15296 char * next;
15297 char * end;
15298 size_t data_remaining;
15299 size_t min_notesz;
15300 Elf_External_Note * enote;
15301 Elf_Internal_Note inote;
15302
15303 bfd_vma offset = shdr->sh_offset;
15304 bfd_vma align = shdr->sh_addralign;
15305 bfd_vma length = shdr->sh_size;
15306
15307 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15308 if (enote == NULL)
15309 continue;
15310
15311 if (align < 4)
15312 align = 4;
15313 else if (align != 4 && align != 8)
f761cb13
AM
15314 {
15315 free (enote);
15316 continue;
15317 }
301a9420
AM
15318
15319 end = (char *) enote + length;
15320 data_remaining = end - (char *) enote;
15321
15322 if (!is_ia64_vms (filedata))
15323 {
15324 min_notesz = offsetof (Elf_External_Note, name);
15325 if (data_remaining < min_notesz)
15326 {
55be8fd0
NC
15327 warn (_("\
15328malformed note encountered in section %s whilst scanning for build-id note\n"),
15329 printable_section_name (filedata, shdr));
f761cb13 15330 free (enote);
55be8fd0 15331 continue;
301a9420
AM
15332 }
15333 data_remaining -= min_notesz;
15334
15335 inote.type = BYTE_GET (enote->type);
15336 inote.namesz = BYTE_GET (enote->namesz);
15337 inote.namedata = enote->name;
15338 inote.descsz = BYTE_GET (enote->descsz);
15339 inote.descdata = ((char *) enote
15340 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15341 inote.descpos = offset + (inote.descdata - (char *) enote);
15342 next = ((char *) enote
15343 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15344 }
15345 else
15346 {
15347 Elf64_External_VMS_Note *vms_enote;
15348
15349 /* PR binutils/15191
15350 Make sure that there is enough data to read. */
15351 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15352 if (data_remaining < min_notesz)
15353 {
55be8fd0
NC
15354 warn (_("\
15355malformed note encountered in section %s whilst scanning for build-id note\n"),
15356 printable_section_name (filedata, shdr));
f761cb13 15357 free (enote);
55be8fd0 15358 continue;
301a9420
AM
15359 }
15360 data_remaining -= min_notesz;
15361
15362 vms_enote = (Elf64_External_VMS_Note *) enote;
15363 inote.type = BYTE_GET (vms_enote->type);
15364 inote.namesz = BYTE_GET (vms_enote->namesz);
15365 inote.namedata = vms_enote->name;
15366 inote.descsz = BYTE_GET (vms_enote->descsz);
15367 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15368 inote.descpos = offset + (inote.descdata - (char *) enote);
15369 next = inote.descdata + align_power (inote.descsz, 3);
15370 }
15371
15372 /* Skip malformed notes. */
15373 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
15374 || (size_t) (inote.descdata - inote.namedata) > data_remaining
15375 || (size_t) (next - inote.descdata) < inote.descsz
15376 || ((size_t) (next - inote.descdata)
15377 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
15378 {
55be8fd0
NC
15379 warn (_("\
15380malformed note encountered in section %s whilst scanning for build-id note\n"),
15381 printable_section_name (filedata, shdr));
f761cb13 15382 free (enote);
301a9420
AM
15383 continue;
15384 }
15385
15386 /* Check if this is the build-id note. If so then convert the build-id
15387 bytes to a hex string. */
15388 if (inote.namesz > 0
24d127aa 15389 && startswith (inote.namedata, "GNU")
301a9420
AM
15390 && inote.type == NT_GNU_BUILD_ID)
15391 {
15392 unsigned long j;
15393 char * build_id;
15394
15395 build_id = malloc (inote.descsz * 2 + 1);
15396 if (build_id == NULL)
f761cb13
AM
15397 {
15398 free (enote);
15399 return NULL;
15400 }
301a9420
AM
15401
15402 for (j = 0; j < inote.descsz; ++j)
15403 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
15404 build_id[inote.descsz * 2] = '\0';
f761cb13 15405 free (enote);
301a9420 15406
55be8fd0 15407 return (unsigned char *) build_id;
301a9420 15408 }
f761cb13 15409 free (enote);
301a9420
AM
15410 }
15411
15412 return NULL;
15413}
15414#endif /* HAVE_LIBDEBUGINFOD */
15415
657d0d47
CC
15416/* If this is not NULL, load_debug_section will only look for sections
15417 within the list of sections given here. */
32ec8896 15418static unsigned int * section_subset = NULL;
657d0d47 15419
015dc7e1 15420bool
dda8d76d 15421load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 15422{
2cf0635d
NC
15423 struct dwarf_section * section = &debug_displays [debug].section;
15424 Elf_Internal_Shdr * sec;
dda8d76d
NC
15425 Filedata * filedata = (Filedata *) data;
15426
f425ec66
NC
15427 /* Without section headers we cannot find any sections. */
15428 if (filedata->section_headers == NULL)
015dc7e1 15429 return false;
f425ec66 15430
9c1ce108
AM
15431 if (filedata->string_table == NULL
15432 && filedata->file_header.e_shstrndx != SHN_UNDEF
15433 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
15434 {
15435 Elf_Internal_Shdr * strs;
15436
15437 /* Read in the string table, so that we have section names to scan. */
15438 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
15439
4dff97b2 15440 if (strs != NULL && strs->sh_size != 0)
dda8d76d 15441 {
9c1ce108
AM
15442 filedata->string_table
15443 = (char *) get_data (NULL, filedata, strs->sh_offset,
15444 1, strs->sh_size, _("string table"));
dda8d76d 15445
9c1ce108
AM
15446 filedata->string_table_length
15447 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
15448 }
15449 }
d966045b
DJ
15450
15451 /* Locate the debug section. */
dda8d76d 15452 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
15453 if (sec != NULL)
15454 section->name = section->uncompressed_name;
15455 else
15456 {
dda8d76d 15457 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
15458 if (sec != NULL)
15459 section->name = section->compressed_name;
15460 }
15461 if (sec == NULL)
015dc7e1 15462 return false;
d966045b 15463
657d0d47
CC
15464 /* If we're loading from a subset of sections, and we've loaded
15465 a section matching this name before, it's likely that it's a
15466 different one. */
15467 if (section_subset != NULL)
15468 free_debug_section (debug);
15469
dda8d76d 15470 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
15471}
15472
19e6b90e
L
15473void
15474free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 15475{
2cf0635d 15476 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 15477
19e6b90e
L
15478 if (section->start == NULL)
15479 return;
1007acb3 15480
19e6b90e
L
15481 free ((char *) section->start);
15482 section->start = NULL;
15483 section->address = 0;
15484 section->size = 0;
a788aedd 15485
9db70fc3
AM
15486 free (section->reloc_info);
15487 section->reloc_info = NULL;
15488 section->num_relocs = 0;
1007acb3
L
15489}
15490
015dc7e1 15491static bool
dda8d76d 15492display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 15493{
b9e920ec 15494 char * name = SECTION_NAME_VALID (section) ? SECTION_NAME (section) : "";
dda8d76d 15495 const char * print_name = printable_section_name (filedata, section);
19e6b90e 15496 bfd_size_type length;
015dc7e1 15497 bool result = true;
3f5e193b 15498 int i;
1007acb3 15499
19e6b90e
L
15500 length = section->sh_size;
15501 if (length == 0)
1007acb3 15502 {
74e1a04b 15503 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 15504 return true;
1007acb3 15505 }
5dff79d8
NC
15506 if (section->sh_type == SHT_NOBITS)
15507 {
15508 /* There is no point in dumping the contents of a debugging section
15509 which has the NOBITS type - the bits in the file will be random.
15510 This can happen when a file containing a .eh_frame section is
15511 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
15512 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
15513 print_name);
015dc7e1 15514 return false;
5dff79d8 15515 }
1007acb3 15516
24d127aa 15517 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 15518 name = ".debug_info";
1007acb3 15519
19e6b90e
L
15520 /* See if we know how to display the contents of this section. */
15521 for (i = 0; i < max; i++)
d85bf2ba
NC
15522 {
15523 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
15524 struct dwarf_section_display * display = debug_displays + i;
15525 struct dwarf_section * sec = & display->section;
d966045b 15526
d85bf2ba 15527 if (streq (sec->uncompressed_name, name)
24d127aa 15528 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15529 || streq (sec->compressed_name, name))
15530 {
015dc7e1 15531 bool secondary = (section != find_section (filedata, name));
1007acb3 15532
d85bf2ba
NC
15533 if (secondary)
15534 free_debug_section (id);
dda8d76d 15535
24d127aa 15536 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15537 sec->name = name;
15538 else if (streq (sec->uncompressed_name, name))
15539 sec->name = sec->uncompressed_name;
15540 else
15541 sec->name = sec->compressed_name;
657d0d47 15542
d85bf2ba
NC
15543 if (load_specific_debug_section (id, section, filedata))
15544 {
15545 /* If this debug section is part of a CU/TU set in a .dwp file,
15546 restrict load_debug_section to the sections in that set. */
15547 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 15548
d85bf2ba 15549 result &= display->display (sec, filedata);
657d0d47 15550
d85bf2ba 15551 section_subset = NULL;
1007acb3 15552
44266f36 15553 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
15554 free_debug_section (id);
15555 }
15556 break;
15557 }
15558 }
1007acb3 15559
19e6b90e 15560 if (i == max)
1007acb3 15561 {
74e1a04b 15562 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 15563 result = false;
1007acb3
L
15564 }
15565
19e6b90e 15566 return result;
5b18a4bc 15567}
103f02d3 15568
aef1f6d0
DJ
15569/* Set DUMP_SECTS for all sections where dumps were requested
15570 based on section name. */
15571
15572static void
dda8d76d 15573initialise_dumps_byname (Filedata * filedata)
aef1f6d0 15574{
2cf0635d 15575 struct dump_list_entry * cur;
aef1f6d0
DJ
15576
15577 for (cur = dump_sects_byname; cur; cur = cur->next)
15578 {
15579 unsigned int i;
015dc7e1 15580 bool any = false;
aef1f6d0 15581
dda8d76d 15582 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
15583 if (SECTION_NAME_VALID (filedata->section_headers + i)
15584 && streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 15585 {
6431e409 15586 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 15587 any = true;
aef1f6d0
DJ
15588 }
15589
835f2fae
NC
15590 if (!any && !filedata->is_separate)
15591 warn (_("Section '%s' was not dumped because it does not exist\n"),
15592 cur->name);
aef1f6d0
DJ
15593 }
15594}
15595
015dc7e1 15596static bool
dda8d76d 15597process_section_contents (Filedata * filedata)
5b18a4bc 15598{
2cf0635d 15599 Elf_Internal_Shdr * section;
19e6b90e 15600 unsigned int i;
015dc7e1 15601 bool res = true;
103f02d3 15602
19e6b90e 15603 if (! do_dump)
015dc7e1 15604 return true;
103f02d3 15605
dda8d76d 15606 initialise_dumps_byname (filedata);
aef1f6d0 15607
dda8d76d 15608 for (i = 0, section = filedata->section_headers;
6431e409 15609 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
15610 i++, section++)
15611 {
6431e409 15612 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 15613
d6bfbc39
NC
15614 if (filedata->is_separate && ! process_links)
15615 dump &= DEBUG_DUMP;
047c3dbf 15616
19e6b90e 15617#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
15618 if (dump & DISASS_DUMP)
15619 {
15620 if (! disassemble_section (section, filedata))
015dc7e1 15621 res = false;
dda8d76d 15622 }
19e6b90e 15623#endif
dda8d76d 15624 if (dump & HEX_DUMP)
32ec8896 15625 {
015dc7e1
AM
15626 if (! dump_section_as_bytes (section, filedata, false))
15627 res = false;
32ec8896 15628 }
103f02d3 15629
dda8d76d 15630 if (dump & RELOC_DUMP)
32ec8896 15631 {
015dc7e1
AM
15632 if (! dump_section_as_bytes (section, filedata, true))
15633 res = false;
32ec8896 15634 }
09c11c86 15635
dda8d76d 15636 if (dump & STRING_DUMP)
32ec8896 15637 {
dda8d76d 15638 if (! dump_section_as_strings (section, filedata))
015dc7e1 15639 res = false;
32ec8896 15640 }
cf13d699 15641
dda8d76d 15642 if (dump & DEBUG_DUMP)
32ec8896 15643 {
dda8d76d 15644 if (! display_debug_section (i, section, filedata))
015dc7e1 15645 res = false;
32ec8896 15646 }
7d9813f1 15647
094e34f2 15648#ifdef ENABLE_LIBCTF
7d9813f1
NA
15649 if (dump & CTF_DUMP)
15650 {
15651 if (! dump_section_as_ctf (section, filedata))
015dc7e1 15652 res = false;
7d9813f1 15653 }
094e34f2 15654#endif
5b18a4bc 15655 }
103f02d3 15656
835f2fae 15657 if (! filedata->is_separate)
0ee3043f 15658 {
835f2fae
NC
15659 /* Check to see if the user requested a
15660 dump of a section that does not exist. */
15661 for (; i < filedata->dump.num_dump_sects; i++)
15662 if (filedata->dump.dump_sects[i])
15663 {
ca0e11aa 15664 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 15665 res = false;
835f2fae 15666 }
0ee3043f 15667 }
32ec8896
NC
15668
15669 return res;
5b18a4bc 15670}
103f02d3 15671
5b18a4bc 15672static void
19e6b90e 15673process_mips_fpe_exception (int mask)
5b18a4bc 15674{
19e6b90e
L
15675 if (mask)
15676 {
015dc7e1 15677 bool first = true;
32ec8896 15678
19e6b90e 15679 if (mask & OEX_FPU_INEX)
015dc7e1 15680 fputs ("INEX", stdout), first = false;
19e6b90e 15681 if (mask & OEX_FPU_UFLO)
015dc7e1 15682 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 15683 if (mask & OEX_FPU_OFLO)
015dc7e1 15684 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 15685 if (mask & OEX_FPU_DIV0)
015dc7e1 15686 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
15687 if (mask & OEX_FPU_INVAL)
15688 printf ("%sINVAL", first ? "" : "|");
15689 }
5b18a4bc 15690 else
19e6b90e 15691 fputs ("0", stdout);
5b18a4bc 15692}
103f02d3 15693
f6f0e17b
NC
15694/* Display's the value of TAG at location P. If TAG is
15695 greater than 0 it is assumed to be an unknown tag, and
15696 a message is printed to this effect. Otherwise it is
15697 assumed that a message has already been printed.
15698
15699 If the bottom bit of TAG is set it assumed to have a
15700 string value, otherwise it is assumed to have an integer
15701 value.
15702
15703 Returns an updated P pointing to the first unread byte
15704 beyond the end of TAG's value.
15705
15706 Reads at or beyond END will not be made. */
15707
15708static unsigned char *
60abdbed 15709display_tag_value (signed int tag,
f6f0e17b
NC
15710 unsigned char * p,
15711 const unsigned char * const end)
15712{
15713 unsigned long val;
15714
15715 if (tag > 0)
15716 printf (" Tag_unknown_%d: ", tag);
15717
15718 if (p >= end)
15719 {
4082ef84 15720 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
15721 }
15722 else if (tag & 1)
15723 {
071436c6
NC
15724 /* PR 17531 file: 027-19978-0.004. */
15725 size_t maxlen = (end - p) - 1;
15726
15727 putchar ('"');
4082ef84
NC
15728 if (maxlen > 0)
15729 {
15730 print_symbol ((int) maxlen, (const char *) p);
15731 p += strnlen ((char *) p, maxlen) + 1;
15732 }
15733 else
15734 {
15735 printf (_("<corrupt string tag>"));
15736 p = (unsigned char *) end;
15737 }
071436c6 15738 printf ("\"\n");
f6f0e17b
NC
15739 }
15740 else
15741 {
cd30bcef 15742 READ_ULEB (val, p, end);
f6f0e17b
NC
15743 printf ("%ld (0x%lx)\n", val, val);
15744 }
15745
4082ef84 15746 assert (p <= end);
f6f0e17b
NC
15747 return p;
15748}
15749
53a346d8
CZ
15750/* ARC ABI attributes section. */
15751
15752static unsigned char *
15753display_arc_attribute (unsigned char * p,
15754 const unsigned char * const end)
15755{
15756 unsigned int tag;
53a346d8
CZ
15757 unsigned int val;
15758
cd30bcef 15759 READ_ULEB (tag, p, end);
53a346d8
CZ
15760
15761 switch (tag)
15762 {
15763 case Tag_ARC_PCS_config:
cd30bcef 15764 READ_ULEB (val, p, end);
53a346d8
CZ
15765 printf (" Tag_ARC_PCS_config: ");
15766 switch (val)
15767 {
15768 case 0:
15769 printf (_("Absent/Non standard\n"));
15770 break;
15771 case 1:
15772 printf (_("Bare metal/mwdt\n"));
15773 break;
15774 case 2:
15775 printf (_("Bare metal/newlib\n"));
15776 break;
15777 case 3:
15778 printf (_("Linux/uclibc\n"));
15779 break;
15780 case 4:
15781 printf (_("Linux/glibc\n"));
15782 break;
15783 default:
15784 printf (_("Unknown\n"));
15785 break;
15786 }
15787 break;
15788
15789 case Tag_ARC_CPU_base:
cd30bcef 15790 READ_ULEB (val, p, end);
53a346d8
CZ
15791 printf (" Tag_ARC_CPU_base: ");
15792 switch (val)
15793 {
15794 default:
15795 case TAG_CPU_NONE:
15796 printf (_("Absent\n"));
15797 break;
15798 case TAG_CPU_ARC6xx:
15799 printf ("ARC6xx\n");
15800 break;
15801 case TAG_CPU_ARC7xx:
15802 printf ("ARC7xx\n");
15803 break;
15804 case TAG_CPU_ARCEM:
15805 printf ("ARCEM\n");
15806 break;
15807 case TAG_CPU_ARCHS:
15808 printf ("ARCHS\n");
15809 break;
15810 }
15811 break;
15812
15813 case Tag_ARC_CPU_variation:
cd30bcef 15814 READ_ULEB (val, p, end);
53a346d8
CZ
15815 printf (" Tag_ARC_CPU_variation: ");
15816 switch (val)
15817 {
15818 default:
15819 if (val > 0 && val < 16)
53a346d8 15820 printf ("Core%d\n", val);
d8cbc93b
JL
15821 else
15822 printf ("Unknown\n");
15823 break;
15824
53a346d8
CZ
15825 case 0:
15826 printf (_("Absent\n"));
15827 break;
15828 }
15829 break;
15830
15831 case Tag_ARC_CPU_name:
15832 printf (" Tag_ARC_CPU_name: ");
15833 p = display_tag_value (-1, p, end);
15834 break;
15835
15836 case Tag_ARC_ABI_rf16:
cd30bcef 15837 READ_ULEB (val, p, end);
53a346d8
CZ
15838 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
15839 break;
15840
15841 case Tag_ARC_ABI_osver:
cd30bcef 15842 READ_ULEB (val, p, end);
53a346d8
CZ
15843 printf (" Tag_ARC_ABI_osver: v%d\n", val);
15844 break;
15845
15846 case Tag_ARC_ABI_pic:
15847 case Tag_ARC_ABI_sda:
cd30bcef 15848 READ_ULEB (val, p, end);
53a346d8
CZ
15849 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
15850 : " Tag_ARC_ABI_pic: ");
15851 switch (val)
15852 {
15853 case 0:
15854 printf (_("Absent\n"));
15855 break;
15856 case 1:
15857 printf ("MWDT\n");
15858 break;
15859 case 2:
15860 printf ("GNU\n");
15861 break;
15862 default:
15863 printf (_("Unknown\n"));
15864 break;
15865 }
15866 break;
15867
15868 case Tag_ARC_ABI_tls:
cd30bcef 15869 READ_ULEB (val, p, end);
53a346d8
CZ
15870 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
15871 break;
15872
15873 case Tag_ARC_ABI_enumsize:
cd30bcef 15874 READ_ULEB (val, p, end);
53a346d8
CZ
15875 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
15876 _("smallest"));
15877 break;
15878
15879 case Tag_ARC_ABI_exceptions:
cd30bcef 15880 READ_ULEB (val, p, end);
53a346d8
CZ
15881 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
15882 : _("default"));
15883 break;
15884
15885 case Tag_ARC_ABI_double_size:
cd30bcef 15886 READ_ULEB (val, p, end);
53a346d8
CZ
15887 printf (" Tag_ARC_ABI_double_size: %d\n", val);
15888 break;
15889
15890 case Tag_ARC_ISA_config:
15891 printf (" Tag_ARC_ISA_config: ");
15892 p = display_tag_value (-1, p, end);
15893 break;
15894
15895 case Tag_ARC_ISA_apex:
15896 printf (" Tag_ARC_ISA_apex: ");
15897 p = display_tag_value (-1, p, end);
15898 break;
15899
15900 case Tag_ARC_ISA_mpy_option:
cd30bcef 15901 READ_ULEB (val, p, end);
53a346d8
CZ
15902 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
15903 break;
15904
db1e1b45 15905 case Tag_ARC_ATR_version:
cd30bcef 15906 READ_ULEB (val, p, end);
db1e1b45 15907 printf (" Tag_ARC_ATR_version: %d\n", val);
15908 break;
15909
53a346d8
CZ
15910 default:
15911 return display_tag_value (tag & 1, p, end);
15912 }
15913
15914 return p;
15915}
15916
11c1ff18
PB
15917/* ARM EABI attributes section. */
15918typedef struct
15919{
70e99720 15920 unsigned int tag;
2cf0635d 15921 const char * name;
11c1ff18 15922 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 15923 unsigned int type;
288f0ba2 15924 const char *const *table;
11c1ff18
PB
15925} arm_attr_public_tag;
15926
288f0ba2 15927static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 15928 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 15929 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 15930 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
288f0ba2
AM
15931static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
15932static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 15933 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 15934static const char *const arm_attr_tag_FP_arch[] =
bca38921 15935 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 15936 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
15937static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
15938static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
15939 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
15940 "NEON for ARMv8.1"};
288f0ba2 15941static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
15942 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
15943 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 15944static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 15945 {"V6", "SB", "TLS", "Unused"};
288f0ba2 15946static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 15947 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 15948static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 15949 {"Absolute", "PC-relative", "None"};
288f0ba2 15950static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 15951 {"None", "direct", "GOT-indirect"};
288f0ba2 15952static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 15953 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
15954static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
15955static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 15956 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
15957static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
15958static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
15959static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 15960 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 15961static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 15962 {"Unused", "small", "int", "forced to int"};
288f0ba2 15963static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 15964 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 15965static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 15966 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 15967static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 15968 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 15969static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
15970 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15971 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 15972static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
15973 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15974 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
15975static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
15976static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 15977 {"Not Allowed", "Allowed"};
288f0ba2 15978static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 15979 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 15980static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 15981 {"Follow architecture", "Allowed"};
288f0ba2 15982static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 15983 {"Not Allowed", "Allowed"};
288f0ba2 15984static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 15985 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 15986 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
15987static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
15988static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 15989 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 15990 "TrustZone and Virtualization Extensions"};
288f0ba2 15991static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 15992 {"Not Allowed", "Allowed"};
11c1ff18 15993
288f0ba2 15994static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
15995 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
15996
11c1ff18
PB
15997#define LOOKUP(id, name) \
15998 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 15999static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16000{
16001 {4, "CPU_raw_name", 1, NULL},
16002 {5, "CPU_name", 1, NULL},
16003 LOOKUP(6, CPU_arch),
16004 {7, "CPU_arch_profile", 0, NULL},
16005 LOOKUP(8, ARM_ISA_use),
16006 LOOKUP(9, THUMB_ISA_use),
75375b3e 16007 LOOKUP(10, FP_arch),
11c1ff18 16008 LOOKUP(11, WMMX_arch),
f5f53991
AS
16009 LOOKUP(12, Advanced_SIMD_arch),
16010 LOOKUP(13, PCS_config),
11c1ff18
PB
16011 LOOKUP(14, ABI_PCS_R9_use),
16012 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16013 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16014 LOOKUP(17, ABI_PCS_GOT_use),
16015 LOOKUP(18, ABI_PCS_wchar_t),
16016 LOOKUP(19, ABI_FP_rounding),
16017 LOOKUP(20, ABI_FP_denormal),
16018 LOOKUP(21, ABI_FP_exceptions),
16019 LOOKUP(22, ABI_FP_user_exceptions),
16020 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16021 {24, "ABI_align_needed", 0, NULL},
16022 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16023 LOOKUP(26, ABI_enum_size),
16024 LOOKUP(27, ABI_HardFP_use),
16025 LOOKUP(28, ABI_VFP_args),
16026 LOOKUP(29, ABI_WMMX_args),
16027 LOOKUP(30, ABI_optimization_goals),
16028 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16029 {32, "compatibility", 0, NULL},
f5f53991 16030 LOOKUP(34, CPU_unaligned_access),
75375b3e 16031 LOOKUP(36, FP_HP_extension),
8e79c3df 16032 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16033 LOOKUP(42, MPextension_use),
16034 LOOKUP(44, DIV_use),
15afaa63 16035 LOOKUP(46, DSP_extension),
a7ad558c 16036 LOOKUP(48, MVE_arch),
f5f53991
AS
16037 {64, "nodefaults", 0, NULL},
16038 {65, "also_compatible_with", 0, NULL},
16039 LOOKUP(66, T2EE_use),
16040 {67, "conformance", 1, NULL},
16041 LOOKUP(68, Virtualization_use),
cd21e546 16042 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16043};
16044#undef LOOKUP
16045
11c1ff18 16046static unsigned char *
f6f0e17b
NC
16047display_arm_attribute (unsigned char * p,
16048 const unsigned char * const end)
11c1ff18 16049{
70e99720 16050 unsigned int tag;
70e99720 16051 unsigned int val;
2cf0635d 16052 arm_attr_public_tag * attr;
11c1ff18 16053 unsigned i;
70e99720 16054 unsigned int type;
11c1ff18 16055
cd30bcef 16056 READ_ULEB (tag, p, end);
11c1ff18 16057 attr = NULL;
2cf0635d 16058 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16059 {
16060 if (arm_attr_public_tags[i].tag == tag)
16061 {
16062 attr = &arm_attr_public_tags[i];
16063 break;
16064 }
16065 }
16066
16067 if (attr)
16068 {
16069 printf (" Tag_%s: ", attr->name);
16070 switch (attr->type)
16071 {
16072 case 0:
16073 switch (tag)
16074 {
16075 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16076 READ_ULEB (val, p, end);
11c1ff18
PB
16077 switch (val)
16078 {
2b692964
NC
16079 case 0: printf (_("None\n")); break;
16080 case 'A': printf (_("Application\n")); break;
16081 case 'R': printf (_("Realtime\n")); break;
16082 case 'M': printf (_("Microcontroller\n")); break;
16083 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16084 default: printf ("??? (%d)\n", val); break;
16085 }
16086 break;
16087
75375b3e 16088 case 24: /* Tag_align_needed. */
cd30bcef 16089 READ_ULEB (val, p, end);
75375b3e
MGD
16090 switch (val)
16091 {
2b692964
NC
16092 case 0: printf (_("None\n")); break;
16093 case 1: printf (_("8-byte\n")); break;
16094 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16095 case 3: printf ("??? 3\n"); break;
16096 default:
16097 if (val <= 12)
dd24e3da 16098 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16099 1 << val);
16100 else
16101 printf ("??? (%d)\n", val);
16102 break;
16103 }
16104 break;
16105
16106 case 25: /* Tag_align_preserved. */
cd30bcef 16107 READ_ULEB (val, p, end);
75375b3e
MGD
16108 switch (val)
16109 {
2b692964
NC
16110 case 0: printf (_("None\n")); break;
16111 case 1: printf (_("8-byte, except leaf SP\n")); break;
16112 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16113 case 3: printf ("??? 3\n"); break;
16114 default:
16115 if (val <= 12)
dd24e3da 16116 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16117 1 << val);
16118 else
16119 printf ("??? (%d)\n", val);
16120 break;
16121 }
16122 break;
16123
11c1ff18 16124 case 32: /* Tag_compatibility. */
071436c6 16125 {
cd30bcef 16126 READ_ULEB (val, p, end);
071436c6 16127 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16128 if (p < end - 1)
16129 {
16130 size_t maxlen = (end - p) - 1;
16131
16132 print_symbol ((int) maxlen, (const char *) p);
16133 p += strnlen ((char *) p, maxlen) + 1;
16134 }
16135 else
16136 {
16137 printf (_("<corrupt>"));
16138 p = (unsigned char *) end;
16139 }
071436c6 16140 putchar ('\n');
071436c6 16141 }
11c1ff18
PB
16142 break;
16143
f5f53991 16144 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16145 /* PR 17531: file: 001-505008-0.01. */
16146 if (p < end)
16147 p++;
2b692964 16148 printf (_("True\n"));
f5f53991
AS
16149 break;
16150
16151 case 65: /* Tag_also_compatible_with. */
cd30bcef 16152 READ_ULEB (val, p, end);
f5f53991
AS
16153 if (val == 6 /* Tag_CPU_arch. */)
16154 {
cd30bcef 16155 READ_ULEB (val, p, end);
071436c6 16156 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16157 printf ("??? (%d)\n", val);
16158 else
16159 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16160 }
16161 else
16162 printf ("???\n");
071436c6
NC
16163 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16164 ;
f5f53991
AS
16165 break;
16166
11c1ff18 16167 default:
bee0ee85
NC
16168 printf (_("<unknown: %d>\n"), tag);
16169 break;
11c1ff18
PB
16170 }
16171 return p;
16172
16173 case 1:
f6f0e17b 16174 return display_tag_value (-1, p, end);
11c1ff18 16175 case 2:
f6f0e17b 16176 return display_tag_value (0, p, end);
11c1ff18
PB
16177
16178 default:
16179 assert (attr->type & 0x80);
cd30bcef 16180 READ_ULEB (val, p, end);
11c1ff18
PB
16181 type = attr->type & 0x7f;
16182 if (val >= type)
16183 printf ("??? (%d)\n", val);
16184 else
16185 printf ("%s\n", attr->table[val]);
16186 return p;
16187 }
16188 }
11c1ff18 16189
f6f0e17b 16190 return display_tag_value (tag, p, end);
11c1ff18
PB
16191}
16192
104d59d1 16193static unsigned char *
60bca95a 16194display_gnu_attribute (unsigned char * p,
60abdbed 16195 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16196 const unsigned char * const end)
104d59d1 16197{
cd30bcef 16198 unsigned int tag;
60abdbed 16199 unsigned int val;
104d59d1 16200
cd30bcef 16201 READ_ULEB (tag, p, end);
104d59d1
JM
16202
16203 /* Tag_compatibility is the only generic GNU attribute defined at
16204 present. */
16205 if (tag == 32)
16206 {
cd30bcef 16207 READ_ULEB (val, p, end);
071436c6
NC
16208
16209 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16210 if (p == end)
16211 {
071436c6 16212 printf (_("<corrupt>\n"));
f6f0e17b
NC
16213 warn (_("corrupt vendor attribute\n"));
16214 }
16215 else
16216 {
4082ef84
NC
16217 if (p < end - 1)
16218 {
16219 size_t maxlen = (end - p) - 1;
071436c6 16220
4082ef84
NC
16221 print_symbol ((int) maxlen, (const char *) p);
16222 p += strnlen ((char *) p, maxlen) + 1;
16223 }
16224 else
16225 {
16226 printf (_("<corrupt>"));
16227 p = (unsigned char *) end;
16228 }
071436c6 16229 putchar ('\n');
f6f0e17b 16230 }
104d59d1
JM
16231 return p;
16232 }
16233
16234 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16235 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16236
f6f0e17b 16237 return display_tag_value (tag, p, end);
104d59d1
JM
16238}
16239
85f7484a
PB
16240static unsigned char *
16241display_m68k_gnu_attribute (unsigned char * p,
16242 unsigned int tag,
16243 const unsigned char * const end)
16244{
16245 unsigned int val;
16246
16247 if (tag == Tag_GNU_M68K_ABI_FP)
16248 {
16249 printf (" Tag_GNU_M68K_ABI_FP: ");
16250 if (p == end)
16251 {
16252 printf (_("<corrupt>\n"));
16253 return p;
16254 }
16255 READ_ULEB (val, p, end);
16256
16257 if (val > 3)
16258 printf ("(%#x), ", val);
16259
16260 switch (val & 3)
16261 {
16262 case 0:
16263 printf (_("unspecified hard/soft float\n"));
16264 break;
16265 case 1:
16266 printf (_("hard float\n"));
16267 break;
16268 case 2:
16269 printf (_("soft float\n"));
16270 break;
16271 }
16272 return p;
16273 }
16274
16275 return display_tag_value (tag & 1, p, end);
16276}
16277
34c8bcba 16278static unsigned char *
f6f0e17b 16279display_power_gnu_attribute (unsigned char * p,
60abdbed 16280 unsigned int tag,
f6f0e17b 16281 const unsigned char * const end)
34c8bcba 16282{
005d79fd 16283 unsigned int val;
34c8bcba
JM
16284
16285 if (tag == Tag_GNU_Power_ABI_FP)
16286 {
34c8bcba 16287 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16288 if (p == end)
005d79fd
AM
16289 {
16290 printf (_("<corrupt>\n"));
16291 return p;
16292 }
cd30bcef 16293 READ_ULEB (val, p, end);
60bca95a 16294
005d79fd
AM
16295 if (val > 15)
16296 printf ("(%#x), ", val);
16297
16298 switch (val & 3)
34c8bcba
JM
16299 {
16300 case 0:
005d79fd 16301 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16302 break;
16303 case 1:
005d79fd 16304 printf (_("hard float, "));
34c8bcba
JM
16305 break;
16306 case 2:
005d79fd 16307 printf (_("soft float, "));
34c8bcba 16308 break;
3c7b9897 16309 case 3:
005d79fd 16310 printf (_("single-precision hard float, "));
3c7b9897 16311 break;
005d79fd
AM
16312 }
16313
16314 switch (val & 0xC)
16315 {
16316 case 0:
16317 printf (_("unspecified long double\n"));
16318 break;
16319 case 4:
16320 printf (_("128-bit IBM long double\n"));
16321 break;
16322 case 8:
16323 printf (_("64-bit long double\n"));
16324 break;
16325 case 12:
16326 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16327 break;
16328 }
16329 return p;
005d79fd 16330 }
34c8bcba 16331
c6e65352
DJ
16332 if (tag == Tag_GNU_Power_ABI_Vector)
16333 {
c6e65352 16334 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 16335 if (p == end)
005d79fd
AM
16336 {
16337 printf (_("<corrupt>\n"));
16338 return p;
16339 }
cd30bcef 16340 READ_ULEB (val, p, end);
005d79fd
AM
16341
16342 if (val > 3)
16343 printf ("(%#x), ", val);
16344
16345 switch (val & 3)
c6e65352
DJ
16346 {
16347 case 0:
005d79fd 16348 printf (_("unspecified\n"));
c6e65352
DJ
16349 break;
16350 case 1:
005d79fd 16351 printf (_("generic\n"));
c6e65352
DJ
16352 break;
16353 case 2:
16354 printf ("AltiVec\n");
16355 break;
16356 case 3:
16357 printf ("SPE\n");
16358 break;
c6e65352
DJ
16359 }
16360 return p;
005d79fd 16361 }
c6e65352 16362
f82e0623
NF
16363 if (tag == Tag_GNU_Power_ABI_Struct_Return)
16364 {
005d79fd 16365 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 16366 if (p == end)
f6f0e17b 16367 {
005d79fd 16368 printf (_("<corrupt>\n"));
f6f0e17b
NC
16369 return p;
16370 }
cd30bcef 16371 READ_ULEB (val, p, end);
0b4362b0 16372
005d79fd
AM
16373 if (val > 2)
16374 printf ("(%#x), ", val);
16375
16376 switch (val & 3)
16377 {
16378 case 0:
16379 printf (_("unspecified\n"));
16380 break;
16381 case 1:
16382 printf ("r3/r4\n");
16383 break;
16384 case 2:
16385 printf (_("memory\n"));
16386 break;
16387 case 3:
16388 printf ("???\n");
16389 break;
16390 }
f82e0623
NF
16391 return p;
16392 }
16393
f6f0e17b 16394 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
16395}
16396
643f7afb
AK
16397static unsigned char *
16398display_s390_gnu_attribute (unsigned char * p,
60abdbed 16399 unsigned int tag,
643f7afb
AK
16400 const unsigned char * const end)
16401{
cd30bcef 16402 unsigned int val;
643f7afb
AK
16403
16404 if (tag == Tag_GNU_S390_ABI_Vector)
16405 {
643f7afb 16406 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 16407 READ_ULEB (val, p, end);
643f7afb
AK
16408
16409 switch (val)
16410 {
16411 case 0:
16412 printf (_("any\n"));
16413 break;
16414 case 1:
16415 printf (_("software\n"));
16416 break;
16417 case 2:
16418 printf (_("hardware\n"));
16419 break;
16420 default:
16421 printf ("??? (%d)\n", val);
16422 break;
16423 }
16424 return p;
16425 }
16426
16427 return display_tag_value (tag & 1, p, end);
16428}
16429
9e8c70f9 16430static void
60abdbed 16431display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
16432{
16433 if (mask)
16434 {
015dc7e1 16435 bool first = true;
071436c6 16436
9e8c70f9 16437 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 16438 fputs ("mul32", stdout), first = false;
9e8c70f9 16439 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 16440 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 16441 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 16442 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 16443 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 16444 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 16445 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 16446 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 16447 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 16448 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 16449 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 16450 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 16451 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 16452 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 16453 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 16454 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 16455 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 16456 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 16457 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 16458 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 16459 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 16460 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 16461 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 16462 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 16463 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 16464 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 16465 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 16466 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 16467 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 16468 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
16469 }
16470 else
071436c6
NC
16471 fputc ('0', stdout);
16472 fputc ('\n', stdout);
9e8c70f9
DM
16473}
16474
3d68f91c 16475static void
60abdbed 16476display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
16477{
16478 if (mask)
16479 {
015dc7e1 16480 bool first = true;
071436c6 16481
3d68f91c 16482 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 16483 fputs ("fjathplus", stdout), first = false;
3d68f91c 16484 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 16485 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 16486 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 16487 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 16488 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 16489 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 16490 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 16491 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 16492 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 16493 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 16494 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 16495 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 16496 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 16497 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 16498 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 16499 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 16500 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 16501 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 16502 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 16503 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
16504 }
16505 else
071436c6
NC
16506 fputc ('0', stdout);
16507 fputc ('\n', stdout);
3d68f91c
JM
16508}
16509
9e8c70f9 16510static unsigned char *
f6f0e17b 16511display_sparc_gnu_attribute (unsigned char * p,
60abdbed 16512 unsigned int tag,
f6f0e17b 16513 const unsigned char * const end)
9e8c70f9 16514{
cd30bcef 16515 unsigned int val;
3d68f91c 16516
9e8c70f9
DM
16517 if (tag == Tag_GNU_Sparc_HWCAPS)
16518 {
cd30bcef 16519 READ_ULEB (val, p, end);
9e8c70f9 16520 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
16521 display_sparc_hwcaps (val);
16522 return p;
3d68f91c
JM
16523 }
16524 if (tag == Tag_GNU_Sparc_HWCAPS2)
16525 {
cd30bcef 16526 READ_ULEB (val, p, end);
3d68f91c
JM
16527 printf (" Tag_GNU_Sparc_HWCAPS2: ");
16528 display_sparc_hwcaps2 (val);
16529 return p;
16530 }
9e8c70f9 16531
f6f0e17b 16532 return display_tag_value (tag, p, end);
9e8c70f9
DM
16533}
16534
351cdf24 16535static void
32ec8896 16536print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
16537{
16538 switch (val)
16539 {
16540 case Val_GNU_MIPS_ABI_FP_ANY:
16541 printf (_("Hard or soft float\n"));
16542 break;
16543 case Val_GNU_MIPS_ABI_FP_DOUBLE:
16544 printf (_("Hard float (double precision)\n"));
16545 break;
16546 case Val_GNU_MIPS_ABI_FP_SINGLE:
16547 printf (_("Hard float (single precision)\n"));
16548 break;
16549 case Val_GNU_MIPS_ABI_FP_SOFT:
16550 printf (_("Soft float\n"));
16551 break;
16552 case Val_GNU_MIPS_ABI_FP_OLD_64:
16553 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
16554 break;
16555 case Val_GNU_MIPS_ABI_FP_XX:
16556 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
16557 break;
16558 case Val_GNU_MIPS_ABI_FP_64:
16559 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
16560 break;
16561 case Val_GNU_MIPS_ABI_FP_64A:
16562 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
16563 break;
3350cc01
CM
16564 case Val_GNU_MIPS_ABI_FP_NAN2008:
16565 printf (_("NaN 2008 compatibility\n"));
16566 break;
351cdf24
MF
16567 default:
16568 printf ("??? (%d)\n", val);
16569 break;
16570 }
16571}
16572
2cf19d5c 16573static unsigned char *
f6f0e17b 16574display_mips_gnu_attribute (unsigned char * p,
60abdbed 16575 unsigned int tag,
f6f0e17b 16576 const unsigned char * const end)
2cf19d5c 16577{
2cf19d5c
JM
16578 if (tag == Tag_GNU_MIPS_ABI_FP)
16579 {
32ec8896 16580 unsigned int val;
f6f0e17b 16581
2cf19d5c 16582 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 16583 READ_ULEB (val, p, end);
351cdf24 16584 print_mips_fp_abi_value (val);
2cf19d5c
JM
16585 return p;
16586 }
16587
a9f58168
CF
16588 if (tag == Tag_GNU_MIPS_ABI_MSA)
16589 {
32ec8896 16590 unsigned int val;
a9f58168 16591
a9f58168 16592 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 16593 READ_ULEB (val, p, end);
a9f58168
CF
16594
16595 switch (val)
16596 {
16597 case Val_GNU_MIPS_ABI_MSA_ANY:
16598 printf (_("Any MSA or not\n"));
16599 break;
16600 case Val_GNU_MIPS_ABI_MSA_128:
16601 printf (_("128-bit MSA\n"));
16602 break;
16603 default:
16604 printf ("??? (%d)\n", val);
16605 break;
16606 }
16607 return p;
16608 }
16609
f6f0e17b 16610 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
16611}
16612
59e6276b 16613static unsigned char *
f6f0e17b
NC
16614display_tic6x_attribute (unsigned char * p,
16615 const unsigned char * const end)
59e6276b 16616{
60abdbed 16617 unsigned int tag;
cd30bcef 16618 unsigned int val;
59e6276b 16619
cd30bcef 16620 READ_ULEB (tag, p, end);
59e6276b
JM
16621
16622 switch (tag)
16623 {
75fa6dc1 16624 case Tag_ISA:
75fa6dc1 16625 printf (" Tag_ISA: ");
cd30bcef 16626 READ_ULEB (val, p, end);
59e6276b
JM
16627
16628 switch (val)
16629 {
75fa6dc1 16630 case C6XABI_Tag_ISA_none:
59e6276b
JM
16631 printf (_("None\n"));
16632 break;
75fa6dc1 16633 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
16634 printf ("C62x\n");
16635 break;
75fa6dc1 16636 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
16637 printf ("C67x\n");
16638 break;
75fa6dc1 16639 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
16640 printf ("C67x+\n");
16641 break;
75fa6dc1 16642 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
16643 printf ("C64x\n");
16644 break;
75fa6dc1 16645 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
16646 printf ("C64x+\n");
16647 break;
75fa6dc1 16648 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
16649 printf ("C674x\n");
16650 break;
16651 default:
16652 printf ("??? (%d)\n", val);
16653 break;
16654 }
16655 return p;
16656
87779176 16657 case Tag_ABI_wchar_t:
87779176 16658 printf (" Tag_ABI_wchar_t: ");
cd30bcef 16659 READ_ULEB (val, p, end);
87779176
JM
16660 switch (val)
16661 {
16662 case 0:
16663 printf (_("Not used\n"));
16664 break;
16665 case 1:
16666 printf (_("2 bytes\n"));
16667 break;
16668 case 2:
16669 printf (_("4 bytes\n"));
16670 break;
16671 default:
16672 printf ("??? (%d)\n", val);
16673 break;
16674 }
16675 return p;
16676
16677 case Tag_ABI_stack_align_needed:
87779176 16678 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 16679 READ_ULEB (val, p, end);
87779176
JM
16680 switch (val)
16681 {
16682 case 0:
16683 printf (_("8-byte\n"));
16684 break;
16685 case 1:
16686 printf (_("16-byte\n"));
16687 break;
16688 default:
16689 printf ("??? (%d)\n", val);
16690 break;
16691 }
16692 return p;
16693
16694 case Tag_ABI_stack_align_preserved:
cd30bcef 16695 READ_ULEB (val, p, end);
87779176
JM
16696 printf (" Tag_ABI_stack_align_preserved: ");
16697 switch (val)
16698 {
16699 case 0:
16700 printf (_("8-byte\n"));
16701 break;
16702 case 1:
16703 printf (_("16-byte\n"));
16704 break;
16705 default:
16706 printf ("??? (%d)\n", val);
16707 break;
16708 }
16709 return p;
16710
b5593623 16711 case Tag_ABI_DSBT:
cd30bcef 16712 READ_ULEB (val, p, end);
b5593623
JM
16713 printf (" Tag_ABI_DSBT: ");
16714 switch (val)
16715 {
16716 case 0:
16717 printf (_("DSBT addressing not used\n"));
16718 break;
16719 case 1:
16720 printf (_("DSBT addressing used\n"));
16721 break;
16722 default:
16723 printf ("??? (%d)\n", val);
16724 break;
16725 }
16726 return p;
16727
87779176 16728 case Tag_ABI_PID:
cd30bcef 16729 READ_ULEB (val, p, end);
87779176
JM
16730 printf (" Tag_ABI_PID: ");
16731 switch (val)
16732 {
16733 case 0:
16734 printf (_("Data addressing position-dependent\n"));
16735 break;
16736 case 1:
16737 printf (_("Data addressing position-independent, GOT near DP\n"));
16738 break;
16739 case 2:
16740 printf (_("Data addressing position-independent, GOT far from DP\n"));
16741 break;
16742 default:
16743 printf ("??? (%d)\n", val);
16744 break;
16745 }
16746 return p;
16747
16748 case Tag_ABI_PIC:
cd30bcef 16749 READ_ULEB (val, p, end);
87779176
JM
16750 printf (" Tag_ABI_PIC: ");
16751 switch (val)
16752 {
16753 case 0:
16754 printf (_("Code addressing position-dependent\n"));
16755 break;
16756 case 1:
16757 printf (_("Code addressing position-independent\n"));
16758 break;
16759 default:
16760 printf ("??? (%d)\n", val);
16761 break;
16762 }
16763 return p;
16764
16765 case Tag_ABI_array_object_alignment:
cd30bcef 16766 READ_ULEB (val, p, end);
87779176
JM
16767 printf (" Tag_ABI_array_object_alignment: ");
16768 switch (val)
16769 {
16770 case 0:
16771 printf (_("8-byte\n"));
16772 break;
16773 case 1:
16774 printf (_("4-byte\n"));
16775 break;
16776 case 2:
16777 printf (_("16-byte\n"));
16778 break;
16779 default:
16780 printf ("??? (%d)\n", val);
16781 break;
16782 }
16783 return p;
16784
16785 case Tag_ABI_array_object_align_expected:
cd30bcef 16786 READ_ULEB (val, p, end);
87779176
JM
16787 printf (" Tag_ABI_array_object_align_expected: ");
16788 switch (val)
16789 {
16790 case 0:
16791 printf (_("8-byte\n"));
16792 break;
16793 case 1:
16794 printf (_("4-byte\n"));
16795 break;
16796 case 2:
16797 printf (_("16-byte\n"));
16798 break;
16799 default:
16800 printf ("??? (%d)\n", val);
16801 break;
16802 }
16803 return p;
16804
3cbd1c06 16805 case Tag_ABI_compatibility:
071436c6 16806 {
cd30bcef 16807 READ_ULEB (val, p, end);
071436c6 16808 printf (" Tag_ABI_compatibility: ");
071436c6 16809 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16810 if (p < end - 1)
16811 {
16812 size_t maxlen = (end - p) - 1;
16813
16814 print_symbol ((int) maxlen, (const char *) p);
16815 p += strnlen ((char *) p, maxlen) + 1;
16816 }
16817 else
16818 {
16819 printf (_("<corrupt>"));
16820 p = (unsigned char *) end;
16821 }
071436c6 16822 putchar ('\n');
071436c6
NC
16823 return p;
16824 }
87779176
JM
16825
16826 case Tag_ABI_conformance:
071436c6 16827 {
4082ef84
NC
16828 printf (" Tag_ABI_conformance: \"");
16829 if (p < end - 1)
16830 {
16831 size_t maxlen = (end - p) - 1;
071436c6 16832
4082ef84
NC
16833 print_symbol ((int) maxlen, (const char *) p);
16834 p += strnlen ((char *) p, maxlen) + 1;
16835 }
16836 else
16837 {
16838 printf (_("<corrupt>"));
16839 p = (unsigned char *) end;
16840 }
071436c6 16841 printf ("\"\n");
071436c6
NC
16842 return p;
16843 }
59e6276b
JM
16844 }
16845
f6f0e17b
NC
16846 return display_tag_value (tag, p, end);
16847}
59e6276b 16848
f6f0e17b 16849static void
60abdbed 16850display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
16851{
16852 unsigned long addr = 0;
16853 size_t bytes = end - p;
16854
feceaa59 16855 assert (end >= p);
f6f0e17b 16856 while (bytes)
87779176 16857 {
f6f0e17b
NC
16858 int j;
16859 int k;
16860 int lbytes = (bytes > 16 ? 16 : bytes);
16861
16862 printf (" 0x%8.8lx ", addr);
16863
16864 for (j = 0; j < 16; j++)
16865 {
16866 if (j < lbytes)
16867 printf ("%2.2x", p[j]);
16868 else
16869 printf (" ");
16870
16871 if ((j & 3) == 3)
16872 printf (" ");
16873 }
16874
16875 for (j = 0; j < lbytes; j++)
16876 {
16877 k = p[j];
16878 if (k >= ' ' && k < 0x7f)
16879 printf ("%c", k);
16880 else
16881 printf (".");
16882 }
16883
16884 putchar ('\n');
16885
16886 p += lbytes;
16887 bytes -= lbytes;
16888 addr += lbytes;
87779176 16889 }
59e6276b 16890
f6f0e17b 16891 putchar ('\n');
59e6276b
JM
16892}
16893
13761a11 16894static unsigned char *
b0191216 16895display_msp430_attribute (unsigned char * p,
13761a11
NC
16896 const unsigned char * const end)
16897{
60abdbed
NC
16898 unsigned int val;
16899 unsigned int tag;
13761a11 16900
cd30bcef 16901 READ_ULEB (tag, p, end);
0b4362b0 16902
13761a11
NC
16903 switch (tag)
16904 {
16905 case OFBA_MSPABI_Tag_ISA:
13761a11 16906 printf (" Tag_ISA: ");
cd30bcef 16907 READ_ULEB (val, p, end);
13761a11
NC
16908 switch (val)
16909 {
16910 case 0: printf (_("None\n")); break;
16911 case 1: printf (_("MSP430\n")); break;
16912 case 2: printf (_("MSP430X\n")); break;
16913 default: printf ("??? (%d)\n", val); break;
16914 }
16915 break;
16916
16917 case OFBA_MSPABI_Tag_Code_Model:
13761a11 16918 printf (" Tag_Code_Model: ");
cd30bcef 16919 READ_ULEB (val, p, end);
13761a11
NC
16920 switch (val)
16921 {
16922 case 0: printf (_("None\n")); break;
16923 case 1: printf (_("Small\n")); break;
16924 case 2: printf (_("Large\n")); break;
16925 default: printf ("??? (%d)\n", val); break;
16926 }
16927 break;
16928
16929 case OFBA_MSPABI_Tag_Data_Model:
13761a11 16930 printf (" Tag_Data_Model: ");
cd30bcef 16931 READ_ULEB (val, p, end);
13761a11
NC
16932 switch (val)
16933 {
16934 case 0: printf (_("None\n")); break;
16935 case 1: printf (_("Small\n")); break;
16936 case 2: printf (_("Large\n")); break;
16937 case 3: printf (_("Restricted Large\n")); break;
16938 default: printf ("??? (%d)\n", val); break;
16939 }
16940 break;
16941
16942 default:
16943 printf (_(" <unknown tag %d>: "), tag);
16944
16945 if (tag & 1)
16946 {
071436c6 16947 putchar ('"');
4082ef84
NC
16948 if (p < end - 1)
16949 {
16950 size_t maxlen = (end - p) - 1;
16951
16952 print_symbol ((int) maxlen, (const char *) p);
16953 p += strnlen ((char *) p, maxlen) + 1;
16954 }
16955 else
16956 {
16957 printf (_("<corrupt>"));
16958 p = (unsigned char *) end;
16959 }
071436c6 16960 printf ("\"\n");
13761a11
NC
16961 }
16962 else
16963 {
cd30bcef 16964 READ_ULEB (val, p, end);
13761a11
NC
16965 printf ("%d (0x%x)\n", val, val);
16966 }
16967 break;
16968 }
16969
4082ef84 16970 assert (p <= end);
13761a11
NC
16971 return p;
16972}
16973
c0ea7c52
JL
16974static unsigned char *
16975display_msp430_gnu_attribute (unsigned char * p,
16976 unsigned int tag,
16977 const unsigned char * const end)
16978{
16979 if (tag == Tag_GNU_MSP430_Data_Region)
16980 {
cd30bcef 16981 unsigned int val;
c0ea7c52 16982
c0ea7c52 16983 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 16984 READ_ULEB (val, p, end);
c0ea7c52
JL
16985
16986 switch (val)
16987 {
16988 case Val_GNU_MSP430_Data_Region_Any:
16989 printf (_("Any Region\n"));
16990 break;
16991 case Val_GNU_MSP430_Data_Region_Lower:
16992 printf (_("Lower Region Only\n"));
16993 break;
16994 default:
cd30bcef 16995 printf ("??? (%u)\n", val);
c0ea7c52
JL
16996 }
16997 return p;
16998 }
16999 return display_tag_value (tag & 1, p, end);
17000}
17001
2dc8dd17
JW
17002struct riscv_attr_tag_t {
17003 const char *name;
cd30bcef 17004 unsigned int tag;
2dc8dd17
JW
17005};
17006
17007static struct riscv_attr_tag_t riscv_attr_tag[] =
17008{
17009#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17010 T(arch),
17011 T(priv_spec),
17012 T(priv_spec_minor),
17013 T(priv_spec_revision),
17014 T(unaligned_access),
17015 T(stack_align),
17016#undef T
17017};
17018
17019static unsigned char *
17020display_riscv_attribute (unsigned char *p,
17021 const unsigned char * const end)
17022{
cd30bcef
AM
17023 unsigned int val;
17024 unsigned int tag;
2dc8dd17
JW
17025 struct riscv_attr_tag_t *attr = NULL;
17026 unsigned i;
17027
cd30bcef 17028 READ_ULEB (tag, p, end);
2dc8dd17
JW
17029
17030 /* Find the name of attribute. */
17031 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17032 {
17033 if (riscv_attr_tag[i].tag == tag)
17034 {
17035 attr = &riscv_attr_tag[i];
17036 break;
17037 }
17038 }
17039
17040 if (attr)
17041 printf (" %s: ", attr->name);
17042 else
17043 return display_tag_value (tag, p, end);
17044
17045 switch (tag)
17046 {
17047 case Tag_RISCV_priv_spec:
17048 case Tag_RISCV_priv_spec_minor:
17049 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17050 READ_ULEB (val, p, end);
17051 printf (_("%u\n"), val);
2dc8dd17
JW
17052 break;
17053 case Tag_RISCV_unaligned_access:
cd30bcef 17054 READ_ULEB (val, p, end);
2dc8dd17
JW
17055 switch (val)
17056 {
17057 case 0:
17058 printf (_("No unaligned access\n"));
17059 break;
17060 case 1:
17061 printf (_("Unaligned access\n"));
17062 break;
17063 }
17064 break;
17065 case Tag_RISCV_stack_align:
cd30bcef
AM
17066 READ_ULEB (val, p, end);
17067 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17068 break;
17069 case Tag_RISCV_arch:
17070 p = display_tag_value (-1, p, end);
17071 break;
17072 default:
17073 return display_tag_value (tag, p, end);
17074 }
17075
17076 return p;
17077}
17078
0861f561
CQ
17079static unsigned char *
17080display_csky_attribute (unsigned char * p,
17081 const unsigned char * const end)
17082{
17083 unsigned int tag;
17084 unsigned int val;
17085 READ_ULEB (tag, p, end);
17086
17087 if (tag >= Tag_CSKY_MAX)
17088 {
17089 return display_tag_value (-1, p, end);
17090 }
17091
17092 switch (tag)
17093 {
17094 case Tag_CSKY_ARCH_NAME:
17095 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17096 return display_tag_value (-1, p, end);
17097 case Tag_CSKY_CPU_NAME:
17098 printf (" Tag_CSKY_CPU_NAME:\t\t");
17099 return display_tag_value (-1, p, end);
17100
17101 case Tag_CSKY_ISA_FLAGS:
17102 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17103 return display_tag_value (0, p, end);
17104 case Tag_CSKY_ISA_EXT_FLAGS:
17105 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17106 return display_tag_value (0, p, end);
17107
17108 case Tag_CSKY_DSP_VERSION:
17109 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17110 READ_ULEB (val, p, end);
17111 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17112 printf ("DSP Extension\n");
17113 else if (val == VAL_CSKY_DSP_VERSION_2)
17114 printf ("DSP 2.0\n");
17115 break;
17116
17117 case Tag_CSKY_VDSP_VERSION:
17118 printf (" Tag_CSKY_VDSP_VERSION:\t");
17119 READ_ULEB (val, p, end);
17120 printf ("VDSP Version %d\n", val);
17121 break;
17122
17123 case Tag_CSKY_FPU_VERSION:
17124 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17125 READ_ULEB (val, p, end);
17126 if (val == VAL_CSKY_FPU_VERSION_1)
17127 printf ("ABIV1 FPU Version 1\n");
17128 else if (val == VAL_CSKY_FPU_VERSION_2)
17129 printf ("FPU Version 2\n");
17130 break;
17131
17132 case Tag_CSKY_FPU_ABI:
17133 printf (" Tag_CSKY_FPU_ABI:\t\t");
17134 READ_ULEB (val, p, end);
17135 if (val == VAL_CSKY_FPU_ABI_HARD)
17136 printf ("Hard\n");
17137 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17138 printf ("SoftFP\n");
17139 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17140 printf ("Soft\n");
17141 break;
17142 case Tag_CSKY_FPU_ROUNDING:
17143 READ_ULEB (val, p, end);
17144 if (val == 1) {
17145 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17146 printf ("Needed\n");
17147 }
17148 break;
17149 case Tag_CSKY_FPU_DENORMAL:
17150 READ_ULEB (val, p, end);
17151 if (val == 1) {
17152 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17153 printf ("Needed\n");
17154 }
17155 break;
17156 case Tag_CSKY_FPU_Exception:
17157 READ_ULEB (val, p, end);
17158 if (val == 1) {
17159 printf (" Tag_CSKY_FPU_Exception:\t");
17160 printf ("Needed\n");
17161 }
17162 break;
17163 case Tag_CSKY_FPU_NUMBER_MODULE:
17164 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17165 return display_tag_value (-1, p, end);
17166 case Tag_CSKY_FPU_HARDFP:
17167 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17168 READ_ULEB (val, p, end);
17169 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17170 printf (" Half");
17171 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17172 printf (" Single");
17173 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17174 printf (" Double");
17175 printf ("\n");
17176 break;
17177 default:
17178 return display_tag_value (tag, p, end);
17179 }
17180 return p;
17181}
17182
015dc7e1 17183static bool
dda8d76d 17184process_attributes (Filedata * filedata,
60bca95a 17185 const char * public_name,
104d59d1 17186 unsigned int proc_type,
f6f0e17b 17187 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17188 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17189{
2cf0635d 17190 Elf_Internal_Shdr * sect;
11c1ff18 17191 unsigned i;
015dc7e1 17192 bool res = true;
11c1ff18
PB
17193
17194 /* Find the section header so that we get the size. */
dda8d76d
NC
17195 for (i = 0, sect = filedata->section_headers;
17196 i < filedata->file_header.e_shnum;
11c1ff18
PB
17197 i++, sect++)
17198 {
071436c6
NC
17199 unsigned char * contents;
17200 unsigned char * p;
17201
104d59d1 17202 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17203 continue;
17204
dda8d76d 17205 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17206 sect->sh_size, _("attributes"));
60bca95a 17207 if (contents == NULL)
32ec8896 17208 {
015dc7e1 17209 res = false;
32ec8896
NC
17210 continue;
17211 }
60bca95a 17212
11c1ff18 17213 p = contents;
60abdbed
NC
17214 /* The first character is the version of the attributes.
17215 Currently only version 1, (aka 'A') is recognised here. */
17216 if (*p != 'A')
32ec8896
NC
17217 {
17218 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17219 res = false;
32ec8896 17220 }
60abdbed 17221 else
11c1ff18 17222 {
071436c6
NC
17223 bfd_vma section_len;
17224
17225 section_len = sect->sh_size - 1;
11c1ff18 17226 p++;
60bca95a 17227
071436c6 17228 while (section_len > 0)
11c1ff18 17229 {
071436c6 17230 bfd_vma attr_len;
e9847026 17231 unsigned int namelen;
015dc7e1
AM
17232 bool public_section;
17233 bool gnu_section;
11c1ff18 17234
071436c6 17235 if (section_len <= 4)
e0a31db1
NC
17236 {
17237 error (_("Tag section ends prematurely\n"));
015dc7e1 17238 res = false;
e0a31db1
NC
17239 break;
17240 }
071436c6 17241 attr_len = byte_get (p, 4);
11c1ff18 17242 p += 4;
60bca95a 17243
071436c6 17244 if (attr_len > section_len)
11c1ff18 17245 {
071436c6
NC
17246 error (_("Bad attribute length (%u > %u)\n"),
17247 (unsigned) attr_len, (unsigned) section_len);
17248 attr_len = section_len;
015dc7e1 17249 res = false;
11c1ff18 17250 }
74e1a04b 17251 /* PR 17531: file: 001-101425-0.004 */
071436c6 17252 else if (attr_len < 5)
74e1a04b 17253 {
071436c6 17254 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17255 res = false;
74e1a04b
NC
17256 break;
17257 }
e9847026 17258
071436c6
NC
17259 section_len -= attr_len;
17260 attr_len -= 4;
17261
17262 namelen = strnlen ((char *) p, attr_len) + 1;
17263 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17264 {
17265 error (_("Corrupt attribute section name\n"));
015dc7e1 17266 res = false;
e9847026
NC
17267 break;
17268 }
17269
071436c6
NC
17270 printf (_("Attribute Section: "));
17271 print_symbol (INT_MAX, (const char *) p);
17272 putchar ('\n');
60bca95a
NC
17273
17274 if (public_name && streq ((char *) p, public_name))
015dc7e1 17275 public_section = true;
11c1ff18 17276 else
015dc7e1 17277 public_section = false;
60bca95a
NC
17278
17279 if (streq ((char *) p, "gnu"))
015dc7e1 17280 gnu_section = true;
104d59d1 17281 else
015dc7e1 17282 gnu_section = false;
60bca95a 17283
11c1ff18 17284 p += namelen;
071436c6 17285 attr_len -= namelen;
e0a31db1 17286
071436c6 17287 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17288 {
e0a31db1 17289 int tag;
cd30bcef 17290 unsigned int val;
11c1ff18 17291 bfd_vma size;
071436c6 17292 unsigned char * end;
60bca95a 17293
e0a31db1 17294 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17295 if (attr_len < 6)
e0a31db1
NC
17296 {
17297 error (_("Unused bytes at end of section\n"));
015dc7e1 17298 res = false;
e0a31db1
NC
17299 section_len = 0;
17300 break;
17301 }
17302
17303 tag = *(p++);
11c1ff18 17304 size = byte_get (p, 4);
071436c6 17305 if (size > attr_len)
11c1ff18 17306 {
e9847026 17307 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17308 (unsigned) size, (unsigned) attr_len);
015dc7e1 17309 res = false;
071436c6 17310 size = attr_len;
11c1ff18 17311 }
e0a31db1
NC
17312 /* PR binutils/17531: Safe handling of corrupt files. */
17313 if (size < 6)
17314 {
17315 error (_("Bad subsection length (%u < 6)\n"),
17316 (unsigned) size);
015dc7e1 17317 res = false;
e0a31db1
NC
17318 section_len = 0;
17319 break;
17320 }
60bca95a 17321
071436c6 17322 attr_len -= size;
11c1ff18 17323 end = p + size - 1;
071436c6 17324 assert (end <= contents + sect->sh_size);
11c1ff18 17325 p += 4;
60bca95a 17326
11c1ff18
PB
17327 switch (tag)
17328 {
17329 case 1:
2b692964 17330 printf (_("File Attributes\n"));
11c1ff18
PB
17331 break;
17332 case 2:
2b692964 17333 printf (_("Section Attributes:"));
11c1ff18
PB
17334 goto do_numlist;
17335 case 3:
2b692964 17336 printf (_("Symbol Attributes:"));
1a0670f3 17337 /* Fall through. */
11c1ff18
PB
17338 do_numlist:
17339 for (;;)
17340 {
cd30bcef 17341 READ_ULEB (val, p, end);
11c1ff18
PB
17342 if (val == 0)
17343 break;
17344 printf (" %d", val);
17345 }
17346 printf ("\n");
17347 break;
17348 default:
2b692964 17349 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 17350 public_section = false;
11c1ff18
PB
17351 break;
17352 }
60bca95a 17353
071436c6 17354 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
17355 {
17356 while (p < end)
f6f0e17b 17357 p = display_pub_attribute (p, end);
60abdbed 17358 assert (p == end);
104d59d1 17359 }
071436c6 17360 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
17361 {
17362 while (p < end)
17363 p = display_gnu_attribute (p,
f6f0e17b
NC
17364 display_proc_gnu_attribute,
17365 end);
60abdbed 17366 assert (p == end);
11c1ff18 17367 }
071436c6 17368 else if (p < end)
11c1ff18 17369 {
071436c6 17370 printf (_(" Unknown attribute:\n"));
f6f0e17b 17371 display_raw_attribute (p, end);
11c1ff18
PB
17372 p = end;
17373 }
071436c6
NC
17374 else
17375 attr_len = 0;
11c1ff18
PB
17376 }
17377 }
17378 }
d70c5fc7 17379
60bca95a 17380 free (contents);
11c1ff18 17381 }
32ec8896
NC
17382
17383 return res;
11c1ff18
PB
17384}
17385
ccb4c951
RS
17386/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
17387 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
17388 and return the VMA of the next entry, or -1 if there was a problem.
17389 Does not read from DATA_END or beyond. */
ccb4c951
RS
17390
17391static bfd_vma
82b1b41b
NC
17392print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
17393 unsigned char * data_end)
ccb4c951
RS
17394{
17395 printf (" ");
17396 print_vma (addr, LONG_HEX);
17397 printf (" ");
17398 if (addr < pltgot + 0xfff0)
17399 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
17400 else
17401 printf ("%10s", "");
17402 printf (" ");
17403 if (data == NULL)
2b692964 17404 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
17405 else
17406 {
17407 bfd_vma entry;
82b1b41b 17408 unsigned char * from = data + addr - pltgot;
ccb4c951 17409
82b1b41b
NC
17410 if (from + (is_32bit_elf ? 4 : 8) > data_end)
17411 {
17412 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
17413 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
17414 return (bfd_vma) -1;
17415 }
17416 else
17417 {
17418 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17419 print_vma (entry, LONG_HEX);
17420 }
ccb4c951
RS
17421 }
17422 return addr + (is_32bit_elf ? 4 : 8);
17423}
17424
861fb55a
DJ
17425/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
17426 PLTGOT. Print the Address and Initial fields of an entry at VMA
17427 ADDR and return the VMA of the next entry. */
17428
17429static bfd_vma
2cf0635d 17430print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
17431{
17432 printf (" ");
17433 print_vma (addr, LONG_HEX);
17434 printf (" ");
17435 if (data == NULL)
2b692964 17436 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
17437 else
17438 {
17439 bfd_vma entry;
17440
17441 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17442 print_vma (entry, LONG_HEX);
17443 }
17444 return addr + (is_32bit_elf ? 4 : 8);
17445}
17446
351cdf24
MF
17447static void
17448print_mips_ases (unsigned int mask)
17449{
17450 if (mask & AFL_ASE_DSP)
17451 fputs ("\n\tDSP ASE", stdout);
17452 if (mask & AFL_ASE_DSPR2)
17453 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
17454 if (mask & AFL_ASE_DSPR3)
17455 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
17456 if (mask & AFL_ASE_EVA)
17457 fputs ("\n\tEnhanced VA Scheme", stdout);
17458 if (mask & AFL_ASE_MCU)
17459 fputs ("\n\tMCU (MicroController) ASE", stdout);
17460 if (mask & AFL_ASE_MDMX)
17461 fputs ("\n\tMDMX ASE", stdout);
17462 if (mask & AFL_ASE_MIPS3D)
17463 fputs ("\n\tMIPS-3D ASE", stdout);
17464 if (mask & AFL_ASE_MT)
17465 fputs ("\n\tMT ASE", stdout);
17466 if (mask & AFL_ASE_SMARTMIPS)
17467 fputs ("\n\tSmartMIPS ASE", stdout);
17468 if (mask & AFL_ASE_VIRT)
17469 fputs ("\n\tVZ ASE", stdout);
17470 if (mask & AFL_ASE_MSA)
17471 fputs ("\n\tMSA ASE", stdout);
17472 if (mask & AFL_ASE_MIPS16)
17473 fputs ("\n\tMIPS16 ASE", stdout);
17474 if (mask & AFL_ASE_MICROMIPS)
17475 fputs ("\n\tMICROMIPS ASE", stdout);
17476 if (mask & AFL_ASE_XPA)
17477 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
17478 if (mask & AFL_ASE_MIPS16E2)
17479 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
17480 if (mask & AFL_ASE_CRC)
17481 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
17482 if (mask & AFL_ASE_GINV)
17483 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
17484 if (mask & AFL_ASE_LOONGSON_MMI)
17485 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
17486 if (mask & AFL_ASE_LOONGSON_CAM)
17487 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
17488 if (mask & AFL_ASE_LOONGSON_EXT)
17489 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
17490 if (mask & AFL_ASE_LOONGSON_EXT2)
17491 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
17492 if (mask == 0)
17493 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
17494 else if ((mask & ~AFL_ASE_MASK) != 0)
17495 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
17496}
17497
17498static void
17499print_mips_isa_ext (unsigned int isa_ext)
17500{
17501 switch (isa_ext)
17502 {
17503 case 0:
17504 fputs (_("None"), stdout);
17505 break;
17506 case AFL_EXT_XLR:
17507 fputs ("RMI XLR", stdout);
17508 break;
2c629856
N
17509 case AFL_EXT_OCTEON3:
17510 fputs ("Cavium Networks Octeon3", stdout);
17511 break;
351cdf24
MF
17512 case AFL_EXT_OCTEON2:
17513 fputs ("Cavium Networks Octeon2", stdout);
17514 break;
17515 case AFL_EXT_OCTEONP:
17516 fputs ("Cavium Networks OcteonP", stdout);
17517 break;
351cdf24
MF
17518 case AFL_EXT_OCTEON:
17519 fputs ("Cavium Networks Octeon", stdout);
17520 break;
17521 case AFL_EXT_5900:
17522 fputs ("Toshiba R5900", stdout);
17523 break;
17524 case AFL_EXT_4650:
17525 fputs ("MIPS R4650", stdout);
17526 break;
17527 case AFL_EXT_4010:
17528 fputs ("LSI R4010", stdout);
17529 break;
17530 case AFL_EXT_4100:
17531 fputs ("NEC VR4100", stdout);
17532 break;
17533 case AFL_EXT_3900:
17534 fputs ("Toshiba R3900", stdout);
17535 break;
17536 case AFL_EXT_10000:
17537 fputs ("MIPS R10000", stdout);
17538 break;
17539 case AFL_EXT_SB1:
17540 fputs ("Broadcom SB-1", stdout);
17541 break;
17542 case AFL_EXT_4111:
17543 fputs ("NEC VR4111/VR4181", stdout);
17544 break;
17545 case AFL_EXT_4120:
17546 fputs ("NEC VR4120", stdout);
17547 break;
17548 case AFL_EXT_5400:
17549 fputs ("NEC VR5400", stdout);
17550 break;
17551 case AFL_EXT_5500:
17552 fputs ("NEC VR5500", stdout);
17553 break;
17554 case AFL_EXT_LOONGSON_2E:
17555 fputs ("ST Microelectronics Loongson 2E", stdout);
17556 break;
17557 case AFL_EXT_LOONGSON_2F:
17558 fputs ("ST Microelectronics Loongson 2F", stdout);
17559 break;
38bf472a
MR
17560 case AFL_EXT_INTERAPTIV_MR2:
17561 fputs ("Imagination interAptiv MR2", stdout);
17562 break;
351cdf24 17563 default:
00ac7aa0 17564 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
17565 }
17566}
17567
32ec8896 17568static signed int
351cdf24
MF
17569get_mips_reg_size (int reg_size)
17570{
17571 return (reg_size == AFL_REG_NONE) ? 0
17572 : (reg_size == AFL_REG_32) ? 32
17573 : (reg_size == AFL_REG_64) ? 64
17574 : (reg_size == AFL_REG_128) ? 128
17575 : -1;
17576}
17577
015dc7e1 17578static bool
dda8d76d 17579process_mips_specific (Filedata * filedata)
5b18a4bc 17580{
2cf0635d 17581 Elf_Internal_Dyn * entry;
351cdf24 17582 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
17583 size_t liblist_offset = 0;
17584 size_t liblistno = 0;
17585 size_t conflictsno = 0;
17586 size_t options_offset = 0;
17587 size_t conflicts_offset = 0;
861fb55a
DJ
17588 size_t pltrelsz = 0;
17589 size_t pltrel = 0;
ccb4c951 17590 bfd_vma pltgot = 0;
861fb55a
DJ
17591 bfd_vma mips_pltgot = 0;
17592 bfd_vma jmprel = 0;
ccb4c951
RS
17593 bfd_vma local_gotno = 0;
17594 bfd_vma gotsym = 0;
17595 bfd_vma symtabno = 0;
015dc7e1 17596 bool res = true;
103f02d3 17597
dda8d76d 17598 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 17599 display_mips_gnu_attribute))
015dc7e1 17600 res = false;
2cf19d5c 17601
dda8d76d 17602 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
17603
17604 if (sect != NULL)
17605 {
17606 Elf_External_ABIFlags_v0 *abiflags_ext;
17607 Elf_Internal_ABIFlags_v0 abiflags_in;
17608
17609 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
17610 {
17611 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 17612 res = false;
32ec8896 17613 }
351cdf24
MF
17614 else
17615 {
dda8d76d 17616 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
17617 sect->sh_size, _("MIPS ABI Flags section"));
17618 if (abiflags_ext)
17619 {
17620 abiflags_in.version = BYTE_GET (abiflags_ext->version);
17621 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
17622 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
17623 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
17624 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
17625 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
17626 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
17627 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
17628 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
17629 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
17630 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
17631
17632 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
17633 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
17634 if (abiflags_in.isa_rev > 1)
17635 printf ("r%d", abiflags_in.isa_rev);
17636 printf ("\nGPR size: %d",
17637 get_mips_reg_size (abiflags_in.gpr_size));
17638 printf ("\nCPR1 size: %d",
17639 get_mips_reg_size (abiflags_in.cpr1_size));
17640 printf ("\nCPR2 size: %d",
17641 get_mips_reg_size (abiflags_in.cpr2_size));
17642 fputs ("\nFP ABI: ", stdout);
17643 print_mips_fp_abi_value (abiflags_in.fp_abi);
17644 fputs ("ISA Extension: ", stdout);
17645 print_mips_isa_ext (abiflags_in.isa_ext);
17646 fputs ("\nASEs:", stdout);
17647 print_mips_ases (abiflags_in.ases);
17648 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
17649 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
17650 fputc ('\n', stdout);
17651 free (abiflags_ext);
17652 }
17653 }
17654 }
17655
19e6b90e 17656 /* We have a lot of special sections. Thanks SGI! */
978c4450 17657 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
17658 {
17659 /* No dynamic information available. See if there is static GOT. */
dda8d76d 17660 sect = find_section (filedata, ".got");
bbdd9a68
MR
17661 if (sect != NULL)
17662 {
17663 unsigned char *data_end;
17664 unsigned char *data;
17665 bfd_vma ent, end;
17666 int addr_size;
17667
17668 pltgot = sect->sh_addr;
17669
17670 ent = pltgot;
17671 addr_size = (is_32bit_elf ? 4 : 8);
17672 end = pltgot + sect->sh_size;
17673
dda8d76d 17674 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
17675 end - pltgot, 1,
17676 _("Global Offset Table data"));
17677 /* PR 12855: Null data is handled gracefully throughout. */
17678 data_end = data + (end - pltgot);
17679
17680 printf (_("\nStatic GOT:\n"));
17681 printf (_(" Canonical gp value: "));
17682 print_vma (ent + 0x7ff0, LONG_HEX);
17683 printf ("\n\n");
17684
17685 /* In a dynamic binary GOT[0] is reserved for the dynamic
17686 loader to store the lazy resolver pointer, however in
17687 a static binary it may well have been omitted and GOT
17688 reduced to a table of addresses.
17689 PR 21344: Check for the entry being fully available
17690 before fetching it. */
17691 if (data
17692 && data + ent - pltgot + addr_size <= data_end
17693 && byte_get (data + ent - pltgot, addr_size) == 0)
17694 {
17695 printf (_(" Reserved entries:\n"));
17696 printf (_(" %*s %10s %*s\n"),
17697 addr_size * 2, _("Address"), _("Access"),
17698 addr_size * 2, _("Value"));
17699 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17700 printf ("\n");
17701 if (ent == (bfd_vma) -1)
17702 goto sgot_print_fail;
17703
17704 /* Check for the MSB of GOT[1] being set, identifying a
17705 GNU object. This entry will be used by some runtime
17706 loaders, to store the module pointer. Otherwise this
17707 is an ordinary local entry.
17708 PR 21344: Check for the entry being fully available
17709 before fetching it. */
17710 if (data
17711 && data + ent - pltgot + addr_size <= data_end
17712 && (byte_get (data + ent - pltgot, addr_size)
17713 >> (addr_size * 8 - 1)) != 0)
17714 {
17715 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17716 printf ("\n");
17717 if (ent == (bfd_vma) -1)
17718 goto sgot_print_fail;
17719 }
17720 printf ("\n");
17721 }
17722
f17e9d8a 17723 if (data != NULL && ent < end)
bbdd9a68
MR
17724 {
17725 printf (_(" Local entries:\n"));
17726 printf (" %*s %10s %*s\n",
17727 addr_size * 2, _("Address"), _("Access"),
17728 addr_size * 2, _("Value"));
17729 while (ent < end)
17730 {
17731 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17732 printf ("\n");
17733 if (ent == (bfd_vma) -1)
17734 goto sgot_print_fail;
17735 }
17736 printf ("\n");
17737 }
17738
17739 sgot_print_fail:
9db70fc3 17740 free (data);
bbdd9a68
MR
17741 }
17742 return res;
17743 }
252b5132 17744
978c4450 17745 for (entry = filedata->dynamic_section;
071436c6 17746 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
17747 (entry < filedata->dynamic_section + filedata->dynamic_nent
17748 && entry->d_tag != DT_NULL);
071436c6 17749 ++entry)
252b5132
RH
17750 switch (entry->d_tag)
17751 {
17752 case DT_MIPS_LIBLIST:
d93f0186 17753 liblist_offset
dda8d76d 17754 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17755 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
17756 break;
17757 case DT_MIPS_LIBLISTNO:
17758 liblistno = entry->d_un.d_val;
17759 break;
17760 case DT_MIPS_OPTIONS:
dda8d76d 17761 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
17762 break;
17763 case DT_MIPS_CONFLICT:
d93f0186 17764 conflicts_offset
dda8d76d 17765 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17766 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
17767 break;
17768 case DT_MIPS_CONFLICTNO:
17769 conflictsno = entry->d_un.d_val;
17770 break;
ccb4c951 17771 case DT_PLTGOT:
861fb55a
DJ
17772 pltgot = entry->d_un.d_ptr;
17773 break;
ccb4c951
RS
17774 case DT_MIPS_LOCAL_GOTNO:
17775 local_gotno = entry->d_un.d_val;
17776 break;
17777 case DT_MIPS_GOTSYM:
17778 gotsym = entry->d_un.d_val;
17779 break;
17780 case DT_MIPS_SYMTABNO:
17781 symtabno = entry->d_un.d_val;
17782 break;
861fb55a
DJ
17783 case DT_MIPS_PLTGOT:
17784 mips_pltgot = entry->d_un.d_ptr;
17785 break;
17786 case DT_PLTREL:
17787 pltrel = entry->d_un.d_val;
17788 break;
17789 case DT_PLTRELSZ:
17790 pltrelsz = entry->d_un.d_val;
17791 break;
17792 case DT_JMPREL:
17793 jmprel = entry->d_un.d_ptr;
17794 break;
252b5132
RH
17795 default:
17796 break;
17797 }
17798
17799 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
17800 {
2cf0635d 17801 Elf32_External_Lib * elib;
252b5132
RH
17802 size_t cnt;
17803
dda8d76d 17804 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
17805 sizeof (Elf32_External_Lib),
17806 liblistno,
17807 _("liblist section data"));
a6e9f9df 17808 if (elib)
252b5132 17809 {
d3a49aa8
AM
17810 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
17811 "\nSection '.liblist' contains %lu entries:\n",
17812 (unsigned long) liblistno),
a6e9f9df 17813 (unsigned long) liblistno);
2b692964 17814 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
17815 stdout);
17816
17817 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 17818 {
a6e9f9df 17819 Elf32_Lib liblist;
91d6fa6a 17820 time_t atime;
d5b07ef4 17821 char timebuf[128];
2cf0635d 17822 struct tm * tmp;
a6e9f9df
AM
17823
17824 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17825 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
17826 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17827 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17828 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17829
91d6fa6a 17830 tmp = gmtime (&atime);
e9e44622
JJ
17831 snprintf (timebuf, sizeof (timebuf),
17832 "%04u-%02u-%02uT%02u:%02u:%02u",
17833 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17834 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 17835
31104126 17836 printf ("%3lu: ", (unsigned long) cnt);
978c4450
AM
17837 if (VALID_DYNAMIC_NAME (filedata, liblist.l_name))
17838 print_symbol (20, GET_DYNAMIC_NAME (filedata, liblist.l_name));
d79b3d50 17839 else
2b692964 17840 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
17841 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
17842 liblist.l_version);
a6e9f9df
AM
17843
17844 if (liblist.l_flags == 0)
2b692964 17845 puts (_(" NONE"));
a6e9f9df
AM
17846 else
17847 {
17848 static const struct
252b5132 17849 {
2cf0635d 17850 const char * name;
a6e9f9df 17851 int bit;
252b5132 17852 }
a6e9f9df
AM
17853 l_flags_vals[] =
17854 {
17855 { " EXACT_MATCH", LL_EXACT_MATCH },
17856 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
17857 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
17858 { " EXPORTS", LL_EXPORTS },
17859 { " DELAY_LOAD", LL_DELAY_LOAD },
17860 { " DELTA", LL_DELTA }
17861 };
17862 int flags = liblist.l_flags;
17863 size_t fcnt;
17864
60bca95a 17865 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
17866 if ((flags & l_flags_vals[fcnt].bit) != 0)
17867 {
17868 fputs (l_flags_vals[fcnt].name, stdout);
17869 flags ^= l_flags_vals[fcnt].bit;
17870 }
17871 if (flags != 0)
17872 printf (" %#x", (unsigned int) flags);
252b5132 17873
a6e9f9df
AM
17874 puts ("");
17875 }
252b5132 17876 }
252b5132 17877
a6e9f9df
AM
17878 free (elib);
17879 }
32ec8896 17880 else
015dc7e1 17881 res = false;
252b5132
RH
17882 }
17883
17884 if (options_offset != 0)
17885 {
2cf0635d 17886 Elf_External_Options * eopt;
252b5132
RH
17887 size_t offset;
17888 int cnt;
dda8d76d 17889 sect = filedata->section_headers;
252b5132
RH
17890
17891 /* Find the section header so that we get the size. */
dda8d76d 17892 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 17893 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
17894 if (sect == NULL)
17895 {
17896 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 17897 return false;
071436c6 17898 }
7fc0c668
NC
17899 /* PR 24243 */
17900 if (sect->sh_size < sizeof (* eopt))
17901 {
17902 error (_("The MIPS options section is too small.\n"));
015dc7e1 17903 return false;
7fc0c668 17904 }
252b5132 17905
dda8d76d 17906 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 17907 sect->sh_size, _("options"));
a6e9f9df 17908 if (eopt)
252b5132 17909 {
fd17d1e6 17910 Elf_Internal_Options option;
76da6bbe 17911
a6e9f9df 17912 offset = cnt = 0;
82b1b41b 17913 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 17914 {
2cf0635d 17915 Elf_External_Options * eoption;
fd17d1e6 17916 unsigned int optsize;
252b5132 17917
a6e9f9df 17918 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 17919
fd17d1e6 17920 optsize = BYTE_GET (eoption->size);
76da6bbe 17921
82b1b41b 17922 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
17923 if (optsize < sizeof (* eopt)
17924 || optsize > sect->sh_size - offset)
82b1b41b 17925 {
645f43a8 17926 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 17927 optsize);
645f43a8 17928 free (eopt);
015dc7e1 17929 return false;
82b1b41b 17930 }
fd17d1e6 17931 offset += optsize;
a6e9f9df
AM
17932 ++cnt;
17933 }
252b5132 17934
d3a49aa8
AM
17935 printf (ngettext ("\nSection '%s' contains %d entry:\n",
17936 "\nSection '%s' contains %d entries:\n",
17937 cnt),
dda8d76d 17938 printable_section_name (filedata, sect), cnt);
76da6bbe 17939
82b1b41b 17940 offset = 0;
a6e9f9df 17941 while (cnt-- > 0)
252b5132 17942 {
a6e9f9df 17943 size_t len;
fd17d1e6
AM
17944 Elf_External_Options * eoption;
17945
17946 eoption = (Elf_External_Options *) ((char *) eopt + offset);
17947
17948 option.kind = BYTE_GET (eoption->kind);
17949 option.size = BYTE_GET (eoption->size);
17950 option.section = BYTE_GET (eoption->section);
17951 option.info = BYTE_GET (eoption->info);
a6e9f9df 17952
fd17d1e6 17953 switch (option.kind)
252b5132 17954 {
a6e9f9df
AM
17955 case ODK_NULL:
17956 /* This shouldn't happen. */
d0c4e780 17957 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 17958 option.section, option.info);
a6e9f9df 17959 break;
2e6be59c 17960
a6e9f9df
AM
17961 case ODK_REGINFO:
17962 printf (" REGINFO ");
dda8d76d 17963 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 17964 {
2cf0635d 17965 Elf32_External_RegInfo * ereg;
b34976b6 17966 Elf32_RegInfo reginfo;
a6e9f9df 17967
2e6be59c 17968 /* 32bit form. */
fd17d1e6
AM
17969 if (option.size < (sizeof (Elf_External_Options)
17970 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
17971 {
17972 printf (_("<corrupt>\n"));
17973 error (_("Truncated MIPS REGINFO option\n"));
17974 cnt = 0;
17975 break;
17976 }
17977
fd17d1e6 17978 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 17979
a6e9f9df
AM
17980 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17981 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17982 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17983 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17984 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
17985 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
17986
d0c4e780
AM
17987 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
17988 reginfo.ri_gprmask, reginfo.ri_gp_value);
17989 printf (" "
17990 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
17991 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
17992 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17993 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17994 }
17995 else
17996 {
17997 /* 64 bit form. */
2cf0635d 17998 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
17999 Elf64_Internal_RegInfo reginfo;
18000
fd17d1e6
AM
18001 if (option.size < (sizeof (Elf_External_Options)
18002 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18003 {
18004 printf (_("<corrupt>\n"));
18005 error (_("Truncated MIPS REGINFO option\n"));
18006 cnt = 0;
18007 break;
18008 }
18009
fd17d1e6 18010 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18011 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18012 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18013 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18014 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18015 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18016 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18017
d0c4e780
AM
18018 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18019 reginfo.ri_gprmask, reginfo.ri_gp_value);
18020 printf (" "
18021 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18022 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18023 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18024 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18025 }
fd17d1e6 18026 offset += option.size;
a6e9f9df 18027 continue;
2e6be59c 18028
a6e9f9df
AM
18029 case ODK_EXCEPTIONS:
18030 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18031 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18032 fputs (") fpe_max(", stdout);
fd17d1e6 18033 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18034 fputs (")", stdout);
18035
fd17d1e6 18036 if (option.info & OEX_PAGE0)
a6e9f9df 18037 fputs (" PAGE0", stdout);
fd17d1e6 18038 if (option.info & OEX_SMM)
a6e9f9df 18039 fputs (" SMM", stdout);
fd17d1e6 18040 if (option.info & OEX_FPDBUG)
a6e9f9df 18041 fputs (" FPDBUG", stdout);
fd17d1e6 18042 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18043 fputs (" DISMISS", stdout);
18044 break;
2e6be59c 18045
a6e9f9df
AM
18046 case ODK_PAD:
18047 fputs (" PAD ", stdout);
fd17d1e6 18048 if (option.info & OPAD_PREFIX)
a6e9f9df 18049 fputs (" PREFIX", stdout);
fd17d1e6 18050 if (option.info & OPAD_POSTFIX)
a6e9f9df 18051 fputs (" POSTFIX", stdout);
fd17d1e6 18052 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18053 fputs (" SYMBOL", stdout);
18054 break;
2e6be59c 18055
a6e9f9df
AM
18056 case ODK_HWPATCH:
18057 fputs (" HWPATCH ", stdout);
fd17d1e6 18058 if (option.info & OHW_R4KEOP)
a6e9f9df 18059 fputs (" R4KEOP", stdout);
fd17d1e6 18060 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18061 fputs (" R8KPFETCH", stdout);
fd17d1e6 18062 if (option.info & OHW_R5KEOP)
a6e9f9df 18063 fputs (" R5KEOP", stdout);
fd17d1e6 18064 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18065 fputs (" R5KCVTL", stdout);
18066 break;
2e6be59c 18067
a6e9f9df
AM
18068 case ODK_FILL:
18069 fputs (" FILL ", stdout);
18070 /* XXX Print content of info word? */
18071 break;
2e6be59c 18072
a6e9f9df
AM
18073 case ODK_TAGS:
18074 fputs (" TAGS ", stdout);
18075 /* XXX Print content of info word? */
18076 break;
2e6be59c 18077
a6e9f9df
AM
18078 case ODK_HWAND:
18079 fputs (" HWAND ", stdout);
fd17d1e6 18080 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18081 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18082 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18083 fputs (" R4KEOP_CLEAN", stdout);
18084 break;
2e6be59c 18085
a6e9f9df
AM
18086 case ODK_HWOR:
18087 fputs (" HWOR ", stdout);
fd17d1e6 18088 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18089 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18090 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18091 fputs (" R4KEOP_CLEAN", stdout);
18092 break;
2e6be59c 18093
a6e9f9df 18094 case ODK_GP_GROUP:
d0c4e780 18095 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18096 option.info & OGP_GROUP,
18097 (option.info & OGP_SELF) >> 16);
a6e9f9df 18098 break;
2e6be59c 18099
a6e9f9df 18100 case ODK_IDENT:
d0c4e780 18101 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18102 option.info & OGP_GROUP,
18103 (option.info & OGP_SELF) >> 16);
a6e9f9df 18104 break;
2e6be59c 18105
a6e9f9df
AM
18106 default:
18107 /* This shouldn't happen. */
d0c4e780 18108 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18109 option.kind, option.section, option.info);
a6e9f9df 18110 break;
252b5132 18111 }
a6e9f9df 18112
2cf0635d 18113 len = sizeof (* eopt);
fd17d1e6 18114 while (len < option.size)
82b1b41b 18115 {
fd17d1e6 18116 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18117
82b1b41b
NC
18118 if (ISPRINT (datum))
18119 printf ("%c", datum);
18120 else
18121 printf ("\\%03o", datum);
18122 len ++;
18123 }
a6e9f9df 18124 fputs ("\n", stdout);
82b1b41b 18125
fd17d1e6 18126 offset += option.size;
252b5132 18127 }
a6e9f9df 18128 free (eopt);
252b5132 18129 }
32ec8896 18130 else
015dc7e1 18131 res = false;
252b5132
RH
18132 }
18133
18134 if (conflicts_offset != 0 && conflictsno != 0)
18135 {
2cf0635d 18136 Elf32_Conflict * iconf;
252b5132
RH
18137 size_t cnt;
18138
978c4450 18139 if (filedata->dynamic_symbols == NULL)
252b5132 18140 {
591a748a 18141 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18142 return false;
252b5132
RH
18143 }
18144
7296a62a
NC
18145 /* PR 21345 - print a slightly more helpful error message
18146 if we are sure that the cmalloc will fail. */
645f43a8 18147 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18148 {
18149 error (_("Overlarge number of conflicts detected: %lx\n"),
18150 (long) conflictsno);
015dc7e1 18151 return false;
7296a62a
NC
18152 }
18153
3f5e193b 18154 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18155 if (iconf == NULL)
18156 {
8b73c356 18157 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18158 return false;
252b5132
RH
18159 }
18160
9ea033b2 18161 if (is_32bit_elf)
252b5132 18162 {
2cf0635d 18163 Elf32_External_Conflict * econf32;
a6e9f9df 18164
3f5e193b 18165 econf32 = (Elf32_External_Conflict *)
95099889
AM
18166 get_data (NULL, filedata, conflicts_offset,
18167 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18168 if (!econf32)
5a814d6d
AM
18169 {
18170 free (iconf);
015dc7e1 18171 return false;
5a814d6d 18172 }
252b5132
RH
18173
18174 for (cnt = 0; cnt < conflictsno; ++cnt)
18175 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18176
18177 free (econf32);
252b5132
RH
18178 }
18179 else
18180 {
2cf0635d 18181 Elf64_External_Conflict * econf64;
a6e9f9df 18182
3f5e193b 18183 econf64 = (Elf64_External_Conflict *)
95099889
AM
18184 get_data (NULL, filedata, conflicts_offset,
18185 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18186 if (!econf64)
5a814d6d
AM
18187 {
18188 free (iconf);
015dc7e1 18189 return false;
5a814d6d 18190 }
252b5132
RH
18191
18192 for (cnt = 0; cnt < conflictsno; ++cnt)
18193 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18194
18195 free (econf64);
252b5132
RH
18196 }
18197
d3a49aa8
AM
18198 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18199 "\nSection '.conflict' contains %lu entries:\n",
18200 (unsigned long) conflictsno),
c7e7ca54 18201 (unsigned long) conflictsno);
252b5132
RH
18202 puts (_(" Num: Index Value Name"));
18203
18204 for (cnt = 0; cnt < conflictsno; ++cnt)
18205 {
b34976b6 18206 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18207
978c4450 18208 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18209 printf (_("<corrupt symbol index>"));
d79b3d50 18210 else
e0a31db1
NC
18211 {
18212 Elf_Internal_Sym * psym;
18213
978c4450 18214 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18215 print_vma (psym->st_value, FULL_HEX);
18216 putchar (' ');
978c4450
AM
18217 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18218 print_symbol (25, GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18219 else
18220 printf (_("<corrupt: %14ld>"), psym->st_name);
18221 }
31104126 18222 putchar ('\n');
252b5132
RH
18223 }
18224
252b5132
RH
18225 free (iconf);
18226 }
18227
ccb4c951
RS
18228 if (pltgot != 0 && local_gotno != 0)
18229 {
91d6fa6a 18230 bfd_vma ent, local_end, global_end;
bbeee7ea 18231 size_t i, offset;
2cf0635d 18232 unsigned char * data;
82b1b41b 18233 unsigned char * data_end;
bbeee7ea 18234 int addr_size;
ccb4c951 18235
91d6fa6a 18236 ent = pltgot;
ccb4c951
RS
18237 addr_size = (is_32bit_elf ? 4 : 8);
18238 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18239
74e1a04b
NC
18240 /* PR binutils/17533 file: 012-111227-0.004 */
18241 if (symtabno < gotsym)
18242 {
18243 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18244 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18245 return false;
74e1a04b 18246 }
82b1b41b 18247
74e1a04b 18248 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18249 /* PR 17531: file: 54c91a34. */
18250 if (global_end < local_end)
18251 {
18252 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18253 return false;
82b1b41b 18254 }
948f632f 18255
dda8d76d
NC
18256 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18257 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18258 global_end - pltgot, 1,
18259 _("Global Offset Table data"));
919383ac 18260 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18261 data_end = data + (global_end - pltgot);
59245841 18262
ccb4c951
RS
18263 printf (_("\nPrimary GOT:\n"));
18264 printf (_(" Canonical gp value: "));
18265 print_vma (pltgot + 0x7ff0, LONG_HEX);
18266 printf ("\n\n");
18267
18268 printf (_(" Reserved entries:\n"));
18269 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18270 addr_size * 2, _("Address"), _("Access"),
18271 addr_size * 2, _("Initial"));
82b1b41b 18272 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18273 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18274 if (ent == (bfd_vma) -1)
18275 goto got_print_fail;
75ec1fdb 18276
c4ab9505
MR
18277 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18278 This entry will be used by some runtime loaders, to store the
18279 module pointer. Otherwise this is an ordinary local entry.
18280 PR 21344: Check for the entry being fully available before
18281 fetching it. */
18282 if (data
18283 && data + ent - pltgot + addr_size <= data_end
18284 && (byte_get (data + ent - pltgot, addr_size)
18285 >> (addr_size * 8 - 1)) != 0)
18286 {
18287 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18288 printf (_(" Module pointer (GNU extension)\n"));
18289 if (ent == (bfd_vma) -1)
18290 goto got_print_fail;
ccb4c951
RS
18291 }
18292 printf ("\n");
18293
f17e9d8a 18294 if (data != NULL && ent < local_end)
ccb4c951
RS
18295 {
18296 printf (_(" Local entries:\n"));
cc5914eb 18297 printf (" %*s %10s %*s\n",
2b692964
NC
18298 addr_size * 2, _("Address"), _("Access"),
18299 addr_size * 2, _("Initial"));
91d6fa6a 18300 while (ent < local_end)
ccb4c951 18301 {
82b1b41b 18302 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18303 printf ("\n");
82b1b41b
NC
18304 if (ent == (bfd_vma) -1)
18305 goto got_print_fail;
ccb4c951
RS
18306 }
18307 printf ("\n");
18308 }
18309
f17e9d8a 18310 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18311 {
18312 int sym_width;
18313
18314 printf (_(" Global entries:\n"));
cc5914eb 18315 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18316 addr_size * 2, _("Address"),
18317 _("Access"),
2b692964 18318 addr_size * 2, _("Initial"),
9cf03b7e
NC
18319 addr_size * 2, _("Sym.Val."),
18320 _("Type"),
18321 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18322 _("Ndx"), _("Name"));
0b4362b0 18323
ccb4c951 18324 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18325
ccb4c951
RS
18326 for (i = gotsym; i < symtabno; i++)
18327 {
82b1b41b 18328 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18329 printf (" ");
e0a31db1 18330
978c4450 18331 if (filedata->dynamic_symbols == NULL)
e0a31db1 18332 printf (_("<no dynamic symbols>"));
978c4450 18333 else if (i < filedata->num_dynamic_syms)
e0a31db1 18334 {
978c4450 18335 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
18336
18337 print_vma (psym->st_value, LONG_HEX);
18338 printf (" %-7s %3s ",
dda8d76d
NC
18339 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18340 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 18341
978c4450
AM
18342 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18343 print_symbol (sym_width,
18344 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18345 else
18346 printf (_("<corrupt: %14ld>"), psym->st_name);
18347 }
ccb4c951 18348 else
7fc5ac57
JBG
18349 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
18350 (unsigned long) i);
e0a31db1 18351
ccb4c951 18352 printf ("\n");
82b1b41b
NC
18353 if (ent == (bfd_vma) -1)
18354 break;
ccb4c951
RS
18355 }
18356 printf ("\n");
18357 }
18358
82b1b41b 18359 got_print_fail:
9db70fc3 18360 free (data);
ccb4c951
RS
18361 }
18362
861fb55a
DJ
18363 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
18364 {
91d6fa6a 18365 bfd_vma ent, end;
861fb55a
DJ
18366 size_t offset, rel_offset;
18367 unsigned long count, i;
2cf0635d 18368 unsigned char * data;
861fb55a 18369 int addr_size, sym_width;
2cf0635d 18370 Elf_Internal_Rela * rels;
861fb55a 18371
dda8d76d 18372 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
18373 if (pltrel == DT_RELA)
18374 {
dda8d76d 18375 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18376 return false;
861fb55a
DJ
18377 }
18378 else
18379 {
dda8d76d 18380 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18381 return false;
861fb55a
DJ
18382 }
18383
91d6fa6a 18384 ent = mips_pltgot;
861fb55a
DJ
18385 addr_size = (is_32bit_elf ? 4 : 8);
18386 end = mips_pltgot + (2 + count) * addr_size;
18387
dda8d76d
NC
18388 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
18389 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 18390 1, _("Procedure Linkage Table data"));
59245841 18391 if (data == NULL)
288f0ba2
AM
18392 {
18393 free (rels);
015dc7e1 18394 return false;
288f0ba2 18395 }
59245841 18396
9cf03b7e 18397 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
18398 printf (_(" Reserved entries:\n"));
18399 printf (_(" %*s %*s Purpose\n"),
2b692964 18400 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 18401 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18402 printf (_(" PLT lazy resolver\n"));
91d6fa6a 18403 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18404 printf (_(" Module pointer\n"));
861fb55a
DJ
18405 printf ("\n");
18406
18407 printf (_(" Entries:\n"));
cc5914eb 18408 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
18409 addr_size * 2, _("Address"),
18410 addr_size * 2, _("Initial"),
18411 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
18412 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
18413 for (i = 0; i < count; i++)
18414 {
df97ab2a 18415 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 18416
91d6fa6a 18417 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 18418 printf (" ");
e0a31db1 18419
978c4450 18420 if (idx >= filedata->num_dynamic_syms)
df97ab2a 18421 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 18422 else
e0a31db1 18423 {
978c4450 18424 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
18425
18426 print_vma (psym->st_value, LONG_HEX);
18427 printf (" %-7s %3s ",
dda8d76d
NC
18428 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18429 get_symbol_index_type (filedata, psym->st_shndx));
978c4450
AM
18430 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18431 print_symbol (sym_width,
18432 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18433 else
18434 printf (_("<corrupt: %14ld>"), psym->st_name);
18435 }
861fb55a
DJ
18436 printf ("\n");
18437 }
18438 printf ("\n");
18439
9db70fc3 18440 free (data);
861fb55a
DJ
18441 free (rels);
18442 }
18443
32ec8896 18444 return res;
252b5132
RH
18445}
18446
015dc7e1 18447static bool
dda8d76d 18448process_nds32_specific (Filedata * filedata)
35c08157
KLC
18449{
18450 Elf_Internal_Shdr *sect = NULL;
18451
dda8d76d 18452 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 18453 if (sect != NULL && sect->sh_size >= 4)
35c08157 18454 {
9c7b8e9b
AM
18455 unsigned char *buf;
18456 unsigned int flag;
35c08157
KLC
18457
18458 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
18459 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
18460 _("NDS32 elf flags section"));
35c08157 18461
9c7b8e9b 18462 if (buf == NULL)
015dc7e1 18463 return false;
32ec8896 18464
9c7b8e9b
AM
18465 flag = byte_get (buf, 4);
18466 free (buf);
18467 switch (flag & 0x3)
35c08157
KLC
18468 {
18469 case 0:
18470 printf ("(VEC_SIZE):\tNo entry.\n");
18471 break;
18472 case 1:
18473 printf ("(VEC_SIZE):\t4 bytes\n");
18474 break;
18475 case 2:
18476 printf ("(VEC_SIZE):\t16 bytes\n");
18477 break;
18478 case 3:
18479 printf ("(VEC_SIZE):\treserved\n");
18480 break;
18481 }
18482 }
18483
015dc7e1 18484 return true;
35c08157
KLC
18485}
18486
015dc7e1 18487static bool
dda8d76d 18488process_gnu_liblist (Filedata * filedata)
047b2264 18489{
2cf0635d
NC
18490 Elf_Internal_Shdr * section;
18491 Elf_Internal_Shdr * string_sec;
18492 Elf32_External_Lib * elib;
18493 char * strtab;
c256ffe7 18494 size_t strtab_size;
047b2264 18495 size_t cnt;
d3a49aa8 18496 unsigned long num_liblist;
047b2264 18497 unsigned i;
015dc7e1 18498 bool res = true;
047b2264
JJ
18499
18500 if (! do_arch)
015dc7e1 18501 return true;
047b2264 18502
dda8d76d
NC
18503 for (i = 0, section = filedata->section_headers;
18504 i < filedata->file_header.e_shnum;
b34976b6 18505 i++, section++)
047b2264
JJ
18506 {
18507 switch (section->sh_type)
18508 {
18509 case SHT_GNU_LIBLIST:
dda8d76d 18510 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
18511 break;
18512
3f5e193b 18513 elib = (Elf32_External_Lib *)
dda8d76d 18514 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 18515 _("liblist section data"));
047b2264
JJ
18516
18517 if (elib == NULL)
32ec8896 18518 {
015dc7e1 18519 res = false;
32ec8896
NC
18520 break;
18521 }
047b2264 18522
dda8d76d
NC
18523 string_sec = filedata->section_headers + section->sh_link;
18524 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
18525 string_sec->sh_size,
18526 _("liblist string table"));
047b2264
JJ
18527 if (strtab == NULL
18528 || section->sh_entsize != sizeof (Elf32_External_Lib))
18529 {
18530 free (elib);
2842702f 18531 free (strtab);
015dc7e1 18532 res = false;
047b2264
JJ
18533 break;
18534 }
59245841 18535 strtab_size = string_sec->sh_size;
047b2264 18536
d3a49aa8
AM
18537 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
18538 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
18539 "\nLibrary list section '%s' contains %lu entries:\n",
18540 num_liblist),
dda8d76d 18541 printable_section_name (filedata, section),
d3a49aa8 18542 num_liblist);
047b2264 18543
2b692964 18544 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
18545
18546 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
18547 ++cnt)
18548 {
18549 Elf32_Lib liblist;
91d6fa6a 18550 time_t atime;
d5b07ef4 18551 char timebuf[128];
2cf0635d 18552 struct tm * tmp;
047b2264
JJ
18553
18554 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18555 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
18556 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18557 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18558 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18559
91d6fa6a 18560 tmp = gmtime (&atime);
e9e44622
JJ
18561 snprintf (timebuf, sizeof (timebuf),
18562 "%04u-%02u-%02uT%02u:%02u:%02u",
18563 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18564 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
18565
18566 printf ("%3lu: ", (unsigned long) cnt);
18567 if (do_wide)
c256ffe7 18568 printf ("%-20s", liblist.l_name < strtab_size
2b692964 18569 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 18570 else
c256ffe7 18571 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 18572 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
18573 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
18574 liblist.l_version, liblist.l_flags);
18575 }
18576
18577 free (elib);
2842702f 18578 free (strtab);
047b2264
JJ
18579 }
18580 }
18581
32ec8896 18582 return res;
047b2264
JJ
18583}
18584
9437c45b 18585static const char *
dda8d76d 18586get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
18587{
18588 static char buff[64];
103f02d3 18589
dda8d76d 18590 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
18591 switch (e_type)
18592 {
57346661 18593 case NT_AUXV:
1ec5cd37 18594 return _("NT_AUXV (auxiliary vector)");
57346661 18595 case NT_PRSTATUS:
1ec5cd37 18596 return _("NT_PRSTATUS (prstatus structure)");
57346661 18597 case NT_FPREGSET:
1ec5cd37 18598 return _("NT_FPREGSET (floating point registers)");
57346661 18599 case NT_PRPSINFO:
1ec5cd37 18600 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 18601 case NT_TASKSTRUCT:
1ec5cd37 18602 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
18603 case NT_GDB_TDESC:
18604 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 18605 case NT_PRXFPREG:
1ec5cd37 18606 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
18607 case NT_PPC_VMX:
18608 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
18609 case NT_PPC_VSX:
18610 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
18611 case NT_PPC_TAR:
18612 return _("NT_PPC_TAR (ppc TAR register)");
18613 case NT_PPC_PPR:
18614 return _("NT_PPC_PPR (ppc PPR register)");
18615 case NT_PPC_DSCR:
18616 return _("NT_PPC_DSCR (ppc DSCR register)");
18617 case NT_PPC_EBB:
18618 return _("NT_PPC_EBB (ppc EBB registers)");
18619 case NT_PPC_PMU:
18620 return _("NT_PPC_PMU (ppc PMU registers)");
18621 case NT_PPC_TM_CGPR:
18622 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
18623 case NT_PPC_TM_CFPR:
18624 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
18625 case NT_PPC_TM_CVMX:
18626 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
18627 case NT_PPC_TM_CVSX:
3fd21718 18628 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
18629 case NT_PPC_TM_SPR:
18630 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
18631 case NT_PPC_TM_CTAR:
18632 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
18633 case NT_PPC_TM_CPPR:
18634 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
18635 case NT_PPC_TM_CDSCR:
18636 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
18637 case NT_386_TLS:
18638 return _("NT_386_TLS (x86 TLS information)");
18639 case NT_386_IOPERM:
18640 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
18641 case NT_X86_XSTATE:
18642 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
18643 case NT_X86_CET:
18644 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
18645 case NT_S390_HIGH_GPRS:
18646 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
18647 case NT_S390_TIMER:
18648 return _("NT_S390_TIMER (s390 timer register)");
18649 case NT_S390_TODCMP:
18650 return _("NT_S390_TODCMP (s390 TOD comparator register)");
18651 case NT_S390_TODPREG:
18652 return _("NT_S390_TODPREG (s390 TOD programmable register)");
18653 case NT_S390_CTRS:
18654 return _("NT_S390_CTRS (s390 control registers)");
18655 case NT_S390_PREFIX:
18656 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
18657 case NT_S390_LAST_BREAK:
18658 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
18659 case NT_S390_SYSTEM_CALL:
18660 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
18661 case NT_S390_TDB:
18662 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
18663 case NT_S390_VXRS_LOW:
18664 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
18665 case NT_S390_VXRS_HIGH:
18666 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
18667 case NT_S390_GS_CB:
18668 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
18669 case NT_S390_GS_BC:
18670 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
18671 case NT_ARM_VFP:
18672 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
18673 case NT_ARM_TLS:
18674 return _("NT_ARM_TLS (AArch TLS registers)");
18675 case NT_ARM_HW_BREAK:
18676 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
18677 case NT_ARM_HW_WATCH:
18678 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
3b2bef8b
LM
18679 case NT_ARM_SVE:
18680 return _("NT_ARM_SVE (AArch SVE registers)");
18681 case NT_ARM_PAC_MASK:
18682 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
18683 case NT_ARM_TAGGED_ADDR_CTRL:
18684 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
27456742
AK
18685 case NT_ARC_V2:
18686 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
18687 case NT_RISCV_CSR:
18688 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 18689 case NT_PSTATUS:
1ec5cd37 18690 return _("NT_PSTATUS (pstatus structure)");
57346661 18691 case NT_FPREGS:
1ec5cd37 18692 return _("NT_FPREGS (floating point registers)");
57346661 18693 case NT_PSINFO:
1ec5cd37 18694 return _("NT_PSINFO (psinfo structure)");
57346661 18695 case NT_LWPSTATUS:
1ec5cd37 18696 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 18697 case NT_LWPSINFO:
1ec5cd37 18698 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 18699 case NT_WIN32PSTATUS:
1ec5cd37 18700 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
18701 case NT_SIGINFO:
18702 return _("NT_SIGINFO (siginfo_t data)");
18703 case NT_FILE:
18704 return _("NT_FILE (mapped files)");
894982bf
LM
18705 case NT_MEMTAG:
18706 return _("NT_MEMTAG (memory tags)");
1ec5cd37
NC
18707 default:
18708 break;
18709 }
18710 else
18711 switch (e_type)
18712 {
18713 case NT_VERSION:
18714 return _("NT_VERSION (version)");
18715 case NT_ARCH:
18716 return _("NT_ARCH (architecture)");
9ef920e9 18717 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 18718 return _("OPEN");
9ef920e9 18719 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 18720 return _("func");
1ec5cd37
NC
18721 default:
18722 break;
18723 }
18724
e9e44622 18725 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 18726 return buff;
779fe533
NC
18727}
18728
015dc7e1 18729static bool
9ece1fa9
TT
18730print_core_note (Elf_Internal_Note *pnote)
18731{
18732 unsigned int addr_size = is_32bit_elf ? 4 : 8;
18733 bfd_vma count, page_size;
18734 unsigned char *descdata, *filenames, *descend;
18735
18736 if (pnote->type != NT_FILE)
04ac15ab
AS
18737 {
18738 if (do_wide)
18739 printf ("\n");
015dc7e1 18740 return true;
04ac15ab 18741 }
9ece1fa9
TT
18742
18743#ifndef BFD64
18744 if (!is_32bit_elf)
18745 {
18746 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
18747 /* Still "successful". */
015dc7e1 18748 return true;
9ece1fa9
TT
18749 }
18750#endif
18751
18752 if (pnote->descsz < 2 * addr_size)
18753 {
32ec8896 18754 error (_(" Malformed note - too short for header\n"));
015dc7e1 18755 return false;
9ece1fa9
TT
18756 }
18757
18758 descdata = (unsigned char *) pnote->descdata;
18759 descend = descdata + pnote->descsz;
18760
18761 if (descdata[pnote->descsz - 1] != '\0')
18762 {
32ec8896 18763 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 18764 return false;
9ece1fa9
TT
18765 }
18766
18767 count = byte_get (descdata, addr_size);
18768 descdata += addr_size;
18769
18770 page_size = byte_get (descdata, addr_size);
18771 descdata += addr_size;
18772
5396a86e
AM
18773 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
18774 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 18775 {
32ec8896 18776 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 18777 return false;
9ece1fa9
TT
18778 }
18779
18780 printf (_(" Page size: "));
18781 print_vma (page_size, DEC);
18782 printf ("\n");
18783
18784 printf (_(" %*s%*s%*s\n"),
18785 (int) (2 + 2 * addr_size), _("Start"),
18786 (int) (4 + 2 * addr_size), _("End"),
18787 (int) (4 + 2 * addr_size), _("Page Offset"));
18788 filenames = descdata + count * 3 * addr_size;
595712bb 18789 while (count-- > 0)
9ece1fa9
TT
18790 {
18791 bfd_vma start, end, file_ofs;
18792
18793 if (filenames == descend)
18794 {
32ec8896 18795 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 18796 return false;
9ece1fa9
TT
18797 }
18798
18799 start = byte_get (descdata, addr_size);
18800 descdata += addr_size;
18801 end = byte_get (descdata, addr_size);
18802 descdata += addr_size;
18803 file_ofs = byte_get (descdata, addr_size);
18804 descdata += addr_size;
18805
18806 printf (" ");
18807 print_vma (start, FULL_HEX);
18808 printf (" ");
18809 print_vma (end, FULL_HEX);
18810 printf (" ");
18811 print_vma (file_ofs, FULL_HEX);
18812 printf ("\n %s\n", filenames);
18813
18814 filenames += 1 + strlen ((char *) filenames);
18815 }
18816
015dc7e1 18817 return true;
9ece1fa9
TT
18818}
18819
1118d252
RM
18820static const char *
18821get_gnu_elf_note_type (unsigned e_type)
18822{
1449284b 18823 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
18824 switch (e_type)
18825 {
18826 case NT_GNU_ABI_TAG:
18827 return _("NT_GNU_ABI_TAG (ABI version tag)");
18828 case NT_GNU_HWCAP:
18829 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
18830 case NT_GNU_BUILD_ID:
18831 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
18832 case NT_GNU_GOLD_VERSION:
18833 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
18834 case NT_GNU_PROPERTY_TYPE_0:
18835 return _("NT_GNU_PROPERTY_TYPE_0");
18836 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
18837 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
18838 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
18839 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 18840 default:
1449284b
NC
18841 {
18842 static char buff[64];
1118d252 18843
1449284b
NC
18844 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18845 return buff;
18846 }
18847 }
1118d252
RM
18848}
18849
a9eafb08
L
18850static void
18851decode_x86_compat_isa (unsigned int bitmask)
18852{
18853 while (bitmask)
18854 {
18855 unsigned int bit = bitmask & (- bitmask);
18856
18857 bitmask &= ~ bit;
18858 switch (bit)
18859 {
18860 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
18861 printf ("i486");
18862 break;
18863 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
18864 printf ("586");
18865 break;
18866 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
18867 printf ("686");
18868 break;
18869 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
18870 printf ("SSE");
18871 break;
18872 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
18873 printf ("SSE2");
18874 break;
18875 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
18876 printf ("SSE3");
18877 break;
18878 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
18879 printf ("SSSE3");
18880 break;
18881 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
18882 printf ("SSE4_1");
18883 break;
18884 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
18885 printf ("SSE4_2");
18886 break;
18887 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
18888 printf ("AVX");
18889 break;
18890 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
18891 printf ("AVX2");
18892 break;
18893 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
18894 printf ("AVX512F");
18895 break;
18896 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
18897 printf ("AVX512CD");
18898 break;
18899 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
18900 printf ("AVX512ER");
18901 break;
18902 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
18903 printf ("AVX512PF");
18904 break;
18905 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
18906 printf ("AVX512VL");
18907 break;
18908 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
18909 printf ("AVX512DQ");
18910 break;
18911 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
18912 printf ("AVX512BW");
18913 break;
65b3d26e
L
18914 default:
18915 printf (_("<unknown: %x>"), bit);
18916 break;
a9eafb08
L
18917 }
18918 if (bitmask)
18919 printf (", ");
18920 }
18921}
18922
9ef920e9 18923static void
32930e4e 18924decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 18925{
0a59decb 18926 if (!bitmask)
90c745dc
L
18927 {
18928 printf (_("<None>"));
18929 return;
18930 }
90c745dc 18931
9ef920e9
NC
18932 while (bitmask)
18933 {
1fc87489 18934 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
18935
18936 bitmask &= ~ bit;
18937 switch (bit)
18938 {
32930e4e 18939 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
18940 printf ("CMOV");
18941 break;
32930e4e 18942 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
18943 printf ("SSE");
18944 break;
32930e4e 18945 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
18946 printf ("SSE2");
18947 break;
32930e4e 18948 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
18949 printf ("SSE3");
18950 break;
32930e4e 18951 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
18952 printf ("SSSE3");
18953 break;
32930e4e 18954 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
18955 printf ("SSE4_1");
18956 break;
32930e4e 18957 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
18958 printf ("SSE4_2");
18959 break;
32930e4e 18960 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
18961 printf ("AVX");
18962 break;
32930e4e 18963 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
18964 printf ("AVX2");
18965 break;
32930e4e 18966 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
18967 printf ("FMA");
18968 break;
32930e4e 18969 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
18970 printf ("AVX512F");
18971 break;
32930e4e 18972 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
18973 printf ("AVX512CD");
18974 break;
32930e4e 18975 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
18976 printf ("AVX512ER");
18977 break;
32930e4e 18978 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
18979 printf ("AVX512PF");
18980 break;
32930e4e 18981 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
18982 printf ("AVX512VL");
18983 break;
32930e4e 18984 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
18985 printf ("AVX512DQ");
18986 break;
32930e4e 18987 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
18988 printf ("AVX512BW");
18989 break;
32930e4e 18990 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
18991 printf ("AVX512_4FMAPS");
18992 break;
32930e4e 18993 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
18994 printf ("AVX512_4VNNIW");
18995 break;
32930e4e 18996 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
18997 printf ("AVX512_BITALG");
18998 break;
32930e4e 18999 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19000 printf ("AVX512_IFMA");
19001 break;
32930e4e 19002 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19003 printf ("AVX512_VBMI");
19004 break;
32930e4e 19005 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19006 printf ("AVX512_VBMI2");
19007 break;
32930e4e 19008 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19009 printf ("AVX512_VNNI");
19010 break;
32930e4e 19011 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19012 printf ("AVX512_BF16");
19013 break;
65b3d26e
L
19014 default:
19015 printf (_("<unknown: %x>"), bit);
19016 break;
9ef920e9
NC
19017 }
19018 if (bitmask)
19019 printf (", ");
19020 }
19021}
19022
32930e4e
L
19023static void
19024decode_x86_isa (unsigned int bitmask)
19025{
32930e4e
L
19026 while (bitmask)
19027 {
19028 unsigned int bit = bitmask & (- bitmask);
19029
19030 bitmask &= ~ bit;
19031 switch (bit)
19032 {
b0ab0693
L
19033 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19034 printf ("x86-64-baseline");
19035 break;
32930e4e
L
19036 case GNU_PROPERTY_X86_ISA_1_V2:
19037 printf ("x86-64-v2");
19038 break;
19039 case GNU_PROPERTY_X86_ISA_1_V3:
19040 printf ("x86-64-v3");
19041 break;
19042 case GNU_PROPERTY_X86_ISA_1_V4:
19043 printf ("x86-64-v4");
19044 break;
19045 default:
19046 printf (_("<unknown: %x>"), bit);
19047 break;
19048 }
19049 if (bitmask)
19050 printf (", ");
19051 }
19052}
19053
ee2fdd6f 19054static void
a9eafb08 19055decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19056{
0a59decb 19057 if (!bitmask)
90c745dc
L
19058 {
19059 printf (_("<None>"));
19060 return;
19061 }
90c745dc 19062
ee2fdd6f
L
19063 while (bitmask)
19064 {
19065 unsigned int bit = bitmask & (- bitmask);
19066
19067 bitmask &= ~ bit;
19068 switch (bit)
19069 {
19070 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19071 printf ("IBT");
ee2fdd6f 19072 break;
48580982 19073 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19074 printf ("SHSTK");
48580982 19075 break;
279d901e
L
19076 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19077 printf ("LAM_U48");
19078 break;
19079 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19080 printf ("LAM_U57");
19081 break;
ee2fdd6f
L
19082 default:
19083 printf (_("<unknown: %x>"), bit);
19084 break;
19085 }
19086 if (bitmask)
19087 printf (", ");
19088 }
19089}
19090
a9eafb08
L
19091static void
19092decode_x86_feature_2 (unsigned int bitmask)
19093{
0a59decb 19094 if (!bitmask)
90c745dc
L
19095 {
19096 printf (_("<None>"));
19097 return;
19098 }
90c745dc 19099
a9eafb08
L
19100 while (bitmask)
19101 {
19102 unsigned int bit = bitmask & (- bitmask);
19103
19104 bitmask &= ~ bit;
19105 switch (bit)
19106 {
19107 case GNU_PROPERTY_X86_FEATURE_2_X86:
19108 printf ("x86");
19109 break;
19110 case GNU_PROPERTY_X86_FEATURE_2_X87:
19111 printf ("x87");
19112 break;
19113 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19114 printf ("MMX");
19115 break;
19116 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19117 printf ("XMM");
19118 break;
19119 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19120 printf ("YMM");
19121 break;
19122 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19123 printf ("ZMM");
19124 break;
a308b89d
L
19125 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19126 printf ("TMM");
19127 break;
32930e4e
L
19128 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19129 printf ("MASK");
19130 break;
a9eafb08
L
19131 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19132 printf ("FXSR");
19133 break;
19134 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19135 printf ("XSAVE");
19136 break;
19137 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19138 printf ("XSAVEOPT");
19139 break;
19140 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19141 printf ("XSAVEC");
19142 break;
65b3d26e
L
19143 default:
19144 printf (_("<unknown: %x>"), bit);
19145 break;
a9eafb08
L
19146 }
19147 if (bitmask)
19148 printf (", ");
19149 }
19150}
19151
cd702818
SD
19152static void
19153decode_aarch64_feature_1_and (unsigned int bitmask)
19154{
19155 while (bitmask)
19156 {
19157 unsigned int bit = bitmask & (- bitmask);
19158
19159 bitmask &= ~ bit;
19160 switch (bit)
19161 {
19162 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19163 printf ("BTI");
19164 break;
19165
19166 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19167 printf ("PAC");
19168 break;
19169
19170 default:
19171 printf (_("<unknown: %x>"), bit);
19172 break;
19173 }
19174 if (bitmask)
19175 printf (", ");
19176 }
19177}
19178
9ef920e9 19179static void
dda8d76d 19180print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19181{
19182 unsigned char * ptr = (unsigned char *) pnote->descdata;
19183 unsigned char * ptr_end = ptr + pnote->descsz;
19184 unsigned int size = is_32bit_elf ? 4 : 8;
19185
19186 printf (_(" Properties: "));
19187
1fc87489 19188 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19189 {
19190 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19191 return;
19192 }
19193
6ab2c4ed 19194 while (ptr < ptr_end)
9ef920e9 19195 {
1fc87489 19196 unsigned int j;
6ab2c4ed
MC
19197 unsigned int type;
19198 unsigned int datasz;
19199
19200 if ((size_t) (ptr_end - ptr) < 8)
19201 {
19202 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19203 break;
19204 }
19205
19206 type = byte_get (ptr, 4);
19207 datasz = byte_get (ptr + 4, 4);
9ef920e9 19208
1fc87489 19209 ptr += 8;
9ef920e9 19210
6ab2c4ed 19211 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19212 {
1fc87489
L
19213 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19214 type, datasz);
9ef920e9 19215 break;
1fc87489 19216 }
9ef920e9 19217
1fc87489
L
19218 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19219 {
dda8d76d
NC
19220 if (filedata->file_header.e_machine == EM_X86_64
19221 || filedata->file_header.e_machine == EM_IAMCU
19222 || filedata->file_header.e_machine == EM_386)
1fc87489 19223 {
aa7bca9b
L
19224 unsigned int bitmask;
19225
19226 if (datasz == 4)
0a59decb 19227 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19228 else
19229 bitmask = 0;
19230
1fc87489
L
19231 switch (type)
19232 {
19233 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19234 if (datasz != 4)
aa7bca9b
L
19235 printf (_("x86 ISA used: <corrupt length: %#x> "),
19236 datasz);
1fc87489 19237 else
aa7bca9b
L
19238 {
19239 printf ("x86 ISA used: ");
19240 decode_x86_isa (bitmask);
19241 }
1fc87489 19242 goto next;
9ef920e9 19243
1fc87489 19244 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19245 if (datasz != 4)
aa7bca9b
L
19246 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19247 datasz);
1fc87489 19248 else
aa7bca9b
L
19249 {
19250 printf ("x86 ISA needed: ");
19251 decode_x86_isa (bitmask);
19252 }
1fc87489 19253 goto next;
9ef920e9 19254
ee2fdd6f 19255 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19256 if (datasz != 4)
aa7bca9b
L
19257 printf (_("x86 feature: <corrupt length: %#x> "),
19258 datasz);
ee2fdd6f 19259 else
aa7bca9b
L
19260 {
19261 printf ("x86 feature: ");
a9eafb08
L
19262 decode_x86_feature_1 (bitmask);
19263 }
19264 goto next;
19265
19266 case GNU_PROPERTY_X86_FEATURE_2_USED:
19267 if (datasz != 4)
19268 printf (_("x86 feature used: <corrupt length: %#x> "),
19269 datasz);
19270 else
19271 {
19272 printf ("x86 feature used: ");
19273 decode_x86_feature_2 (bitmask);
19274 }
19275 goto next;
19276
19277 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
19278 if (datasz != 4)
19279 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
19280 else
19281 {
19282 printf ("x86 feature needed: ");
19283 decode_x86_feature_2 (bitmask);
19284 }
19285 goto next;
19286
19287 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
19288 if (datasz != 4)
19289 printf (_("x86 ISA used: <corrupt length: %#x> "),
19290 datasz);
19291 else
19292 {
19293 printf ("x86 ISA used: ");
19294 decode_x86_compat_isa (bitmask);
19295 }
19296 goto next;
19297
19298 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
19299 if (datasz != 4)
19300 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19301 datasz);
19302 else
19303 {
19304 printf ("x86 ISA needed: ");
19305 decode_x86_compat_isa (bitmask);
aa7bca9b 19306 }
ee2fdd6f
L
19307 goto next;
19308
32930e4e
L
19309 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
19310 if (datasz != 4)
19311 printf (_("x86 ISA used: <corrupt length: %#x> "),
19312 datasz);
19313 else
19314 {
19315 printf ("x86 ISA used: ");
19316 decode_x86_compat_2_isa (bitmask);
19317 }
19318 goto next;
19319
19320 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
19321 if (datasz != 4)
19322 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19323 datasz);
19324 else
19325 {
19326 printf ("x86 ISA needed: ");
19327 decode_x86_compat_2_isa (bitmask);
19328 }
19329 goto next;
19330
1fc87489
L
19331 default:
19332 break;
19333 }
19334 }
cd702818
SD
19335 else if (filedata->file_header.e_machine == EM_AARCH64)
19336 {
19337 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
19338 {
19339 printf ("AArch64 feature: ");
19340 if (datasz != 4)
19341 printf (_("<corrupt length: %#x> "), datasz);
19342 else
19343 decode_aarch64_feature_1_and (byte_get (ptr, 4));
19344 goto next;
19345 }
19346 }
1fc87489
L
19347 }
19348 else
19349 {
19350 switch (type)
9ef920e9 19351 {
1fc87489
L
19352 case GNU_PROPERTY_STACK_SIZE:
19353 printf (_("stack size: "));
19354 if (datasz != size)
19355 printf (_("<corrupt length: %#x> "), datasz);
19356 else
19357 printf ("%#lx", (unsigned long) byte_get (ptr, size));
19358 goto next;
19359
19360 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
19361 printf ("no copy on protected ");
19362 if (datasz)
19363 printf (_("<corrupt length: %#x> "), datasz);
19364 goto next;
19365
19366 default:
9ef920e9
NC
19367 break;
19368 }
9ef920e9
NC
19369 }
19370
1fc87489
L
19371 if (type < GNU_PROPERTY_LOPROC)
19372 printf (_("<unknown type %#x data: "), type);
19373 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 19374 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
19375 else
19376 printf (_("<application-specific type %#x data: "), type);
19377 for (j = 0; j < datasz; ++j)
19378 printf ("%02x ", ptr[j] & 0xff);
19379 printf (">");
19380
dc1e8a47 19381 next:
9ef920e9 19382 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
19383 if (ptr == ptr_end)
19384 break;
1fc87489 19385
6ab2c4ed
MC
19386 if (do_wide)
19387 printf (", ");
19388 else
19389 printf ("\n\t");
9ef920e9
NC
19390 }
19391
19392 printf ("\n");
19393}
19394
015dc7e1 19395static bool
dda8d76d 19396print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 19397{
1449284b 19398 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
19399 switch (pnote->type)
19400 {
19401 case NT_GNU_BUILD_ID:
19402 {
19403 unsigned long i;
19404
19405 printf (_(" Build ID: "));
19406 for (i = 0; i < pnote->descsz; ++i)
19407 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 19408 printf ("\n");
664f90a3
TT
19409 }
19410 break;
19411
19412 case NT_GNU_ABI_TAG:
19413 {
19414 unsigned long os, major, minor, subminor;
19415 const char *osname;
19416
3102e897
NC
19417 /* PR 17531: file: 030-599401-0.004. */
19418 if (pnote->descsz < 16)
19419 {
19420 printf (_(" <corrupt GNU_ABI_TAG>\n"));
19421 break;
19422 }
19423
664f90a3
TT
19424 os = byte_get ((unsigned char *) pnote->descdata, 4);
19425 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19426 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
19427 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
19428
19429 switch (os)
19430 {
19431 case GNU_ABI_TAG_LINUX:
19432 osname = "Linux";
19433 break;
19434 case GNU_ABI_TAG_HURD:
19435 osname = "Hurd";
19436 break;
19437 case GNU_ABI_TAG_SOLARIS:
19438 osname = "Solaris";
19439 break;
19440 case GNU_ABI_TAG_FREEBSD:
19441 osname = "FreeBSD";
19442 break;
19443 case GNU_ABI_TAG_NETBSD:
19444 osname = "NetBSD";
19445 break;
14ae95f2
RM
19446 case GNU_ABI_TAG_SYLLABLE:
19447 osname = "Syllable";
19448 break;
19449 case GNU_ABI_TAG_NACL:
19450 osname = "NaCl";
19451 break;
664f90a3
TT
19452 default:
19453 osname = "Unknown";
19454 break;
19455 }
19456
19457 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
19458 major, minor, subminor);
19459 }
19460 break;
926c5385
CC
19461
19462 case NT_GNU_GOLD_VERSION:
19463 {
19464 unsigned long i;
19465
19466 printf (_(" Version: "));
19467 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
19468 printf ("%c", pnote->descdata[i]);
19469 printf ("\n");
19470 }
19471 break;
1449284b
NC
19472
19473 case NT_GNU_HWCAP:
19474 {
19475 unsigned long num_entries, mask;
19476
19477 /* Hardware capabilities information. Word 0 is the number of entries.
19478 Word 1 is a bitmask of enabled entries. The rest of the descriptor
19479 is a series of entries, where each entry is a single byte followed
19480 by a nul terminated string. The byte gives the bit number to test
19481 if enabled in the bitmask. */
19482 printf (_(" Hardware Capabilities: "));
19483 if (pnote->descsz < 8)
19484 {
32ec8896 19485 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 19486 return false;
1449284b
NC
19487 }
19488 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
19489 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19490 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
19491 /* FIXME: Add code to display the entries... */
19492 }
19493 break;
19494
9ef920e9 19495 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 19496 print_gnu_property_note (filedata, pnote);
9ef920e9 19497 break;
9abca702 19498
1449284b
NC
19499 default:
19500 /* Handle unrecognised types. An error message should have already been
19501 created by get_gnu_elf_note_type(), so all that we need to do is to
19502 display the data. */
19503 {
19504 unsigned long i;
19505
19506 printf (_(" Description data: "));
19507 for (i = 0; i < pnote->descsz; ++i)
19508 printf ("%02x ", pnote->descdata[i] & 0xff);
19509 printf ("\n");
19510 }
19511 break;
664f90a3
TT
19512 }
19513
015dc7e1 19514 return true;
664f90a3
TT
19515}
19516
685080f2
NC
19517static const char *
19518get_v850_elf_note_type (enum v850_notes n_type)
19519{
19520 static char buff[64];
19521
19522 switch (n_type)
19523 {
19524 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
19525 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
19526 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
19527 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
19528 case V850_NOTE_CACHE_INFO: return _("Use of cache");
19529 case V850_NOTE_MMU_INFO: return _("Use of MMU");
19530 default:
19531 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
19532 return buff;
19533 }
19534}
19535
015dc7e1 19536static bool
685080f2
NC
19537print_v850_note (Elf_Internal_Note * pnote)
19538{
19539 unsigned int val;
19540
19541 if (pnote->descsz != 4)
015dc7e1 19542 return false;
32ec8896 19543
685080f2
NC
19544 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
19545
19546 if (val == 0)
19547 {
19548 printf (_("not set\n"));
015dc7e1 19549 return true;
685080f2
NC
19550 }
19551
19552 switch (pnote->type)
19553 {
19554 case V850_NOTE_ALIGNMENT:
19555 switch (val)
19556 {
015dc7e1
AM
19557 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
19558 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
19559 }
19560 break;
14ae95f2 19561
685080f2
NC
19562 case V850_NOTE_DATA_SIZE:
19563 switch (val)
19564 {
015dc7e1
AM
19565 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
19566 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
19567 }
19568 break;
14ae95f2 19569
685080f2
NC
19570 case V850_NOTE_FPU_INFO:
19571 switch (val)
19572 {
015dc7e1
AM
19573 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
19574 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
19575 }
19576 break;
14ae95f2 19577
685080f2
NC
19578 case V850_NOTE_MMU_INFO:
19579 case V850_NOTE_CACHE_INFO:
19580 case V850_NOTE_SIMD_INFO:
19581 if (val == EF_RH850_SIMD)
19582 {
19583 printf (_("yes\n"));
015dc7e1 19584 return true;
685080f2
NC
19585 }
19586 break;
19587
19588 default:
19589 /* An 'unknown note type' message will already have been displayed. */
19590 break;
19591 }
19592
19593 printf (_("unknown value: %x\n"), val);
015dc7e1 19594 return false;
685080f2
NC
19595}
19596
015dc7e1 19597static bool
c6056a74
SF
19598process_netbsd_elf_note (Elf_Internal_Note * pnote)
19599{
19600 unsigned int version;
19601
19602 switch (pnote->type)
19603 {
19604 case NT_NETBSD_IDENT:
b966f55f
AM
19605 if (pnote->descsz < 1)
19606 break;
c6056a74
SF
19607 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19608 if ((version / 10000) % 100)
b966f55f 19609 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
19610 version, version / 100000000, (version / 1000000) % 100,
19611 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 19612 'A' + (version / 10000) % 26);
c6056a74
SF
19613 else
19614 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 19615 version, version / 100000000, (version / 1000000) % 100,
15f205b1 19616 (version / 100) % 100);
015dc7e1 19617 return true;
c6056a74
SF
19618
19619 case NT_NETBSD_MARCH:
9abca702 19620 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 19621 pnote->descdata);
015dc7e1 19622 return true;
c6056a74 19623
9abca702 19624 case NT_NETBSD_PAX:
b966f55f
AM
19625 if (pnote->descsz < 1)
19626 break;
9abca702
CZ
19627 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19628 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
19629 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
19630 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
19631 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
19632 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
19633 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
19634 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 19635 return true;
c6056a74 19636 }
b966f55f
AM
19637
19638 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
19639 pnote->descsz, pnote->type);
015dc7e1 19640 return false;
c6056a74
SF
19641}
19642
f4ddf30f 19643static const char *
dda8d76d 19644get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 19645{
f4ddf30f
JB
19646 switch (e_type)
19647 {
19648 case NT_FREEBSD_THRMISC:
19649 return _("NT_THRMISC (thrmisc structure)");
19650 case NT_FREEBSD_PROCSTAT_PROC:
19651 return _("NT_PROCSTAT_PROC (proc data)");
19652 case NT_FREEBSD_PROCSTAT_FILES:
19653 return _("NT_PROCSTAT_FILES (files data)");
19654 case NT_FREEBSD_PROCSTAT_VMMAP:
19655 return _("NT_PROCSTAT_VMMAP (vmmap data)");
19656 case NT_FREEBSD_PROCSTAT_GROUPS:
19657 return _("NT_PROCSTAT_GROUPS (groups data)");
19658 case NT_FREEBSD_PROCSTAT_UMASK:
19659 return _("NT_PROCSTAT_UMASK (umask data)");
19660 case NT_FREEBSD_PROCSTAT_RLIMIT:
19661 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
19662 case NT_FREEBSD_PROCSTAT_OSREL:
19663 return _("NT_PROCSTAT_OSREL (osreldate data)");
19664 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
19665 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
19666 case NT_FREEBSD_PROCSTAT_AUXV:
19667 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
19668 case NT_FREEBSD_PTLWPINFO:
19669 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 19670 }
dda8d76d 19671 return get_note_type (filedata, e_type);
f4ddf30f
JB
19672}
19673
9437c45b 19674static const char *
dda8d76d 19675get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
19676{
19677 static char buff[64];
19678
540e6170
CZ
19679 switch (e_type)
19680 {
19681 case NT_NETBSDCORE_PROCINFO:
19682 /* NetBSD core "procinfo" structure. */
19683 return _("NetBSD procinfo structure");
9437c45b 19684
540e6170
CZ
19685 case NT_NETBSDCORE_AUXV:
19686 return _("NetBSD ELF auxiliary vector data");
9437c45b 19687
06d949ec
KR
19688 case NT_NETBSDCORE_LWPSTATUS:
19689 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 19690
540e6170 19691 default:
06d949ec 19692 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
19693 defined for NetBSD core files. If the note type is less
19694 than the start of the machine-dependent note types, we don't
19695 understand it. */
19696
19697 if (e_type < NT_NETBSDCORE_FIRSTMACH)
19698 {
19699 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19700 return buff;
19701 }
19702 break;
9437c45b
JT
19703 }
19704
dda8d76d 19705 switch (filedata->file_header.e_machine)
9437c45b
JT
19706 {
19707 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
19708 and PT_GETFPREGS == mach+2. */
19709
19710 case EM_OLD_ALPHA:
19711 case EM_ALPHA:
19712 case EM_SPARC:
19713 case EM_SPARC32PLUS:
19714 case EM_SPARCV9:
19715 switch (e_type)
19716 {
2b692964 19717 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 19718 return _("PT_GETREGS (reg structure)");
2b692964 19719 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 19720 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19721 default:
19722 break;
19723 }
19724 break;
19725
c0d38b0e
CZ
19726 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
19727 There's also old PT___GETREGS40 == mach + 1 for old reg
19728 structure which lacks GBR. */
19729 case EM_SH:
19730 switch (e_type)
19731 {
19732 case NT_NETBSDCORE_FIRSTMACH + 1:
19733 return _("PT___GETREGS40 (old reg structure)");
19734 case NT_NETBSDCORE_FIRSTMACH + 3:
19735 return _("PT_GETREGS (reg structure)");
19736 case NT_NETBSDCORE_FIRSTMACH + 5:
19737 return _("PT_GETFPREGS (fpreg structure)");
19738 default:
19739 break;
19740 }
19741 break;
19742
9437c45b
JT
19743 /* On all other arch's, PT_GETREGS == mach+1 and
19744 PT_GETFPREGS == mach+3. */
19745 default:
19746 switch (e_type)
19747 {
2b692964 19748 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 19749 return _("PT_GETREGS (reg structure)");
2b692964 19750 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 19751 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19752 default:
19753 break;
19754 }
19755 }
19756
9cf03b7e 19757 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 19758 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
19759 return buff;
19760}
19761
70616151
TT
19762static const char *
19763get_stapsdt_note_type (unsigned e_type)
19764{
19765 static char buff[64];
19766
19767 switch (e_type)
19768 {
19769 case NT_STAPSDT:
19770 return _("NT_STAPSDT (SystemTap probe descriptors)");
19771
19772 default:
19773 break;
19774 }
19775
19776 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19777 return buff;
19778}
19779
015dc7e1 19780static bool
c6a9fc58
TT
19781print_stapsdt_note (Elf_Internal_Note *pnote)
19782{
3ca60c57
NC
19783 size_t len, maxlen;
19784 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
19785 char *data = pnote->descdata;
19786 char *data_end = pnote->descdata + pnote->descsz;
19787 bfd_vma pc, base_addr, semaphore;
19788 char *provider, *probe, *arg_fmt;
19789
3ca60c57
NC
19790 if (pnote->descsz < (addr_size * 3))
19791 goto stapdt_note_too_small;
19792
c6a9fc58
TT
19793 pc = byte_get ((unsigned char *) data, addr_size);
19794 data += addr_size;
3ca60c57 19795
c6a9fc58
TT
19796 base_addr = byte_get ((unsigned char *) data, addr_size);
19797 data += addr_size;
3ca60c57 19798
c6a9fc58
TT
19799 semaphore = byte_get ((unsigned char *) data, addr_size);
19800 data += addr_size;
19801
3ca60c57
NC
19802 if (data >= data_end)
19803 goto stapdt_note_too_small;
19804 maxlen = data_end - data;
19805 len = strnlen (data, maxlen);
19806 if (len < maxlen)
19807 {
19808 provider = data;
19809 data += len + 1;
19810 }
19811 else
19812 goto stapdt_note_too_small;
19813
19814 if (data >= data_end)
19815 goto stapdt_note_too_small;
19816 maxlen = data_end - data;
19817 len = strnlen (data, maxlen);
19818 if (len < maxlen)
19819 {
19820 probe = data;
19821 data += len + 1;
19822 }
19823 else
19824 goto stapdt_note_too_small;
9abca702 19825
3ca60c57
NC
19826 if (data >= data_end)
19827 goto stapdt_note_too_small;
19828 maxlen = data_end - data;
19829 len = strnlen (data, maxlen);
19830 if (len < maxlen)
19831 {
19832 arg_fmt = data;
19833 data += len + 1;
19834 }
19835 else
19836 goto stapdt_note_too_small;
c6a9fc58
TT
19837
19838 printf (_(" Provider: %s\n"), provider);
19839 printf (_(" Name: %s\n"), probe);
19840 printf (_(" Location: "));
19841 print_vma (pc, FULL_HEX);
19842 printf (_(", Base: "));
19843 print_vma (base_addr, FULL_HEX);
19844 printf (_(", Semaphore: "));
19845 print_vma (semaphore, FULL_HEX);
9cf03b7e 19846 printf ("\n");
c6a9fc58
TT
19847 printf (_(" Arguments: %s\n"), arg_fmt);
19848
19849 return data == data_end;
3ca60c57
NC
19850
19851 stapdt_note_too_small:
19852 printf (_(" <corrupt - note is too small>\n"));
19853 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 19854 return false;
c6a9fc58
TT
19855}
19856
00e98fc7
TG
19857static const char *
19858get_ia64_vms_note_type (unsigned e_type)
19859{
19860 static char buff[64];
19861
19862 switch (e_type)
19863 {
19864 case NT_VMS_MHD:
19865 return _("NT_VMS_MHD (module header)");
19866 case NT_VMS_LNM:
19867 return _("NT_VMS_LNM (language name)");
19868 case NT_VMS_SRC:
19869 return _("NT_VMS_SRC (source files)");
19870 case NT_VMS_TITLE:
9cf03b7e 19871 return "NT_VMS_TITLE";
00e98fc7
TG
19872 case NT_VMS_EIDC:
19873 return _("NT_VMS_EIDC (consistency check)");
19874 case NT_VMS_FPMODE:
19875 return _("NT_VMS_FPMODE (FP mode)");
19876 case NT_VMS_LINKTIME:
9cf03b7e 19877 return "NT_VMS_LINKTIME";
00e98fc7
TG
19878 case NT_VMS_IMGNAM:
19879 return _("NT_VMS_IMGNAM (image name)");
19880 case NT_VMS_IMGID:
19881 return _("NT_VMS_IMGID (image id)");
19882 case NT_VMS_LINKID:
19883 return _("NT_VMS_LINKID (link id)");
19884 case NT_VMS_IMGBID:
19885 return _("NT_VMS_IMGBID (build id)");
19886 case NT_VMS_GSTNAM:
19887 return _("NT_VMS_GSTNAM (sym table name)");
19888 case NT_VMS_ORIG_DYN:
9cf03b7e 19889 return "NT_VMS_ORIG_DYN";
00e98fc7 19890 case NT_VMS_PATCHTIME:
9cf03b7e 19891 return "NT_VMS_PATCHTIME";
00e98fc7
TG
19892 default:
19893 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19894 return buff;
19895 }
19896}
19897
015dc7e1 19898static bool
00e98fc7
TG
19899print_ia64_vms_note (Elf_Internal_Note * pnote)
19900{
8d18bf79
NC
19901 int maxlen = pnote->descsz;
19902
19903 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
19904 goto desc_size_fail;
19905
00e98fc7
TG
19906 switch (pnote->type)
19907 {
19908 case NT_VMS_MHD:
8d18bf79
NC
19909 if (maxlen <= 36)
19910 goto desc_size_fail;
19911
19912 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
19913
19914 printf (_(" Creation date : %.17s\n"), pnote->descdata);
19915 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
19916 if (l + 34 < maxlen)
19917 {
19918 printf (_(" Module name : %s\n"), pnote->descdata + 34);
19919 if (l + 35 < maxlen)
19920 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
19921 else
19922 printf (_(" Module version : <missing>\n"));
19923 }
00e98fc7 19924 else
8d18bf79
NC
19925 {
19926 printf (_(" Module name : <missing>\n"));
19927 printf (_(" Module version : <missing>\n"));
19928 }
00e98fc7 19929 break;
8d18bf79 19930
00e98fc7 19931 case NT_VMS_LNM:
8d18bf79 19932 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19933 break;
8d18bf79 19934
00e98fc7
TG
19935#ifdef BFD64
19936 case NT_VMS_FPMODE:
9cf03b7e 19937 printf (_(" Floating Point mode: "));
8d18bf79
NC
19938 if (maxlen < 8)
19939 goto desc_size_fail;
19940 /* FIXME: Generate an error if descsz > 8 ? */
19941
4a5cb34f 19942 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 19943 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 19944 break;
8d18bf79 19945
00e98fc7
TG
19946 case NT_VMS_LINKTIME:
19947 printf (_(" Link time: "));
8d18bf79
NC
19948 if (maxlen < 8)
19949 goto desc_size_fail;
19950 /* FIXME: Generate an error if descsz > 8 ? */
19951
00e98fc7 19952 print_vms_time
8d18bf79 19953 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19954 printf ("\n");
19955 break;
8d18bf79 19956
00e98fc7
TG
19957 case NT_VMS_PATCHTIME:
19958 printf (_(" Patch time: "));
8d18bf79
NC
19959 if (maxlen < 8)
19960 goto desc_size_fail;
19961 /* FIXME: Generate an error if descsz > 8 ? */
19962
00e98fc7 19963 print_vms_time
8d18bf79 19964 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19965 printf ("\n");
19966 break;
8d18bf79 19967
00e98fc7 19968 case NT_VMS_ORIG_DYN:
8d18bf79
NC
19969 if (maxlen < 34)
19970 goto desc_size_fail;
19971
00e98fc7
TG
19972 printf (_(" Major id: %u, minor id: %u\n"),
19973 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
19974 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 19975 printf (_(" Last modified : "));
00e98fc7
TG
19976 print_vms_time
19977 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 19978 printf (_("\n Link flags : "));
4a5cb34f 19979 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 19980 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 19981 printf (_(" Header flags: 0x%08x\n"),
948f632f 19982 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 19983 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
19984 break;
19985#endif
8d18bf79 19986
00e98fc7 19987 case NT_VMS_IMGNAM:
8d18bf79 19988 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19989 break;
8d18bf79 19990
00e98fc7 19991 case NT_VMS_GSTNAM:
8d18bf79 19992 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19993 break;
8d18bf79 19994
00e98fc7 19995 case NT_VMS_IMGID:
8d18bf79 19996 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19997 break;
8d18bf79 19998
00e98fc7 19999 case NT_VMS_LINKID:
8d18bf79 20000 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20001 break;
8d18bf79 20002
00e98fc7 20003 default:
015dc7e1 20004 return false;
00e98fc7 20005 }
8d18bf79 20006
015dc7e1 20007 return true;
8d18bf79
NC
20008
20009 desc_size_fail:
20010 printf (_(" <corrupt - data size is too small>\n"));
20011 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20012 return false;
00e98fc7
TG
20013}
20014
fd486f32
AM
20015struct build_attr_cache {
20016 Filedata *filedata;
20017 char *strtab;
20018 unsigned long strtablen;
20019 Elf_Internal_Sym *symtab;
20020 unsigned long nsyms;
20021} ba_cache;
20022
6f156d7a
NC
20023/* Find the symbol associated with a build attribute that is attached
20024 to address OFFSET. If PNAME is non-NULL then store the name of
20025 the symbol (if found) in the provided pointer, Returns NULL if a
20026 symbol could not be found. */
c799a79d 20027
6f156d7a 20028static Elf_Internal_Sym *
015dc7e1
AM
20029get_symbol_for_build_attribute (Filedata *filedata,
20030 unsigned long offset,
20031 bool is_open_attr,
20032 const char **pname)
9ef920e9 20033{
fd486f32
AM
20034 Elf_Internal_Sym *saved_sym = NULL;
20035 Elf_Internal_Sym *sym;
9ef920e9 20036
dda8d76d 20037 if (filedata->section_headers != NULL
fd486f32 20038 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20039 {
c799a79d 20040 Elf_Internal_Shdr * symsec;
9ef920e9 20041
fd486f32
AM
20042 free (ba_cache.strtab);
20043 ba_cache.strtab = NULL;
20044 free (ba_cache.symtab);
20045 ba_cache.symtab = NULL;
20046
c799a79d 20047 /* Load the symbol and string sections. */
dda8d76d
NC
20048 for (symsec = filedata->section_headers;
20049 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20050 symsec ++)
9ef920e9 20051 {
28d13567
AM
20052 if (symsec->sh_type == SHT_SYMTAB
20053 && get_symtab (filedata, symsec,
20054 &ba_cache.symtab, &ba_cache.nsyms,
20055 &ba_cache.strtab, &ba_cache.strtablen))
20056 break;
9ef920e9 20057 }
fd486f32 20058 ba_cache.filedata = filedata;
9ef920e9
NC
20059 }
20060
fd486f32 20061 if (ba_cache.symtab == NULL)
6f156d7a 20062 return NULL;
9ef920e9 20063
c799a79d 20064 /* Find a symbol whose value matches offset. */
fd486f32 20065 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20066 if (sym->st_value == offset)
20067 {
fd486f32 20068 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20069 /* Huh ? This should not happen. */
20070 continue;
9ef920e9 20071
fd486f32 20072 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20073 continue;
9ef920e9 20074
8fd75781
NC
20075 /* The AArch64 and ARM architectures define mapping symbols
20076 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20077 if (ba_cache.strtab[sym->st_name] == '$'
20078 && ba_cache.strtab[sym->st_name + 1] != 0
20079 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20080 continue;
20081
c799a79d
NC
20082 if (is_open_attr)
20083 {
20084 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20085 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20086 FUNC symbols entirely. */
20087 switch (ELF_ST_TYPE (sym->st_info))
20088 {
c799a79d 20089 case STT_OBJECT:
6f156d7a 20090 case STT_FILE:
c799a79d 20091 saved_sym = sym;
6f156d7a
NC
20092 if (sym->st_size)
20093 {
20094 /* If the symbol has a size associated
20095 with it then we can stop searching. */
fd486f32 20096 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20097 }
c799a79d 20098 continue;
9ef920e9 20099
c799a79d
NC
20100 case STT_FUNC:
20101 /* Ignore function symbols. */
20102 continue;
20103
20104 default:
20105 break;
20106 }
20107
20108 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20109 {
c799a79d
NC
20110 case STB_GLOBAL:
20111 if (saved_sym == NULL
20112 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20113 saved_sym = sym;
20114 break;
c871dade 20115
c799a79d
NC
20116 case STB_LOCAL:
20117 if (saved_sym == NULL)
20118 saved_sym = sym;
20119 break;
20120
20121 default:
9ef920e9
NC
20122 break;
20123 }
20124 }
c799a79d
NC
20125 else
20126 {
20127 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20128 continue;
20129
20130 saved_sym = sym;
20131 break;
20132 }
20133 }
20134
6f156d7a 20135 if (saved_sym && pname)
fd486f32 20136 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20137
20138 return saved_sym;
c799a79d
NC
20139}
20140
d20e98ab
NC
20141/* Returns true iff addr1 and addr2 are in the same section. */
20142
015dc7e1 20143static bool
d20e98ab
NC
20144same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20145{
20146 Elf_Internal_Shdr * a1;
20147 Elf_Internal_Shdr * a2;
20148
20149 a1 = find_section_by_address (filedata, addr1);
20150 a2 = find_section_by_address (filedata, addr2);
9abca702 20151
d20e98ab
NC
20152 return a1 == a2 && a1 != NULL;
20153}
20154
015dc7e1 20155static bool
dda8d76d
NC
20156print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20157 Filedata * filedata)
c799a79d 20158{
015dc7e1
AM
20159 static unsigned long global_offset = 0;
20160 static unsigned long global_end = 0;
20161 static unsigned long func_offset = 0;
20162 static unsigned long func_end = 0;
c871dade 20163
015dc7e1
AM
20164 Elf_Internal_Sym *sym;
20165 const char *name;
20166 unsigned long start;
20167 unsigned long end;
20168 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20169
20170 switch (pnote->descsz)
c799a79d 20171 {
6f156d7a
NC
20172 case 0:
20173 /* A zero-length description means that the range of
20174 the previous note of the same type should be used. */
c799a79d 20175 if (is_open_attr)
c871dade 20176 {
6f156d7a
NC
20177 if (global_end > global_offset)
20178 printf (_(" Applies to region from %#lx to %#lx\n"),
20179 global_offset, global_end);
20180 else
20181 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20182 }
20183 else
20184 {
6f156d7a
NC
20185 if (func_end > func_offset)
20186 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20187 else
20188 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20189 }
015dc7e1 20190 return true;
9ef920e9 20191
6f156d7a
NC
20192 case 4:
20193 start = byte_get ((unsigned char *) pnote->descdata, 4);
20194 end = 0;
20195 break;
20196
20197 case 8:
c74147bb
NC
20198 start = byte_get ((unsigned char *) pnote->descdata, 4);
20199 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20200 break;
20201
20202 case 16:
20203 start = byte_get ((unsigned char *) pnote->descdata, 8);
20204 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20205 break;
9abca702 20206
6f156d7a 20207 default:
c799a79d
NC
20208 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
20209 printf (_(" <invalid descsz>"));
015dc7e1 20210 return false;
c799a79d
NC
20211 }
20212
6f156d7a
NC
20213 name = NULL;
20214 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
20215 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
20216 in order to avoid them being confused with the start address of the
20217 first function in the file... */
20218 if (sym == NULL && is_open_attr)
20219 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
20220 & name);
6f156d7a
NC
20221
20222 if (end == 0 && sym != NULL && sym->st_size > 0)
20223 end = start + sym->st_size;
c799a79d
NC
20224
20225 if (is_open_attr)
20226 {
d20e98ab
NC
20227 /* FIXME: Need to properly allow for section alignment.
20228 16 is just the alignment used on x86_64. */
20229 if (global_end > 0
20230 && start > BFD_ALIGN (global_end, 16)
20231 /* Build notes are not guaranteed to be organised in order of
20232 increasing address, but we should find the all of the notes
20233 for one section in the same place. */
20234 && same_section (filedata, start, global_end))
6f156d7a
NC
20235 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
20236 global_end + 1, start - 1);
20237
20238 printf (_(" Applies to region from %#lx"), start);
20239 global_offset = start;
20240
20241 if (end)
20242 {
20243 printf (_(" to %#lx"), end);
20244 global_end = end;
20245 }
c799a79d
NC
20246 }
20247 else
20248 {
6f156d7a
NC
20249 printf (_(" Applies to region from %#lx"), start);
20250 func_offset = start;
20251
20252 if (end)
20253 {
20254 printf (_(" to %#lx"), end);
20255 func_end = end;
20256 }
c799a79d
NC
20257 }
20258
6f156d7a
NC
20259 if (sym && name)
20260 printf (_(" (%s)"), name);
20261
20262 printf ("\n");
015dc7e1 20263 return true;
9ef920e9
NC
20264}
20265
015dc7e1 20266static bool
9ef920e9
NC
20267print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
20268{
1d15e434
NC
20269 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
20270 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
20271 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
20272 char name_type;
20273 char name_attribute;
1d15e434 20274 const char * expected_types;
9ef920e9
NC
20275 const char * name = pnote->namedata;
20276 const char * text;
88305e1b 20277 signed int left;
9ef920e9
NC
20278
20279 if (name == NULL || pnote->namesz < 2)
20280 {
20281 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 20282 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20283 return false;
9ef920e9
NC
20284 }
20285
6f156d7a
NC
20286 if (do_wide)
20287 left = 28;
20288 else
20289 left = 20;
88305e1b
NC
20290
20291 /* Version 2 of the spec adds a "GA" prefix to the name field. */
20292 if (name[0] == 'G' && name[1] == 'A')
20293 {
6f156d7a
NC
20294 if (pnote->namesz < 4)
20295 {
20296 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
20297 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20298 return false;
6f156d7a
NC
20299 }
20300
88305e1b
NC
20301 printf ("GA");
20302 name += 2;
20303 left -= 2;
20304 }
20305
9ef920e9
NC
20306 switch ((name_type = * name))
20307 {
20308 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20309 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20310 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20311 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20312 printf ("%c", * name);
88305e1b 20313 left --;
9ef920e9
NC
20314 break;
20315 default:
20316 error (_("unrecognised attribute type in name field: %d\n"), name_type);
20317 print_symbol (-20, _("<unknown name type>"));
015dc7e1 20318 return false;
9ef920e9
NC
20319 }
20320
9ef920e9
NC
20321 ++ name;
20322 text = NULL;
20323
20324 switch ((name_attribute = * name))
20325 {
20326 case GNU_BUILD_ATTRIBUTE_VERSION:
20327 text = _("<version>");
1d15e434 20328 expected_types = string_expected;
9ef920e9
NC
20329 ++ name;
20330 break;
20331 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20332 text = _("<stack prot>");
75d7d298 20333 expected_types = "!+*";
9ef920e9
NC
20334 ++ name;
20335 break;
20336 case GNU_BUILD_ATTRIBUTE_RELRO:
20337 text = _("<relro>");
1d15e434 20338 expected_types = bool_expected;
9ef920e9
NC
20339 ++ name;
20340 break;
20341 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
20342 text = _("<stack size>");
1d15e434 20343 expected_types = number_expected;
9ef920e9
NC
20344 ++ name;
20345 break;
20346 case GNU_BUILD_ATTRIBUTE_TOOL:
20347 text = _("<tool>");
1d15e434 20348 expected_types = string_expected;
9ef920e9
NC
20349 ++ name;
20350 break;
20351 case GNU_BUILD_ATTRIBUTE_ABI:
20352 text = _("<ABI>");
20353 expected_types = "$*";
20354 ++ name;
20355 break;
20356 case GNU_BUILD_ATTRIBUTE_PIC:
20357 text = _("<PIC>");
1d15e434 20358 expected_types = number_expected;
9ef920e9
NC
20359 ++ name;
20360 break;
a8be5506
NC
20361 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
20362 text = _("<short enum>");
1d15e434 20363 expected_types = bool_expected;
a8be5506
NC
20364 ++ name;
20365 break;
9ef920e9
NC
20366 default:
20367 if (ISPRINT (* name))
20368 {
20369 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
20370
20371 if (len > left && ! do_wide)
20372 len = left;
75d7d298 20373 printf ("%.*s:", len, name);
9ef920e9 20374 left -= len;
0dd6ae21 20375 name += len;
9ef920e9
NC
20376 }
20377 else
20378 {
3e6b6445 20379 static char tmpbuf [128];
88305e1b 20380
3e6b6445
NC
20381 error (_("unrecognised byte in name field: %d\n"), * name);
20382 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
20383 text = tmpbuf;
20384 name ++;
9ef920e9
NC
20385 }
20386 expected_types = "*$!+";
20387 break;
20388 }
20389
20390 if (text)
88305e1b 20391 left -= printf ("%s", text);
9ef920e9
NC
20392
20393 if (strchr (expected_types, name_type) == NULL)
75d7d298 20394 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
20395
20396 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
20397 {
20398 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
20399 (unsigned long) pnote->namesz,
20400 (long) (name - pnote->namedata));
015dc7e1 20401 return false;
9ef920e9
NC
20402 }
20403
20404 if (left < 1 && ! do_wide)
015dc7e1 20405 return true;
9ef920e9
NC
20406
20407 switch (name_type)
20408 {
20409 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20410 {
b06b2c92 20411 unsigned int bytes;
ddef72cd
NC
20412 unsigned long long val = 0;
20413 unsigned int shift = 0;
20414 char * decoded = NULL;
20415
b06b2c92
NC
20416 bytes = pnote->namesz - (name - pnote->namedata);
20417 if (bytes > 0)
20418 /* The -1 is because the name field is always 0 terminated, and we
20419 want to be able to ensure that the shift in the while loop below
20420 will not overflow. */
20421 -- bytes;
20422
ddef72cd
NC
20423 if (bytes > sizeof (val))
20424 {
3e6b6445
NC
20425 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
20426 bytes);
20427 bytes = sizeof (val);
ddef72cd 20428 }
3e6b6445
NC
20429 /* We do not bother to warn if bytes == 0 as this can
20430 happen with some early versions of the gcc plugin. */
9ef920e9
NC
20431
20432 while (bytes --)
20433 {
54b8331d 20434 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
20435
20436 val |= byte << shift;
9ef920e9
NC
20437 shift += 8;
20438 }
20439
75d7d298 20440 switch (name_attribute)
9ef920e9 20441 {
75d7d298 20442 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
20443 switch (val)
20444 {
75d7d298
NC
20445 case 0: decoded = "static"; break;
20446 case 1: decoded = "pic"; break;
20447 case 2: decoded = "PIC"; break;
20448 case 3: decoded = "pie"; break;
20449 case 4: decoded = "PIE"; break;
20450 default: break;
9ef920e9 20451 }
75d7d298
NC
20452 break;
20453 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20454 switch (val)
9ef920e9 20455 {
75d7d298
NC
20456 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
20457 case 0: decoded = "off"; break;
20458 case 1: decoded = "on"; break;
20459 case 2: decoded = "all"; break;
20460 case 3: decoded = "strong"; break;
20461 case 4: decoded = "explicit"; break;
20462 default: break;
9ef920e9 20463 }
75d7d298
NC
20464 break;
20465 default:
20466 break;
9ef920e9
NC
20467 }
20468
75d7d298 20469 if (decoded != NULL)
3e6b6445
NC
20470 {
20471 print_symbol (-left, decoded);
20472 left = 0;
20473 }
20474 else if (val == 0)
20475 {
20476 printf ("0x0");
20477 left -= 3;
20478 }
9ef920e9 20479 else
75d7d298
NC
20480 {
20481 if (do_wide)
ddef72cd 20482 left -= printf ("0x%llx", val);
75d7d298 20483 else
ddef72cd 20484 left -= printf ("0x%-.*llx", left, val);
75d7d298 20485 }
9ef920e9
NC
20486 }
20487 break;
20488 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20489 left -= print_symbol (- left, name);
20490 break;
20491 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20492 left -= print_symbol (- left, "true");
20493 break;
20494 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20495 left -= print_symbol (- left, "false");
20496 break;
20497 }
20498
20499 if (do_wide && left > 0)
20500 printf ("%-*s", left, " ");
9abca702 20501
015dc7e1 20502 return true;
9ef920e9
NC
20503}
20504
6d118b09
NC
20505/* Note that by the ELF standard, the name field is already null byte
20506 terminated, and namesz includes the terminating null byte.
20507 I.E. the value of namesz for the name "FSF" is 4.
20508
e3c8793a 20509 If the value of namesz is zero, there is no name present. */
9ef920e9 20510
015dc7e1 20511static bool
9ef920e9 20512process_note (Elf_Internal_Note * pnote,
dda8d76d 20513 Filedata * filedata)
779fe533 20514{
2cf0635d
NC
20515 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
20516 const char * nt;
9437c45b
JT
20517
20518 if (pnote->namesz == 0)
1ec5cd37
NC
20519 /* If there is no note name, then use the default set of
20520 note type strings. */
dda8d76d 20521 nt = get_note_type (filedata, pnote->type);
1ec5cd37 20522
24d127aa 20523 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
20524 /* GNU-specific object file notes. */
20525 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 20526
24d127aa 20527 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 20528 /* FreeBSD-specific core file notes. */
dda8d76d 20529 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 20530
24d127aa 20531 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 20532 /* NetBSD-specific core file notes. */
dda8d76d 20533 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 20534
24d127aa 20535 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
20536 /* NetBSD-specific core file notes. */
20537 return process_netbsd_elf_note (pnote);
20538
24d127aa 20539 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
20540 /* NetBSD-specific core file notes. */
20541 return process_netbsd_elf_note (pnote);
20542
e9b095a5 20543 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
20544 {
20545 /* SPU-specific core file notes. */
20546 nt = pnote->namedata + 4;
20547 name = "SPU";
20548 }
20549
24d127aa 20550 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
20551 /* VMS/ia64-specific file notes. */
20552 nt = get_ia64_vms_note_type (pnote->type);
20553
24d127aa 20554 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
20555 nt = get_stapsdt_note_type (pnote->type);
20556
9437c45b 20557 else
1ec5cd37
NC
20558 /* Don't recognize this note name; just use the default set of
20559 note type strings. */
dda8d76d 20560 nt = get_note_type (filedata, pnote->type);
9437c45b 20561
1449284b 20562 printf (" ");
9ef920e9 20563
24d127aa 20564 if (((startswith (pnote->namedata, "GA")
483767a3
AM
20565 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20566 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20567 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20568 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
20569 print_gnu_build_attribute_name (pnote);
20570 else
20571 print_symbol (-20, name);
20572
20573 if (do_wide)
20574 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
20575 else
20576 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 20577
24d127aa 20578 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 20579 return print_ia64_vms_note (pnote);
24d127aa 20580 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 20581 return print_gnu_note (filedata, pnote);
24d127aa 20582 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 20583 return print_stapsdt_note (pnote);
24d127aa 20584 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 20585 return print_core_note (pnote);
24d127aa 20586 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
20587 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20588 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20589 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20590 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 20591 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 20592
9ef920e9 20593 if (pnote->descsz)
1449284b
NC
20594 {
20595 unsigned long i;
20596
20597 printf (_(" description data: "));
20598 for (i = 0; i < pnote->descsz; i++)
178d8719 20599 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
20600 if (!do_wide)
20601 printf ("\n");
1449284b
NC
20602 }
20603
9ef920e9
NC
20604 if (do_wide)
20605 printf ("\n");
20606
015dc7e1 20607 return true;
1449284b 20608}
6d118b09 20609
015dc7e1 20610static bool
dda8d76d
NC
20611process_notes_at (Filedata * filedata,
20612 Elf_Internal_Shdr * section,
20613 bfd_vma offset,
82ed9683
L
20614 bfd_vma length,
20615 bfd_vma align)
779fe533 20616{
015dc7e1
AM
20617 Elf_External_Note *pnotes;
20618 Elf_External_Note *external;
20619 char *end;
20620 bool res = true;
103f02d3 20621
779fe533 20622 if (length <= 0)
015dc7e1 20623 return false;
103f02d3 20624
1449284b
NC
20625 if (section)
20626 {
dda8d76d 20627 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 20628 if (pnotes)
32ec8896 20629 {
dda8d76d 20630 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
20631 {
20632 free (pnotes);
015dc7e1 20633 return false;
f761cb13 20634 }
32ec8896 20635 }
1449284b
NC
20636 }
20637 else
82ed9683 20638 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 20639 _("notes"));
4dff97b2 20640
dd24e3da 20641 if (pnotes == NULL)
015dc7e1 20642 return false;
779fe533 20643
103f02d3 20644 external = pnotes;
103f02d3 20645
ca0e11aa
NC
20646 if (filedata->is_separate)
20647 printf (_("In linked file '%s': "), filedata->file_name);
20648 else
20649 printf ("\n");
1449284b 20650 if (section)
ca0e11aa 20651 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 20652 else
ca0e11aa 20653 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
20654 (unsigned long) offset, (unsigned long) length);
20655
82ed9683
L
20656 /* NB: Some note sections may have alignment value of 0 or 1. gABI
20657 specifies that notes should be aligned to 4 bytes in 32-bit
20658 objects and to 8 bytes in 64-bit objects. As a Linux extension,
20659 we also support 4 byte alignment in 64-bit objects. If section
20660 alignment is less than 4, we treate alignment as 4 bytes. */
20661 if (align < 4)
20662 align = 4;
20663 else if (align != 4 && align != 8)
20664 {
20665 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
20666 (long) align);
a788aedd 20667 free (pnotes);
015dc7e1 20668 return false;
82ed9683
L
20669 }
20670
dbe15e4e 20671 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 20672
c8071705
NC
20673 end = (char *) pnotes + length;
20674 while ((char *) external < end)
779fe533 20675 {
b34976b6 20676 Elf_Internal_Note inote;
15b42fb0 20677 size_t min_notesz;
4dff97b2 20678 char * next;
2cf0635d 20679 char * temp = NULL;
c8071705 20680 size_t data_remaining = end - (char *) external;
6d118b09 20681
dda8d76d 20682 if (!is_ia64_vms (filedata))
15b42fb0 20683 {
9dd3a467
NC
20684 /* PR binutils/15191
20685 Make sure that there is enough data to read. */
15b42fb0
AM
20686 min_notesz = offsetof (Elf_External_Note, name);
20687 if (data_remaining < min_notesz)
9dd3a467 20688 {
d3a49aa8
AM
20689 warn (ngettext ("Corrupt note: only %ld byte remains, "
20690 "not enough for a full note\n",
20691 "Corrupt note: only %ld bytes remain, "
20692 "not enough for a full note\n",
20693 data_remaining),
20694 (long) data_remaining);
9dd3a467
NC
20695 break;
20696 }
5396a86e
AM
20697 data_remaining -= min_notesz;
20698
15b42fb0
AM
20699 inote.type = BYTE_GET (external->type);
20700 inote.namesz = BYTE_GET (external->namesz);
20701 inote.namedata = external->name;
20702 inote.descsz = BYTE_GET (external->descsz);
276da9b3 20703 inote.descdata = ((char *) external
4dff97b2 20704 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 20705 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 20706 next = ((char *) external
4dff97b2 20707 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 20708 }
00e98fc7 20709 else
15b42fb0
AM
20710 {
20711 Elf64_External_VMS_Note *vms_external;
00e98fc7 20712
9dd3a467
NC
20713 /* PR binutils/15191
20714 Make sure that there is enough data to read. */
15b42fb0
AM
20715 min_notesz = offsetof (Elf64_External_VMS_Note, name);
20716 if (data_remaining < min_notesz)
9dd3a467 20717 {
d3a49aa8
AM
20718 warn (ngettext ("Corrupt note: only %ld byte remains, "
20719 "not enough for a full note\n",
20720 "Corrupt note: only %ld bytes remain, "
20721 "not enough for a full note\n",
20722 data_remaining),
20723 (long) data_remaining);
9dd3a467
NC
20724 break;
20725 }
5396a86e 20726 data_remaining -= min_notesz;
3e55a963 20727
15b42fb0
AM
20728 vms_external = (Elf64_External_VMS_Note *) external;
20729 inote.type = BYTE_GET (vms_external->type);
20730 inote.namesz = BYTE_GET (vms_external->namesz);
20731 inote.namedata = vms_external->name;
20732 inote.descsz = BYTE_GET (vms_external->descsz);
20733 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
20734 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20735 next = inote.descdata + align_power (inote.descsz, 3);
20736 }
20737
5396a86e
AM
20738 /* PR 17531: file: 3443835e. */
20739 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
20740 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
20741 || (size_t) (inote.descdata - inote.namedata) > data_remaining
20742 || (size_t) (next - inote.descdata) < inote.descsz
20743 || ((size_t) (next - inote.descdata)
20744 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 20745 {
15b42fb0 20746 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 20747 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
20748 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
20749 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
20750 break;
20751 }
20752
15b42fb0 20753 external = (Elf_External_Note *) next;
dd24e3da 20754
6d118b09
NC
20755 /* Verify that name is null terminated. It appears that at least
20756 one version of Linux (RedHat 6.0) generates corefiles that don't
20757 comply with the ELF spec by failing to include the null byte in
20758 namesz. */
18344509 20759 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 20760 {
5396a86e 20761 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 20762 {
5396a86e
AM
20763 temp = (char *) malloc (inote.namesz + 1);
20764 if (temp == NULL)
20765 {
20766 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 20767 res = false;
5396a86e
AM
20768 break;
20769 }
76da6bbe 20770
5396a86e
AM
20771 memcpy (temp, inote.namedata, inote.namesz);
20772 inote.namedata = temp;
20773 }
20774 inote.namedata[inote.namesz] = 0;
6d118b09
NC
20775 }
20776
dda8d76d 20777 if (! process_note (& inote, filedata))
015dc7e1 20778 res = false;
103f02d3 20779
9db70fc3
AM
20780 free (temp);
20781 temp = NULL;
779fe533
NC
20782 }
20783
20784 free (pnotes);
103f02d3 20785
779fe533
NC
20786 return res;
20787}
20788
015dc7e1 20789static bool
dda8d76d 20790process_corefile_note_segments (Filedata * filedata)
779fe533 20791{
015dc7e1 20792 Elf_Internal_Phdr *segment;
b34976b6 20793 unsigned int i;
015dc7e1 20794 bool res = true;
103f02d3 20795
dda8d76d 20796 if (! get_program_headers (filedata))
015dc7e1 20797 return true;
103f02d3 20798
dda8d76d
NC
20799 for (i = 0, segment = filedata->program_headers;
20800 i < filedata->file_header.e_phnum;
b34976b6 20801 i++, segment++)
779fe533
NC
20802 {
20803 if (segment->p_type == PT_NOTE)
dda8d76d 20804 if (! process_notes_at (filedata, NULL,
32ec8896 20805 (bfd_vma) segment->p_offset,
82ed9683
L
20806 (bfd_vma) segment->p_filesz,
20807 (bfd_vma) segment->p_align))
015dc7e1 20808 res = false;
779fe533 20809 }
103f02d3 20810
779fe533
NC
20811 return res;
20812}
20813
015dc7e1 20814static bool
dda8d76d 20815process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
20816{
20817 Elf_External_Note * pnotes;
20818 Elf_External_Note * external;
c8071705 20819 char * end;
015dc7e1 20820 bool res = true;
685080f2
NC
20821
20822 if (length <= 0)
015dc7e1 20823 return false;
685080f2 20824
dda8d76d 20825 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
20826 _("v850 notes"));
20827 if (pnotes == NULL)
015dc7e1 20828 return false;
685080f2
NC
20829
20830 external = pnotes;
c8071705 20831 end = (char*) pnotes + length;
685080f2
NC
20832
20833 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
20834 (unsigned long) offset, (unsigned long) length);
20835
c8071705 20836 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
20837 {
20838 Elf_External_Note * next;
20839 Elf_Internal_Note inote;
20840
20841 inote.type = BYTE_GET (external->type);
20842 inote.namesz = BYTE_GET (external->namesz);
20843 inote.namedata = external->name;
20844 inote.descsz = BYTE_GET (external->descsz);
20845 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
20846 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20847
c8071705
NC
20848 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
20849 {
20850 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
20851 inote.descdata = inote.namedata;
20852 inote.namesz = 0;
20853 }
20854
685080f2
NC
20855 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
20856
c8071705 20857 if ( ((char *) next > end)
685080f2
NC
20858 || ((char *) next < (char *) pnotes))
20859 {
20860 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
20861 (unsigned long) ((char *) external - (char *) pnotes));
20862 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20863 inote.type, inote.namesz, inote.descsz);
20864 break;
20865 }
20866
20867 external = next;
20868
20869 /* Prevent out-of-bounds indexing. */
c8071705 20870 if ( inote.namedata + inote.namesz > end
685080f2
NC
20871 || inote.namedata + inote.namesz < inote.namedata)
20872 {
20873 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
20874 (unsigned long) ((char *) external - (char *) pnotes));
20875 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20876 inote.type, inote.namesz, inote.descsz);
20877 break;
20878 }
20879
20880 printf (" %s: ", get_v850_elf_note_type (inote.type));
20881
20882 if (! print_v850_note (& inote))
20883 {
015dc7e1 20884 res = false;
685080f2
NC
20885 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
20886 inote.namesz, inote.descsz);
20887 }
20888 }
20889
20890 free (pnotes);
20891
20892 return res;
20893}
20894
015dc7e1 20895static bool
dda8d76d 20896process_note_sections (Filedata * filedata)
1ec5cd37 20897{
015dc7e1 20898 Elf_Internal_Shdr *section;
1ec5cd37 20899 unsigned long i;
32ec8896 20900 unsigned int n = 0;
015dc7e1 20901 bool res = true;
1ec5cd37 20902
dda8d76d
NC
20903 for (i = 0, section = filedata->section_headers;
20904 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 20905 i++, section++)
685080f2
NC
20906 {
20907 if (section->sh_type == SHT_NOTE)
20908 {
dda8d76d 20909 if (! process_notes_at (filedata, section,
32ec8896 20910 (bfd_vma) section->sh_offset,
82ed9683
L
20911 (bfd_vma) section->sh_size,
20912 (bfd_vma) section->sh_addralign))
015dc7e1 20913 res = false;
685080f2
NC
20914 n++;
20915 }
20916
dda8d76d
NC
20917 if (( filedata->file_header.e_machine == EM_V800
20918 || filedata->file_header.e_machine == EM_V850
20919 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
20920 && section->sh_type == SHT_RENESAS_INFO)
20921 {
dda8d76d 20922 if (! process_v850_notes (filedata,
32ec8896
NC
20923 (bfd_vma) section->sh_offset,
20924 (bfd_vma) section->sh_size))
015dc7e1 20925 res = false;
685080f2
NC
20926 n++;
20927 }
20928 }
df565f32
NC
20929
20930 if (n == 0)
20931 /* Try processing NOTE segments instead. */
dda8d76d 20932 return process_corefile_note_segments (filedata);
1ec5cd37
NC
20933
20934 return res;
20935}
20936
015dc7e1 20937static bool
dda8d76d 20938process_notes (Filedata * filedata)
779fe533
NC
20939{
20940 /* If we have not been asked to display the notes then do nothing. */
20941 if (! do_notes)
015dc7e1 20942 return true;
103f02d3 20943
dda8d76d
NC
20944 if (filedata->file_header.e_type != ET_CORE)
20945 return process_note_sections (filedata);
103f02d3 20946
779fe533 20947 /* No program headers means no NOTE segment. */
dda8d76d
NC
20948 if (filedata->file_header.e_phnum > 0)
20949 return process_corefile_note_segments (filedata);
779fe533 20950
ca0e11aa
NC
20951 if (filedata->is_separate)
20952 printf (_("No notes found in linked file '%s'.\n"),
20953 filedata->file_name);
20954 else
20955 printf (_("No notes found file.\n"));
20956
015dc7e1 20957 return true;
779fe533
NC
20958}
20959
60abdbed
NC
20960static unsigned char *
20961display_public_gnu_attributes (unsigned char * start,
20962 const unsigned char * const end)
20963{
20964 printf (_(" Unknown GNU attribute: %s\n"), start);
20965
20966 start += strnlen ((char *) start, end - start);
20967 display_raw_attribute (start, end);
20968
20969 return (unsigned char *) end;
20970}
20971
20972static unsigned char *
20973display_generic_attribute (unsigned char * start,
20974 unsigned int tag,
20975 const unsigned char * const end)
20976{
20977 if (tag == 0)
20978 return (unsigned char *) end;
20979
20980 return display_tag_value (tag, start, end);
20981}
20982
015dc7e1 20983static bool
dda8d76d 20984process_arch_specific (Filedata * filedata)
252b5132 20985{
a952a375 20986 if (! do_arch)
015dc7e1 20987 return true;
a952a375 20988
dda8d76d 20989 switch (filedata->file_header.e_machine)
252b5132 20990 {
53a346d8
CZ
20991 case EM_ARC:
20992 case EM_ARC_COMPACT:
20993 case EM_ARC_COMPACT2:
dda8d76d 20994 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
20995 display_arc_attribute,
20996 display_generic_attribute);
11c1ff18 20997 case EM_ARM:
dda8d76d 20998 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
20999 display_arm_attribute,
21000 display_generic_attribute);
21001
252b5132 21002 case EM_MIPS:
4fe85591 21003 case EM_MIPS_RS3_LE:
dda8d76d 21004 return process_mips_specific (filedata);
60abdbed
NC
21005
21006 case EM_MSP430:
dda8d76d 21007 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21008 display_msp430_attribute,
c0ea7c52 21009 display_msp430_gnu_attribute);
60abdbed 21010
2dc8dd17
JW
21011 case EM_RISCV:
21012 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21013 display_riscv_attribute,
21014 display_generic_attribute);
21015
35c08157 21016 case EM_NDS32:
dda8d76d 21017 return process_nds32_specific (filedata);
60abdbed 21018
85f7484a
PB
21019 case EM_68K:
21020 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21021 display_m68k_gnu_attribute);
21022
34c8bcba 21023 case EM_PPC:
b82317dd 21024 case EM_PPC64:
dda8d76d 21025 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21026 display_power_gnu_attribute);
21027
643f7afb
AK
21028 case EM_S390:
21029 case EM_S390_OLD:
dda8d76d 21030 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21031 display_s390_gnu_attribute);
21032
9e8c70f9
DM
21033 case EM_SPARC:
21034 case EM_SPARC32PLUS:
21035 case EM_SPARCV9:
dda8d76d 21036 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21037 display_sparc_gnu_attribute);
21038
59e6276b 21039 case EM_TI_C6000:
dda8d76d 21040 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
21041 display_tic6x_attribute,
21042 display_generic_attribute);
21043
0861f561
CQ
21044 case EM_CSKY:
21045 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
21046 display_csky_attribute, NULL);
21047
252b5132 21048 default:
dda8d76d 21049 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
21050 display_public_gnu_attributes,
21051 display_generic_attribute);
252b5132 21052 }
252b5132
RH
21053}
21054
015dc7e1 21055static bool
dda8d76d 21056get_file_header (Filedata * filedata)
252b5132 21057{
9ea033b2 21058 /* Read in the identity array. */
dda8d76d 21059 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21060 return false;
252b5132 21061
9ea033b2 21062 /* Determine how to read the rest of the header. */
dda8d76d 21063 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 21064 {
1a0670f3
AM
21065 default:
21066 case ELFDATANONE:
adab8cdc
AO
21067 case ELFDATA2LSB:
21068 byte_get = byte_get_little_endian;
21069 byte_put = byte_put_little_endian;
21070 break;
21071 case ELFDATA2MSB:
21072 byte_get = byte_get_big_endian;
21073 byte_put = byte_put_big_endian;
21074 break;
9ea033b2
NC
21075 }
21076
21077 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 21078 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
21079
21080 /* Read in the rest of the header. */
21081 if (is_32bit_elf)
21082 {
21083 Elf32_External_Ehdr ehdr32;
252b5132 21084
dda8d76d 21085 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21086 return false;
103f02d3 21087
dda8d76d
NC
21088 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
21089 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
21090 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
21091 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
21092 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
21093 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
21094 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
21095 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
21096 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
21097 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
21098 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
21099 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
21100 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 21101 }
252b5132 21102 else
9ea033b2
NC
21103 {
21104 Elf64_External_Ehdr ehdr64;
a952a375
NC
21105
21106 /* If we have been compiled with sizeof (bfd_vma) == 4, then
21107 we will not be able to cope with the 64bit data found in
21108 64 ELF files. Detect this now and abort before we start
50c2245b 21109 overwriting things. */
a952a375
NC
21110 if (sizeof (bfd_vma) < 8)
21111 {
e3c8793a
NC
21112 error (_("This instance of readelf has been built without support for a\n\
2111364 bit data type and so it cannot read 64 bit ELF files.\n"));
015dc7e1 21114 return false;
a952a375 21115 }
103f02d3 21116
dda8d76d 21117 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21118 return false;
103f02d3 21119
dda8d76d
NC
21120 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
21121 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
21122 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
21123 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
21124 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
21125 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
21126 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
21127 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
21128 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
21129 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
21130 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
21131 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
21132 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 21133 }
252b5132 21134
dda8d76d 21135 if (filedata->file_header.e_shoff)
7ece0d85
JJ
21136 {
21137 /* There may be some extensions in the first section header. Don't
21138 bomb if we can't read it. */
21139 if (is_32bit_elf)
015dc7e1 21140 get_32bit_section_headers (filedata, true);
7ece0d85 21141 else
015dc7e1 21142 get_64bit_section_headers (filedata, true);
7ece0d85 21143 }
560f3c1c 21144
015dc7e1 21145 return true;
252b5132
RH
21146}
21147
13acb58d
AM
21148static void
21149free_filedata (Filedata *filedata)
21150{
21151 free (filedata->program_interpreter);
21152 filedata->program_interpreter = NULL;
21153
21154 free (filedata->program_headers);
21155 filedata->program_headers = NULL;
21156
21157 free (filedata->section_headers);
21158 filedata->section_headers = NULL;
21159
21160 free (filedata->string_table);
21161 filedata->string_table = NULL;
21162 filedata->string_table_length = 0;
21163
21164 free (filedata->dump.dump_sects);
21165 filedata->dump.dump_sects = NULL;
21166 filedata->dump.num_dump_sects = 0;
21167
21168 free (filedata->dynamic_strings);
21169 filedata->dynamic_strings = NULL;
21170 filedata->dynamic_strings_length = 0;
21171
21172 free (filedata->dynamic_symbols);
21173 filedata->dynamic_symbols = NULL;
21174 filedata->num_dynamic_syms = 0;
21175
21176 free (filedata->dynamic_syminfo);
21177 filedata->dynamic_syminfo = NULL;
21178
21179 free (filedata->dynamic_section);
21180 filedata->dynamic_section = NULL;
21181
21182 while (filedata->symtab_shndx_list != NULL)
21183 {
21184 elf_section_list *next = filedata->symtab_shndx_list->next;
21185 free (filedata->symtab_shndx_list);
21186 filedata->symtab_shndx_list = next;
21187 }
21188
21189 free (filedata->section_headers_groups);
21190 filedata->section_headers_groups = NULL;
21191
21192 if (filedata->section_groups)
21193 {
21194 size_t i;
21195 struct group_list * g;
21196 struct group_list * next;
21197
21198 for (i = 0; i < filedata->group_count; i++)
21199 {
21200 for (g = filedata->section_groups [i].root; g != NULL; g = next)
21201 {
21202 next = g->next;
21203 free (g);
21204 }
21205 }
21206
21207 free (filedata->section_groups);
21208 filedata->section_groups = NULL;
21209 }
21210}
21211
dda8d76d
NC
21212static void
21213close_file (Filedata * filedata)
21214{
21215 if (filedata)
21216 {
21217 if (filedata->handle)
21218 fclose (filedata->handle);
21219 free (filedata);
21220 }
21221}
21222
21223void
21224close_debug_file (void * data)
21225{
13acb58d 21226 free_filedata ((Filedata *) data);
dda8d76d
NC
21227 close_file ((Filedata *) data);
21228}
21229
21230static Filedata *
015dc7e1 21231open_file (const char * pathname, bool is_separate)
dda8d76d
NC
21232{
21233 struct stat statbuf;
21234 Filedata * filedata = NULL;
21235
21236 if (stat (pathname, & statbuf) < 0
21237 || ! S_ISREG (statbuf.st_mode))
21238 goto fail;
21239
21240 filedata = calloc (1, sizeof * filedata);
21241 if (filedata == NULL)
21242 goto fail;
21243
21244 filedata->handle = fopen (pathname, "rb");
21245 if (filedata->handle == NULL)
21246 goto fail;
21247
21248 filedata->file_size = (bfd_size_type) statbuf.st_size;
21249 filedata->file_name = pathname;
ca0e11aa 21250 filedata->is_separate = is_separate;
dda8d76d
NC
21251
21252 if (! get_file_header (filedata))
21253 goto fail;
21254
21255 if (filedata->file_header.e_shoff)
21256 {
015dc7e1 21257 bool res;
dda8d76d
NC
21258
21259 /* Read the section headers again, this time for real. */
21260 if (is_32bit_elf)
015dc7e1 21261 res = get_32bit_section_headers (filedata, false);
dda8d76d 21262 else
015dc7e1 21263 res = get_64bit_section_headers (filedata, false);
dda8d76d
NC
21264
21265 if (!res)
21266 goto fail;
21267 }
21268
21269 return filedata;
21270
21271 fail:
21272 if (filedata)
21273 {
21274 if (filedata->handle)
21275 fclose (filedata->handle);
21276 free (filedata);
21277 }
21278 return NULL;
21279}
21280
21281void *
21282open_debug_file (const char * pathname)
21283{
015dc7e1 21284 return open_file (pathname, true);
dda8d76d
NC
21285}
21286
835f2fae
NC
21287static void
21288initialise_dump_sects (Filedata * filedata)
21289{
21290 /* Initialise the dump_sects array from the cmdline_dump_sects array.
21291 Note we do this even if cmdline_dump_sects is empty because we
21292 must make sure that the dump_sets array is zeroed out before each
21293 object file is processed. */
21294 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
21295 memset (filedata->dump.dump_sects, 0,
21296 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21297
21298 if (cmdline.num_dump_sects > 0)
21299 {
21300 if (filedata->dump.num_dump_sects == 0)
21301 /* A sneaky way of allocating the dump_sects array. */
21302 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
21303
21304 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
21305 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
21306 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21307 }
21308}
21309
fb52b2f4
NC
21310/* Process one ELF object file according to the command line options.
21311 This file may actually be stored in an archive. The file is
32ec8896
NC
21312 positioned at the start of the ELF object. Returns TRUE if no
21313 problems were encountered, FALSE otherwise. */
fb52b2f4 21314
015dc7e1 21315static bool
dda8d76d 21316process_object (Filedata * filedata)
252b5132 21317{
015dc7e1 21318 bool have_separate_files;
252b5132 21319 unsigned int i;
015dc7e1 21320 bool res;
252b5132 21321
dda8d76d 21322 if (! get_file_header (filedata))
252b5132 21323 {
dda8d76d 21324 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 21325 return false;
252b5132
RH
21326 }
21327
21328 /* Initialise per file variables. */
978c4450
AM
21329 for (i = ARRAY_SIZE (filedata->version_info); i--;)
21330 filedata->version_info[i] = 0;
252b5132 21331
978c4450
AM
21332 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
21333 filedata->dynamic_info[i] = 0;
21334 filedata->dynamic_info_DT_GNU_HASH = 0;
21335 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
21336
21337 /* Process the file. */
21338 if (show_name)
dda8d76d 21339 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 21340
835f2fae 21341 initialise_dump_sects (filedata);
d70c5fc7 21342
dda8d76d 21343 if (! process_file_header (filedata))
015dc7e1 21344 return false;
252b5132 21345
dda8d76d 21346 if (! process_section_headers (filedata))
2f62977e 21347 {
32ec8896 21348 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 21349 do_unwind = do_version = do_dump = do_arch = false;
252b5132 21350
2f62977e 21351 if (! do_using_dynamic)
015dc7e1 21352 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 21353 }
252b5132 21354
dda8d76d 21355 if (! process_section_groups (filedata))
32ec8896 21356 /* Without loaded section groups we cannot process unwind. */
015dc7e1 21357 do_unwind = false;
d1f5c6e3 21358
2482f306
AM
21359 res = process_program_headers (filedata);
21360 if (res)
21361 res = process_dynamic_section (filedata);
252b5132 21362
dda8d76d 21363 if (! process_relocs (filedata))
015dc7e1 21364 res = false;
252b5132 21365
dda8d76d 21366 if (! process_unwind (filedata))
015dc7e1 21367 res = false;
4d6ed7c8 21368
dda8d76d 21369 if (! process_symbol_table (filedata))
015dc7e1 21370 res = false;
252b5132 21371
0f03783c 21372 if (! process_lto_symbol_tables (filedata))
015dc7e1 21373 res = false;
b9e920ec 21374
dda8d76d 21375 if (! process_syminfo (filedata))
015dc7e1 21376 res = false;
252b5132 21377
dda8d76d 21378 if (! process_version_sections (filedata))
015dc7e1 21379 res = false;
252b5132 21380
82ed9683 21381 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 21382 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 21383 else
015dc7e1 21384 have_separate_files = false;
dda8d76d
NC
21385
21386 if (! process_section_contents (filedata))
015dc7e1 21387 res = false;
f5842774 21388
24841daa 21389 if (have_separate_files)
dda8d76d 21390 {
24841daa
NC
21391 separate_info * d;
21392
21393 for (d = first_separate_info; d != NULL; d = d->next)
21394 {
835f2fae
NC
21395 initialise_dump_sects (d->handle);
21396
ca0e11aa 21397 if (process_links && ! process_file_header (d->handle))
015dc7e1 21398 res = false;
ca0e11aa 21399 else if (! process_section_headers (d->handle))
015dc7e1 21400 res = false;
d6bfbc39 21401 else if (! process_section_contents (d->handle))
015dc7e1 21402 res = false;
ca0e11aa
NC
21403 else if (process_links)
21404 {
ca0e11aa 21405 if (! process_section_groups (d->handle))
015dc7e1 21406 res = false;
ca0e11aa 21407 if (! process_program_headers (d->handle))
015dc7e1 21408 res = false;
ca0e11aa 21409 if (! process_dynamic_section (d->handle))
015dc7e1 21410 res = false;
ca0e11aa 21411 if (! process_relocs (d->handle))
015dc7e1 21412 res = false;
ca0e11aa 21413 if (! process_unwind (d->handle))
015dc7e1 21414 res = false;
ca0e11aa 21415 if (! process_symbol_table (d->handle))
015dc7e1 21416 res = false;
ca0e11aa 21417 if (! process_lto_symbol_tables (d->handle))
015dc7e1 21418 res = false;
ca0e11aa 21419 if (! process_syminfo (d->handle))
015dc7e1 21420 res = false;
ca0e11aa 21421 if (! process_version_sections (d->handle))
015dc7e1 21422 res = false;
ca0e11aa 21423 if (! process_notes (d->handle))
015dc7e1 21424 res = false;
ca0e11aa 21425 }
24841daa
NC
21426 }
21427
21428 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
21429 }
21430
21431 if (! process_notes (filedata))
015dc7e1 21432 res = false;
103f02d3 21433
dda8d76d 21434 if (! process_gnu_liblist (filedata))
015dc7e1 21435 res = false;
047b2264 21436
dda8d76d 21437 if (! process_arch_specific (filedata))
015dc7e1 21438 res = false;
252b5132 21439
13acb58d 21440 free_filedata (filedata);
e4b17d5c 21441
19e6b90e 21442 free_debug_memory ();
18bd398b 21443
32ec8896 21444 return res;
252b5132
RH
21445}
21446
2cf0635d 21447/* Process an ELF archive.
32ec8896
NC
21448 On entry the file is positioned just after the ARMAG string.
21449 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 21450
015dc7e1
AM
21451static bool
21452process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
21453{
21454 struct archive_info arch;
21455 struct archive_info nested_arch;
21456 size_t got;
015dc7e1 21457 bool ret = true;
2cf0635d 21458
015dc7e1 21459 show_name = true;
2cf0635d
NC
21460
21461 /* The ARCH structure is used to hold information about this archive. */
21462 arch.file_name = NULL;
21463 arch.file = NULL;
21464 arch.index_array = NULL;
21465 arch.sym_table = NULL;
21466 arch.longnames = NULL;
21467
21468 /* The NESTED_ARCH structure is used as a single-item cache of information
21469 about a nested archive (when members of a thin archive reside within
21470 another regular archive file). */
21471 nested_arch.file_name = NULL;
21472 nested_arch.file = NULL;
21473 nested_arch.index_array = NULL;
21474 nested_arch.sym_table = NULL;
21475 nested_arch.longnames = NULL;
21476
dda8d76d 21477 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
21478 filedata->file_size, is_thin_archive,
21479 do_archive_index) != 0)
2cf0635d 21480 {
015dc7e1 21481 ret = false;
2cf0635d 21482 goto out;
4145f1d5 21483 }
fb52b2f4 21484
4145f1d5
NC
21485 if (do_archive_index)
21486 {
2cf0635d 21487 if (arch.sym_table == NULL)
1cb7d8b1
AM
21488 error (_("%s: unable to dump the index as none was found\n"),
21489 filedata->file_name);
4145f1d5
NC
21490 else
21491 {
591f7597 21492 unsigned long i, l;
4145f1d5
NC
21493 unsigned long current_pos;
21494
1cb7d8b1
AM
21495 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
21496 "in the symbol table)\n"),
21497 filedata->file_name, (unsigned long) arch.index_num,
21498 arch.sym_size);
dda8d76d
NC
21499
21500 current_pos = ftell (filedata->handle);
4145f1d5 21501
2cf0635d 21502 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 21503 {
1cb7d8b1
AM
21504 if (i == 0
21505 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
21506 {
21507 char * member_name
21508 = get_archive_member_name_at (&arch, arch.index_array[i],
21509 &nested_arch);
2cf0635d 21510
1cb7d8b1
AM
21511 if (member_name != NULL)
21512 {
21513 char * qualified_name
21514 = make_qualified_name (&arch, &nested_arch,
21515 member_name);
2cf0635d 21516
1cb7d8b1
AM
21517 if (qualified_name != NULL)
21518 {
21519 printf (_("Contents of binary %s at offset "),
21520 qualified_name);
c2a7d3f5
NC
21521 (void) print_vma (arch.index_array[i], PREFIX_HEX);
21522 putchar ('\n');
1cb7d8b1
AM
21523 free (qualified_name);
21524 }
fd486f32 21525 free (member_name);
4145f1d5
NC
21526 }
21527 }
2cf0635d
NC
21528
21529 if (l >= arch.sym_size)
4145f1d5 21530 {
1cb7d8b1
AM
21531 error (_("%s: end of the symbol table reached "
21532 "before the end of the index\n"),
dda8d76d 21533 filedata->file_name);
015dc7e1 21534 ret = false;
cb8f3167 21535 break;
4145f1d5 21536 }
591f7597 21537 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
21538 printf ("\t%.*s\n",
21539 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 21540 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
21541 }
21542
67ce483b 21543 if (arch.uses_64bit_indices)
c2a7d3f5
NC
21544 l = (l + 7) & ~ 7;
21545 else
21546 l += l & 1;
21547
2cf0635d 21548 if (l < arch.sym_size)
32ec8896 21549 {
d3a49aa8
AM
21550 error (ngettext ("%s: %ld byte remains in the symbol table, "
21551 "but without corresponding entries in "
21552 "the index table\n",
21553 "%s: %ld bytes remain in the symbol table, "
21554 "but without corresponding entries in "
21555 "the index table\n",
21556 arch.sym_size - l),
dda8d76d 21557 filedata->file_name, arch.sym_size - l);
015dc7e1 21558 ret = false;
32ec8896 21559 }
4145f1d5 21560
dda8d76d 21561 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 21562 {
1cb7d8b1
AM
21563 error (_("%s: failed to seek back to start of object files "
21564 "in the archive\n"),
dda8d76d 21565 filedata->file_name);
015dc7e1 21566 ret = false;
2cf0635d 21567 goto out;
4145f1d5 21568 }
fb52b2f4 21569 }
4145f1d5
NC
21570
21571 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
21572 && !do_segments && !do_header && !do_dump && !do_version
21573 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 21574 && !do_section_groups && !do_dyn_syms)
2cf0635d 21575 {
015dc7e1 21576 ret = true; /* Archive index only. */
2cf0635d
NC
21577 goto out;
21578 }
fb52b2f4
NC
21579 }
21580
fb52b2f4
NC
21581 while (1)
21582 {
2cf0635d
NC
21583 char * name;
21584 size_t namelen;
21585 char * qualified_name;
21586
21587 /* Read the next archive header. */
dda8d76d 21588 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
21589 {
21590 error (_("%s: failed to seek to next archive header\n"),
21591 arch.file_name);
015dc7e1 21592 ret = false;
1cb7d8b1
AM
21593 break;
21594 }
dda8d76d 21595 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 21596 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
21597 {
21598 if (got == 0)
2cf0635d 21599 break;
28e817cc
NC
21600 /* PR 24049 - we cannot use filedata->file_name as this will
21601 have already been freed. */
21602 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 21603
015dc7e1 21604 ret = false;
1cb7d8b1
AM
21605 break;
21606 }
2cf0635d 21607 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
21608 {
21609 error (_("%s: did not find a valid archive header\n"),
21610 arch.file_name);
015dc7e1 21611 ret = false;
1cb7d8b1
AM
21612 break;
21613 }
2cf0635d
NC
21614
21615 arch.next_arhdr_offset += sizeof arch.arhdr;
21616
978c4450
AM
21617 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
21618 if (filedata->archive_file_size & 01)
21619 ++filedata->archive_file_size;
2cf0635d
NC
21620
21621 name = get_archive_member_name (&arch, &nested_arch);
21622 if (name == NULL)
fb52b2f4 21623 {
28e817cc 21624 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 21625 ret = false;
d989285c 21626 break;
fb52b2f4 21627 }
2cf0635d 21628 namelen = strlen (name);
fb52b2f4 21629
2cf0635d
NC
21630 qualified_name = make_qualified_name (&arch, &nested_arch, name);
21631 if (qualified_name == NULL)
fb52b2f4 21632 {
28e817cc 21633 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 21634 free (name);
015dc7e1 21635 ret = false;
d989285c 21636 break;
fb52b2f4
NC
21637 }
21638
2cf0635d 21639 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
21640 {
21641 /* This is a proxy for an external member of a thin archive. */
21642 Filedata * member_filedata;
21643 char * member_file_name = adjust_relative_path
dda8d76d 21644 (filedata->file_name, name, namelen);
32ec8896 21645
fd486f32 21646 free (name);
1cb7d8b1
AM
21647 if (member_file_name == NULL)
21648 {
fd486f32 21649 free (qualified_name);
015dc7e1 21650 ret = false;
1cb7d8b1
AM
21651 break;
21652 }
2cf0635d 21653
015dc7e1 21654 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
21655 if (member_filedata == NULL)
21656 {
21657 error (_("Input file '%s' is not readable.\n"), member_file_name);
21658 free (member_file_name);
fd486f32 21659 free (qualified_name);
015dc7e1 21660 ret = false;
1cb7d8b1
AM
21661 break;
21662 }
2cf0635d 21663
978c4450 21664 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 21665 member_filedata->file_name = qualified_name;
2cf0635d 21666
1cb7d8b1 21667 if (! process_object (member_filedata))
015dc7e1 21668 ret = false;
2cf0635d 21669
1cb7d8b1
AM
21670 close_file (member_filedata);
21671 free (member_file_name);
1cb7d8b1 21672 }
2cf0635d 21673 else if (is_thin_archive)
1cb7d8b1
AM
21674 {
21675 Filedata thin_filedata;
eb02c04d 21676
1cb7d8b1 21677 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 21678
a043396b
NC
21679 /* PR 15140: Allow for corrupt thin archives. */
21680 if (nested_arch.file == NULL)
21681 {
21682 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 21683 qualified_name, name);
fd486f32
AM
21684 free (qualified_name);
21685 free (name);
015dc7e1 21686 ret = false;
a043396b
NC
21687 break;
21688 }
fd486f32 21689 free (name);
a043396b 21690
1cb7d8b1 21691 /* This is a proxy for a member of a nested archive. */
978c4450
AM
21692 filedata->archive_file_offset
21693 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 21694
1cb7d8b1
AM
21695 /* The nested archive file will have been opened and setup by
21696 get_archive_member_name. */
978c4450
AM
21697 if (fseek (nested_arch.file, filedata->archive_file_offset,
21698 SEEK_SET) != 0)
1cb7d8b1
AM
21699 {
21700 error (_("%s: failed to seek to archive member.\n"),
21701 nested_arch.file_name);
fd486f32 21702 free (qualified_name);
015dc7e1 21703 ret = false;
1cb7d8b1
AM
21704 break;
21705 }
2cf0635d 21706
dda8d76d
NC
21707 thin_filedata.handle = nested_arch.file;
21708 thin_filedata.file_name = qualified_name;
9abca702 21709
1cb7d8b1 21710 if (! process_object (& thin_filedata))
015dc7e1 21711 ret = false;
1cb7d8b1 21712 }
2cf0635d 21713 else
1cb7d8b1 21714 {
fd486f32 21715 free (name);
978c4450 21716 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 21717 filedata->file_name = qualified_name;
1cb7d8b1 21718 if (! process_object (filedata))
015dc7e1 21719 ret = false;
978c4450 21720 arch.next_arhdr_offset += filedata->archive_file_size;
4c836627 21721 /* Stop looping with "negative" archive_file_size. */
978c4450 21722 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 21723 arch.next_arhdr_offset = -1ul;
1cb7d8b1 21724 }
fb52b2f4 21725
2cf0635d 21726 free (qualified_name);
fb52b2f4
NC
21727 }
21728
4145f1d5 21729 out:
2cf0635d
NC
21730 if (nested_arch.file != NULL)
21731 fclose (nested_arch.file);
21732 release_archive (&nested_arch);
21733 release_archive (&arch);
fb52b2f4 21734
d989285c 21735 return ret;
fb52b2f4
NC
21736}
21737
015dc7e1 21738static bool
2cf0635d 21739process_file (char * file_name)
fb52b2f4 21740{
dda8d76d 21741 Filedata * filedata = NULL;
fb52b2f4
NC
21742 struct stat statbuf;
21743 char armag[SARMAG];
015dc7e1 21744 bool ret = true;
fb52b2f4
NC
21745
21746 if (stat (file_name, &statbuf) < 0)
21747 {
f24ddbdd
NC
21748 if (errno == ENOENT)
21749 error (_("'%s': No such file\n"), file_name);
21750 else
21751 error (_("Could not locate '%s'. System error message: %s\n"),
21752 file_name, strerror (errno));
015dc7e1 21753 return false;
f24ddbdd
NC
21754 }
21755
21756 if (! S_ISREG (statbuf.st_mode))
21757 {
21758 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 21759 return false;
fb52b2f4
NC
21760 }
21761
dda8d76d
NC
21762 filedata = calloc (1, sizeof * filedata);
21763 if (filedata == NULL)
21764 {
21765 error (_("Out of memory allocating file data structure\n"));
015dc7e1 21766 return false;
dda8d76d
NC
21767 }
21768
21769 filedata->file_name = file_name;
21770 filedata->handle = fopen (file_name, "rb");
21771 if (filedata->handle == NULL)
fb52b2f4 21772 {
f24ddbdd 21773 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 21774 free (filedata);
015dc7e1 21775 return false;
fb52b2f4
NC
21776 }
21777
dda8d76d 21778 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 21779 {
4145f1d5 21780 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
21781 fclose (filedata->handle);
21782 free (filedata);
015dc7e1 21783 return false;
fb52b2f4
NC
21784 }
21785
dda8d76d 21786 filedata->file_size = (bfd_size_type) statbuf.st_size;
015dc7e1 21787 filedata->is_separate = false;
f54498b4 21788
fb52b2f4 21789 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 21790 {
015dc7e1
AM
21791 if (! process_archive (filedata, false))
21792 ret = false;
32ec8896 21793 }
2cf0635d 21794 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 21795 {
015dc7e1
AM
21796 if ( ! process_archive (filedata, true))
21797 ret = false;
32ec8896 21798 }
fb52b2f4
NC
21799 else
21800 {
1b513401 21801 if (do_archive_index && !check_all)
4145f1d5
NC
21802 error (_("File %s is not an archive so its index cannot be displayed.\n"),
21803 file_name);
21804
dda8d76d 21805 rewind (filedata->handle);
978c4450 21806 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 21807
dda8d76d 21808 if (! process_object (filedata))
015dc7e1 21809 ret = false;
fb52b2f4
NC
21810 }
21811
dda8d76d 21812 fclose (filedata->handle);
8fb879cd
AM
21813 free (filedata->section_headers);
21814 free (filedata->program_headers);
21815 free (filedata->string_table);
6431e409 21816 free (filedata->dump.dump_sects);
dda8d76d 21817 free (filedata);
32ec8896 21818
fd486f32 21819 free (ba_cache.strtab);
1bd6175a 21820 ba_cache.strtab = NULL;
fd486f32 21821 free (ba_cache.symtab);
1bd6175a 21822 ba_cache.symtab = NULL;
fd486f32
AM
21823 ba_cache.filedata = NULL;
21824
fb52b2f4
NC
21825 return ret;
21826}
21827
252b5132
RH
21828#ifdef SUPPORT_DISASSEMBLY
21829/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 21830 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 21831 symbols. */
252b5132
RH
21832
21833void
2cf0635d 21834print_address (unsigned int addr, FILE * outfile)
252b5132
RH
21835{
21836 fprintf (outfile,"0x%8.8x", addr);
21837}
21838
e3c8793a 21839/* Needed by the i386 disassembler. */
dda8d76d 21840
252b5132
RH
21841void
21842db_task_printsym (unsigned int addr)
21843{
21844 print_address (addr, stderr);
21845}
21846#endif
21847
21848int
2cf0635d 21849main (int argc, char ** argv)
252b5132 21850{
ff78d6d6
L
21851 int err;
21852
87b9f255 21853#ifdef HAVE_LC_MESSAGES
252b5132 21854 setlocale (LC_MESSAGES, "");
3882b010 21855#endif
3882b010 21856 setlocale (LC_CTYPE, "");
252b5132
RH
21857 bindtextdomain (PACKAGE, LOCALEDIR);
21858 textdomain (PACKAGE);
21859
869b9d07
MM
21860 expandargv (&argc, &argv);
21861
dda8d76d 21862 parse_args (& cmdline, argc, argv);
59f14fc0 21863
18bd398b 21864 if (optind < (argc - 1))
1b513401
NC
21865 /* When displaying information for more than one file,
21866 prefix the information with the file name. */
015dc7e1 21867 show_name = true;
5656ba2c
L
21868 else if (optind >= argc)
21869 {
1b513401 21870 /* Ensure that the warning is always displayed. */
015dc7e1 21871 do_checks = true;
1b513401 21872
5656ba2c
L
21873 warn (_("Nothing to do.\n"));
21874 usage (stderr);
21875 }
18bd398b 21876
015dc7e1 21877 err = false;
252b5132 21878 while (optind < argc)
32ec8896 21879 if (! process_file (argv[optind++]))
015dc7e1 21880 err = true;
252b5132 21881
9db70fc3 21882 free (cmdline.dump_sects);
252b5132 21883
7d9813f1
NA
21884 free (dump_ctf_symtab_name);
21885 free (dump_ctf_strtab_name);
21886 free (dump_ctf_parent_name);
21887
32ec8896 21888 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 21889}